Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
17e8118
Added quotes around invalid characters in type_id check.
BryanRumsey May 2, 2022
18528c1
Updated version to v1.0.3
BryanRumsey May 3, 2022
0ca2433
Added a run coverage script.
BryanRumsey May 20, 2022
13530f1
Added a module to contain the unittest files.
BryanRumsey May 20, 2022
d2f9a6a
Moved the unittest files into the unittests module.
BryanRumsey May 20, 2022
976725a
Added source args to coverage calls in testing github actions.
BryanRumsey May 20, 2022
5f9a469
Added unittests for the new timespan module.
BryanRumsey May 20, 2022
5492923
Added the error class for the timespan module.
BryanRumsey May 20, 2022
02c39ca
Added the timespan module to the core directory.
BryanRumsey May 20, 2022
c736547
Fixed import error with timespan error class.
BryanRumsey May 20, 2022
7fb2abc
Added the timespan to the core init.
BryanRumsey May 20, 2022
2a76aa0
Added a timespan module.
BryanRumsey May 22, 2022
54f376b
Added unittest for the new timespan module.
BryanRumsey May 22, 2022
cb3a4d5
Integrated the new timespan module into the package.
BryanRumsey May 22, 2022
4a447ba
Updated the unittests for the species module and added a validate fun…
BryanRumsey May 22, 2022
599665a
Added a validate function to the parameter class to handle all parame…
BryanRumsey May 23, 2022
ea5ebd5
Updated the unittests for the parameter module to test the updates.
BryanRumsey May 23, 2022
9a14edb
Re-organized the model class functions.
BryanRumsey May 25, 2022
9afb31c
Moved imports to the top of the model module.
BryanRumsey May 25, 2022
efc1e21
Updated Model.update_namespace().
BryanRumsey May 25, 2022
56fa78d
Refactored and re-organized the component functions. Added missing co…
BryanRumsey Jun 1, 2022
b47ee66
Fixed issue in solver caused by the change in the data functions data…
BryanRumsey Jun 1, 2022
5c51d77
Refactored the reaction class to be more consistent with GillesPy2.Re…
BryanRumsey Jun 2, 2022
bcb8c18
Refactored the unit test to cover the changes in reaction.py.
BryanRumsey Jun 2, 2022
69622c8
Converted all model subclasses with create functions.
BryanRumsey Jun 3, 2022
37338bb
Example updates part one.
BryanRumsey Jun 6, 2022
853b12b
Added the __str__ and _ipython_display_ function to the TimeSapn Module.
BryanRumsey Jun 6, 2022
4f95fd0
Fixed issue in compile prep function.
BryanRumsey Jun 6, 2022
f6e1888
Merge branch 'timespan-module' of https://github.com/StochSS/SpatialP…
BryanRumsey Jun 6, 2022
a90611d
Merge branch 'update-species-module' of https://github.com/StochSS/Sp…
BryanRumsey Jun 6, 2022
27e6a4f
Resolved merge conflicts.
BryanRumsey Jun 6, 2022
d4982ff
Merge branch 'update-model-reaction' of https://github.com/StochSS/Sp…
BryanRumsey Jun 6, 2022
8d592de
Merge branch 'update-model-reaction' of https://github.com/StochSS/Sp…
BryanRumsey Jun 6, 2022
e4b9fed
Merge branch 'update-model-reaction' of https://github.com/StochSS/Sp…
BryanRumsey Jun 6, 2022
2568e8f
Silenced isuniform check for coverage=="all"
BryanRumsey Jun 6, 2022
a80dbd2
Merge pull request #266 from StochSS/timespan-module
briandrawert Jun 6, 2022
1e03087
Merge branch 'develop' of https://github.com/StochSS/SpatialPy into u…
BryanRumsey Jun 6, 2022
65ed293
Merge branch 'develop' of https://github.com/StochSS/SpatialPy into u…
BryanRumsey Jun 6, 2022
6d59d77
Merge pull request #267 from StochSS/update-species-module
briandrawert Jun 6, 2022
277b34f
Merge branch 'develop' of https://github.com/StochSS/SpatialPy into u…
BryanRumsey Jun 6, 2022
a1c9c94
Merge pull request #268 from StochSS/update-parameter-modeule
briandrawert Jun 6, 2022
3ade2f7
Merge branch 'develop' of https://github.com/StochSS/SpatialPy into u…
BryanRumsey Jun 6, 2022
e032174
Merge pull request #272 from StochSS/update-model-module
briandrawert Jun 6, 2022
b9121f2
Merge pull request #273 from StochSS/update-reaction-module
briandrawert Jun 6, 2022
8425322
Added missing functions to reaction bug and fixed issue with resolvin…
BryanRumsey Jun 6, 2022
756c225
Merge branch 'update-model-reaction' of https://github.com/StochSS/Sp…
BryanRumsey Jun 6, 2022
c3942d5
Added check to ensure that the marate is a str before checking if its…
BryanRumsey Jun 6, 2022
171747f
Merge branch 'update-model-reaction' of https://github.com/StochSS/Sp…
BryanRumsey Jun 6, 2022
f55e8dd
Resticted the isuniform check to build and replaced StochKit with Spa…
BryanRumsey Jun 6, 2022
e0b2910
Fixed divide by zero error when particle vols are equal.
BryanRumsey Jun 6, 2022
131bbbf
Fixed the tspan validation in compile prep.
BryanRumsey Jun 6, 2022
6b911ef
Added missing ptp calculation.
BryanRumsey Jun 6, 2022
246661f
Merge pull request #271 from StochSS/update-model-reaction
seanebum Jun 7, 2022
82eb3f2
Example updates part two.
BryanRumsey Jun 7, 2022
98dde9e
Merge branch 'develop' of https://github.com/StochSS/SpatialPy into b…
BryanRumsey Jun 7, 2022
efd5021
Final examples update for working models.
BryanRumsey Jun 7, 2022
670741b
Fixed type issue for default timestep size.
BryanRumsey Jun 8, 2022
47dbbc5
Final updates to test examples.
BryanRumsey Jun 8, 2022
858992d
Fixed my dummy mistake of casting the timestep_size to the wrong type.
BryanRumsey Jun 8, 2022
ce01890
Removed duplicate examples
BryanRumsey Jun 9, 2022
00968de
Merge pull request #274 from StochSS/build-model
seanebum Jun 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Updated the unittests for the species module and added a validate fun…
…ction.
  • Loading branch information
BryanRumsey committed May 22, 2022
commit 4a447ba7c397c119bd6ac76031c9c0afc2aabd87
63 changes: 45 additions & 18 deletions spatialpy/core/species.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,6 @@ class Species():
:type restrict_to: int, str, list of ints or list of strs
"""
def __init__(self, name=None, diffusion_coefficient=None, restrict_to=None):
if name is None:
raise SpeciesError("Species must have a name")
if not isinstance(name, str):
raise SpeciesError("Species name must be a string")

if diffusion_coefficient is None:
raise SpeciesError("Species must have a diffusion_coefficient.")
if not (isinstance(diffusion_coefficient, (Parameter, str, float, int)) or \
type(diffusion_coefficient).__name__ == 'Parameter'):
raise SpeciesError("Diffusion coefficient must be a spatialpy.Parameter, str, float, or int.")
if isinstance(diffusion_coefficient, (float, int)) and diffusion_coefficient < 0:
raise SpeciesError("Diffusion coefficient must be non-negative.")

if not (restrict_to is None or isinstance(restrict_to, (str, int, list))):
raise SpeciesError("Restrict_to must be an int, str or list of ints or strs.")
if restrict_to is not None and isinstance(restrict_to, (int, str)):
Expand All @@ -58,6 +45,8 @@ def __init__(self, name=None, diffusion_coefficient=None, restrict_to=None):
for type_id in restrict_to:
self.restrict_to.append(f"type_{type_id}")

self.validate()

def __str__(self):
print_string = f"{self.name}: {str(self.diffusion_coefficient)}"
return print_string
Expand All @@ -71,10 +60,48 @@ def set_diffusion_coefficient(self, diffusion_coefficient):

:raises SpeciesError: If diffusion_coefficient is negative or not a valid type.
"""
if not (isinstance(diffusion_coefficient, (Parameter, str, float, int)) or \
type(diffusion_coefficient).__name__ == 'Parameter'):
raise SpeciesError("Diffusion coefficient must be a spatialpy.Parameter, str, float, or int.")
if diffusion_coefficient < 0:
raise SpeciesError("Diffusion coefficient must be non-negative.")
self.validate(diffusion_coefficient=diffusion_coefficient, coverage="diffusion_coefficient")

self.diffusion_coefficient = diffusion_coefficient

def validate(self, diffusion_coefficient=None, coverage="all"):
"""
Validate the species.

:param coverage: The scope of attributes to validate. Set to an attribute name to restrict validation \
to a specific attribute.
:type coverage: str

:raises SpeciesError: Attribute is of invalid type. Required attribute set to None. \
Attribute is value outside of accepted bounds.
"""
# Check name
if coverage in ("all", "name"):
if self.name is None:
raise SpeciesError("name can't be None type.")
if not isinstance(self.name, str):
raise SpeciesError(f"name must be of type str not {type(self.name)}.")
if self.name == "":
raise SpeciesError("name can't be an empty str.")

# Check diffusion coefficient
if coverage in ("all", "diffusion_coefficient"):
if coverage == "all" and diffusion_coefficient is None:
diffusion_coefficient = self.diffusion_coefficient

if diffusion_coefficient is None:
raise SpeciesError("diffusion_coefficient can't be None type.")
if not (isinstance(diffusion_coefficient, (Parameter, str, float, int)) or \
type(diffusion_coefficient).__name__ == 'Parameter'):
errmsg = "diffusion_coefficient must be of type SpatialPy.Parameter, "
errmsg += f"str, int, float not {type(diffusion_coefficient)}"
raise SpeciesError(errmsg)
if isinstance(diffusion_coefficient, (int, float)) and diffusion_coefficient < 0:
raise SpeciesError("diffusion_coefficient must be a positive value.")

# Check restrict_to
if coverage in ("all", "restrict_to"):
if not (self.restrict_to is None or isinstance(self.restrict_to, list)):
raise SpeciesError("restrict_to must be None or of type int, str, or list")
if self.restrict_to is not None and len(self.restrict_to) == 0:
raise SpeciesError("restrict_to can't be an empty list.")
119 changes: 81 additions & 38 deletions test/unit_tests/test_species.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,92 +25,135 @@ class TestSpecies(unittest.TestCase):
Unit tests for spatialpy.Species.
################################################################################################
'''
def setUp(self):
self.species = Species(name="test_species", diffusion_coefficient=0)

def test_constructor(self):
""" Test the Species constructor. """
species = Species(name="test_species", diffusion_coefficient=0)
self.assertEqual(species.name, "test_species")
self.assertEqual(species.diffusion_coefficient, 0)


def test_constructor__no_name(self):
""" Test the Species constructor without name. """
with self.assertRaises(SpeciesError):
species = Species(diffusion_coefficient=0)


def test_constructor__name_not_str(self):
""" Test the Species constructor with non-str name. """
with self.assertRaises(SpeciesError):
species = Species(name=0, diffusion_coefficient=0)

def test_constructor__invalid_name(self):
""" Test the Species constructor with an invalid name. """
test_names = ["", None, 0, 0.5, [0]]
for test_name in test_names:
with self.subTest(name=test_name):
with self.assertRaises(SpeciesError):
species = Species(name=test_name, diffusion_coefficient=0)

def test_constructor__no_diffusion_coefficient(self):
""" Test the Species constructor without diffusion_coefficient. """
with self.assertRaises(SpeciesError):
species = Species(name="test_species")


def test_constructor__negative_diffusion_coefficient(self):
""" Test the Species constructor with negative diffusion_coefficient. """
with self.assertRaises(SpeciesError):
species = Species(name="test_species", diffusion_coefficient=-1)


def test_constructor__parameter_diffusion_coefficient(self):
""" Test the Species constructor with a parameter for diffusion_coefficient. """
test_parameter = Parameter(name="test_parameter", expression=0.5)
species = Species(name="test_species", diffusion_coefficient=test_parameter)
self.assertIsInstance(species.diffusion_coefficient, Parameter)


def test_constructor__diffusion_coefficient_not_str_int_or_float(self):
""" Test the Species constructor with non-str, non-int, or non-float diffusion_coefficient. """
with self.assertRaises(SpeciesError):
species = Species(name="test_species", diffusion_coefficient=[0])


def test_constructor__restrict_to_not_accepted_type(self):
""" Test the Species constructor with a restrict_to that is not the proper type. """
with self.assertRaises(SpeciesError):
species = Species(name="test_species", diffusion_coefficient="0", restrict_to=1.5)

def test_constructor__invalid_diffusion_coefficient(self):
""" Test the Species constructor with an invalid diffusion_coefficient. """
test_dcs = [None, [0]]
for test_dc in test_dcs:
with self.subTest(initial_value=test_dc):
with self.assertRaises(SpeciesError):
species = Species(name="test_species", diffusion_coefficient=test_dc)

def test_constructor__invalid_restrict_to(self):
""" Test the Species constructor with an invalid restrict_to. """
test_rts = [0.5, [], (5, 2), {'x': 5}]
for test_rt in test_rts:
with self.subTest(restrict_to=test_rt):
with self.assertRaises(SpeciesError):
species = Species(name="test_species", diffusion_coefficient="0", restrict_to=test_rt)

def test_constructor__int_restrict_to(self):
""" Test the Species constructor with a int restrict_to. """
species = Species(name="test_species", diffusion_coefficient=0, restrict_to=1)
self.assertIsInstance(species.restrict_to, list)
self.assertEqual(species.restrict_to, ["type_1"])


def test_constructor__str_restrict_to(self):
""" Test the Species constructor with a string restrict_to. """
species = Species(name="test_species", diffusion_coefficient=0, restrict_to="Walls")
self.assertIsInstance(species.restrict_to, list)
self.assertEqual(species.restrict_to, ["type_Walls"])


def test___str___(self):
""" Test Species.__str__ method. """
species = Species(name="test_species", diffusion_coefficient=0)
self.assertIsInstance(str(species), str)

self.assertIsInstance(str(self.species), str)

def test_set_diffusion_coefficient(self):
""" Test Species.set_diffusion_coefficient method. """
species = Species(name="test_species", diffusion_coefficient=0)
species.set_diffusion_coefficient(diffusion_coefficient=1)
self.assertEqual(species.diffusion_coefficient, 1)
self.species.set_diffusion_coefficient(diffusion_coefficient=1)
self.assertEqual(self.species.diffusion_coefficient, 1)

def test_set_diffusion_coefficient__invalid_diffusion_coefficient(self):
""" Test Species.set_diffusion_coefficient method with an invalid diffusion_coefficient. """
test_dcs = [None, [1]]
for test_dc in test_dcs:
with self.subTest(diffusion_coefficient=test_dc):
with self.assertRaises(SpeciesError):
self.species.set_diffusion_coefficient(diffusion_coefficient=test_dc)

def test_set_diffusion_coefficient__negative_diffusion_coefficient(self):
""" Test Species.set_diffusion_coefficient method with negative diffusion_coefficient. """
species = Species(name="test_species", diffusion_coefficient=0)
with self.assertRaises(SpeciesError):
species.set_diffusion_coefficient(diffusion_coefficient=-1)


def test_set_diffusion_coefficient__diffusion_coefficient_not_str_int_or_float(self):
""" Test Species.set_diffusion_coefficient method with non-str, non-int, or non-float diffusion_coefficient. """
species = Species(name="test_species", diffusion_coefficient=0)
with self.assertRaises(SpeciesError):
species.set_diffusion_coefficient(diffusion_coefficient=[0])
self.species.set_diffusion_coefficient(diffusion_coefficient=-1)

def test_validate__invalid_name(self):
""" Test Species.validate with an invalid name. """
test_names = ["", None, 0, 0.5, [0]]
for test_name in test_names:
with self.subTest(name=test_name):
with self.assertRaises(SpeciesError):
self.species.name = test_name
self.species.validate()

def test_validate__invalid_diffusion_coefficient(self):
""" Test Species.validate with an invalid diffusion_coefficient. """
test_dcs = [None, [0]]
for test_dc in test_dcs:
with self.subTest(initial_value=test_dc):
with self.assertRaises(SpeciesError):
self.species.diffusion_coefficient = test_dc
self.species.validate()

def test_validate__invalid_diffusion_coefficient_value(self):
""" Test Species.validate with an invalid diffusion_coefficient value. """
test_dcs = [-0.5, -1, -3, -5]
for test_dc in test_dcs:
with self.subTest(initial_value=test_dc):
with self.assertRaises(SpeciesError):
self.species.diffusion_coefficient = test_dc
self.species.validate()

def test_validate__invalid_restrict_to(self):
""" Test Species.validate with an invalid restrict_to. """
test_rts = ["5", 1, 0.5, [], (1, 2), {'x': 1}]
for test_rt in test_rts:
with self.subTest(restrict_to=test_rt):
with self.assertRaises(SpeciesError):
self.species.restrict_to = test_rt
self.species.validate()

def test_comp_time_of_validate(self):
""" Check the computation time of validate. """
import time
from datetime import datetime
start = time.time()
self.species.validate()
tic = datetime.utcfromtimestamp(time.time() - start)
print(f"Total time to run validate: {tic.strftime('%M mins %S secs %f msecs')}")