From 3e817be079e3d94908923dec31628b3cc7efab22 Mon Sep 17 00:00:00 2001 From: Watanyu Foosang <watanyu.f@gmail.com> Date: Tue, 9 Mar 2021 16:32:54 +0100 Subject: [PATCH] Add action monitor and plot - cs_invariant method in Bunch is renamed to 'action'. - Action is now saved together with BunchMonitor and can be plotted in plot_bunchdata --- tracking/monitors/monitors.py | 10 +++++---- tracking/monitors/plotting.py | 41 ++++++++++++++++++++--------------- tracking/particles.py | 4 ++-- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/tracking/monitors/monitors.py b/tracking/monitors/monitors.py index 7a2b209..88ae258 100644 --- a/tracking/monitors/monitors.py +++ b/tracking/monitors/monitors.py @@ -230,7 +230,8 @@ class Monitor(Element, metaclass=ABCMeta): class BunchMonitor(Monitor): """ - Monitor a single bunch and save attributes (mean, std, emit and current). + Monitor a single bunch and save attributes + (mean, std, emit, current, and action). Parameters ---------- @@ -267,9 +268,11 @@ class BunchMonitor(Monitor): self.bunch_number = bunch_number group_name = "BunchData_" + str(self.bunch_number) dict_buffer = {"mean":(6, buffer_size), "std":(6, buffer_size), - "emit":(3, buffer_size), "current":(buffer_size,)} + "emit":(3, buffer_size), "current":(buffer_size,), + "action":(2, buffer_size)} dict_file = {"mean":(6, total_size), "std":(6, total_size), - "emit":(3, total_size), "current":(total_size,)} + "emit":(3, total_size), "current":(total_size,), + "action":(2, total_size)} self.monitor_init(group_name, save_every, buffer_size, total_size, dict_buffer, dict_file, file_name, mpi_mode) @@ -984,4 +987,3 @@ class TuneMonitor(Monitor): spread = np.nanstd(tune_single_particle, 0) return (mean, spread) - \ No newline at end of file diff --git a/tracking/monitors/plotting.py b/tracking/monitors/plotting.py index 63ed6bf..bbd39ba 100644 --- a/tracking/monitors/plotting.py +++ b/tracking/monitors/plotting.py @@ -112,7 +112,7 @@ def plot_beamdata(filename, dataset, option=None, stat_var=None, x_var="time"): file.close() return fig -def plot_bunchdata(filename, bunch_number, dataset, option=None, x_var="time"): +def plot_bunchdata(filename, bunch_number, dataset, dimension="x", x_var="time"): """ Plot data recorded by BunchMonitor. @@ -123,13 +123,14 @@ def plot_bunchdata(filename, bunch_number, dataset, option=None, x_var="time"): bunch_number : int Bunch to plot. This has to be identical to 'bunch_number' parameter in 'BunchMonitor' object. - detaset : {"current","emit","mean","std"} + dataset : {"current", "emit", "mean", "std", "action"} HDF5 file's dataset to be plotted. - option : str, optional - If dataset is "emit", "mean", or "std", the variable name to be plotted - needs to be specified : - for "emit", option = {"x","y","s"} - for "mean" and "std", option = {"x","xp","y","yp","tau","delta"} + dimension : str, optional + The dimension of the dataset to plot. Use "None" for "current", + otherwise use the following : + for "emit", dimension = {"x","y","s"}, + for "mean" and "std", dimension = {"x","xp","y","yp","tau","delta"}, + for "action", dimension = {"x","y"}. x_var : {"time", "current"}, optional Variable to be plotted on the horizontal axis. The default is "time". @@ -149,19 +150,19 @@ def plot_bunchdata(filename, bunch_number, dataset, option=None, x_var="time"): label = "current (mA)" elif dataset == "emit": - option_dict = {"x":0, "y":1, "s":2} + dimension_dict = {"x":0, "y":1, "s":2} - y_var = file[group][dataset][option_dict[option]]*1e9 + y_var = file[group][dataset][dimension_dict[dimension]]*1e9 - if option == "x": label = "hor. emittance (nm.rad)" - elif option == "y": label = "ver. emittance (nm.rad)" - elif option == "s": label = "long. emittance (nm.rad)" + if dimension == "x": label = "hor. emittance (nm.rad)" + elif dimension == "y": label = "ver. emittance (nm.rad)" + elif dimension == "s": label = "long. emittance (nm.rad)" - elif dataset == "mean" or "std": - option_dict = {"x":0, "xp":1, "y":2, "yp":3, "tau":4, "delta":5} + elif dataset == "mean" or dataset == "std": + dimension_dict = {"x":0, "xp":1, "y":2, "yp":3, "tau":4, "delta":5} scale = [1e6, 1e6, 1e6, 1e6, 1e12, 1] - axis_index = option_dict[option] + axis_index = dimension_dict[dimension] y_var = file[group][dataset][axis_index]*scale[axis_index] if dataset == "mean": @@ -174,6 +175,13 @@ def plot_bunchdata(filename, bunch_number, dataset, option=None, x_var="time"): label = label_list[axis_index] + elif dataset == "action": + dimension_dict = {"x":0, "y":1} + axis_index = dimension_dict[dimension] + y_var = file[group][dataset][axis_index] + label_list = ['$J_x$ (m)', '$J_y$ (m)'] + label = label_list[axis_index] + if x_var == "current": x_axis = file[group]["current"][:] * 1e3 xlabel = "current (mA)" @@ -544,5 +552,4 @@ def plot_tunedata(filename, bunch_number): ax2.set_ylabel("Synchrotron tune") file.close() - return (fig1, fig2) - \ No newline at end of file + return (fig1, fig2) \ No newline at end of file diff --git a/tracking/particles.py b/tracking/particles.py index c272e98..c9ad596 100644 --- a/tracking/particles.py +++ b/tracking/particles.py @@ -232,9 +232,9 @@ class Bunch: return np.array([emitX, emitY, emitS]) @property - def cs_invariant(self): + def action(self): """ - Return the average Couran-Snyder invariant of each plane. + Return the average action (Couran-Snyder invariant) of each plane. """ Jx = (self.ring.optics.local_gamma[0] * self['x']**2) + \ -- GitLab