def _validate_arguments_to_add_state(self, ms, m_name): """ makes sure the add_motif function is called correctly :param m: motif to add to tree :type m: Motif object :param m_name: name of motif to add :type m_name: str :return: None """ if ms is not None and m_name is not None: raise exceptions.MotifStateTreeException( "cannot supply both a state and motif name to add a state to " "a motif state tree") if ms is None and m_name is None: raise exceptions.MotifStateTreeException( "must supply a motif state object or motif name to add_state") if ms is not None: for n in self.tree.nodes: if n.data.ref_state.uuid == ms.uuid: raise exceptions.MotifStateTreeException( "cannot add state: " + ms.name + " to tree as its uuid is " + "already present in the tree")
def add_mst(self, mst, parent_index=-1, parent_end_index=-1, parent_end_name=None): parent = self._get_parent_node(parent_index) parent_avail_ends = self._get_parent_available_ends( parent, parent_end_index, parent_end_name) if len(parent_avail_ends) > 1 or len(parent_avail_ends) == 0: parent_end_index = -1 else: parent_end_index = parent_avail_ends[0] index_dict = {} for i, n in enumerate(mst): if i == 0: j = self.add_state(n.data.ref_state, parent_index, parent_end_index) else: ind = index_dict[n.parent_index()] pei = n.parent_end_index() j = self.add_state(n.data.ref_state, parent_index=ind, parent_end_index=pei) if j == -1: raise exceptions.MotifStateTreeException( "failed to add a state in add_mst to the current " "motif tree it is likely a steric clash, consider " "turning off sterics") index_dict[n.index] = j
def _get_state_from_manager(self, m_name, m_end_name): """ helper function for add_motif should not be called directly. calls resource manager to get motif to be added to tree by the name of the motif. :param m_name: name of the motif to add to the tree :type m_name: str :param m_end_name: name of the basepair end of the motif to align by. :type m_end_name: str """ try: if m_end_name is not None: state = rm.manager.get_state(name=m_name, end_name=m_end_name) else: state = rm.manager.get_state(name=m_name) except exceptions.ResourceManagerException as e: raise exceptions.MotifStateTreeException( "cannot add state to tree, state cannot be found in resource " "manager") return state
def get_node(self, i=None, uuid=None): if i is not None: return self.tree.get_node(i) elif uuid is not None: for n in self.tree: if n.data.cur_state.uuid == uuid: return n raise exceptions.MotifStateTreeException( "cannot find motif state with uuid")
def _get_connection_end(self, node, bp_name): node_end_index = -1 if bp_name != "": ei = node.data.get_end_index(name=bp_name) if not node.available_pos(ei): raise exceptions.MotifStateTreeException( "cannot add connection with " + str(node.index) + " and " "end name " + bp_name + " as this end is not available") if self.connections.in_connection(node.index, bp_name): raise exceptions.MotifStateTreeException( "cannot add connection with " + node.index + " and end " "name " + bp_name + " as this end is already in a " "connection") node_end_index = ei else: node_indexes = node.available_children_pos() node_indexes.remove(0) if len(node_indexes) > 1: raise exceptions.MotifStateTreeException( "cannot connect nodes " + str(node.index) + " its unclear " " which ends to attach") if len(node_indexes) == 0: raise exceptions.MotifStateTreeException( "cannot connect nodes " + str(node.index) + " there are " "no ends free ends to attach too") node_index_name = node.data.cur_state.end_names[node_indexes[0]] if self.connections.in_connection(node.index, node_index_name): raise exceptions.MotifStateTreeException( "cannot add connection with " + str(node.index) + " and end " "name " + node_index_name + " as this end is already in a " "connection") node_end_index = node_indexes[0] return node_end_index
def _get_parent_node(self, parent_index): """ gets node that serve as the parent of the current motif being added to the tree. :param parent_index: the tree index corresponding to the requested motif :type parent_index: int :return: tree node of parent :rtype: TreeNode """ parent = self.tree.last_node if parent_index != -1: try: parent = self.tree.get_node(parent_index) except exceptions.TreeIndexException: raise exceptions.MotifStateTreeException( "parent_index supplied: " + str(parent_index) + " does not " + "exist in current motif state tree") return parent
def _get_parent_available_ends(self, parent, parent_end_index, parent_end_name): """ Gets the available ends of the parent that the current motif can align to. If either parent_end_index or parent_end_name are specified, checks to see if that position is available. :param parent: the TreeNode of parent :type parent: TreeNode :param parent_end_index: which end this motif will be aligned to on parent :type parent_end_index: int :param parent_end_name: the name instead of the index of the end the current motif will align to :type parent_end_name: str :return: list of available parent end indexes that meet the specified constraints :rtype: list of ints """ if parent is None: return [] if parent_end_index != -1 and parent_end_name is not None: raise exceptions.MotifStateTreeException( "cannot supply parent_end_index and parent_end_name together") elif parent_end_name is not None: try: parent_end_index = parent.data.get_end_index( name=parent_end_name) except: raise exceptions.MotifStateTreeException( "cannot find parent_end_name: " + parent_end_name + " in " "parent motif: " + parent.data.name()) if parent_end_index == parent.data.block_end_add(): raise exceptions.MotifStateTreeException( "cannot add state: to tree as the parent_end_name" + " supplied is blocked see class MotifState") available = parent.available_pos(parent_end_index) if not available: raise exceptions.MotifStateTreeException( "cannot add state to tree as the end " + "you are trying to add it to is already filled or does " "not exist") if self.connections.in_connection(parent.index, parent_end_name): raise exceptions.MotifStateTreeException( "cannot add motif to tree as the end " + "you are trying to add it to is in a connection") return [parent_end_index] elif parent_end_index != -1: if parent_end_index == parent.data.block_end_add(): raise exceptions.MotifStateTreeException( "cannot add state: to tree as the parent_end_index" + " supplied is blocked see class MotifState") available = parent.available_pos(parent_end_index) if not available: raise exceptions.MotifStateTreeException( "cannot add state to tree as the end " + "you are trying to add it to is already filled or does " "not exist") parent_end_name = parent.data.cur_state.end_names[parent_end_index] if self.connections.in_connection(parent.index, parent_end_name): raise exceptions.MotifStateTreeException( "cannot add motif to tree as the end " + "you are trying to add it to is in a connection") return [parent_end_index] else: avail_pos = parent.available_children_pos() avail_pos.remove(0) final_avail_pos = [] for p in avail_pos: pen = parent.data.cur_state.end_names[p] if self.connections.in_connection(parent.index, pen): continue if p == parent.data.block_end_add: continue final_avail_pos.append(p) return final_avail_pos