From 8a09649dd88883d34d88f886791664fcd7e26411 Mon Sep 17 00:00:00 2001
From: Alexis Gamelin <alexis.gamelin@synchrotron-soleil.fr>
Date: Thu, 16 May 2024 17:20:51 +0200
Subject: [PATCH] Document modifications

---
 mbtrack2/impedance/wakefield.py   | 16 ++++++++++---
 mbtrack2/tracking/rf.py           | 37 ++++++++++++++++---------------
 mbtrack2/tracking/synchrotron.py  | 25 ++++++++++++++++++---
 mbtrack2/utilities/beamloading.py | 10 +++++++++
 4 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/mbtrack2/impedance/wakefield.py b/mbtrack2/impedance/wakefield.py
index ee83e57..5ef7bea 100644
--- a/mbtrack2/impedance/wakefield.py
+++ b/mbtrack2/impedance/wakefield.py
@@ -600,6 +600,8 @@ class Impedance(ComplexData):
         Return a WakeFunction object from the impedance data.
     plot()
         Plot the impedance data.
+    to_pycolleff()
+        Convenience method to export impedance to pycolleff.
     """
 
     def __init__(self,
@@ -782,7 +784,18 @@ class Impedance(ComplexData):
         return ax
     
     def to_pycolleff(self):
+        """
+        Convenience method to export impedance to pycolleff.
+        Only implemented for longitudinal impedance.
+
+        Returns
+        -------
+        imp : pycolleff.longitudinal_equilibrium.ImpedanceSource
+            pycolleff ImpedanceSource object
+        """
+        # pycolleff is a soft dependency
         from pycolleff.longitudinal_equilibrium import ImpedanceSource
+        # avoid circular import
         from mbtrack2.utilities.misc import double_sided_impedance
         imp = ImpedanceSource()
         if self.component_type == "long":
@@ -793,10 +806,7 @@ class Impedance(ComplexData):
         else:
             raise NotImplementedError()
         
-        # Methods: Impedance or Wake
         imp.calc_method = ImpedanceSource.Methods.ImpedanceDFT
-        
-        # Device type: Active of Passive
         imp.active_passive = ImpedanceSource.ActivePassive.Passive
         
         return imp
diff --git a/mbtrack2/tracking/rf.py b/mbtrack2/tracking/rf.py
index 149b03e..41284a1 100644
--- a/mbtrack2/tracking/rf.py
+++ b/mbtrack2/tracking/rf.py
@@ -191,6 +191,8 @@ class CavityResonator():
         Force feedback update from current CavityResonator parameters.
     sample_voltage()
         Sample the voltage seen by a zero charge particle during an RF period.
+    to_pycolleff()
+        Convenience method to export a CavityResonator to pycolleff.
     
     References
     ----------
@@ -1143,6 +1145,22 @@ class CavityResonator():
         return pos, voltage_rec
     
     def to_pycolleff(self, Impedance=True):
+        """
+        Convenience method to export a CavityResonator to pycolleff.
+        
+        Parameters
+        ----------
+        Impedance : bool, optional
+            If True, export as impedance (i.e. ImpedanceSource.Methods.ImpedanceDFT).
+            If False, export as wake (i.e. ImpedanceSource.Methods.Wake).
+            Default is True.
+
+        Returns
+        -------
+        cav : pycolleff ImpedanceSource object
+
+        """
+        # pycolleff is a soft dependency
         from pycolleff.longitudinal_equilibrium import ImpedanceSource
         
         cav = ImpedanceSource()
@@ -1156,24 +1174,7 @@ class CavityResonator():
         if self.Vg != 0:
             cav.active_passive = ImpedanceSource.ActivePassive.Active
             if Impedance:
-                cav.calc_method = ImpedanceSource.Methods.ImpedanceDFT
-                # Define PID transfer function for control loop
-                def pid_transfer_func(w, wrf, gain=1, kp=1, ki=1, kd=0, delay=0):
-                    phase = wrf * delay
-                    exp_delay = np.exp(-1j * delay * w)
-                    exp_phase = np.exp(1j * phase)
-                    eps = 1e-16
-                    pid_ctrl = kp + ki / 1j / (w - wrf + eps) + kd * 1j * (w - wrf)
-                    transfer = gain * pid_ctrl * exp_delay * exp_phase
-                    return transfer
-                
-                delay = 1.9e-6
-                ki = 0.01
-                kp = 2.96e-6
-                kd = 0
-                cav.loop_ctrl_ang_freq = self.ring.omega1
-                cav.loop_ctrl_transfer = partial(pid_transfer_func, kp=kp, ki=ki, delay=delay)
-                # cav.loop_ctrl_transfer = partial(pid_transfer_func, kp=0, ki=1, delay=0)
+                raise NotImplementedError()
             else:
                 cav.calc_method = ImpedanceSource.Methods.Wake         
         else:
diff --git a/mbtrack2/tracking/synchrotron.py b/mbtrack2/tracking/synchrotron.py
index 8a4dd02..fa37923 100644
--- a/mbtrack2/tracking/synchrotron.py
+++ b/mbtrack2/tracking/synchrotron.py
@@ -116,6 +116,8 @@ class Synchrotron:
         single or multi-harmonic RF systems.
     to_pyat(Vrf)
         Return a pyAT simple_ring element from the Synchrotron element data.
+    to_pycolleff(I0, Vrf, bunch_number)
+        Return a pycolleff Ring element from the Synchrotron element data.
     """
 
     def __init__(self, h, optics, particle, **kwargs):
@@ -585,7 +587,26 @@ class Synchrotron:
                                      TimeLag=TimeLag)
         return at_simple_ring
     
-    def to_pycolleff(self, I0, Vrf, bunch_number, delta=0):
+    def to_pycolleff(self, I0, Vrf, bunch_number):
+        """
+        Return a pycolleff Ring element from the Synchrotron element data.
+
+        Parameters
+        ----------
+        I0 : float
+            Beam current in [A].
+        Vrf : float
+            RF voltage in [V].
+        bunch_number : int
+            Total number of bunches filled.
+
+        Returns
+        -------
+        ring : pycolleff.colleff.Ring
+            pycolleff Ring object.
+
+        """
+        # pycolleff is a soft dependency
         from pycolleff.colleff import Ring
         
         ring = Ring()
@@ -599,7 +620,6 @@ class Synchrotron:
         ring.chromy = self.chro[1]  # vertical chromaticity
         ring.harm_num = self.h  # harmonic Number
         ring.num_bun = bunch_number  # number of bunches filled
-        
         ring.total_current = I0  # total current [A]
         ring.sync_tune = self.synchrotron_tune(Vrf)  # synchrotron tune
         ring.espread = self.sigma_delta
@@ -609,7 +629,6 @@ class Synchrotron:
         ring.dampte = self.tau[2]  # [s]
         ring.en_lost_rad = self.U0 # [eV]
         ring.gap_voltage = Vrf  # [V]
-        ring.delta_HC = delta
         
         return ring
 
diff --git a/mbtrack2/utilities/beamloading.py b/mbtrack2/utilities/beamloading.py
index 041741b..b51554f 100644
--- a/mbtrack2/utilities/beamloading.py
+++ b/mbtrack2/utilities/beamloading.py
@@ -397,6 +397,16 @@ class BeamLoadingEquilibrium():
     
     @property
     def R_factor(self):
+        """
+        Touschek lifetime ratio as defined in [1].
+            
+        Reference
+        ---------
+        [1] : Byrd, J. M., and M. Georgsson. "Lifetime increase using passive 
+        harmonic cavities in synchrotron light sources." Physical Review 
+        Special Topics-Accelerators and Beams 4.3 (2001): 030701.
+
+        """
         rho0 = gaussian_bunch(self.tau0, self.ring.sigma_0)/c
         R = trapz(rho0**2, self.tau0)/trapz(self.rho0**2, self.tau0)
         return R
-- 
GitLab