示例#1
0
文件: sample.cpp 项目: ASKCOS/rdkit
void CleanupMolecule() {
  // an example of doing some cleaning up of a molecule before
  // calling the sanitizeMol function()

  // build: C1CC1C(:O):O
  RWMol *mol = new RWMol();

  // add atoms and bonds:
  mol->addAtom(new Atom(6));           // atom 0
  mol->addAtom(new Atom(6));           // atom 1
  mol->addAtom(new Atom(6));           // atom 2
  mol->addAtom(new Atom(6));           // atom 3
  mol->addAtom(new Atom(8));           // atom 4
  mol->addAtom(new Atom(8));           // atom 5
  mol->addBond(3, 4, Bond::AROMATIC);  // bond 0
  mol->addBond(3, 5, Bond::AROMATIC);  // bond 1
  mol->addBond(3, 2, Bond::SINGLE);    // bond 2
  mol->addBond(2, 1, Bond::SINGLE);    // bond 3
  mol->addBond(1, 0, Bond::SINGLE);    // bond 4
  mol->addBond(0, 2, Bond::SINGLE);    // bond 5

  // instead of calling sanitize mol, which would generate an error,
  // we'll perceive the rings, then take care of aromatic bonds
  // that aren't in a ring, then sanitize:
  MolOps::findSSSR(*mol);
  for (ROMol::BondIterator bondIt = mol->beginBonds();
       bondIt != mol->endBonds(); ++bondIt) {
    if (((*bondIt)->getIsAromatic() ||
         (*bondIt)->getBondType() == Bond::AROMATIC) &&
        !mol->getRingInfo()->numBondRings((*bondIt)->getIdx())) {
      // remove the aromatic flag on the bond:
      (*bondIt)->setIsAromatic(false);
      // and cleanup its attached atoms as well (they were
      // also marked aromatic when the bond was added)
      (*bondIt)->getBeginAtom()->setIsAromatic(false);
      (*bondIt)->getEndAtom()->setIsAromatic(false);

      // NOTE: this isn't really reasonable:
      (*bondIt)->setBondType(Bond::SINGLE);
    }
  }

  // now it's safe to sanitize:
  RDKit::MolOps::sanitizeMol(*mol);

  // Get the canonical SMILES, include stereochemistry:
  std::string smiles;
  smiles = MolToSmiles(*(static_cast<ROMol *>(mol)), true);
  BOOST_LOG(rdInfoLog) << " fixed SMILES: " << smiles << std::endl;
}
示例#2
0
int setAromaticity(RWMol &mol) {
  // FIX: we will assume for now that if the input molecule came
  // with aromaticity information it is correct and we will not
  // touch it. Loop through the atoms and check if any atom has
  // arom stuff set.  We may want check this more carefully later
  // and start from scratch if necessary
  ROMol::AtomIterator ai;
  for (ai = mol.beginAtoms(); ai != mol.endAtoms(); ai++) {
    if ((*ai)->getIsAromatic()) {
      // found aromatic info
      return -1;
    }
  }

  // first find the all the simple rings in the molecule
  VECT_INT_VECT srings;
  if (mol.getRingInfo()->isInitialized()) {
    srings = mol.getRingInfo()->atomRings();
  } else {
    MolOps::symmetrizeSSSR(mol, srings);
  }

  int narom = 0;
  // loop over all the atoms in the rings that can be candidates
  // for aromaticity
  // Atoms are candidates if
  //   - it is part of ring
  //   - has one or more electron to donate or has empty p-orbitals
  int natoms = mol.getNumAtoms();
  boost::dynamic_bitset<> acands(natoms);
  boost::dynamic_bitset<> aseen(natoms);
  VECT_EDON_TYPE edon(natoms);

  VECT_INT_VECT cRings;  // holder for rings that are candidates for aromaticity
  for (VECT_INT_VECT_I vivi = srings.begin(); vivi != srings.end(); ++vivi) {
    bool allAromatic = true;
    for (INT_VECT_I ivi = (*vivi).begin(); ivi != (*vivi).end(); ++ivi) {
      if (aseen[*ivi]) {
        if (!acands[*ivi]) allAromatic = false;
        continue;
      }
      aseen[*ivi] = 1;
      Atom *at = mol.getAtomWithIdx(*ivi);

      // now that the atom is part of ring check if it can donate
      // electron or has empty orbitals. Record the donor type
      // information in 'edon' - we will need it when we get to
      // the Huckel rule later
      edon[*ivi] = getAtomDonorTypeArom(at);
      acands[*ivi] = isAtomCandForArom(at, edon[*ivi]);
      if (!acands[*ivi]) allAromatic = false;
    }
    if (allAromatic) {
      cRings.push_back((*vivi));
    }
  }

  // first convert all rings to bonds ids
  VECT_INT_VECT brings;
  RingUtils::convertToBonds(cRings, brings, mol);

  // make the neighbor map for the rings
  // i.e. a ring is a neighbor a another candidate ring if
  // shares at least one bond
  // useful to figure out fused systems
  INT_INT_VECT_MAP neighMap;
  RingUtils::makeRingNeighborMap(brings, neighMap, maxFusedAromaticRingSize);

  // now loop over all the candidate rings and check the
  // huckel rule - of course paying attention to fused systems.
  INT_VECT doneRs;
  int curr = 0;
  int cnrs = rdcast<int>(cRings.size());
  boost::dynamic_bitset<> fusDone(cnrs);
  INT_VECT fused;
  while (curr < cnrs) {
    fused.resize(0);
    RingUtils::pickFusedRings(curr, neighMap, fused, fusDone);
    applyHuckelToFused(mol, cRings, brings, fused, edon, neighMap, narom, 6);

    int rix;
    for (rix = 0; rix < cnrs; rix++) {
      if (!fusDone[rix]) {
        curr = rix;
        break;
      }
    }
    if (rix == cnrs) {
      break;
    }
  }

  mol.setProp(common_properties::numArom, narom, true);

  return narom;
}