def track_one(self, x=0, px=0, y=0, py=0, range='#s/#e', **kwargs): """ Track a particle through the sequence. Handles backward tracking (sort of) by specifying a negative range. Currently uses TWISS for tracking internally (to allow tracking through thick sequences). This might change. """ elems = self.elements start, end = range.split('/') if isinstance(range, str) else range start, end = normalize_range_name(start), normalize_range_name(end) kwargs.setdefault('betx', 1) kwargs.setdefault('bety', 1) if elems.index(end) < elems.index(start): # TODO: we should use a separate madx process with inplace # reversed sequence for backtracking in the future, this will # simplify all the complications with element names etc. flip = {'#s': '#e', '#e': '#s'} start = flip.get(start, start + '_reversed') end = flip.get(end, end + '_reversed') tw = self.backtrack(x=-x, y=y, px=px, py=-py, range=start + '/' + end, **kwargs) return AttrDict({ 's': tw.s[-1] - tw.s, 'x': -tw.x, 'px': tw.px, 'y': tw.y, 'py': -tw.py, }) return self.madx.twiss(x=x, px=px, y=y, py=py, range=range, **kwargs)
def test_normalize_range_name(self): self.assertEqual(util.normalize_range_name('dr[1]'), 'dr[1]') self.assertEqual(util.normalize_range_name('lebt$start'), '#s') self.assertEqual(util.normalize_range_name('lebt$end'), '#e') self.assertEqual(util.normalize_range_name('dr'), 'dr') self.assertEqual(util.normalize_range_name('l$start/qp[5]'), '#s/qp[5]')
def __init__(self, session, sequence, range, beam, twiss_args, show_element_indicators): """ :param Session session: :param str sequence: :param tuple range: """ self.hook = HookCollection( update=None, remove=None, show_element_indicators=None, ) self.session = session self.sequence = session.madx.sequences[sequence] self.start, self.stop = self.parse_range(range) self.range = (normalize_range_name(self.start.name), normalize_range_name(self.stop.name)) self._beam = beam self._twiss_args = twiss_args self._show_element_indicators = show_element_indicators self._use_beam(beam) raw_elements = self.sequence.elements # TODO: provide uncached version of elements with units: self.elements = list(map( session.utool.dict_add_unit, raw_elements)) # TODO: self.hook.create(self) self.twiss()
def _init_segment(self, sequence, range, beam, twiss_args): """ :param str sequence: :param tuple range: """ self.sequence = self.madx.sequence[sequence] self.seq_name = self.sequence.name self.continuous_matching = True self._beam = beam = dict(beam, sequence=self.seq_name) self._twiss_args = twiss_args self.madx.command.beam(**beam) self.sequence.use() # Use `expanded_elements` rather than `elements` to have a one-to-one # correspondence with the data points of TWISS/SURVEY: self.elements = elems = ElementList(self.madx, self.seq_name) self.positions = self.sequence.expanded_element_positions() self.start, self.stop = self.parse_range(range) self.range = (normalize_range_name(self.start.name, elems), normalize_range_name(self.stop.name, elems))
def test_normalize_range_name(): assert util.normalize_range_name('dr[1]') == 'dr[1]' assert util.normalize_range_name('lebt$start') == '#s' assert util.normalize_range_name('lebt$end') == '#e' assert util.normalize_range_name('dr') == 'dr' assert util.normalize_range_name('l$start/qp[5]') == '#s/qp[5]'
def test_normalize_range_name(self): self.assertEqual(util.normalize_range_name('dr[1]'), 'dr[1]') self.assertEqual(util.normalize_range_name('lebt$end'), '#e') self.assertEqual(util.normalize_range_name('dr'), 'dr')