diff --git a/tracking/monitors/__init__.py b/tracking/monitors/__init__.py
index 8309d51c3918d422452f64646626eac858ff1d08..adc490ba661610646c8ad5831362e407daf7984f 100644
--- a/tracking/monitors/__init__.py
+++ b/tracking/monitors/__init__.py
@@ -17,4 +17,5 @@ from mbtrack2.tracking.monitors.plotting import (plot_bunchdata,
                                                  plot_profiledata,
                                                  plot_beamdata,
                                                  plot_wakedata,
-                                                 plot_tunedata)
\ No newline at end of file
+                                                 plot_tunedata,
+                                                 plot_cavitydata)
\ No newline at end of file
diff --git a/tracking/monitors/monitors.py b/tracking/monitors/monitors.py
index 1d66539280b71ec7c5c08db334155c1c2c345d0c..01a2e217b660a2c8a2c8d0cf4352a0a72e5bb988 100644
--- a/tracking/monitors/monitors.py
+++ b/tracking/monitors/monitors.py
@@ -77,7 +77,8 @@ class Monitor(Element, metaclass=ABCMeta):
             raise ValueError
             
     def monitor_init(self, group_name, save_every, buffer_size, total_size,
-                     dict_buffer, dict_file, file_name=None, mpi_mode=True):
+                     dict_buffer, dict_file, file_name=None, mpi_mode=True,
+                     dict_dtype=None):
         """
         Method called to initialize Monitor subclass. 
         
@@ -112,6 +113,10 @@ class Monitor(Element, metaclass=ABCMeta):
             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.
             If False, open the HDF5 file in standard mode.
+        dict_dtype : dict, optional
+            Dictionary with keys as the attribute name to save and values as
+            the dtype to use to save the values.
+            If None, float is used for all attributes.
         """
         
         # setup and open common file for all monitors
@@ -142,7 +147,10 @@ class Monitor(Element, metaclass=ABCMeta):
         
         # setup attribute buffers from values given in dict_buffer
         for key, value in dict_buffer.items():
-            self.__setattr__(key,np.zeros(value))
+            if dict_dtype == None:
+                self.__setattr__(key,np.zeros(value))
+            else:
+                self.__setattr__(key,np.zeros(value, dtype=dict_dtype[key]))
         self.time = np.zeros((self.buffer_size,), dtype=int)
 
         # create HDF5 groups and datasets to save data from group_name and 
@@ -150,7 +158,10 @@ class Monitor(Element, metaclass=ABCMeta):
         self.g = self.file.require_group(self.group_name)
         self.g.require_dataset("time", (self.total_size,), dtype=int)
         for key, value in dict_file.items():
-            self.g.require_dataset(key, value, dtype=float)
+            if dict_dtype == None:
+                self.g.require_dataset(key, value, dtype=float)
+            else:
+                self.g.require_dataset(key, value, dtype=dict_dtype[key])
         
         # create a dictionary which handle slices
         slice_dict = {}
@@ -388,6 +399,8 @@ class BeamMonitor(Monitor):
     
     Parameters
     ----------
+    h : int
+        Harmonic number of the ring.
     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
@@ -602,10 +615,10 @@ class ProfileMonitor(Monitor):
         dict_buffer = {}
         dict_file = {}
         for index, dim in enumerate(self.dimensions):
-            dict_buffer.update({dim : (self.n_bin[index], buffer_size)})
-            dict_buffer.update({dim + "_bin" : (self.n_bin[index] + 1, buffer_size)})
-            dict_file.update({dim : (self.n_bin[index], total_size)})
-            dict_file.update({dim + "_bin" : (self.n_bin[index] + 1, total_size)})
+            dict_buffer.update({dim : (self.n_bin[index] - 1, buffer_size)})
+            dict_buffer.update({dim + "_bin" : (self.n_bin[index] - 1, buffer_size)})
+            dict_file.update({dim : (self.n_bin[index] - 1, total_size)})
+            dict_file.update({dim + "_bin" : (self.n_bin[index] - 1, total_size)})
 
         self.monitor_init(group_name, save_every, buffer_size, total_size,
                           dict_buffer, dict_file, file_name, mpi_mode)
@@ -624,11 +637,9 @@ class ProfileMonitor(Monitor):
 
         self.time[self.buffer_count] = self.track_count
         for index, dim in enumerate(self.dimensions):
-            bins, sorted_index, profile = bunch.binning(dim, self.n_bin[index])
-            bin_array = np.append(np.array(bins.left), bins.right[-1])
-            profile_array = np.array(profile)
-            self.__getattribute__(dim + "_bin")[:, self.buffer_count] = bin_array
-            self.__getattribute__(dim)[:, self.buffer_count] = profile_array
+            bins, sorted_index, profile, center = bunch.binning(dim, self.n_bin[index])
+            self.__getattribute__(dim + "_bin")[:, self.buffer_count] = center
+            self.__getattribute__(dim)[:, self.buffer_count] = profile
         
         self.buffer_count += 1
         
@@ -997,6 +1008,7 @@ class CavityMonitor(Monitor):
     ----------
     cavity_name : str
         Name of the CavityResonator object to monitor.
+    ring : Synchrotron object
     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
@@ -1018,37 +1030,51 @@ class CavityMonitor(Monitor):
 
     Methods
     -------
-    track(object_to_save)
+    track(beam, cavity)
         Save data
     """
     
-    def __init__(self, cavity_name, file_name=None, save_every=5,
+    def __init__(self, cavity_name, ring, file_name=None, save_every=5,
                  buffer_size=500, total_size=2e4, mpi_mode=True):
         
         self.cavity_name = cavity_name
+        self.ring = ring
+        
         group_name = cavity_name
-        dict_buffer = {"cavity_voltage":(buffer_size,), 
-                       "cavity_phase":(buffer_size,)}
-        dict_file = {"cavity_voltage":(total_size,), 
-                     "cavity_phase":(total_size,)}
-
+        dict_buffer = {"cavity_phasor_record":(ring.h, buffer_size,),
+                       "beam_phasor_record":(ring.h, buffer_size,),
+                       "detune":(buffer_size,)}
+        dict_file = {"cavity_phasor_record":(ring.h, total_size,),
+                     "beam_phasor_record":(ring.h, total_size,),
+                      "detune":(total_size,)}
+        dict_dtype = {"cavity_phasor_record":complex,
+                      "beam_phasor_record":complex,
+                      "detune":float}
+        
         self.monitor_init(group_name, save_every, buffer_size, total_size,
-                          dict_buffer, dict_file, file_name, mpi_mode)
+                          dict_buffer, dict_file, file_name, mpi_mode, 
+                          dict_dtype)
         
         self.dict_buffer = dict_buffer
         self.dict_file = dict_file
                     
-    def track(self, cavity):
+    def track(self, beam, cavity):
         """
         Save data
         
         Parameters
         ----------
+        beam : Beam object
         cavity : CavityResonator object
         """        
         if self.track_count % self.save_every == 0:
             if isinstance(cavity, CavityResonator):
-                self.to_buffer(cavity)
+                if beam.mpi_switch == False:
+                    self.to_buffer(cavity)
+                elif beam.mpi.rank == 0:
+                    self.to_buffer(cavity)
+                else:
+                    pass
             else:                            
                 raise TypeError("cavity should be a CavityResonator object.")
         self.track_count += 1
diff --git a/tracking/monitors/plotting.py b/tracking/monitors/plotting.py
index f2f247c2f832306677d645ad2f21df998d0e8878..9078150ef0c4aafd41cdd26ee0644fb3c61bbf21 100644
--- a/tracking/monitors/plotting.py
+++ b/tracking/monitors/plotting.py
@@ -328,7 +328,7 @@ def plot_profiledata(filename, bunch_number, dimension="tau", start=0,
         turn_index = start_index + i * step / save_every 
         turn_index_array[i] = turn_index
         # construct an array of bin mids
-        x_var[i,:] = 0.5*(l_bound[:-1,turn_index]+l_bound[1:,turn_index])
+        x_var[i,:] = l_bound[:,turn_index]
         
     if profile_plot is True:
         fig, ax = plt.subplots()
@@ -531,4 +531,118 @@ 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)  
+
+def plot_cavitydata(filename, cavity_name, phasor="cavity", 
+                    plot_type="bunch", bunch_number=0, turn=None):
+    """
+    Plot data recorded by CavityMonitor.
+
+    Parameters
+    ----------
+    filename : str 
+        Name of the HDF5 file that contains the data.
+    cavity_name : str
+        Name of the CavityResonator object.
+    phasor : str, optional
+        Type of the phasor to plot. Can be "beam" or "cavity".
+    plot_type : str, optional
+        Type of plot:
+            - "bunch" plots the phasor voltage and angle versus time for a 
+            given bunch.
+            - "turn" plots the phasor voltage and ange versus bunch index for
+            a given turn.
+            - "streak_volt" plots the phasor voltage versus bunch index and 
+            time
+            - "streak_angle" plots the phasor angle versus bunch index and 
+            time
+    bunch_number : int, optional
+        Bunch number to select. The default is 0.
+    turn : int, optional
+        Turn to plot. The default is None.
+
+    Returns
+    -------
+    fig : Figure
+        Figure object with the plot on it.
+
+    """
+    
+    file = hp.File(filename, "r")
+    cavity_data = file[cavity_name]
+    
+    time = cavity_data["time"]
+    
+    ph = {"cavity":0, "beam":1}
+    labels = ["Cavity", "Beam"]
+    
+    if plot_type == "bunch":
+    
+        data = [cavity_data["cavity_phasor_record"][bunch_number,:], 
+                cavity_data["beam_phasor_record"][bunch_number,:]]
+
+        ylabel1 = labels[ph[phasor]] + " voltage [MV]"
+        ylabel2 = labels[ph[phasor]] + " phase [rad]"
+        
+        fig, ax = plt.subplots()
+        twin = ax.twinx()
+        p1, = ax.plot(time, np.abs(data[ph[phasor]])*1e-6, color="r",label=ylabel1)
+        p2, = twin.plot(time, np.angle(data[ph[phasor]]), color="b", label=ylabel2)
+        ax.set_xlabel("Turn number")
+        ax.set_ylabel(ylabel1)
+        twin.set_ylabel(ylabel2)
+        
+        plots = [p1, p2]
+        ax.legend(handles=plots, loc="best")
+        
+        ax.yaxis.label.set_color("r")
+        twin.yaxis.label.set_color("b")
+        
+    if plot_type == "turn":
+        
+        index = time == turn
+        
+        ph = {"cavity":0, "beam":1}
+        data = [cavity_data["cavity_phasor_record"][:,index], 
+                cavity_data["beam_phasor_record"][:,index]]
+        labels = ["Cavity", "Beam"]
+        
+        h=len(data[0])
+        x=np.arange(h)
+
+        ylabel1 = labels[ph[phasor]] + " voltage [MV]"
+        ylabel2 = labels[ph[phasor]] + " phase [rad]"
+        
+        fig, ax = plt.subplots()
+        twin = ax.twinx()
+        p1, = ax.plot(x, np.abs(data[ph[phasor]])*1e-6, color="r",label=ylabel1)
+        p2, = twin.plot(x, np.angle(data[ph[phasor]]), color="b", label=ylabel2)
+        ax.set_xlabel("Bunch index")
+        ax.set_ylabel(ylabel1)
+        twin.set_ylabel(ylabel2)
+        
+        plots = [p1, p2]
+        ax.legend(handles=plots, loc="best")
+        
+        ax.yaxis.label.set_color("r")
+        twin.yaxis.label.set_color("b")
+        
+    if plot_type == "streak_volt" or plot_type == "streak_phase":
+        
+        if plot_type == "streak_volt":
+            data = np.transpose(np.abs(cavity_data["cavity_phasor_record"][:,:])*1e-6)
+            ylabel = labels[ph[phasor]] + " voltage [MV]"
+        elif plot_type == "streak_phase":
+            data = np.transpose(np.angle(cavity_data["cavity_phasor_record"][:,:]))
+            ylabel = labels[ph[phasor]] + " phase [rad]"
+            
+        fig, ax = plt.subplots()
+        cmap = mpl.cm.cool
+        c = ax.imshow(data, cmap=cmap, origin='lower' , aspect='auto')
+        ax.set_xlabel("Bunch index")
+        ax.set_ylabel("Number of turns")
+        cbar = fig.colorbar(c, ax=ax)
+        cbar.set_label(ylabel) 
+    
+    file.close()
+    return fig
\ No newline at end of file
diff --git a/tracking/particles.py b/tracking/particles.py
index cf03762c4dcbe29b97484cdeb118231bcbe2678f..4e515376fd04bc3801b8036bb4ca700d6e4a50ad 100644
--- a/tracking/particles.py
+++ b/tracking/particles.py
@@ -715,7 +715,7 @@ class Beam:
             self.mpi.comm.Allgather([center,  MPI.DOUBLE], [self.mpi.__getattribute__(dim + "_center"), MPI.DOUBLE])
             
             self.mpi.__setattr__(dim + "_profile", np.empty((len(self), len(profile)), dtype=np.int64))
-            self.mpi.comm.Allgather([center,  MPI.INT64_T], [self.mpi.__getattribute__(dim + "_profile"), MPI.INT64_T])
+            self.mpi.comm.Allgather([profile,  MPI.INT64_T], [self.mpi.__getattribute__(dim + "_profile"), MPI.INT64_T])
             
             self.mpi.__setattr__(dim + "_sorted_index", sorted_index)
         
diff --git a/tracking/rf.py b/tracking/rf.py
index 3194e75cff031ea3a68d55dbd8032a344acbe521..8b553c5b223ff5abae612c83b1ad37cae5ba6a8c 100644
--- a/tracking/rf.py
+++ b/tracking/rf.py
@@ -78,8 +78,14 @@ class CavityResonator():
     ----------
     beam_phasor : complex
         Beam phasor in [V].
+    beam_phasor_record : array of complex
+        Last beam phasor value of each bunch in [V].
     generator_phasor : complex
         Generator phasor in [V].
+    cavity_phasor : complex
+        Cavity phasor in [V].
+    cavity_phasor_record : array of complex
+        Last cavity phasor value of each bunch in [V].
     cavity_voltage : float
         Cavity total voltage in [V].
     cavity_phase : float
@@ -165,6 +171,7 @@ class CavityResonator():
         self.Vc = Vc
         self.theta = theta
         self.beam_phasor = np.zeros(1, dtype=np.complex)
+        self.beam_phasor_record = np.zeros((self.ring.h), dtype=np.complex)
         self.tracking = False
         
     def init_tracking(self, beam):
@@ -202,61 +209,65 @@ class CavityResonator():
         if self.tracking is False:
             self.init_tracking(beam)
         
-        for j, bunch in enumerate(beam.not_empty):
+        for index, bunch in enumerate(beam):
             
-            index = self.valid_bunch_index[j]
-            
-            if beam.mpi_switch:
-                # get shared bunch profile for current bunch
-                center = beam.mpi.center_all[j]
-                profile = beam.mpi.profile_all[j]
-                bin_length = center[1]-center[0]
-                charge_per_mp = beam.mpi.charge_per_mp_all[j]
+            if beam.filling_pattern[index]:
+                
+                if beam.mpi_switch:
+                    # mpi -> get shared bunch profile for current bunch
+                    center = beam.mpi.tau_center[index]
+                    profile = beam.mpi.tau_profile[index]
+                    bin_length = center[1]-center[0]
+                    charge_per_mp = beam.mpi.charge_per_mp_all[index]
+                    if index == self.bunch_index:
+                        sorted_index = beam.mpi.tau_sorted_index
+                else:
+                    # no mpi -> get bunch profile for current bunch
+                    (bins, sorted_index, profile, center) = bunch.binning()
+                    bin_length = center[1]-center[0]
+                    charge_per_mp = bunch.charge_per_mp
+                    self.bunch_index = index
+                
+                energy_change = bunch["tau"]*0
+                
+                # remove part of beam phasor decay to be at the start of the binning (=bins[0])
+                self.phasor_decay(center[0] - bin_length/2, ref_frame="beam")
+                
+                if index != self.bunch_index:
+                    self.phasor_evol(profile, bin_length, charge_per_mp, ref_frame="beam")
+                else:
+                    # modify beam phasor
+                    for i, center0 in enumerate(center):
+                        mp_per_bin = profile[i]
+                        
+                        if mp_per_bin == 0:
+                            self.phasor_decay(bin_length, ref_frame="beam")
+                            continue
+                        
+                        ind = (sorted_index == i)
+                        phase = self.m * self.ring.omega1 * (center0 + self.ring.T1* (index + self.ring.h * self.nturn))
+                        Vgene = self.Vg*np.cos(phase + self.theta_g)
+                        Vbeam = np.real(self.beam_phasor)
+                        Vtot = Vgene + Vbeam - charge_per_mp*self.loss_factor*mp_per_bin
+                        energy_change[ind] = Vtot / self.ring.E0
+    
+                        self.beam_phasor -= 2*charge_per_mp*self.loss_factor*mp_per_bin
+                        self.phasor_decay(bin_length, ref_frame="beam")
+                
+                # phasor decay to be at t=0 of the current bunch (=-1*bins[-1])
+                self.phasor_decay(-1 * (center[-1] + bin_length/2), ref_frame="beam")
+                
                 if index == self.bunch_index:
-                    sorted_index = beam.mpi.sorted_index
-            else:
-                # get bunch profile for current bunch
-                (bins, sorted_index, profile, center) = bunch.binning()
-                bin_length = center[1]-center[0]
-                charge_per_mp = bunch.charge_per_mp
-                self.bunch_index = index
+                    # apply kick
+                    bunch["delta"] += energy_change
             
-            energy_change = bunch["tau"]*0
-            
-            # remove part of beam phasor decay to be at the start of the binning (=bins[0])
-            self.phasor_decay(center[0] - bin_length/2, ref_frame="beam")
-            
-            if index != self.bunch_index:
-                self.phasor_evol(profile, bin_length, charge_per_mp, ref_frame="beam")
-            else:
-                # modify beam phasor
-                for i, center0 in enumerate(center):
-                    mp_per_bin = profile[i]
-                    
-                    if mp_per_bin == 0:
-                        self.phasor_decay(bin_length, ref_frame="beam")
-                        continue
-                    
-                    ind = (sorted_index == i)
-                    phase = self.m * self.ring.omega1 * (center0 + self.ring.T1* (j + self.ring.h * self.nturn))
-                    Vgene = self.Vg*np.cos(phase + self.theta_g)
-                    Vbeam = np.real(self.beam_phasor)
-                    Vtot = Vgene + Vbeam - charge_per_mp*self.loss_factor*mp_per_bin
-                    energy_change[ind] = Vtot / self.ring.E0
-
-                    self.beam_phasor -= 2*charge_per_mp*self.loss_factor*mp_per_bin
-                    self.phasor_decay(bin_length, ref_frame="beam")
+            # save beam phasor value
+            self.beam_phasor_record[index] = self.beam_phasor
             
-            # phasor decay to be at t=0 of the current bunch (=-1*bins[-1])
-            self.phasor_decay(-1 * (center[-1] + bin_length/2), ref_frame="beam")
             # phasor decay to be at t=0 of the next bunch
-            self.phasor_decay( (self.distance[index] * self.ring.T1), ref_frame="beam")
-            
-            if index == self.bunch_index:
-                # apply kick
-                bunch["delta"] += energy_change
+            self.phasor_decay(self.ring.T1, ref_frame="beam")
                 
-            self.nturn += 1
+        self.nturn += 1
                 
         
     def init_phasor(self, beam):
@@ -283,13 +294,23 @@ class CavityResonator():
                 
                 if beam.mpi_switch:
                     # get shared bunch profile for current bunch
-                    center = beam.mpi.center_all[j]
-                    profile = beam.mpi.profile_all[j]
+                    center = beam.mpi.tau_center[j]
+                    profile = beam.mpi.tau_profile[j]
                     bin_length = center[1]-center[0]
                     charge_per_mp = beam.mpi.charge_per_mp_all[j]
                 else:
-                    # get bunch profile for current bunch
-                    (bins, sorted_index, profile, center) = bunch.binning()
+                    if i == 0:
+                        # get bunch profile for current bunch
+                        (bins, sorted_index, profile, center) = bunch.binning()
+                        if j == 0:
+                            self.profile_save = np.zeros((len(beam),len(profile),))
+                            self.center_save = np.zeros((len(beam),len(center),))
+                        self.profile_save[j,:] = profile
+                        self.center_save[j,:] = center
+                    else:
+                        profile = self.profile_save[j,:]
+                        center = self.center_save[j,:]
+                        
                     bin_length = center[1]-center[0]
                     charge_per_mp = bunch.charge_per_mp
                 
@@ -367,18 +388,16 @@ class CavityResonator():
         """Cavity total phasor in [V]"""
         return self.generator_phasor + self.beam_phasor
     
+    @property
+    def cavity_phasor_record(self):
+        """Last cavity phasor value of each bunch in [V]"""
+        return self.generator_phasor + self.beam_phasor_record
+    
     @property
     def cavity_voltage(self):
         """Cavity total voltage in [V]"""
         return np.abs(self.cavity_phasor)
     
-    def cavity_real_voltage(self, t):
-        """Cavity total voltage in [V]"""
-        Vg = self.Vg*np.exp(1j*(self.m*self.ring.omega1*t + self.theta_g))
-        Vb = self.beam_phasor*np.exp((-1/self.filling_time +
-                                  1j*2*np.pi*self.detune)*t)
-        return np.real(Vg+Vb)
-    
     @property
     def cavity_phase(self):
         """Cavity total phase in [rad]"""