From 7507d6595b7ddee0d1432e5925e5b1e25814a246 Mon Sep 17 00:00:00 2001 From: Gamelin Alexis <gamelin@synchrotron-soleil.fr> Date: Fri, 23 Apr 2021 17:32:36 +0200 Subject: [PATCH] Fix TuneMonitor Fix bug when buffer_size=1 in TuneMonitor by switching to init buffer_count to 0. Now total_size should be 1 less. Improve plot_tunedata --- tracking/monitors/monitors.py | 9 +++--- tracking/monitors/plotting.py | 60 ++++++++++++----------------------- 2 files changed, 25 insertions(+), 44 deletions(-) diff --git a/tracking/monitors/monitors.py b/tracking/monitors/monitors.py index d1bb18e..6eb7bd9 100644 --- a/tracking/monitors/monitors.py +++ b/tracking/monitors/monitors.py @@ -842,7 +842,8 @@ class TuneMonitor(Monitor): save_fft : bool, optional If True, FFT data is saved. n_fft : int or float, optional - The number of points used for FFT computation. + The number of points used for FFT computation, if n_fft is bigger than + save_every zero-padding is applied. file_name : string, optional Name of the HDF5 where the data will be stored. Must be specified the first time a subclass of Monitor is instancied and must be None @@ -856,7 +857,7 @@ class TuneMonitor(Monitor): Total size of the save. The following relationships between the parameters must exist: total_size % buffer_size == 0 - number of call to track / save_every == total_size + number of call to track / save_every == total_size - 1 mpi_mode : bool, optional If True, open the HDF5 file in parallel mode, which is needed to allow several cores to write in the same file at the same time. @@ -897,7 +898,7 @@ class TuneMonitor(Monitor): self.index_sample = sorted(random.sample(list(index), self.sample_size)) self.save_count = 0 - self.buffer_count = 1 + self.buffer_count = 0 self.save_tune = save_tune self.save_fft = save_fft @@ -930,7 +931,7 @@ class TuneMonitor(Monitor): else: raise TypeError("object_to_save should be a Beam or Bunch object.") - if skip is not True: + if skip is False: self.x[:, self.save_count] = bunch["x"][self.index_sample] self.y[:, self.save_count] = bunch["y"][self.index_sample] self.tau[:, self.save_count] = bunch["tau"][self.index_sample] diff --git a/tracking/monitors/plotting.py b/tracking/monitors/plotting.py index 2b06b97..a4c7a50 100644 --- a/tracking/monitors/plotting.py +++ b/tracking/monitors/plotting.py @@ -493,7 +493,7 @@ def plot_wakedata(filename, bunch_number, wake_type="Wlong", start=0, elif streak_plot is True: return fig2 -def plot_tunedata(filename, bunch_number, ring=None, plot_tune=True, plot_fft=False, +def plot_tunedata(filename, bunch_number, f0, plot_tune=True, plot_fft=False, dimension='x', min_tune=0, max_tune=0.5, min_turn=None, max_turn=None, streak_plot=True, profile_plot=False): """ @@ -506,12 +506,10 @@ def plot_tunedata(filename, bunch_number, ring=None, plot_tune=True, plot_fft=Fa bunch_number : int Bunch to plot. This has to be identical to 'bunch_number' parameter in 'BunchMonitor' object. - ring : Synchrotron object, optional - The ring configuration that is used in TuneMonitor. If None, the default - value of the revolution period and the revolution frequency are used, - which are 1.183 us and 0.845 MHz, respectively. + f0 : float + Revolution frequency of the ring used for the tracking in [Hz]. plot_tune : bool, optional - If True, tune data is plotted. + If True, tune data usinf NAFF is plotted. plot_fft : bool, optional If True, FFT data is plotted. dimension : {'x', 'y', 's'} @@ -522,13 +520,13 @@ def plot_tunedata(filename, bunch_number, ring=None, plot_tune=True, plot_fft=Fa The minimum and the maximum number of turns to plot FFT data. streak_plot : bool, optional If True, the FFT data is plotted as a streak plot. - bunch_profile : bool, optional. - If True, the FFT data is plotted as line profiles. + profile_plot : bool, optional. + If True, the FFT data is plotted as line plots. Return ------ fig : Figure - Figure object with the plot on it. + Figure objects with the plot on it. """ @@ -537,30 +535,29 @@ def plot_tunedata(filename, bunch_number, ring=None, plot_tune=True, plot_fft=Fa group = "TuneData_{0}".format(bunch_number) # Data group of the HDF5 file time = file[group]["time"] + fig_to_return = [] + if plot_tune is True: tune = file[group]["tune"] tune_spread = file[group]["tune_spread"] fig1, ax1 = plt.subplots() - ax1.errorbar(x=time[1:], y=tune[0,1:], yerr=tune_spread[0,1:]) - ax1.errorbar(x=time[1:], y=tune[1,1:], yerr=tune_spread[1,1:]) + ax1.errorbar(x=time, y=tune[0,:], yerr=tune_spread[0,:]) + ax1.errorbar(x=time, y=tune[1,:], yerr=tune_spread[1,:]) ax1.set_xlabel("Turn number") ax1.set_ylabel("Transverse tunes") plt.legend(["x","y"]) + fig_to_return.append(fig1) fig2, ax2 = plt.subplots() - ax2.errorbar(x=time[1:], y=tune[2,1:], yerr=tune_spread[2,1:]) + ax2.errorbar(x=time, y=tune[2,:], yerr=tune_spread[2,:]) ax2.set_xlabel("Turn number") ax2.set_ylabel("Synchrotron tune") + fig_to_return.append(fig2) if plot_fft is True: - if ring is None: - T0 = 1.183e-06 - f0 = 0.845e6 - else: - T0 = ring.T0 - f0 = ring.f0 + T0 = 1/f0 n_freq = file[group]['fft'].shape[1] freq = rfftfreq((n_freq-1)*2, T0) tune_fft = freq / f0 @@ -573,12 +570,12 @@ def plot_tunedata(filename, bunch_number, ring=None, plot_tune=True, plot_fft=Fa if max_turn is None: max_turn = time[-1] if min_turn is None: - min_turn = time[1] + min_turn = time[0] min_tune_iloc = np.where(tune_fft >= min_tune)[0][0] max_tune_iloc = np.where(tune_fft <= max_tune)[0][-1] save_every = int(time[1] - time[0]) - min_turn_iloc = min_turn // save_every + min_turn_iloc = min_turn // save_every - 1 max_turn_iloc = max_turn // save_every @@ -595,6 +592,7 @@ def plot_tunedata(filename, bunch_number, ring=None, plot_tune=True, plot_fft=Fa ax3.set_ylabel("Turns") cbar = fig3.colorbar(c, ax=ax3) cbar.set_label("log FFT amplitude") + fig_to_return.append(fig3) if profile_plot is True: fig4, ax4 = plt.subplots() @@ -604,28 +602,11 @@ def plot_tunedata(filename, bunch_number, ring=None, plot_tune=True, plot_fft=Fa ax4.set_xlabel('$Q_{}$'.format(dimension)) ax4.set_ylabel("FFT amplitude") ax4.legend(time[min_turn_iloc:max_turn_iloc+1]) + fig_to_return.append(fig4) file.close() - - if plot_tune is True and plot_fft is True: - if streak_plot is True and profile_plot is True: - return fig1, fig2, fig3, fig4 - elif streak_plot is True: - return fig1, fig2, fig3 - elif profile_plot is True: - return fig1, fig2, fig4 - - elif plot_tune is True: - return fig1, fig2 - - elif plot_fft is True: - if streak_plot is True and profile_plot is True: - return fig3, fig4 - elif streak_plot is True: - return fig3 - elif profile_plot is True: - return fig4 + return tuple(fig_to_return) def plot_cavitydata(filename, cavity_name, phasor="cavity", plot_type="bunch", bunch_number=0, turn=None): @@ -740,4 +721,3 @@ def plot_cavitydata(filename, cavity_name, phasor="cavity", file.close() return fig - return fig -- GitLab