Esempio n. 1
0
    def _C_ordered_bases(self):
        """
        [compute method for self.ordered_bases]
        Return our two bases (as Base5_recognizer objects, which may or may not be .in_helix),
        in an order consistent with backbone bond direction,
        which we require to be locally defined in a consistent way.

        @warning: value will be None (not a sequence) if a RecognizerError was
                  raised.
        """
        if self.unordered_bases is None:
            raise RecognizerError("doesn't have two bases")
        bases = list(
            self.unordered_bases
        )  # we might destructively reverse this later, before returning it
        nn = bases[0].atom, bases[1].atom
        # reverse bases if bond directions go backwards, or complain if not defined or not consistent
        # (Note: the following code is mostly generic for pairs of directional bonds,
        #  so we might package it up into a utility function someday.)

        # BTW, in the future we should improve this as follows:
        # - find directional-bond strands in both directions, including at least one bond not altered
        #   when making/unmaking a crossover, and ending on the first bond with direction defined,
        #   or when you have to end due to error (too far away to stop us) or end of strand.
        # - require that this gave you a direction and was not inconsistent.
        # - when making the crossover later, actually set all those directions you passed over
        #   (not just those of your new bonds).
        dir1 = bond_direction(nn[0], self.atom)  # -1 or 0 or 1
        dir2 = bond_direction(self.atom, nn[1])
        dirprod = dir1 * dir2
        if dirprod < 0:
            # both directions are set, and they're inconsistent
            raise RecognizerError("inconsistent bond directions")
            # including self.atom in the message would be redundant -- compute method glue will annotate with self ###DOIT
        elif dirprod > 0:
            # both directions are set, consistently
            if dir1 < 0:
                bases.reverse()
        else:  # dirprod == 0
            # at most one direction is set (need a warning if one is set and one not? assume not, for now)
            dir = dir1 + dir2
            if dir < 0:
                bases.reverse()
            elif dir == 0:
                # both directions are unset
                raise RecognizerError(
                    "backbone bond direction is locally undefined")
                ###REVIEW: this should not prevent offering "Make Crossover", only doing it successfully.
        return bases
    def _filter_neighbor_atompairs(self, atom_dict):
        """
        @see: self._find_crossover_atompairs_between_atom_dicts()
        """
        new_atom_dict = {}
        atomPairsList = []
        for atm in atom_dict.values():
            for neighbor in atm.neighbors():
                if atom_dict.has_key(id(neighbor)):
                    if self._final_crossover_atoms_dict.has_key(id(atm)) and \
                       self._final_crossover_atoms_dict.has_key(id(neighbor)):
                        continue #skip this iteration

                    if self.graphicsMode.DEBUG_DRAW_ALL_POTENTIAL_CROSSOVER_SITES:
                        if not new_atom_dict.has_key(id(neighbor)):
                            new_atom_dict[id(neighbor)] = neighbor
                        if not new_atom_dict.has_key(id(atm)):
                            new_atom_dict[id(atm)] = atm

                    #@@BUG: What if both neighbors of atm are in atom_dict_1??
                    #In that case, this code creates two separate tuples with
                    #'atm' as a common atom in each.
                    #MAKE SURE TO append atoms in the same order as
                    #their bond_direction. Example, if the bond is atm --> neighbor
                    #append them as (atm, neighbor) . If bond is from
                    #neighbor > atm, append them as (neighbor, atm).
                    #Possible BUG: This method DOES NOT handle case with
                    #bond_direction = 0 (simply assumes a random order)
                    if bond_direction(atm, neighbor) == - 1:
                        atomPairsList.append((neighbor, atm))
                    else:
                        atomPairsList.append((atm, neighbor))

        return new_atom_dict, atomPairsList
Esempio n. 3
0
    def _filter_neighbor_atompairs(self, atom_dict):
        """
        @see: self._find_crossover_atompairs_between_atom_dicts()
        """
        new_atom_dict = {}
        atomPairsList = []
        for atm in atom_dict.values():
            for neighbor in atm.neighbors():
                if atom_dict.has_key(id(neighbor)):
                    if self._final_crossover_atoms_dict.has_key(id(atm)) and \
                       self._final_crossover_atoms_dict.has_key(id(neighbor)):
                        continue  #skip this iteration

                    if self.graphicsMode.DEBUG_DRAW_ALL_POTENTIAL_CROSSOVER_SITES:
                        if not new_atom_dict.has_key(id(neighbor)):
                            new_atom_dict[id(neighbor)] = neighbor
                        if not new_atom_dict.has_key(id(atm)):
                            new_atom_dict[id(atm)] = atm

                    #@@BUG: What if both neighbors of atm are in atom_dict_1??
                    #In that case, this code creates two separate tuples with
                    #'atm' as a common atom in each.
                    #MAKE SURE TO append atoms in the same order as
                    #their bond_direction. Example, if the bond is atm --> neighbor
                    #append them as (atm, neighbor) . If bond is from
                    #neighbor > atm, append them as (neighbor, atm).
                    #Possible BUG: This method DOES NOT handle case with
                    #bond_direction = 0 (simply assumes a random order)
                    if bond_direction(atm, neighbor) == -1:
                        atomPairsList.append((neighbor, atm))
                    else:
                        atomPairsList.append((atm, neighbor))

        return new_atom_dict, atomPairsList
Esempio n. 4
0
    def _C_ordered_bases(self):
        """
        [compute method for self.ordered_bases]
        Return our two bases (as Base5_recognizer objects, which may or may not be .in_helix),
        in an order consistent with backbone bond direction,
        which we require to be locally defined in a consistent way.

        @warning: value will be None (not a sequence) if a RecognizerError was
                  raised.
        """
        if self.unordered_bases is None:
            raise RecognizerError("doesn't have two bases")
        bases = list(self.unordered_bases) # we might destructively reverse this later, before returning it
        nn = bases[0].atom, bases[1].atom
        # reverse bases if bond directions go backwards, or complain if not defined or not consistent
        # (Note: the following code is mostly generic for pairs of directional bonds,
        #  so we might package it up into a utility function someday.)

        # BTW, in the future we should improve this as follows:
        # - find directional-bond strands in both directions, including at least one bond not altered
        #   when making/unmaking a crossover, and ending on the first bond with direction defined,
        #   or when you have to end due to error (too far away to stop us) or end of strand.
        # - require that this gave you a direction and was not inconsistent.
        # - when making the crossover later, actually set all those directions you passed over
        #   (not just those of your new bonds).
        dir1 = bond_direction(nn[0], self.atom) # -1 or 0 or 1
        dir2 = bond_direction(self.atom, nn[1])
        dirprod = dir1 * dir2
        if dirprod < 0:
            # both directions are set, and they're inconsistent
            raise RecognizerError("inconsistent bond directions")
                # including self.atom in the message would be redundant -- compute method glue will annotate with self ###DOIT
        elif dirprod > 0:
            # both directions are set, consistently
            if dir1 < 0:
                bases.reverse()
        else: # dirprod == 0
            # at most one direction is set (need a warning if one is set and one not? assume not, for now)
            dir = dir1 + dir2
            if dir < 0:
                bases.reverse()
            elif dir == 0:
                # both directions are unset
                raise RecognizerError("backbone bond direction is locally undefined")
                    ###REVIEW: this should not prevent offering "Make Crossover", only doing it successfully.
        return bases