From c9dd62c3970a416d4534042f86a416a05ed90ff6 Mon Sep 17 00:00:00 2001 From: adelhpour Date: Tue, 10 Dec 2024 18:08:20 -0800 Subject: [PATCH 1/3] - test directory is renamed to 'test_with_generic_models' - another test suite called 'test_with_specific_models' is added - tests used by antimony are used in the newly created test suite - CI/CD pipeline is updated to install the dependencies used by the new tests - bugs found by new tests are fixed --- .github/workflows/build.yml | 3 + .../python/ctypes/libsbmlnetwork.py.cmake | 16 +- ...bml_network.py => test_with_all_models.py} | 0 .../tests/test_with_specific_models.py | 559 ++++++++++++++++++ src/libsbmlnetwork_layout.cpp | 1 + 5 files changed, 577 insertions(+), 2 deletions(-) rename src/bindings/python/ctypes/sbmlnetwork/tests/{test_sbml_network.py => test_with_all_models.py} (100%) create mode 100644 src/bindings/python/ctypes/sbmlnetwork/tests/test_with_specific_models.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e6c0766..4683a13 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -241,14 +241,17 @@ jobs: python -m pip install pytest ipython setuptools wheel python -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/libsbmlnetwork python -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/sbmlnetwork + python -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/tellurium elif [ "${{ matrix.platform.os_type }}" == 'manylinux' ]; then python${{ matrix.python_version }} -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org pytest ipython setuptools wheel python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/libsbmlnetwork python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/sbmlnetwork + python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/tellurium else python${{ matrix.python_version }} -m pip install pytest ipython setuptools wheel python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/libsbmlnetwork python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/sbmlnetwork + python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/tellurium fi - name: Run libSBMLNetwork tests diff --git a/src/bindings/python/ctypes/libsbmlnetwork.py.cmake b/src/bindings/python/ctypes/libsbmlnetwork.py.cmake index a8f1fa6..bb20718 100644 --- a/src/bindings/python/ctypes/libsbmlnetwork.py.cmake +++ b/src/bindings/python/ctypes/libsbmlnetwork.py.cmake @@ -1317,7 +1317,7 @@ class LibSBMLNetwork: """ return lib.c_api_getNumSpeciesReferenceAssociatedWithSpecies(self.sbml_object, str(species_id).encode(), str(reaction_id).encode(), reaction_glyph_index) - def getSpeciesReferenceIndexAssociatedWithSpecies(self, species_id, reaction_id, reaction_glyph_index = 0, n = 0): + def getSpeciesReferenceIndexAssociatedWithSpecies(self, species_id, reaction_id, reaction_glyph_index = 0, n = 0, layout_index = 0): """ Returns the index of the SpeciesReference associated with the given species_id in the given SBMLDocument @@ -1327,12 +1327,13 @@ class LibSBMLNetwork: - reaction_id (string): a string that determines the id of the Reaction - reaction_glyph_index (int, optional): an integer (default: 0) that determines the index of the ReactionGlyph in the given SBMLDocument - n (int, optional): an integer (default: 0) that determines the index of the SpeciesReference among the associated SpeciesReferences to the given species_id in the given SBMLDocument + - layout_index (int, optional): an integer (default: 0) that determines the index of the Layout object in the given SBMLDocument :Returns: an integer that determines the index of the SpeciesReference associated with the given species_id in the given SBMLDocument """ - return lib.c_api_getSpeciesReferenceIndexAssociatedWithSpecies(self.sbml_object, str(species_id).encode(), str(reaction_id).encode(), reaction_glyph_index, n) + return lib.c_api_getSpeciesReferenceIndexAssociatedWithSpecies(self.sbml_object, str(species_id).encode(), str(reaction_id).encode(), reaction_glyph_index, n, layout_index) def getNumSpeciesReferenceCurveSegments(self, reaction_id, reaction_glyph_index=0, species_reference_index=0, layout_index=0): """ @@ -7740,6 +7741,17 @@ class LibSBMLNetwork: """ return lib.c_api_setSpeciesBorderColor(self.sbml_object, str(border_color).encode(), layout_index) + def getReactionsLineColor(self, layout_index=0): + """ + Returns the default line color of the ReactionGlyph objects in the given SBMLDocument + + :Returns: + + a string that determines the default line color of the ReactionGlyph objects in the given SBMLDocument + """ + lib.c_api_getReactionsLineColor.restype = ctypes.c_char_p + return ctypes.c_char_p(lib.c_api_getReactionsLineColor(self.sbml_object, layout_index)).value.decode() + def setReactionsLineColor(self, line_color, layout_index=0): """ Sets the line color of all the ReactionGlyph object with the given layout_index in the given SBMLDocument diff --git a/src/bindings/python/ctypes/sbmlnetwork/tests/test_sbml_network.py b/src/bindings/python/ctypes/sbmlnetwork/tests/test_with_all_models.py similarity index 100% rename from src/bindings/python/ctypes/sbmlnetwork/tests/test_sbml_network.py rename to src/bindings/python/ctypes/sbmlnetwork/tests/test_with_all_models.py diff --git a/src/bindings/python/ctypes/sbmlnetwork/tests/test_with_specific_models.py b/src/bindings/python/ctypes/sbmlnetwork/tests/test_with_specific_models.py new file mode 100644 index 0000000..50c0d11 --- /dev/null +++ b/src/bindings/python/ctypes/sbmlnetwork/tests/test_with_specific_models.py @@ -0,0 +1,559 @@ +import unittest +import math + +import tellurium as te +import sbmlnetwork + + +class TestSBMLNetwork(unittest.TestCase): + def test_basic_autolayout(self): + model = te.loada(""" + S1 -> S2; + S2 -> S3; + """) + sbml = model.getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + self.assertNotEqual(network.getX("S1"), math.nan) + self.assertNotEqual(network.getY("S1"), math.nan) + self.assertNotEqual(network.getX("S2"), math.nan) + self.assertNotEqual(network.getY("S2"), math.nan) + self.assertNotEqual(network.getX("S3"), math.nan) + self.assertNotEqual(network.getY("S3"), math.nan) + + def test_basic_positions(self): + model = te.loada(""" + S1 -> S2; + """) + sbml = model.getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setPosition("S1", 52, 80) + network.setX("S2", 86) + network.setY("S2", 73) + self.assertEqual(network.getX("S1"), 52) + self.assertEqual(network.getY("S1"), 80) + self.assertEqual(network.getX("S2"), 86) + self.assertEqual(network.getY("S2"), 73) + + def test_basic_sizes(self): + model = te.loada(""" + S1 -> S2; + """) + sbml = model.getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setWidth("S1", 52) + network.setHeight("S1", 80) + network.setWidth("S2", 86) + network.setHeight("S2", 73) + self.assertEqual(network.getWidth("S1"), 52) + self.assertEqual(network.getHeight("S1"), 80) + self.assertEqual(network.getWidth("S2"), 86) + self.assertEqual(network.getHeight("S2"), 73) + + + def test_max_edges(self): + model = """ + S1 -> S2; + S1 -> S3; + S1 -> S4; + S1 -> S5; + S1 -> S6; + S1 -> S7; + S1 -> S8; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + # default max num connected edges + self.assertEqual(network.getNumSpeciesGlyphs("S1"), 3) + # max num connected edges = 7 + network.autolayout(max_num_connected_edges=7) + self.assertEqual(network.getNumSpeciesGlyphs("S1"), 1) + + def test_use_name_as_text_label(self): + model = """ + S1 -> S2; + S1 is "Species 1"; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + # default use name as text label is False + self.assertEqual(network.getText("S1"), "Species 1") + # set use name as text label to False + network.setUseNameAsTextLabel(False) + self.assertEqual(network.getText("S1"), "S1") + # set use name as text label to True + network.setUseNameAsTextLabel(True) + self.assertEqual(network.getText("S1"), "Species 1") + + def test_set_layout_style(self): + model = """ + S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setStyle("power") + self.assertEqual(network.getStyle(), "power") + self.assertEqual(network.getBackgroundColor(), "white") + self.assertEqual(network.getCompartmentsGeometricShapeType(), "rectangle") + self.assertEqual(network.getCompartmentsBorderColor(), "mandy") + self.assertEqual(network.getCompartmentsBorderWidth(), 3.0) + self.assertEqual(network.getCompartmentsFillColor(), "pewter") + self.assertEqual(network.getCompartmentsFontColor(), "gondola") + self.assertEqual(network.getCompartmentsFontSize(), 10.0) + self.assertEqual(network.getSpeciesGeometricShapeType(), "rectangle") + self.assertEqual(network.getSpeciesFillColor(), "carnation") + self.assertEqual(network.getSpeciesBorderColor(), "gondola") + self.assertEqual(network.getSpeciesBorderWidth(), 3.0) + self.assertEqual(network.getSpeciesFontColor(), "gondola") + self.assertEqual(network.getSpeciesFontSize(), 24.0) + self.assertEqual(network.getReactionsLineColor(), "gondola") + self.assertEqual(network.getReactionsLineWidth(), 3.0) + self.assertEqual(network.getReactionsFontColor(), "gondola") + self.assertEqual(network.getReactionsFontSize(), 12.0) + self.assertEqual(network.getLineEndingsBorderColor(0), "gondola") + self.assertEqual(network.getLineEndingsBorderWidth(), 3.0) + self.assertEqual(network.getLineEndingsFillColor(), "gondola") + + def test_layout_size(self): + model = """ + S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setCanvasWidth(1234.0) + network.setCanvasHeight(1432.0) + self.assertEqual(network.getCanvasWidth(), 1234.0) + self.assertEqual(network.getCanvasHeight(), 1432.0) + + def test_align_top(self): + model = """ + S1 -> S2; + S2 -> S3; + S3 -> S4; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + species_list = ["S1", "S2", "S3"] + min_position_y = self._get_min_position_y(network, species_list) + network.align(species_list, "top") + self.assertAlmostEqual(network.getY("S1"), min_position_y, 1) + self.assertAlmostEqual(network.getY("S2"), min_position_y, 1) + self.assertAlmostEqual(network.getY("S3"), min_position_y, 1) + + def test_align_bottom(self): + model = """ + S1 -> S2; + S2 -> S3; + S3 -> S4; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + species_list = ["S1", "S2", "S3"] + max_position_y = self._get_max_position_y(network, species_list) + network.align(species_list, "bottom") + self.assertAlmostEqual(network.getY("S1"), max_position_y, 1) + self.assertAlmostEqual(network.getY("S2"), max_position_y, 1) + self.assertAlmostEqual(network.getY("S3"), max_position_y, 1) + + def test_align_left(self): + model = """ + S1 -> S2; + S2 -> S3; + S3 -> S4; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + species_list = ["S1", "S2", "S3"] + min_position_x = self._get_min_position_x(network, species_list) + network.align(species_list, "left") + self.assertAlmostEqual(network.getX("S1"), min_position_x, 1) + self.assertAlmostEqual(network.getX("S2"), min_position_x, 1) + self.assertAlmostEqual(network.getX("S3"), min_position_x, 1) + + def test_align_right(self): + model = """ + S1 -> S2; + S2 -> S3; + S3 -> S4; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + species_list = ["S1", "S2", "S3"] + max_position_x = self._get_max_position_x(network, species_list) + network.align(species_list, "right") + self.assertAlmostEqual(network.getX("S1"), max_position_x, 1) + self.assertAlmostEqual(network.getX("S2"), max_position_x, 1) + self.assertAlmostEqual(network.getX("S3"), max_position_x, 1) + + def test_align_vCenter(self): + model = """ + S1 -> S2; + S2 -> S3; + S3 -> S4; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + species_list = ["S1", "S2", "S3"] + min_position_y = self._get_min_position_y(network, species_list) + max_position_y = self._get_max_position_y(network, species_list) + network.align(species_list, "vCenter") + self.assertAlmostEqual(network.getY("S1"), 0.5 * (min_position_y + max_position_y), 1) + self.assertAlmostEqual(network.getY("S2"), 0.5 * (min_position_y + max_position_y), 1) + self.assertAlmostEqual(network.getY("S3"), 0.5 * (min_position_y + max_position_y), 1) + + def test_align_hCenter(self): + model = """ + S1 -> S2; + S2 -> S3; + S3 -> S4; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + species_list = ["S1", "S2", "S3"] + min_position_x = self._get_min_position_x(network, species_list) + max_position_x = self._get_max_position_x(network, species_list) + network.align(species_list, "hCenter") + self.assertAlmostEqual(network.getX("S1"), 0.5 * (min_position_x + max_position_x), 1) + self.assertAlmostEqual(network.getX("S2"), 0.5 * (min_position_x + max_position_x), 1) + self.assertAlmostEqual(network.getX("S3"), 0.5 * (min_position_x + max_position_x), 1) + + def test_whole_model_settings(self): + model = """ + S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setBackgroundColor("orange") + self.assertEqual(network.getBackgroundColor(), "orange") + network.setCompartmentsFillColor("khaki") + self.assertEqual(network.getCompartmentsFillColor(), "khaki") + network.setSpeciesFillColor("khaki") + self.assertEqual(network.getSpeciesFillColor(), "khaki") + network.setReactionsFillColor("khaki") + self.assertEqual(network.getReactionsFillColor(), "khaki") + network.setCompartmentsBorderColor("azure") + self.assertEqual(network.getCompartmentsBorderColor(), "azure") + network.setSpeciesBorderColor("azure") + self.assertEqual(network.getSpeciesBorderColor(), "azure") + network.setReactionsLineColor("azure") + self.assertEqual(network.getReactionsLineColor(), "azure") + network.setCompartmentsFontColor("coral") + self.assertEqual(network.getCompartmentsFontColor(), "coral") + network.setSpeciesFontColor("coral") + self.assertEqual(network.getSpeciesFontColor(), "coral") + network.setReactionsFontColor("coral") + self.assertEqual(network.getReactionsFontColor(), "coral") + network.setCompartmentsBorderWidth(32.0) + self.assertEqual(network.getCompartmentsBorderWidth(), 32.0) + network.setSpeciesBorderWidth(32.0) + self.assertEqual(network.getSpeciesBorderWidth(), 32.0) + network.setReactionsLineWidth(32.0) + self.assertEqual(network.getReactionsLineWidth(), 32.0) + network.setCompartmentsFontFamily("monospace") + self.assertEqual(network.getCompartmentsFontFamily(), "monospace") + network.setSpeciesFontFamily("monospace") + self.assertEqual(network.getSpeciesFontFamily(), "monospace") + network.setReactionsFontFamily("monospace") + self.assertEqual(network.getReactionsFontFamily(), "monospace") + network.setCompartmentsFontSize(4.0) + self.assertEqual(network.getCompartmentsFontSize(), 4.0) + network.setSpeciesFontSize(4.0) + self.assertEqual(network.getSpeciesFontSize(), 4.0) + network.setReactionsFontSize(4.0) + self.assertEqual(network.getReactionsFontSize(), 4.0) + network.setCompartmentsFontStyle("italic") + self.assertEqual(network.getCompartmentsFontStyle(), "italic") + network.setSpeciesFontStyle("italic") + self.assertEqual(network.getSpeciesFontStyle(), "italic") + network.setReactionsFontStyle("italic") + self.assertEqual(network.getReactionsFontStyle(), "italic") + network.setCompartmentsFontWeight("normal") + self.assertEqual(network.getCompartmentsFontWeight(), "normal") + network.setSpeciesFontWeight("normal") + self.assertEqual(network.getSpeciesFontWeight(), "normal") + network.setReactionsFontWeight("normal") + self.assertEqual(network.getReactionsFontWeight(), "normal") + + def test_compartment_settings(self): + model = """ + species S1 in C, S2 in C; + S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setWidth("C", 420.0) + self.assertEqual(network.getWidth("C"), 420.0) + network.setWidth("C", 420.0) + self.assertEqual(network.getWidth("C"), 420.0) + network.setHeight("C", 550.0) + self.assertEqual(network.getHeight("C"), 550.0) + network.setFillColor("C", "khaki") + self.assertEqual(network.getFillColor("C"), "khaki") + network.setBorderColor("C", "azure") + self.assertEqual(network.getBorderColor("C"), "azure") + network.setFontColor("C", "coral") + self.assertEqual(network.getFontColor("C"), "coral") + network.setBorderWidth("C", 32.0) + self.assertEqual(network.getBorderWidth("C"), 32.0) + network.setFontFamily("C", "monospace") + self.assertEqual(network.getFontFamily("C"), "monospace") + network.setFontSize("C", 4.0) + self.assertEqual(network.getFontSize("C"), 4.0) + network.setFontStyle("C", "italic") + self.assertEqual(network.getFontStyle("C"), "italic") + network.setFontWeight("C", "normal") + self.assertEqual(network.getFontWeight("C"), "normal") + + def test_species_settings(self): + model = """ + S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setWidth("S1", 42.0) + self.assertEqual(network.getWidth("S1"), 42.0) + network.setHeight("S1", 55.0) + self.assertEqual(network.getHeight("S1"), 55.0) + network.setWidth("S2", 42.0) + self.assertEqual(network.getWidth("S2"), 42.0) + network.setHeight("S2", 55.0) + self.assertEqual(network.getHeight("S2"), 55.0) + network.setFillColor("S1", "khaki") + self.assertEqual(network.getFillColor("S1"), "khaki") + network.setBorderColor("S1", "azure") + self.assertEqual(network.getBorderColor("S1"), "azure") + network.setFontColor("S1", "coral") + self.assertEqual(network.getFontColor("S1"), "coral") + network.setBorderWidth("S1", 32.0) + self.assertEqual(network.getBorderWidth("S1"), 32.0) + network.setFontFamily("S1", "monospace") + self.assertEqual(network.getFontFamily("S1"), "monospace") + network.setFontSize("S1", 4.0) + self.assertEqual(network.getFontSize("S1"), 4.0) + network.setFontStyle("S1", "italic") + self.assertEqual(network.getFontStyle("S1"), "italic") + network.setFontWeight("S1", "normal") + self.assertEqual(network.getFontWeight("S1"), "normal") + + def test_reaction_settings(self): + model = """ + J0: S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setWidth("J0", 420.0) + self.assertEqual(network.getWidth("J0"), 420.0) + network.setHeight("J0", 550.0) + self.assertEqual(network.getHeight("J0"), 550.0) + network.setFillColor("J0", "khaki") + self.assertEqual(network.getFillColor("J0"), "khaki") + network.setLineColor("J0", "azure") + self.assertEqual(network.getLineColor("J0"), "azure") + network.setFontColor("J0", "coral") + self.assertEqual(network.getFontColor("J0"), "coral") + network.setLineWidth("J0", 32.0) + self.assertEqual(network.getLineWidth("J0"), 32.0) + network.setFontFamily("J0", "monospace") + self.assertEqual(network.getFontFamily("J0"), "monospace") + network.setFontSize("J0", 4.0) + self.assertEqual(network.getFontSize("J0"), 4.0) + network.setFontStyle("J0", "italic") + self.assertEqual(network.getFontStyle("J0"), "italic") + network.setFontWeight("J0", "normal") + self.assertEqual(network.getFontWeight("J0"), "normal") + + def test_locations_pos(self): + model = """ + J0: S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setPosition("S1", 120.0, 250.0) + self.assertEqual(network.getPosition("S1"), (120.0, 250.0)) + network.setPosition("S2", 420.0, 550.0) + self.assertEqual(network.getPosition("S2"), (420.0, 550.0)) + network.setPosition("J0", 270.0, 400.0) + self.assertEqual(network.getX("J0"), 270.0) + self.assertEqual(network.getY("J0"), 400.0) + + def test_locations_xy(self): + model = """ + J0: S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setX("S1", 120.0) + self.assertEqual(network.getX("S1"), 120.0) + network.setY("S1", 250.0) + self.assertEqual(network.getY("S1"), 250.0) + network.setX("S2", 420.0) + self.assertEqual(network.getX("S2"), 420.0) + network.setY("S2", 550.0) + self.assertEqual(network.getY("S2"), 550.0) + network.setX("J0", 270.0) + self.assertEqual(network.getX("J0"), 270.0) + network.setY("J0", 400.0) + self.assertEqual(network.getY("J0"), 400.0) + + def test_control_points(self): + model = """ + J0: S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setPosition("S1", 560.0, 0.0) + network.setPosition("S2", 30.0, 37.5) + network.setPosition("J0", 318.13, 29.25) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S1", reaction_id="J0") + network.setSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index, x=318.13) + network.setSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index, y=29.25) + network.setSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index, x=364.9) + network.setSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index, y=33.93) + network.setSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index, x=350.0) + network.setSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index, y=35.0) + network.setSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index, x=550.02) + network.setSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index, y=20.83) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S2", reaction_id="J0") + network.setSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index, x=318.13) + network.setSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index, y=29.25) + network.setSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index, x=285.1) + network.setSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index, y=39.57) + network.setSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index, x=290.0) + network.setSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index, y=40.0) + network.setSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index, x=99.98) + network.setSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index, y=52.67) + self.assertEqual(network.getY("S1"), 0.0) + self.assertEqual(network.getX("S2"), 30.0) + self.assertEqual(network.getY("S2"), 37.5) + self.assertEqual(network.getX("J0"), 318.13) + self.assertEqual(network.getY("J0"), 29.25) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S1", reaction_id="J0") + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index), 318.13) + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index), 29.25) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index), 364.9) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index), 33.93) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index), 350) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index), 35) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index), 550.02) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index), 20.83) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S2", reaction_id="J0") + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index), 318.13) + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index), 29.25) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index), 285.1) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index), 39.57) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index), 290) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index), 40) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index), 99.98) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index), 52.67) + + def test_control_points_double_arcs(self): + model = """ + J0: 2 S1 -> S2; + """ + sbml = te.loada(model).getSBML() + network = sbmlnetwork.SBMLNetwork(sbml) + network.setPosition("S1", 560.0, 0.0) + network.setPosition("S2", 30.0, 37.5) + network.setPosition("J0", 318.13, 29.25) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S1", reaction_id="J0", n = 0) + network.setSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index, x=318.13) + network.setSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index, y=29.25) + network.setSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index, x=364.9) + network.setSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index, y=33.93) + network.setSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index, x=350.0) + network.setSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index, y=35.0) + network.setSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index, x=550.02) + network.setSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index, y=20.83) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S1", reaction_id="J0", n = 1) + network.setSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index, x=318.13) + network.setSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index, y=29.25) + network.setSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index, x=342.95) + network.setSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index, y=26.25) + network.setSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index, x=490.02) + network.setSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index, y=18.95) + network.setSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index, x=550.01) + network.setSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index, y=18.38) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S2", reaction_id="J0", n = 0) + network.setSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index, x=318.13) + network.setSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index, y=29.25) + network.setSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index, x=285.1) + network.setSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index, y=39.57) + network.setSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index, x=290.0) + network.setSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index, y=40.0) + network.setSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index, x=99.98) + network.setSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index, y=52.67) + self.assertEqual(network.getY("S1"), 0.0) + self.assertEqual(network.getX("S2"), 30.0) + self.assertEqual(network.getY("S2"), 37.5) + self.assertEqual(network.getX("J0"), 318.13) + self.assertEqual(network.getY("J0"), 29.25) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S1", reaction_id="J0", n = 0) + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index), 318.13) + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index), 29.25) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index), 364.9) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index), 33.93) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index), 350) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index), 35) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index), 550.02) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index), 20.83) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S1", reaction_id="J0", n = 1) + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index), 318.13) + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index), 29.25) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index), 342.95) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index), 26.25) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index), 490.02) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index), 18.95) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index), 550.01) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index), 18.38) + species_reference_index = network.getSpeciesReferenceIndexAssociatedWithSpecies(species_id="S2", reaction_id="J0", n = 0) + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointX("J0", species_reference_index=species_reference_index), 318.13) + self.assertEqual(network.getSpeciesReferenceCurveSegmentStartPointY("J0", species_reference_index=species_reference_index), 29.25) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1X("J0", species_reference_index=species_reference_index), 285.1) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint1Y("J0", species_reference_index=species_reference_index), 39.57) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2X("J0", species_reference_index=species_reference_index), 290) + self.assertEqual(network.getSpeciesReferenceCurveSegmentBasePoint2Y("J0", species_reference_index=species_reference_index), 40) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointX("J0", species_reference_index=species_reference_index), 99.98) + self.assertEqual(network.getSpeciesReferenceCurveSegmentEndPointY("J0", species_reference_index=species_reference_index), 52.67) + + @staticmethod + def _get_max_position_y(network, species_list): + max_position_y = -math.inf + for species in species_list: + y = network.getY(species) + if y > max_position_y: + max_position_y = y + + return max_position_y + + @staticmethod + def _get_min_position_y(network, species_list): + min_position_y = math.inf + for species in species_list: + y = network.getY(species) + if y < min_position_y: + min_position_y = y + + return min_position_y + + @staticmethod + def _get_max_position_x(network, species_list): + max_position_x = -math.inf + for species in species_list: + x = network.getX(species) + if x > max_position_x: + max_position_x = x + + return max_position_x + + @staticmethod + def _get_min_position_x(network, species_list): + min_position_x = math.inf + for species in species_list: + x = network.getX(species) + if x < min_position_x: + min_position_x = x + + return min_position_x + + +if __name__ == '__main__': + unittest.main() diff --git a/src/libsbmlnetwork_layout.cpp b/src/libsbmlnetwork_layout.cpp index 55af22c..4ea3956 100755 --- a/src/libsbmlnetwork_layout.cpp +++ b/src/libsbmlnetwork_layout.cpp @@ -958,6 +958,7 @@ int setPosition(Layout* layout, GraphicalObject* graphicalObject, const double& double moveDistanceY = y - getPositionY(graphicalObject); if ((isSetCurve(graphicalObject) && !setPosition(getCurve(graphicalObject), x, y)) || !setPosition(getBoundingBox(graphicalObject), x, y)) { updateAssociatedTextGlyphsPosition(layout, graphicalObject, moveDistanceX, moveDistanceY); + fix_elements_fixGraphicalObjectPosition(graphicalObject); return 0; } From 3d4e134cb6b5e6c9f713a1968e5cc4e4c07a53c8 Mon Sep 17 00:00:00 2001 From: adelhpour Date: Tue, 10 Dec 2024 18:11:57 -0800 Subject: [PATCH 2/3] - fix the issue with CI/CD to install test dependency --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4683a13..15e726d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -241,17 +241,17 @@ jobs: python -m pip install pytest ipython setuptools wheel python -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/libsbmlnetwork python -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/sbmlnetwork - python -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/tellurium + python -m pip install tellurium elif [ "${{ matrix.platform.os_type }}" == 'manylinux' ]; then python${{ matrix.python_version }} -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org pytest ipython setuptools wheel python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/libsbmlnetwork python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/sbmlnetwork - python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/tellurium + python${{ matrix.python_version }} -m pip install tellurium else python${{ matrix.python_version }} -m pip install pytest ipython setuptools wheel python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/libsbmlnetwork python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/sbmlnetwork - python${{ matrix.python_version }} -m pip install ${RUNNER_WORKSPACE}/install-libsbmlnetwork/lib/python/site-packages/tellurium + python${{ matrix.python_version }} -m pip install tellurium fi - name: Run libSBMLNetwork tests From 3bcb2fbb9318a664ef2186ac0157306b9f022fe4 Mon Sep 17 00:00:00 2001 From: adelhpour Date: Tue, 10 Dec 2024 18:30:40 -0800 Subject: [PATCH 3/3] add missing function declarations in the c api --- src/c_api/libsbmlnetwork_c_api.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/c_api/libsbmlnetwork_c_api.h b/src/c_api/libsbmlnetwork_c_api.h index 1fe2b87..7667064 100644 --- a/src/c_api/libsbmlnetwork_c_api.h +++ b/src/c_api/libsbmlnetwork_c_api.h @@ -5297,6 +5297,23 @@ namespace LIBSBMLNETWORK_CPP_NAMESPACE { /// @return integer value indicating success/failure of the function. LIBSBMLNETWORK_EXTERN int c_api_setGeometricShapesId(SBMLDocument* document, const char* id, const char* geometricShapeId, int geometricShapeIndex = 0, int graphicalObjectIndex = 0, int layoutIndex = 0); + /// @brief Returns the type of the geometric shape of the RenderGroup of the Style of all CompartmentGlyph objects in this Layout object. + /// @param document a pointer to the SBMLDocument object. + /// @return the type of the geometric shape of the RenderGroup of the Style for all CompartmentGlyph objects, or @c "" if the object is @c NULL + LIBSBMLNETWORK_EXTERN const char* c_api_getCompartmentsGeometricShapeType(SBMLDocument* document); + + /// @brief Sets the geometric shape as the single geometric shape of the RenderGroup of the Style of all CompartmentGlyph objects in this Layout object. + /// @param document a pointer to the SBMLDocument object. + /// @param shape a string value indicating the shape of the geometric shape to be set. + /// @param layoutIndex the index number of the Layout to return. + /// @return integer value indicating success/failure of the function. + LIBSBMLNETWORK_EXTERN int c_api_setCompartmentsGeometricShapeType(SBMLDocument* document, const char* shape, int layoutIndex = 0); + + /// @brief Returns the type of the geometric shape of the RenderGroup of the Style of all SpeciesGlyph objects in this Layout object. + /// @param document a pointer to the SBMLDocument object. + /// @return the type of the geometric shape of the RenderGroup of the Style for all SpeciesGlyph objects, or @c "" if the object is @c NULL + LIBSBMLNETWORK_EXTERN const char* c_api_getSpeciesGeometricShapeType(SBMLDocument* document); + /// @brief Sets the geometric shape as the single geometric shape of the RenderGroup of the Style of all SpeciesGlyph objects in this Layout object. /// @param document a pointer to the SBMLDocument object. /// @param shape a string value indicating the shape of the geometric shape to be set. @@ -5304,6 +5321,11 @@ namespace LIBSBMLNETWORK_CPP_NAMESPACE { /// @return integer value indicating success/failure of the function. LIBSBMLNETWORK_EXTERN int c_api_setSpeciesGeometricShapeType(SBMLDocument* document, const char* shape, int layoutIndex = 0); + /// @brief Returns the type of the geometric shape of the RenderGroup of the Style of all ReactionGlyph objects in this Layout object. + /// @param document a pointer to the SBMLDocument object. + /// @return the type of the geometric shape of the RenderGroup of the Style for all ReactionGlyph objects, or @c "" if the object is @c NULL + LIBSBMLNETWORK_EXTERN const char* c_api_getReactionsGeometricShapeType(SBMLDocument* document); + /// @brief Sets the geometric shape as the single geometric shape of the RenderGroup of the Style of all ReactionGlyph objects in this Layout object. /// @param document a pointer to the SBMLDocument object. /// @param shape a string value indicating the shape of the geometric shape to be set.