Skip to content

Genesis 4 Lattice

genesis.version4.Lattice

Lattice(elements=None, *, filename=None)

Bases: BaseModel

A Genesis 4 beamline Lattice configuration.

Attributes:

Name Type Description
elements list of BeamlineElement or Line

Elements contained in the lattice.

filename Path or None

The filename from which this lattice was loaded.

Source code in genesis/version4/input/lattice.py
346
347
348
349
350
351
352
353
354
355
356
357
358
def __init__(
    self,
    elements: Union[
        Dict[str, AnyBeamlineElement], List[AnyBeamlineElement], None
    ] = None,
    *,
    filename: Optional[pathlib.Path] = None,
) -> None:
    if elements is None:
        elements = {}
    if not isinstance(elements, dict):
        elements = lattice_elements_from_list(elements)
    super().__init__(elements=elements, filename=filename)

Attributes

genesis.version4.Lattice.by_element property
by_element

Get beamline elements organized by their class.

genesis.version4.Lattice.chicanes property
chicanes

List of all Chicane instances.

genesis.version4.Lattice.correctors property
correctors

List of all Corrector instances.

genesis.version4.Lattice.drifts property
drifts

List of all Drift instances.

genesis.version4.Lattice.lines property
lines

List of all Line instances.

genesis.version4.Lattice.markers property
markers

List of all Marker instances.

genesis.version4.Lattice.phase_shifters property
phase_shifters

List of all PhaseShifter instances.

genesis.version4.Lattice.quadrupoles property
quadrupoles

List of all Quadrupole instances.

genesis.version4.Lattice.undulators property
undulators

List of all Undulator instances.

Functions

genesis.version4.Lattice.by_z_location
by_z_location(beamline, limit_to=None)

Get all (flattened) beamline elements by Z location.

Returns:

Type Description
list of (zend, element)

Each list item is a ZElement, a namedtuple which has .zend and .element that is also usable as a normal tuple.

Source code in genesis/version4/input/lattice.py
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
def by_z_location(
    self,
    beamline: str,
    limit_to: Union[
        Type[BeamlineElement],
        Tuple[Type[BeamlineElement], ...],
        None,
    ] = None,
) -> List[ZElement]:
    """
    Get all (flattened) beamline elements by Z location.

    Returns
    -------
    list of (zend, element)
        Each list item is a ZElement, a namedtuple which has `.zend` and
        `.element` that is also usable as a normal tuple.
    """
    z = 0.0
    by_z = []
    for insp in self._inspect(beamline):
        if isinstance(insp.element, Line):
            # Line is already expanded
            continue

        if insp.z is not None:
            # A located lattice element has a user-specified, explicit
            # location and is exempt from our element-by-element counting:
            by_z.append(ZElement(zend=insp.z, element=insp.element))
            continue

        if isinstance(
            insp.element,
            (
                auto_lattice.Drift,
                auto_lattice.Quadrupole,
                auto_lattice.Corrector,
                auto_lattice.Chicane,
                auto_lattice.PhaseShifter,
                auto_lattice.Undulator,
            ),
        ):
            z += insp.element.L
        elif isinstance(insp.element, auto_lattice.Marker):
            ...
        else:
            raise NotImplementedError(type(insp.element))

        if limit_to is None or isinstance(insp.element, limit_to):
            by_z.append(ZElement(zend=z, element=insp.element))

    def sort_z(item: ZElement):
        return item.zend

    return sorted(by_z, key=sort_z)
genesis.version4.Lattice.fix_labels
fix_labels()

Fix labels of elements based on their dictionary key in .elements.

Source code in genesis/version4/input/lattice.py
860
861
862
863
864
865
866
867
868
869
870
def fix_labels(self) -> None:
    """Fix labels of elements based on their dictionary key in `.elements`."""
    for label, element in self.elements.items():
        if element.label != label:
            if element.label:
                logger.warning(
                    "Renaming beamline element in lattice from %s to %s",
                    element.label,
                    label,
                )
            element.label = label
genesis.version4.Lattice.flatten_line
flatten_line(beamline, *, count=1, start=0, format='L{index}_{name}', in_place=True, new_beamline='')

Flatten a beamline such that any nested beamlines are made into distinct elements.

For example, take a beamline LN which contains 2 nested beamlines "L1" (containing UND) and "L2" (containing QUAD). Flattening this with the default format of L{index}_{name} would result with replacing LN with: * L0_UND and L0_QUAD (wtih start=0, count=1) * L1_UND, L1_QUAD, L2_UND, L2_QUAD (with start=1, count=2)

Parameters:

Name Type Description Default
beamline str

The beamline name to flatten.

required
count int

The number of times to duplicate the flattened beamline.

1
start int

The starting index for relabeling elements.

0
format str

The string format to use for renaming beamline elements.

"L{index}_{name}"
in_place bool

Perform the flattening in-place. Remove unused elements and add the new elements directly to the lattice.

True
new_beamline str

For in-place mode, use this as the name for the new beamline.

''

Returns:

Type Description
[segment(start), segment(start+1), ... segment(start+count-1)]

Each segment corresponds to a single index of the flattened line, from start to start + count - 1. Each segment is a list of created elements based on that index.

Source code in genesis/version4/input/lattice.py
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
def flatten_line(
    self,
    beamline: str,
    *,
    count: int = 1,
    start: int = 0,
    format: str = "L{index}_{name}",
    in_place: bool = True,
    new_beamline: str = "",
):
    """
    Flatten a beamline such that any nested beamlines are made into distinct elements.

    For example, take a beamline ``LN`` which contains 2 nested beamlines
    "L1" (containing UND) and "L2" (containing QUAD).
    Flattening this with the default format of ``L{index}_{name}``
    would result with replacing ``LN`` with:
    * ``L0_UND`` and ``L0_QUAD`` (wtih start=0, count=1)
    * ``L1_UND``, ``L1_QUAD``, ``L2_UND``, ``L2_QUAD`` (with start=1, count=2)

    Parameters
    ----------
    beamline : str
        The beamline name to flatten.
    count : int, default=1
        The number of times to duplicate the flattened beamline.
    start : int, default=0
        The starting index for relabeling elements.
    format : str, default="L{index}_{name}"
        The string format to use for renaming beamline elements.
    in_place : bool, default=True
        Perform the flattening in-place.  Remove unused elements and add
        the new elements directly to the lattice.
    new_beamline : str
        For in-place mode, use this as the name for the new beamline.

    Returns
    -------
    [segment(start), segment(start+1), ... segment(start+count-1)]
        Each segment corresponds to a single index of the flattened line,
        from ``start`` to ``start + count - 1``. Each segment is a list of
        created elements based on that index.
    """
    to_duplicate = self.inspect_line_by_name(beamline)
    new_elements = {}
    sections = []
    for index in range(start, start + count):
        section = []
        for name in to_duplicate:
            new_name = format.format(
                name=name,
                index=index,
                start=start,
                count=count,
                beamline=beamline,
            )
            new_element = copy.deepcopy(self.elements[name])
            new_element.label = new_name

            if new_name in new_elements:
                raise ValueError(
                    f"Name for element conflicts with another new element: {new_name}"
                )
            new_elements[new_name] = new_element
            section.append(new_element)
        sections.append(section)

    if in_place:
        for name in to_duplicate:
            if name not in new_elements:
                self.elements.pop(name, None)
        if new_beamline != beamline and beamline not in new_elements:
            self.elements.pop(beamline, None)

        self.elements[new_beamline or beamline] = Line(elements=list(new_elements))
        self.elements.update(new_elements)

    return sections
genesis.version4.Lattice.from_contents classmethod
from_contents(contents, filename=None)

Load a lattice from its file contents.

Parameters:

Name Type Description Default
contents str

The contents of the lattice file.

required
filename AnyPath or None

The filename of the lattice, if known.

None

Returns:

Type Description
Lattice
Source code in genesis/version4/input/lattice.py
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
@classmethod
def from_contents(
    cls, contents: str, filename: Optional[AnyPath] = None
) -> Lattice:
    """
    Load a lattice from its file contents.

    Parameters
    ----------
    contents : str
        The contents of the lattice file.
    filename : AnyPath or None, optional
        The filename of the lattice, if known.

    Returns
    -------
    Lattice
    """
    parser = parsers.new_lattice_parser()
    filename = filename or "unknown"
    try:
        tree = parser.parse(contents)
    except Exception:
        if "\n" not in contents:
            raise ValueError(
                f"Unable to parse the provided input in Genesis4 lattice "
                f"format. It looks like this might have been a filename: "
                f"{contents!r}"
            )
        raise
    return _LatticeTransformer(filename).transform(tree)
genesis.version4.Lattice.from_elements classmethod
from_elements(elements, filename=None)

Create a Lattice from a list of labeled elements.

Parameters:

Name Type Description Default
elements list of BeamlineElement

Elements of the beamline. These must have a label set.

required
filename AnyPath or None

The filename of the lattice, if applicable.

None

Returns:

Type Description
Lattice
Source code in genesis/version4/input/lattice.py
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
@classmethod
def from_elements(
    cls, elements: Sequence[AnyBeamlineElement], filename: Optional[AnyPath] = None
) -> Lattice:
    """
    Create a Lattice from a list of labeled elements.

    Parameters
    ----------
    elements : list of BeamlineElement
        Elements of the beamline.  These must have a label set.
    filename : AnyPath or None, optional
        The filename of the lattice, if applicable.

    Returns
    -------
    Lattice
    """
    elements = list(elements)
    for el in elements:
        if not el.label:
            raise ValueError(f"Beamline element is missing a label: {el}")
    elements_by_name = {el.label: el for el in elements}
    if len(elements_by_name) != len(elements):
        raise ValueError("One or more duplicate labels exist in the input")
    return cls(
        elements_by_name,
        filename=pathlib.Path(filename) if filename else None,
    )
genesis.version4.Lattice.from_file classmethod
from_file(filename)

Load a lattice file from disk.

Parameters:

Name Type Description Default
filename AnyPath

The filename to load.

required

Returns:

Type Description
Lattice
Source code in genesis/version4/input/lattice.py
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
@classmethod
def from_file(cls, filename: AnyPath) -> Lattice:
    """
    Load a lattice file from disk.

    Parameters
    ----------
    filename : AnyPath
        The filename to load.

    Returns
    -------
    Lattice
    """
    with open(filename) as fp:
        contents = fp.read()
    return cls.from_contents(contents, filename=filename)
genesis.version4.Lattice.inspect_line
inspect_line(beamline)

Returns a list of all elements in the given beamline.

This recursively inspects any LINEs inside the beamline.

Returns:

Type Description
list of BeamlineElement

List of beamline element instances.

Source code in genesis/version4/input/lattice.py
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
def inspect_line(self, beamline: str) -> List[AnyBeamlineElement]:
    """
    Returns a list of all elements in the given beamline.

    This recursively inspects any LINEs inside the beamline.

    Returns
    -------
    list of BeamlineElement
        List of beamline element instances.
    """
    return [
        insp.element
        for insp in self._inspect(beamline)
        if not isinstance(insp.element, Line)
    ]
genesis.version4.Lattice.inspect_line_by_name
inspect_line_by_name(beamline)

Returns a list of all element names in the given beamline.

This recursively inspects any LINEs inside the beamline.

Returns:

Type Description
list of str

List of names.

Source code in genesis/version4/input/lattice.py
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
def inspect_line_by_name(self, beamline: str) -> List[str]:
    """
    Returns a list of all element names in the given beamline.

    This recursively inspects any LINEs inside the beamline.

    Returns
    -------
    list of str
        List of names.
    """
    self.fix_labels()
    return [
        insp.element.label
        for insp in self._inspect(beamline)
        if not isinstance(insp.element, Line)
    ]
genesis.version4.Lattice.is_flat
is_flat(beamline)

Checks if the given beamline does not reuse elements.

Source code in genesis/version4/input/lattice.py
625
626
627
628
def is_flat(self, beamline: str) -> bool:
    """Checks if the given `beamline` does not reuse elements."""
    names = self.inspect_line_by_name(beamline)
    return len(set(names)) == len(names)
genesis.version4.Lattice.model_dump
model_dump(**kwargs)

Serialize this lattice to a list of dictionaries.

Source code in genesis/version4/input/lattice.py
921
922
923
924
925
@override
def model_dump(self, **kwargs: Any) -> Dict[str, Any]:
    """Serialize this lattice to a list of dictionaries."""
    self.fix_labels()
    return super().model_dump(**kwargs)
genesis.version4.Lattice.plot
plot(beamline=None, *, ax=None, show_labels=True, show=True, normalize_aw=False, figsize=None, xlim=None, ylim=None)

Plot the layout of the given beamline.

Parameters:

Name Type Description Default
beamline str

The name of the beamline.

None
ax Axes or None

Plot on the given axis, or create a new one.

None
show_labels bool

Show labels for each undulator.

True
show bool

Show the plot.

True
normalize_aw bool

Normalize undulator strengths with respect to the first undulator (\(aw0\)): \(aw / aw0 - 1\)

False
figsize Tuple[float, float]

The figure size to create. Used if ax is not provided.

None
xlim Tuple[float, float]

X axis limits for the plot.

None
ylim Tuple[float, float]

Y axis limits for the plot.

None
Source code in genesis/version4/input/lattice.py
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
def plot(
    self,
    beamline: Optional[str] = None,
    *,
    ax: Optional[matplotlib.axes.Axes] = None,
    show_labels: bool = True,
    show: bool = True,
    normalize_aw: bool = False,
    figsize: Optional[Tuple[float, float]] = None,
    xlim: Optional[Tuple[float, float]] = None,
    ylim: Optional[Tuple[float, float]] = None,
):
    """
    Plot the layout of the given beamline.

    Parameters
    ----------
    beamline : str
        The name of the beamline.
    ax : matplotlib.axes.Axes or None
        Plot on the given axis, or create a new one.
    show_labels : bool
        Show labels for each undulator.
    show : bool
        Show the plot.
    normalize_aw : bool, default=False
        Normalize undulator strengths with respect to the first undulator
        ($aw0$): $aw / aw0 - 1$
    figsize : Tuple[float, float], optional
        The figure size to create.  Used if ``ax`` is not provided.
    xlim : Tuple[float, float], optional
        X axis limits for the plot.
    ylim : Tuple[float, float], optional
        Y axis limits for the plot.
    """
    beamline = self._check_beamline_name(beamline)
    elements = self.by_z_location(beamline)
    undulators = [
        (elem.zend, elem.element)
        for elem in elements
        if isinstance(elem.element, auto_lattice.Undulator)
    ]
    quads = [
        (elem.zend, elem.element)
        for elem in elements
        if isinstance(elem.element, auto_lattice.Quadrupole)
    ]
    if ax is None:
        _, ax = plt.subplots(figsize=figsize)
    assert ax is not None

    aw0 = undulators[0][1].aw if undulators else 1.0
    if aw0 == 0.0:
        # Avoid dividing by zero when the strengths aren't yet set
        normalize_aw = False

    bars = [
        _BarPlotBar(
            x=zend - und.L,
            width=und.L,
            height=und.aw / aw0 - 1 if normalize_aw else und.aw,
            color="red",
            edgecolor="red",
            element=und,
        )
        for zend, und in undulators
    ]
    _nice_bar_plot(
        ax,
        bars,
        units="1",
        alpha=0.5,
        label="$aw/aw0 - 1$" if normalize_aw else "$aw$",
        show_labels=show_labels,
    )

    bars = [
        _BarPlotBar(
            x=zend - quad.L,
            width=quad.L,
            height=quad.k1,
            color="blue",
            edgecolor="blue",
            element=quad,
        )
        for zend, quad in quads
    ]
    _nice_bar_plot(
        ax.twinx(),
        bars,
        units="$1/m^2$",
        alpha=0.5,
        label="Quad $k$",
        show_labels=show_labels,
    )

    ax.set_xlabel("$z$ (m)")
    ax.set_title(f"{beamline} Layout")
    if xlim is not None:
        ax.set_xlim(xlim)
    if ylim is not None:
        ax.set_xlim(ylim)
    if show:
        plt.show()
genesis.version4.Lattice.taper_array
taper_array(beamline, aws)

Apply a list of undulator strengths to set the taper.

Parameters:

Name Type Description Default
beamline str

The beamline name.

required
aws list of floats (or equivalent, np.ndarray)

The undulator strengths, one for each undulator in the beamline. Undulators are sorted based on Z position.

required
Source code in genesis/version4/input/lattice.py
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
def taper_array(
    self,
    beamline: str,
    aws: Sequence[float],
) -> None:
    """
    Apply a list of undulator strengths to set the taper.

    Parameters
    ----------
    beamline : str
        The beamline name.
    aws : list of floats (or equivalent, np.ndarray)
        The undulator strengths, one for each undulator in the beamline.
        Undulators are sorted based on Z position.
    """
    if not self.is_flat(beamline):
        raise NotFlatError(
            f"The beamline {beamline!r} is not flat: it contains reused "
            f"elements.  Before performing a taper operation, first flatten "
            f"the beamline with `.flatten_line()`"
        )

    undulators = self.by_z_location(beamline, limit_to=auto_lattice.Undulator)
    aws = list(aws)
    if len(aws) != len(undulators):
        raise ValueError(
            f"The number of undulators ({len(undulators)}) is not equal to "
            f"the number of aw parameters provided ({len(aws)})"
        )
    for aw, (_z, und) in zip(aws, undulators):
        und = typing.cast(auto_lattice.Undulator, und)
        und.aw = aw
genesis.version4.Lattice.taper_custom
taper_custom(beamline, *, aw0, zstart, zend)

Get a list of undulators to perform a custom taper on.

Only elements that fit within the range [zstart, zend] will be included.

Parameters:

Name Type Description Default
beamline str

The beamline containing the undulators.

required
aw0 float

The starting undulator strength.

required
zstart float

The starting Z position, relative to the first element on the line.

required
zend float

The ending Z position, relative to the first element on the line.

required

Returns:

Type Description
list of ZElement

List of ZElement instances, which contain a normalized Z location (zstart=0.0, zend=1.0) and an Undulator element.

Source code in genesis/version4/input/lattice.py
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
def taper_custom(
    self,
    beamline: str,
    *,
    aw0: float,
    zstart: float,
    zend: float,
) -> List[ZElement]:
    """
    Get a list of undulators to perform a custom taper on.

    Only elements that fit within the range [zstart, zend] will be
    included.

    Parameters
    ----------
    beamline : str
        The beamline containing the undulators.
    aw0 : float
        The starting undulator strength.
    zstart : float
        The starting Z position, relative to the first element on the line.
    zend : float
        The ending Z position, relative to the first element on the line.

    Returns
    -------
    list of ZElement
        List of ZElement instances, which contain a normalized Z location
        (zstart=0.0, zend=1.0) and an Undulator element.
    """
    if not self.is_flat(beamline):
        raise NotFlatError(
            f"The beamline {beamline!r} is not flat: it contains reused "
            f"elements.  Before performing a taper operation, first flatten "
            f"the beamline with `.flatten_line()`"
        )

    if zend < zstart:
        zstart, zend = zend, zstart

    undulators = self.by_z_location(beamline, limit_to=auto_lattice.Undulator)
    norm_z = []
    for zelem in undulators:
        und = zelem.element
        assert isinstance(und, auto_lattice.Undulator)
        if zstart <= zelem.zend <= zend:
            norm_z.append(
                ZElement(
                    zend=(zelem.zend - zstart) / (zend - zstart),
                    element=und,
                )
            )
        else:
            und.aw = aw0

    return norm_z
genesis.version4.Lattice.taper_linear
taper_linear(beamline, *, aw0, zstart, zend, taper_start, taper_end)

Perform a linear taper on undulators in the given beamline.

Only elements that fit within the range [zstart, zend] will be included.

Parameters:

Name Type Description Default
beamline str

The beamline containing the undulators.

required
aw0 float

The starting undulator strength.

required
zstart float

The starting Z position, relative to the first element on the line.

required
zend float

The ending Z position, relative to the first element on the line.

required
taper_start float

The starting taper multiplier (applied to aw0) at zstart.

required
taper_end float

The final taper multiplier (applied to aw0) at zend.

required

Returns:

Type Description
list of float

List of undulator strengths.

Source code in genesis/version4/input/lattice.py
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
def taper_linear(
    self,
    beamline: str,
    *,
    aw0: float,
    zstart: float,
    zend: float,
    taper_start: float,
    taper_end: float,
) -> List[float]:
    """
    Perform a linear taper on undulators in the given beamline.

    Only elements that fit within the range [zstart, zend] will be
    included.

    Parameters
    ----------
    beamline : str
        The beamline containing the undulators.
    aw0 : float
        The starting undulator strength.
    zstart : float
        The starting Z position, relative to the first element on the line.
    zend : float
        The ending Z position, relative to the first element on the line.
    taper_start : float
        The starting taper multiplier (applied to `aw0`) at `zstart`.
    taper_end : float
        The final taper multiplier (applied to `aw0`) at `zend`.

    Returns
    -------
    list of float
        List of undulator strengths.
    """
    # taper_custom will give normalized Z values for [zstart, zend] -> [0, 1]
    undulators = self.taper_custom(beamline, aw0=aw0, zstart=zstart, zend=zend)
    slope = aw0 * (taper_end - taper_start) / (1.0 - 0.0)  # / (zend - zstart)
    for norm_z, und in undulators:
        assert isinstance(und, auto_lattice.Undulator)
        und.aw = aw0 + slope * norm_z

    return [zelem.element.aw for zelem in undulators]
genesis.version4.Lattice.to_file
to_file(filename)

Write the lattice input file, in Genesis format, to filename.

Parameters:

Name Type Description Default
filename str or Path
required
Source code in genesis/version4/input/lattice.py
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
def to_file(
    self,
    filename: AnyPath,
) -> None:
    """
    Write the lattice input file, in Genesis format, to ``filename``.

    Parameters
    ----------
    filename : str or pathlib.Path
    """
    main_config = self.to_genesis()
    with open(filename, "wt") as fp:
        print(main_config, file=fp)

    logger.debug(
        "Wrote lattice to %s:\n%s",
        main_config,
        filename,
    )
genesis.version4.Lattice.to_genesis
to_genesis()

Generate a Genesis 4-compatible lattice input string.

Source code in genesis/version4/input/lattice.py
855
856
857
858
def to_genesis(self) -> str:
    """Generate a Genesis 4-compatible lattice input string."""
    self.fix_labels()
    return "\n".join(element.to_genesis() for element in self.elements.values())

Beamline Elements

genesis.version4.Chicane

Bases: BeamlineElement

Lattice beamline element: chicane.

Chicane corresponds to Genesis 4 beamlineelement chicane.

Attributes:

Name Type Description
L float, default=0.0

Length of the chicane, which consists out of 4 dipoles without focusing. The first and last are placed at the beginning and end of the reserved space. The inner ones are defined by the drift length in between. Any remaining distance, namely the length subtracted by 4 times the dipole length and twice the drift length are placed between the second and third dipole.

lb float, default=0.0

Length of an individual dipole in meter.

ld float, default=0.0

Drift between the outer and inner dipoles, projected onto the undulator axis. The actual path length is longer by the factor \(1/\cos\theta\), where \(\theta\) is the bending angle of an individual dipole.

delay float, default=0.0

Path length difference between the straight path and the actual trajectory in meters. Genesis 1.3 calculates the bending angle internally starting from this value. \(R_{56} = 2\)delay.

genesis.version4.Corrector

Bases: BeamlineElement

Lattice beamline element: corrector.

Corrector corresponds to Genesis 4 beamlineelement corrector.

Attributes:

Name Type Description
L float, default=0.0

Length of the corrector in meter.

cx float, default=0.0

Kick angle in \(x\) in units of \(\gamma \beta_x\).

cy float, default=0.0

Kick angle in \(y\) in units of \(\gamma \beta_y\).

genesis.version4.Drift

Bases: BeamlineElement

Lattice beamline element: drift.

Drift corresponds to Genesis 4 beamlineelement drift.

Attributes:

Name Type Description
L float, default=0.0

Length of the drift in meter.

genesis.version4.Line

Bases: BeamlineElement

A Genesis 4 beamline Line.

Attributes:

Name Type Description
elements list of LineItem

Elements contained in the line.

label (str, optional)

An optional label to attach to the line.

Attributes

genesis.version4.Line.flattened property
flattened

Flattened elements by name, including Z location if available.

Functions

genesis.version4.Line.from_labels classmethod
from_labels(elements, *element_labels, label='')

Create a Line from labeled beamline elements.

Parameters:

Name Type Description Default
elements Dict[str, BeamlineElement]

The element dictionary.

required
*element_labels str

Labels of elements. May be either a single label per argument or a whitespace-delimited string of labels.

()
label str

Label name for the line.

''

Returns:

Type Description
Line
Source code in genesis/version4/input/lattice.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
@classmethod
def from_labels(
    cls,
    elements: Dict[str, AnyBeamlineElement],
    *element_labels: str,
    label: str = "",
) -> Line:
    """
    Create a `Line` from labeled beamline elements.

    Parameters
    ----------
    elements : Dict[str, BeamlineElement]
        The element dictionary.
    *element_labels : str
        Labels of elements.  May be either a single label per argument or a
        whitespace-delimited string of labels.
    label : str
        Label name for the line.

    Returns
    -------
    Line
    """
    try:
        return cls(
            elements=[
                elements[label]
                for labels in element_labels
                for label in labels.strip().split()
            ],
            label=label,
        )
    except KeyError as ex:
        raise ValueError(
            f"Label {ex} is not present in the beamline element dictionary. "
            f"The following are valid: {tuple(elements.keys())}"
        )

genesis.version4.Marker

Bases: BeamlineElement

Lattice beamline element: marker.

Marker corresponds to Genesis 4 beamlineelement marker.

Attributes:

Name Type Description
dumpfield int, default=0

A non-zero value enforces the dump of the field distribution of this zero length element.

dumpbeam int, default=0

A non-zero value enforces the dump of the particle distribution.

sort int, default=0

A non-zero value enforces the sorting of particles, if one-for-one simulations are enabled.

stop int, default=0

A non-zero value stops the execution of the tracking module. Note that the output file still contains the full length with zeros as output for those integration steps which are no further calculated.

genesis.version4.PhaseShifter

Bases: BeamlineElement

Lattice beamline element: phase shifter.

PhaseShifter corresponds to Genesis 4 beamlineelement phaseshifter.

Attributes:

Name Type Description
L float, default=0.0

Length of the phase shifter in meter.

phi float, default=0.0

Change in the ponderomotive phase of the electrons in units of rad. Note that Genesis 1.3 is doing an autophasing, so that the electrons at reference energy are not changing in ponderomotive phase in drifts.

genesis.version4.Quadrupole

Bases: BeamlineElement

Lattice beamline element: quadrupole.

Quadrupole corresponds to Genesis 4 beamlineelement quadrupole.

Attributes:

Name Type Description
L float, default=0.0

Length of the quadrupole in meter.

k1 float, default=0.0

Normalized focusing strength in 1/m^2.

x_offset float, default=0.0

Offset in \(x\) in meter.

y_offset float, default=0.0

Offset in \(y\) in meter.

genesis.version4.Undulator

Bases: BeamlineElement

Lattice beamline element: an undulator.

Undulator corresponds to Genesis 4 beamlineelement undulator.

Attributes:

Name Type Description
aw float, default=0.0

The dimensionless rms undulator parameter. For planar undulator this value is smaller by a factor \(1 / \sqrt{2}\) than its K-value, while for helical undulator rms and peak values are identical.

lambdau float, default=0.0

Undulator period length in meter. Default is 0 m.

nwig int, default=0

Number of periods.

helical bool, default=False

Boolean flag whether the undulator is planar or helical. A planar undulator has helical=false. Note that setting it to true, does not change the roll-off parameters for focusing. To be consistent they have to be set directly.

kx float, default=0.0

Roll-off parameter of the quadratic term of the undulator field in x. It is normalized with respect to \(k_u^2\).

ky float, default=1.0

Roll-off parameter of the quadratic term of the undulator field in y.

ax float, default=0.0

Offset of the undulator module in \(x\) in meter.

ay float, default=0.0

Offset of the undulator module in \(y\) in meter.

gradx float, default=0.0

Relative transverse gradient of undulator field in \(x\) \(\equiv (1/a_w) \partial a_w/\partial x\).

grady float, default=0.0

Relative transverse gradient of undulator field in \(y\) \(\equiv (1/a_w) \partial a_w/\partial y\).

Attributes

genesis.version4.Undulator.L property
L

Calculated undulator length.