예제 #1
0
bool AromaticityMatcher::isNecessary (QueryMolecule &query)
{
   for (int e = query.edgeBegin(); e < query.edgeEnd(); e = query.edgeNext(e))
   {
      if (!query.aromaticity.canBeAromatic(e))
         continue;

      QueryMolecule::Bond &bond = query.getBond(e);
      // Check if bond isn't aromatic but can be aromatic
      if (bond.possibleValue(QueryMolecule::BOND_ORDER, BOND_SINGLE))
         return true; 
      if (bond.possibleValue(QueryMolecule::BOND_ORDER, BOND_DOUBLE))
         return true;
   }

   // Check R-groups
   MoleculeRGroups &rgroups = query.rgroups;
   int n_rgroups = rgroups.getRGroupCount();
   for (int i = 1; i <= n_rgroups; i++)
   {
      PtrPool<BaseMolecule> &frags = rgroups.getRGroup(i).fragments;

      for (int j = frags.begin(); j != frags.end(); j = frags.next(j))
      {
         QueryMolecule &fragment = frags[j]->asQueryMolecule();
         if ( AromaticityMatcher::isNecessary(fragment))
            return true;
      }
   }

   return false;
}
예제 #2
0
bool QueryMoleculeAromatizer::_aromatizeBondsFuzzy (QueryMolecule &mol, const AromaticityOptions &options)
{
   bool aromatized = false;
   QueryMoleculeAromatizer aromatizer(mol, options);

   aromatizer.setMode(QueryMoleculeAromatizer::FUZZY);
   aromatizer.precalculatePiLabels();
   aromatizer.aromatize();

   mol.aromaticity.clear();
   for (int e_idx = mol.edgeBegin(); e_idx < mol.edgeEnd(); e_idx = mol.edgeNext(e_idx))
   {
      bool aromatic_constraint = 
         mol.getBond(e_idx).possibleValue(QueryMolecule::BOND_ORDER, BOND_AROMATIC);
      if (aromatic_constraint || aromatizer.isBondAromatic(e_idx))
      {
         mol.aromaticity.setCanBeAromatic(e_idx, true);
         aromatized = true;
      }
   }
   return aromatized;
}
예제 #3
0
bool QueryMoleculeAromatizer::_aromatizeBonds (QueryMolecule &mol, int additional_atom, const AromaticityOptions &options)
{
   bool aromatized = false;
   // Mark edges that can be aromatic in some matching
   aromatized |= _aromatizeBondsFuzzy(mol, options);
   // Aromatize all aromatic cycles
   aromatized |= _aromatizeBondsExact(mol, options);

   MoleculeRGroups &rgroups = mol.rgroups;
   int n_rgroups = rgroups.getRGroupCount();

   // Check if r-groups are attached with single bonds
   QS_DEF(Array<bool>, rgroups_attached_single);
   rgroups_attached_single.clear();
   for (int v = mol.vertexBegin(); v != mol.vertexEnd(); v = mol.vertexNext(v))
   {
      if (v == additional_atom)
         continue;
      if (mol.isRSite(v))
      {
         // Check if neighbor bonds are single
         const Vertex &vertex = mol.getVertex(v);
         for (int nei = vertex.neiBegin(); nei != vertex.neiEnd(); nei = vertex.neiNext(nei))
         {
            int edge = vertex.neiEdge(nei);
            QueryMolecule::Bond &bond = mol.getBond(edge);

            // DP TODO: implement smth. like Node::possibleOtherValueExcept() ...

            bool can_be_double = bond.possibleValue(QueryMolecule::BOND_ORDER, BOND_DOUBLE);
            bool can_be_triple = bond.possibleValue(QueryMolecule::BOND_ORDER, BOND_TRIPLE);
            bool can_be_arom = bond.possibleValue(QueryMolecule::BOND_ORDER, BOND_AROMATIC);
            if (can_be_double || can_be_triple || can_be_arom)
            {
               QS_DEF(Array<int>, sites);

               mol.getAllowedRGroups(v, sites);
               for (int j = 0; j < sites.size(); j++)
               {
                  rgroups_attached_single.expandFill(sites[j] + 1, true);
                  rgroups_attached_single[sites[j]] = false;
               }
            }
         }
      }
   }

   rgroups_attached_single.expandFill(n_rgroups + 1, true);
   for (int i = 1; i <= n_rgroups; i++)
   {
      PtrPool<BaseMolecule> &frags = rgroups.getRGroup(i).fragments;

      for (int j = frags.begin(); j != frags.end(); j = frags.next(j))
      {
         QueryMolecule &fragment = frags[j]->asQueryMolecule();

         aromatized |= _aromatizeRGroupFragment(fragment, rgroups_attached_single[i], options);
      }
   }
   return aromatized;
}
예제 #4
0
bool MoleculePiSystemsMatcher::_fixBonds (QueryMolecule &query, const int *mapping)
{
   for (int e = query.edgeBegin(); 
           e != query.edgeEnd(); 
           e = query.edgeNext(e))
   {
      const Edge &query_edge = query.getEdge(e);
      if (mapping[query_edge.beg] < 0 || mapping[query_edge.end] < 0)
         continue; // Edges connected with ignored vertices

      int target_edge = Graph::findMappedEdge(query, _target, e, mapping);
      const Edge &edge = _target.getEdge(target_edge);

      int p1_idx = _atom_pi_system_idx[edge.beg];
      int p2_idx = _atom_pi_system_idx[edge.end];
      if (p1_idx == _NOT_IN_PI_SYSTEM || p2_idx == _NOT_IN_PI_SYSTEM || p1_idx != p2_idx)
         continue;

      if (!_pi_systems[p1_idx].initialized)
         throw Error("pi-system must be initialized here");

      _Pi_System &pi_system = _pi_systems[p1_idx];

      int pi_sys_edge = Graph::findMappedEdge(_target, pi_system.pi_system, 
         target_edge, pi_system.inv_mapping.ptr());

      // Get target topology
      int topology = _target.getBondTopology(target_edge);

      QueryMolecule::Bond &qbond = query.getBond(e);

      bool can_be_single = qbond.possibleValuePair(
         QueryMolecule::BOND_ORDER, BOND_SINGLE,
         QueryMolecule::BOND_TOPOLOGY, topology);
      bool can_be_double = qbond.possibleValuePair(
         QueryMolecule::BOND_ORDER, BOND_DOUBLE,
         QueryMolecule::BOND_TOPOLOGY, topology);
      bool can_be_triple = qbond.possibleValuePair(
         QueryMolecule::BOND_ORDER, BOND_TRIPLE,
         QueryMolecule::BOND_TOPOLOGY, topology);

      if (!can_be_single && !can_be_double && !can_be_triple)
         return false;
      if (can_be_single && can_be_double && can_be_triple)
         continue;

      bool ret = false; // initializing to avoid compiler warning
      if (can_be_single && can_be_double)
         // Here can_be_triple = false because of previous check
         ret = pi_system.localizer->fixBondSingleDouble(pi_sys_edge);
      else
      {
         if (can_be_triple)
         {
            if (can_be_single)
               throw Error("Unsupported bond order specified (can be single or triple)");
            else if (can_be_double)
               throw Error("Unsupported bond order specified (can be double or triple)");
            ret = pi_system.localizer->fixBond(pi_sys_edge, BOND_TRIPLE);
         }
         if (can_be_single)
            ret = pi_system.localizer->fixBond(pi_sys_edge, BOND_SINGLE);
         if (can_be_double)
            ret = pi_system.localizer->fixBond(pi_sys_edge, BOND_DOUBLE);
      }

      if (!ret)
         return false;
   }

   return true;
}