class CavityAnalytic(PynacElement): """ A Pynac representation of a resonant EM cavity (i.e., the ``CAVMC`` model used by Dynac to do analytic calculations). Before the simulation is run, any changes made to elements using this class have to be put back into the ``lattice`` attribute of ``Pynac`` using the ``dynacRepresentation`` method. """ def __init__(self, phase, fieldReduction, cavID=0, xesln=0, isec=0): self.cavID = Param(val = cavID, unit = None) self.xesln = Param(val = xesln, unit = 'cm') self.phase = Param(val = phase, unit = 'deg') self.fieldReduction = Param(val = fieldReduction, unit = 'percent') self.isec = Param(val = isec, unit = None) @classmethod def from_dynacRepr(cls, pynacRepr): """ Construct a ``CavityAnalytic`` instance from the Pynac lattice element """ cavID = int(pynacRepr[1][0][0]) xesln = float(pynacRepr[1][1][0]) phase = float(pynacRepr[1][1][1]) fieldReduction = float(pynacRepr[1][1][2]) isec = int(pynacRepr[1][1][3]) return cls(phase, fieldReduction, cavID, xesln, isec) def adjustPhase(self, adjustment): """ Adjust the accelerating phase of the cavity by the value of ``adjustment``. The adjustment is additive, so a value of ``scalingFactor = 0.0`` will result in no change of the phase. """ self.phase = self.phase._replace(val = self.phase.val + adjustment) def scaleField(self, scalingFactor): """ Adjust the accelerating field of the cavity by the value of ``scalingFactor``. The adjustment is multiplicative, so a value of ``scalingFactor = 1.0`` will result in no change of the field. """ oldField = self.fieldReduction.val newField = 100.0 * (scalingFactor * (1.0 + oldField/100.0) - 1.0) self.fieldReduction = self.fieldReduction._replace(val = newField) def dynacRepresentation(self): """ Return the Dynac representation of this cavity instance. """ return ['CAVMC', [ [self.cavID.val], [self.xesln.val, self.phase.val, self.fieldReduction.val, self.isec.val, 1], ]] def __repr__(self): s = 'CavityAnalytic:' s += ' | phase = ' + self.phase.__repr__() s += ' | fieldReduction = ' + self.fieldReduction.__repr__() return s
class Steerer(PynacElement): def __init__(self, field_strength, plane): self.field_strength = Param( val=field_strength, unit='T.m' ) self.plane = Param( val=plane, unit='None' ) @classmethod def from_dynacRepr(cls, pynacRepr): """ Construct a ``Steerer`` instance from the Pynac lattice element """ f = float(pynacRepr[1][0][0]) p = 'HV'[int(pynacRepr[1][0][1])] return cls(f, p) def dynacRepresentation(self): """ Return the Dynac representation of this steerer instance. """ if self.plane.val == 'H': p = 0 elif self.plane.val == 'V': p = 1 return ['STEER', [[self.field_strength.val], [p]]] def scaleField(self, scalingFactor): """ Adjust the field of the magnet by the value of ``scalingFactor``. The adjustment is multiplicative, so a value of ``scalingFactor = 1.0`` will result in no change of the field. """ self.field_strength = self.field_strength._replace( val=self.field_strength.val * scalingFactor ) def setField(self, new_value): """ Adjust the field of the magnet by the value of ``scalingFactor``. The adjustment is multiplicative, so a value of ``scalingFactor = 1.0`` will result in no change of the field. """ self.field_strength = self.field_strength._replace( val=new_value ) def __repr__(self): s = 'STEER:' s += ' | f = ' + self.field_strength.__repr__() s += ' | plane = ' + self.plane.__repr__() return s
class Quad(PynacElement): """ A Pynac representation of a quadrupole magnet. Before the simulation is run, any changes made to elements using this class have to be put back into the ``lattice`` attribute of `Pynac` using the ``dynacRepresentation`` method. """ def __init__(self, L, B, aperRadius): self.L = Param(val = L, unit = 'cm') self.B = Param(val = B, unit = 'kG') self.aperRadius = Param(val = aperRadius, unit = 'cm') @classmethod def from_dynacRepr(cls, pynacRepr): """ Construct a ``Quad`` instance from the Pynac lattice element """ L = float(pynacRepr[1][0][0]) B = float(pynacRepr[1][0][1]) aperRadius = float(pynacRepr[1][0][2]) return cls(L, B, aperRadius) def scaleField(self, scalingFactor): """ Adjust the field of the magnet by the value of ``scalingFactor``. The adjustment is multiplicative, so a value of ``scalingFactor = 1.0`` will result in no change of the field. """ self.B = self.B._replace(val=self.B.val * scalingFactor) def setField(self, new_value): """ Adjust the field of the magnet by the value of ``scalingFactor``. The adjustment is multiplicative, so a value of ``scalingFactor = 1.0`` will result in no change of the field. """ self.B = self.B._replace(val=new_value) def dynacRepresentation(self): """ Return the Pynac representation of this quadrupole instance. """ return ['QUADRUPO', [[self.L.val, self.B.val, self.aperRadius.val]]] def __repr__(self): s = 'QUAD:' s += ' | L = ' + self.L.__repr__() s += ' | B = ' + self.B.__repr__() s += ' | aperRadius = ' + self.aperRadius.__repr__() return s