function to construct patches for ``plotLattice()``, from different elements like
    ``rbend``, ``quadrupole``,etc. parsing from lattice file, mad-8.
    drift sections are calculated from other elements.

    Input parameters:

    :param beamlinelist: list, which elements are dict, each dict is the description for magnetic element, should be returned from module ``blparser``, function ``madParser()``
    :param startpoint: pos to start drawing, ``(0, 0)`` by default
    :return: tuple of beamline patches list, xlim and ylim
        * beamline patches list: patches to be drawn
        * xlim: data limit along x-axis
        * ylim: data limit along y-axis

def makeBeamline(beamlinelist, startpoint=(0, 0)):
    """
    function to construct patches for ``plotLattice()``, from different elements like
    ``rbend``, ``quadrupole``,etc. parsing from lattice file, mad-8.
    drift sections are calculated from other elements.

    Input parameters:

    :param beamlinelist: list, which elements are dict, each dict is the description for magnetic element, should be returned from module ``blparser``, function ``madParser()``
    :param startpoint: pos to start drawing, ``(0, 0)`` by default
    :return: tuple of beamline patches list, xlim and ylim
        * beamline patches list: patches to be drawn
        * xlim: data limit along x-axis
        * ylim: data limit along y-axis
    """
    latticelist = []
    anglenow = 0.0
    maxx, maxy = startpoint
    minx, miny = startpoint

    for i in range(len(beamlinelist)):
        element = beamlinelist[i]
        elementtype = element["type"][0:4].lower()
        if elementtype == "rben":
            newelement = elements.Rbend(width=float(element["l"]), height=1.5 * float(element["l"]),
                                        angle=float(element["angle"]),
                                        link_node=startpoint, )
            anglenow += newelement.angle
            minx = min(minx, newelement.minx)
            miny = min(miny, newelement.miny)
            maxx = max(maxx, newelement.maxx)
            maxy = max(maxy, newelement.maxy)

        elif elementtype == "drif":
            newelement = elements.Drift(length=float(element["l"]), angle=anglenow,
                                        link_node=startpoint, )
            minx = min(minx, newelement.minx)
            miny = min(miny, newelement.miny)
            maxx = max(maxx, newelement.maxx)
            maxy = max(maxy, newelement.maxy)

        elif elementtype == "quad":
            xory = "x"
            if float(element["k1"]) < 0:
                xory = "y"
            newelement = elements.Quadrupole(width=float(element["l"]),
                                             angle=float(element["angle"]),
                                             xysign=xory,
                                             link_node=startpoint, )
            minx = min(minx, newelement.minx)
            miny = min(miny, newelement.miny)
            maxx = max(maxx, newelement.maxx)
            maxy = max(maxy, newelement.maxy)

        elif elementtype == "undu":
            newelement = elements.Undulator(period_length=float(element["xlamd"]),
                                            period_number=int(element["nwig"]),
                                            link_node=startpoint, )
            minx = min(minx, newelement.minx)
            miny = min(miny, newelement.miny)
            maxx = max(maxx, newelement.maxx)
            maxy = max(maxy, newelement.maxy)

        else:
            print("unknown element\n")

        startpoint = newelement.link_node
        latticelist.append(newelement)

    return latticelist, np.array([minx, maxx]), np.array([miny, maxy])