def test_membrane(self):
     m = sme.open_example_model()
     self.assertEqual(len(m.membranes), 2)
     self.assertRaises(sme.InvalidArgument, lambda: m.membranes["X"])
     mem = m.membranes["Outside <-> Cell"]
     self.assertEqual(mem, m.membranes[0])
     self.assertEqual(m.membranes[-1], m.membranes[1])
     self.assertEqual(repr(mem), "<sme.Membrane named 'Outside <-> Cell'>")
     self.assertEqual(
         str(mem)[0:43], "<sme.Membrane>\n  - name: 'Outside <-> Cell'")
     self.assertEqual(mem.name, "Outside <-> Cell")
     mem.name = "new name"
     self.assertEqual(mem.name, "new name")
     self.assertEqual(len(mem.reactions), 2)
     self.assertRaises(sme.InvalidArgument, lambda: mem.reactions["X"])
     r = mem.reactions["A uptake from outside"]
     self.assertEqual(r.name, "A uptake from outside")
     # export model, open again, check membrane is preserved
     m.export_sbml_file("tmp.xml")
     m2 = sme.open_sbml_file("tmp.xml")
     self.assertEqual(len(m2.membranes), 2)
     mem2 = m2.membranes["new name"]
     self.assertEqual(mem2.name, mem.name)
     self.assertEqual(len(mem2.reactions), 2)
     r2 = mem2.reactions["A uptake from outside"]
     self.assertEqual(r2.name, r.name)
    def test_reaction(self):

        # get an existing reaction
        m = sme.open_example_model()
        c = m.compartments["Nucleus"]
        r = c.reactions["A to B conversion"]

        # verify name and properties
        self.assertEqual(repr(r), "<sme.Reaction named 'A to B conversion'>")
        self.assertEqual(
            str(r)[0:44], "<sme.Reaction>\n  - name: 'A to B conversion'")
        self.assertEqual(r.name, "A to B conversion")
        self.assertEqual(len(r.parameters), 1)
        self.assertEqual(r.parameters[0].name, "k1")
        self.assertEqual(r.parameters[0].value, 0.3)

        # assign new values
        r.name = "New reac"
        r.parameters[0].name = "kk"
        r.parameters[0].value = 0.99
        self.assertEqual(repr(r), "<sme.Reaction named 'New reac'>")
        self.assertEqual(str(r)[0:35], "<sme.Reaction>\n  - name: 'New reac'")
        self.assertEqual(r.name, "New reac")

        # check change was propagated to model
        self.assertRaises(
            sme.InvalidArgument,
            lambda: c.reactions["A to B conversion"],
        )
        r2 = c.reactions["New reac"]
        self.assertEqual(r2.name, "New reac")
        self.assertEqual(len(r2.parameters), 1)
        self.assertEqual(r2.parameters[0].name, "kk")
        self.assertEqual(r2.parameters[0].value, 0.99)
    def test_parameter(self):

        # get an existing parameter
        m = sme.open_example_model()
        p = m.parameters["param"]

        # verify name and properties
        self.assertEqual(repr(p), "<sme.Parameter named 'param'>")
        self.assertEqual(str(p)[0:33], "<sme.Parameter>\n  - name: 'param'")
        self.assertEqual(p.name, "param")
        self.assertEqual(p.value, "1")

        # assign new values
        p.name = "New param"
        p.value = "0.8765"
        self.assertEqual(repr(p), "<sme.Parameter named 'New param'>")
        self.assertEqual(
            str(p)[0:37], "<sme.Parameter>\n  - name: 'New param'")
        self.assertEqual(p.name, "New param")
        self.assertEqual(p.value, "0.8765")

        # check change was propagated to model
        self.assertRaises(
            sme.InvalidArgument,
            lambda: m.parameters["param"],
        )
        p2 = m.parameters["New param"]
        self.assertEqual(p2.name, "New param")
        self.assertEqual(p2.value, "0.8765")
        self.assertEqual(p2, p)
        self.assertEqual(p2, m.parameters[0])
        self.assertEqual(p2, m.parameters[-1])
 def test_compartment_image(self):
     m = sme.open_example_model()
     img = m.compartment_image
     self.assertEqual(len(img), 100)
     self.assertEqual(len(img[0]), 100)
     self.assertEqual(len(img[0][0]), 3)
     self.assertEqual(img[0][0].tolist(), [0, 2, 0])  # outside
     self.assertEqual(img[30][30].tolist(), [144, 97, 193])  # Cell
     self.assertEqual(img[50][50].tolist(), [197, 133, 96])  # Nucleus
 def test_export_sme_file(self):
     m = sme.open_example_model()
     m.name = "Mod"
     m.compartments["Cell"].name = "C"
     m.export_sme_file("tmp.sme")
     m2 = sme.open_file("tmp.sme")
     self.assertEqual(m2.name, "Mod")
     self.assertEqual(len(m2.membranes), 2)
     self.assertEqual(len(m2.compartments), 3)
     self.assertEqual(m2.compartments["C"].name, "C")
     self.assertEqual(m2.compartments["Nucleus"].name, "Nucleus")
     self.assertRaises(sme.InvalidArgument, lambda: m2.compartments["Cell"])
    def test_open_example_model(self):
        m = sme.open_example_model()
        self.assertEqual(repr(m), "<sme.Model named 'Very Simple Model'>")
        self.assertEqual(
            str(m),
            "<sme.Model>\n  - name: 'Very Simple Model'\n  - compartments:\n     - Outside\n     - Cell\n     - Nucleus\n  - membranes:\n     - Outside <-> Cell\n     - Cell <-> Nucleus",
        )
        self.assertEqual(m.name, "Very Simple Model")
        self.assertEqual(len(m.compartments), 3)
        self.assertEqual(len(m.membranes), 2)
        m.name = "Model !"
        self.assertEqual(m.name, "Model !")

        self.assertRaises(sme.InvalidArgument,
                          lambda: sme.open_example_model("idontexist"))
        self.assertRaises(sme.InvalidArgument,
                          lambda: sme.open_example_model(""))
        self.assertRaises(TypeError, lambda: sme.open_example_model([1, 2, 3]))

        m = sme.open_example_model("brusselator-model")
        self.assertEqual(repr(m), "<sme.Model named 'The Brusselator'>")
        self.assertEqual(len(m.compartments), 1)
        self.assertEqual(len(m.membranes), 0)

        m = sme.open_example_model("gray-scott")
        self.assertEqual(repr(m), "<sme.Model named 'Gray-Scott Model'>")
        self.assertEqual(len(m.compartments), 1)
        self.assertEqual(len(m.membranes), 0)
 def test_import_geometry_from_image(self):
     imgfile_original = _get_abs_path("concave-cell-nucleus-100x100.png")
     imgfile_modified = _get_abs_path(
         "modified-concave-cell-nucleus-100x100.png")
     m = sme.open_example_model()
     comp_img_0 = m.compartment_image
     nucl_mask_0 = m.compartments["Nucleus"].geometry_mask
     m.import_geometry_from_image(imgfile_modified)
     comp_img_1 = m.compartment_image
     nucl_mask_1 = m.compartments["Nucleus"].geometry_mask
     self.assertFalse(np.array_equal(nucl_mask_0, nucl_mask_1))
     self.assertFalse(np.array_equal(comp_img_0, comp_img_1))
     m.import_geometry_from_image(imgfile_original)
     comp_img_2 = m.compartment_image
     nucl_mask_2 = m.compartments["Nucleus"].geometry_mask
     self.assertTrue(np.array_equal(comp_img_0, comp_img_2))
     self.assertTrue(np.array_equal(nucl_mask_0, nucl_mask_2))
 def test_compartment(self):
     m = sme.open_example_model()
     c = m.compartments["Cell"]
     self.assertEqual(repr(c), "<sme.Compartment named 'Cell'>")
     self.assertEqual(str(c)[0:34], "<sme.Compartment>\n  - name: 'Cell'")
     self.assertEqual(c.name, "Cell")
     self.assertEqual(len(c.species), 2)
     c.name = "NewCell"
     self.assertEqual(c.name, "NewCell")
     self.assertEqual(m.compartments["NewCell"].name, "NewCell")
     self.assertRaises(sme.InvalidArgument, lambda: m.compartments["Cell"])
     img = c.geometry_mask
     self.assertEqual(len(img), 100)
     self.assertEqual(len(img[0]), 100)
     self.assertEqual(img[0][0], False)
     self.assertEqual(img[30][30], True)
     self.assertEqual(img[50][50], False)
    def test_parameter_list(self):

        # get an existing reaction parameter list
        m = sme.open_example_model()
        ps = m.compartments["Nucleus"].reactions[
            "A to B conversion"].parameters

        # verify indexing / name-lookup
        self.assertEqual(len(ps), 1)
        self.assertRaises(sme.InvalidArgument, lambda: ps["k2"])
        self.assertRaises(sme.InvalidArgument, lambda: ps[1])
        self.assertRaises(sme.InvalidArgument, lambda: ps[-2])
        k = ps["k1"]
        self.assertEqual(k, ps[0])
        self.assertEqual(k, ps[-1])
        for p in ps:
            self.assertEqual(p, k)
Example #10
0
    def test_reactionparameter(self):

        # get an existing reaction parameter
        m = sme.open_example_model()
        r = m.compartments["Nucleus"].reactions["A to B conversion"]
        k = r.parameters["k1"]

        # verify name and properties
        self.assertEqual(repr(k), "<sme.ReactionParameter named 'k1'>")
        self.assertEqual(
            str(k)[0:38], "<sme.ReactionParameter>\n  - name: 'k1'")
        self.assertEqual(k.name, "k1")
        self.assertEqual(k.value, 0.3)

        # check getting it again doesn't make a copy
        k2 = r.parameters["k1"]
        self.assertEqual(k, k2)
        self.assertEqual(id(k), id(k2))

        # assign new values
        k.name = "New k"
        k.value = 0.8765
        self.assertEqual(repr(k), "<sme.ReactionParameter named 'New k'>")
        self.assertEqual(
            str(k)[0:41], "<sme.ReactionParameter>\n  - name: 'New k'")
        self.assertEqual(k.name, "New k")
        self.assertEqual(k.value, 0.8765)

        # check change was propagated to model
        self.assertRaises(
            sme.InvalidArgument,
            lambda: r.parameters["k1"],
        )
        k3 = r.parameters["New k"]
        self.assertEqual(k, k2)
        self.assertEqual(k, k3)
    def test_simulate(self):
        for sim_type in [sme.SimulatorType.DUNE, sme.SimulatorType.Pixel]:
            m = sme.open_example_model()
            sim_results = m.simulate(0.002, 0.001, simulator_type=sim_type)
            self.assertEqual(len(sim_results), 3)

            sim_results2 = m.simulation_results()
            self.assertEqual(len(sim_results), len(sim_results2))

            # continue previous sim
            sim_results = m.simulate(0.002,
                                     0.001,
                                     simulator_type=sim_type,
                                     continue_existing_simulation=True)
            self.assertEqual(len(sim_results), 5)

            sim_results2 = m.simulation_results()
            self.assertEqual(len(sim_results), len(sim_results2))

            # use string overload
            sim_results = m.simulate(
                "0.002;0.001",
                "0.001;0.001",
                simulator_type=sim_type,
                continue_existing_simulation=True,
            )
            self.assertEqual(len(sim_results), 8)

            sim_results2 = m.simulation_results()
            self.assertEqual(len(sim_results), len(sim_results2))

            # previous sim results are cleared by default
            sim_results = m.simulate(0.002,
                                     0.001,
                                     simulator_type=sim_type,
                                     n_threads=2)
            self.assertEqual(len(sim_results), 3)

            sim_results2 = m.simulation_results()
            self.assertEqual(len(sim_results), len(sim_results2))

            for res in [sim_results[1], sim_results2[1]]:
                self.assertEqual(
                    repr(res), "<sme.SimulationResult from timepoint 0.001>")
                self.assertEqual(
                    str(res),
                    "<sme.SimulationResult>\n  - timepoint: 0.001\n  - number of species: 5\n",
                )
                self.assertEqual(res.time_point, 0.001)
                img = res.concentration_image
                self.assertEqual(len(img), 100)
                self.assertEqual(len(img[0]), 100)
                self.assertEqual(len(img[0][0]), 3)
                self.assertEqual(len(res.species_concentration), 5)
                conc = res.species_concentration["B_cell"]
                self.assertEqual(len(conc), 100)
                self.assertEqual(len(conc[0]), 100)
                self.assertEqual(conc[0][0], 0.0)

            # set timeout to 1 second: by default simulation throws on timeout
            # multiple timesteps before timeout:
            with self.assertRaises(sme.RuntimeError):
                m.simulate(10000,
                           0.1,
                           timeout_seconds=0,
                           simulator_type=sim_type)

        # approximate dcdt (only returned from simulate & pixel & last timepoint)
        m = sme.open_example_model()
        sim_results = m.simulate(0.002,
                                 0.001,
                                 simulator_type=sme.SimulatorType.Pixel)
        self.assertEqual(len(sim_results), 3)
        self.assertEqual(len(sim_results[0].species_dcdt), 0)
        self.assertEqual(len(sim_results[1].species_dcdt), 0)
        self.assertEqual(len(sim_results[2].species_dcdt), 5)
        dcdt_approx = (sim_results[2].species_concentration["A_cell"] -
                       sim_results[1].species_concentration["A_cell"]) / 0.001
        dcdt = sim_results[2].species_dcdt["A_cell"]
        rms_norm = _rms(dcdt)
        rms_diff = _rms(dcdt - dcdt_approx)
        self.assertLess(rms_diff / rms_norm, 0.01)

        # don't get dcdt from simulation_results():
        sim_results2 = m.simulation_results()
        self.assertEqual(len(sim_results2[0].species_dcdt), 0)
        self.assertEqual(len(sim_results2[1].species_dcdt), 0)
        self.assertEqual(len(sim_results2[2].species_dcdt), 0)

        # single long timestep that times out (only pixel)
        with self.assertRaises(sme.RuntimeError):
            m.simulate(10000, 10000, 1)
        # set timeout to 1 second: don't throw on timeout, return partial results
        res1 = m.simulate(10000, 0.1, 1, False)
        self.assertGreaterEqual(len(res1), 1)
        res2 = m.simulate(10000, 10000, 1, False)
        self.assertEqual(len(res2), 1)

        # option to not return simulation results
        for sim_type in [sme.SimulatorType.DUNE, sme.SimulatorType.Pixel]:
            m = sme.open_example_model()
            sim_results = m.simulate(0.002,
                                     0.001,
                                     simulator_type=sim_type,
                                     return_results=False)
            self.assertEqual(len(sim_results), 0)

            # but results are still available from the model
            sim_results2 = m.simulation_results()
            self.assertEqual(len(sim_results2), 3)
    def test_species(self):

        # get an existing species
        m = sme.open_example_model()
        s = m.compartments["Cell"].species["A_cell"]

        # verify name and properties
        self.assertEqual(repr(s), "<sme.Species named 'A_cell'>")
        self.assertEqual(str(s)[0:32], "<sme.Species>\n  - name: 'A_cell'")
        self.assertEqual(s.name, "A_cell")
        self.assertEqual(s.diffusion_constant, 6.0)
        self.assertEqual(s.concentration_type, sme.ConcentrationType.Uniform)
        self.assertEqual(s.uniform_concentration, 0.0)
        self.assertEqual(s.analytic_concentration, "")
        self.assertEqual(s.concentration_image.shape, (100, 100))
        self.assertEqual(s.concentration_image[1, 2], 0.0)
        self.assertEqual(s.concentration_image[23, 40], 0.0)

        # assign new values
        s.name = "New A!"
        s.diffusion_constant = 1.0
        s.uniform_concentration = 0.3
        self.assertEqual(repr(s), "<sme.Species named 'New A!'>")
        self.assertEqual(str(s)[0:32], "<sme.Species>\n  - name: 'New A!'")
        self.assertEqual(s.name, "New A!")
        self.assertEqual(s.diffusion_constant, 1.0)
        self.assertEqual(s.concentration_type, sme.ConcentrationType.Uniform)
        self.assertEqual(s.uniform_concentration, 0.3)
        self.assertEqual(s.analytic_concentration, "")
        self.assertEqual(s.concentration_image.shape, (100, 100))
        self.assertAlmostEqual(s.concentration_image[1, 2], 0.0)
        self.assertAlmostEqual(s.concentration_image[23, 40], 0.3)

        # check changes were propagated to model
        self.assertRaises(
            sme.InvalidArgument,
            lambda: m.compartments["Cell"].species["A_cell"],
        )
        s2 = m.compartments["Cell"].species["New A!"]
        self.assertEqual(s, s2)

        # set an analytic initial concentration
        s.analytic_concentration = "cos(x)+1"
        # type of initial concentration changes:
        self.assertEqual(s.concentration_type, sme.ConcentrationType.Analytic)
        # uniform concentration value is unchanged:
        self.assertEqual(s.uniform_concentration, 0.3)
        # analytic concentration expression is no longer empty:
        self.assertEqual(s.analytic_concentration, "cos(x) + 1")
        self.assertEqual(s.concentration_image.shape, (100, 100))
        self.assertAlmostEqual(s.concentration_image[1, 2], 0.0)
        self.assertAlmostEqual(s.concentration_image[23, 40],
                               0.05748050894911694)

        # set a uniform initial concentration
        s.uniform_concentration = 2.0
        # type of initial concentration changes:
        self.assertEqual(s.concentration_type, sme.ConcentrationType.Uniform)
        self.assertEqual(s.uniform_concentration, 2.0)
        # analytic concentration expression is now empty:
        self.assertEqual(s.analytic_concentration, "")
        self.assertEqual(s.concentration_image.shape, (100, 100))
        self.assertAlmostEqual(s.concentration_image[1, 2], 0.0)
        self.assertAlmostEqual(s.concentration_image[23, 40], 2.0)

        # round trip check of image concentration
        a1 = np.random.default_rng().uniform(0, 1, (100, 100))
        s.concentration_image = a1
        # uniform concentration value is unchanged:
        self.assertEqual(s.uniform_concentration, 2.0)
        self.assertEqual(s.concentration_type, sme.ConcentrationType.Image)
        # get concentration image
        a2 = s.concentration_image
        self.assertEqual(s.concentration_type, sme.ConcentrationType.Image)
        self.assertAlmostEqual(a1[23, 48], a2[23, 48])
        # pixels outside of compartment are ignored
        compartment_mask = m.compartments["Cell"].geometry_mask
        self.assertLess(np.sum(np.square(a2[~compartment_mask])), 1e-7)
        a1[~compartment_mask] = 0.0
        self.assertLess(np.sum(np.square(a1 - a2)), 1e-7)
        # set concentration to output concentration image
        s.concentration_image = a2
        a3 = s.concentration_image
        self.assertEqual(s.concentration_type, sme.ConcentrationType.Image)
        self.assertAlmostEqual(a2[23, 48], a3[23, 48])
        self.assertLess(np.sum(np.square(a2 - a3)), 1e-7)

        # invalid image assignments throw with helpful message
        with self.assertRaises(sme.InvalidArgument) as err:
            s.concentration_image = np.random.default_rng().uniform(0, 1, 100)
        self.assertEqual(
            "Invalid concentration image array: is 1-dimensional, should be 2-dimensional",
            str(err.exception),
        )

        with self.assertRaises(sme.InvalidArgument) as err:
            s.concentration_image = np.random.default_rng().uniform(
                0, 1, (10, 10, 10))
        self.assertEqual(
            "Invalid concentration image array: is 3-dimensional, should be 2-dimensional",
            str(err.exception),
        )

        with self.assertRaises(sme.InvalidArgument) as err:
            s.concentration_image = np.random.default_rng().uniform(
                0, 1, (10, 100))
        self.assertEqual(
            "Invalid concentration image array: height is 10, should be 100",
            str(err.exception),
        )

        with self.assertRaises(sme.InvalidArgument) as err:
            s.concentration_image = np.random.default_rng().uniform(
                0, 1, (100, 101))
        self.assertEqual(
            "Invalid concentration image array: width is 101, should be 100",
            str(err.exception),
        )