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; }
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; }
// Some cycles with query features can be aromatized bool QueryMoleculeAromatizer::_aromatizeBondsExact (QueryMolecule &qmol, const AromaticityOptions &options) { bool aromatized = false; QueryMoleculeAromatizer aromatizer(qmol, options); aromatizer.setMode(QueryMoleculeAromatizer::EXACT); aromatizer.precalculatePiLabels(); aromatizer.aromatize(); for (int e_idx = qmol.edgeBegin(); e_idx < qmol.edgeEnd(); e_idx = qmol.edgeNext(e_idx)) if (aromatizer.isBondAromatic(e_idx)) { AutoPtr<QueryMolecule::Bond> bond(qmol.releaseBond(e_idx)); bond->removeConstraints(QueryMolecule::BOND_ORDER); AutoPtr<QueryMolecule::Bond> arom_bond( new QueryMolecule::Bond(QueryMolecule::BOND_ORDER, BOND_AROMATIC)); qmol.resetBond(e_idx, QueryMolecule::Bond::und(bond.release(), arom_bond.release())); aromatized = true; } return aromatized; }
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; }