From beabcd4f6f769e2e1e6db7fd785ac3a6ba6d4d8d Mon Sep 17 00:00:00 2001 From: Bryan Rumsey Date: Fri, 24 Jun 2022 10:47:41 -0400 Subject: [PATCH 1/6] Fixed type_id assignments when creating stochss domain particles. --- spatialpy/stochss/stochss_export.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spatialpy/stochss/stochss_export.py b/spatialpy/stochss/stochss_export.py index 7fe2c545..869ce2dc 100644 --- a/spatialpy/stochss/stochss_export.py +++ b/spatialpy/stochss/stochss_export.py @@ -173,12 +173,16 @@ def __build_element(stoich_species): def __get_particles(domain): s_particles = [] for i, point in enumerate(domain.vertices): + if domain.type_id[i] is None: + type_id = 0 + else: + type_id = domain.typeNdxMapping[domain.type_id[i]] s_particle = {"fixed":bool(domain.fixed[i]), "mass":domain.mass[i], "nu":domain.nu[i], "particle_id":i, "point":list(point), - "type":int(domain.type_id[i]), + "type":type_id, "volume":domain.vol[i]} s_particles.append(s_particle) From 26dd43501f087ab34e49dcd3cf7c14c2945926c1 Mon Sep 17 00:00:00 2001 From: Bryan Rumsey Date: Fri, 24 Jun 2022 10:49:54 -0400 Subject: [PATCH 2/6] Fixed type_id assignments when adding points to spatialpy domains from stochss domains. --- spatialpy/core/domain.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spatialpy/core/domain.py b/spatialpy/core/domain.py index cdb033bf..c9ba7d1f 100644 --- a/spatialpy/core/domain.py +++ b/spatialpy/core/domain.py @@ -834,19 +834,25 @@ def read_stochss_domain(cls, filename): obj = Domain(0, tuple(domain['x_lim']), tuple(domain['y_lim']), tuple(domain['z_lim']), rho0=domain['rho_0'], c0=domain['c_0'], P0=domain['p_0'], gravity=domain['gravity']) - for particle in domain['particles']: + for i, particle in enumerate(domain['particles']): try: type_id = list(filter( lambda d_type, t_ndx=particle['type']: d_type['typeID'] == t_ndx, domain['types'] ))[0]['name'] except IndexError: type_id = particle['type'] + if type_id == "Un-Assigned" or type_id == 0: + type_id = "UnAssigned" # StochSS backward compatability check for rho rho = None if "rho" not in particle.keys() else particle['rho'] # StochSS backward compatability check for c c = 0 if "c" not in particle.keys() else particle['c'] obj.add_point(particle['point'], vol=particle['volume'], mass=particle['mass'], type_id=type_id, nu=particle['nu'], fixed=particle['fixed'], rho=rho, c=c) + if "UnAssigned" in obj.type_id[-1]: + obj.type_id[-1] = None + if None not in obj.typeNdxMapping: + obj.typeNdxMapping[None] = 0 return obj except KeyError as err: From 0ee8367a331960a2322cbca136add0ec5d72fed0 Mon Sep 17 00:00:00 2001 From: Bryan Rumsey Date: Fri, 24 Jun 2022 12:08:25 -0400 Subject: [PATCH 3/6] Added checks for UnAssigned types. --- spatialpy/core/boundarycondition.py | 2 ++ spatialpy/core/reaction.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/spatialpy/core/boundarycondition.py b/spatialpy/core/boundarycondition.py index 32f25ae7..8c833c2a 100644 --- a/spatialpy/core/boundarycondition.py +++ b/spatialpy/core/boundarycondition.py @@ -87,6 +87,8 @@ def __init__(self, xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=N if type_id is not None and not isinstance(type_id, (int, str)): raise BoundaryConditionError("Type-ID must be of type int.") elif type_id is not None: + if "UnAssigned" in type_id: + raise BoundaryConditionError("'UnAssigned' is not a valid type_id") type_id = f"type_{type_id}" if target is None or not (isinstance(target, (str, Species)) or type(target).__name__ == 'Species' or property in ('nu', 'rho', 'v')): diff --git a/spatialpy/core/reaction.py b/spatialpy/core/reaction.py index d0404734..098e23db 100644 --- a/spatialpy/core/reaction.py +++ b/spatialpy/core/reaction.py @@ -623,6 +623,8 @@ def validate(self, coverage="build", reactants=None, products=None, propensity_f raise ReactionError("Type ids in restrict_to must be of type int or str.") if type_id == "": raise ReactionError("Type ids in restrict_to can't be an empty string.") + if "UnAssigned" in type_id: + raise ReactionError("'UnAssigned' is not a valid type_id.") if coverage in ("all", "initialized"): if not isinstance(type_id, str): raise ReactionError("Type ids in restrict_to must be of type str.") From 6e0acac1f9cd92361274ea93eeafbac4538fa5f3 Mon Sep 17 00:00:00 2001 From: Bryan Rumsey Date: Fri, 24 Jun 2022 12:10:00 -0400 Subject: [PATCH 4/6] Transitioned from using 'None' as the default/un-accepted type id to 'UnAssigned'. --- spatialpy/core/domain.py | 23 ++++++++++++++--------- spatialpy/solvers/solver.py | 4 ++-- spatialpy/stochss/stochss_export.py | 5 +---- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/spatialpy/core/domain.py b/spatialpy/core/domain.py index c9ba7d1f..9d616a76 100644 --- a/spatialpy/core/domain.py +++ b/spatialpy/core/domain.py @@ -68,7 +68,7 @@ def __init__(self, numpoints, xlim, ylim, zlim, rho0=1.0, c0=10, P0=None, gravit self.vol = numpy.zeros((numpoints), dtype=float) self.mass = numpy.zeros((numpoints), dtype=float) - self.type_id = numpy.array([None] * numpoints, dtype=object) + self.type_id = numpy.array(["type_UnAssigned"] * numpoints, dtype=object) self.nu = numpy.zeros((numpoints), dtype=float) self.c = numpy.zeros((numpoints), dtype=float) self.rho = numpy.zeros((numpoints), dtype=float) @@ -136,7 +136,7 @@ def compile_prep(self): :raises DomainError: If a type_id is not set or rho=0 for a particle. """ - if self.type_id.tolist().count(None) > 0: + if self.type_id.tolist().count("type_UnAssigned") > 0: raise DomainError(f"Particles must be assigned a type_id.") if numpy.count_nonzero(self.rho) < len(self.rho): raise DomainError(f"Rho must be a positive value.") @@ -184,7 +184,10 @@ def add_point(self, point, vol=0, mass=0, type_id=1, nu=0, fixed=False, rho=None if (char in string.punctuation and char != "_") or char == " ": raise DomainError(f"Type_id cannot contain {char}") if type_id not in self.typeNdxMapping: - self.typeNdxMapping[type_id] = len(self.typeNdxMapping) + 1 + if "UnAssigned" in type_id: + self.typeNdxMapping[type_id] = 0 + else: + self.typeNdxMapping[type_id] = len(self.typeNdxMapping) + 1 if rho is None: rho = mass / vol @@ -240,7 +243,10 @@ def set_properties(self, geometry_ivar, type_id, vol=None, mass=None, nu=None, r if (char in string.punctuation and char != "_") or char == " ": raise DomainError(f"Type_id cannot contain '{char}'") if type_id not in self.typeNdxMapping: - self.typeNdxMapping[type_id] = len(self.typeNdxMapping) + 1 + if "UnAssigned" in type_id: + self.typeNdxMapping[type_id] = 0 + else: + self.typeNdxMapping[type_id] = len(self.typeNdxMapping) + 1 # apply the type to all points, set type for any points that match count = 0 on_boundary = self.find_boundary_points() @@ -807,7 +813,10 @@ def read_stochss_subdomain_file(self, filename, type_ids=None): if (char in string.punctuation and char != "_") or char == " ": raise DomainError(f"Type_id cannot contain {char}") if type_id not in self.typeNdxMapping: - self.typeNdxMapping[type_id] = len(self.typeNdxMapping) + 1 + if "UnAssigned" in type_id: + self.typeNdxMapping[type_id] = 0 + else: + self.typeNdxMapping[type_id] = len(self.typeNdxMapping) + 1 self.type_id[int(ndx)] = type_id @@ -849,10 +858,6 @@ def read_stochss_domain(cls, filename): c = 0 if "c" not in particle.keys() else particle['c'] obj.add_point(particle['point'], vol=particle['volume'], mass=particle['mass'], type_id=type_id, nu=particle['nu'], fixed=particle['fixed'], rho=rho, c=c) - if "UnAssigned" in obj.type_id[-1]: - obj.type_id[-1] = None - if None not in obj.typeNdxMapping: - obj.typeNdxMapping[None] = 0 return obj except KeyError as err: diff --git a/spatialpy/solvers/solver.py b/spatialpy/solvers/solver.py index 5d46bfe9..c2da3a26 100644 --- a/spatialpy/solvers/solver.py +++ b/spatialpy/solvers/solver.py @@ -312,9 +312,9 @@ def __get_param_defs(self): def __get_particle_inits(self, num_chem_species): init_particles = "" if self.model.domain.type_id is None: - self.model.domain.type_id = ["type 1"] * self.model.domain.get_num_voxels() + self.model.domain.type_id = ["type_1"] * self.model.domain.get_num_voxels() for i, type_id in enumerate(self.model.domain.type_id): - if type_id is None: + if "UnAssigned" in type_id: errmsg = "Not all particles have been defined in a type. Mass and other properties must be defined" raise SimulationError(errmsg) x = self.model.domain.coordinates()[i, 0] diff --git a/spatialpy/stochss/stochss_export.py b/spatialpy/stochss/stochss_export.py index 869ce2dc..5d7d586d 100644 --- a/spatialpy/stochss/stochss_export.py +++ b/spatialpy/stochss/stochss_export.py @@ -173,10 +173,7 @@ def __build_element(stoich_species): def __get_particles(domain): s_particles = [] for i, point in enumerate(domain.vertices): - if domain.type_id[i] is None: - type_id = 0 - else: - type_id = domain.typeNdxMapping[domain.type_id[i]] + type_id = domain.typeNdxMapping[domain.type_id[i]] s_particle = {"fixed":bool(domain.fixed[i]), "mass":domain.mass[i], "nu":domain.nu[i], From 96f39d6f301348838c29e044975e8fb22675fede Mon Sep 17 00:00:00 2001 From: Bryan Rumsey Date: Fri, 24 Jun 2022 12:15:17 -0400 Subject: [PATCH 5/6] Fixed broken tests. --- spatialpy/core/reaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spatialpy/core/reaction.py b/spatialpy/core/reaction.py index 098e23db..cad800c9 100644 --- a/spatialpy/core/reaction.py +++ b/spatialpy/core/reaction.py @@ -623,7 +623,7 @@ def validate(self, coverage="build", reactants=None, products=None, propensity_f raise ReactionError("Type ids in restrict_to must be of type int or str.") if type_id == "": raise ReactionError("Type ids in restrict_to can't be an empty string.") - if "UnAssigned" in type_id: + if isinstance(type_id, str) and "UnAssigned" in type_id: raise ReactionError("'UnAssigned' is not a valid type_id.") if coverage in ("all", "initialized"): if not isinstance(type_id, str): From 3d0a35ee12c27387ece7f2ba96ee2ff05bab738d Mon Sep 17 00:00:00 2001 From: Bryan Rumsey Date: Sun, 10 Jul 2022 10:26:24 -0400 Subject: [PATCH 6/6] Added un-assigned type to the default typeNDXMapping. --- spatialpy/core/domain.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spatialpy/core/domain.py b/spatialpy/core/domain.py index 9d616a76..e2a2f49d 100644 --- a/spatialpy/core/domain.py +++ b/spatialpy/core/domain.py @@ -74,7 +74,7 @@ def __init__(self, numpoints, xlim, ylim, zlim, rho0=1.0, c0=10, P0=None, gravit self.rho = numpy.zeros((numpoints), dtype=float) self.fixed = numpy.zeros((numpoints), dtype=bool) self.listOfTypeIDs = [] - self.typeNdxMapping = OrderedDict() + self.typeNdxMapping = OrderedDict({"type_UnAssigned": 0}) self.typeNameMapping = None self.rho0 = rho0 @@ -187,7 +187,7 @@ def add_point(self, point, vol=0, mass=0, type_id=1, nu=0, fixed=False, rho=None if "UnAssigned" in type_id: self.typeNdxMapping[type_id] = 0 else: - self.typeNdxMapping[type_id] = len(self.typeNdxMapping) + 1 + self.typeNdxMapping[type_id] = len(self.typeNdxMapping) if rho is None: rho = mass / vol @@ -246,7 +246,7 @@ def set_properties(self, geometry_ivar, type_id, vol=None, mass=None, nu=None, r if "UnAssigned" in type_id: self.typeNdxMapping[type_id] = 0 else: - self.typeNdxMapping[type_id] = len(self.typeNdxMapping) + 1 + self.typeNdxMapping[type_id] = len(self.typeNdxMapping) # apply the type to all points, set type for any points that match count = 0 on_boundary = self.find_boundary_points() @@ -816,7 +816,7 @@ def read_stochss_subdomain_file(self, filename, type_ids=None): if "UnAssigned" in type_id: self.typeNdxMapping[type_id] = 0 else: - self.typeNdxMapping[type_id] = len(self.typeNdxMapping) + 1 + self.typeNdxMapping[type_id] = len(self.typeNdxMapping) self.type_id[int(ndx)] = type_id