Esempio n. 1
0
    def test_Composition(self):
        J = Swoop.Mixin(self.Jumper, "Jump")
        WJ = Swoop.Mixin(self.Walker, "Walk", base=J)

        wjl = WJ.from_file(self.me + "/inputs/Components.lbr")

        self.assertEqual(wjl.get_library().jump(), "jump",
                         "Extension composition error")
        self.assertEqual(wjl.get_library().walk(), "walk",
                         "Extension composition error")

        WJA = Swoop.Mixin(Area, "Area", base=WJ)
        wjal = WJA.from_file(self.me + "/inputs/Components.lbr")
        self.assertAlmostEqual(From(wjal).get_library().get_packages(
        ).get_drawing_elements().with_type(Rectangle).get_area().reduce(
            lambda x, y: x + y, init=0.0),
                               7711.54157257,
                               places=5,
                               msg="Extension composition error")

        A = Swoop.Mixin(Area, "Area")
        AJ = Swoop.Mixin(self.Jumper, "Jump", base=A)
        ajl = AJ.from_file(self.me + "/inputs/Components.lbr")
        self.assertAlmostEqual(From(ajl).get_library().get_packages(
        ).get_drawing_elements().with_type(Rectangle).get_area().reduce(
            lambda x, y: x + y, init=0.0),
                               7711.54157257,
                               places=7,
                               msg="Extension composition error")
Esempio n. 2
0
    def setUp(self):
        #log.basicConfig(format="%(levelname)s: %(message)s", level=log.DEBUG)

        NewEagleFile = Swoop.Mixin(self.MyMixin, "Typer")

        self.me = os.path.dirname(os.path.realpath(__file__))
        self.sch = NewEagleFile.from_file(
            self.me +
            "/inputs/Xperimental_Trinket_Pro_small_parts_power_breakout.picked.sch"
        )
        self.brd = NewEagleFile.from_file(
            self.me +
            "/inputs/Xperimental_Trinket_Pro_small_parts_power_breakout.picked.brd"
        )
        self.lbr = NewEagleFile.from_file(self.me + "/inputs/Components.lbr")

        NewEagleFileMod = Swoop.Mixin(testExt, "Mod")
        #print(NewEagleFile.__name__)
        self.lbr2 = NewEagleFileMod.from_file(self.me +
                                              "/inputs/Components.lbr")

        AreaEagleFile = Swoop.Mixin(Area, "Area")
        #print(NewEagleFile.__name__)
        self.lbr_area = AreaEagleFile.from_file(self.me +
                                                "/inputs/Components.lbr")
Esempio n. 3
0
def propagatePartToBoard(part, brd):
    """
    Copy :code:`part` to ``brd`` by creating a new :class:`Element` and populating it accordingly.
    If the part already exists, it will be replaced.  Attributes are not displayed by default, but the display layer is set to "Document".
    
    If the library for the part is missing in the board, it will be create.  If the package is missing, it will be copied.  If it exists and the package for the part and the package in the board are not the same, raise an exception.

    .. Note::
       This function doesn't update the board's signals.  You can run :meth:`rebuildBoardConnections` to do that.

    :param part: :class:`Part` object that to propagate.
    :param brd: Destination :class`BoardFile`.
    :rtype: :code:`None`

    """
    if part.find_device().get_package() is None:
        return

    if part.find_package() is None:
        raise Swoop.SwoopError(
            "Can't find package for '{}' ({}.{}.{}.{}).".format(
                part.get_name(), part.get_library(), part.get_deviceset(),
                part.get_device(), part.get_technology()))

    dst_lib = brd.get_library(part.get_library())

    if dst_lib is None:
        dst_lib = Swoop.Library().set_name(part.get_library())
        brd.add_library(dst_lib)

    #src_lib = part.find_library()
    #assert src_lib is not None, "Missing library '{}' for part '{}'".format(part.get_library(), part.get_name())

    dst_package = dst_lib.get_package(part.find_package().get_name())
    if dst_package is None:
        dst_package = part.find_package().clone()
        dst_lib.add_package(dst_package)
    else:
        assert dst_package.is_equal(part.find_package(
        )), "Package from schematic is not the same as package in board"

    # Reverse-engineered logic about setting values in board files.
    if part.find_deviceset().get_uservalue():
        fallback_value = ""
    else:
        fallback_value = part.get_deviceset() + part.get_device()

    n = (Swoop.Element().set_name(part.get_name()).set_library(
        part.get_library()).set_package(
            part.find_package().get_name()).set_value(part.get_value(
            ) if part.get_value() is not None else fallback_value).set_x(
                0).set_y(0))

    for a in part.find_technology().get_attributes():
        n.add_attribute(a.clone().set_display("off").set_layer("Document"))

    for a in part.get_attributes():
        n.add_attribute(a.clone().set_display("off").set_layer("Document"))

    brd.add_element(n)
Esempio n. 4
0
    def test_Heterogenous(self):

        J = Swoop.Mixin(self.Jumper, "Jump")
        W = Swoop.Mixin(self.Walker, "Walk")

        js = J.from_file(self.me + "/inputs/test06.sch")
        ws = W.from_file(self.me + "/inputs/test06.sch")

        jl = J.from_file(self.me + "/inputs/Components.lbr")
        wl = W.from_file(self.me + "/inputs/Components.lbr")

        # print EagleFile.class_map["library"]
        # print J.class_map["library"]
        # print W.class_map["library"]

        # print "2here " + str(type(js.get_libraries()[0]))
        # print js.get_libraries()[0].do_it()
        # print ws.get_libraries()[0].do_it()

        # print jl.get_library().get_packages()[0].do_it()
        # print wl.get_library().get_packages()[0].do_it()

        self.assertEqual(js.get_libraries()[0].do_it(), "jump",
                         "Heterogenous extension error")
        self.assertEqual(ws.get_libraries()[0].do_it(), "walk",
                         "Heterogenous extension error")
        self.assertEqual(jl.get_library().get_packages()[0].do_it(), "jump",
                         "Heterogenous extension error")
        self.assertEqual(wl.get_library().get_packages()[0].do_it(), "walk",
                         "Heterogenous extension error")

        self.assertEqual(type(jl.new_Package()),
                         type(jl.get_library().get_packages()[0]),
                         "EFP factory error")
Esempio n. 5
0
    def check_routing(self):
        with NestedError(self.errors, self.brd.get_filename()):

            unrouted = Swoop.From(
                self.brd).get_signals().get_wires().with_width(0.0)
            if unrouted.count() > 0:
                self.error(u"You have unrouted nets: {}".format(" ".join(
                    map(output_format,
                        unrouted.get_parent().unique().sort()))),
                           inexcusable=True)

            routed_wires = Swoop.From(
                self.brd).get_signals().get_wires().without_width(0.0)

            self.check_intersections(routed_wires)

            for w in routed_wires:
                with NestedError(self.errors, w):
                    x1, y1, x2, y2 = w.get_points()

                    if abs(x1 - x2) < 0.1 or abs(y1 - y2) < 0.1 or abs(
                            abs(x1 - x2) -
                            abs(y1 - y2)) < 0.1 or w.get_length() < 2:
                        pass
                    else:
                        self.warn(
                            "Net routed at odd angle: {} centered at ({}, {}) in layer {}.  Net should only be vertical, horizontal, or diagonal (i.e., 45 degrees)."
                            .format(output_format(w.get_parent()),
                                    (x1 + x2) / 2, (y1 + y2) / 2,
                                    w.get_layer()))
Esempio n. 6
0
    def check_names(self):
        parts = Swoop.From(self.sch).get_parts().filtered_by(
            lambda x: "$" in x.get_name()).sort()
        if parts:
            self.warn(
                "These parts have '$' in their names.  Parts should all have nice, pretty names.  Either set the prefix on the device or name it yourself: {}"
                .format(" ".join(map(output_format, parts))),
                inexcusable=True)

        labeled_nets = Swoop.From(self.sch).get_sheets().get_nets(
        ).get_segments().get_labels().get_parent().get_parent().filtered_by(
            lambda x: '$' in x.get_name()).sort()

        if labeled_nets.count():
            self.warn(
                "These nets have labels on them and have '$' in their names.  Labeled nets should have meaningful names: {}"
                .format(" ".join(map(output_format, labeled_nets))),
                inexcusable=True)

        net_names = set(
            Swoop.From(self.sch).get_sheets().get_nets().get_name())
        part_names = set(Swoop.From(self.sch).get_parts().get_name())

        i = net_names.intersection(part_names)
        if i:
            self.warn(
                "The following are names of both a net and part.  That's confusing: {}"
                .format(", ".join(map(lambda x: "'{}'".format(x), i))),
                inexcusable=True)
Esempio n. 7
0
    def match(self, pattern):
        solutions = []

        for i in range(0, len(pattern)):
            if isinstance(pattern[i], Swoop.Part):
                pattern[i] = Part(part=pattern[i])
            elif isinstance(pattern[i], Swoop.Net):
                pattern[i] = Net(net=pattern[i])

        link = pattern[0]
        if isinstance(link, Part):
            options = Swoop.From(
                self.sch).get_parts().filtered_by(lambda x: link.match(x))
        elif isinstance(link, Net):
            options = Swoop.From(self.sch).get_sheets().get_nets().filtered_by(
                lambda x: link.match(x))
        else:
            raise Exception(
                "First link in pattern must be Net or Part: {}".format(link))

        for o in options:
            path = [o]
            self.do_match(path, pattern[1:], solutions)

        return solutions
Esempio n. 8
0
    def do_match(self, path, pattern, solutions):
        if len(pattern) == 0:
            solutions.append(path)
            return
        tail = path[-1]

        if isinstance(tail, Swoop.Part):

            if len(pattern) == 2:
                pin_link = pattern[0]
                assert isinstance(pin_link, Pin)
                net_link = pattern[1]
                assert isinstance(net_link, Net), "{}".format(net_link)

                nets = (Swoop.From(
                    self.sch).get_sheets().get_nets().filtered_by(
                        lambda x: net_link.match(x)).get_segments().
                        get_pinrefs().filtered_by(
                            lambda x: pin_link.match(x) and x.get_part(
                            ) == tail.get_name()).get_parent().get_parent())
                for n in nets:
                    self.do_match(path + [n], pattern[2:], solutions)

            elif len(pattern) > 2:
                initial_pin_link = pattern[0]
                assert isinstance(initial_pin_link, Pin)
                net_link = pattern[1]
                assert isinstance(net_link, Net)
                terminal_pin_link = pattern[2]
                assert isinstance(terminal_pin_link, Pin)
                part_link = pattern[3]
                assert isinstance(part_link, Part), "Bad pattern: {}".format(
                    str_pattern(pattern=pattern))

                nets = (Swoop.From(self.sch).get_sheets().get_nets(
                ).filtered_by(lambda x: net_link.match(x)).get_segments(
                ).get_pinrefs().filtered_by(lambda x: x.get_part(
                ) == tail.get_name()).get_parent().get_parent().unique())

                for n in nets:
                    refs = (Swoop.From(n).get_segments().get_pinrefs())
                    initial_pin_matches = refs.filtered_by(
                        lambda x: initial_pin_link.match(x) and x.get_part(
                        ) == tail.get_name())
                    terminal_pin_matches = refs.filtered_by(
                        lambda x: terminal_pin_link.match(x))

                    if (len(initial_pin_matches)):
                        parts = map(lambda x: self.sch.get_part(x),
                                    terminal_pin_matches.get_part())
                        for p in parts:
                            if part_link.match(p) and p != tail:
                                self.do_match(path + [n, p], pattern[4:],
                                              solutions)

            else:
                raise Exception("Couldn't process pattern {}".format(
                    str_pattern(path, pattern)))
        else:
            raise Exception("Patterns must start with a part.")
Esempio n. 9
0
def rename_part(old, new, schematic=None, board=None):
    """Rename a part in a schematic and the corresponding board, if provided.
    Change the name of the part and update all references to it.
    
    :param schematic: The :class:`SchematicFile` in which to do the renaming
    :param board: The :class:`BoardFile` in which to do the renaming (optional)
    :param old: Old part name.
    :param new: New part name.

    """

    if schematic is not None:
        old_part = schematic.get_part(old)
        old_part.set_name(new)

        for i in Swoop.From(schematic).get_sheets().get_instances():
            if i.get_part().upper() == old.upper():
                i.set_part(new.upper())

        for pinref in Swoop.From(schematic).get_sheets().get_nets(
        ).get_segments().get_pinrefs():
            if pinref.get_part().upper() == old.upper():
                pinref.set_part(new.upper())

    if board is not None:
        for e in Swoop.From(board).get_elements():
            if e.get_name().upper() == old.upper():
                e.set_name(new.upper())

        for contact_ref in Swoop.From(board).get_signals().get_contactrefs():
            if contact_ref.get_element().upper() == old.upper():
                contact_ref.set_element(new.upper())
Esempio n. 10
0
    def check_deviceset(self, ds, power_and_ground):
        with NestedError(self.errors, ds):
            gates = Swoop.From(ds).get_gates()

            if len(gates) == 1:
                if gates[0].get_x() != 0 or gates[0].get_y() != 0:
                    self.warn(
                        u"In the left pane of the device window, the schematic symbol for device should be at origin (0,0) instead of ({} ,{})."
                        .format(gates[0].get_x(), gates[0].get_y()),
                        inexcusable=True)

            if ds.get_name() not in power_and_ground:
                if ds.get_uservalue():
                    if len(
                            Swoop.From(ds).get_gates().find_symbol().
                            get_drawing_elements().with_type(
                                Swoop.Text).with_text(
                                    lambda x: x.upper() == ">VALUE")) == 0:
                        self.warn(
                            u"Device has user value (look for a check box at the bottom of the device editor window), but symbol does not include '>VALUE'.  This means the value will not visible in the schematic."
                        )

            for device in ds.get_devices():
                value_labels = Swoop.From(
                    device).find_package().get_drawing_elements().with_type(
                        Swoop.Text).with_text(
                            lambda x: x.upper() == ">VALUE").count()

                if ds.get_uservalue() and value_labels == 0:
                    self.warn(
                        u"Device has user value (look for a check box at the bottom of the device editor window), but package for variant '{}' does not include '>VALUE'.  This means the value will not be visible in the board."
                        .format(device.get_name()))
                if not ds.get_uservalue() and value_labels > 0:
                    self.warn(
                        u"Device does not have user value (look for a check box at the bottom of the device editor window), but package for variant '{}' includes '>VALUE'.  This means the package name will appear on the board, which is probably not what you want."
                        .format(device.get_name()))

            for d in ds.get_devices():
                if d.get_package() is not None:
                    with NestedError(self.errors, d):
                        t = d.get_technology("")
                        if not t:
                            self.warn(
                                "{} does not have a default technology".format(
                                    d.get_name()))
                            continue
                        for a in self.required_deviceset_attributes:
                            if t.get_attribute(
                                    a) is None or not t.get_attribute(
                                        a).get_value():
                                self.warn(
                                    u"Missing required attribute '{}'".format(
                                        a),
                                    inexcusable=True)
                            elif not t.get_attribute(a).get_constant():
                                self.warn(
                                    u"Attribute '{}' should be constant.".
                                    format(a),
                                    inexcusable=True)
Esempio n. 11
0
    def test_Detach(self):

        brd = self.brd.clone()

        (Swoop.From(brd).get_layers().with_name(Swoop.matching("^t")).detach())

        self.assertEqual(
            Swoop.From(brd).get_layers().count(), 56, "Detach Error")
Esempio n. 12
0
    def check_frame(self):
        if not Swoop.From(self.sch).get_parts().with_deviceset("FRAME_B_L"):
            self.warn(u"You don't have a frame around your schematic.")

        if Swoop.From(self.sch).get_sheets().get_plain_elements().with_layer(
                "Info") < 5:
            self.warn(
                u"You don't have enough documentation (items in layer 'Info') on your schematic.  If your schematic is very simple, you can provide that as an explanation for why no documentation is needed."
            )
Esempio n. 13
0
def copy_deviceset(deviceset, to_lib):
    """Copy :code:`deviceset` and all associated packages and symbols to :code:`to_lib`.  Fail if there are any name conflicts.

    """

    for p in Swoop.From(deviceset).get_devices().find_package():
        to_lib.add_package(p.clone())
    for s in Swoop.From(deviceset).get_gates().find_symbol():
        to_lib.add_symbol(s.clone())
    to_lib.add_deviceset(deviceset.clone())
Esempio n. 14
0
def consolidate_parts_in_schematic(schematic,
                                   lib_name,
                                   part_names=None,
                                   ignore_conflicts=False):
    """
    Create a new library called :code:`lib_name` in :code:`schematic` that the
    information for the parts listed in :code:`part_names`.  Check for
    conflicting names.

    Update the parts to refer to the new libray. 

    Warning:  This will make the schematic inconsistent with the board (if one exists).

    :param schematic: A :class:`SchematicFile` object to operate on.
    :param lib_name: The name of the new library.
    :param part_names: An array of part names (i.e., reference designators).  If :code:`None` then do all the parts.  Defaults to :code:`None`.
    :returns:  Nothing.
    """

    if schematic.get_library(lib_name) is None:
        lib = Swoop.Library().set_name(lib_name)
        schematic.add_library(lib)
    else:
        lib = schematic.get_library(lib_name)

    src_lib = {}

    def check_for_conflicts(name, lib):
        if name in src_lib:
            assert src_lib[name] == lib, "Name '{}' in both {} and {}".format(
                name, lib, src_lib[name])
        else:
            src_lib[name] = lib

    for p in Swoop.From(schematic).get_parts().filtered_by(
            lambda x: part_names is None or x.get_name() in part_names):
        package = p.find_device().find_package()
        if package is not None:
            if not ignore_conflicts:
                check_for_conflicts(package.get_name(), p.get_library())

        for s in Swoop.From(p).find_deviceset().get_gates().find_symbol():
            if not ignore_conflicts:
                check_for_conflicts(s.get_name(), p.get_library())

        if not ignore_conflicts:
            check_for_conflicts(p.find_deviceset().get_name(), p.get_library())

        copy_deviceset(p.find_deviceset(), lib)

        p.set_library(lib_name)

    return lib
Esempio n. 15
0
def consolidate_libraries_in_schematic(schematic,
                                       new_lib_name,
                                       lib_names,
                                       cleanup=False):
    """Create a new library called :code:`new_lib_name` in :code:`schematic` that the
    information for all the parts from libraries listed in :code:`lib_names`.

    Update the parts to refer to the new libray.  If :code:`remove_libs` is
    :code:`True`, then remove the old libraries from the schematic.

    Warning:  This will make the schematic inconsistent with the board (if one exists).

    :param schematic: A :class:`SchematicFile` object to operate on.
    :param new_lib_name: The name of the new library.
    :param lib_names: An array of library names to remove.
    :param remove_libs: Should we remove the libraries in :code:`lib_names` after consolidation?
    :returns:  The new :code:`Library` object in :code:`schematic'

    """

    part_names = Swoop.From(schematic).get_parts().filtered_by(
        lambda x: x.get_library() in lib_names).get_name().unique()
    lib = consolidate_parts_in_schematic(schematic, new_lib_name, part_names)

    if cleanup:
        removeDeadEFPs(schematic)

    return lib
Esempio n. 16
0
    def check_connections(self):
        parts = self.match([
            Part(select=lambda x: count_pins(x) == 2,
                 description="a two-terminal device")
        ])

        for p in parts:
            p = p[0]

            for g in Swoop.From(p).find_deviceset().get_gates():
                for n in Swoop.From(self.sch).get_sheets().get_nets():
                    if Swoop.From(n).get_segments().get_pinrefs().with_part(
                            p.get_name()).with_gate(g.get_name()).count() == 2:
                        self.error(
                            "Both pins on {} are connected to the same net ({})."
                            .format(output_format(p), output_format(n)))
Esempio n. 17
0
    def test_ConstantAttrs(self):
        sch = self.sch.clone()

        a = Swoop.From(sch).get_libraries().get_devicesets().get_devices(
        ).get_technologies().get_attributes()[0]

        self.assertEqual(
            a.get_xml(),
            '<attribute name="CASE" value="" constant="no"/>'.encode('utf8'))
        a.set_constant(True)
        self.assertEqual(a.get_xml(),
                         '<attribute name="CASE" value=""/>'.encode('utf8'))
        a.set_constant(False)
        self.assertEqual(
            a.get_xml(),
            '<attribute name="CASE" value="" constant="no"/>'.encode('utf8'))

        brd = self.brd.clone()
        c1a = brd.get_element("C1A")
        c1b = brd.get_element("C1B")
        c1 = brd.get_element("C1")

        self.assertEqual(c1a.get_locked(), True)
        self.assertEqual(c1b.get_locked(), False)
        self.assertEqual(c1.get_locked(), False)
Esempio n. 18
0
def mergeLayers(src, dst, force=False):
    """
    Merge layers from the :class:`EagleFile` :code:`src` into :class:`EagleFile` :code:`dst`.  If there is some conflict
    between the two (different names for the same layer number or vice versa),
    then raise an exception (unless :code:`force == True`)

    :param src: The :class:`EagleFile` to update.
    :param dst:  The :class:`EagleFile` to draw layers from.
    :param force:  If :code:`True` overwrite the layers.  Otherwise, throw an :class:`SwoopError` on conflict.

    """
    for srcLayer in src.get_layers():
        for dstLayer in dst.get_layers():
            if ((srcLayer.name == dstLayer.name
                 and srcLayer.number != dstLayer.number)
                    or (srcLayer.name != dstLayer.name
                        and srcLayer.number == dstLayer.number)):
                if force:
                    try:
                        src.remove_layer(dstLayer)
                    except:
                        pass
                else:
                    raise Swoop.SwoopError("Layer mismatch: " +
                                           str(src.filename) + " <" +
                                           str(srcLayer.number) + ", '" +
                                           str(srcLayer.name) + "'>; " +
                                           str(dst.filename) + " = <" +
                                           str(dstLayer.number) + ", '" +
                                           str(dstLayer.name) + "'>;")
        if srcLayer.name not in dst.get_layersByName():
            dst.add_layer(srcLayer.clone())
Esempio n. 19
0
 def check_names(self):
     with self.errors.nest(self.brd.get_filename()):
         for p in Swoop.From(self.brd).get_elements().get_name():
             m = re.match("[A-Z][A-Z]?\d+", p)
             if not m and self.sch.get_part(p):
                 self.warn(
                     "The name of part '{}' is too long.  It should be at most two capital letters followed numbers."
                     .format(p))
Esempio n. 20
0
    def check_outline(self):
        with self.errors.nest(self.brd.get_filename()):
            dims = Swoop.From(self.brd).get_plain_elements().with_type(
                Swoop.Wire).with_layer("Dimension")
            self.info("Found {} lines in layer 'Dimension'".format(len(dims)))
            if dims.filtered_by(lambda x: x.get_width() < 0.01).count():
                self.warn(
                    "Lines in 'Dimension' should have width >= 0.01mm.  Otherwise some CAM viewers have trouble displaying them the board outline.",
                    inexcusable=True)

            non_wire = Swoop.From(self.brd).get_plain_elements().without_type(
                Swoop.Hole).without_type(Swoop.Wire).without_type(
                    Swoop.Circle).with_layer("Dimension")
            if len(non_wire):
                self.warn(
                    "You things in your Dimension layer other than lines, arcs, and circles.  You probably don't want that.",
                    inexcusable=True)
Esempio n. 21
0
    def check_pours(self):
        with self.errors.nest(self.brd.get_filename()):

            for p in Swoop.From(self.brd).get_signals().get_polygons():
                if p.get_isolate() not in [0, 0.0, None]:
                    self.warn(
                        "A pour in {} has non-zero 'isolate'.  This is unusual, and probably not what you want."
                        .format(p.get_parent().get_name()))
Esempio n. 22
0
 def check_vias(self):
     with self.errors.nest(self.brd.get_filename()):
         for s in Swoop.From(self.brd.get_signals()):
             for v in s.get_vias():
                 if v.get_drill() > 0.8:
                     self.warn(
                         "The via at ({},{}) on {} is too big ({}mm). You probably don't want vias larger than 0.8mm"
                         .format(v.get_x(), v.get_y(), output_format(s),
                                 v.get_drill()))
Esempio n. 23
0
def updateLibrary(eagleFile, library):
    """
    Add :code:`library` to :code'eagleFile', overwriting it if it's already
    there.  If it's a schematic, it will add the whole library.  For boards, it
    just adds the packages.

    :param eagleFile: A :class:`SchematicFile` or :class:`BoardFile`.
    :param library: The :class:`Library` to add.
    :returns: Nothing

    """
    l = library.get_library().clone()

    if isinstance(eagleFile, Swoop.BoardFile):
        Swoop.From(l).get_library().get_symbols().detach()
        Swoop.From(l).get_library().get_devicesets().detach()

    eagleFile.add_library(l)
Esempio n. 24
0
    def check_parts(self):

        # alignment
        alignment = 25.4 / 10 / 4
        for i in Swoop.From(self.sch).get_sheets().get_instances():

            x1 = i.get_x()
            y1 = i.get_y()
            if not self.is_aligned(x1, alignment) or not self.is_aligned(
                    y1, alignment):
                if self.fix:
                    i.set_x(math.ceil(x1 / alignment) * alignment)
                    i.set_y(math.ceil(y1 / alignment) * alignment)
                else:
                    self.warn("{} not aligned to {}\" grid".format(
                        output_format(i.find_part()), alignment / 25.4),
                              inexcusable=True)

        # check for mismatched values
        for p in Swoop.From(self.sch).get_parts():
            attribute = p.find_technology().get_attribute("VALUE")
            if attribute and attribute.get_value() != p.get_value():
                self.warn(
                    "Part {} has a pre-set value ({}) but you have set a different value ({}).  "
                    "This is probably an error, since the value won't match the part the device's "
                    "attributes describe.".format(p.get_name(),
                                                  attribute.get_value(),
                                                  p.get_value()))

        for p in Swoop.From(self.sch).get_parts():
            # The right solution here is to count the number of pins on the the part.  If there are only 1 or 0 pins, then its not an error if just 1 or 0 pins are connected.
            if Swoop.From(p).find_deviceset().get_gates().find_symbol(
            ).get_pins().count() not in [
                    0, 1
            ]:  # not in checker_options.power_and_ground_names + ["ANTENNA", "FRAME_B_L", "MOUNTING-HOLE"] and "VIA" not in p.get_deviceset():
                if Swoop.From(self.sch).get_sheets().get_nets().get_segments(
                ).get_pinrefs().filtered_by(
                        lambda x: x.get_part() == p.get_name()).count() in [
                            0, 1
                        ]:
                    self.warn("Part {} has 1 or zero nets attached.".format(
                        output_format(p)))
Esempio n. 25
0
def create_empty_schematic_file(template):
    """
    Create an empty :class:`SchematicFile` object with the layers from template.
    """

    sch = Swoop.SchematicFile()
    for l in template.get_layers():
        sch.add_layer(l.clone())
    sch.set_version(template.get_version())

    return sch
Esempio n. 26
0
def create_empty_board_file(template):
    """
    Create an empty :class:`BoardFile` object with the layers from template.
    """

    brd = Swoop.BoardFile()
    for l in template.get_layers():
        brd.add_layer(l.clone())
    brd.set_version(template.get_version())

    return brd
Esempio n. 27
0
def create_empty_library_file(template):
    """
    Create an empty :class:`LibraryFile` object with the layers from template.
    """

    lbr = Swoop.LibraryFile()
    for l in template.get_layers():
        lbr.add_layer(l.clone())
    lbr.set_version(template.get_version())

    return lbr
Esempio n. 28
0
    def test_Detach(self):

        brd = self.brd.clone()

        (Swoop.From(brd).
         get_layers().
         with_name(Swoop.matching("^t")).
         detach())

        self.assertEqual(Swoop.From(brd).
                         get_layers().
                         count(), 56, "Detach Error")
Esempio n. 29
0
    def test_Rekey(self):
        sch = self.sch.clone()
        brd = self.brd.clone()
        s = Swoop.From(sch).get_libraries().get_symbols()[0]
        l = s.get_parent()

        old = s.get_name()
        self.assertEqual(l.get_symbol(old), s, "Rename precondition error")
        s.set_name("foo")
        self.assertEqual(s.get_name(), "foo", "Rename error")
        self.assertEqual(l.get_symbol("foo"), s, "Rename error")
        self.assertEqual(l.get_symbol(old), None, "Rename error")
        l.check_sanity()
Esempio n. 30
0
def facetizeWire(wire):

    if wire.get_curve() == 0:
        return [wire]

    points = getFacetsForWire(wire)
    wires = []
    for i in range(0, len(points) - 1):
        wires.append(Swoop.Wire().set_points(
            points[i].x, points[i].y, points[i + 1].x,
            points[i + 1].y).set_layer(wire.get_layer()).set_width(
                wire.get_width()))
    return wires
Esempio n. 31
0
    def get_geometry(self, layer_query=None, **options):
        brd = Swoop.From(self)

        wires = self._do_polygonize_wires(
            brd.get_plain_elements().with_type(Wire),
            layer_query=layer_query,
            **options)

        parts = (brd.get_elements() +
                 brd.get_plain_elements().without_type(Wire) +
                 brd.get_signals().get_wires() + brd.get_signals().get_vias())

        return shapely.ops.unary_union(
            parts.get_geometry(layer_query=layer_query, **options) + [wires])
Esempio n. 32
0
def schematic_stats(filename, part_limit, conn_limit, dup_limit):
    try:
        sch = Swoop.from_file(filename)[0]
    except:
        return None

    if len(sch.get_parts()) < part_limit:
        return None

    cpd = get_connections_per_device(sch)
    # print cpd

    # Number of times a device with over conn_limit connections was instantiated
    # There will be a count for each (important part)
    duplicate_instantiate_count = []
    for device in cpd.keys():
        # Does the usage of this device have enough connections?
        filter_enough_connections = filter(lambda d: d >= conn_limit, cpd[device])

        # Number of "actual" duplicates with enough connections
        dupes = len(filter_enough_connections)
        if dupes >= dup_limit:
            duplicate_instantiate_count.append((device, dupes))
    return duplicate_instantiate_count
Esempio n. 33
0
    def test_Fluent(self):
        t = Swoop.From(self.sch)
        #print t
        #print t.get_libraries()
        #print t.get_libraries().get_package("CAPC1608X90_HS")
        #print t.get_libraries().get_package("CAPC1608X90_HS").get_drawing_elements(layer="tCream")
        self.assertEqual(t.
                         get_libraries().
                         get_package("CAPC1608X90_HS").
                         get_drawing_elements().
                         with_layer("tCream").
                         count(), 2)#, "Fluent search failure")

        self.assertEqual(t.
                         get_libraries().
                         get_package("CAPC1608X90_HS").
                         get_drawing_elements().
                         with_layer("tCream").
                         with_type(Swoop.Polygon).
                         get_vertices().
                         count(),
                         18, "Fluent container search failure")


        self.assertEqual(len(t.
                             get_libraries().
                             get_package("CAPC1608X90_HS").
                             get_drawing_elements().
                             with_type(Swoop.Polygon).
                             get_vertices().
                             unpack()), 36, "Fluent container search failure")
        self.assertEqual(t.
                         get_libraries().
                         get_package("CAPC1608X90_HS").
                         get_drawing_elements().
                         with_type(Swoop.Polygon).
                         get_vertices().
                         count(), 36, "Fluent container search failure")

        self.assertEqual(t.get_libraries().
                         get_packages().
                         with_name("CAPC1608X90_HS").
                         get_name().
                         lower().
                         unpack()[0], "CAPC1608X90_HS".lower(), "Fluent container search failure")

        self.assertEqual(t.get_libraries().
                         get_packages().
                         with_name("CAPC1608X90_HS").
                         get_name().
                         lower().
                         unpack()[0], "CAPC1608X90_HS".lower(), "Fluent container search failure")

        self.assertEqual(t.
                         get_layers().
                         with_name(lambda x: re.match("^t", x) is not None).
                         count(), 17, "Regex filter failure")

        self.assertEqual(t.get_layers().
                         get_number().
                         reduce(min),
                         1, "From reduction failure")

        self.assertEqual(t.get_layers().
                         get_number().
                         reduce(max), 167, "From reduction failure")

        self.assertEqual(t.get_layers().
                         get_number().
                         map(lambda x: x*2).
                         reduce(max), 334, "From map failure")

        self.assertEqual(t.get_layers().
                         get_number().
                         filtered_by(lambda x: ((x % 2) == 0)).
                         reduce(max), 164, "From filter failure")

        s = 0;
        for i in t.get_layers().get_number():
            s += i

        self.assertEqual(t.get_layers().
                         get_number().
                         reduce(lambda x,y:x + y), s, "iteration failure")

        self.assertEqual(sum(t.get_layers().
                             get_number()), s, "iteration failure")


        self.assertEqual(round(Swoop.From(self.brd).
                               get_signals().
                               get_wires().
                               with_layer("Unrouted").
                               apply(lambda w: math.sqrt(((w.get_x1()-w.get_x2())**2 + (w.get_y1()-w.get_y2())**2))).
                               reduce(lambda x,y:x + y),6), round(1751.08121386,6), "Airwire test error")

        self.assertEqual(Swoop.From(self.brd).
                         get_layers().
                         with_name(Swoop.matching("^t")).
                         count(), 17, "Regex matching failure")

        self.assertEqual(Swoop.From(self.brd).
                         get_layers().
                         with_name(Swoop.not_matching("^t")).
                         count(),56, "Regex not matching failure")