def cell(diameter=diameter):
        """Create a DCpad cell.

        Args:
            diameter (float): diameter of circular debt

        Returns:
            Cell
        """
        with nd.Cell(hashme=True) as C:
            C.groupname = groupname
            pdk.addBBmap(name)
            bb_width = diameter + 2*buf_width
            bb_length = diameter + 2*buf_length

            C.default_pins('c0', 'c0')
            nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0'], remark='electrical').\
                put(0.5*bb_length, 0, 180)

            pdk.put_stub('c0', length=pinwidth['c0'], shape='circle')
            pdk.put_boundingbox('org', bb_length, bb_width)

            for lay, grow, acc in nd.layeriter(xs['c0']):
                pad = nd.geom.circle(radius=0.5*diameter, N=100)
                nd.Polygon(layer=lay, points=pad).\
                    put('cc')

        return C
    def cell(length=length, angle=angle):
        anglerad = radians(angle)
        """Create a trapezoidal IO cell.

        Returns:
            Cell
        """
        with nd.Cell(hashme=True, instantiate=False) as C:
            #When instantiate is True, cell put in (0,0,0)
            nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180)
            nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).\
                put(length/cos(anglerad)-0.5*width*tan(abs(anglerad)))

            pdk.put_stub(['b0'])
            pdk.cellname(length=0.5 * length).put(-0.1 * length, 0, 180, 'a0')

            for lay, grow, acc in nd.layeriter(xs['a0']):
                outline = nd.geom.trapezoid(length=length / cos(anglerad) +
                                            grow * tan(abs(anglerad)),
                                            height=width + 2 * grow,
                                            angle1=90 + angle,
                                            angle2=90,
                                            position=2)
                nd.Polygon(layer=lay, points=outline).put(0)
            cfg.cp = C.pin['b0']
            C.groupname = groupname
        return C
    def cell(length=length, width=width):
        """Create a DCpad_lw cell.

        Args:
            length (float): length of the pad in um
            width (float): width of the pad in um

        Returns:
            Cell: dcpad element
        """
        with nd.Cell(hashme=True) as C:
            C.groupname = groupname
            C.default_pins('c0','c0')
            buf = 10
            bb_width = width + buf
            bb_length = length + buf
            nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0'], remark='electrical').\
                put(0.5*bb_length, 0, 180)
            pdk.put_stub('c0', length=pinwidth['c0'], shape='circle')
            pdk.put_boundingbox('org', bb_length, bb_width)

            for lay, grow, acc in nd.layeriter(xs['c0']):
                pad = nd.geom.rounded_rect(
                    length=length+grow, height=width, position=5)
                nd.Polygon(layer=lay, points=pad).\
                    put(C.pin['c0'])
        return C
    def cell(length=length, angle=angle):
        anglerad = radians(angle)
        """Create a trapezoidal IO cell.

        Returns:
            Cell
        """
        with nd.Cell(hashme=True, instantiate=False) as C:
            """When instantiate is True, cell put in (0, 0, 0)"""
            nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180)
            nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).\
                put(0.5*length*(1.0+1.0/cos(anglerad)))

            pdk.put_stub(['a0', 'b0'])
            pdk.cellname(length=0.5 * length).put(C.pin['a0'].rot(180))

            temp_a = tan(anglerad) + 0.5 * width * tan(anglerad)
            temp_b = length / cos(anglerad) + length
            for lay, grow, acc in nd.layeriter(xs['a0']):
                outline = [(0, 0.5 * width + grow),
                           (0.5 * temp_b - (width + grow) * temp_a,
                            0.5 * width + grow),
                           (0.5 * temp_b + grow * temp_a, -0.5 * width - grow),
                           (0, -0.5 * width - grow)]
                nd.Polygon(layer=lay, points=outline).put(0)
            cfg.cp = C.pin['b0']
        C.groupname = groupname
        return C
    def cell(length=length, height=height, cleave=cleave, pitch=pitch):
        """Create a cell boundary.

        Returns:
            Cell
        """
        with nd.Cell(hashme=True) as C:
            pdk.parameters('hashme').put(0)

            #TODO: No foundry specific stuff here: remove.
            for lay, grow, acc in nd.layeriter(xs):
                frame = geom.frame(sizew=cleave,
                                   sizel=length,
                                   sizeh=height,
                                   grow=grow)
                nd.Polygon(layer=lay, points=frame).put(0)

            #Placing IOs
            amount_ios = round((height - cleave - pitch) / pitch)

            #IOs positions
            lay = 'AnnotationIO'
            for no in range(0, amount_ios):
                pinID = 'ioL{:03d}'.format(no)
                angle = 0

                p = nd.Pin(name=pinID).put(-cleave, pitch + no * pitch, angle)
                p = nd.Pin(name='ioL' + str(no)).put(-cleave,
                                                     pitch + no * pitch, angle)
                pdk.arrow.put(p)
                nd.text(pinID, layer=lay, height=0.15,
                        align='rc').put(p.move(-0.1))

            for no in range(0, amount_ios):
                mo = amount_ios + no
                pinID = 'ioR{:03d}'.format(no)
                angle = 0

                p = nd.Pin(name=pinID).put(length, pitch + no * pitch,
                                           180 + angle)
                p = nd.Pin(name='ioR' + str(no)).put(length,
                                                     pitch + no * pitch,
                                                     180 + angle)
                pdk.arrow.put(p)
                nd.text(pinID, layer=lay, height=0.15, align='lc').\
                    put(p.move(-0.1, 0, 180))

        C.groupname = groupname
        return C
    def cell(length=length, angle=angle):
        """Create a trapezoidal IO cell.

        Returns:
            Cell
        """
        a = radians(angle)
        with nd.Cell(hashme=True, instantiate=False) as C:
            l = 0.5 * length / cos(a)  # half the length of the hypotenuse.
            """When instantiate is True, cell put in (0,0,0)"""
            nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180)
            nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).put(l)

            pdk.put_stub(['b0'])
            pdk.cellname(C.cell_name, -0.5 * l).put(0, 'a0')

            for lay, grow, acc in nd.layeriter(xs['a0']):
                w = (width + 2 * grow) / 2
                x = w * tan(a)
                outline = [(l, w), (-l + x, w), (-l - x, -w), (l, -w)]
                nd.Polygon(layer=lay, points=outline).put(0)
            cfg.cp = C.pin['b0']
        C.groupname = groupname
        return C
    def cell(cleave=cleave,
             length=length,
             height=height,
             coatingW=coatingW,
             coatingE=coatingE):
        """Create a Cell_Boundary cell.

        Returns:
            Cell
        """
        with nd.Cell(hashme=True) as C:

            pdk.put_boundingbox('org', length, height, outline=False, \
                move=(-0.5*cleave, 0.5*height-0.5*cleave))
            pdk.parameters('hashme').put(0, 'cc')

            #TODO: No foundry specific stuff here: remove.
            outline = [(0, 0), (length - cleave, 0),
                       (length - cleave, height - cleave),
                       (0, height - cleave)]
            nd.Polygon(layer='Polyimide1Base', points=outline).put(0)

            for lay, grow, acc in nd.layeriter(xs):
                frame = geom.frame(sizew=cleave,
                                   sizel=length,
                                   sizeh=height,
                                   grow=grow)
                nd.Polygon(layer=lay, points=frame).put(0)

            ##adding coating to nd.Cell boundary: west and east
            options = {
                'AR': 'Coating_AR',
                'HR': 'Coating_HR',
                'NO': 'Coating_NO',
                'DC': 'Coating_DC'
            }
            coating_on_chip = nd.get_parameter('cell_coating_on_chip')
            box_coatno = [(0, 0), (cleave / 2, 0), (cleave / 2, height),
                          (0, height)]
            box_coatother = [(0, 0), (coating_on_chip + 0.5 * cleave, 0),
                             (coating_on_chip + 0.5 * cleave, height),
                             (0, height)]
            pinW = nd.Pin().put(-0.5 * cleave, -0.5 * cleave)
            pinE = nd.Pin().put(length - 0.5 * cleave, height - 0.5 * cleave,
                                180)

            coatings = {'E': (coatingE, pinE), 'W': (coatingW, pinW)}

            for coat, pin in coatings.values():
                if coat in options.keys():
                    layer = options[coat]
                else:
                    print(
                        'Available coating options: AR | HR | NO | DC. Default is NO.'
                    )

                if coat is 'NO':
                    box = box_coatno
                else:
                    box = box_coatother
                nd.Polygon(layer=layer, points=box).put(pin)

            #Placing IOs
            pitch = 12.5
            amount_ios = round((height - cleave - pitch) / pitch)

            #IOs positions
            lay = 'bb_pin'
            for no in range(0, amount_ios):
                pinID = 'io{:03d}'.format(no)
                if no % 2 is 0:
                    angle = 7
                else:
                    angle = 0

                p = nd.Pin(name=pinID).put(-cleave / 2, 12.5 + no * pitch,
                                           angle)
                p = nd.Pin(name='io' + str(no)).put(-cleave / 2,
                                                    12.5 + no * pitch, angle)
                pdk.make_pincell().put(p)
                nd.text(pinID, layer=lay, height=0.15,
                        align='rc').put(p.move(-0.1))

            for no in range(0, amount_ios):
                mo = amount_ios + no
                pinID = 'io{:03d}'.format(mo)
                if mo % 2 is 0:
                    angle = 7
                else:
                    angle = 0

                p = nd.Pin(name=pinID).put(length - cleave / 2,
                                           2 * 12.5 + no * pitch, 180 + angle)
                pdk.make_pincell().put(p)
                nd.text(pinID, layer=lay, height=0.15, align='lc').\
                    put(p.move(-0.1, 0, 180))

            C.groupname = groupname
        return C
def _makestub(xs_guide=None,
              width=0,
              length=2.0,
              shape=None,
              pinshape=None,
              pinsize=None,
              pinlayer=None,
              cell=None):
    """Create a stub in the logical layers.

    A stub is the stub of a xsection shape around a pin to visualize a connection.
    A pincell is added to the stub to indicate the pin position inside the stub.
    The new stub is added to the stubs dictionary: {name: stubcell}

    Args:
        xs_guide (str): name of xsection
        width (float): stub width
        thick (float): thickness of stub into cell (length)
        shape (str): shape of the stub: 'box' | 'circ' (default = 'box')
        pinshape (string): pinshape used in the stub
        pinsize (float): scaling factor of the pinshape (default = 1)
        cell (Cell): use the provided cell as stub instead of creating a new stub cell

    Returns:
        str: name of the stub
    """
    try:
        xs_logic = cfg.stubmap[xs_guide]
    except:
        # if no stub defined, use the xs as its own stub.
        if xs_guide is None:
            arrow = make_pincell(layer=pinlayer, shape=pinshape, size=pinsize)
            return arrow

        if xs_guide not in cfg.XSdict.keys():
            if xs_guide not in missing_xs:
                missing_xs.append(xs_guide)
                if xs_guide != cfg.default_xs_name:
                    print("Can not make a stub in undefined xsection '{0}'.\n"\
                       "  Possible causes: '{0}' is misspelled or not yet defined.\n"\
                       "  Will use xsection '{2}' instead and continue.\n"
                       "  To define a new xsection:\n"\
                       "      add_xsection(name='{0}')\n"\
                       "  or with layers info and adding a custom stub:\n"\
                       "      add_xsection(name='{0}', layer=1)\n"\
                       "      add_xsection(name='{1}', layer=2)\n"\
                       "      add_stub(xsection='{0}', stub='{1}')".\
                           format(xs_guide, 'stubname', cfg.default_xs_name))
                xs_guide = cfg.default_xs_name

        cfg.stubmap[xs_guide] = xs_guide
        xs_logic = xs_guide

    name = stubname(xs_guide, width, length, shape, pinshape, pinsize,
                    pinlayer)
    if name in stubs.keys():
        return name

    # make a new stub:
    stubshapes = ['box', 'circle']
    arrow = make_pincell(layer=pinlayer, shape=pinshape, size=pinsize)

    if width is None:
        width = 0

    with nd.Cell(name, instantiate=cfg.stub_instantiate,
                 store_pins=False) as C:
        arrow.put(0)

        if cell is not None:
            cell.put()
        else:
            for lay, growx, acc in nd.layeriter(xs_logic):
                if shape is 'circle':
                    outline = geom.circle(radius=0.5 * length, N=32)
                else:
                    outline = geom.box(width=width + 2 * growx, length=length)
                if width != 0:
                    nd.Polygon(layer=lay, points=outline).put(0, 0, 180)

                if shape not in stubshapes:
                    print(
                        "Warning: stub shape '{}' not recognized, possible options are {}."
                        .format(shape, stubshapes))
    stubs[name] = C
    return name  #name can have change to default_xs