From 2096034a13856b6f971d149d9b9f21bcc90cb92d Mon Sep 17 00:00:00 2001 From: smayotte Date: Tue, 1 Feb 2022 14:58:12 -0700 Subject: [PATCH 01/11] implementation of read-in for general plot settings (such as SaveFig option and figure size) for all plot options (--plotconfig and --plot/--plotall) --- sample_plot_config.ini | 18 +++++-- src/nuspacesim/apps/cli.py | 43 +++++++++++++-- src/nuspacesim/compute.py | 25 +++++---- .../simulation/eas_optical/local_plots.py | 20 ++++++- .../simulation/geometry/local_plots.py | 11 +++- .../simulation/spectra/local_plots.py | 12 ++++- src/nuspacesim/simulation/taus/local_plots.py | 54 ++++++++++++++----- src/nuspacesim/utils/decorators.py | 6 +-- 8 files changed, 149 insertions(+), 40 deletions(-) diff --git a/sample_plot_config.ini b/sample_plot_config.ini index 736ed57..8b34da0 100644 --- a/sample_plot_config.ini +++ b/sample_plot_config.ini @@ -1,15 +1,25 @@ +[General] +fig_width = 8 +fig_height = 7 +pop_up = no +save_to_file = yes +save_as = pdf + +[Spectra] +spectra_histogram = yes + [Geometry] -geom_beta_tr_hist = no +geom_beta_tr_hist = yes #interaction_height = no (to be implemented) [Taus] -taus_scatter = no -taus_pexit = no +taus_density_beta = yes +taus_pexit = yes taus_histogram = yes taus_overview = yes [EASOpitcal] -eas_optical_scatter = no +eas_optical_density = yes eas_optical_histogram = yes [Detector] diff --git a/src/nuspacesim/apps/cli.py b/src/nuspacesim/apps/cli.py index 3c87076..6262a98 100644 --- a/src/nuspacesim/apps/cli.py +++ b/src/nuspacesim/apps/cli.py @@ -85,7 +85,15 @@ def cli(): help="Available plotting functions. Select multiple plots with multiple uses of -p", ) @click.option( - "-P", + "-ps", + "--plotsettings", + nargs=5, + type=click.Tuple([int, int, bool, str, bool]), + default=None, + help="Save plot supplied with -p with given file extension, optionally suppress pop_up", +) +@click.option( + "-pc", "--plotconfig", type=click.Path( exists=True, @@ -136,6 +144,7 @@ def run( plot: list, plotconfig: str, plotall: bool, + plotsettings, write_stages: bool, ) -> None: """Perform the full nuspacesim simulation. @@ -183,22 +192,37 @@ def run( config.simulation.spectrum = MonoSpectrum(monospectrum) if powerspectrum is not None: config.simulation.spectrum = PowerSpectrum(*powerspectrum) - plot = ( list(registry) if plotall - else read_plot_config(plotconfig) + else read_plot_config(plotconfig)[0] if plotconfig else plot ) + + if plotconfig: + plot_kwargs = read_plot_config(plotconfig)[1] + if output is not None: + plot_kwargs["filename"] = output + elif (plot and plotsettings) or (plotall and plotsettings): + plot_kwargs = { + "figsize": (plotsettings[0], plotsettings[1]), + "save_to_file": plotsettings[2], + "save_as": plotsettings[3], + "pop_up": plotsettings[4], + } + if output is not None: + plot_kwargs["filename"] = output + else: + plot_kwargs = {} simulation = compute( config, verbose=True, to_plot=plot, + plot_kwargs=plot_kwargs, output_file=output, write_stages=write_stages, ) - if not no_result_file: simulation.write(output, overwrite=True) @@ -329,6 +353,15 @@ def read_plot_config(filename): plot_list = [] cfg = configparser.ConfigParser() cfg.read(filename) + plot_kwargs = { + "figsize": ( + cfg["General"].getint("fig_width"), + cfg["General"].getint("fig_height"), + ), + "save_as": cfg["General"]["save_as"], + "pop_up": cfg["General"].getboolean("pop_up"), + "save_to_file": cfg["General"].getboolean("save_to_file"), + } for sec in cfg.sections()[1:]: for key in cfg[sec]: try: @@ -336,7 +369,7 @@ def read_plot_config(filename): plot_list.append(key) except Exception as e: print(e, "Config file contains non-valid option") - return plot_list + return plot_list, plot_kwargs if __name__ == "__main__": diff --git a/src/nuspacesim/compute.py b/src/nuspacesim/compute.py index 5c95595..6ca5cc3 100644 --- a/src/nuspacesim/compute.py +++ b/src/nuspacesim/compute.py @@ -66,6 +66,7 @@ def compute( verbose: bool = False, output_file: str = None, to_plot: list = [], + plot_kwargs: dict = {}, write_stages=False, ) -> ResultsTable: r"""Simulate an upward going shower. @@ -107,6 +108,8 @@ def compute( Name of file to write intermediate stages to_plot: list, optional Call the listed plotting functions as appropritate. + plot_kwargs: dict, option + Set the contained plotting specifications write_stages: bool, optional Enable writing intermediate results to the output_file. @@ -142,6 +145,8 @@ def mc_logv(mcint, mcintgeo, numEvPass, method): tau = Taus(config) eas = EAS(config) eas_radio = EASRadio(config) + if "filename" not in plot_kwargs: + plot_kwargs["filename"] = "nuspacesim_run_" + sim.meta["simTime"][0] class StagedWriter: """Optionally write intermediate values to file""" @@ -157,37 +162,35 @@ def add_meta(self, *args, **kwargs): sim.write(output_file, overwrite=True) sw = StagedWriter() - logv(f"Running NuSpaceSim with Energy Spectrum ({config.simulation.spectrum})") logv("Computing [green] Geometries.[/]") - beta_tr, thetaArr, pathLenArr = geom(config.simulation.N, store=sw, plot=to_plot) + beta_tr, thetaArr, pathLenArr = geom( + config.simulation.N, store=sw, plot=to_plot, kwargs=plot_kwargs + ) logv( f"\t[blue]Threw {config.simulation.N} neutrinos. {beta_tr.size} were valid.[/]" ) logv("Computing [green] Energy Spectra.[/]") log_e_nu, mc_spec_norm, spec_weights_sum = spec( - beta_tr.shape[0], store=sw, plot=to_plot + beta_tr.shape[0], store=sw, plot=to_plot, kwargs=plot_kwargs ) - logv("Computing [green] Taus.[/]") tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = tau( - beta_tr, log_e_nu, store=sw, plot=to_plot + beta_tr, log_e_nu, store=sw, plot=to_plot, kwargs=plot_kwargs ) logv("Computing [green] Decay Altitudes.[/]") - altDec, lenDec = eas.altDec(beta_tr, tauBeta, tauLorentz, store=sw) + altDec, lenDec = eas.altDec( + beta_tr, tauBeta, tauLorentz, store=sw, plot=to_plot, kwargs=plot_kwargs + ) if config.detector.method == "Optical" or config.detector.method == "Both": logv("Computing [green] EAS Optical Cherenkov light.[/]") numPEs, costhetaChEff = eas( - beta_tr, - altDec, - showerEnergy, - store=sw, - plot=to_plot, + beta_tr, altDec, showerEnergy, store=sw, plot=to_plot, kwargs=plot_kwargs ) logv("Computing [green] Optical Monte Carlo Integral.[/]") diff --git a/src/nuspacesim/simulation/eas_optical/local_plots.py b/src/nuspacesim/simulation/eas_optical/local_plots.py index b0905d3..5afe708 100644 --- a/src/nuspacesim/simulation/eas_optical/local_plots.py +++ b/src/nuspacesim/simulation/eas_optical/local_plots.py @@ -42,6 +42,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): _, betas, altDec, showerEnergy = inputs numPEs, costhetaChEff = results + plotting_opts = kwargs.get("kwargs") fig, ax = plt.subplots(2, 3, figsize=(15, 8), constrained_layout=True) @@ -91,13 +92,21 @@ def eas_optical_density(inputs, results, *args, **kwargs): ) fig.suptitle("EAS Optical Cherenkov properties.") - plt.show() + if plotting_opts.get("pop_up") is True: + plt.show() + if plotting_opts.get("save_to_file") is True: + fig.savefig( + plotting_opts.get("filename") + + "_eas_optical_density." + + plotting_opts.get("save_as") + ) def eas_optical_histogram(inputs, results, *args, **kwargs): r"""Plot some histograms""" # eas_self, betas, altDec, showerEnergy = inputs + plotting_opts = kwargs.get("kwargs") numPEs, costhetaChEff = results color = "salmon" @@ -112,4 +121,11 @@ def eas_optical_histogram(inputs, results, *args, **kwargs): ax[1].set_xlabel("log(cos(θ_chEff))") fig.suptitle("EAS Optical Cherenkov property Histograms") - plt.show() + if plotting_opts.get("pop_up") is True: + plt.show() + if plotting_opts.get("save_to_file") is True: + fig.savefig( + plotting_opts.get("filename") + + "_eas_optical_histogram." + + plotting_opts.get("save_as") + ) diff --git a/src/nuspacesim/simulation/geometry/local_plots.py b/src/nuspacesim/simulation/geometry/local_plots.py index 68b014b..80fe4f3 100644 --- a/src/nuspacesim/simulation/geometry/local_plots.py +++ b/src/nuspacesim/simulation/geometry/local_plots.py @@ -40,9 +40,18 @@ def geom_beta_tr_hist(inputs, results, *args, **kwargs): _ = inputs betas, _, _ = results + plotting_opts = kwargs.get("kwargs") + fig = plt.figure(figsize=(8, 7), constrained_layout=True) plt.hist(np.degrees(betas), 50, alpha=0.75) plt.xlabel("beta_tr (radians)") plt.ylabel("frequency (counts)") plt.title(f"Histogram of {betas.size} Beta Angles") - plt.show() + if plotting_opts.get("pop_up") is True: + plt.show() + if plotting_opts.get("save_to_file") is True: + fig.savefig( + plotting_opts.get("filename") + + "_geom_beta_tr_hist." + + plotting_opts.get("save_as") + ) diff --git a/src/nuspacesim/simulation/spectra/local_plots.py b/src/nuspacesim/simulation/spectra/local_plots.py index 39896bd..1828b2d 100644 --- a/src/nuspacesim/simulation/spectra/local_plots.py +++ b/src/nuspacesim/simulation/spectra/local_plots.py @@ -39,9 +39,10 @@ def spectra_histogram(inputs, results, *args, **kwargs): N, spectrum = inputs log_e_nu = results + plotting_opts = kwargs.get("kwargs") color = "g" - fig = plt.figure(figsize=(8, 7), constrained_layout=True) + fig = plt.figure(figsize=plotting_opts.get("figsize"), constrained_layout=True) ax = fig.add_subplot(211) ax.hist(log_e_nu, 100, log=False, facecolor=color) ax.set_xlabel(f"log(E_nu) of {N} events") @@ -51,4 +52,11 @@ def spectra_histogram(inputs, results, *args, **kwargs): ax.set_xlabel(f"log(E_nu) of {N} events") fig.suptitle(f"Energy Spectra Histogram, Log(E_nu)\n {spectrum}") - plt.show() + if plotting_opts.get("pop_up") is True: + plt.show() + if plotting_opts.get("save_to_file") is True: + fig.savefig( + plotting_opts.get("filename") + + "_spectra_histogram." + + plotting_opts.get("save_as") + ) diff --git a/src/nuspacesim/simulation/taus/local_plots.py b/src/nuspacesim/simulation/taus/local_plots.py index 5ac9f7a..9961ffc 100644 --- a/src/nuspacesim/simulation/taus/local_plots.py +++ b/src/nuspacesim/simulation/taus/local_plots.py @@ -42,9 +42,9 @@ def get_profile(x, y, nbins, useStd=True, *args, **kwargs): x = x[~np.isnan(y)] y = y[~np.isnan(y)] - n, _ = np.histogram(x, bins=nbins, **kwargs) - sy, _ = np.histogram(x, bins=nbins, weights=y, **kwargs) - sy2, _ = np.histogram(x, bins=nbins, weights=y * y, **kwargs) + n, _ = np.histogram(x, bins=nbins) + sy, _ = np.histogram(x, bins=nbins, weights=y) + sy2, _ = np.histogram(x, bins=nbins, weights=y * y) mean = sy / n std = np.sqrt(sy2 / n - mean * mean) if not useStd: @@ -60,6 +60,7 @@ def taus_density_beta(inputs, results, *args, **kwargs): _, betas, log_e_nu = inputs tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + plotting_opts = kwargs.get("kwargs") fig, ax = plt.subplots(2, 2, figsize=(10, 8), sharex=True, constrained_layout=True) @@ -82,7 +83,14 @@ def hist2d(ax, x, y, xlab, ylab): fig.colorbar(im, ax=ax, label="Counts", format="%.0e") fig.suptitle("Tau interaction properties vs. β_tr Angles") - plt.show() + if plotting_opts.get("pop_up") is True: + plt.show() + if plotting_opts.get("save_to_file") is True: + fig.savefig( + plotting_opts.get("filename") + + "_taus_density_beta." + + plotting_opts.get("save_as") + ) def taus_histogram(inputs, results, *args, **kwargs): @@ -93,6 +101,7 @@ def taus_histogram(inputs, results, *args, **kwargs): color = "c" alpha = 1 + plotting_opts = kwargs.get("kwargs") fig, ax = plt.subplots(2, 2, constrained_layout=True) @@ -106,7 +115,14 @@ def taus_histogram(inputs, results, *args, **kwargs): ax[1, 1].set_xlabel("log(PExit(τ))") fig.suptitle("Tau interaction property Histograms") - plt.show() + if plotting_opts.get("pop_up") is True: + plt.show() + if plotting_opts.get("save_to_file") is True: + fig.savefig( + plotting_opts.get("filename") + + "_taus_histogram." + + plotting_opts.get("save_as") + ) def taus_pexit(inputs, results, *args, **kwargs): @@ -115,6 +131,7 @@ def taus_pexit(inputs, results, *args, **kwargs): color = "c" alpha = 0.1 / np.log10(betas.size) + plotting_opts = kwargs.get("kwargs") fig, ax = plt.subplots(1, 2, constrained_layout=True) @@ -135,19 +152,28 @@ def taus_pexit(inputs, results, *args, **kwargs): ax[1].set_xlabel("PExit(τ)") fig.suptitle("Tau Pexit") - plt.show() + if plotting_opts.get("pop_up") is True: + plt.show() + if plotting_opts.get("save_to_file") is True: + fig.savefig( + plotting_opts.get("filename") + + "_taus_pexit." + + plotting_opts.get("save_as") + ) def taus_overview(inputs, results, *args, **kwargs): - r"""Overview plot for taus""" + print(kwargs) + r"""Overview plot for taus""" + plotting_opts = kwargs.get("kwargs") _, betas, log_e_nu = inputs _, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results log_e_nu = log_e_nu + 9 tauEnergy = tauEnergy * 1e9 showerEnergy = showerEnergy * 1e9 * 1e8 - fig, ax = plt.subplots(2, 2, figsize=(10, 8)) + fig, ax = plt.subplots(2, 2, figsize=kwargs.get("figsize")) binning_b = np.arange( np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 ) @@ -233,7 +259,11 @@ def taus_overview(inputs, results, *args, **kwargs): fig.suptitle("Overview of Tau interaction properties") fig.tight_layout() - plt.show() - # if "pop_up" in kwargs and kwargs.get("pop_up") is True: - # plt.show() - # fig.savefig("taus_overview", format="pdf") + if plotting_opts.get("pop_up") is True: + plt.show() + if plotting_opts.get("save_to_file") is True: + fig.savefig( + plotting_opts.get("filename") + + "_taus_overview." + + plotting_opts.get("save_as") + ) diff --git a/src/nuspacesim/utils/decorators.py b/src/nuspacesim/utils/decorators.py index 20ca40d..a84a24a 100644 --- a/src/nuspacesim/utils/decorators.py +++ b/src/nuspacesim/utils/decorators.py @@ -200,17 +200,17 @@ def wrapper_f( if isinstance(plot, str): for plotf in plot_fs: if plotf.__name__ == plot: - plotf(args, values) + plotf(args, values, **kwargs) elif callable(plot): plot(args, values) elif isinstance(plot, Iterable): if all(isinstance(p, str) for p in plot): for plotf in plot_fs: if plotf.__name__ in plot: - plotf(args, values) + plotf(args, values, **kwargs) elif all(callable(p) for p in plot): for plotf in plot: - plotf(args, values) + plotf(args, values, **kwargs) return values return wrapper_f From 3297efb349daaafa3b74fcda66b325b55be4520d Mon Sep 17 00:00:00 2001 From: smayotte Date: Thu, 3 Feb 2022 13:23:13 -0700 Subject: [PATCH 02/11] remove redundant print call --- src/nuspacesim/simulation/taus/local_plots.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nuspacesim/simulation/taus/local_plots.py b/src/nuspacesim/simulation/taus/local_plots.py index 9961ffc..cfee83c 100644 --- a/src/nuspacesim/simulation/taus/local_plots.py +++ b/src/nuspacesim/simulation/taus/local_plots.py @@ -164,7 +164,6 @@ def taus_pexit(inputs, results, *args, **kwargs): def taus_overview(inputs, results, *args, **kwargs): - print(kwargs) r"""Overview plot for taus""" plotting_opts = kwargs.get("kwargs") _, betas, log_e_nu = inputs From 24f81ccb585566e49ed39310de737e9cb8e6ee22 Mon Sep 17 00:00:00 2001 From: smayotte Date: Fri, 4 Feb 2022 14:27:56 -0700 Subject: [PATCH 03/11] unified default colors and colormaps, implemented option to choose color/colormap, corrected default behaviors if no plot-settings are chosen when calling --plot/plotall --- sample_plot_config.ini | 6 ++ src/nuspacesim/apps/cli.py | 10 ++- .../simulation/eas_optical/local_plots.py | 33 ++++--- .../simulation/geometry/local_plots.py | 10 ++- .../simulation/spectra/local_plots.py | 15 ++-- src/nuspacesim/simulation/taus/local_plots.py | 85 ++++++++++++++----- 6 files changed, 113 insertions(+), 46 deletions(-) diff --git a/sample_plot_config.ini b/sample_plot_config.ini index 8b34da0..4f70e5b 100644 --- a/sample_plot_config.ini +++ b/sample_plot_config.ini @@ -4,6 +4,9 @@ fig_height = 7 pop_up = no save_to_file = yes save_as = pdf +default_color = 0 + # as in 'C0' +default_colormap = viridis [Spectra] spectra_histogram = yes @@ -11,6 +14,7 @@ spectra_histogram = yes [Geometry] geom_beta_tr_hist = yes #interaction_height = no (to be implemented) +#geometry_overview = no (to be implemented) [Taus] taus_density_beta = yes @@ -21,7 +25,9 @@ taus_overview = yes [EASOpitcal] eas_optical_density = yes eas_optical_histogram = yes +#eas_optical_overview = no (to be implemented) [Detector] #event_count_at_detector = no (to be implemented) #detection_prob_vs_beta = no (to be implemented) +#detector_overview = no (to be implemented) \ No newline at end of file diff --git a/src/nuspacesim/apps/cli.py b/src/nuspacesim/apps/cli.py index 6262a98..1ff77c0 100644 --- a/src/nuspacesim/apps/cli.py +++ b/src/nuspacesim/apps/cli.py @@ -87,8 +87,8 @@ def cli(): @click.option( "-ps", "--plotsettings", - nargs=5, - type=click.Tuple([int, int, bool, str, bool]), + nargs=7, + type=click.Tuple([int, int, bool, str, bool, int, str]), default=None, help="Save plot supplied with -p with given file extension, optionally suppress pop_up", ) @@ -210,6 +210,8 @@ def run( "save_to_file": plotsettings[2], "save_as": plotsettings[3], "pop_up": plotsettings[4], + "default_color": plotsettings[5], + "default_colormap": plotsettings[6], } if output is not None: plot_kwargs["filename"] = output @@ -289,7 +291,7 @@ def create_config(filename: str, numtrajs: float, monospectrum, powerspectrum) - help="Available plotting functions. Select multiple plots with multiple uses of -p", ) @click.option( - "-P", + "-pc", "--plotconfig", type=click.Path( exists=True, @@ -361,6 +363,8 @@ def read_plot_config(filename): "save_as": cfg["General"]["save_as"], "pop_up": cfg["General"].getboolean("pop_up"), "save_to_file": cfg["General"].getboolean("save_to_file"), + "default_color": cfg["General"].getint("default_color"), + "default_colormap": cfg["General"].get("default_colormap"), } for sec in cfg.sections()[1:]: for key in cfg[sec]: diff --git a/src/nuspacesim/simulation/eas_optical/local_plots.py b/src/nuspacesim/simulation/eas_optical/local_plots.py index 5afe708..a530d8c 100644 --- a/src/nuspacesim/simulation/eas_optical/local_plots.py +++ b/src/nuspacesim/simulation/eas_optical/local_plots.py @@ -43,10 +43,14 @@ def eas_optical_density(inputs, results, *args, **kwargs): _, betas, altDec, showerEnergy = inputs numPEs, costhetaChEff = results plotting_opts = kwargs.get("kwargs") + if "default_colormap" in plotting_opts: + cm = plotting_opts.get("default_colormap") + else: + cm = "viridis" fig, ax = plt.subplots(2, 3, figsize=(15, 8), constrained_layout=True) - hist2d(fig, ax[0, 0], np.degrees(betas), numPEs, "β", "numPEs", cmap="plasma") + hist2d(fig, ax[0, 0], np.degrees(betas), numPEs, "β", "numPEs", cmap=cm) hist2d( fig, ax[1, 0], @@ -54,12 +58,10 @@ def eas_optical_density(inputs, results, *args, **kwargs): costhetaChEff, "β", "cos(θ_chEff)", - cmap="plasma", + cmap=cm, ) - hist2d( - fig, ax[0, 1], altDec, numPEs, "decay altitude (km)", "numPEs", cmap="plasma" - ) + hist2d(fig, ax[0, 1], altDec, numPEs, "decay altitude (km)", "numPEs", cmap=cm) hist2d( fig, @@ -68,7 +70,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): costhetaChEff, "decay altitude (km)", "cos(θ_chEff)", - cmap="plasma", + cmap=cm, ) hist2d( @@ -78,7 +80,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): numPEs, "showerEnergy (100 PeV)", "numPEs", - cmap="plasma", + cmap=cm, ) hist2d( @@ -88,7 +90,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): costhetaChEff, "showerEnergy (100 PeV)", "cos(θ_chEff)", - cmap="plasma", + cmap=cm, ) fig.suptitle("EAS Optical Cherenkov properties.") @@ -107,21 +109,24 @@ def eas_optical_histogram(inputs, results, *args, **kwargs): # eas_self, betas, altDec, showerEnergy = inputs plotting_opts = kwargs.get("kwargs") + if "default_color" in plotting_opts: + c = "C{}".format(plotting_opts.get("default_color")) + else: + c = "C0" numPEs, costhetaChEff = results - color = "salmon" - alpha = 1 - fig, ax = plt.subplots(2, 1, constrained_layout=True) - ax[0].hist(numPEs, 100, log=True, facecolor=color, alpha=alpha) + ax[0].hist(numPEs, 100, log=True, facecolor=c) ax[0].set_xlabel("log(numPEs)") - ax[1].hist(costhetaChEff, 100, log=True, facecolor=color, alpha=alpha) + ax[1].hist(costhetaChEff, 100, log=True, facecolor=c) ax[1].set_xlabel("log(cos(θ_chEff))") fig.suptitle("EAS Optical Cherenkov property Histograms") - if plotting_opts.get("pop_up") is True: + if "pop_up" not in plotting_opts: + plt.show() + elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: plt.show() if plotting_opts.get("save_to_file") is True: fig.savefig( diff --git a/src/nuspacesim/simulation/geometry/local_plots.py b/src/nuspacesim/simulation/geometry/local_plots.py index 80fe4f3..fc99df1 100644 --- a/src/nuspacesim/simulation/geometry/local_plots.py +++ b/src/nuspacesim/simulation/geometry/local_plots.py @@ -41,13 +41,19 @@ def geom_beta_tr_hist(inputs, results, *args, **kwargs): _ = inputs betas, _, _ = results plotting_opts = kwargs.get("kwargs") + if "default_color" in plotting_opts: + c = "C{}".format(plotting_opts.get("default_color")) + else: + c = "C0" fig = plt.figure(figsize=(8, 7), constrained_layout=True) - plt.hist(np.degrees(betas), 50, alpha=0.75) + plt.hist(np.degrees(betas), 50, color=c) plt.xlabel("beta_tr (radians)") plt.ylabel("frequency (counts)") plt.title(f"Histogram of {betas.size} Beta Angles") - if plotting_opts.get("pop_up") is True: + if "pop_up" not in plotting_opts: + plt.show() + elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: plt.show() if plotting_opts.get("save_to_file") is True: fig.savefig( diff --git a/src/nuspacesim/simulation/spectra/local_plots.py b/src/nuspacesim/simulation/spectra/local_plots.py index 1828b2d..7194cae 100644 --- a/src/nuspacesim/simulation/spectra/local_plots.py +++ b/src/nuspacesim/simulation/spectra/local_plots.py @@ -40,19 +40,24 @@ def spectra_histogram(inputs, results, *args, **kwargs): N, spectrum = inputs log_e_nu = results plotting_opts = kwargs.get("kwargs") + if "default_color" in plotting_opts: + c = "C{}".format(plotting_opts.get("default_color")) + else: + c = "C0" - color = "g" - fig = plt.figure(figsize=plotting_opts.get("figsize"), constrained_layout=True) + fig = plt.figure(constrained_layout=True) ax = fig.add_subplot(211) - ax.hist(log_e_nu, 100, log=False, facecolor=color) + ax.hist(log_e_nu, 100, log=False, color=c) ax.set_xlabel(f"log(E_nu) of {N} events") ax = fig.add_subplot(212) - ax.hist(log_e_nu, 100, log=True, facecolor=color) + ax.hist(log_e_nu, 100, log=True, color=c) ax.set_xlabel(f"log(E_nu) of {N} events") fig.suptitle(f"Energy Spectra Histogram, Log(E_nu)\n {spectrum}") - if plotting_opts.get("pop_up") is True: + if "pop_up" not in plotting_opts: + plt.show() + elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: plt.show() if plotting_opts.get("save_to_file") is True: fig.savefig( diff --git a/src/nuspacesim/simulation/taus/local_plots.py b/src/nuspacesim/simulation/taus/local_plots.py index cfee83c..facdfa9 100644 --- a/src/nuspacesim/simulation/taus/local_plots.py +++ b/src/nuspacesim/simulation/taus/local_plots.py @@ -61,6 +61,10 @@ def taus_density_beta(inputs, results, *args, **kwargs): _, betas, log_e_nu = inputs tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results plotting_opts = kwargs.get("kwargs") + if "default_colormap" in plotting_opts: + cm = plotting_opts.get("default_colormap") + else: + cm = "viridis" fig, ax = plt.subplots(2, 2, figsize=(10, 8), sharex=True, constrained_layout=True) @@ -69,7 +73,7 @@ def taus_density_beta(inputs, results, *args, **kwargs): def hist2d(ax, x, y, xlab, ylab): nonlocal im _, _, _, im = ax.hist2d( - x=np.degrees(x), y=np.log10(y), bins=(50, 50), cmin=1, cmap="jet" + x=np.degrees(x), y=np.log10(y), bins=(50, 50), cmin=1, cmap=cm ) ax.set_xlabel(xlab) ax.set_ylabel(ylab) @@ -83,7 +87,9 @@ def hist2d(ax, x, y, xlab, ylab): fig.colorbar(im, ax=ax, label="Counts", format="%.0e") fig.suptitle("Tau interaction properties vs. β_tr Angles") - if plotting_opts.get("pop_up") is True: + if "pop_up" not in plotting_opts: + plt.show() + elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: plt.show() if plotting_opts.get("save_to_file") is True: fig.savefig( @@ -99,23 +105,27 @@ def taus_histogram(inputs, results, *args, **kwargs): _, _, _ = inputs tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results - color = "c" - alpha = 1 plotting_opts = kwargs.get("kwargs") + if "default_color" in plotting_opts: + c = "C{}".format(plotting_opts.get("default_color")) + else: + c = "C0" fig, ax = plt.subplots(2, 2, constrained_layout=True) - ax[0, 0].hist(tauBeta, 100, log=True, facecolor=color, alpha=alpha) + ax[0, 0].hist(tauBeta, 100, log=True, facecolor=c) ax[0, 0].set_xlabel("log(τ_β)") - ax[0, 1].hist(tauLorentz, 100, log=True, facecolor=color, alpha=alpha) + ax[0, 1].hist(tauLorentz, 100, log=True, facecolor=c) ax[0, 1].set_xlabel("log(τ_Lorentz)") - ax[1, 0].hist(showerEnergy, 100, log=True, facecolor=color, alpha=alpha) + ax[1, 0].hist(showerEnergy, 100, log=True, facecolor=c) ax[1, 0].set_xlabel("log(showerEnergy)") - ax[1, 1].hist(tauExitProb, 100, log=True, facecolor=color, alpha=alpha) + ax[1, 1].hist(tauExitProb, 100, log=True, facecolor=c) ax[1, 1].set_xlabel("log(PExit(τ))") fig.suptitle("Tau interaction property Histograms") - if plotting_opts.get("pop_up") is True: + if "pop_up" not in plotting_opts: + plt.show() + elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: plt.show() if plotting_opts.get("save_to_file") is True: fig.savefig( @@ -129,9 +139,12 @@ def taus_pexit(inputs, results, *args, **kwargs): _, betas, _ = inputs _, _, _, _, tauExitProb = results - color = "c" - alpha = 0.1 / np.log10(betas.size) plotting_opts = kwargs.get("kwargs") + if "default_color" in plotting_opts: + c = "C{}".format(plotting_opts.get("default_color")) + else: + c = "C0" + alpha = 0.1 / np.log10(betas.size) fig, ax = plt.subplots(1, 2, constrained_layout=True) @@ -139,7 +152,7 @@ def taus_pexit(inputs, results, *args, **kwargs): x=np.degrees(betas), y=np.log10(tauExitProb), s=1, - c=color, + c=c, marker=".", alpha=alpha, ) @@ -147,12 +160,14 @@ def taus_pexit(inputs, results, *args, **kwargs): ax[0].set_ylabel("log(PExit(τ))") ax[0].set_title("β vs Exit Probability.") - ax[1].hist(tauExitProb, 100, log=True, facecolor=color) + ax[1].hist(tauExitProb, 100, log=True, facecolor=c) ax[1].set_ylabel("log(frequency)") ax[1].set_xlabel("PExit(τ)") fig.suptitle("Tau Pexit") - if plotting_opts.get("pop_up") is True: + if "pop_up" not in plotting_opts: + plt.show() + elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: plt.show() if plotting_opts.get("save_to_file") is True: fig.savefig( @@ -166,6 +181,18 @@ def taus_overview(inputs, results, *args, **kwargs): r"""Overview plot for taus""" plotting_opts = kwargs.get("kwargs") + if "default_color" in plotting_opts: + c1, c2, c3 = ( + "C{}".format(plotting_opts.get("default_color")), + "C{}".format(plotting_opts.get("default_color") + 1), + "C{}".format(plotting_opts.get("default_color") + 2), + ) + else: + c1, c2, c3 = "C0", "C1", "C2" + if "default_colormap" in plotting_opts: + cm = plotting_opts.get("default_colormap") + else: + cm = "viridis" _, betas, log_e_nu = inputs _, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results log_e_nu = log_e_nu + 9 @@ -182,19 +209,23 @@ def taus_overview(inputs, results, *args, **kwargs): 0.1, ) ax[0, 0].hist( - x=log_e_nu, bins=binning_e, color="C0", alpha=0.6, label=r"$E_{\nu_\tau}$" + x=log_e_nu, + bins=binning_e, + color=c1, + alpha=0.6, + label=r"$E_{\nu_\tau}$", ) ax[0, 0].hist( x=np.log10(tauEnergy), bins=binning_e, - color="C1", + color=c2, alpha=0.6, label=r"$E_\tau$", ) ax[0, 0].hist( x=np.log10(showerEnergy), bins=binning_e, - color="C2", + color=c3, alpha=0.6, label=r"$E_\mathrm{shower}$", ) @@ -205,7 +236,11 @@ def taus_overview(inputs, results, *args, **kwargs): ) ax[0, 0].set_ylabel(r"Counts") - n, bins, _ = ax[0, 1].hist(x=np.degrees(betas), bins=binning_b) + n, bins, _ = ax[0, 1].hist( + x=np.degrees(betas), + bins=binning_b, + color=c1, + ) ax[0, 1].set_xlabel(r"Earth emergence angle $\beta$ / $^{\circ}$") ax[0, 1].set_ylabel("Counts") ax[0, 1].set_yscale("log") @@ -215,7 +250,7 @@ def taus_overview(inputs, results, *args, **kwargs): np.log10(np.min(tauLorentz)) - 0.2, np.log10(np.max(tauLorentz)) + 0.2, 25 ) _, _, _, im = ax[1, 0].hist2d( - np.degrees(betas), tauLorentz, bins=[binning_b, binning_y], cmin=1 + np.degrees(betas), tauLorentz, bins=[binning_b, binning_y], cmin=1, cmap=cm ) bincenter, mean, std, binwidth = get_profile( np.degrees(betas), tauLorentz, 10, useStd=True, **kwargs @@ -225,7 +260,7 @@ def taus_overview(inputs, results, *args, **kwargs): mean, yerr=std, xerr=binwidth, - color="C1", + color=c2, fmt=".", lw=2, zorder=5, @@ -245,7 +280,11 @@ def taus_overview(inputs, results, *args, **kwargs): np.log10(np.min(tauExitProb)) - 0.2, np.log10(np.max(tauExitProb)) + 0.2, 25 ) _, _, _, im = ax[1, 1].hist2d( - np.degrees(betas), tauExitProb, bins=[binning_b, binning_y], cmin=1 + np.degrees(betas), + tauExitProb, + bins=[binning_b, binning_y], + cmin=1, + cmap=cm, ) divider = make_axes_locatable(ax[1, 1]) cax = divider.append_axes("right", size="5%", pad=0.0) @@ -258,7 +297,9 @@ def taus_overview(inputs, results, *args, **kwargs): fig.suptitle("Overview of Tau interaction properties") fig.tight_layout() - if plotting_opts.get("pop_up") is True: + if "pop_up" not in plotting_opts: + plt.show() + elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: plt.show() if plotting_opts.get("save_to_file") is True: fig.savefig( From 1b45e0e8a6cd16ecda5c8eac27e54c790707905b Mon Sep 17 00:00:00 2001 From: smayotte Date: Wed, 16 Feb 2022 11:14:08 -0700 Subject: [PATCH 04/11] added new plot function, adjusted all labels to be more uniform, switched to hexbins for 2D-histograms because they look better. Adjustments for show-plot still needed! --- sample_plot_config.ini | 7 +- .../simulation/eas_optical/local_plots.py | 54 ++++-- .../simulation/geometry/local_plots.py | 48 +++++- .../simulation/geometry/region_geometry.py | 4 +- .../simulation/spectra/local_plots.py | 16 +- src/nuspacesim/simulation/taus/local_plots.py | 154 +++++++++++------- src/nuspacesim/utils/plots.py | 25 ++- 7 files changed, 219 insertions(+), 89 deletions(-) diff --git a/sample_plot_config.ini b/sample_plot_config.ini index 4f70e5b..e23a1da 100644 --- a/sample_plot_config.ini +++ b/sample_plot_config.ini @@ -1,6 +1,6 @@ [General] -fig_width = 8 -fig_height = 7 +fig_width = 10 +fig_height = 8 pop_up = no save_to_file = yes save_as = pdf @@ -13,7 +13,8 @@ spectra_histogram = yes [Geometry] geom_beta_tr_hist = yes -#interaction_height = no (to be implemented) +path_length_to_detector = yes +interaction_height = no #geometry_overview = no (to be implemented) [Taus] diff --git a/src/nuspacesim/simulation/eas_optical/local_plots.py b/src/nuspacesim/simulation/eas_optical/local_plots.py index a530d8c..fb5a7ad 100644 --- a/src/nuspacesim/simulation/eas_optical/local_plots.py +++ b/src/nuspacesim/simulation/eas_optical/local_plots.py @@ -34,7 +34,7 @@ import numpy as np from matplotlib import pyplot as plt -from ...utils.plots import hist2d +from ...utils.plots import hexbin def eas_optical_density(inputs, results, *args, **kwargs): @@ -42,6 +42,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): _, betas, altDec, showerEnergy = inputs numPEs, costhetaChEff = results + plotting_opts = kwargs.get("kwargs") if "default_colormap" in plotting_opts: cm = plotting_opts.get("default_colormap") @@ -50,50 +51,67 @@ def eas_optical_density(inputs, results, *args, **kwargs): fig, ax = plt.subplots(2, 3, figsize=(15, 8), constrained_layout=True) - hist2d(fig, ax[0, 0], np.degrees(betas), numPEs, "β", "numPEs", cmap=cm) - hist2d( + hexbin( + fig, + ax[0, 0], + np.degrees(betas), + numPEs, + "$\\beta$ / $^{\\circ}$", + "#PEs", + cmap=cm, + ) + hexbin( fig, ax[1, 0], np.degrees(betas), costhetaChEff, - "β", - "cos(θ_chEff)", + "$\\beta$ / $^{\\circ}$", + "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", cmap=cm, ) - hist2d(fig, ax[0, 1], altDec, numPEs, "decay altitude (km)", "numPEs", cmap=cm) + hexbin( + fig, + ax[0, 1], + altDec, + numPEs, + "$Decay_\\mathrm{Altitude}$ / km", + "#PEs", + cmap=cm, + ) - hist2d( + hexbin( fig, ax[1, 1], altDec, costhetaChEff, - "decay altitude (km)", - "cos(θ_chEff)", + "Decay_\\mathrm{Altitude}$ / km", + "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", cmap=cm, ) - hist2d( + hexbin( fig, ax[0, 2], showerEnergy, numPEs, - "showerEnergy (100 PeV)", - "numPEs", + "$E_\\mathrm{shower}$ / 100 PeV", + "#PEs", cmap=cm, ) - hist2d( + hexbin( fig, ax[1, 2], showerEnergy, costhetaChEff, - "showerEnergy (100 PeV)", - "cos(θ_chEff)", + "$E_\\mathrm{shower}$ / 100 PeV", + "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", cmap=cm, ) fig.suptitle("EAS Optical Cherenkov properties.") + if plotting_opts.get("pop_up") is True: plt.show() if plotting_opts.get("save_to_file") is True: @@ -118,10 +136,12 @@ def eas_optical_histogram(inputs, results, *args, **kwargs): fig, ax = plt.subplots(2, 1, constrained_layout=True) ax[0].hist(numPEs, 100, log=True, facecolor=c) - ax[0].set_xlabel("log(numPEs)") + ax[0].set_xlabel("log(#PEs)") + ax[0].set_ylabel("Counts") ax[1].hist(costhetaChEff, 100, log=True, facecolor=c) - ax[1].set_xlabel("log(cos(θ_chEff))") + ax[1].set_xlabel("$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)") + ax[1].set_ylabel("Counts") fig.suptitle("EAS Optical Cherenkov property Histograms") if "pop_up" not in plotting_opts: diff --git a/src/nuspacesim/simulation/geometry/local_plots.py b/src/nuspacesim/simulation/geometry/local_plots.py index fc99df1..b8e725d 100644 --- a/src/nuspacesim/simulation/geometry/local_plots.py +++ b/src/nuspacesim/simulation/geometry/local_plots.py @@ -31,6 +31,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import matplotlib import numpy as np from matplotlib import pyplot as plt @@ -48,9 +49,9 @@ def geom_beta_tr_hist(inputs, results, *args, **kwargs): fig = plt.figure(figsize=(8, 7), constrained_layout=True) plt.hist(np.degrees(betas), 50, color=c) - plt.xlabel("beta_tr (radians)") - plt.ylabel("frequency (counts)") - plt.title(f"Histogram of {betas.size} Beta Angles") + plt.xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") + plt.ylabel("Counts") + plt.title(f"Histogram of {betas.size} $\\beta$ angles") if "pop_up" not in plotting_opts: plt.show() elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: @@ -61,3 +62,44 @@ def geom_beta_tr_hist(inputs, results, *args, **kwargs): + "_geom_beta_tr_hist." + plotting_opts.get("save_as") ) + + +def path_length_to_detector(inputs, results, *args, **kwargs): + r"""Plot a histgram of beta trajectories.""" + + _ = inputs + betas, _, path_lens = results + plotting_opts = kwargs.get("kwargs") + if "default_colormap" in plotting_opts: + cm = plotting_opts.get("default_colormap") + else: + cm = "viridis" + + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 + ) + fig, ax = plt.subplots(figsize=kwargs.get("figsize"), constrained_layout=True) + im = ax.hexbin( + np.degrees(betas), + path_lens, + gridsize=len(binning_b), + yscale="log", + mincnt=1, + cmap=cm, + edgecolors="none", + ) + ax.set_xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") + ax.set_ylabel("Path length to detector / km") + cbar = fig.colorbar(im, ax=ax, pad=0.0) + cbar.set_label("Counts") + + if "pop_up" not in plotting_opts: + plt.show() + elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: + plt.show() + if plotting_opts.get("save_to_file") is True: + fig.savefig( + plotting_opts.get("filename") + + "_path_length_to_detector." + + plotting_opts.get("save_as") + ) diff --git a/src/nuspacesim/simulation/geometry/region_geometry.py b/src/nuspacesim/simulation/geometry/region_geometry.py index b2f6551..943e335 100644 --- a/src/nuspacesim/simulation/geometry/region_geometry.py +++ b/src/nuspacesim/simulation/geometry/region_geometry.py @@ -34,7 +34,7 @@ import numpy as np from ...utils import decorators -from .local_plots import geom_beta_tr_hist +from .local_plots import geom_beta_tr_hist, path_length_to_detector __all__ = ["RegionGeom"] @@ -235,7 +235,7 @@ def valid_costhetaNSubV(self): def valid_costhetaTrSubV(self): return self.costhetaTrSubV[self.event_mask] - @decorators.nss_result_plot(geom_beta_tr_hist) + @decorators.nss_result_plot(geom_beta_tr_hist, path_length_to_detector) @decorators.nss_result_store("beta_rad", "theta_rad", "path_len") def __call__(self, numtrajs, *args, **kwargs): """Throw numtrajs events and return valid betas.""" diff --git a/src/nuspacesim/simulation/spectra/local_plots.py b/src/nuspacesim/simulation/spectra/local_plots.py index 7194cae..735a529 100644 --- a/src/nuspacesim/simulation/spectra/local_plots.py +++ b/src/nuspacesim/simulation/spectra/local_plots.py @@ -45,16 +45,16 @@ def spectra_histogram(inputs, results, *args, **kwargs): else: c = "C0" - fig = plt.figure(constrained_layout=True) - ax = fig.add_subplot(211) - ax.hist(log_e_nu, 100, log=False, color=c) - ax.set_xlabel(f"log(E_nu) of {N} events") + fig, ax = plt.subplots(2, 1, figsize=(8, 8), sharex=True) + ax[0].hist(log_e_nu, 100, log=False, color=c) + ax[0].set_ylabel("Counts") - ax = fig.add_subplot(212) - ax.hist(log_e_nu, 100, log=True, color=c) - ax.set_xlabel(f"log(E_nu) of {N} events") + ax[1].hist(log_e_nu, 100, log=True, color=c) + ax[1].set_xlabel("$\\log_{{10}}\\left(E_\\nu\\right)$") + ax[1].set_ylabel("Counts") - fig.suptitle(f"Energy Spectra Histogram, Log(E_nu)\n {spectrum}") + fig.suptitle(f"Energy Spectra Histogram of {N} events\n {spectrum}") + fig.tight_layout() if "pop_up" not in plotting_opts: plt.show() elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: diff --git a/src/nuspacesim/simulation/taus/local_plots.py b/src/nuspacesim/simulation/taus/local_plots.py index facdfa9..f31da2a 100644 --- a/src/nuspacesim/simulation/taus/local_plots.py +++ b/src/nuspacesim/simulation/taus/local_plots.py @@ -65,28 +65,63 @@ def taus_density_beta(inputs, results, *args, **kwargs): cm = plotting_opts.get("default_colormap") else: cm = "viridis" - + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 + ) fig, ax = plt.subplots(2, 2, figsize=(10, 8), sharex=True, constrained_layout=True) im = None - def hist2d(ax, x, y, xlab, ylab): + def hexbin(ax, x, y, xlab, xunits, ylab): nonlocal im - _, _, _, im = ax.hist2d( - x=np.degrees(x), y=np.log10(y), bins=(50, 50), cmin=1, cmap=cm + im = ax.hexbin( + x=np.degrees(x), + y=np.log10(y), + gridsize=len(binning_b), + mincnt=1, + cmap=cm, + edgecolors="none", ) - ax.set_xlabel(xlab) - ax.set_ylabel(ylab) + ax.set_xlabel(f"{xlab} / {xunits}") + ax.set_ylabel(f"{ylab}") ax.set_title(f"{xlab} vs {ylab}") - hist2d(ax[0, 0], betas, tauBeta, "β", "log(τ_β)") - hist2d(ax[0, 1], betas, tauLorentz, "β", "log(τ_Lorentz)") - hist2d(ax[1, 0], betas, showerEnergy, "β", "log(showerEnergy)") - hist2d(ax[1, 1], betas, tauExitProb, "β", "log(Exit Probability (τ))") + hexbin( + ax[0, 0], + betas, + tauBeta, + "$\\beta$", + "$^{\\circ}$", + "$\\log_{10}(\\tau_\\beta)$", + ) + hexbin( + ax[0, 1], + betas, + tauLorentz, + "$\\beta$", + "$^{\\circ}$", + "$\\log_{10}(\\tau_\\mathrm{Lorentz})$", + ) + hexbin( + ax[1, 0], + betas, + showerEnergy, + "$\\beta$", + "$^{\\circ}$", + "$\\log_{10}(E_\\mathrm{shower})$", + ) + hexbin( + ax[1, 1], + betas, + tauExitProb, + "$\\beta$", + "$^{\\circ}$", + "$\\log_{10}(P_\\mathrm{Exit}(\\tau))$", + ) fig.colorbar(im, ax=ax, label="Counts", format="%.0e") - fig.suptitle("Tau interaction properties vs. β_tr Angles") + fig.suptitle("Tau interaction properties vs. Earth emergence angles $\\beta$") if "pop_up" not in plotting_opts: plt.show() elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: @@ -114,15 +149,15 @@ def taus_histogram(inputs, results, *args, **kwargs): fig, ax = plt.subplots(2, 2, constrained_layout=True) ax[0, 0].hist(tauBeta, 100, log=True, facecolor=c) - ax[0, 0].set_xlabel("log(τ_β)") + ax[0, 0].set_xlabel("$\\log_{10}(\\tau_\\beta)$") ax[0, 1].hist(tauLorentz, 100, log=True, facecolor=c) - ax[0, 1].set_xlabel("log(τ_Lorentz)") + ax[0, 1].set_xlabel("$\\log_{10}(\\tau_\\mathrm{Lorentz})$") ax[1, 0].hist(showerEnergy, 100, log=True, facecolor=c) - ax[1, 0].set_xlabel("log(showerEnergy)") + ax[1, 0].set_xlabel("$\\log_{10}(E_\\mathrm{shower})$") ax[1, 1].hist(tauExitProb, 100, log=True, facecolor=c) - ax[1, 1].set_xlabel("log(PExit(τ))") + ax[1, 1].set_xlabel("$\\log_{10}(P_\\mathrm{Exit}(\\tau))$") - fig.suptitle("Tau interaction property Histograms") + fig.suptitle("$\\tau$ interaction property Histograms") if "pop_up" not in plotting_opts: plt.show() elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: @@ -144,27 +179,36 @@ def taus_pexit(inputs, results, *args, **kwargs): c = "C{}".format(plotting_opts.get("default_color")) else: c = "C0" - alpha = 0.1 / np.log10(betas.size) - - fig, ax = plt.subplots(1, 2, constrained_layout=True) + if "default_colormap" in plotting_opts: + cm = plotting_opts.get("default_colormap") + else: + cm = "viridis" - ax[0].scatter( - x=np.degrees(betas), - y=np.log10(tauExitProb), - s=1, - c=c, - marker=".", - alpha=alpha, + fig, ax = plt.subplots(1, 2, figsize=(10, 5), constrained_layout=True) + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 ) - ax[0].set_xlabel("β") - ax[0].set_ylabel("log(PExit(τ))") - ax[0].set_title("β vs Exit Probability.") + im = ax[0].hexbin( + np.degrees(betas), + np.log10(tauExitProb), + gridsize=len(binning_b), + mincnt=1, + cmap=cm, + edgecolors="none", + ) + ax[0].set_xlabel("$\\beta$ / $^{\\circ}$") + ax[0].set_ylabel("$\\log_{10}(P_\\mathrm{Exit}(\\tau))$") ax[1].hist(tauExitProb, 100, log=True, facecolor=c) - ax[1].set_ylabel("log(frequency)") - ax[1].set_xlabel("PExit(τ)") + ax[1].set_ylabel("$\\log(Counts)$") + ax[1].set_xlabel("$P_\\mathrm{Exit}(\\tau)$") + + divider = make_axes_locatable(ax[0]) + cax = divider.append_axes("right", size="5%", pad=0.0) + cbar = fig.colorbar(im, cax=cax) + cbar.set_label("Counts") - fig.suptitle("Tau Pexit") + fig.suptitle("$\\tau$ exit probability") if "pop_up" not in plotting_opts: plt.show() elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: @@ -213,26 +257,26 @@ def taus_overview(inputs, results, *args, **kwargs): bins=binning_e, color=c1, alpha=0.6, - label=r"$E_{\nu_\tau}$", + label="$E_{\\nu_\\tau}$", ) ax[0, 0].hist( x=np.log10(tauEnergy), bins=binning_e, color=c2, alpha=0.6, - label=r"$E_\tau$", + label="$E_\\tau$", ) ax[0, 0].hist( x=np.log10(showerEnergy), bins=binning_e, color=c3, alpha=0.6, - label=r"$E_\mathrm{shower}$", + label="$E_\\mathrm{shower}$", ) ax[0, 0].set_yscale("log") ax[0, 0].legend(loc="upper left") ax[0, 0].set_xlabel( - r"Energy / $\log_\mathrm{10}\left(\frac{E}{\mathrm{eV}}\right)$" + "Energy / $\\log_\\mathrm{10}\\left(\\frac{E}{\\mathrm{eV}}\\right)$" ) ax[0, 0].set_ylabel(r"Counts") @@ -241,16 +285,19 @@ def taus_overview(inputs, results, *args, **kwargs): bins=binning_b, color=c1, ) - ax[0, 1].set_xlabel(r"Earth emergence angle $\beta$ / $^{\circ}$") + ax[0, 1].set_xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") ax[0, 1].set_ylabel("Counts") ax[0, 1].set_yscale("log") ax[0, 1].set_xlim(min(binning_b), max(binning_b)) - binning_y = np.logspace( - np.log10(np.min(tauLorentz)) - 0.2, np.log10(np.max(tauLorentz)) + 0.2, 25 - ) - _, _, _, im = ax[1, 0].hist2d( - np.degrees(betas), tauLorentz, bins=[binning_b, binning_y], cmin=1, cmap=cm + im = ax[1, 0].hexbin( + np.degrees(betas), + tauLorentz, + gridsize=len(binning_b), + yscale="log", + mincnt=1, + cmap=cm, + edgecolors="none", ) bincenter, mean, std, binwidth = get_profile( np.degrees(betas), tauLorentz, 10, useStd=True, **kwargs @@ -270,30 +317,27 @@ def taus_overview(inputs, results, *args, **kwargs): cax = divider.append_axes("right", size="5%", pad=0.0) cbar = fig.colorbar(im, cax=cax) cbar.set_label("Counts") - ax[1, 0].set_yscale("log") ax[1, 0].set_xlim(min(binning_b), max(binning_b)) - ax[1, 0].legend(loc="upper center") - ax[1, 0].set_xlabel(r"Earth emergence angle $\beta$ / $^{\circ}$") - ax[1, 0].set_ylabel(r"$\tau_\mathrm{Lorentz}$") + ax[1, 0].legend(loc="lower center") + ax[1, 0].set_xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") + ax[1, 0].set_ylabel("$\\tau_\\mathrm{Lorentz}$") - binning_y = np.logspace( - np.log10(np.min(tauExitProb)) - 0.2, np.log10(np.max(tauExitProb)) + 0.2, 25 - ) - _, _, _, im = ax[1, 1].hist2d( + im = ax[1, 1].hexbin( np.degrees(betas), tauExitProb, - bins=[binning_b, binning_y], - cmin=1, + gridsize=len(binning_b), + yscale="log", + mincnt=1, cmap=cm, + edgecolors="none", ) divider = make_axes_locatable(ax[1, 1]) cax = divider.append_axes("right", size="5%", pad=0.0) cbar = fig.colorbar(im, cax=cax) cbar.set_label("Counts") - ax[1, 1].set_yscale("log") ax[1, 1].set_xlim(min(binning_b), max(binning_b)) - ax[1, 1].set_xlabel(r"Earth emergence angle $\beta$ / $^{\circ}$") - ax[1, 1].set_ylabel(r"$P_\mathrm{Exit}(\tau)$") + ax[1, 1].set_xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") + ax[1, 1].set_ylabel("$P_\\mathrm{Exit}(\\tau)$") fig.suptitle("Overview of Tau interaction properties") fig.tight_layout() diff --git a/src/nuspacesim/utils/plots.py b/src/nuspacesim/utils/plots.py index 0dda951..6970489 100644 --- a/src/nuspacesim/utils/plots.py +++ b/src/nuspacesim/utils/plots.py @@ -38,6 +38,30 @@ __all__ = ["dashboard", "energy_histograms", "show_plot"] +def hexbin(fig, ax, x, y, xlab, ylab, cmap="viridis", logx=True, logy=True): + + xf = np.log10 if logx else lambda q: q + yf = np.log10 if logy else lambda q: q + + xl = f"log({xlab})" if logx else xlab + yl = f"log({ylab})" if logy else ylab + + xmask = x > 0 if logx else np.full(x.shape, True) + ymask = y > 0 if logy else np.full(y.shape, True) + m = xmask & ymask + + im = ax.hexbin( + x=xf(x[m]), y=yf(y[m]), gridsize=25, mincnt=1, cmap=cmap, edgecolors="none" + ) + + ax.set_xlabel(xl) + ax.set_ylabel(yl) + + ax.set_title(f"{yl} vs {xl}") + cbar = fig.colorbar(im, ax=ax, pad=0.0) + cbar.set_label("Counts") + + def hist2d(fig, ax, x, y, xlab, ylab, cmap="jet", logx=True, logy=True): xf = np.log10 if logx else lambda q: q @@ -103,7 +127,6 @@ def energy_histograms(sim, fig, ax=None): color="C0", alpha=0.6, label=r"$E_{\nu_\tau}$", - edgecolor="k", ) ax.hist( x=np.log10(sim["tauEnergy"]) + 9, From 0ad8557124d3ba0f70f9829cb46ecf1f51eba823 Mon Sep 17 00:00:00 2001 From: smayotte Date: Wed, 23 Feb 2022 13:25:56 -0700 Subject: [PATCH 05/11] added plotsettings compatibility for show-plot --- sample_plot_config.ini | 17 ++- src/nuspacesim/apps/cli.py | 52 ++++++- src/nuspacesim/simulation/eas_optical/eas.py | 6 +- .../simulation/eas_optical/local_plots.py | 12 +- .../simulation/geometry/region_geometry.py | 6 +- src/nuspacesim/simulation/taus/taus.py | 6 +- src/nuspacesim/utils/decorators.py | 5 +- src/nuspacesim/utils/plots.py | 141 ++++++++++-------- 8 files changed, 156 insertions(+), 89 deletions(-) diff --git a/sample_plot_config.ini b/sample_plot_config.ini index e23a1da..29dbeda 100644 --- a/sample_plot_config.ini +++ b/sample_plot_config.ini @@ -5,7 +5,7 @@ pop_up = no save_to_file = yes save_as = pdf default_color = 0 - # as in 'C0' +# as in 'C0' default_colormap = viridis [Spectra] @@ -14,8 +14,8 @@ spectra_histogram = yes [Geometry] geom_beta_tr_hist = yes path_length_to_detector = yes -interaction_height = no -#geometry_overview = no (to be implemented) +# interaction_height = no (to be implemented) +# geometry_overview = no (to be implemented) [Taus] taus_density_beta = yes @@ -26,9 +26,12 @@ taus_overview = yes [EASOpitcal] eas_optical_density = yes eas_optical_histogram = yes -#eas_optical_overview = no (to be implemented) +# eas_optical_overview = no (to be implemented) [Detector] -#event_count_at_detector = no (to be implemented) -#detection_prob_vs_beta = no (to be implemented) -#detector_overview = no (to be implemented) \ No newline at end of file +# event_count_at_detector = no (to be implemented) +# detection_prob_vs_beta = no (to be implemented) +# detector_overview = no (to be implemented) + +[Overview] +dashboard = yes diff --git a/src/nuspacesim/apps/cli.py b/src/nuspacesim/apps/cli.py index 1ff77c0..0307d19 100644 --- a/src/nuspacesim/apps/cli.py +++ b/src/nuspacesim/apps/cli.py @@ -203,7 +203,11 @@ def run( if plotconfig: plot_kwargs = read_plot_config(plotconfig)[1] if output is not None: - plot_kwargs["filename"] = output + for ext in [".h5", ".hdf5", ".fits"]: + if ext in output: + plot_kwargs["filename"] = output.replace(ext, "") + else: + plot_kwargs["filename"] = output elif (plot and plotsettings) or (plotall and plotsettings): plot_kwargs = { "figsize": (plotsettings[0], plotsettings[1]), @@ -214,7 +218,11 @@ def run( "default_colormap": plotsettings[6], } if output is not None: - plot_kwargs["filename"] = output + for ext in [".h5", ".hdf5", ".fits"]: + if ext in output: + plot_kwargs["filename"] = output.replace(ext, "") + else: + plot_kwargs["filename"] = output else: plot_kwargs = {} simulation = compute( @@ -290,6 +298,14 @@ def create_config(filename: str, numtrajs: float, monospectrum, powerspectrum) - default=[], help="Available plotting functions. Select multiple plots with multiple uses of -p", ) +@click.option( + "-ps", + "--plotsettings", + nargs=7, + type=click.Tuple([int, int, bool, str, bool, int, str]), + default=None, + help="Save plot supplied with -p with given file extension, optionally suppress pop_up", +) @click.option( "-pc", "--plotconfig", @@ -311,6 +327,7 @@ def show_plot( plot: list, plotconfig: str, plotall: bool, + plotsettings, ) -> None: """Show predefined plots of results in simulation file. @@ -340,15 +357,36 @@ def show_plot( plot = ( list(registry) if plotall - else read_plot_config(plotconfig) + else read_plot_config(plotconfig)[0] if plotconfig else plot ) - simulation.geometry.region_geometry.show_plot(sim, plot) - simulation.taus.taus.show_plot(sim, plot) - simulation.eas_optical.eas.show_plot(sim, plot) - plots.show_plot(sim, plot) + for ext in [".h5", ".hdf5", ".fits"]: + if ext in simulation_file: + plot_filename = simulation_file.replace(ext, "") + else: + plot_filename = simulation_file + if plotconfig: + plot_kwargs = read_plot_config(plotconfig)[1] + plot_kwargs["filename"] = plot_filename + elif (plot and plotsettings) or (plotall and plotsettings): + plot_kwargs = { + "figsize": (plotsettings[0], plotsettings[1]), + "save_to_file": plotsettings[2], + "save_as": plotsettings[3], + "pop_up": plotsettings[4], + "default_color": plotsettings[5], + "default_colormap": plotsettings[6], + "filename": plot_filename, + } + else: + plot_kwargs = {} + + simulation.geometry.region_geometry.show_plot(sim, plot, plot_kwargs) + simulation.taus.taus.show_plot(sim, plot, plot_kwargs) + simulation.eas_optical.eas.show_plot(sim, plot, plot_kwargs) + plots.show_plot(sim, plot, plot_kwargs) def read_plot_config(filename): diff --git a/src/nuspacesim/simulation/eas_optical/eas.py b/src/nuspacesim/simulation/eas_optical/eas.py index 60595c9..99a9bda 100644 --- a/src/nuspacesim/simulation/eas_optical/eas.py +++ b/src/nuspacesim/simulation/eas_optical/eas.py @@ -116,8 +116,10 @@ def __call__(self, beta, altDec, showerEnergy, *args, **kwargs): return numPEs, costhetaChEff -def show_plot(sim, plot): +def show_plot(sim, plot, plot_kwargs): plotfs = (eas_optical_density, eas_optical_histogram) inputs = ("beta_rad", "altDec", "showerEnergy") outputs = ("numPEs", "costhetaChEff") - decorators.nss_result_plot_from_file(sim, inputs, outputs, plotfs, plot) + decorators.nss_result_plot_from_file( + sim, inputs, outputs, plotfs, plot, plot_kwargs + ) diff --git a/src/nuspacesim/simulation/eas_optical/local_plots.py b/src/nuspacesim/simulation/eas_optical/local_plots.py index fb5a7ad..241f4bd 100644 --- a/src/nuspacesim/simulation/eas_optical/local_plots.py +++ b/src/nuspacesim/simulation/eas_optical/local_plots.py @@ -58,7 +58,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): numPEs, "$\\beta$ / $^{\\circ}$", "#PEs", - cmap=cm, + cm=cm, ) hexbin( fig, @@ -67,7 +67,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): costhetaChEff, "$\\beta$ / $^{\\circ}$", "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", - cmap=cm, + cm=cm, ) hexbin( @@ -77,7 +77,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): numPEs, "$Decay_\\mathrm{Altitude}$ / km", "#PEs", - cmap=cm, + cm=cm, ) hexbin( @@ -87,7 +87,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): costhetaChEff, "Decay_\\mathrm{Altitude}$ / km", "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", - cmap=cm, + cm=cm, ) hexbin( @@ -97,7 +97,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): numPEs, "$E_\\mathrm{shower}$ / 100 PeV", "#PEs", - cmap=cm, + cm=cm, ) hexbin( @@ -107,7 +107,7 @@ def eas_optical_density(inputs, results, *args, **kwargs): costhetaChEff, "$E_\\mathrm{shower}$ / 100 PeV", "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", - cmap=cm, + cm=cm, ) fig.suptitle("EAS Optical Cherenkov properties.") diff --git a/src/nuspacesim/simulation/geometry/region_geometry.py b/src/nuspacesim/simulation/geometry/region_geometry.py index 943e335..aadf22a 100644 --- a/src/nuspacesim/simulation/geometry/region_geometry.py +++ b/src/nuspacesim/simulation/geometry/region_geometry.py @@ -283,8 +283,10 @@ def mcintegral( return mcintegral, mcintegralgeoonly, numEvPass -def show_plot(sim, plot): +def show_plot(sim, plot, plot_kwargs): plotfs = tuple([geom_beta_tr_hist]) inputs = tuple([0]) outputs = ("beta_rad", "theta_rad", "path_len") - decorators.nss_result_plot_from_file(sim, inputs, outputs, plotfs, plot) + decorators.nss_result_plot_from_file( + sim, inputs, outputs, plotfs, plot, plot_kwargs + ) diff --git a/src/nuspacesim/simulation/taus/taus.py b/src/nuspacesim/simulation/taus/taus.py index f4c7787..7a5ae31 100644 --- a/src/nuspacesim/simulation/taus/taus.py +++ b/src/nuspacesim/simulation/taus/taus.py @@ -176,8 +176,10 @@ def __call__(self, betas, log_e_nu, *args, **kwargs): return tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb -def show_plot(sim, plot): +def show_plot(sim, plot, plot_kwargs): inputs = ("beta_rad", "log_e_nu") outputs = ("tauBeta", "tauLorentz", "tauEnergy", "showerEnergy", "tauExitProb") plotfs = (taus_density_beta, taus_histogram, taus_pexit, taus_overview) - decorators.nss_result_plot_from_file(sim, inputs, outputs, plotfs, plot) + decorators.nss_result_plot_from_file( + sim, inputs, outputs, plotfs, plot, plot_kwargs + ) diff --git a/src/nuspacesim/utils/decorators.py b/src/nuspacesim/utils/decorators.py index a84a24a..7918500 100644 --- a/src/nuspacesim/utils/decorators.py +++ b/src/nuspacesim/utils/decorators.py @@ -218,8 +218,7 @@ def wrapper_f( return decorator_plot -def nss_result_plot_from_file(sim, inputs, outputs, plotfs, plot): - +def nss_result_plot_from_file(sim, inputs, outputs, plotfs, plot, plot_kwargs): f_input = tuple() if inputs is None else tuple(sim[i] for i in inputs) results = tuple() if outputs is None else tuple(sim[o] for o in outputs) @@ -227,7 +226,7 @@ def nss_result_plot_from_file(sim, inputs, outputs, plotfs, plot): def f(*args, **kwargs): return results - f(None, *f_input, plot=plot) + f(None, *f_input, plot=plot, kwargs=plot_kwargs) def ensure_plot_registry(*plot_fs): diff --git a/src/nuspacesim/utils/plots.py b/src/nuspacesim/utils/plots.py index 6970489..2b7f2da 100644 --- a/src/nuspacesim/utils/plots.py +++ b/src/nuspacesim/utils/plots.py @@ -38,7 +38,7 @@ __all__ = ["dashboard", "energy_histograms", "show_plot"] -def hexbin(fig, ax, x, y, xlab, ylab, cmap="viridis", logx=True, logy=True): +def hexbin(fig, ax, x, y, xlab, ylab, cm="viridis", logx=True, logy=True): xf = np.log10 if logx else lambda q: q yf = np.log10 if logy else lambda q: q @@ -51,7 +51,7 @@ def hexbin(fig, ax, x, y, xlab, ylab, cmap="viridis", logx=True, logy=True): m = xmask & ymask im = ax.hexbin( - x=xf(x[m]), y=yf(y[m]), gridsize=25, mincnt=1, cmap=cmap, edgecolors="none" + x=xf(x[m]), y=yf(y[m]), gridsize=25, mincnt=1, cmap=cm, edgecolors="none" ) ax.set_xlabel(xl) @@ -62,7 +62,7 @@ def hexbin(fig, ax, x, y, xlab, ylab, cmap="viridis", logx=True, logy=True): cbar.set_label("Counts") -def hist2d(fig, ax, x, y, xlab, ylab, cmap="jet", logx=True, logy=True): +def hist2d(fig, ax, x, y, xlab, ylab, cm="viridis", logx=True, logy=True): xf = np.log10 if logx else lambda q: q yf = np.log10 if logy else lambda q: q @@ -74,7 +74,7 @@ def hist2d(fig, ax, x, y, xlab, ylab, cmap="jet", logx=True, logy=True): ymask = y > 0 if logy else np.full(y.shape, True) m = xmask & ymask - _, _, _, im = ax.hist2d(x=xf(x[m]), y=yf(y[m]), bins=(50, 50), cmin=1, cmap=cmap) + _, _, _, im = ax.hist2d(x=xf(x[m]), y=yf(y[m]), bins=(50, 50), cmin=1, cmap=cm) ax.set_xlabel(xl) ax.set_ylabel(yl) @@ -84,37 +84,55 @@ def hist2d(fig, ax, x, y, xlab, ylab, cmap="jet", logx=True, logy=True): cbar.set_label("Counts") -def dashboard(sim): +def dashboard(sim, plot_kwargs={}): """Full dashboard of plots""" + if plot_kwargs: + if "default_color" in plot_kwargs: + c1, c2, c3 = ( + "C{}".format(plot_kwargs.get("default_color")), + "C{}".format(plot_kwargs.get("default_color") + 1), + "C{}".format(plot_kwargs.get("default_color") + 2), + ) + if "default_colormap" in plot_kwargs: + cm = plot_kwargs.get("default_colormap") + else: + c1, c2, c3 = "C0", "C1", "C2" + cm = "viridis" fig, ax = plt.subplots(3, 4, figsize=(14, 8), constrained_layout=True) - energy_histograms(sim, fig, ax[0, 0]) - tau_pexit_hist(sim, fig, ax[1, 0]) - tau_lorentz(sim, fig, ax[2, 0]) + energy_histograms(sim, fig, ax[0, 0], [c1, c2, c3]) + tau_pexit_hist(sim, fig, ax[1, 0], c1) + tau_lorentz(sim, fig, ax[2, 0], cm) - betas_histogram(sim, fig, ax[0, 1]) - tau_pexit_density(sim, fig, ax[1, 1]) - decay_altitude(sim, fig, ax[2, 1]) + betas_histogram(sim, fig, ax[0, 1], c1) + tau_pexit_density(sim, fig, ax[1, 1], cm) + decay_altitude(sim, fig, ax[2, 1], cm) # decay_altitude_hist(sim, fig, ax[0, 2]) - num_photo_electrons_hist(sim, fig, ax[0, 2]) - num_photo_electrons_density(sim, fig, ax[1, 2]) - num_photo_electrons_altitude(sim, fig, ax[2, 2]) + num_photo_electrons_hist(sim, fig, ax[0, 2], c1) + num_photo_electrons_density(sim, fig, ax[1, 2], cm) + num_photo_electrons_altitude(sim, fig, ax[2, 2], cm) # eas_input_density(sim, fig, ax[0, 3]) - cherenkov_angle_hist(sim, fig, ax[0, 3]) - eas_results_density(sim, fig, ax[1, 3]) - cherenkov_angle(sim, fig, ax[2, 3]) + cherenkov_angle_hist(sim, fig, ax[0, 3], c1) + eas_results_density(sim, fig, ax[1, 3], cm) + cherenkov_angle(sim, fig, ax[2, 3], cm) # tau_betas(sim, fig, ax[1, 2]) fig.suptitle("Nuspacesim Results Dashboard", size="x-large") + if "pop_up" not in plot_kwargs: + plt.show() + elif "pop_up" in plot_kwargs and plot_kwargs.get("pop_up") is True: + plt.show() + if plot_kwargs.get("save_to_file") is True: + fig.savefig( + plot_kwargs.get("filename") + "_dashboard." + plot_kwargs.get("save_as") + ) - plt.show() - -def energy_histograms(sim, fig, ax=None): +def energy_histograms(sim, fig, ax, c): energy_bins = np.arange( np.round(np.min(np.log10(sim["showerEnergy"]) + 17), 1) - 0.1, @@ -124,21 +142,21 @@ def energy_histograms(sim, fig, ax=None): ax.hist( x=sim["log_e_nu"] + 9, bins=energy_bins, - color="C0", + color=c[0], alpha=0.6, label=r"$E_{\nu_\tau}$", ) ax.hist( x=np.log10(sim["tauEnergy"]) + 9, bins=energy_bins, - color="C1", + color=c[1], alpha=0.6, label=r"$E_\tau$", ) ax.hist( x=np.log10(sim["showerEnergy"]) + 17, bins=energy_bins, - color="C2", + color=c[2], alpha=0.6, label=r"$E_\mathrm{shower}$", ) @@ -148,7 +166,7 @@ def energy_histograms(sim, fig, ax=None): ax.set_ylabel(r"Counts") -def betas_histogram(sim, fig, ax): +def betas_histogram(sim, fig, ax, c): beta_bins = np.arange( np.min(np.degrees(sim["beta_rad"])) - 1, @@ -156,165 +174,168 @@ def betas_histogram(sim, fig, ax): 1, ) - ax.hist(x=np.degrees(sim["beta_rad"]), bins=beta_bins) + ax.hist(x=np.degrees(sim["beta_rad"]), bins=beta_bins, color=c) ax.set_xlabel(r"Earth emergence angle $\beta$ / $^{\circ}$") ax.set_ylabel("Counts") ax.set_yscale("log") ax.set_xlim(min(beta_bins), max(beta_bins)) -def tau_lorentz(sim, fig, ax): - hist2d( +def tau_lorentz(sim, fig, ax, cm): + hexbin( fig, ax, np.degrees(sim["beta_rad"]), sim["tauLorentz"], r"$\beta$", r"$τ_\mathrm{Lorentz}$", + cm=cm, logx=False, logy=True, ) -def tau_pexit_hist(sim, fig, ax): - ax.hist(sim["tauExitProb"], 100, log=True, facecolor="g") +def tau_pexit_hist(sim, fig, ax, c): + ax.hist(sim["tauExitProb"], 100, log=True, color=c) ax.set_ylabel("Counts") ax.set_xlabel(r"$\log(P_\mathrm{exit}(\tau))$") -def tau_pexit_density(sim, fig, ax): - hist2d( +def tau_pexit_density(sim, fig, ax, cm): + hexbin( fig, ax, np.degrees(sim["beta_rad"]), sim["tauExitProb"], r"$\beta$", r"$P_\mathrm{exit}(\tau)$", - cmap="viridis", + cm=cm, logx=False, logy=True, ) -def tau_betas(sim, fig, ax): - hist2d( +def tau_betas(sim, fig, ax, cm): + hexbin( fig, ax, sim["beta_rad"], sim["tauBeta"], r"$\beta$", r"$τ_β$", + cm=cm, logx=False, logy=True, ) -def decay_altitude_hist(sim, fig, ax): - ax.hist(sim["altDec"], 100, log=True) +def decay_altitude_hist(sim, fig, ax, c): + ax.hist(sim["altDec"], 100, log=True, color=c) ax.set_ylabel("Counts") ax.set_xlabel("decay_altitude log(km)") -def num_photo_electrons_hist(sim, fig, ax): +def num_photo_electrons_hist(sim, fig, ax, c): m = sim["numPEs"] != 0 - ax.hist(np.log(sim["numPEs"][m]), 100, log=False) + ax.hist(np.log(sim["numPEs"][m]), 100, log=False, color=c) ax.set_ylabel("Counts") ax.set_xlabel("log(numPEs)") -def num_photo_electrons_density(sim, fig, ax): - hist2d( +def num_photo_electrons_density(sim, fig, ax, cm): + hexbin( fig, ax, sim["numPEs"], np.degrees(sim["beta_rad"]), "numPEs", "β", - "plasma", + cm=cm, logx=True, logy=False, ) -def num_photo_electrons_altitude(sim, fig, ax): - hist2d( +def num_photo_electrons_altitude(sim, fig, ax, cm): + hexbin( fig, ax, sim["numPEs"], sim["altDec"], "numPEs", "decay_altitude km", - "plasma", + cm=cm, logx=True, logy=True, ) -def decay_altitude(sim, fig, ax): - hist2d( +def decay_altitude(sim, fig, ax, cm): + hexbin( fig, ax, np.degrees(sim["beta_rad"]), sim["altDec"], "β", "decay_altitude km", - cmap="viridis", + cm=cm, logx=False, logy=True, ) -def cherenkov_angle_hist(sim, fig, ax): - ax.hist(np.degrees(np.arccos(sim["costhetaChEff"])), 100, log=True) +def cherenkov_angle_hist(sim, fig, ax, c): + ax.hist(np.degrees(np.arccos(sim["costhetaChEff"])), 100, log=True, color=c) ax.set_ylabel("Counts") ax.set_xlabel("θ_chEff") -def eas_input_density(sim, fig, ax): - hist2d( +def eas_input_density(sim, fig, ax, cm): + hexbin( fig, ax, np.degrees(sim["beta_rad"]), sim["altDec"], "beta_rad", "decay alt km", - cmap="jet", + cm=cm, logx=False, logy=True, ) -def cherenkov_angle(sim, fig, ax): - hist2d( +def cherenkov_angle(sim, fig, ax, cm): + hexbin( fig, ax, np.degrees(np.arccos(sim["costhetaChEff"])), np.degrees(sim["beta_rad"]), "θ_chEff", "β", - cmap="jet", + cm=cm, logx=False, logy=False, ) -def eas_results_density(sim, fig, ax): - hist2d( +def eas_results_density(sim, fig, ax, cm): + hexbin( fig, ax, np.degrees(np.arccos(sim["costhetaChEff"])), sim["numPEs"], "θ_chEff", "NumPEs", - cmap="jet", + cm=cm, logx=False, logy=False, ) @decorators.ensure_plot_registry(dashboard) -def show_plot(sim, plot): +def show_plot(sim, plot, plot_kwargs={}): + if dashboard.__name__ in plot: - dashboard(sim) + dashboard(sim, plot_kwargs) # dashboard(sim, plot) From a42d49829150bad1e39fbc87533d2e3801deca73 Mon Sep 17 00:00:00 2001 From: smayotte Date: Fri, 6 May 2022 14:21:47 -0600 Subject: [PATCH 06/11] implementation of PlotWrapper class to handle formatting of plots created with nuSpaceSim --- sample_plot_config.ini | 37 +- src/nuspacesim/apps/cli.py | 30 +- src/nuspacesim/compute.py | 15 +- .../simulation/eas_optical/__init__.py | 2 +- src/nuspacesim/simulation/eas_optical/eas.py | 43 +- .../simulation/eas_optical/local_plots.py | 300 ++++++++--- .../simulation/geometry/local_plots.py | 81 +-- .../simulation/geometry/region_geometry.py | 2 +- .../simulation/spectra/local_plots.py | 46 +- src/nuspacesim/simulation/taus/local_plots.py | 490 ++++++++---------- src/nuspacesim/simulation/taus/taus.py | 43 +- src/nuspacesim/utils/__init__.py | 6 +- src/nuspacesim/utils/decorators.py | 52 +- src/nuspacesim/utils/plot_wrapper.py | 137 +++++ src/nuspacesim/utils/plots.py | 308 ++--------- test/utils/test_decorators.py | 20 +- 16 files changed, 831 insertions(+), 781 deletions(-) create mode 100644 src/nuspacesim/utils/plot_wrapper.py diff --git a/sample_plot_config.ini b/sample_plot_config.ini index 29dbeda..b5fe70d 100644 --- a/sample_plot_config.ini +++ b/sample_plot_config.ini @@ -1,11 +1,11 @@ [General] -fig_width = 10 -fig_height = 8 -pop_up = no +#standard_plot_size = (8,7) (to be implemented) +pop_up = yes save_to_file = yes save_as = pdf default_color = 0 # as in 'C0' +default_markersize = 3 default_colormap = viridis [Spectra] @@ -15,18 +15,27 @@ spectra_histogram = yes geom_beta_tr_hist = yes path_length_to_detector = yes # interaction_height = no (to be implemented) -# geometry_overview = no (to be implemented) +# geometry_overview = no (to be implemented) [Taus] -taus_density_beta = yes -taus_pexit = yes -taus_histogram = yes -taus_overview = yes +energy_hists = yes +beta_hist = yes +tau_beta_hist = yes +tau_lorentz_hist = yes +tau_exit_prob_hist = yes +tau_beta_hex = yes +tau_lorentz_hex = yes +tau_exit_prob_hex = yes [EASOpitcal] -eas_optical_density = yes -eas_optical_histogram = yes -# eas_optical_overview = no (to be implemented) +numpes_vs_beta = yes +altdec_vs_numpes = yes +showerEnergy_vs_numPEs = yes +costhetacheff_vs_beta = yes +altDec_vs_costhetacheff = yes +showerEnergy_vs_costhetacheff = yes +numpes_hist = yes +costhetacheff_hist = yes [Detector] # event_count_at_detector = no (to be implemented) @@ -35,3 +44,9 @@ eas_optical_histogram = yes [Overview] dashboard = yes +taus_density_beta_overview = yes +taus_histograms_overview = yes +taus_pexit_overview = yes +taus_overview = yes +eas_optical_density_overview = yes +eas_optical_histogram_overview = yes diff --git a/src/nuspacesim/apps/cli.py b/src/nuspacesim/apps/cli.py index 0307d19..24eddcf 100644 --- a/src/nuspacesim/apps/cli.py +++ b/src/nuspacesim/apps/cli.py @@ -210,12 +210,11 @@ def run( plot_kwargs["filename"] = output elif (plot and plotsettings) or (plotall and plotsettings): plot_kwargs = { - "figsize": (plotsettings[0], plotsettings[1]), - "save_to_file": plotsettings[2], - "save_as": plotsettings[3], - "pop_up": plotsettings[4], - "default_color": plotsettings[5], - "default_colormap": plotsettings[6], + "save_to_file": plotsettings[0], + "save_as": plotsettings[1], + "pop_up": plotsettings[2], + "default_color": plotsettings[3], + "default_colormap": plotsettings[4], } if output is not None: for ext in [".h5", ".hdf5", ".fits"]: @@ -301,8 +300,8 @@ def create_config(filename: str, numtrajs: float, monospectrum, powerspectrum) - @click.option( "-ps", "--plotsettings", - nargs=7, - type=click.Tuple([int, int, bool, str, bool, int, str]), + nargs=5, + type=click.Tuple([bool, str, bool, int, str]), default=None, help="Save plot supplied with -p with given file extension, optionally suppress pop_up", ) @@ -372,12 +371,11 @@ def show_plot( plot_kwargs["filename"] = plot_filename elif (plot and plotsettings) or (plotall and plotsettings): plot_kwargs = { - "figsize": (plotsettings[0], plotsettings[1]), - "save_to_file": plotsettings[2], - "save_as": plotsettings[3], - "pop_up": plotsettings[4], - "default_color": plotsettings[5], - "default_colormap": plotsettings[6], + "save_to_file": plotsettings[0], + "save_as": plotsettings[1], + "pop_up": plotsettings[2], + "default_color": plotsettings[3], + "default_colormap": plotsettings[4], "filename": plot_filename, } else: @@ -394,10 +392,6 @@ def read_plot_config(filename): cfg = configparser.ConfigParser() cfg.read(filename) plot_kwargs = { - "figsize": ( - cfg["General"].getint("fig_width"), - cfg["General"].getint("fig_height"), - ), "save_as": cfg["General"]["save_as"], "pop_up": cfg["General"].getboolean("pop_up"), "save_to_file": cfg["General"].getboolean("save_to_file"), diff --git a/src/nuspacesim/compute.py b/src/nuspacesim/compute.py index 6ca5cc3..a17560f 100644 --- a/src/nuspacesim/compute.py +++ b/src/nuspacesim/compute.py @@ -166,7 +166,7 @@ def add_meta(self, *args, **kwargs): logv("Computing [green] Geometries.[/]") beta_tr, thetaArr, pathLenArr = geom( - config.simulation.N, store=sw, plot=to_plot, kwargs=plot_kwargs + config.simulation.N, store=sw, plot=to_plot, plot_kwargs=plot_kwargs ) logv( f"\t[blue]Threw {config.simulation.N} neutrinos. {beta_tr.size} were valid.[/]" @@ -174,23 +174,28 @@ def add_meta(self, *args, **kwargs): logv("Computing [green] Energy Spectra.[/]") log_e_nu, mc_spec_norm, spec_weights_sum = spec( - beta_tr.shape[0], store=sw, plot=to_plot, kwargs=plot_kwargs + beta_tr.shape[0], store=sw, plot=to_plot, plot_kwargs=plot_kwargs ) logv("Computing [green] Taus.[/]") tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = tau( - beta_tr, log_e_nu, store=sw, plot=to_plot, kwargs=plot_kwargs + beta_tr, log_e_nu, store=sw, plot=to_plot, plot_kwargs=plot_kwargs ) logv("Computing [green] Decay Altitudes.[/]") altDec, lenDec = eas.altDec( - beta_tr, tauBeta, tauLorentz, store=sw, plot=to_plot, kwargs=plot_kwargs + beta_tr, tauBeta, tauLorentz, store=sw, plot=to_plot, plot_kwargs=plot_kwargs ) if config.detector.method == "Optical" or config.detector.method == "Both": logv("Computing [green] EAS Optical Cherenkov light.[/]") numPEs, costhetaChEff = eas( - beta_tr, altDec, showerEnergy, store=sw, plot=to_plot, kwargs=plot_kwargs + beta_tr, + altDec, + showerEnergy, + store=sw, + plot=to_plot, + plot_kwargs=plot_kwargs, ) logv("Computing [green] Optical Monte Carlo Integral.[/]") diff --git a/src/nuspacesim/simulation/eas_optical/__init__.py b/src/nuspacesim/simulation/eas_optical/__init__.py index bfff857..a73022b 100644 --- a/src/nuspacesim/simulation/eas_optical/__init__.py +++ b/src/nuspacesim/simulation/eas_optical/__init__.py @@ -53,7 +53,7 @@ cphotang """ -__all__ = ["EAS", "atmospheric_models"] +__all__ = ["EAS", "atmospheric_models", "local_plots"] from . import atmospheric_models from .eas import EAS diff --git a/src/nuspacesim/simulation/eas_optical/eas.py b/src/nuspacesim/simulation/eas_optical/eas.py index 99a9bda..76c5b68 100644 --- a/src/nuspacesim/simulation/eas_optical/eas.py +++ b/src/nuspacesim/simulation/eas_optical/eas.py @@ -36,7 +36,20 @@ from ...config import NssConfig from ...utils import decorators from .cphotang import CphotAng -from .local_plots import eas_optical_density, eas_optical_histogram +from .local_plots import ( + altdec_vs_beta, + altdec_vs_costhetacheff, + altdec_vs_numpes, + costhetacheff_hist, + costhetacheff_vs_beta, + costhetacheff_vs_numpes, + eas_optical_density_overview, + eas_optical_histogram_overview, + numpes_hist, + numpes_vs_beta, + showerenergy_vs_costhetacheff, + showerenergy_vs_numpes, +) __all__ = ["EAS", "show_plot"] @@ -74,7 +87,19 @@ def altDec(self, beta, tauBeta, tauLorentz, u=None, *args, **kwargs): return altDec, lenDec - @decorators.nss_result_plot(eas_optical_density, eas_optical_histogram) + @decorators.nss_result_plot( + numpes_vs_beta, + altdec_vs_numpes, + altdec_vs_beta, + showerenergy_vs_numpes, + costhetacheff_vs_beta, + altdec_vs_costhetacheff, + showerenergy_vs_costhetacheff, + numpes_hist, + costhetacheff_hist, + eas_optical_density_overview, + eas_optical_histogram_overview, + ) @decorators.nss_result_store("numPEs", "costhetaChEff") def __call__(self, beta, altDec, showerEnergy, *args, **kwargs): """ @@ -117,7 +142,19 @@ def __call__(self, beta, altDec, showerEnergy, *args, **kwargs): def show_plot(sim, plot, plot_kwargs): - plotfs = (eas_optical_density, eas_optical_histogram) + plotfs = ( + numpes_vs_beta, + altdec_vs_numpes, + altdec_vs_beta, + showerenergy_vs_numpes, + costhetacheff_vs_beta, + altdec_vs_costhetacheff, + showerenergy_vs_costhetacheff, + numpes_hist, + costhetacheff_hist, + eas_optical_density_overview, + eas_optical_histogram_overview, + ) inputs = ("beta_rad", "altDec", "showerEnergy") outputs = ("numPEs", "costhetaChEff") decorators.nss_result_plot_from_file( diff --git a/src/nuspacesim/simulation/eas_optical/local_plots.py b/src/nuspacesim/simulation/eas_optical/local_plots.py index 241f4bd..bf332b9 100644 --- a/src/nuspacesim/simulation/eas_optical/local_plots.py +++ b/src/nuspacesim/simulation/eas_optical/local_plots.py @@ -32,125 +32,253 @@ # POSSIBILITY OF SUCH DAMAGE. import numpy as np -from matplotlib import pyplot as plt -from ...utils.plots import hexbin +from ...utils.plot_wrapper import PlotWrapper -def eas_optical_density(inputs, results, *args, **kwargs): - r"""Plot some density plots""" +def numpes_vs_beta(inputs, results, fig, ax, *args, **kwargs): + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 + ) + im = fig.hexbin( + ax, + x=np.degrees(betas), + y=numPEs, + gs=len(binning_b), + logx=True, + logy=True, + ) + fig.make_labels( + ax, + "$\\beta$ / $^{\\circ}$", + "#PEs", + clabel="Counts", + im=im, + logx=True, + logy=True, + ) + +def altdec_vs_numpes(inputs, results, fig, ax, *args, **kwargs): _, betas, altDec, showerEnergy = inputs numPEs, costhetaChEff = results - plotting_opts = kwargs.get("kwargs") - if "default_colormap" in plotting_opts: - cm = plotting_opts.get("default_colormap") - else: - cm = "viridis" + im = fig.hexbin( + ax, + x=altDec, + y=numPEs, + gs=25, + logx=True, + logy=True, + ) + fig.make_labels( + ax, + "$Decay_\\mathrm{Altitude}$ / km", + "#PEs", + clabel="Counts", + im=im, + logx=True, + logy=True, + ) - fig, ax = plt.subplots(2, 3, figsize=(15, 8), constrained_layout=True) - hexbin( - fig, - ax[0, 0], - np.degrees(betas), - numPEs, +def altdec_vs_beta(inputs, results, fig, ax, *args, **kwargs): + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 + ) + im = fig.hexbin( + ax, + x=np.degrees(betas), + y=altDec, + gs=len(binning_b), + logx=True, + logy=True, + ) + fig.make_labels( + ax, "$\\beta$ / $^{\\circ}$", + "$Decay_\\mathrm{Altitude}$ / km", + clabel="Counts", + im=im, + logx=True, + logy=True, + ) + + +def showerenergy_vs_numpes(inputs, results, fig, ax, *args, **kwargs): + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + + im = fig.hexbin( + ax, + x=showerEnergy, + y=numPEs, + gs=25, + logx=True, + logy=True, + ) + fig.make_labels( + ax, + "$E_\\mathrm{shower}$ / 100 PeV", "#PEs", - cm=cm, + clabel="Counts", + im=im, + logx=True, + logy=True, + ) + + +def costhetacheff_vs_beta(inputs, results, fig, ax, *args, **kwargs): + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 ) - hexbin( - fig, - ax[1, 0], - np.degrees(betas), - costhetaChEff, + im = fig.hexbin( + ax, + x=np.degrees(betas), + y=costhetaChEff, + gs=len(binning_b), + logx=True, + logy=True, + ) + fig.make_labels( + ax, "$\\beta$ / $^{\\circ}$", "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", - cm=cm, + clabel="Counts", + im=im, + logx=True, + logy=True, ) - hexbin( - fig, - ax[0, 1], - altDec, - numPEs, - "$Decay_\\mathrm{Altitude}$ / km", + +def costhetacheff_vs_numpes(inputs, results, fig, ax, *args, **kwargs): + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + im = fig.hexbin( + ax, + x=numPEs, + y=costhetaChEff, + gs=25, + logx=True, + logy=True, + ) + fig.make_labels( + ax, "#PEs", - cm=cm, + "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", + clabel="Counts", + im=im, + logx=True, + logy=True, ) - hexbin( - fig, - ax[1, 1], - altDec, - costhetaChEff, - "Decay_\\mathrm{Altitude}$ / km", + +def altdec_vs_costhetacheff(inputs, results, fig, ax, *args, **kwargs): + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + im = fig.hexbin( + ax, + x=altDec, + y=costhetaChEff, + gs=25, + logx=True, + logy=True, + ) + fig.make_labels( + ax, + "$Decay_\\mathrm{Altitude}$ / km", "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", - cm=cm, + clabel="Counts", + im=im, + logx=True, + logy=True, ) - hexbin( - fig, - ax[0, 2], - showerEnergy, - numPEs, + +def showerenergy_vs_costhetacheff(inputs, results, fig, ax, *args, **kwargs): + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + im = fig.hexbin( + ax, + x=showerEnergy, + y=costhetaChEff, + gs=25, + logx=True, + logy=True, + ) + fig.make_labels( + ax, "$E_\\mathrm{shower}$ / 100 PeV", + "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", + clabel="Counts", + im=im, + logx=True, + logy=True, + ) + + +def numpes_hist(inputs, results, fig, ax, *args, **kwargs): + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + ax.hist( + x=numPEs, + bins=np.linspace(min(numPEs), max(numPEs), 100), + color=fig.params["default_colors"][0], + ) + fig.make_labels( + ax, "#PEs", - cm=cm, + "Counts", ) - hexbin( - fig, - ax[1, 2], - showerEnergy, - costhetaChEff, - "$E_\\mathrm{shower}$ / 100 PeV", + +def costhetacheff_hist(inputs, results, fig, ax, *args, **kwargs): + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + ax.hist( + x=costhetaChEff, + bins=np.linspace(min(costhetaChEff), max(costhetaChEff), 100), + color=fig.params["default_colors"][0], + ) + fig.make_labels( + ax, "$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)", - cm=cm, + "Counts", ) - fig.suptitle("EAS Optical Cherenkov properties.") - if plotting_opts.get("pop_up") is True: - plt.show() - if plotting_opts.get("save_to_file") is True: - fig.savefig( - plotting_opts.get("filename") - + "_eas_optical_density." - + plotting_opts.get("save_as") - ) +def eas_optical_density_overview(inputs, results, plot_kwargs, *args, **kwargs): + r"""Plot some density plots""" + + _, betas, altDec, showerEnergy = inputs + numPEs, costhetaChEff = results + fig = PlotWrapper(plot_kwargs, 2, 3, (15, 8), "EAS Optical Cherenkov properties") + numpes_vs_beta(inputs, results, fig, fig.ax[0, 0]) + altdec_vs_numpes(inputs, results, fig, fig.ax[0, 1]) + showerenergy_vs_numpes(inputs, results, fig, fig.ax[0, 2]) + costhetacheff_vs_beta(inputs, results, fig, fig.ax[1, 0]) + altdec_vs_costhetacheff(inputs, results, fig, fig.ax[1, 1]) + showerenergy_vs_costhetacheff(inputs, results, fig, fig.ax[1, 2]) + fig.close( + "eas_optical_density_overview", fig.params["save_to_file"], fig.params["pop_up"] + ) -def eas_optical_histogram(inputs, results, *args, **kwargs): +def eas_optical_histogram_overview(inputs, results, plot_kwargs, *args, **kwargs): r"""Plot some histograms""" - # eas_self, betas, altDec, showerEnergy = inputs - plotting_opts = kwargs.get("kwargs") - if "default_color" in plotting_opts: - c = "C{}".format(plotting_opts.get("default_color")) - else: - c = "C0" + eas_self, betas, altDec, showerEnergy = inputs numPEs, costhetaChEff = results - fig, ax = plt.subplots(2, 1, constrained_layout=True) - - ax[0].hist(numPEs, 100, log=True, facecolor=c) - ax[0].set_xlabel("log(#PEs)") - ax[0].set_ylabel("Counts") - - ax[1].hist(costhetaChEff, 100, log=True, facecolor=c) - ax[1].set_xlabel("$\\cos(\\theta_\\mathrm{Cherenkov}$ / rad)") - ax[1].set_ylabel("Counts") - - fig.suptitle("EAS Optical Cherenkov property Histograms") - if "pop_up" not in plotting_opts: - plt.show() - elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: - plt.show() - if plotting_opts.get("save_to_file") is True: - fig.savefig( - plotting_opts.get("filename") - + "_eas_optical_histogram." - + plotting_opts.get("save_as") - ) + fig = PlotWrapper( + plot_kwargs, 2, 1, title="EAS Optical Cherenkov property Histograms" + ) + numpes_hist(inputs, results, fig, fig.ax[0]) + costhetacheff_hist(inputs, results, fig, fig.ax[1]) + fig.close("eas_optical_histogram", fig.params["save_to_file"], fig.params["pop_up"]) diff --git a/src/nuspacesim/simulation/geometry/local_plots.py b/src/nuspacesim/simulation/geometry/local_plots.py index b8e725d..27711d7 100644 --- a/src/nuspacesim/simulation/geometry/local_plots.py +++ b/src/nuspacesim/simulation/geometry/local_plots.py @@ -31,75 +31,46 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -import matplotlib import numpy as np -from matplotlib import pyplot as plt +from ...utils.plot_wrapper import PlotWrapper -def geom_beta_tr_hist(inputs, results, *args, **kwargs): + +def geom_beta_tr_hist(inputs, results, fig, *args, **kwargs): r"""Plot a histgram of beta trajectories.""" _ = inputs betas, _, _ = results - plotting_opts = kwargs.get("kwargs") - if "default_color" in plotting_opts: - c = "C{}".format(plotting_opts.get("default_color")) - else: - c = "C0" - - fig = plt.figure(figsize=(8, 7), constrained_layout=True) - plt.hist(np.degrees(betas), 50, color=c) - plt.xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") - plt.ylabel("Counts") - plt.title(f"Histogram of {betas.size} $\\beta$ angles") - if "pop_up" not in plotting_opts: - plt.show() - elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: - plt.show() - if plotting_opts.get("save_to_file") is True: - fig.savefig( - plotting_opts.get("filename") - + "_geom_beta_tr_hist." - + plotting_opts.get("save_as") - ) + fig.ax.hist( + x=np.degrees(betas), + bins=np.linspace(min(np.degrees(betas)), max(np.degrees(betas)), 50), + color=fig.params["default_colors"][0], + ) + fig.make_labels( + fig.ax, + "Earth emergence angle $\\beta$ / $^{\\circ}$", + "Counts", + ) -def path_length_to_detector(inputs, results, *args, **kwargs): +def path_length_to_detector(inputs, results, fig, *args, **kwargs): r"""Plot a histgram of beta trajectories.""" _ = inputs betas, _, path_lens = results - plotting_opts = kwargs.get("kwargs") - if "default_colormap" in plotting_opts: - cm = plotting_opts.get("default_colormap") - else: - cm = "viridis" - binning_b = np.arange( np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 ) - fig, ax = plt.subplots(figsize=kwargs.get("figsize"), constrained_layout=True) - im = ax.hexbin( - np.degrees(betas), - path_lens, - gridsize=len(binning_b), - yscale="log", - mincnt=1, - cmap=cm, - edgecolors="none", + im = fig.hexbin( + fig.ax, + x=np.degrees(betas), + y=path_lens, + gs=len(binning_b), + ) + fig.make_labels( + fig.ax, + "Earth emergence angle $\\beta$ / $^{\\circ}$", + "Path length to detector / km", + clabel="Counts", + im=im, ) - ax.set_xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") - ax.set_ylabel("Path length to detector / km") - cbar = fig.colorbar(im, ax=ax, pad=0.0) - cbar.set_label("Counts") - - if "pop_up" not in plotting_opts: - plt.show() - elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: - plt.show() - if plotting_opts.get("save_to_file") is True: - fig.savefig( - plotting_opts.get("filename") - + "_path_length_to_detector." - + plotting_opts.get("save_as") - ) diff --git a/src/nuspacesim/simulation/geometry/region_geometry.py b/src/nuspacesim/simulation/geometry/region_geometry.py index aadf22a..9f1f0a1 100644 --- a/src/nuspacesim/simulation/geometry/region_geometry.py +++ b/src/nuspacesim/simulation/geometry/region_geometry.py @@ -284,7 +284,7 @@ def mcintegral( def show_plot(sim, plot, plot_kwargs): - plotfs = tuple([geom_beta_tr_hist]) + plotfs = tuple([geom_beta_tr_hist, path_length_to_detector]) inputs = tuple([0]) outputs = ("beta_rad", "theta_rad", "path_len") decorators.nss_result_plot_from_file( diff --git a/src/nuspacesim/simulation/spectra/local_plots.py b/src/nuspacesim/simulation/spectra/local_plots.py index 735a529..a9e340d 100644 --- a/src/nuspacesim/simulation/spectra/local_plots.py +++ b/src/nuspacesim/simulation/spectra/local_plots.py @@ -31,37 +31,27 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -from matplotlib import pyplot as plt +import numpy as np +from ...utils.plot_wrapper import PlotWrapper -def spectra_histogram(inputs, results, *args, **kwargs): + +def spectra_histogram(inputs, results, fig, ax, *args, **kwargs): r"""Plot some histograms""" N, spectrum = inputs log_e_nu = results - plotting_opts = kwargs.get("kwargs") - if "default_color" in plotting_opts: - c = "C{}".format(plotting_opts.get("default_color")) - else: - c = "C0" - - fig, ax = plt.subplots(2, 1, figsize=(8, 8), sharex=True) - ax[0].hist(log_e_nu, 100, log=False, color=c) - ax[0].set_ylabel("Counts") - - ax[1].hist(log_e_nu, 100, log=True, color=c) - ax[1].set_xlabel("$\\log_{{10}}\\left(E_\\nu\\right)$") - ax[1].set_ylabel("Counts") - - fig.suptitle(f"Energy Spectra Histogram of {N} events\n {spectrum}") - fig.tight_layout() - if "pop_up" not in plotting_opts: - plt.show() - elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: - plt.show() - if plotting_opts.get("save_to_file") is True: - fig.savefig( - plotting_opts.get("filename") - + "_spectra_histogram." - + plotting_opts.get("save_as") - ) + # log_e_nu = log_e_nu + 9 + ax.hist( + x=log_e_nu, + bins=100, + color=fig.params["default_colors"][0], + label=f"Energy spectrum histogram with {N} events\n {spectrum}", + ) + fig.make_labels( + ax, + "$E_{\\nu_\\tau}$ / $\\log_\\mathrm{10}\\left(\\frac{E}{\\mathrm{eV}}\\right)$", + "Counts", + logy_scale=True, + ) + ax.legend(loc="best") diff --git a/src/nuspacesim/simulation/taus/local_plots.py b/src/nuspacesim/simulation/taus/local_plots.py index f31da2a..144d524 100644 --- a/src/nuspacesim/simulation/taus/local_plots.py +++ b/src/nuspacesim/simulation/taus/local_plots.py @@ -32,322 +32,260 @@ # POSSIBILITY OF SUCH DAMAGE. import numpy as np -from matplotlib import pyplot as plt -from mpl_toolkits.axes_grid1 import make_axes_locatable +from ...utils.plot_wrapper import PlotWrapper -def get_profile(x, y, nbins, useStd=True, *args, **kwargs): - if sum(np.isnan(y)) > 0: - # print "Array contains NaN, removing them for profile plot" - x = x[~np.isnan(y)] - y = y[~np.isnan(y)] +r"""Single plots""" - n, _ = np.histogram(x, bins=nbins) - sy, _ = np.histogram(x, bins=nbins, weights=y) - sy2, _ = np.histogram(x, bins=nbins, weights=y * y) - mean = sy / n - std = np.sqrt(sy2 / n - mean * mean) - if not useStd: - std /= np.sqrt(n) - bincenter = (_[1:] + _[:-1]) / 2 - binwidth = bincenter - _[1:] - - return bincenter, mean, std, binwidth - - -def taus_density_beta(inputs, results, *args, **kwargs): - r"""Plot some density plots""" +def energy_hists(inputs, results, fig, ax, *args, **kwargs): _, betas, log_e_nu = inputs tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results - plotting_opts = kwargs.get("kwargs") - if "default_colormap" in plotting_opts: - cm = plotting_opts.get("default_colormap") - else: - cm = "viridis" - binning_b = np.arange( - np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 - ) - fig, ax = plt.subplots(2, 2, figsize=(10, 8), sharex=True, constrained_layout=True) - - im = None - - def hexbin(ax, x, y, xlab, xunits, ylab): - nonlocal im - im = ax.hexbin( - x=np.degrees(x), - y=np.log10(y), - gridsize=len(binning_b), - mincnt=1, - cmap=cm, - edgecolors="none", - ) - ax.set_xlabel(f"{xlab} / {xunits}") - ax.set_ylabel(f"{ylab}") - ax.set_title(f"{xlab} vs {ylab}") - - hexbin( - ax[0, 0], - betas, - tauBeta, - "$\\beta$", - "$^{\\circ}$", - "$\\log_{10}(\\tau_\\beta)$", - ) - hexbin( - ax[0, 1], - betas, - tauLorentz, - "$\\beta$", - "$^{\\circ}$", - "$\\log_{10}(\\tau_\\mathrm{Lorentz})$", - ) - hexbin( - ax[1, 0], - betas, - showerEnergy, - "$\\beta$", - "$^{\\circ}$", - "$\\log_{10}(E_\\mathrm{shower})$", - ) - hexbin( - ax[1, 1], - betas, - tauExitProb, - "$\\beta$", - "$^{\\circ}$", - "$\\log_{10}(P_\\mathrm{Exit}(\\tau))$", - ) - - fig.colorbar(im, ax=ax, label="Counts", format="%.0e") - - fig.suptitle("Tau interaction properties vs. Earth emergence angles $\\beta$") - if "pop_up" not in plotting_opts: - plt.show() - elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: - plt.show() - if plotting_opts.get("save_to_file") is True: - fig.savefig( - plotting_opts.get("filename") - + "_taus_density_beta." - + plotting_opts.get("save_as") - ) - - -def taus_histogram(inputs, results, *args, **kwargs): - r"""Plot some histograms""" - - _, _, _ = inputs - tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results - - plotting_opts = kwargs.get("kwargs") - if "default_color" in plotting_opts: - c = "C{}".format(plotting_opts.get("default_color")) - else: - c = "C0" - - fig, ax = plt.subplots(2, 2, constrained_layout=True) - - ax[0, 0].hist(tauBeta, 100, log=True, facecolor=c) - ax[0, 0].set_xlabel("$\\log_{10}(\\tau_\\beta)$") - ax[0, 1].hist(tauLorentz, 100, log=True, facecolor=c) - ax[0, 1].set_xlabel("$\\log_{10}(\\tau_\\mathrm{Lorentz})$") - ax[1, 0].hist(showerEnergy, 100, log=True, facecolor=c) - ax[1, 0].set_xlabel("$\\log_{10}(E_\\mathrm{shower})$") - ax[1, 1].hist(tauExitProb, 100, log=True, facecolor=c) - ax[1, 1].set_xlabel("$\\log_{10}(P_\\mathrm{Exit}(\\tau))$") - - fig.suptitle("$\\tau$ interaction property Histograms") - if "pop_up" not in plotting_opts: - plt.show() - elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: - plt.show() - if plotting_opts.get("save_to_file") is True: - fig.savefig( - plotting_opts.get("filename") - + "_taus_histogram." - + plotting_opts.get("save_as") - ) - - -def taus_pexit(inputs, results, *args, **kwargs): - _, betas, _ = inputs - _, _, _, _, tauExitProb = results - - plotting_opts = kwargs.get("kwargs") - if "default_color" in plotting_opts: - c = "C{}".format(plotting_opts.get("default_color")) - else: - c = "C0" - if "default_colormap" in plotting_opts: - cm = plotting_opts.get("default_colormap") - else: - cm = "viridis" - - fig, ax = plt.subplots(1, 2, figsize=(10, 5), constrained_layout=True) - binning_b = np.arange( - np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 - ) - im = ax[0].hexbin( - np.degrees(betas), - np.log10(tauExitProb), - gridsize=len(binning_b), - mincnt=1, - cmap=cm, - edgecolors="none", - ) - ax[0].set_xlabel("$\\beta$ / $^{\\circ}$") - ax[0].set_ylabel("$\\log_{10}(P_\\mathrm{Exit}(\\tau))$") - - ax[1].hist(tauExitProb, 100, log=True, facecolor=c) - ax[1].set_ylabel("$\\log(Counts)$") - ax[1].set_xlabel("$P_\\mathrm{Exit}(\\tau)$") - - divider = make_axes_locatable(ax[0]) - cax = divider.append_axes("right", size="5%", pad=0.0) - cbar = fig.colorbar(im, cax=cax) - cbar.set_label("Counts") - - fig.suptitle("$\\tau$ exit probability") - if "pop_up" not in plotting_opts: - plt.show() - elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: - plt.show() - if plotting_opts.get("save_to_file") is True: - fig.savefig( - plotting_opts.get("filename") - + "_taus_pexit." - + plotting_opts.get("save_as") - ) - - -def taus_overview(inputs, results, *args, **kwargs): - - r"""Overview plot for taus""" - plotting_opts = kwargs.get("kwargs") - if "default_color" in plotting_opts: - c1, c2, c3 = ( - "C{}".format(plotting_opts.get("default_color")), - "C{}".format(plotting_opts.get("default_color") + 1), - "C{}".format(plotting_opts.get("default_color") + 2), - ) - else: - c1, c2, c3 = "C0", "C1", "C2" - if "default_colormap" in plotting_opts: - cm = plotting_opts.get("default_colormap") - else: - cm = "viridis" - _, betas, log_e_nu = inputs - _, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results log_e_nu = log_e_nu + 9 tauEnergy = tauEnergy * 1e9 showerEnergy = showerEnergy * 1e9 * 1e8 - - fig, ax = plt.subplots(2, 2, figsize=kwargs.get("figsize")) - binning_b = np.arange( - np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 - ) binning_e = np.arange( np.round(np.min(np.log10(showerEnergy)), 1) - 0.1, np.round(np.max(log_e_nu), 1) + 0.1, 0.1, ) - ax[0, 0].hist( + ax.hist( x=log_e_nu, bins=binning_e, - color=c1, + color=fig.params["default_colors"][0], alpha=0.6, label="$E_{\\nu_\\tau}$", ) - ax[0, 0].hist( + ax.hist( x=np.log10(tauEnergy), bins=binning_e, - color=c2, + color=fig.params["default_colors"][1], alpha=0.6, label="$E_\\tau$", ) - ax[0, 0].hist( + ax.hist( x=np.log10(showerEnergy), bins=binning_e, - color=c3, + color=fig.params["default_colors"][2], alpha=0.6, label="$E_\\mathrm{shower}$", ) - ax[0, 0].set_yscale("log") - ax[0, 0].legend(loc="upper left") - ax[0, 0].set_xlabel( - "Energy / $\\log_\\mathrm{10}\\left(\\frac{E}{\\mathrm{eV}}\\right)$" + fig.make_labels( + ax, + "Energy / $\\log_\\mathrm{10}\\left(\\frac{E}{\\mathrm{eV}}\\right)$", + "Counts", + logy_scale=True, ) - ax[0, 0].set_ylabel(r"Counts") + ax.legend(loc="best") - n, bins, _ = ax[0, 1].hist( + +def beta_hist(inputs, results, fig, ax, *args, **kwargs): + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 + ) + ax.hist( x=np.degrees(betas), bins=binning_b, - color=c1, + color=fig.params["default_colors"][0], + ) + fig.make_labels( + ax, + "Earth emergence angle $\\beta$ / $^{\\circ}$", + "Counts", + ) + + +def tau_beta_hist(inputs, results, fig, ax, *args, **kwargs): + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + ax.hist( + x=tauBeta, + bins=np.linspace(min(tauBeta), max(tauBeta), 100), + color=fig.params["default_colors"][0], + ) + fig.make_labels( + ax, + "$\\tau_\\beta$", + "Counts", ) - ax[0, 1].set_xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") - ax[0, 1].set_ylabel("Counts") - ax[0, 1].set_yscale("log") - ax[0, 1].set_xlim(min(binning_b), max(binning_b)) - - im = ax[1, 0].hexbin( - np.degrees(betas), - tauLorentz, - gridsize=len(binning_b), - yscale="log", - mincnt=1, - cmap=cm, - edgecolors="none", + + +def tau_lorentz_hist(inputs, results, fig, ax, *args, **kwargs): + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + ax.hist( + x=tauLorentz, + bins=np.linspace(min(tauLorentz), max(tauLorentz), 100), + color=fig.params["default_colors"][0], ) - bincenter, mean, std, binwidth = get_profile( - np.degrees(betas), tauLorentz, 10, useStd=True, **kwargs + fig.make_labels( + ax, + "$\\tau_\\mathrm{Lorentz}$", + "Counts", ) - ax[1, 0].errorbar( + + +def tau_exit_prob_hist(inputs, results, fig, ax, *args, **kwargs): + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + ax.hist( + x=tauExitProb, + bins=np.linspace(min(tauExitProb), max(tauExitProb), 100), + color=fig.params["default_colors"][0], + ) + fig.make_labels( + ax, + "$P_\\mathrm{Exit}(\\tau)$", + "Counts", + ) + + +def tau_beta_hex(inputs, results, fig, ax, *args, **kwargs): + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 + ) + im = fig.hexbin( + ax, + x=np.degrees(betas), + y=tauBeta, + gs=len(binning_b), + logy_scale=True, + ) + fig.make_labels( + ax, + "Earth emergence angle $\\beta$ / $^{\\circ}$", + "$\\tau_\\beta$", + clabel="Counts", + im=im, + logy_scale=True, + ) + + +def tau_lorentz_hex(inputs, results, fig, ax, *args, **kwargs): + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 + ) + im = fig.hexbin( + ax, + x=np.degrees(betas), + y=tauLorentz, + gs=len(binning_b), + logy_scale=True, + ) + bincenter, mean, std, binwidth = fig.get_profile( + np.degrees(betas), tauLorentz, 10, useStd=True + ) + ax.errorbar( bincenter, mean, - yerr=std, xerr=binwidth, - color=c2, + yerr=std, + color=fig.params["default_colors"][1], fmt=".", - lw=2, - zorder=5, label="Profile", ) - divider = make_axes_locatable(ax[1, 0]) - cax = divider.append_axes("right", size="5%", pad=0.0) - cbar = fig.colorbar(im, cax=cax) - cbar.set_label("Counts") - ax[1, 0].set_xlim(min(binning_b), max(binning_b)) - ax[1, 0].legend(loc="lower center") - ax[1, 0].set_xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") - ax[1, 0].set_ylabel("$\\tau_\\mathrm{Lorentz}$") - - im = ax[1, 1].hexbin( - np.degrees(betas), - tauExitProb, - gridsize=len(binning_b), - yscale="log", - mincnt=1, - cmap=cm, - edgecolors="none", + ax.legend(loc="best") + fig.make_labels( + ax, + "Earth emergence angle $\\beta$ / $^{\\circ}$", + "$\\tau_\\mathrm{Lorentz}$", + clabel="Counts", + im=im, + logy_scale=True, + ) + + +def tau_exit_prob_hex(inputs, results, fig, ax, *args, **kwargs): + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + binning_b = np.arange( + np.min(np.degrees(betas)) - 1, np.max(np.degrees(betas)) + 2, 1 + ) + im = fig.hexbin( + ax, + x=np.degrees(betas), + y=tauExitProb, + gs=len(binning_b), + logy_scale=True, + ) + fig.make_labels( + ax, + "Earth emergence angle $\\beta$ / $^{\\circ}$", + "$P_\\mathrm{Exit}(\\tau)$", + clabel="Counts", + im=im, + logy_scale=True, + ) + + +r"""Multiplot collections""" + + +def taus_density_beta_overview(inputs, results, plot_kwargs, *args, **kwargs): + r"""Plot some density plots""" + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + + fig = PlotWrapper( + plot_kwargs, + 1, + 3, + (15, 4), + "Tau interaction properties vs. Earth emergence angles $\\beta$", + ) + tau_beta_hex(inputs, results, fig, fig.ax[0]) + tau_lorentz_hex(inputs, results, fig, fig.ax[1]) + tau_exit_prob_hex(inputs, results, fig, fig.ax[2]) + + fig.close("taus_density_beta", fig.params["save_to_file"], fig.params["pop_up"]) + + +def taus_histograms_overview(inputs, results, plot_kwargs, *args, **kwargs): + r"""Plot some histograms""" + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + + fig = PlotWrapper( + plot_kwargs, 1, 3, (15, 4), "$\\tau$ interaction property Histograms" ) - divider = make_axes_locatable(ax[1, 1]) - cax = divider.append_axes("right", size="5%", pad=0.0) - cbar = fig.colorbar(im, cax=cax) - cbar.set_label("Counts") - ax[1, 1].set_xlim(min(binning_b), max(binning_b)) - ax[1, 1].set_xlabel("Earth emergence angle $\\beta$ / $^{\\circ}$") - ax[1, 1].set_ylabel("$P_\\mathrm{Exit}(\\tau)$") - - fig.suptitle("Overview of Tau interaction properties") - fig.tight_layout() - if "pop_up" not in plotting_opts: - plt.show() - elif "pop_up" in plotting_opts and plotting_opts.get("pop_up") is True: - plt.show() - if plotting_opts.get("save_to_file") is True: - fig.savefig( - plotting_opts.get("filename") - + "_taus_overview." - + plotting_opts.get("save_as") - ) + + tau_beta_hist(inputs, results, fig, fig.ax[0]) + tau_lorentz_hist(inputs, results, fig, fig.ax[1]) + tau_exit_prob_hist(inputs, results, fig, fig.ax[2]) + fig.close("taus_histogram", fig.params["save_to_file"], fig.params["pop_up"]) + + +def taus_pexit_overview(inputs, results, plot_kwargs, *args, **kwargs): + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + + fig = PlotWrapper(plot_kwargs, 1, 2, (10, 4), "$\\tau$ exit probability") + + tau_exit_prob_hex(inputs, results, fig, fig.ax[0]) + tau_exit_prob_hist(inputs, results, fig, fig.ax[1]) + fig.close("taus_pexit", fig.params["save_to_file"], fig.params["pop_up"]) + + +def taus_overview(inputs, results, plot_kwargs, *args, **kwargs): + r"""Overview plot for taus""" + _, betas, log_e_nu = inputs + tauBeta, tauLorentz, tauEnergy, showerEnergy, tauExitProb = results + fig = PlotWrapper( + plot_kwargs, + rows=2, + cols=2, + size=(10, 8), + title="Overview of Tau interaction properties", + ) + energy_hists(inputs, results, fig, fig.ax[0, 0]) + beta_hist(inputs, results, fig, fig.ax[0, 1]) + tau_lorentz_hex(inputs, results, fig, fig.ax[1, 0]) + tau_exit_prob_hex(inputs, results, fig, fig.ax[1, 1]) + + fig.close("taus_overview", fig.params["save_to_file"], fig.params["pop_up"]) diff --git a/src/nuspacesim/simulation/taus/taus.py b/src/nuspacesim/simulation/taus/taus.py index 7a5ae31..c99d9c4 100644 --- a/src/nuspacesim/simulation/taus/taus.py +++ b/src/nuspacesim/simulation/taus/taus.py @@ -40,7 +40,20 @@ from ...utils import decorators from ...utils.cdf import grid_cdf_sampler from ...utils.grid import NssGrid -from .local_plots import taus_density_beta, taus_histogram, taus_overview, taus_pexit +from .local_plots import ( + beta_hist, + energy_hists, + tau_beta_hex, + tau_beta_hist, + tau_exit_prob_hex, + tau_exit_prob_hist, + tau_lorentz_hex, + tau_lorentz_hist, + taus_density_beta_overview, + taus_histograms_overview, + taus_overview, + taus_pexit_overview, +) try: from importlib.resources import as_file, files @@ -139,7 +152,18 @@ def tau_energy(self, betas, log_e_nu): return E_tau * 10 ** log_e_nu @decorators.nss_result_plot( - taus_density_beta, taus_histogram, taus_pexit, taus_overview + energy_hists, + beta_hist, + tau_beta_hist, + tau_lorentz_hist, + tau_exit_prob_hist, + tau_beta_hex, + tau_lorentz_hex, + tau_exit_prob_hex, + taus_density_beta_overview, + taus_histograms_overview, + taus_pexit_overview, + taus_overview, ) @decorators.nss_result_store( "tauBeta", "tauLorentz", "tauEnergy", "showerEnergy", "tauExitProb" @@ -179,7 +203,20 @@ def __call__(self, betas, log_e_nu, *args, **kwargs): def show_plot(sim, plot, plot_kwargs): inputs = ("beta_rad", "log_e_nu") outputs = ("tauBeta", "tauLorentz", "tauEnergy", "showerEnergy", "tauExitProb") - plotfs = (taus_density_beta, taus_histogram, taus_pexit, taus_overview) + plotfs = ( + energy_hists, + beta_hist, + tau_beta_hist, + tau_lorentz_hist, + tau_exit_prob_hist, + tau_beta_hex, + tau_lorentz_hex, + tau_exit_prob_hex, + taus_density_beta_overview, + taus_histograms_overview, + taus_pexit_overview, + taus_overview, + ) decorators.nss_result_plot_from_file( sim, inputs, outputs, plotfs, plot, plot_kwargs ) diff --git a/src/nuspacesim/utils/__init__.py b/src/nuspacesim/utils/__init__.py index d15df7a..af92113 100644 --- a/src/nuspacesim/utils/__init__.py +++ b/src/nuspacesim/utils/__init__.py @@ -43,9 +43,9 @@ interp misc plots - + plot_wrapper """ -__all__ = ["cdf", "decorators", "grid", "interp", "misc", "plots"] +__all__ = ["cdf", "decorators", "grid", "interp", "misc", "plots", "plot_wrapper"] -from . import cdf, decorators, grid, interp, misc, plots +from . import cdf, decorators, grid, interp, misc, plot_wrapper, plots diff --git a/src/nuspacesim/utils/decorators.py b/src/nuspacesim/utils/decorators.py index 7918500..a0f4f2a 100644 --- a/src/nuspacesim/utils/decorators.py +++ b/src/nuspacesim/utils/decorators.py @@ -49,6 +49,8 @@ from functools import wraps from typing import Callable, Iterable, Union +from nuspacesim.utils.plot_wrapper import PlotWrapper + def nss_result_store(*names): r"""Store result columns in nuspacesim.ResultsTable @@ -194,23 +196,61 @@ def decorator_plot(func): @wraps(func) def wrapper_f( - *args, plot: Union[None, str, Iterable, Callable] = None, **kwargs + *args, + plot: Union[None, str, Iterable, Callable] = None, + plot_kwargs: dict, + **kwargs ): values = func(*args, **kwargs) if isinstance(plot, str): for plotf in plot_fs: - if plotf.__name__ == plot: - plotf(args, values, **kwargs) + if "overview" in plotf.__name__: + plotf(args, values, plot_kwargs, **kwargs) + else: + fig = PlotWrapper(plot_kwargs, 1, 1) + plotf(args, values, fig, fig.ax, **kwargs) + fig.close( + str(plotf.__name__), + fig.params["save_to_file"], + fig.params["pop_up"], + ) elif callable(plot): - plot(args, values) + if "overview" in plot.__name__: + plot(args, values, plot_kwargs, **kwargs) + else: + fig = PlotWrapper(plot_kwargs, 1, 1) + plot(args, values, fig, fig.ax, **kwargs) + fig.close( + str(plot.__name__), + fig.params["save_to_file"], + fig.params["pop_up"], + ) elif isinstance(plot, Iterable): if all(isinstance(p, str) for p in plot): for plotf in plot_fs: if plotf.__name__ in plot: - plotf(args, values, **kwargs) + if "overview" in plotf.__name__: + plotf(args, values, plot_kwargs, **kwargs) + else: + fig = PlotWrapper(plot_kwargs, 1, 1) + plotf(args, values, fig, fig.ax, **kwargs) + fig.close( + str(plotf.__name__), + fig.params["save_to_file"], + fig.params["pop_up"], + ) elif all(callable(p) for p in plot): for plotf in plot: - plotf(args, values, **kwargs) + if "overview" in plotf.__name__: + plotf(args, values, plot_kwargs, **kwargs) + else: + fig = PlotWrapper(plot_kwargs, 1, 1) + plotf(args, values, fig, fig.ax, **kwargs) + fig.close( + str(plotf.__name__), + fig.params["save_to_file"], + fig.params["pop_up"], + ) return values return wrapper_f diff --git a/src/nuspacesim/utils/plot_wrapper.py b/src/nuspacesim/utils/plot_wrapper.py new file mode 100644 index 0000000..af46bea --- /dev/null +++ b/src/nuspacesim/utils/plot_wrapper.py @@ -0,0 +1,137 @@ +import numpy as np +from matplotlib import pyplot as plt + + +class PlotWrapper: + """ + The PlotWrapper class produces figures that are uniformly formatted for nuspacesim as set up in sample_plot_config.ini + """ + + def __init__( + self, + plot_kwargs={ + "save_as": "pdf", + "pop_up": True, + "save_to_file": True, + "default_color": 0, + "default_colormap": "viridis", + "filename": "nuspacesim_run", + }, + rows=1, + cols=1, + size=(8, 7), + title=None, + ): + """ + initialize figure + rows = number of rows of plots + cols = number of cols of plots + default is 1 for single plot, but can be changed to add subplots for making a multiplot + """ + self.params = { + "save_to_file": plot_kwargs["save_to_file"], + "save_as": plot_kwargs["save_as"], + "pop_up": plot_kwargs["pop_up"], + "default_colors": [ + "C{}".format(plot_kwargs["default_color"]), + "C{}".format(plot_kwargs["default_color"] + 1), + "C{}".format(plot_kwargs["default_color"] + 2), + ], + "default_colormap": plot_kwargs["default_colormap"], + "filename": plot_kwargs["filename"], + } + # initialize figure as subplots + self.fig, self.ax = plt.subplots(nrows=rows, ncols=cols, figsize=size) + self.fig.suptitle(title) + + def make_labels( + self, + ax, + xlabel, + ylabel, + clabel=None, + im=None, + logx=False, + logy=False, + logx_scale=False, + logy_scale=False, + ): + + xl = "$\\log_{10}$" + f"({xlabel})" if logx else xlabel + yl = "$\\log_{10}$" + f"({ylabel})" if logy else ylabel + xs = "log" if logx_scale else "linear" + ys = "log" if logy_scale else "linear" + + ax.set_xlabel(xl) + ax.set_ylabel(yl) + ax.set_xscale(xs) + ax.set_yscale(ys) + if clabel is not None: + cbar = self.fig.colorbar(im, ax=ax, pad=0.0) + cbar.set_label(clabel) + + def get_profile(self, x, y, nbins, useStd=True): + + if sum(np.isnan(y)) > 0: + x = x[~np.isnan(y)] + y = y[~np.isnan(y)] + n, _ = np.histogram(x, bins=nbins) + sy, _ = np.histogram(x, bins=nbins, weights=y) + sy2, _ = np.histogram(x, bins=nbins, weights=y * y) + mean = sy / n + std = np.sqrt(sy2 / n - mean * mean) + if not useStd: + std /= np.sqrt(n) + bincenter = (_[1:] + _[:-1]) / 2 + binwidth = bincenter - _[1:] + + return bincenter, mean, std, binwidth + + def hexbin( + self, + ax, + x, + y, + gs=25, + logx=False, + logy=False, + logx_scale=False, + logy_scale=False, + ): + + xf = np.log10 if logx else lambda q: q + yf = np.log10 if logy else lambda q: q + + xs = "log" if logx_scale else "linear" + ys = "log" if logy_scale else "linear" + + xmask = x > 0 if logx else np.full(x.shape, True) + ymask = y > 0 if logy else np.full(y.shape, True) + m = xmask & ymask + + im = ax.hexbin( + x=xf(x[m]), + y=yf(y[m]), + gridsize=gs, + mincnt=1, + xscale=xs, + yscale=ys, + cmap=self.params["default_colormap"], + edgecolors="none", + ) + return im + + def close(self, plot_name, save_to_file=True, pop_up=True): + self.fig.tight_layout() + if save_to_file: + self.fig.savefig( + fname=self.params["filename"] + + "_" + + plot_name + + "." + + self.params["save_as"], + bbox_inches="tight", + ) + if pop_up: + plt.show() + plt.close(self.fig) diff --git a/src/nuspacesim/utils/plots.py b/src/nuspacesim/utils/plots.py index 2b7f2da..230e937 100644 --- a/src/nuspacesim/utils/plots.py +++ b/src/nuspacesim/utils/plots.py @@ -33,308 +33,58 @@ import numpy as np from matplotlib import pyplot as plt +from ..simulation import * from . import decorators +from .plot_wrapper import PlotWrapper -__all__ = ["dashboard", "energy_histograms", "show_plot"] - - -def hexbin(fig, ax, x, y, xlab, ylab, cm="viridis", logx=True, logy=True): - - xf = np.log10 if logx else lambda q: q - yf = np.log10 if logy else lambda q: q - - xl = f"log({xlab})" if logx else xlab - yl = f"log({ylab})" if logy else ylab - - xmask = x > 0 if logx else np.full(x.shape, True) - ymask = y > 0 if logy else np.full(y.shape, True) - m = xmask & ymask - - im = ax.hexbin( - x=xf(x[m]), y=yf(y[m]), gridsize=25, mincnt=1, cmap=cm, edgecolors="none" - ) - - ax.set_xlabel(xl) - ax.set_ylabel(yl) - - ax.set_title(f"{yl} vs {xl}") - cbar = fig.colorbar(im, ax=ax, pad=0.0) - cbar.set_label("Counts") - - -def hist2d(fig, ax, x, y, xlab, ylab, cm="viridis", logx=True, logy=True): - - xf = np.log10 if logx else lambda q: q - yf = np.log10 if logy else lambda q: q - - xl = f"log({xlab})" if logx else xlab - yl = f"log({ylab})" if logy else ylab - - xmask = x > 0 if logx else np.full(x.shape, True) - ymask = y > 0 if logy else np.full(y.shape, True) - m = xmask & ymask - - _, _, _, im = ax.hist2d(x=xf(x[m]), y=yf(y[m]), bins=(50, 50), cmin=1, cmap=cm) - - ax.set_xlabel(xl) - ax.set_ylabel(yl) - - ax.set_title(f"{yl} vs {xl}") - cbar = fig.colorbar(im, ax=ax, pad=0.0) - cbar.set_label("Counts") +__all__ = ["dashboard", "show_plot"] def dashboard(sim, plot_kwargs={}): """Full dashboard of plots""" - if plot_kwargs: - if "default_color" in plot_kwargs: - c1, c2, c3 = ( - "C{}".format(plot_kwargs.get("default_color")), - "C{}".format(plot_kwargs.get("default_color") + 1), - "C{}".format(plot_kwargs.get("default_color") + 2), - ) - if "default_colormap" in plot_kwargs: - cm = plot_kwargs.get("default_colormap") - else: - c1, c2, c3 = "C0", "C1", "C2" - cm = "viridis" - - fig, ax = plt.subplots(3, 4, figsize=(14, 8), constrained_layout=True) - - energy_histograms(sim, fig, ax[0, 0], [c1, c2, c3]) - tau_pexit_hist(sim, fig, ax[1, 0], c1) - tau_lorentz(sim, fig, ax[2, 0], cm) - - betas_histogram(sim, fig, ax[0, 1], c1) - tau_pexit_density(sim, fig, ax[1, 1], cm) - decay_altitude(sim, fig, ax[2, 1], cm) - - # decay_altitude_hist(sim, fig, ax[0, 2]) - num_photo_electrons_hist(sim, fig, ax[0, 2], c1) - num_photo_electrons_density(sim, fig, ax[1, 2], cm) - num_photo_electrons_altitude(sim, fig, ax[2, 2], cm) - - # eas_input_density(sim, fig, ax[0, 3]) - cherenkov_angle_hist(sim, fig, ax[0, 3], c1) - eas_results_density(sim, fig, ax[1, 3], cm) - cherenkov_angle(sim, fig, ax[2, 3], cm) - - # tau_betas(sim, fig, ax[1, 2]) - - fig.suptitle("Nuspacesim Results Dashboard", size="x-large") - if "pop_up" not in plot_kwargs: - plt.show() - elif "pop_up" in plot_kwargs and plot_kwargs.get("pop_up") is True: - plt.show() - if plot_kwargs.get("save_to_file") is True: - fig.savefig( - plot_kwargs.get("filename") + "_dashboard." + plot_kwargs.get("save_as") - ) - - -def energy_histograms(sim, fig, ax, c): - - energy_bins = np.arange( - np.round(np.min(np.log10(sim["showerEnergy"]) + 17), 1) - 0.1, - np.round(np.max(sim["log_e_nu"] + 9), 1) + 0.1, - 0.1, - ) - ax.hist( - x=sim["log_e_nu"] + 9, - bins=energy_bins, - color=c[0], - alpha=0.6, - label=r"$E_{\nu_\tau}$", - ) - ax.hist( - x=np.log10(sim["tauEnergy"]) + 9, - bins=energy_bins, - color=c[1], - alpha=0.6, - label=r"$E_\tau$", - ) - ax.hist( - x=np.log10(sim["showerEnergy"]) + 17, - bins=energy_bins, - color=c[2], - alpha=0.6, - label=r"$E_\mathrm{shower}$", - ) - ax.set_yscale("log") - ax.legend(loc="upper left") - ax.set_xlabel(r"Energy / $\log_\mathrm{10}\left(\frac{E}{\mathrm{eV}}\right)$") - ax.set_ylabel(r"Counts") - + fig = PlotWrapper(plot_kwargs, 3, 4, (15, 8), "Nuspacesim Results Dashboard") -def betas_histogram(sim, fig, ax, c): - - beta_bins = np.arange( - np.min(np.degrees(sim["beta_rad"])) - 1, - np.max(np.degrees(sim["beta_rad"])) + 2, - 1, - ) - - ax.hist(x=np.degrees(sim["beta_rad"]), bins=beta_bins, color=c) - ax.set_xlabel(r"Earth emergence angle $\beta$ / $^{\circ}$") - ax.set_ylabel("Counts") - ax.set_yscale("log") - ax.set_xlim(min(beta_bins), max(beta_bins)) - - -def tau_lorentz(sim, fig, ax, cm): - hexbin( - fig, - ax, - np.degrees(sim["beta_rad"]), + tau_input = None, sim["beta_rad"], sim["log_e_nu"] + tau_results = ( + sim["tauBeta"], sim["tauLorentz"], - r"$\beta$", - r"$τ_\mathrm{Lorentz}$", - cm=cm, - logx=False, - logy=True, - ) - - -def tau_pexit_hist(sim, fig, ax, c): - ax.hist(sim["tauExitProb"], 100, log=True, color=c) - ax.set_ylabel("Counts") - ax.set_xlabel(r"$\log(P_\mathrm{exit}(\tau))$") - - -def tau_pexit_density(sim, fig, ax, cm): - hexbin( - fig, - ax, - np.degrees(sim["beta_rad"]), + sim["tauEnergy"], + sim["showerEnergy"], sim["tauExitProb"], - r"$\beta$", - r"$P_\mathrm{exit}(\tau)$", - cm=cm, - logx=False, - logy=True, - ) - - -def tau_betas(sim, fig, ax, cm): - hexbin( - fig, - ax, - sim["beta_rad"], - sim["tauBeta"], - r"$\beta$", - r"$τ_β$", - cm=cm, - logx=False, - logy=True, ) + eas_input = None, sim["beta_rad"], sim["altDec"], sim["showerEnergy"] + eas_results = sim["numPEs"], sim["costhetaChEff"] -def decay_altitude_hist(sim, fig, ax, c): - ax.hist(sim["altDec"], 100, log=True, color=c) - ax.set_ylabel("Counts") - ax.set_xlabel("decay_altitude log(km)") + taus.local_plots.energy_hists(tau_input, tau_results, fig, fig.ax[0, 0]) + taus.local_plots.tau_exit_prob_hist(tau_input, tau_results, fig, fig.ax[1, 0]) + taus.local_plots.tau_lorentz_hex(tau_input, tau_results, fig, fig.ax[2, 0]) + taus.local_plots.beta_hist(tau_input, tau_results, fig, fig.ax[0, 1]) + taus.local_plots.tau_exit_prob_hex(tau_input, tau_results, fig, fig.ax[1, 1]) + eas_optical.local_plots.altdec_vs_beta(eas_input, eas_results, fig, fig.ax[2, 1]) -def num_photo_electrons_hist(sim, fig, ax, c): - m = sim["numPEs"] != 0 - ax.hist(np.log(sim["numPEs"][m]), 100, log=False, color=c) - ax.set_ylabel("Counts") - ax.set_xlabel("log(numPEs)") + eas_optical.local_plots.numpes_hist(eas_input, eas_results, fig, fig.ax[0, 2]) + eas_optical.local_plots.numpes_vs_beta(eas_input, eas_results, fig, fig.ax[1, 2]) + eas_optical.local_plots.altdec_vs_numpes(eas_input, eas_results, fig, fig.ax[2, 2]) - -def num_photo_electrons_density(sim, fig, ax, cm): - hexbin( - fig, - ax, - sim["numPEs"], - np.degrees(sim["beta_rad"]), - "numPEs", - "β", - cm=cm, - logx=True, - logy=False, - ) - - -def num_photo_electrons_altitude(sim, fig, ax, cm): - hexbin( - fig, - ax, - sim["numPEs"], - sim["altDec"], - "numPEs", - "decay_altitude km", - cm=cm, - logx=True, - logy=True, - ) - - -def decay_altitude(sim, fig, ax, cm): - hexbin( - fig, - ax, - np.degrees(sim["beta_rad"]), - sim["altDec"], - "β", - "decay_altitude km", - cm=cm, - logx=False, - logy=True, + # eas_input_density(sim, fig, ax[0, 3]) + eas_optical.local_plots.costhetacheff_hist( + eas_input, eas_results, fig, fig.ax[0, 3] ) - - -def cherenkov_angle_hist(sim, fig, ax, c): - ax.hist(np.degrees(np.arccos(sim["costhetaChEff"])), 100, log=True, color=c) - ax.set_ylabel("Counts") - ax.set_xlabel("θ_chEff") - - -def eas_input_density(sim, fig, ax, cm): - hexbin( - fig, - ax, - np.degrees(sim["beta_rad"]), - sim["altDec"], - "beta_rad", - "decay alt km", - cm=cm, - logx=False, - logy=True, + eas_optical.local_plots.costhetacheff_vs_numpes( + eas_input, eas_results, fig, fig.ax[1, 3] ) - - -def cherenkov_angle(sim, fig, ax, cm): - hexbin( - fig, - ax, - np.degrees(np.arccos(sim["costhetaChEff"])), - np.degrees(sim["beta_rad"]), - "θ_chEff", - "β", - cm=cm, - logx=False, - logy=False, + eas_optical.local_plots.costhetacheff_vs_beta( + eas_input, eas_results, fig, fig.ax[2, 3] ) - -def eas_results_density(sim, fig, ax, cm): - hexbin( - fig, - ax, - np.degrees(np.arccos(sim["costhetaChEff"])), - sim["numPEs"], - "θ_chEff", - "NumPEs", - cm=cm, - logx=False, - logy=False, - ) + # tau_betas(sim, fig, ax[1, 2]) + fig.close("dashboard", fig.params["save_to_file"], fig.params["pop_up"]) @decorators.ensure_plot_registry(dashboard) def show_plot(sim, plot, plot_kwargs={}): - if dashboard.__name__ in plot: dashboard(sim, plot_kwargs) diff --git a/test/utils/test_decorators.py b/test/utils/test_decorators.py index 2dd46f2..d0450c1 100644 --- a/test/utils/test_decorators.py +++ b/test/utils/test_decorators.py @@ -59,6 +59,14 @@ def test_nss_result_plot(): plot_written = False iA, iB = np.random.randn(2, 128) + plot_kwargs = { + "save_as": "pdf", + "pop_up": False, + "save_to_file": False, + "default_color": 0, + "default_colormap": "viridis", + "filename": "nuspacesim_run", + } def plotter(inputs, results, *args, **kwargs): nonlocal plot_written @@ -66,7 +74,7 @@ def plotter(inputs, results, *args, **kwargs): assert plot_written assert len(inputs) == 2 assert len(results) == 2 - assert len(args) == 0 + assert len(args) == 2 assert len(kwargs) == 0 assert np.array_equal(inputs[0], iA) assert np.array_equal(inputs[1], iB) @@ -84,35 +92,35 @@ def test_base_f(input1, input2): # test plotter is not called without a plot argument assert not plot_written - cA, cB = test_base_f(iA, iB) + cA, cB = test_base_f(iA, iB, plot_kwargs=plot_kwargs) assert not plot_written assert np.all(np.equal(cA, 0.0)) assert np.all(np.equal(cB, 1.0)) # test plotter is called with a callable plot argument plot_written = False - cA, cB = test_base_f(iA, iB, plot=plotter) + cA, cB = test_base_f(iA, iB, plot=plotter, plot_kwargs=plot_kwargs) assert plot_written assert np.all(np.equal(cA, 0.0)) assert np.all(np.equal(cB, 1.0)) # test plotter is called with a string plot argument plot_written = False - cA, cB = test_base_f(iA, iB, plot=plotter.__name__) + cA, cB = test_base_f(iA, iB, plot=plotter.__name__, plot_kwargs=plot_kwargs) assert plot_written assert np.all(np.equal(cA, 0.0)) assert np.all(np.equal(cB, 1.0)) # test plotter is called with a list of callable plot arguments plot_written = False - cA, cB = test_base_f(iA, iB, plot=list([plotter])) + cA, cB = test_base_f(iA, iB, plot=list([plotter]), plot_kwargs=plot_kwargs) assert plot_written assert np.all(np.equal(cA, 0.0)) assert np.all(np.equal(cB, 1.0)) # test plotter is called with a list of string plot arguments plot_written = False - cA, cB = test_base_f(iA, iB, plot=list([plotter.__name__])) + cA, cB = test_base_f(iA, iB, plot=list([plotter.__name__]), plot_kwargs=plot_kwargs) assert plot_written assert np.all(np.equal(cA, 0.0)) assert np.all(np.equal(cB, 1.0)) From 8cb4fcdd4247f1f46d49cfb6787d154f1430f307 Mon Sep 17 00:00:00 2001 From: smayotte Date: Mon, 13 Jun 2022 15:51:29 -0600 Subject: [PATCH 07/11] fixed show-plot command not working properly --- src/nuspacesim/utils/decorators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nuspacesim/utils/decorators.py b/src/nuspacesim/utils/decorators.py index a0f4f2a..c7423ef 100644 --- a/src/nuspacesim/utils/decorators.py +++ b/src/nuspacesim/utils/decorators.py @@ -266,7 +266,7 @@ def nss_result_plot_from_file(sim, inputs, outputs, plotfs, plot, plot_kwargs): def f(*args, **kwargs): return results - f(None, *f_input, plot=plot, kwargs=plot_kwargs) + f(None, *f_input, plot=plot, plot_kwargs=plot_kwargs) def ensure_plot_registry(*plot_fs): From e24af368beac0e30c9c2a4c1d00bfd495d5592c6 Mon Sep 17 00:00:00 2001 From: smayotte Date: Thu, 26 Jan 2023 14:18:13 -0700 Subject: [PATCH 08/11] commit to rerun pull request checks From 08f51de2cc16978c7fb15d648c08fdfe73c109de Mon Sep 17 00:00:00 2001 From: smayotte Date: Sat, 28 Jan 2023 11:05:32 -0700 Subject: [PATCH 09/11] Added plotsettings to run.py to set plot settings when making plots with --plot. Changed default settings back to viridis. Fixed calculation of binwidth (was producing negative values) --- .pre-commit-config.yaml | 12 ++++++------ src/nuspacesim/apps/commands/run.py | 9 +++++++++ src/nuspacesim/simulation/taus/local_plots.py | 2 +- src/nuspacesim/utils/plot_wrapper.py | 2 +- src/nuspacesim/utils/plots.py | 2 +- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6611ba6..325cf60 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.4.0 hooks: - id: check-merge-conflict - id: check-added-large-files @@ -9,22 +9,22 @@ repos: - id: check-xml - repo: https://github.com/ambv/black - rev: 22.3.0 + rev: 22.12.0 hooks: - id: black - - repo: https://gitlab.com/pycqa/flake8 - rev: 3.9.2 + - repo: https://github.com/pycqa/flake8 + rev: 6.0.0 hooks: - id: flake8 - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.12.0 hooks: - id: isort args: ["--profile", "black", "--filter-files"] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v1.20.1 + rev: v2.2.0 hooks: - id: setup-cfg-fmt diff --git a/src/nuspacesim/apps/commands/run.py b/src/nuspacesim/apps/commands/run.py index 5a63a53..a0ba6a9 100644 --- a/src/nuspacesim/apps/commands/run.py +++ b/src/nuspacesim/apps/commands/run.py @@ -18,6 +18,14 @@ default=[], help="Available plotting functions. Select multiple plots with multiple uses of -p", ) +@click.option( + "-ps", + "--plotsettings", + nargs=7, + type=click.Tuple([int, int, bool, str, bool, int, str]), + default=None, + help="Save plot supplied with -p with given file extension, optionally suppress pop_up", +) @click.option( "-pc", "--plotconfig", @@ -68,6 +76,7 @@ def run( no_result_file: bool, output: str, plot: list, + plotsettings, plotconfig: str, plotall: bool, write_stages: bool, diff --git a/src/nuspacesim/simulation/taus/local_plots.py b/src/nuspacesim/simulation/taus/local_plots.py index 92af7e4..60fb4f9 100644 --- a/src/nuspacesim/simulation/taus/local_plots.py +++ b/src/nuspacesim/simulation/taus/local_plots.py @@ -190,7 +190,7 @@ def tau_lorentz_hex(inputs, results, fig, ax, *args, **kwargs): mean, xerr=binwidth, yerr=std, - color=kwargs["color"][0], + color=kwargs["color"][1], fmt=".", label="Profile", ) diff --git a/src/nuspacesim/utils/plot_wrapper.py b/src/nuspacesim/utils/plot_wrapper.py index 0422920..9eed96b 100644 --- a/src/nuspacesim/utils/plot_wrapper.py +++ b/src/nuspacesim/utils/plot_wrapper.py @@ -73,7 +73,7 @@ def __init__( cfg_args.setdefault("pop_up", True) cfg_args.setdefault("save_to_file", False) cfg_args.setdefault("default_color", 0) - cfg_args.setdefault("default_colormap", "jet") + cfg_args.setdefault("default_colormap", "viridis") cfg_args.setdefault("filename", "NuSpaceSim") cfg_args.setdefault("output_path", ".") diff --git a/src/nuspacesim/utils/plots.py b/src/nuspacesim/utils/plots.py index 09f1b99..d5f4610 100644 --- a/src/nuspacesim/utils/plots.py +++ b/src/nuspacesim/utils/plots.py @@ -75,7 +75,7 @@ def get_profile(x, y, nbins, useStd=True): if not useStd: std /= np.sqrt(n) bincenter = (_[1:] + _[:-1]) / 2 - binwidth = bincenter - _[1:] + binwidth = _[1:] - bincenter return bincenter, mean, std, binwidth From e575cddab7a58a9fa2d9650655c6390754d812e8 Mon Sep 17 00:00:00 2001 From: smayotte Date: Sat, 28 Jan 2023 11:32:12 -0700 Subject: [PATCH 10/11] fix pre-commit issue --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 325cf60..4c52bb5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,3 +28,4 @@ repos: rev: v2.2.0 hooks: - id: setup-cfg-fmt + args: ["--include-version-classifiers", "--max-py-version=3.11"] From 99401ab4f840ae4d8d2e9d8fbec741617310a719 Mon Sep 17 00:00:00 2001 From: smayotte Date: Sat, 28 Jan 2023 11:58:09 -0700 Subject: [PATCH 11/11] change jet to viridis --- sample_plot_config.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample_plot_config.ini b/sample_plot_config.ini index 6d54638..e9c6923 100644 --- a/sample_plot_config.ini +++ b/sample_plot_config.ini @@ -9,7 +9,7 @@ save_as = pdf default_color = 0 # as in 'C0' default_markersize = 3 -default_colormap = jet +default_colormap = viridis # output_path = ~/Documents/Pictures [Spectra]