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