rs package
This commit is contained in:
182
rs/reaction_system.py
Normal file
182
rs/reaction_system.py
Normal file
@@ -0,0 +1,182 @@
|
||||
from sys import exit
|
||||
from colour import *
|
||||
|
||||
class ReactionSystem(object):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.reactions = []
|
||||
self.background_set = []
|
||||
|
||||
#self.reactions_by_agents = [] # each element is 'reactions_by_prod'
|
||||
self.reactions_by_prod = None
|
||||
|
||||
## legacy:
|
||||
self.init_contexts = []
|
||||
self.context_entities = []
|
||||
|
||||
def assume_not_in_bgset(self, name):
|
||||
if self.is_in_background_set(name):
|
||||
raise RuntimeError("The entity " + name + " is already on the list")
|
||||
|
||||
def add_bg_set_entity(self, name):
|
||||
self.assume_not_in_bgset(name)
|
||||
self.background_set.append(name)
|
||||
|
||||
def ensure_bg_set_entity(self, name):
|
||||
if not self.is_in_background_set(name):
|
||||
self.background_set.append(name)
|
||||
|
||||
def add_bg_set_entities(self, elements):
|
||||
for e in elements:
|
||||
self.add_bg_set_entity(e)
|
||||
|
||||
def is_in_background_set(self, entity):
|
||||
"""Checks if the given name is valid wrt the background set="""
|
||||
if entity in self.background_set:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_entity_id(self, name):
|
||||
try:
|
||||
return self.background_set.index(name)
|
||||
except ValueError:
|
||||
print("Undefined background set entity: " + repr(name))
|
||||
exit(1)
|
||||
|
||||
def get_state_ids(self, state):
|
||||
ids = []
|
||||
for entity in state:
|
||||
ids.append(self.get_entity_id(entity))
|
||||
|
||||
return ids
|
||||
|
||||
def get_entity_name(self, entity_id):
|
||||
"""Returns the string corresponding to the entity"""
|
||||
return self.background_set[entity_id]
|
||||
|
||||
def add_reaction(self, R, I, P):
|
||||
"""Adds a reaction"""
|
||||
|
||||
if R == [] or P == []:
|
||||
raise RuntimeError("No reactants or products defined")
|
||||
|
||||
reactants = []
|
||||
for entity in R:
|
||||
reactants.append(self.get_entity_id(entity))
|
||||
|
||||
inhibitors = []
|
||||
for entity in I:
|
||||
inhibitors.append(self.get_entity_id(entity))
|
||||
|
||||
products = []
|
||||
for entity in P:
|
||||
products.append(self.get_entity_id(entity))
|
||||
|
||||
self.reactions.append((reactants, inhibitors, products))
|
||||
|
||||
def add_initial_context_set(self, context_set):
|
||||
if context_set == []:
|
||||
print("Empty context set is not allowed")
|
||||
raise
|
||||
|
||||
integers = []
|
||||
for entity in context_set:
|
||||
if not entity in self.background_set:
|
||||
print("The entity", entity, "is not in the background set")
|
||||
raise
|
||||
else:
|
||||
integers.append(self.get_entity_id(entity))
|
||||
|
||||
self.init_contexts.append(integers)
|
||||
|
||||
def set_context_entities(self, entities):
|
||||
|
||||
for entity in entities:
|
||||
entity_id = self.get_entity_id(entity)
|
||||
self.context_entities.append(entity_id)
|
||||
|
||||
def entities_names_set_to_str(self, entities):
|
||||
s = ""
|
||||
for entity in entities:
|
||||
s += entity + ", "
|
||||
s = s[:-2]
|
||||
return s
|
||||
|
||||
def entities_ids_set_to_str(self, entities):
|
||||
s = ""
|
||||
for entity in entities:
|
||||
s += self.get_entity_name(entity) + ", "
|
||||
s = s[:-2]
|
||||
return s
|
||||
|
||||
def state_to_str(self, state):
|
||||
return self.entities_ids_set_to_str(state)
|
||||
|
||||
def show_reactions(self, soft=False):
|
||||
print(C_MARK_INFO + " Reactions:")
|
||||
if soft and len(self.reactions) > 50:
|
||||
print(" -> there are more than 50 reactions (" + str(len(self.reactions)) + ")")
|
||||
else:
|
||||
print(" "*4 + "{0: ^35}{1: ^25}{2: ^15}".format("reactants"," inhibitors"," products"))
|
||||
for reaction in self.reactions:
|
||||
# print("\t( R={" + self.state_to_str(reaction[0]) + "}, I={" + self.state_to_str(reaction[1]) + "}, P={" + self.state_to_str(reaction[2]) + "} )")
|
||||
print(" " + "- {0: ^35}{1: ^25}{2: ^15}".format("{ " + self.state_to_str(reaction[0]) + " }",
|
||||
" { " + self.state_to_str(reaction[1]) + " }",
|
||||
" { " + self.state_to_str(reaction[2]) + " }"))
|
||||
|
||||
def show_background_set(self):
|
||||
print(C_MARK_INFO + " Background set: {" + self.entities_names_set_to_str(self.background_set) + "}")
|
||||
|
||||
def show_initial_contexts(self):
|
||||
if len(self.init_contexts) > 0:
|
||||
print(C_MARK_INFO + " Initial context sets:")
|
||||
for ctx in self.init_contexts:
|
||||
print(" - {" + self.entities_ids_set_to_str(ctx) + "}")
|
||||
|
||||
def show_context_entities(self):
|
||||
if len(self.context_entities) > 0:
|
||||
print(C_MARK_INFO + " Context entities: " + self.entities_ids_set_to_str(self.context_entities))
|
||||
|
||||
def show(self, soft=False):
|
||||
|
||||
self.show_background_set()
|
||||
self.show_initial_contexts()
|
||||
self.show_reactions(soft)
|
||||
self.show_context_entities()
|
||||
|
||||
def get_reactions_by_product(self):
|
||||
"""Sorts reactions by their products and returns a dictionary of products"""
|
||||
|
||||
if self.reactions_by_prod != None:
|
||||
return self.reactions_by_prod
|
||||
|
||||
producible_entities = set()
|
||||
|
||||
for reaction in self.reactions:
|
||||
producible_entities = producible_entities.union(set(reaction[2]))
|
||||
|
||||
reactions_by_prod = {}
|
||||
|
||||
for prod_entity in producible_entities:
|
||||
reactions_by_prod[prod_entity] = []
|
||||
for reaction in self.reactions:
|
||||
if prod_entity in reaction[2]:
|
||||
reactions_by_prod[prod_entity].append([reaction[0],reaction[1]])
|
||||
|
||||
# save in cache
|
||||
self.reactions_by_prod = reactions_by_prod
|
||||
|
||||
return reactions_by_prod
|
||||
|
||||
def sanity_check(self):
|
||||
"""Performs a sanity check on the defined reaction system"""
|
||||
|
||||
if self.reactions == []:
|
||||
print("No reactions defined")
|
||||
exit(1)
|
||||
|
||||
if self.background_set == []:
|
||||
print("Empty background set")
|
||||
exit(1)
|
||||
Reference in New Issue
Block a user