Ignore:
Timestamp:
Oct 28, 2022, 7:23:01 AM (3 years ago)
Author:
Frederik Heber <frederik.heber@…>
Branches:
Candidate_v1.7.0, stable
Children:
80bf6e
Parents:
1d9586
git-author:
Frederik Heber <frederik.heber@…> (10/25/22 16:00:09)
git-committer:
Frederik Heber <frederik.heber@…> (10/28/22 07:23:01)
Message:

Graph6Writer::write_elementlist uses least connected non-hydrogen.

  • this should enforce outermost atom in linear chain.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Graph/Graph6Writer.cpp

    r1d9586 r78e5cf  
    125125
    126126/**
    127  * Picks a non-hydrogen from all hydrogen atoms in the current set
    128  * of atoms.
     127 * Picks a non-hydrogen from all atoms in the current set of atoms
     128 * with lowest non-hydrogen bonds.
    129129 *
    130130 * Returns -1 if none could be found.
     
    132132atomId_t Graph6Writer::getBoundaryNonHydrogen() const {
    133133  atomId_t start_atom_id = -1;
    134   int bond_degree = 16;
     134  int lowest_non_hydrogen_count = 16;
    135135  for(std::vector<const atom *>::const_iterator iter = _atoms.begin();
    136136      iter != _atoms.end(); ++iter) {
    137137    const atom *walker = *iter;
    138     if (walker->getElement().getSymbol() == "H") {
     138    if (walker->getElement().getSymbol() != "H") {
    139139      const BondList& bond_list = walker->getListOfBonds();
    140       assert(bond_list.size() == 1);
    141       const atom *other = bond_list.front().get()->GetOtherAtom(walker);
    142       const int number_of_bonds = other->getListOfBonds().size();
    143       if ((other->getElement().getSymbol() != "H") && (bond_degree > number_of_bonds)) {
    144         start_atom_id = other->getId();
    145         bond_degree = number_of_bonds;
     140      int number_of_non_hydrogen_bonds = 0;
     141      for (BondList::const_iterator iter = bond_list.begin();
     142        iter != bond_list.end(); ++iter) {
     143        number_of_non_hydrogen_bonds += (*iter)->GetOtherAtom(walker)->getElement().getSymbol() != "H";
    146144      }
    147     }
     145      if (lowest_non_hydrogen_count > number_of_non_hydrogen_bonds) {
     146        start_atom_id = walker->getId();
     147        lowest_non_hydrogen_count = number_of_non_hydrogen_bonds;
     148      }
     149    }
     150  }
     151  if ((start_atom_id == -1) && (!_atoms.empty())) {
     152    // we only have hydrogens, just pick the first
     153    start_atom_id = (*_atoms.begin())->getId();
    148154  }
    149155  return start_atom_id;
     
    162168   * (e.g., BW having 123<->321 but not 123<->132 symmetry).
    163169   */
     170  const World& world = World::getConstInstance();
    164171  // pick bond neighbor of a hydrogen atom
    165172  atomId_t start_atom_id = getBoundaryNonHydrogen();
     
    168175    start_atom_id = _atoms.front()->getId();
    169176  }
     177  const atom* start_atom = world.getAtom(AtomById(start_atom_id));
     178  LOG(1, "INFO: Start atom is " << *start_atom << ".");
    170179
    171180  // do an unlimited BFS and get set of nodes, ordered by discovery level
     
    173182  graphCreator.createFromAtoms(_atoms, OnlyNonHydrogens);
    174183  BreadthFirstSearchGatherer gatherer(graphCreator);
    175   const std::vector<atomId_t> gathered_atoms = gatherer(start_atom_id);
    176 
    177   // print all nodes
    178   const World& world = World::getConstInstance();
    179   for (std::vector<atomId_t>::const_iterator iter = gathered_atoms.begin();
    180       iter != gathered_atoms.end(); ++iter) {
    181     if (iter != gathered_atoms.begin())
    182       out << ' ';
    183     const atom* walker = world.getAtom(AtomById(*iter));
    184     assert(walker != NULL);
    185     out << walker->getElement().getSymbol();
    186   }
    187 }
    188 
     184  gatherer(start_atom_id);
     185
     186  // go through distance map and print sorted by discovery level
     187  const BreadthFirstSearchGatherer::distance_map_t &distances = gatherer.getDistances();
     188  using pairtype = std::pair<atomId_t, size_t>;
     189  const size_t max_distance = std::max_element(distances.begin(), distances.end(), [] (const pairtype & p1, const pairtype & p2) {
     190    return p1.second < p2.second;
     191  })->second;
     192  bool isFirst = true;
     193  /**
     194   * This is O(N^2) and a stupid implementation. However, we only intend to
     195   * use this for small molecules, so I don't care at the moment. The better
     196   * approach is to revert the map into a multimap and then traverse that.
     197   */
     198  for (size_t i=0; i<= max_distance; ++i) {
     199    for (BreadthFirstSearchGatherer::distance_map_t::const_iterator iter = distances.begin();
     200        iter != distances.end(); ++iter) {
     201      if (iter->second != i)
     202        continue;
     203      const atom* walker = world.getAtom(AtomById(iter->first));
     204      assert(walker != NULL);
     205      LOG(1, "INFO: Gathered atom " << *walker);
     206      if (!isFirst)
     207        out << ' ';
     208      isFirst = false;
     209      out << walker->getElement().getSymbol();
     210    }
     211  }
     212}
     213
Note: See TracChangeset for help on using the changeset viewer.