def replace_entity(self, e1, e2): """Replaces an entity pool by another in the map :param e1: the entity pool to be replaced :param e2: the replacing entity pool """ if isinstance(e1, str): parser = Parser() e1 = parser.entity.parseString(e1)[0] if isinstance(e2, str): parser = Parser() e2 = parser.entity.parseString(e2)[0] existent_entity = self.get_entity(e2, by_entity=True) if existent_entity: e2 = existent_entity for modulation in self.modulations: if modulation.source == e1: modulation.source = e2 for process in self.processes: for reac in process.reactants: if reac == e1: process.reactants[process.reactants.index(e1)] = e2 for prod in process.products: if prod == e1: process.products[process.products.index(e1)] = e2 for lo in self.los: for child in lo.children: if child == e1: lo.children[lo.children.index(e1)] = e2 self.remove_entity(e1) self.add_entity(e2)
def replace_modulation(self, m1, m2): """Replaces an modulation by another in the map :param m1: the modulation to be replaced :param m2: the replacing modulation """ if isinstance(m1, str): parser = Parser() m1 = parser.modulation.parseString(m1)[0] if isinstance(m2, str): parser = Parser() m2 = parser.modulation.parseString(m2)[0] self.add_modulation(m2) self.remove_modulation(m1)
def get_process(self, val, by_process=False, by_id=False, by_label=False, by_string=False): """Retrieves a process from the map Possible ways of searching for the process: by object, id, hash or sbgntxt string. Only the first matching process is retrieved. Returns None if no matching process is found. :param val: the value to be searched :param by_process: if True, search by object :param by_id: if True, search by id :param by_string: if True, search by sbgntxt string :return: the unit of information or None """ if by_string: parser = Parser() val = parser.process.parseString(val)[0] for p in self.processes: if by_process or by_string: if p == val: return p if by_id: if p.id == val: return p if by_label: if hasattr(p, "label"): if p.label == val: return p return None
def add_modulation(self, mod): """Adds an modulation to the map Also recursively adds the source and the target if they do not already belong to the map. :param mod: the modulation to be added (object or sbgntxt string) """ if isinstance(mod, str): parser = Parser() mod = parser.modulation.parseString(mod)[0] if mod not in self.modulations: source = mod.source target = mod.target if isinstance(source, Entity): existent_source = self.get_entity(source, by_entity=True) if existent_source: mod.source = existent_source else: self.add_entity(source) elif isinstance(source, LogicalOperator): existent_source = self.get_lo(source, by_lo=True) if existent_source: mod.source = existent_source else: self.add_lo(source) existent_target = self.get_process(target, by_process=True) if existent_target: mod.target = existent_target else: self.add_process(target) self.modulations.append(mod)
def remove_lo(self, op): """Removes a logical operator from the map Also removes all children of the logical operators that are themselves logical operators, if those are not the children of other operators or the source of a modulation, as well as the modulations departing from the operator. :param op: the logical operator to be removed """ if isinstance(op, str): parser = Parser() op = parser.lo.parseString(op)[0] self.los.remove(op) toremove = [] for child in op.children: if isinstance(child, LogicalOperator): remove_child = True # we don't remove the child if it belongs to another logical function for lo in self.los: for ch in lo.children: if ch == child: remove_child = False break if remove_child: # we don't remove the child if it is the source of a modulation for mod in self.modulations: if mod.source == child: remove_child = False if remove_child: toremove.append(child) for child in toremove: self.remove_lo(child) self.modulations = [ mod for mod in self.modulations if mod.source != op ]
def add_lo(self, op): """Adds a logical operator to the map Also recursively adds the children if they do not already belong to the map. :param op: the logical operator to be added (object or sbgntxt string) """ if isinstance(op, str): parser = Parser() op = parser.lo.parseString(op)[0] if op not in self.los: for child in op.children: if isinstance(child, Entity): existent_child = self.get_entity(child, by_entity=True) if existent_child: op.children[op.children.index(child)] = existent_child else: self.add_entity(child) elif isinstance(child, LogicalOperator): existent_child = self.get_lo(child, by_lo=True) if existent_child: op.children[op.children.index(child)] = existent_child else: self.add_lo(child) self.los.append(op)
def get_entity(self, val, by_entity=True, by_id=False, by_label=False, by_string=False): """Retrieves a entity pool from the map Possible ways of searching for the entity pool: by object, id, hash or sbgntxt string. Only the first matching entity pool is retrieved. Returns None if no matching entity pool is found. :param val: the value to be searched :param by_entity: if True, search by object :param by_id: if True, search by id :param by_string: if True, search by sbgntxt string :return: the unit of information or None """ if by_string: parser = Parser() val = parser.entity.parseString(val)[0] for e in self.entities: if by_entity or by_string: if e == val: return e if by_id: if e.id == val: return e if by_label: if hasattr(e, "label"): if e.label == val: return e return None
def add_process(self, proc): """Adds a process to the map Also recursively adds the reactants and the products if they do not already belong to the map. :param proc: the process to be added (object or sbgntxt string) """ if isinstance(proc, str): parser = Parser() proc = parser.process.parseString(proc)[0] if proc not in self.processes: if hasattr(proc, "reactants"): reactants = [] for reactant in proc.reactants: existent_reactant = self.get_entity(reactant, by_entity=True) if existent_reactant: reactants.append(existent_reactant) else: self.add_entity(reactant) reactants.append(reactant) proc.reactants = reactants if hasattr(proc, "products"): products = [] for product in proc.products: existent_product = self.get_entity(product, by_entity=True) if existent_product: products.append(existent_product) else: products.append(product) self.add_entity(product) proc.products = products self.processes.append(proc)
def get_modulation(self, val, by_modulation=False, by_id=False, by_string=False): """Retrieves a modulation from the map Possible ways of searching for the modulation: by object, id, hash or sbgntxt string. Only the first matching modulation is retrieved. Returns None if no matching modulation is found. :param val: the value to be searched :param by_ui: if True, search by object :param by_modulation: if True, search by id :param by_string: if True, search by sbgntxt string :return: the unit of information or None """ if by_string: parser = Parser() val = parser.modulation.parseString(val)[0] for m in self.modulations: if by_modulation or by_string: if m == val: return m if by_id: if m.id == val: return m return None
def get_compartment(self, val, by_compartment=False, by_id=False, by_label=False, by_string=False): """Retrieves a compartment from the map Possible ways of searching for the compartment: by object, id, hash or sbgntxt string. Only the first matching compartment is retrieved. Returns None if no matching compartment is found. :param val: the value to be searched :param by_compartment: if True, search by object :param by_id: if True, search by id :param by_string: if True, search by sbgntxt string :return: the unit of information or None """ if by_string: parser = Parser() val = parser.compartment.parseString(val)[0] for c in self.compartments: if by_compartment or by_string: if c == val: return c if by_id: if c.id == val: return c if by_label: if hasattr(c, "label"): if c.label == val: return c return None
def replace_sv(self, sv1, sv2): """Replaces a state variable by another state variable in the map :param sv1: the state variable to be replaced :param sv2: the replacing state variable """ if isinstance(sv1, str): parser = Parser() sv1 = parser.sv.parseString(e1)[0] if isinstance(sv2, str): parser = Parser() sv2 = parser.sv.parseString(e2)[0] for entity in self.entities: if hasattr(entity, "svs"): for i, sv in enumerate(entity.svs): if sv == sv1: entity.svs[i] = copy.deepcopy(sv2)
def replace_ui(self, ui1, ui2): """Replaces a unit of information by another unit of information in the map :param ui1: the unit of information to be replaced :param ui2: the replacing unit of information """ if isinstance(ui1, str): parser = Parser() ui1 = parser.ui.parseString(e1)[0] if isinstance(sv2, str): parser = Parser() ui2 = parser.ui.parseString(e2)[0] for entity in self.entities: if hasattr(entity, "uis"): for i, ui in enumerate(entity.uis): if ui == ui1: entity.uis[i] = copy.deepcopy(ui2)
def add_compartment(self, comp): """Adds a compartment to the map :param comp: the compartment to be added (object or sbgntxt string) """ if isinstance(comp, str): parser = Parser() comp = parser.compartment.parseString(comp)[0] if comp not in self.compartments: self.compartments.append(comp)
def replace_process(self, p1, p2): """Replaces a process by another in the map :param p1: the process to be replaced :param p2: the replacing process """ if isinstance(p1, str): parser = Parser() p1 = parser.process.parseString(p1)[0] if isinstance(p2, str): parser = Parser() p2 = parser.process.parseString(p2)[0] existent_process = self.get_process(p2, by_process=True) if existent_process: p2 = existent_process for modulation in self.modulations: if modulation.target == p1: modulation.target = p2 self.remove_process(p1) self.add_process(p2)
def replace_compartment(self, c1, c2): """Replaces a compartment by another in the map :param c1: the compartment to be replaced :param c2: the replacing compartment """ if isinstance(c1, str): parser = Parser() c1 = parser.compartment.parseString(c1)[0] if isinstance(c2, str): parser = Parser() c2 = parser.compartment.parseString(c2)[0] existent_compartment = self.get_compartment(c2, by_compartment=True) if existent_compartment: c2 = existent_compartment for entity in self.entities: if hasattr(entity, "compartment"): if entity.compartment == c1: entity.compartment = c2 self.remove_compartment(c1) self.add_compartment(c2)
def replace_subentity(self, e1, e2): """Replaces a subentity by another in the map :param e1: the subentity to be replaced :param e2: the replacing subentity """ def _replace_subentity_rec(e, e1, e2): if hasattr(e, "components"): for i, se in enumerate(e.components): if se == e1: e.components[i] = copy.deepcopy(e2) _replace_subentity_rec(se, e1, e2) if isinstance(e1, str): parser = Parser() e1 = parser.subentity.parseString(e1)[0] if isinstance(e2, str): parser = Parser() e2 = parser.subentity.parseString(e2)[0] for e in self.entities: _replace_subentity_rec(e, e1, e2)
def replace_lo(self, lo1, lo2): """Replaces an logical operator by another in the map :param lo1: the logical operator to be replaced :param lo2: the replacing logical operator """ if isinstance(lo1, str): parser = Parser() lo1 = parser.lo.parseString(lo1)[0] if isinstance(lo2, str): parser = Parser() lo2 = parser.modulation.parseString(lo2)[0] existent_lo = self.get_entity(lo2, by_lo=True) if existent_lo: lo2 = existent_lo for modulation in self.modulations: if modulation.source == lo1: modulation.source = lo2 for op in self.los: for child in op.children: if child == lo1: op.children[op.children.index(lo1)] = lo2 self.remove_lo(lo1) self.add_lo(lo2)
def remove_compartment(self, compartment): """Removes a compartment from the map Also sets the compartment attribute of the entity pools belonging to this compartment to None. :param compartment: the compartment to be removed """ if isinstance(compartment, str): parser = Parser() compartment = parser.compartment.parseString(compartment)[0] self.compartments.remove(compartment) for entity in self.entities: if hasattr(entity, "compartment") and entity.compartment == compartment: entity.compartment = None
def remove_process(self, process): """Removes a process from the map Also removes the modulations targetting this process. :param process: the process to be removed """ if isinstance(process, str): parser = Parser() process = parser.process.parseString(process)[0] to_remove = [] for modulation in self.modulations: if modulation.target == process: to_remove.append(modulation) for modulation in to_remove: self.remove_modulation(modulation) self.processes.remove(process)
def add_entity(self, entity): """Adds an entity pool to the map Also recursively adds the compartment if it does not already belong to the map. :param entity: the entity to be added (object or sbgntxt string) """ if isinstance(entity, str): parser = Parser() entity = parser.entity.parseString(entity)[0] if entity not in self.entities: self.entities.append(entity) if hasattr(entity, "compartment") and entity.compartment: existent_compartment = self.get_compartment( entity.compartment, by_compartment=True) if existent_compartment: entity.compartment = existent_compartment else: self.add_compartment(entity.compartment)
def remove_modulation(self, modulation): """Removes a modulation from the map Also removes its source if it is a logical operator that is not the child of another operator or the source of another modulation. :param modulation: the modulation to be removed """ if isinstance(modulation, str): parser = Parser() modulation = parser.modulation.parseString(modulation)[0] self.modulations.remove(modulation) # no orphan logical operator if isinstance(modulation.source, LogicalOperator): # we don't remove the lo if it is the source of another modulation for mod in self.modulations: if mod.source == modulation.source: return # we don't remove the lo if it belongs to another logical function for lo in self.los: if modulation.source in lo.children: return self.remove_lo(modulation.source)
def remove_entity(self, entity): """Removes an entity pool from the map Also removes the processes consuming or producing this entity pool, an the modulations departing from it. :param entity: the entity pool to be removed """ if isinstance(entity, str): parser = Parser() entity = parser.entity.parseString(entity)[0] toremove = [] for process in self.processes: if entity in process.reactants or entity in process.products: toremove.append(process) for process in toremove: self.remove_process(process) toremove = [] for modulation in self.modulations: if modulation.source == entity: toremove.append(modulation) for modulation in toremove: self.remove_modulation(modulation) self.entities.remove(entity)
def get_lo(self, val, by_lo=False, by_id=False, by_string=False): """Retrieves a logical operator from the map Possible ways of searching for the logical operator: by object, id, hash or sbgntxt string. Only the first matching logical operator is retrieved. Returns None if no matching logical operator is found. :param val: the value to be searched :param by_lo: if True, search by object :param by_id: if True, search by id :param by_string: if True, search by sbgntxt string :return: the unit of information or None """ if by_string: parser = Parser() val = parser.lo.parseString(val)[0] for o in self.los: if by_lo or by_string: if o == val: return o if by_id: if o.id == val: return o return None