"""
Module. Includes classes for RF accelerator nodes.
"""
import math
# import teapot drift class
from orbit.teapot import DriftTEAPOT
# import RF cavity classes
from orbit.core.rfcavities import Frequency_Cav, Harmonic_Cav, Barrier_Cav, Dual_Harmonic_Cav
class Base_RFNode(DriftTEAPOT):
def __init__(self, length, name="base_rfnode"):
"""
Constructor. Creates Base RF Cavity TEAPOT element.
It will never be called.
"""
DriftTEAPOT.__init__(self, name)
self.setType("base rf node")
self.setLength(0.0)
def trackBunch(self, bunch):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
# put the track method here:
# self..trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
def track(self, paramsDict):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
bunch = paramsDict["bunch"]
# put the track method here:
# self..trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs]class Frequency_RFNode(Base_RFNode):
def __init__(self, RFFreq, RFE0TL, RFPhase, length, name="frequency_rfnode"):
"""
Constructor. Creates Frequency
RF Cavity TEAPOT element
"""
Base_RFNode.__init__(self, length, name)
self.frequencynode = Frequency_Cav(RFFreq, RFE0TL, RFPhase)
self.setType("frequency rf node")
self.setLength(0.0)
[docs] def trackBunch(self, bunch):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
# put the track method here:
self.frequencynode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs] def track(self, paramsDict):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
bunch = paramsDict["bunch"]
# put the track method here:
self.frequencynode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs]class Harmonic_RFNode(Base_RFNode):
def __init__(self, ZtoPhi, dESync, RFHNum, RFVoltage, RFPhase, length, name="harmonic_rfnode"):
"""
Constructor. Creates Harmonic
RF Cavity TEAPOT element
"""
Base_RFNode.__init__(self, length, name)
self.harmonicnode = Harmonic_Cav(ZtoPhi, dESync, RFHNum, RFVoltage, RFPhase)
self.setType("harmonic rf node")
self.setLength(0.0)
[docs] def trackBunch(self, bunch):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
# put the track method here:
self.harmonicnode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs] def track(self, paramsDict):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
bunch = paramsDict["bunch"]
# put the track method here:
self.harmonicnode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
class Dual_Harmonic_RFNode(Base_RFNode):
def __init__(self, ZtoPhi, RFHNum, RatioRFHNum, RFVoltage, RatioVoltage, RFPhase, RFPhase2, length, name="harmonic_rfnode"):
"""
Constructor. Creates Harmonic
RF Cavity TEAPOT element
"""
Base_RFNode.__init__(self, length, name)
self.dualharmonicnode = Dual_Harmonic_Cav(ZtoPhi, RFHNum, RatioRFHNum, RFVoltage, RatioVoltage, RFPhase, RFPhase2)
self.setType("dual harmonic rf node")
self.setLength(0.0)
def trackBunch(self, bunch):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
# put the track method here:
self.dualharmonicnode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
def track(self, paramsDict):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
bunch = paramsDict["bunch"]
# put the track method here:
self.dualharmonicnode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs]class BRhoDep_Harmonic_RFNode(Base_RFNode):
def __init__(self, ZtoPhi, accelDict, bunch, length, name="brho_timedep_harmonic_rfnode"):
"""
Constructor. Creates BRho Time Dependent
Harmonic RF Cavity TEAPOT element
"""
Base_RFNode.__init__(self, length, name)
self.Z2Phi = ZtoPhi
self.localDict = accelDict
gammaTrans = self.localDict["gammaTrans"]
RFHNum = self.localDict["RFHNum"]
n_tuple = self.localDict["n_tuple"]
time_tuple = self.localDict["time"]
BRho_tuple = self.localDict["BRho"]
RFVoltage_tuple = self.localDict["RFVoltage"]
RFPhase_tuple = self.localDict["RFPhase"]
time = bunch.getSyncParticle().time()
mass = bunch.mass()
charge = bunch.charge()
gamma = bunch.getSyncParticle().gamma()
keold = bunch.getSyncParticle().kinEnergy()
eold = keold + mass
RFVoltage = interp(time, n_tuple, time_tuple, RFVoltage_tuple)
RFPhase = interp(time, n_tuple, time_tuple, RFPhase_tuple)
BRho = interp(time, n_tuple, time_tuple, BRho_tuple)
pcnew = 0.299792458 * charge * BRho
enew = math.sqrt(pcnew * pcnew + mass * mass)
kenew = enew - mass
bunch.getSyncParticle().kinEnergy(kenew)
dESync = enew - eold
Zsync = syncZ(ZtoPhi, gammaTrans, gamma, charge, dESync, RFHNum, RFVoltage, RFPhase)
bunch.getSyncParticle().z(Zsync)
self.harmonicnode = Harmonic_Cav(ZtoPhi, dESync, RFHNum, RFVoltage, RFPhase)
self.setType("harmonic rf node")
self.setLength(0.0)
[docs] def trackBunch(self, bunch):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
gammaTrans = self.localDict["gammaTrans"]
RFHNum = self.localDict["RFHNum"]
n_tuple = self.localDict["n_tuple"]
time_tuple = self.localDict["time"]
BRho_tuple = self.localDict["BRho"]
RFVoltage_tuple = self.localDict["RFVoltage"]
RFPhase_tuple = self.localDict["RFPhase"]
time = bunch.getSyncParticle().time()
mass = bunch.mass()
charge = bunch.charge()
gamma = bunch.getSyncParticle().gamma()
keold = bunch.getSyncParticle().kinEnergy()
eold = keold + mass
RFVoltage = interp(time, n_tuple, time_tuple, RFVoltage_tuple)
RFPhase = interp(time, n_tuple, time_tuple, RFPhase_tuple)
BRho = interp(time, n_tuple, time_tuple, BRho_tuple)
pcnew = 0.299792458 * charge * BRho
enew = math.sqrt(pcnew * pcnew + mass * mass)
kenew = enew - mass
bunch.getSyncParticle().kinEnergy(kenew)
dESync = enew - eold
ZtoPhi = self.Z2Phi
Zsync = syncZ(ZtoPhi, gammaTrans, gamma, charge, dESync, RFHNum, RFVoltage, RFPhase)
bunch.getSyncParticle().z(Zsync)
self.harmonicnode.dESync(dESync)
self.harmonicnode.RFVoltage(RFVoltage)
self.harmonicnode.RFPhase(RFPhase)
# put the track method here:
self.harmonicnode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs] def track(self, paramsDict):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
bunch = paramsDict["bunch"]
gammaTrans = self.localDict["gammaTrans"]
RFHNum = self.localDict["RFHNum"]
n_tuple = self.localDict["n_tuple"]
time_tuple = self.localDict["time"]
BRho_tuple = self.localDict["BRho"]
RFVoltage_tuple = self.localDict["RFVoltage"]
RFPhase_tuple = self.localDict["RFPhase"]
time = bunch.getSyncParticle().time()
mass = bunch.mass()
charge = bunch.charge()
gamma = bunch.getSyncParticle().gamma()
keold = bunch.getSyncParticle().kinEnergy()
eold = keold + mass
RFVoltage = interp(time, n_tuple, time_tuple, RFVoltage_tuple)
RFPhase = interp(time, n_tuple, time_tuple, RFPhase_tuple)
BRho = interp(time, n_tuple, time_tuple, BRho_tuple)
pcnew = 0.299792458 * charge * BRho
enew = math.sqrt(pcnew * pcnew + mass * mass)
kenew = enew - mass
bunch.getSyncParticle().kinEnergy(kenew)
dESync = enew - eold
ZtoPhi = self.Z2Phi
Zsync = syncZ(ZtoPhi, gammaTrans, gamma, charge, dESync, RFHNum, RFVoltage, RFPhase)
bunch.getSyncParticle().z(Zsync)
self.harmonicnode.dESync(dESync)
self.harmonicnode.RFVoltage(RFVoltage)
self.harmonicnode.RFPhase(RFPhase)
# put the track method here:
self.harmonicnode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs]class SyncPhaseDep_Harmonic_RFNode(Base_RFNode):
def __init__(self, ZtoPhi, accelDict, bunch, length, name="syncphase_timedep_harmonic_rfnode"):
"""
Constructor. Creates SyncPhase Time Dependent
Harmonic RF Cavity TEAPOT element
"""
Base_RFNode.__init__(self, length, name)
self.Z2Phi = ZtoPhi
self.localDict = accelDict
gammaTrans = self.localDict["gammaTrans"]
RFHNum = self.localDict["RFHNum"]
n_tuple = self.localDict["n_tuple"]
time_tuple = self.localDict["time"]
SyncPhase_tuple = self.localDict["SyncPhase"]
RFVoltage_tuple = self.localDict["RFVoltage"]
RFPhase_tuple = self.localDict["RFPhase"]
time = bunch.getSyncParticle().time()
charge = bunch.charge()
gamma = bunch.getSyncParticle().gamma()
keold = bunch.getSyncParticle().kinEnergy()
RFVoltage = interp(time, n_tuple, time_tuple, RFVoltage_tuple)
RFPhase = interp(time, n_tuple, time_tuple, RFPhase_tuple)
SyncPhase = interp(time, n_tuple, time_tuple, SyncPhase_tuple)
dESync = charge * RFVoltage * math.sin(math.pi * (RFHNum * SyncPhase + RFPhase) / 180.0)
kenew = keold + dESync
bunch.getSyncParticle().kinEnergy(kenew)
Zsync = -math.pi * SyncPhase / (180.0 * ZtoPhi)
bunch.getSyncParticle().z(Zsync)
self.harmonicnode = Harmonic_Cav(ZtoPhi, dESync, RFHNum, RFVoltage, RFPhase)
self.setType("harmonic rf node")
self.setLength(0.0)
[docs] def trackBunch(self, bunch):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
gammaTrans = self.localDict["gammaTrans"]
RFHNum = self.localDict["RFHNum"]
n_tuple = self.localDict["n_tuple"]
time_tuple = self.localDict["time"]
SyncPhase_tuple = self.localDict["SyncPhase"]
RFVoltage_tuple = self.localDict["RFVoltage"]
RFPhase_tuple = self.localDict["RFPhase"]
time = bunch.getSyncParticle().time()
charge = bunch.charge()
gamma = bunch.getSyncParticle().gamma()
keold = bunch.getSyncParticle().kinEnergy()
RFVoltage = interp(time, n_tuple, time_tuple, RFVoltage_tuple)
RFPhase = interp(time, n_tuple, time_tuple, RFPhase_tuple)
SyncPhase = interp(time, n_tuple, time_tuple, SyncPhase_tuple)
dESync = charge * RFVoltage * math.sin(math.pi * (RFHNum * SyncPhase + RFPhase) / 180.0)
kenew = keold + dESync
bunch.getSyncParticle().kinEnergy(kenew)
ZtoPhi = self.Z2Phi
Zsync = -math.pi * SyncPhase / (180.0 * ZtoPhi)
bunch.getSyncParticle().z(Zsync)
self.harmonicnode.dESync(dESync)
self.harmonicnode.RFVoltage(RFVoltage)
self.harmonicnode.RFPhase(RFPhase)
# put the track method here:
self.harmonicnode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs] def track(self, paramsDict):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
bunch = paramsDict["bunch"]
gammaTrans = self.localDict["gammaTrans"]
RFHNum = self.localDict["RFHNum"]
n_tuple = self.localDict["n_tuple"]
time_tuple = self.localDict["time"]
SyncPhase_tuple = self.localDict["SyncPhase"]
RFVoltage_tuple = self.localDict["RFVoltage"]
RFPhase_tuple = self.localDict["RFPhase"]
time = bunch.getSyncParticle().time()
charge = bunch.charge()
gamma = bunch.getSyncParticle().gamma()
keold = bunch.getSyncParticle().kinEnergy()
RFVoltage = interp(time, n_tuple, time_tuple, RFVoltage_tuple)
RFPhase = interp(time, n_tuple, time_tuple, RFPhase_tuple)
SyncPhase = interp(time, n_tuple, time_tuple, SyncPhase_tuple)
dESync = charge * RFVoltage * math.sin(math.pi * (RFHNum * SyncPhase + RFPhase) / 180.0)
kenew = keold + dESync
bunch.getSyncParticle().kinEnergy(kenew)
ZtoPhi = self.Z2Phi
Zsync = -math.pi * SyncPhase / (180.0 * ZtoPhi)
bunch.getSyncParticle().z(Zsync)
self.harmonicnode.dESync(dESync)
self.harmonicnode.RFVoltage(RFVoltage)
self.harmonicnode.RFPhase(RFPhase)
# put the track method here:
self.harmonicnode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs]class Barrier_RFNode(Base_RFNode):
def __init__(self, ZtoPhi, RFVoltage, RFPhasep, RFPhasem, dRFPhasep, dRFPhasem, length, name="barrier_rfnode"):
"""
Constructor. Creates Barrier
RF Cavity TEAPOT element
"""
Base_RFNode.__init__(self, length, name)
self.barriernode = Barrier_Cav(ZtoPhi, RFVoltage, RFPhasep, RFPhasem, dRFPhasep, dRFPhasem)
self.setType("barrier rf node")
self.setLength(0.0)
[docs] def trackBunch(self, bunch):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
# put the track method here:
self.barriernode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
[docs] def track(self, paramsDict):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
bunch = paramsDict["bunch"]
# put the track method here:
self.barriernode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
class TimeDep_Barrier_RFNode(Base_RFNode):
def __init__(self, ZtoPhi, accelDict, bunch, length, name="syncphase_timedep_harmonic_rfnode"):
"""
Constructor. Creates SyncPhase Time Dependent
Harmonic RF Cavity TEAPOT element
"""
Base_RFNode.__init__(self, length, name)
self.localDict = accelDict
n_tuple = self.localDict["n_tuple"]
time_tuple = self.localDict["time"]
RFVoltage_tuple = self.localDict["RFVoltage"]
RFPhasep_tuple = self.localDict["RFPhasep"]
RFPhasem_tuple = self.localDict["RFPhasem"]
dRFPhasep_tuple = self.localDict["dRFPhasep"]
dRFPhasem_tuple = self.localDict["dRFPhasem"]
time = bunch.getSyncParticle().time()
RFVoltage = interp(time, n_tuple, time_tuple, RFVoltage_tuple)
RFPhasep = interp(time, n_tuple, time_tuple, RFPhasep_tuple)
RFPhasem = interp(time, n_tuple, time_tuple, RFPhasem_tuple)
dRFPhasep = interp(time, n_tuple, time_tuple, dRFPhasep_tuple)
dRFPhasem = interp(time, n_tuple, time_tuple, dRFPhasem_tuple)
self.barriernode = Barrier_Cav(ZtoPhi, RFVoltage, RFPhasep, RFPhasem, dRFPhasep, dRFPhasem)
self.setType("barrier rf node")
self.setLength(0.0)
def trackBunch(self, bunch):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
n_tuple = self.localDict["n_tuple"]
time_tuple = self.localDict["time"]
RFVoltage_tuple = self.localDict["RFVoltage"]
RFPhasep_tuple = self.localDict["RFPhasep"]
RFPhasem_tuple = self.localDict["RFPhasem"]
dRFPhasep_tuple = self.localDict["dRFPhasep"]
dRFPhasem_tuple = self.localDict["dRFPhasem"]
time = bunch.getSyncParticle().time()
RFVoltage = interp(time, n_tuple, time_tuple, RFVoltage_tuple)
RFPhasep = interp(time, n_tuple, time_tuple, RFPhasep_tuple)
RFPhasem = interp(time, n_tuple, time_tuple, RFPhasem_tuple)
dRFPhasep = interp(time, n_tuple, time_tuple, dRFPhasep_tuple)
dRFPhasem = interp(time, n_tuple, time_tuple, dRFPhasem_tuple)
self.barriernode.RFVoltage(RFVoltage)
self.barriernode.RFPhasep(RFPhasep)
self.barriernode.RFPhasem(RFPhasem)
self.barriernode.dRFPhasep(dRFPhasep)
self.barriernode.dRFPhasem(dRFPhasem)
# put the track method here:
self.barriernode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
def track(self, paramsDict):
"""
The rfcavity-teapot class implementation of the
AccNodeBunchTracker class track(probe) method.
"""
length = self.getLength(self.getActivePartIndex())
bunch = paramsDict["bunch"]
n_tuple = self.localDict["n_tuple"]
time_tuple = self.localDict["time"]
RFVoltage_tuple = self.localDict["RFVoltage"]
RFPhasep_tuple = self.localDict["RFPhasep"]
RFPhasem_tuple = self.localDict["RFPhasem"]
dRFPhasep_tuple = self.localDict["dRFPhasep"]
dRFPhasem_tuple = self.localDict["dRFPhasem"]
time = bunch.getSyncParticle().time()
RFVoltage = interp(time, n_tuple, time_tuple, RFVoltage_tuple)
RFPhasep = interp(time, n_tuple, time_tuple, RFPhasep_tuple)
RFPhasem = interp(time, n_tuple, time_tuple, RFPhasem_tuple)
dRFPhasep = interp(time, n_tuple, time_tuple, dRFPhasep_tuple)
dRFPhasem = interp(time, n_tuple, time_tuple, dRFPhasem_tuple)
self.barriernode.RFVoltage(RFVoltage)
self.barriernode.RFPhasep(RFPhasep)
self.barriernode.RFPhasem(RFPhasem)
self.barriernode.dRFPhasep(dRFPhasep)
self.barriernode.dRFPhasem(dRFPhasem)
# put the track method here:
self.barriernode.trackBunch(bunch)
# print "debug tracking the bunch through the rf node = ",\
self.getName(), " part ind = ", self.getActivePartIndex(), " length = ", length
# print "time = ", time
# print "RFVoltage = ", RFVoltage
# print "RFPhaseplus = ", RFPhasep + dRFPhasep, RFPhasep - dRFPhasep
# print "RFPhasemnus = ", RFPhasem - dRFPhasem, RFPhasem + dRFPhasem
def interp(x, n_tuple, x_tuple, y_tuple):
"""
Linear interpolation: Given n-tuple + 1 points,
x_tuple and y_tuple, routine finds y = y_tuple
at x in x_tuple. Assumes x_tuple is increasing array.
"""
if x <= x_tuple[0]:
y = y_tuple[0]
return y
if x >= x_tuple[n_tuple]:
y = y_tuple[n_tuple]
return y
dxp = x - x_tuple[0]
for n in range(n_tuple):
dxm = dxp
dxp = x - x_tuple[n + 1]
dxmp = dxm * dxp
if dxmp <= 0:
break
y = (-dxp * y_tuple[n] + dxm * y_tuple[n + 1]) / (dxm - dxp)
return y
def syncZ(ZtoPhi, gammaTrans, gamma, charge, dESync, RFHNum, RFVoltage, RFPhase):
"""
Calculates position of synchronous particle.
"""
Zsync = 0
if abs(dESync) > abs(charge * RFVoltage):
return Zsync
PhaseTot = math.asin(dESync / (charge * RFVoltage))
if gamma > gammaTrans and gammaTrans > 0:
PhaseTot = math.pi - PhaseTot
Zsync = -(PhaseTot - math.pi * RFPhase / 180.0) / (RFHNum * ZtoPhi)
return Zsync