Exemplo n.º 1
0
 def mark_aromatic_bonds(self):
     sssr = self.get_smallest_independent_cycles()
     if len(sssr) > 10:
         # turn off processing of all cycles - it would be too slow, just use SSSR
         rings = sssr
     else:
         rings = self.get_all_cycles(
         )  #self.get_smallest_independent_cycles()
     solved = [1]
     # we need to repeat it to mark such things as 'badly' drawn naphtalene (no double bond in the centre)
     while solved:
         solved = []
         for aring in rings:
             els = [
                 self._get_atoms_possible_aromatic_electrons(a, aring)
                 for a in aring
             ]
             if () in els:
                 continue
             for comb in common.gen_combinations_of_series(els):
                 if sum(comb) % 4 == 2:
                     bring = self.vertex_subgraph_to_edge_subgraph(aring)
                     for b in bring:
                         b.aromatic = 1
                         #b.order = 4
                     solved.append(aring)
                     break
         for r in solved:
             rings.remove(r)
Exemplo n.º 2
0
 def mark_aromatic_bonds( self):
   sssr = self.get_smallest_independent_cycles()
   if len( sssr) > 10:
     # turn off processing of all cycles - it would be too slow, just use SSSR
     rings = sssr
   else:
     rings = self.get_all_cycles()   #self.get_smallest_independent_cycles()
   solved = [1]
   # we need to repeat it to mark such things as 'badly' drawn naphtalene (no double bond in the centre) 
   while solved:
     solved = []
     for aring in rings:
       els = [self._get_atoms_possible_aromatic_electrons( a, aring) for a in aring]
       if () in els:
         continue
       for comb in common.gen_combinations_of_series( els):
         if sum( comb) % 4 == 2:
           bring = self.vertex_subgraph_to_edge_subgraph( aring)
           for b in bring:
             b.aromatic = 1
             #b.order = 4
           solved.append( aring)
           break
     for r in solved:
       rings.remove( r)
Exemplo n.º 3
0
    def localize_aromatic_bonds(self):
        """localizes aromatic bonds (does not relocalize already localized ones),
    for those that are not aromatic but marked so
    (it is for instance possible to misuse 'cccc' in smiles to create butadiene)
    they will be properly localized but marked as non-aromatic"""
        erings = self.get_smallest_independent_cycles_e()
        # filter off rings without aromatic bonds
        erings = filter(lambda x: len([b for b in x if b.aromatic]), erings)
        rings = map(self.edge_subgraph_to_vertex_subgraph, erings)
        # sort rings
        rings.sort(
            lambda x, y: len(y) % 2 - len(x) % 2)  # odd size rings first
        last_rings = []
        while rings:
            # we have to continue with the neighbor rings of the last_ring (or the rings before)
            intersection = None
            if last_rings:
                aring = None
                while last_rings:
                    last_ring = last_rings.pop(-1)
                    for ring in rings:
                        intersection = ring & last_ring
                        if intersection:
                            aring = ring
                            last_rings.append(last_ring)
                            break
                    if aring:
                        break
                if not aring:
                    aring = rings.pop(0)
                else:
                    rings.remove(aring)
            else:
                aring = rings.pop(0)
            last_rings.append(aring)
            # convert ring from set to list
            aring = self.sort_vertices_in_path(
                aring, start_from=intersection and intersection.pop() or None)
            # taken from mark_aromatic_bonds
            els = [
                self._get_atoms_possible_aromatic_electrons(a, aring)
                for a in aring
            ]
            if () in els:
                continue  # misuse of aromatic bonds (e.g. by smiles) or e.g. tetrahydronaphtalene
            for comb in common.gen_combinations_of_series(els):
                if sum(comb) % 4 == 2:
                    aring.append(aring[0])
                    comb.append(comb[0])
                    # at first we process the bonds that are surely single (like C-S-C in thiophene)
                    already_set = None
                    for i in range(len(aring) - 1):
                        if comb[i] + comb[i + 1] != 2:
                            # these bonds must be single
                            b = aring[i].get_edge_leading_to(aring[i + 1])
                            b.order = 1
                            already_set = i
                    if already_set != None:
                        # we reorder the comb and aring to start from the already set bonds
                        j = already_set + 1
                        aring = aring[j:len(aring)] + aring[1:j]
                        aring.insert(0, aring[-1])
                        comb = comb[j:len(comb)] + comb[1:j]
                        comb.insert(0, comb[-1])
                    i = 0
                    while i + 1 < len(aring):
                        if comb[i] + comb[i + 1] == 2:
                            b = aring[i].get_edge_leading_to(aring[i + 1])
                            assert b != None  # should be
                            # to assure alternating bonds
                            bs1 = [
                                bo for bo in aring[i].get_neighbor_edges()
                                if bo.order == 2 and bo.aromatic and bo != b
                            ]
                            bs2 = [
                                bo for bo in aring[i + 1].get_neighbor_edges()
                                if bo.order == 2 and bo.aromatic and bo != b
                            ]
                            if len(bs1) == 0 and len(bs2) == 0:
                                b.order = 2
                            else:
                                b.order = 1
                        i += 1
                    break

        self.localize_fake_aromatic_bonds()
Exemplo n.º 4
0
  def localize_aromatic_bonds( self):
    """localizes aromatic bonds (does not relocalize already localized ones),
    for those that are not aromatic but marked so
    (it is for instance possible to misuse 'cccc' in smiles to create butadiene)
    they will be properly localized but marked as non-aromatic"""
    erings = self.get_smallest_independent_cycles_e()
    # filter off rings without aromatic bonds
    erings = filter( lambda x: len( [b for b in x if b.aromatic]), erings)
    rings = map( self.edge_subgraph_to_vertex_subgraph, erings)
    # sort rings
    rings.sort( lambda x,y: len(y)%2 - len(x)%2) # odd size rings first
    last_rings = []
    while rings:
      # we have to continue with the neighbor rings of the last_ring (or the rings before)
      intersection = None
      if last_rings:
        aring = None
        while last_rings:
          last_ring = last_rings.pop( -1)
          for ring in rings:
            intersection = ring & last_ring
            if intersection:
              aring = ring
              last_rings.append( last_ring)
              break
          if aring:
            break
        if not aring:
          aring = rings.pop(0)
        else:
          rings.remove( aring)
      else:
        aring = rings.pop(0)
      last_rings.append( aring)
      # convert ring from set to list
      aring = self.sort_vertices_in_path( aring, start_from=intersection and intersection.pop() or None)
      # taken from mark_aromatic_bonds
      els = [self._get_atoms_possible_aromatic_electrons( a, aring) for a in aring]
      if () in els:
        continue  # misuse of aromatic bonds (e.g. by smiles) or e.g. tetrahydronaphtalene
      for comb in common.gen_combinations_of_series( els):
        if sum( comb) % 4 == 2:
          aring.append( aring[0])
          comb.append( comb[0])
          # at first we process the bonds that are surely single (like C-S-C in thiophene)
          already_set = None
          for i in range( len( aring) -1):
            if comb[i] + comb[i+1] != 2:
              # these bonds must be single
              b = aring[i].get_edge_leading_to( aring[i+1])
              b.order = 1
              already_set = i
          if already_set != None:
            # we reorder the comb and aring to start from the already set bonds
            j = already_set + 1
            aring = aring[j:len(aring)] + aring[1:j]
            aring.insert( 0, aring[-1])
            comb = comb[j:len(comb)] + comb[1:j]
            comb.insert( 0, comb[-1])
          i = 0
          while i+1 < len( aring):
            if comb[i] + comb[i+1] == 2:
              b = aring[i].get_edge_leading_to( aring[i+1])
              assert b != None # should be
              # to assure alternating bonds
              bs1 = [bo for bo in aring[i].get_neighbor_edges() if bo.order == 2 and bo.aromatic and bo!=b]
              bs2 = [bo for bo in aring[i+1].get_neighbor_edges() if bo.order == 2 and bo.aromatic and bo!=b]
              if len( bs1) == 0 and len( bs2) == 0:
                b.order = 2
              else:
                b.order = 1
            i += 1
          break

    self.localize_fake_aromatic_bonds()