コード例 #1
0
ファイル: MolDraw2DUtils.cpp プロジェクト: ASKCOS/rdkit
void prepareMolForDrawing(RWMol &mol, bool kekulize, bool addChiralHs,
                          bool wedgeBonds, bool forceCoords) {
  if (kekulize) {
    MolOps::Kekulize(mol, false);  // kekulize, but keep the aromatic flags!
  }
  if (addChiralHs) {
    std::vector<unsigned int> chiralAts;
    for (RWMol::AtomIterator atIt = mol.beginAtoms(); atIt != mol.endAtoms();
         ++atIt) {
      if ((*atIt)->getChiralTag() == Atom::CHI_TETRAHEDRAL_CCW ||
          (*atIt)->getChiralTag() == Atom::CHI_TETRAHEDRAL_CW) {
        chiralAts.push_back((*atIt)->getIdx());
      }
    }
    if (chiralAts.size()) {
      bool addCoords = false;
      if (!forceCoords && mol.getNumConformers()) addCoords = true;
      MolOps::addHs(mol, false, addCoords, &chiralAts);
    }
  }
  if (forceCoords || !mol.getNumConformers()) {
    RDDepict::compute2DCoords(mol);
  }
  if (wedgeBonds) {
    WedgeMolBonds(mol, &mol.getConformer());
  }
}
コード例 #2
0
ファイル: DepictorDLL.cpp プロジェクト: Acpharis/rdkit
  //*************************************************************************************
  //
  //  Adds 2D coordinates to a molecule using the Depict.dll
  //
  //  ARGUMENTS:
  //    mol:          the molecule to be altered
  //    tempFilename: (OPTIONAL) the name of the temporary file 
  //
  //  RETURNS:
  //   1 on success, 0 otherwise
  //
  //  Here's the process by which this works (it's kind of contorted):
  //   1) convert the mol to SMILES
  //   2) use the DLL to convert the SMILES to a mol file (on disk)
  //   3) parse the mol file into a temporary molecule
  //   4) do a substructure match from the old molecule to the
  //      temp one (which may have a different atom numbering or additional
  //      atoms added).
  //   5) Update the positions of the atoms on the old molecule.
  //   6) Free the temp molecule.
  //
  //  NOTES:
  //   - *FIX:* at the moment we're not doing anything to clear up the
  //     temp file created in this process.  It'll always have the same
  //     name unless the user explicitly asks that we do something different.
  //   - To use the DLL, it's essential that the COMBICHEM_ROOT and COMBICHEM_RELEASE
  //     environment variables be set.  If this isn't done, this whole process
  //     will fail.
  //   - See the notes above about failures when opening the DLL.
  //
  //*************************************************************************************
  int Add2DCoordsToMolDLL(ROMol &mol,std::string tempFilename){
    std::string smi=MolToSmiles(mol,true);
    int tmp = SmilesToMolFileDLL(smi,tempFilename);
    int res = -1;
    if(tmp){
      // build another mol from that mol file:
      RWMol *tmpMol = MolFileToMol(tempFilename,false);
      // match it up with the starting mol:
      //  (We need to do this because the depict.dll conversion
      //   to a mol file may have added Hs)
      MatchVectType matchVect;
      bool hasMatch=SubstructMatch(tmpMol,&mol,matchVect);
      if(hasMatch){
        const Conformer &conf = tmpMol->getCoformer(0);
        Coformer *nconf = new Coformer(mol.getNumAtoms());
	for(MatchVectType::const_iterator mvi=matchVect.begin();
	    mvi!=matchVect.end();mvi++){
	  
          nconf->setAtomPos(conf.getAtomPos(mvi->first));
	}
        confId = (int)mol.addConformer(nconf, true);
      }
      delete tmpMol;
    }
    return res;
  }
コード例 #3
0
ファイル: MinimizeCLI.cpp プロジェクト: Acpharis/rdkit
void runSDFile(std::string fileName,int checkEvery=10){
  SDMolSupplier suppl(fileName,false);
  
  RWMol *mol;

  mol = (RWMol *)suppl.next();
  while(mol){
    std::string name;
    mol->getProp("_Name",name);
    std::cerr << "Mol: " << name << std::endl;
    try{
      MolOps::sanitizeMol(*mol);
    } catch (...) {
      std::cerr << " sanitization failed" << std::endl;
      delete mol;
      mol = 0;
    }
    if(mol){
      ROMol *mol2=MolOps::addHs(*mol,false,true);
      delete mol;
      runMol(mol2,checkEvery,false);
      delete mol2;
    }
    mol = (RWMol *)suppl.next();

  }

}
コード例 #4
0
ファイル: MolFileStereochem.cpp プロジェクト: apahl/rdkit
// handles stereochem markers set by the Mol file parser and
// converts them to the RD standard:
void DetectAtomStereoChemistry(RWMol &mol, const Conformer *conf) {
    PRECONDITION(conf, "no conformer");

    // make sure we've calculated the implicit valence on each atom:
    for (RWMol::AtomIterator atomIt = mol.beginAtoms(); atomIt != mol.endAtoms();
            ++atomIt) {
        (*atomIt)->calcImplicitValence(false);
    }

    for (RWMol::BondIterator bondIt = mol.beginBonds(); bondIt != mol.endBonds();
            ++bondIt) {
        Bond *bond = *bondIt;
        if (bond->getBondDir() != Bond::UNKNOWN) {
            Bond::BondDir dir = bond->getBondDir();
            // the bond is marked as chiral:
            if (dir == Bond::BEGINWEDGE || dir == Bond::BEGINDASH) {
                Atom *atom = bond->getBeginAtom();
                if (atom->getImplicitValence() == -1) {
                    atom->calcExplicitValence();
                    atom->calcImplicitValence();
                }
                Atom::ChiralType code = FindAtomStereochemistry(mol, bond, conf);
                atom->setChiralTag(code);
                // within the RD representation, if a three-coordinate atom
                // is chiral and has an implicit H, that H needs to be made explicit:
                if (atom->getDegree() == 3 && !atom->getNumExplicitHs() &&
                        atom->getNumImplicitHs() == 1) {
                    atom->setNumExplicitHs(1);
                    // recalculated number of implicit Hs:
                    atom->updatePropertyCache();
                }
            }
        }
    }
}
コード例 #5
0
ファイル: testMol2ToMol.cpp プロジェクト: Acpharis/rdkit
void testIssue3399798(std::string rdbase){

  BOOST_LOG(rdInfoLog) << "---------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- testing issue 3399798             --" << std::endl;
  BOOST_LOG(rdInfoLog) << "---------------------------------------" << std::endl;

  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3399798.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag()==Atom::CHI_UNSPECIFIED);
    TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag()==Atom::CHI_UNSPECIFIED);

    delete m;
  }

  {
    std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3399798.2.mol2";
    RWMol *m = Mol2FileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag()==Atom::CHI_UNSPECIFIED);
    TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag()!=Atom::CHI_UNSPECIFIED);

    delete m;
  }

  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- DONE                           --" << std::endl;
  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
}
コード例 #6
0
ファイル: testMol2ToMol.cpp プロジェクト: rdkit/rdkit
void testGithub438(std::string rdbase) {
  BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog)
      << "-- testing GitHub issue #438: problems with metals in mol2 files  --"
      << std::endl;
  BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl;

  {
    std::string fName =
        rdbase + "/Code/GraphMol/FileParsers/test_data/github438_1.mol2";
    RWMol *mol = Mol2FileToMol(fName);
    TEST_ASSERT(mol);
    TEST_ASSERT(mol->getAtomWithIdx(0)->getFormalCharge() == 1);
    delete mol;
  }
  {
    std::string fName =
        rdbase + "/Code/GraphMol/FileParsers/test_data/github438_2.mol2";
    RWMol *mol = Mol2FileToMol(fName);
    TEST_ASSERT(mol);
    TEST_ASSERT(mol->getAtomWithIdx(0)->getFormalCharge() == 2);
    delete mol;
  }
  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- DONE                           --" << std::endl;
  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
}
コード例 #7
0
void testGithubIssue429() 
{
  BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "Testing github issue 429: fragmentOnSomeBonds() should update implicit H count on aromatic heteroatoms when addDummies is False"<< std::endl;

  {
    std::string smi = "c1cccn1CC1CC1";
    RWMol *mol = SmilesToMol(smi);
    TEST_ASSERT(mol);
    TEST_ASSERT(mol->getNumAtoms());
    unsigned int indices[]={4,5};
    std::vector<unsigned int> bindices(indices,indices+(sizeof(indices)/sizeof(indices[0])));
    std::vector<ROMOL_SPTR> frags;
    MolFragmenter::fragmentOnSomeBonds(*mol,bindices,frags,1,false);
    TEST_ASSERT(frags.size()==2);
    std::vector<std::vector<int> > fragMap;
    
    BOOST_FOREACH(ROMOL_SPTR romol,frags){
      RWMol *rwmol=(RWMol *)(romol.get());
      MolOps::sanitizeMol(*rwmol);
    }

    // we actually changed fragmentOnBonds(), check that too:
    RWMol *nmol=(RWMol *)MolFragmenter::fragmentOnBonds(*mol,bindices,false);
    MolOps::sanitizeMol(*nmol);
    delete nmol;

    delete mol;
  }
コード例 #8
0
void testUFFBuilderSpecialCases(){
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing UFF special cases." << std::endl;

  RWMol *mol;
  std::string key;
  int needMore;
  RDGeom::Point3D v1,v2;
  ForceFields::ForceField *field;

  std::string pathName=getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data";
  // ----------
  //  Trigonal bipyramid
  // ----------
  mol = MolFileToMol(pathName+"/tbp.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);

  const Conformer &conf = mol->getConformer();
  field=UFF::constructForceField(*mol);
  TEST_ASSERT(field);
  field->initialize();
  needMore = field->minimize(200,1e-8,1e-4);
  TEST_ASSERT(!needMore);
  v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(1));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(2));
  TEST_ASSERT(feq(v1.dotProduct(v2),-1.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(3));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));

  v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(2));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(3));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5));
  TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3));

  v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4));
  TEST_ASSERT(feq(v1.dotProduct(v2),-0.5,1e-3));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5));
  TEST_ASSERT(feq(v1.dotProduct(v2),-0.5,1e-3));

  v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4));
  v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5));
  TEST_ASSERT(feq(v1.dotProduct(v2),-0.5,1e-3));

  
  delete mol;
  delete field;
  

  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
コード例 #9
0
ファイル: test1.cpp プロジェクト: janholstjensen/rdkit
void testPaths2() {
  std::cout << "-----------------------\n Path retrieval2" << std::endl;
  // build: CCC(C)CC
  RWMol mol;
  bool updateLabel = true;
  bool takeOwnership = true;
  mol.addAtom(new Atom(6), updateLabel, takeOwnership);
  mol.addAtom(new Atom(6), updateLabel, takeOwnership);
  mol.addAtom(new Atom(6), updateLabel, takeOwnership);
  mol.addAtom(new Atom(6), updateLabel, takeOwnership);
  mol.addBond(0, 1, Bond::SINGLE);
  mol.addBond(1, 2, Bond::SINGLE);
  mol.addBond(2, 3, Bond::SINGLE);
  mol.addBond(2, 0, Bond::SINGLE);

  //
  //  Retrieve using bonds
  //
  PATH_LIST tmp = findAllPathsOfLengthN(mol, 3);
  // std::cout << "\n3:" << std::endl;
  // dumpVIV(tmp);
  CHECK_INVARIANT(tmp.size() == 3, "");

  std::cout << "Finished" << std::endl;
}
コード例 #10
0
ファイル: MolDraw2DUtils.cpp プロジェクト: Richard-Hall/rdkit
void prepareMolForDrawing(RWMol &mol, bool kekulize, bool addChiralHs,
                          bool wedgeBonds, bool forceCoords) {
  if (kekulize) {
    MolOps::Kekulize(mol, false);  // kekulize, but keep the aromatic flags!
  }
  if (addChiralHs) {
    std::vector<unsigned int> chiralAts;
    for (RWMol::AtomIterator atIt = mol.beginAtoms(); atIt != mol.endAtoms();
         ++atIt) {
      if (isAtomCandForChiralH(mol, *atIt)) {
        chiralAts.push_back((*atIt)->getIdx());
      }
    }
    if (chiralAts.size()) {
      bool addCoords = false;
      if (!forceCoords && mol.getNumConformers()) addCoords = true;
      MolOps::addHs(mol, false, addCoords, &chiralAts);
    }
  }
  if (forceCoords || !mol.getNumConformers()) {
    // compute 2D coordinates in a standard orientation:
    const bool canonOrient = true;
    RDDepict::compute2DCoords(mol, NULL, canonOrient);
  }
  if (wedgeBonds) {
    WedgeMolBonds(mol, &mol.getConformer());
  }
}
コード例 #11
0
ファイル: testMIF.cpp プロジェクト: dfhahn/rdkit
void test4Coulomb () {
  std::string path = getenv("RDBASE");
  path += "/Code/GraphMol/MIF/test_data/";

  RWMol mol = *MolFileToMol(path + "HCl.mol", true, false);

  computeGasteigerCharges(mol);

  std::vector<double> charges;
  std::vector<Point3D> pos;
  Conformer conf = mol.getConformer(0);
  for (int i = 0; i < mol.getNumAtoms(); ++i) {
    charges.push_back(mol.getAtomWithIdx (i)->getProp<double> ("_GasteigerCharge"));
    pos.push_back(conf.getAtomPos(i));
  }

  UniformRealValueGrid3D grd = *constructGrid(mol);
  UniformRealValueGrid3D grd2 = *constructGrid(mol);

  Coulomb coul(mol);

  calculateDescriptors<Coulomb>(grd, coul);
  calculateDescriptors<Coulomb>(grd2, Coulomb (charges, pos));

  CHECK_INVARIANT(grd.compareGrids(grd2),
                  "Coulomb: Different constructors do not yield the same descriptor.");
  CHECK_INVARIANT(feq (coul(0.0,0.0,0.0, 1000), 0.0),
                  "Coulomb: Potential between atoms wrong.(should be 0)");
  CHECK_INVARIANT(coul(2.0,0.0,0.0, 1000) < 0,
                  "Coulomb: Potential between positive charges not positive.");
  CHECK_INVARIANT(coul(-2.0,0.0,0.0, 1000) > 0,
                  "Coulomb: Potential between positive and negative charges not negative.");
  CHECK_INVARIANT(feq(coul(0.0,0.0,0.0, 0.1), 0.0),
                  "Coulomb: Small threshold dist does not give 0.");
                  
  calculateDescriptors<Coulomb>(grd, Coulomb(mol, 0, 1.0, true));
  for (unsigned int i = 0; i < grd.getSize(); i++) {
    CHECK_INVARIANT(grd.getVal (i) <= 0.0, "Coulomb: Absolute value field not negative");
  }

Coulomb coul1(mol, 0, -1.0, false, "_GasteigerCharge", 0.0, 0.01);
  CHECK_INVARIANT(coul1(-2.0, 0.0, 0.0, 1000) < 0, "Coulomb: Potential between negative charges not positive.");
  CHECK_INVARIANT(coul1(2.0, 0.0, 0.0, 1000) > 0, "Coulomb: Potential between positive and negative charges not negative.");

  Coulomb coul2 = Coulomb(mol, 0, -.5, false, "_GasteigerCharge", 0.0, 0.01);
  CHECK_INVARIANT(coul1(-2.0, 0.0, 0.0, 1000) < coul2 (-2.0, 0.0, 0.0, 1000),
                  "Coulomb: Higher probecharge does not result in stronger forces.");

  Coulomb coul3(mol, 0, 1.0, false, "_GasteigerCharge", 0.01, 1.0);
  CHECK_INVARIANT(coul3(0.0, 0.0, 0.0, 1000) > coul3(0.1, 0.0, 0.0, 1000),
                  "Coulomb: Softcore interaction wrong.");
  CHECK_INVARIANT(coul3(0.66, 0.0, 0.0, 1000) > coul3(0.68, 0.0, 0.0, 1000),
                  "Coulomb: Softcore interaction wrong.");
  CHECK_INVARIANT(coul3(0.70, 0.0, 0.0, 1000) > coul3(0.68, 0.0, 0.0, 1000),
                  "Coulomb: Softcore interaction wrong.");
  CHECK_INVARIANT(feq(coul3(0.0,0.0,0.0, 0.1), 0.0),
                  "Coulomb: Small threshold dist does not give 0.");

}
コード例 #12
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;
}
コード例 #13
0
ファイル: test1.cpp プロジェクト: Acpharis/rdkit
void testGetSetBondLength() {
  std::string rdbase = getenv("RDBASE");
  std::string fName = rdbase + "/Code/GraphMol/MolTransforms/test_data/3-cyclohexylpyridine.mol";
  RWMol *m = MolFileToMol(fName, true, false);
  TEST_ASSERT(m);
  Conformer &conf = m->getConformer();
  double dist = getBondLength(conf, 0, 19);
  TEST_ASSERT(RDKit::feq(dist, 1.36));
  setBondLength(conf, 0, 19, 2.5);
  dist = getBondLength(conf, 0, 19);
  TEST_ASSERT(RDKit::feq(dist, 2.5));
  setBondLength(conf, 19, 0, 3.0);
  dist = getBondLength(conf, 0, 19);
  TEST_ASSERT(RDKit::feq(dist, 3.0));
}
コード例 #14
0
ファイル: Kekulize.cpp プロジェクト: giallu/rdkit
void kekulizeFused(RWMol &mol, const VECT_INT_VECT &arings,
                   unsigned int maxBackTracks) {
  // get all the atoms in the ring system
  INT_VECT allAtms;
  Union(arings, allAtms);

  // get all the atoms that are candidates to receive a double bond
  // also mark atoms in the fused system that are not aromatic to begin with
  // as done. Mark all the bonds that are part of the aromatic system
  // to be single bonds
  INT_VECT done;
  INT_VECT questions;
  unsigned int nats = mol.getNumAtoms();
  unsigned int nbnds = mol.getNumBonds();
  boost::dynamic_bitset<> dBndCands(nats);
  boost::dynamic_bitset<> dBndAdds(nbnds);

  markDbondCands(mol, allAtms, dBndCands, questions, done);
#if 0
      std::cerr << "candidates: ";
      for(int i=0;i<nats;++i) std::cerr << dBndCands[i];
      std::cerr << std::endl;
#endif

  bool kekulized;
  kekulized =
      kekulizeWorker(mol, allAtms, dBndCands, dBndAdds, done, maxBackTracks);
  if (!kekulized && questions.size()) {
    // we failed, but there are some dummy atoms we can try permuting.
    kekulized = permuteDummiesAndKekulize(mol, allAtms, dBndCands, questions,
                                          maxBackTracks);
  }
  if (!kekulized) {
    // we exhausted all option (or crossed the allowed
    // number of backTracks) and we still need to backtrack
    // can't kekulize this thing
    std::ostringstream errout;
    errout << "Can't kekulize mol.";
    errout << "  Unkekulized atoms:";
    for (unsigned int i = 0; i < nats; ++i) {
      if (dBndCands[i]) errout << " " << i;
    }
    errout << std::endl;
    std::string msg = errout.str();
    BOOST_LOG(rdErrorLog) << msg << std::endl;
    throw MolSanitizeException(msg);
  }
}
コード例 #15
0
ファイル: testFMCS_Unit.cpp プロジェクト: DoliathGavid/rdkit
void test504() {
  BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "Testing FMCS test504" << std::endl;
  std::cout << "\ntest504()\n";
  std::vector<ROMOL_SPTR> mols;
  const char* smi[] = {
      // TEST 504
      "C(CCNC(C1CC1[c:1]1[c:2]c(Cl)c(Cl)c[c:3]1)=O)CCN1CCC(NC(Nc2ccc(Cl)cc2)=O)"
      "C1 CHEMBL545864",  // - QUERY

      "FC(F)(F)c1cc(NC(N2CCCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)ccc1Cl "
      "CHEMBL528228",
      "FC(F)(F)c1cc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)C2)=O)ccc1Cl "
      "CHEMBL525875",
      "Fc1ccc(NC(N2CCCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)cc1C(F)(F)F "
      "CHEMBL527277",
      "FC(F)(F)c1cc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)ccc1Cl "
      "CHEMBL537333",
      "Fc1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)C2)=O)cc1C(F)(F)F "
      "CHEMBL588077",
      "FC(F)(F)c1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3cc(Cl)c(Cl)cc3)=O)C2)=O)cc1 "
      "CHEMBL525307",
      "Fc1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)cc1C(F)(F)F "
      "CHEMBL581847",
      "FC(F)(F)c1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3cc(Cl)c(Cl)cc3)=O)CC2)=O)cc1 "
      "CHEMBL579547",
      "N#Cc1cccc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)c1 "
      "CHEMBL529994",
  };
  RWMol* qm = SmilesToMol(getSmilesOnly(smi[0]));
  unsigned nq = qm->getNumAtoms();
  for (size_t ai = 0; ai < nq; ai++) {
    Atom* atom = qm->getAtomWithIdx(ai);
    atom->setProp("molAtomMapNumber", (int)ai);
  }
  std::cout << "Query +MAP " << MolToSmiles(*qm) << "\n";
  mols.push_back(ROMOL_SPTR(qm));  // with RING INFO
  for (size_t i = 1; i < sizeof(smi) / sizeof(smi[0]); i++)
    mols.push_back(
        ROMOL_SPTR(SmilesToMol(getSmilesOnly(smi[i]))));  // with RING INFO
  t0 = nanoClock();
  MCSResult res = findMCS(mols);
  std::cout << "MCS: " << res.SmartsString << " " << res.NumAtoms << " atoms, "
            << res.NumBonds << " bonds\n";
  printTime();
  TEST_ASSERT(res.NumAtoms == 34 && res.NumBonds == 36);
  BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
}
コード例 #16
0
ファイル: testMol2ToMol.cpp プロジェクト: Acpharis/rdkit
// Test the following GitHub issue: https://github.com/rdkit/rdkit/issues/114
void testIssue114(std::string rdbase) {

  BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- testing GitHub issue #114     --" << std::endl;
  BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl;

  std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/EZ_mol2_issue114.mol2";
  RWMol *mol = Mol2FileToMol(fName);
  TEST_ASSERT(mol);
  TEST_ASSERT(mol->getBondWithIdx(1)->getStereo() == Bond::STEREOZ);
  delete mol;
  
  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "-- DONE                           --" << std::endl;
  BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl;
}
コード例 #17
0
ファイル: test1.cpp プロジェクト: Acpharis/rdkit
void testGetSetAngle() {
  std::string rdbase = getenv("RDBASE");
  std::string fName = rdbase + "/Code/GraphMol/MolTransforms/test_data/3-cyclohexylpyridine.mol";
  RWMol *m = MolFileToMol(fName, true, false);
  TEST_ASSERT(m);
  Conformer &conf = m->getConformer();
  double angle = getAngleDeg(conf, 0, 19, 21);
  TEST_ASSERT(RDKit::feq(RDKit::round(angle * 10) / 10, 109.7));
  setAngleDeg(conf, 0, 19, 21, 125.0);
  angle = getAngleDeg(conf, 0, 19, 21);
  TEST_ASSERT(RDKit::feq(angle, 125.0));
  setAngleRad(conf, 21, 19, 0, M_PI / 2.);
  angle = getAngleRad(conf, 0, 19, 21);
  TEST_ASSERT(RDKit::feq(angle, M_PI / 2.));
  angle = getAngleDeg(conf, 0, 19, 21);
  TEST_ASSERT(RDKit::feq(angle, 90.0));
}
コード例 #18
0
ファイル: testMolWriter.cpp プロジェクト: chrissly31415/rdkit
void testGithub186(){
  BOOST_LOG(rdInfoLog) << "testing github issue 186: chiral S not written to ctab" << std::endl;
  std::string rdbase = getenv("RDBASE");
  rdbase += "/Code/GraphMol/FileParsers/test_data/";
  
  {
    std::string fName = rdbase + "github186.mol";
    RWMol *m = MolFileToMol(fName);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==11);
    TEST_ASSERT(m->getNumBonds()==10);
    TEST_ASSERT(m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_UNSPECIFIED &&
                m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_OTHER
                );

    std::string mb=MolToMolBlock(*m);
    delete m;
    m = MolBlockToMol(mb);
    TEST_ASSERT(m);
    TEST_ASSERT(m->getNumAtoms()==11);
    TEST_ASSERT(m->getNumBonds()==10);
    TEST_ASSERT(m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_UNSPECIFIED &&
                m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_OTHER
                );

    delete m;
  }
  
}
コード例 #19
0
  const std::string GetMolFileQueryInfo(const RWMol &mol){
    std::stringstream ss;
    boost::dynamic_bitset<> listQs(mol.getNumAtoms());
    for(ROMol::ConstAtomIterator atomIt=mol.beginAtoms();
	atomIt!=mol.endAtoms();++atomIt){
      if(hasListQuery(*atomIt)) listQs.set((*atomIt)->getIdx());
    }    
    for(ROMol::ConstAtomIterator atomIt=mol.beginAtoms();
	atomIt!=mol.endAtoms();++atomIt){
      if(!listQs[(*atomIt)->getIdx()] && hasComplexQuery(*atomIt)){
	std::string sma=SmartsWrite::GetAtomSmarts(static_cast<const QueryAtom *>(*atomIt));
	ss<< "V  "<<std::setw(3)<<(*atomIt)->getIdx()+1<<" "<<sma<<std::endl;
      }
    }

    for(ROMol::ConstAtomIterator atomIt=mol.beginAtoms();
	atomIt!=mol.endAtoms();++atomIt){
      if(listQs[(*atomIt)->getIdx()]){
        INT_VECT vals;
        getListQueryVals((*atomIt)->getQuery(),vals);
        ss<<"M  ALS "<<std::setw(3)<<(*atomIt)->getIdx()+1<<" ";
        ss<<std::setw(2)<<vals.size();
        if((*atomIt)->getQuery()->getNegation()){
          ss<<" T";
        } else {
          ss<<" F";
        }
        BOOST_FOREACH(int val,vals){
          ss<<" "<<std::setw(3)<<std::left<<(PeriodicTable::getTable()->getElementSymbol(val));
        }
        ss<<"\n";
      }

    }
コード例 #20
0
ファイル: StripSmallFragments.cpp プロジェクト: abradle/rdkit
void AddMWMF(RWMol &mol,
             bool pre) {  // set formula & mass properties "MW_PRE" "MW_POST"
  double mass = 0.0;
  mass = RDKit::Descriptors::calcExactMW(mol);
  /*
          for (unsigned i = 0; i < mol.getNumAtoms(); i++) {
               const Atom& atom = *mol.getAtomWithIdx(i);
               mass += atom.getMass();
               mass += atom.getNumImplicitHs() * 1.0080; // and add implicit
     Hydrogens mass
           }
  */
  std::string formula = getMolecularFormula(mol);
  if (!formula.empty()) mol.setProp((pre ? "MF_PRE" : "MF_POST"), formula);
  char propertyValue[64];
  snprintf(propertyValue, sizeof(propertyValue), "%g", mass);
  mol.setProp((pre ? "MW_PRE" : "MW_POST"), mass);
}
コード例 #21
0
ファイル: Kekulize.cpp プロジェクト: giallu/rdkit
bool permuteDummiesAndKekulize(RWMol &mol, const INT_VECT &allAtms,
                               boost::dynamic_bitset<> dBndCands,
                               INT_VECT &questions,
                               unsigned int maxBackTracks) {
  boost::dynamic_bitset<> atomsInPlay(mol.getNumAtoms());
  for (int allAtm : allAtms) {
    atomsInPlay[allAtm] = 1;
  }
  bool kekulized = false;
  QuestionEnumerator qEnum(questions);
  while (!kekulized && questions.size()) {
    boost::dynamic_bitset<> dBndAdds(mol.getNumBonds());
    INT_VECT done;
#if 1
    // reset the state: all aromatic bonds are remarked to single:
    for (RWMol::BondIterator bi = mol.beginBonds(); bi != mol.endBonds();
         ++bi) {
      if ((*bi)->getIsAromatic() && (*bi)->getBondType() != Bond::SINGLE &&
          atomsInPlay[(*bi)->getBeginAtomIdx()] &&
          atomsInPlay[(*bi)->getEndAtomIdx()]) {
        (*bi)->setBondType(Bond::SINGLE);
      }
    }
#endif
    // pick a new permutation of the questionable atoms:
    const INT_VECT &switchOff = qEnum.next();
    if (!switchOff.size()) break;
    boost::dynamic_bitset<> tCands = dBndCands;
    for (int it : switchOff) {
      tCands[it] = 0;
    }
#if 0
        std::cerr<<"permute: ";
        for (boost::dynamic_bitset<>::size_type i = 0; i < tCands.size(); ++i){
          std::cerr << tCands[i];
        }
        std::cerr<<std::endl;
#endif
    // try kekulizing again:
    kekulized =
        kekulizeWorker(mol, allAtms, tCands, dBndAdds, done, maxBackTracks);
  }
  return kekulized;
}
コード例 #22
0
void testSFIssue1653802(){
  BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdErrorLog) << "    Testing SFIssue1653802." << std::endl;

  RWMol *mol;
  int needMore;
  ForceFields::ForceField *field;

  std::string pathName=getenv("RDBASE");
  pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data";

  mol = MolFileToMol(pathName+"/cyclobutadiene.mol",false);
  TEST_ASSERT(mol);
  MolOps::sanitizeMol(*mol);


  UFF::AtomicParamVect types;
  bool foundAll;
  boost::shared_array<boost::uint8_t> nbrMat;
  boost::tie(types,foundAll)=UFF::getAtomTypes(*mol);
  TEST_ASSERT(foundAll);
  TEST_ASSERT(types.size()==mol->getNumAtoms());
  field=new ForceFields::ForceField();
  UFF::Tools::addBonds(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==8);

  nbrMat = UFF::Tools::buildNeighborMatrix(*mol);
  UFF::Tools::addAngles(*mol,types,field);
  TEST_ASSERT(field->contribs().size()==20);
  UFF::Tools::addTorsions(*mol,types,field);
  //std::cout << field->contribs().size() << std::endl;
  TEST_ASSERT(field->contribs().size()==36);
  UFF::Tools::addNonbonded(*mol,0,types,field,nbrMat);
  delete field;

  field = UFF::constructForceField(*mol);
  field->initialize();
  needMore = field->minimize(200,1e-6,1e-3);
  TEST_ASSERT(!needMore);
  
  delete mol;
  delete field;
  BOOST_LOG(rdErrorLog) << "  done" << std::endl;
}
コード例 #23
0
ファイル: test1.cpp プロジェクト: ASKCOS/rdkit
void test2() {
  BOOST_LOG(rdInfoLog) << "testing coordinate generation" << std::endl;

#if 1
  {
    RWMol *m = SmilesToMol("c1cccnc1");
    TEST_ASSERT(m);
    unsigned int confId = AvalonTools::set2DCoords(*m);
    TEST_ASSERT(m->getNumConformers() == 1);
    TEST_ASSERT(confId == 0);
    delete m;
  }
#endif
  {
    std::string molb = AvalonTools::set2DCoords("c1cccnc1", true);
    TEST_ASSERT(molb != "");
  }

  BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
コード例 #24
0
ファイル: test1.cpp プロジェクト: Acpharis/rdkit
void testGetSetDihedral() {
  std::string rdbase = getenv("RDBASE");
  std::string fName = rdbase + "/Code/GraphMol/MolTransforms/test_data/3-cyclohexylpyridine.mol";
  RWMol *m = MolFileToMol(fName, true, false);
  TEST_ASSERT(m);
  Conformer &conf = m->getConformer();
  double dihedral = getDihedralDeg(conf, 0, 19, 21, 24);
  TEST_ASSERT(RDKit::feq(RDKit::round(dihedral * 100) / 100, 176.05));
  setDihedralDeg(conf, 8, 0, 19, 21, 65.0);
  dihedral = getDihedralDeg(conf, 8, 0, 19, 21);
  TEST_ASSERT(RDKit::feq(dihedral, 65.0));
  setDihedralDeg(conf, 8, 0, 19, 21, -130.0);
  dihedral = getDihedralDeg(conf, 8, 0, 19, 21);
  TEST_ASSERT(RDKit::feq(dihedral, -130.0));
  setDihedralRad(conf, 21, 19, 0, 8, -2. / 3. * M_PI);
  dihedral = getDihedralRad(conf, 8, 0, 19, 21);
  TEST_ASSERT(RDKit::feq(dihedral, -2. / 3. * M_PI));
  dihedral = getDihedralDeg(conf, 8, 0, 19, 21);
  TEST_ASSERT(RDKit::feq(dihedral, -120.0));
}
コード例 #25
0
ファイル: sanitTest.cpp プロジェクト: giallu/rdkit
int main(int argc, char *argv[]) {
  RDLog::InitLogs();
  std::string fname;
  if (argc > 1) {
    fname = argv[1];
  } else {
    BOOST_LOG(rdErrorLog) << "Pass in the list of smiles\n";
  }

  std::ifstream inStream(fname.c_str());
  const int MAX_LINE_LEN = 256;
  char inLine[MAX_LINE_LEN];
  std::string tmpstr;
  std::string smi;
  inStream.getline(inLine, MAX_LINE_LEN, '\n');
  tmpstr = inLine;
  // MolOps molop;
  while (tmpstr.size() > 0) {
    getSmiles(tmpstr, smi);
    RWMol *m = SmilesToMol(smi, 0, 0);

    try {
      // testKekule(*m);

      MolOps::sanitizeMol(*m);

      int nar;
      m->getProp(common_properties::numArom, nar);
      BOOST_LOG(rdInfoLog) << nar << "\n";

      // MolOps::setHybridization(*m);
      delete m;
    } catch (MolSanitizeException) {
      BOOST_LOG(rdErrorLog) << smi << "\n";
      delete m;
    }
    inStream.getline(inLine, MAX_LINE_LEN, '\n');
    tmpstr = inLine;
  }
  return 1;
}
コード例 #26
0
ファイル: iotest.cpp プロジェクト: AlexanderSavelyev/rdkit
void test1(){
#ifdef SUPPORT_COMPRESSED_IO
  BOOST_LOG(rdInfoLog) << "testing basic reading from compressed streams" << std::endl;

  std::string rdbase = getenv("RDBASE");
  std::string fname2 = rdbase + "/Code/Demos/RDKit/BinaryIO/test_data/triazine.mol.gz";
  RWMol *m;
  
  io::filtering_istream inStrm;
  inStrm.push(io::gzip_decompressor());
  inStrm.push(io::file_source(fname2));
  TEST_ASSERT(inStrm.is_complete());
  unsigned int lineNo=0;
  m = MolDataStreamToMol(inStrm,lineNo);
  TEST_ASSERT(m);
  TEST_ASSERT(m->getNumAtoms(6));

  BOOST_LOG(rdInfoLog) << "done" << std::endl;
#else
  BOOST_LOG(rdInfoLog) << "Compressed IO disabled; test skipped" << std::endl;
#endif
}
コード例 #27
0
ファイル: iotest.cpp プロジェクト: giallu/rdkit
void test2() {
#ifdef SUPPORT_COMPRESSED_IO
  BOOST_LOG(rdInfoLog)
      << "testing writing to, then reading from compressed streams"
      << std::endl;

  std::string smiles = "C1CCCC1";
  std::string buff, molBlock;
  RWMol *m;
  m = SmilesToMol(smiles);
  TEST_ASSERT(m);
  TEST_ASSERT(m->getNumAtoms(5));
  m->setProp(common_properties::_Name, "monkey");
  io::filtering_ostream outStrm;
  outStrm.push(io::gzip_compressor());
  outStrm.push(io::back_inserter(buff));
  TEST_ASSERT(outStrm.is_complete());

  molBlock = MolToMolBlock(*m);
  outStrm << molBlock;
  outStrm.reset();

  delete m;
  io::filtering_istream inStrm;
  inStrm.push(io::gzip_decompressor());
  inStrm.push(boost::make_iterator_range(buff));
  TEST_ASSERT(inStrm.is_complete());

  unsigned int lineNo = 0;
  m = MolDataStreamToMol(inStrm, lineNo);
  TEST_ASSERT(m);
  TEST_ASSERT(m->getNumAtoms(5));

  BOOST_LOG(rdInfoLog) << "done" << std::endl;
#else
  BOOST_LOG(rdInfoLog) << "Compressed IO disabled; test skipped" << std::endl;
#endif
}
コード例 #28
0
ファイル: testFMCS_Unit.cpp プロジェクト: DoliathGavid/rdkit
void test18() {
  BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
  BOOST_LOG(rdInfoLog) << "Testing FMCS test18" << std::endl;
  std::cout << "\ntest18()\n";
  std::vector<ROMOL_SPTR> mols;
  const char* smi[] = {
      // TEST 18
      "Cc1nc(CN(C(C)c2ncccc2)CCCCN)ccc1 CHEMBL1682991",  //-- QUERY
      "Cc1ccc(CN(C(C)c2ccccn2)CCCCN)nc1 CHEMBL1682990",
      "Cc1cccnc1CN(C(C)c1ccccn1)CCCCN CHEMBL1682998",
      "CC(N(CCCCN)Cc1c(N)cccn1)c1ccccn1 CHEMBL1682987",
      "Cc1cc(C)c(CN(C(C)c2ccccn2)CCCCN)nc1 CHEMBL1682992",
      "Cc1cc(C(C)N(CCCCN)Cc2c(C)cccn2)ncc1 CHEMBL1682993",
      "Cc1nc(C(C)N(CCCCN)Cc2nc3c([nH]2)cccc3)ccc1 CHEMBL1682878",
      "CC(c1ncccc1)N(CCCCN)Cc1nc2c([nH]1)cccc2 CHEMBL1682867",
      "CC(N(CCCCN)Cc1c(C(C)(C)C)cccn1)c1ccccn1 CHEMBL1682989",
      "CC(N(CCCCN)Cc1c(C(F)(F)F)cccn1)c1ccccn1 CHEMBL1682988",
      //# 18 .  20 20 0.04 sec. Python MCS: CC(c1ccccn1)N(CCCCN)Ccnccc
  };
  RWMol* qm = SmilesToMol(getSmilesOnly(smi[0]));
  unsigned nq = qm->getNumAtoms();
  for (size_t ai = 0; ai < nq; ai++) {
    Atom* atom = qm->getAtomWithIdx(ai);
    atom->setProp("molAtomMapNumber", (int)ai);
  }
  std::cout << "Query +MAP " << MolToSmiles(*qm) << "\n";
  mols.push_back(ROMOL_SPTR(qm));  // with RING INFO
  for (size_t i = 1; i < sizeof(smi) / sizeof(smi[0]); i++)
    mols.push_back(
        ROMOL_SPTR(SmilesToMol(getSmilesOnly(smi[i]))));  // with RING INFO
  t0 = nanoClock();
  MCSResult res = findMCS(mols);
  std::cout << "MCS: " << res.SmartsString << " " << res.NumAtoms << " atoms, "
            << res.NumBonds << " bonds\n";
  printTime();
  TEST_ASSERT(res.NumAtoms == 21 && res.NumBonds == 21);
  BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
}
コード例 #29
0
ファイル: testMIF.cpp プロジェクト: dfhahn/rdkit
void test1ConstructGrid() {
  std::string path = getenv("RDBASE");
  path += "/Code/GraphMol/MIF/test_data/";
  //	//Generate Molecule with 3D Coordinates and Partial Charges
  //	RWMol mol=*SmilesToMol("Cl");
  //	MolOps::addHs(mol);
  //	DGeomHelpers::EmbedMolecule(mol);

  //	MolToMolFile(mol, path + "HCl.mol");

  RWMol mol = *MolFileToMol(path + "HCl.mol", true, false);
  UniformRealValueGrid3D grd = *constructGrid(mol, 0, 5.0, 0.5);

  Point3D bond = mol.getConformer().getAtomPos(1) - mol.getConformer().getAtomPos(0);
  CHECK_INVARIANT(feq(grd.getSpacing (), 0.5),
                  "Spacing of grid is not correct.");
  CHECK_INVARIANT(feq(grd.getNumX (), std::floor ((fabs (bond.x) + 10.0) / 0.5 + 0.5)),
                  "X length of grid is incorrect.");
  CHECK_INVARIANT(feq(grd.getNumY (), std::floor ((fabs (bond.y) + 10.0) / 0.5 + 0.5)),
                  "Y length of grid is incorrect.");
  CHECK_INVARIANT(feq(grd.getNumZ (), std::floor ((fabs (bond.z) + 10.0) / 0.5 + 0.5)),
                  "Z length of grid is incorrect.");
}
コード例 #30
0
ファイル: MolFragmenter.cpp プロジェクト: ASKCOS/rdkit
ROMol *fragmentOnBonds(
    const ROMol &mol, const std::vector<unsigned int> &bondIndices,
    bool addDummies,
    const std::vector<std::pair<unsigned int, unsigned int> > *dummyLabels,
    const std::vector<Bond::BondType> *bondTypes,
    std::vector<unsigned int> *nCutsPerAtom) {
  PRECONDITION((!dummyLabels || dummyLabels->size() == bondIndices.size()),
               "bad dummyLabel vector");
  PRECONDITION((!bondTypes || bondTypes->size() == bondIndices.size()),
               "bad bondType vector");
  PRECONDITION((!nCutsPerAtom || nCutsPerAtom->size() == mol.getNumAtoms()),
               "bad nCutsPerAtom vector");
  if (nCutsPerAtom) {
    BOOST_FOREACH (unsigned int &nCuts, *nCutsPerAtom) { nCuts = 0; }
  }
  RWMol *res = new RWMol(mol);
  if (!mol.getNumAtoms()) return res;

  std::vector<Bond *> bondsToRemove;
  bondsToRemove.reserve(bondIndices.size());
  BOOST_FOREACH (unsigned int bondIdx, bondIndices) {
    bondsToRemove.push_back(res->getBondWithIdx(bondIdx));
  }