Пример #1
0
def test_zero_errors():
    # check that zero-errors are loaded without error
    cpymad_spec = util.find_spec("cpymad")
    if cpymad_spec is None:
        print("cpymad is not available - abort test")
        sys.exit(0)

    from cpymad.madx import Madx

    madx = Madx()
    madx.input('''
        qd: multipole, knl={0,-0.3};
        qf: multipole, knl={0, 0.3};
        testseq: sequence, l = 1;
            qd, at = 0.3;
            qf, at = 0.6;
        endsequence;
    ''')
    madx.beam()
    madx.use('testseq')
    madx.select(flag='error', pattern='qf')
    madx.command.efcomp(dkn=[0, 0, 0, 0, 0.0, 0.0, 0.0], dks=[0.0, 0.0, 0, 0])
    madx.command.ealign(dx=0.0,
                        dy=0.0,
                        ds=0.0,
                        DPHI=0.0,
                        DTHETA=0.0,
                        DPSI=0.0,
                        MREX=0.0,
                        MREY=0.0,
                        MSCALX=0.0,
                        MSCALY=0.0,
                        AREX=0.0,
                        AREY=0.0)
Пример #2
0
def get_pattern_twiss(
    madx: Madx, patterns: Sequence[str] = [""], columns: Sequence[str] = None, **kwargs,
) -> tfs.TfsDataFrame:
    """
    Extract the `TWISS` table for desired variables, and for certain elements matching a pattern.
    Additionally, the `SUMM` table is also returned in the form of the TfsDataFrame's headers dictionary.

    Warning:
        Although the `pattern` parameter should accept a regex, MAD-X does not implement actual regexes.
        Please refer to the MAD-X manual, section `Regular Expressions` for details on what is implemented
        in MAD-X itself.

    Args:
        madx (cpymad.madx.Madx): an instanciated cpymad Madx object.
        patterns (Sequence[str]): the different element patterns (such as `MQX` or `BPM`) to be applied to
            the command, which will determine the rows in the returned DataFrame. Defaults to [""] which
            will select all elements.
        columns (Sequence[str]): the variables to be returned, as columns in the DataFrame. Defaults to
            None, which will return all available columns.

    Keyword Args:
        Any keyword argument that can be given to the MAD-X TWISS command, such as `chrom`, `ripken`,
        `centre` or starting coordinates with `betax`, 'betay` etc.

    Returns:
        A TfsDataFrame with the selected columns for all elements matching the provided patterns,
        and the internal `summ` table as header dict.
    """
    logger.trace("Clearing 'TWISS' flag")
    madx.select(flag="twiss", clear=True)
    for pattern in patterns:
        logger.trace(f"Adding pattern {pattern} to 'TWISS' flag")
        madx.select(flag="twiss", pattern=pattern, column=columns)
    madx.twiss(**kwargs)

    logger.trace("Extracting relevant parts of the TWISS table")
    twiss_df = tfs.TfsDataFrame(madx.table.twiss.dframe().copy())
    twiss_df.headers = {var.upper(): madx.table.summ[var][0] for var in madx.table.summ}
    twiss_df = twiss_df[madx.table.twiss.selected_columns()].iloc[
        np.array(madx.table.twiss.selected_rows()).astype(bool)
    ]

    logger.trace("Clearing 'TWISS' flag")
    madx.select(flag="twiss", clear=True)
    return twiss_df
Пример #3
0
    def __repr__(self):
        return "".join(ll.decode() for ll in self.out)


madout = Madout()
mad = Madx(stdout=madout)

mad.call("h7ba_n8.seq")
mad.beam(energy=6, sequence="ring", particle="electron", radiate=False)
mad.use("ring")
mad.twiss()
print(mad.table.summ.q1, mad.table.summ.q2)

nslices = 4
mad.select(flag="makethin", clear=True)
mad.select(flag="makethin", class_="sbend", slice=nslices)
mad.select(flag="makethin", class_="quadrupole", slice=nslices)
mad.makethin(sequence="ring")
mad.use(sequence="ring")
print(mad.table.summ.q1, mad.table.summ.q2)
twiss = mad.twiss()
print(mad.table.summ.q1, mad.table.summ.q2)

twissout = pysixtrack.Particles.from_madx_twiss(
    mad.twiss(betx=1, bety=1, x=0.001))

line = pysixtrack.Line.from_madx_sequence(mad.sequence.ring)
part = pysixtrack.Particles()
part.x = 0.001
pysixout = pysixtrack.Particles.from_list(
Пример #4
0
def misalign_lhc_ir_quadrupoles(
    madx: Madx,
    ip: int,
    beam: int,
    quadrupoles: Sequence[int],
    sides: Sequence[str] = ("r", "l"),
    table: str = "ir_quads_errors",
    **kwargs,
) -> None:
    """
    Apply misalignment errors to IR quadrupoles on a given side of a given IP. In case of a sliced
    lattice, this will misalign all slices of the magnet together.

    According to the equipment codes main system, those are Q1 to Q10 included, quads beyond are MQ or MQT
    which are considered arc elements.

    Args:
        madx (cpymad.madx.Madx): an instanciated cpymad Madx object.
        ip (int): the interaction point around which to apply errors.
        beam (int): beam number to apply the errors to. Unlike triplet quadrupoles which are single
            aperture, Q4 to Q10 are not and will need this information.
        quadrupoles (Sequence[int]): the number of quadrupoles to apply errors to.
        sides (Sequence[str]): sides of the IP to apply error on the triplets, either L or R or both.
            Defaults to both.
        table (str): the name of the internal table that will save the assigned errors. Defaults to
            'ir_quads_errors'.

    Keyword Args:
        Any keyword argument to give to the EALIGN command, including the error to apply (DX, DY,
        DPSI etc) as a string, like it would be given directly into MAD-X.

    Warning:
        One should avoid issuing different errors with several uses of this command as it is unclear to me
        how MAD-X chooses to handle this internally. Instead, it is advised to give all errors in the same
        command, which is guaranteed to work. See the last provided example below.

    Examples:
        For systematic DX misalignment:
            misalign_lhc_ir_quadrupoles(
                madx, ip=1, quadrupoles=[1, 2, 3, 4, 5, 6], beam=1, sides="RL", dx="1E-5"
            )
        For a tilt distribution centered on 1mrad:
            misalign_lhc_ir_quadrupoles(
                madx, ip=5, quadrupoles=[7, 8, 9, 10], beam=1, sides="RL", dpsi="1E-3 + 8E-4 * TGAUSS(2.5)"
            )
        For several error types on the elements, here DY and DPSI:
            misalign_lhc_ir_quadrupoles(
                madx,
                ip=1,
                quadrupoles=list(range(1, 11)),
                beam=1,
                sides="RL",
                dy=1e-5,  # ok too as cpymad converts this to a string first
                dpsi="1E-3 + 8E-4 * TGAUSS(2.5)"
            )
    """
    if ip not in (1, 2, 5, 8):
        logger.error(
            "The IP number provided is invalid, not applying any error.")
        raise ValueError("Invalid 'ip'parameter")
    if beam and beam not in (1, 2, 3, 4):
        logger.error(
            "The beam number provided is invalid, not applying any error.")
        raise ValueError("Invalid 'beam' parameter")
    if any(side.upper() not in ("R", "L") for side in sides):
        logger.error("The side provided is invalid, not applying any error.")
        raise ValueError("Invalid 'sides' parameter")

    sides = [side.upper() for side in sides]
    logger.trace("Clearing error flag")
    madx.select(flag="error", clear=True)

    logger.info(
        f"Applying alignment errors to IR quads '{quadrupoles}', with arguments {kwargs}"
    )
    for side in sides:
        for quad_number in quadrupoles:
            for quad_pattern in IR_QUADS_PATTERNS[quad_number]:
                # Triplets are single aperture and don't need beam information, others do
                if quad_number <= 3:
                    madx.select(flag="error",
                                pattern=quad_pattern.format(side=side, ip=ip))
                else:
                    madx.select(flag="error",
                                pattern=quad_pattern.format(side=side,
                                                            ip=ip,
                                                            beam=beam))
    madx.command.ealign(**kwargs)

    table = table if table else "etable"  # guarantee etable command won't fail if someone gives `table=None`
    logger.debug(f"Saving assigned errors in internal table '{table}'")
    madx.command.etable(table=table)

    logger.trace("Clearing up error flag")
    madx.select(flag="error", clear=True)
Пример #5
0
def make_lhc_thin(madx: Madx,
                  sequence: str,
                  slicefactor: int = 1,
                  **kwargs) -> None:
    """
    Makethin for the LHC sequence as previously done in MAD-X macros. This will use the `teapot` style and
    will enforce `makedipedge`.

    Args:
        madx (Madx): an instantiated cpymad.madx.Madx object.
        sequence (str): the sequence to use for the MAKETHIN command.
        slicefactor (int): the slice factor to apply in makethin. Defaults to 1.

    Keyword Args:
        The keyword arguments for the MAD-X MAKETHN commands, namely `style` (will default to `teapot`) and
        the `makedipedge` flag (will default to True).
    """
    logger.info(f"Slicing sequence '{sequence}'")
    madx.select(flag="makethin", clear=True)
    four_slices_patterns = [r"mbx\.", r"mbrb\.", r"mbrc\.", r"mbrs\."]
    four_slicefactor_patterns = [
        r"mqwa\.",
        r"mqwb\.",
        r"mqy\.",
        r"mqm\.",
        r"mqmc\.",
        r"mqml\.",
        r"mqtlh\.",
        r"mqtli\.",
        r"mqt\.",
    ]

    logger.trace("Defining slices for general MB and MQ elements")
    madx.select(flag="makethin", class_="MB", slice=2)
    madx.select(flag="makethin", class_="MQ", slice=2 * slicefactor)

    logger.trace("Defining slices for triplets")
    madx.select(flag="makethin", class_="mqxa", slice=16 * slicefactor)
    madx.select(flag="makethin", class_="mqxb", slice=16 * slicefactor)

    logger.trace("Defining slices for various specifc mb elements")
    for pattern in four_slices_patterns:
        madx.select(flag="makethin", pattern=pattern, slice=4)

    logger.trace("Defining slices for varous specifc mq elements")
    for pattern in four_slicefactor_patterns:
        madx.select(flag="makethin", pattern=pattern, slice=4 * slicefactor)

    madx.use(sequence=sequence)
    style = kwargs.get("style", "teapot")
    makedipedge = kwargs.get(
        "makedipedge",
        False)  # defaults to False to compensate default TEAPOT style
    madx.command.makethin(sequence=sequence,
                          style=style,
                          makedipedge=makedipedge)