def test_create_components():
    va = make_vis_area()
    va.visualizer.terminal_graph = top.terminal_graph(make_plumbing_engine())
    va.visualizer.layout_pos = {
        'A': [0, 0],
        f'{COMPONENT_NAME}.A': [1, 1],
        'B': [3, 2],
        f'{COMPONENT_NAME}.B': [2, 1]
    }
    va.visualizer.create_graphics()

    component_nodeA = GraphicsNode((1, 1), 5, 'injector_valve.A',
                                   NodeType.COMPONENT_NODE)
    component_nodeB = GraphicsNode((2, 1), 5, 'injector_valve.B',
                                   NodeType.COMPONENT_NODE)

    expected_nodes = {
        'A': GraphicsNode((0, 0), 5, 'A'),
        'B': GraphicsNode((3, 2), 5, 'B'),
        'injector_valve.A': component_nodeA,
        'injector_valve.B': component_nodeB
    }
    expected_components = {
        COMPONENT_NAME:
        GraphicsComponent(COMPONENT_NAME, [component_nodeA, component_nodeB])
    }

    assert va.visualizer.graphics_nodes == expected_nodes
    assert va.visualizer.graphics_components == expected_components
def test_vis_area_component_paint():
    va = make_vis_area()
    va.visualizer.terminal_graph = top.terminal_graph(make_plumbing_engine())
    va.visualizer.layout_pos = {
        'A': [0, 0],
        f'{COMPONENT_NAME}.A': [1, 1],
        'B': [3, 2],
        f'{COMPONENT_NAME}.B': [2, 1]
    }
    va.visualizer.create_graphics()

    painter = MockPainter()
    r = 5

    va.visualizer.paint_component(painter, COMPONENT_NAME, name=False)
    expected_ellipses = [(1, 1, r, r), (2, 1, r, r)]
    assert expected_ellipses == painter.ellipses
    painter.clear()

    va.visualizer.paint_component(painter, COMPONENT_NAME, state=True)
    centroid = va.visualizer.graphics_components[COMPONENT_NAME].centroid()
    offset = va.visualizer.graphics_components[COMPONENT_NAME].offset
    state = 'closed'
    expected_text = [(centroid[0] + offset, centroid[1] + offset,
                      COMPONENT_NAME),
                     (centroid[0] + offset, centroid[1] + 3 * offset, state)]
    assert expected_text == expected_text
Esempio n. 3
0
def test_terminal_graph_parallel_components():
    p = parallel_component_engine()
    t = top.terminal_graph(p)

    expected_t = nx.Graph([(1, 'c1.1'), ('c1.1', 'c1.2'), ('c1.2', 2),
                           (1, 'c2.1'), ('c2.1', 'c2.2'), ('c2.2', 2)])
    assert nx.is_isomorphic(t, expected_t)
def make_vis_area():
    va = QMLVisualizationArea()

    va.setWidth(30)
    va.setHeight(20)

    plumb = make_plumbing_engine()

    # Assign these directly because we want to use a hardcoded layout,
    # not the automatic layout that uploadEngineInstance would trigger.
    va.visualizer.engine_instance = plumb
    va.visualizer.terminal_graph = top.terminal_graph(plumb)
    va.visualizer.components = top.component_nodes(plumb)
    va.visualizer.layout_pos = {
        'A': [0, 0],
        f'{COMPONENT_NAME}.A': [1, 1],
        'B': [3, 2],
        f'{COMPONENT_NAME}.B': [2, 1]
    }

    return va
    def uploadEngineInstance(self, engine):
        """
        Set the local engine to the input variable and initialize associated local objects.

        Setter and initializer for uploading an engine to be displayed. After an engine is set,
        the according layout and terminal graph is generated from the engine data.

        Parameters
        ----------

        engine: topside.plumbing_engine
            An instance of the topside engine to be displayed.
        """
        if self.DEBUG_MODE:
            print('New plumbing engine instance received')
        self.engine_instance = engine
        self.terminal_graph = top.terminal_graph(self.engine_instance)
        self.components = top.component_nodes(self.engine_instance)
        self.layout_pos = top.layout_plumbing_engine(self.engine_instance)
        self.create_graphics()
        self.setRescaleNeeded()
        self.parent().update()
def test_vis_area_scale_and_center():
    va = QMLVisualizationArea()

    va.setWidth(30)
    va.setHeight(20)

    va.visualizer.terminal_graph = top.terminal_graph(make_plumbing_engine())
    va.visualizer.layout_pos = {
        'A': [0, 0],
        f'{COMPONENT_NAME}.A': [1, 1],
        'B': [3, 2],
        f'{COMPONENT_NAME}.B': [2, 1]
    }

    va.visualizer.scale_and_center()

    # 80% box of the 30x20 rectangle gives [xmin, xmax] = [3, 27] and
    # [ymin, ymax] = [2, 18].
    assert va.visualizer.layout_pos == {
        'A': [3, 2],
        f'{COMPONENT_NAME}.A': [11, 10],
        'B': [27, 18],
        f'{COMPONENT_NAME}.B': [19, 10]
    }
Esempio n. 7
0
def layout_plumbing_engine(plumbing_engine):
    """
    Given a plumbing engine, determine the best placement of components.

    Parameters
    ----------

    plumbing_engine: topside.PlumbingEngine

    Returns
    -------

    pos: dict
        dict with keys corresponding to the nodes in the terminal graph
        of plumbing_engine and values corresponding to the x-y point
        that the node should be placed at.
    """
    t = top.terminal_graph(plumbing_engine)
    components = list(top.component_nodes(plumbing_engine).values())

    node_indices = {n: i for i, n in enumerate(t.nodes)}

    neighbors = {n: [] for n in t.nodes}
    for cnodes in components:
        for n in cnodes:
            neighbors[n] = [v for v in t.neighbors(n) if v in cnodes]

    initial_pos = make_initial_pos(t.order())

    stage_1_settings = OptimizerSettings(horizontal_weight=0.1)
    stage_1_cost_terms = make_cost_terms(t, node_indices, neighbors,
                                         stage_1_settings)
    stage_1_args = (stage_1_cost_terms)

    # TODO(jacob): Investigate if BFGS is really the best option.
    # Consider implementing the Hessian of the cost function in order
    # to try other methods (trust-exact, trust-krylov, etc.).
    initial_positioning_res = minimize(cost_fn,
                                       initial_pos,
                                       jac=True,
                                       method='BFGS',
                                       args=stage_1_args,
                                       options={'maxiter': 400})
    if not initial_positioning_res.success:
        warn('Initial positioning optimization stage was unsuccessful!')

    constraints = make_constraints(components, node_indices)

    stage_2_settings = OptimizerSettings()
    stage_2_cost_terms = make_cost_terms(t, node_indices, neighbors,
                                         stage_2_settings)
    stage_2_args = (stage_2_cost_terms)

    fine_tuning_res = minimize(cost_fn,
                               initial_positioning_res.x,
                               jac=True,
                               method='SLSQP',
                               constraints=constraints,
                               args=stage_2_args,
                               options={'maxiter': 200})
    if not fine_tuning_res.success:
        warn('Fine-tuning optimization stage was unsuccessful!')

    pos = top.vector_to_pos_dict(fine_tuning_res.x, node_indices)

    return pos
Esempio n. 8
0
def layout_and_plot_plumbing_engine(engine):
    t = top.terminal_graph(engine)
    pos = top.layout_plumbing_engine(engine)

    return plot_graph(t, pos)