// $Id$ // // Copyright (C) 2001-2008 Greg Landrum and Rational Discovery LLC // // @@ All Rights Reserved @@ // This file is part of the RDKit. // The contents are covered by the terms of the BSD license // which is included in the file license.txt, found at the root // of the RDKit source tree. // #include #include #include #include //#include #include using namespace std; using namespace RDKit; // ------------------------------------------------------------------- void testBookmarks(ROMol m){ int i; // ------------------------ // simple bookmark stuff Atom *a1 = m.getAtomWithIdx(1); m.setAtomBookmark(a1,666); Atom *a2 = m.getAtomWithBookmark(666); TEST_ASSERT(a2->getIdx()==a1->getIdx()); bool ok; m.clearAtomBookmark(666); boost::logging::disable_logs("rdApp.error"); try{ a2 = m.getAtomWithBookmark(666); ok=0; } catch (...) { ok=1; } boost::logging::enable_logs("rdApp.error"); CHECK_INVARIANT(ok,"atom bookmark not properly cleared"); // ------------------------ // repeat a bookmark a1 = m.getAtomWithIdx(1); CHECK_INVARIANT(a1->getIdx()==1,""); m.setAtomBookmark(a1,666); m.setAtomBookmark(m.getAtomWithIdx(0),666); a2 = m.getAtomWithBookmark(666); CHECK_INVARIANT(a2->getIdx()==1,""); CHECK_INVARIANT(a2->getIdx()==a1->getIdx(),""); m.clearAtomBookmark(666,a2); a2 = m.getAtomWithBookmark(666); i = a2->getIdx(); CHECK_INVARIANT(i==0,""); m.clearAtomBookmark(666,a2); boost::logging::disable_logs("rdApp.error"); try{ a2 = m.getAtomWithBookmark(666); ok=0; } catch (...) { ok=1; } boost::logging::enable_logs("rdApp.error"); CHECK_INVARIANT(ok,"atom bookmark not properly cleared"); // make sure clearAtomBookmark doesn't barf if there's no // such bookmark: m.clearAtomBookmark(777); //---------------------------- // now do bond bookmarks Bond * b1 = m.getBondWithIdx(0); m.setBondBookmark(b1,23); Bond * b2 = m.getBondWithBookmark(23); CHECK_INVARIANT(b2->getIdx()==b1->getIdx(),""); m.clearBondBookmark(23); boost::logging::disable_logs("rdApp.error"); try{ b2 = m.getBondWithBookmark(23); ok=0; } catch (...) { ok=1; } boost::logging::enable_logs("rdApp.error"); CHECK_INVARIANT(ok,"bond bookmark not properly cleared"); m.setBondBookmark(b1,23); m.setBondBookmark(m.getBondWithIdx(1),23); b2 = m.getBondWithBookmark(23); CHECK_INVARIANT(b2->getIdx()==b1->getIdx(),""); m.clearBondBookmark(23,b2); b2 = m.getBondWithBookmark(23); CHECK_INVARIANT(b2->getIdx()==1,""); m.clearBondBookmark(23,b2); boost::logging::disable_logs("rdApp.error"); try{ b2 = m.getBondWithBookmark(23); ok=0; } catch (...) { ok=1; } boost::logging::enable_logs("rdApp.error"); CHECK_INVARIANT(ok,"bond bookmark not properly cleared"); // make sure clearAtomBookmark doesn't barf if there's no // such bookmark: m.clearBondBookmark(777); } void testMolProps() { BOOST_LOG(rdInfoLog) << "-----------------------\n Testing Mol Property Caches" << std::endl; RWMol m2; STR_VECT propNames; m2.addAtom(new Atom(6)); m2.addAtom(new Atom(6)); m2.addBond(0,1,Bond::TRIPLE); CHECK_INVARIANT(!m2.hasProp("prop1"),""); CHECK_INVARIANT(!m2.hasProp("prop2"),""); m2.setProp("prop1",2); int tmpI; std::string tmpS; CHECK_INVARIANT(m2.hasProp("prop1"),""); m2.getProp("prop1",tmpI); CHECK_INVARIANT(tmpI==2,""); m2.getProp("prop1",tmpS); CHECK_INVARIANT(tmpS=="2",""); m2.setProp("prop1",std::string("2")); CHECK_INVARIANT(m2.hasProp("prop1"),""); m2.getProp("prop1",tmpS); CHECK_INVARIANT(tmpS=="2",""); std::string tmpString("2"); m2.setProp("prop1",tmpString.c_str()); CHECK_INVARIANT(m2.hasProp("prop1"),""); m2.getProp("prop1",tmpS); CHECK_INVARIANT(tmpS=="2",""); tmpS="name"; m2.setProp("_Name",tmpS); propNames=m2.getPropList(false,false); TEST_ASSERT(propNames.size()==1); propNames=m2.getPropList(true,false); TEST_ASSERT(propNames.size()==2); // check for computed properties m2.setProp("cprop1", 1, true); m2.setProp("cprop2", 2, true); STR_VECT cplst; m2.getProp("__computedProps", cplst); CHECK_INVARIANT(cplst.size() == 2, ""); CHECK_INVARIANT(cplst[0] == "cprop1", ""); CHECK_INVARIANT(cplst[1] == "cprop2", ""); propNames=m2.getPropList(false,false); TEST_ASSERT(propNames.size()==1); propNames=m2.getPropList(true,false); TEST_ASSERT(propNames.size()==2); propNames=m2.getPropList(false,true); TEST_ASSERT(propNames.size()==3); propNames=m2.getPropList(true,true); TEST_ASSERT(propNames.size()==5); propNames=m2.getPropList(); TEST_ASSERT(propNames.size()==5); m2.clearProp("cprop1"); CHECK_INVARIANT(!m2.hasProp("cprop1"), ""); m2.getProp("__computedProps", cplst); CHECK_INVARIANT(cplst.size() == 1, ""); m2.clearComputedProps(); CHECK_INVARIANT(!m2.hasProp("cprop2"), ""); m2.getProp("__computedProps", cplst); CHECK_INVARIANT(cplst.size() == 0, ""); BOOST_LOG(rdInfoLog) << "Finished" << std::endl; } void testAtomProps() { BOOST_LOG(rdInfoLog) << "-----------------------\n Testing Atom Property Caches" << std::endl; RWMol m2; m2.addAtom(new Atom(6)); m2.addAtom(new Atom(6)); m2.addBond(0,1,Bond::TRIPLE); Atom *a1 = m2.getAtomWithIdx(0); Atom *a2 = m2.getAtomWithIdx(0); Atom *a3 = &(*a1); CHECK_INVARIANT(!a1->hasProp("prop1"),""); CHECK_INVARIANT(!a1->hasProp("prop2"),""); CHECK_INVARIANT(!a2->hasProp("prop1"),""); CHECK_INVARIANT(!a2->hasProp("prop2"),""); CHECK_INVARIANT(!a3->hasProp("prop1"),""); CHECK_INVARIANT(!a3->hasProp("prop2"),""); a1->setProp("prop1",3); a1->setProp("prop2",4); CHECK_INVARIANT(a1->hasProp("prop1"),""); CHECK_INVARIANT(a1->hasProp("prop2"),""); CHECK_INVARIANT(a2->hasProp("prop1"),""); CHECK_INVARIANT(a2->hasProp("prop2"),""); CHECK_INVARIANT(a3->hasProp("prop1"),""); CHECK_INVARIANT(a3->hasProp("prop2"),""); CHECK_INVARIANT(!a1->hasProp("bogus"),""); CHECK_INVARIANT(!a2->hasProp("bogus"),""); CHECK_INVARIANT(!a3->hasProp("bogus"),""); int tmp; a1->getProp("prop1",tmp); CHECK_INVARIANT(tmp==3,""); a1->getProp("prop2",tmp); CHECK_INVARIANT(tmp==4,""); a2->getProp("prop1",tmp); CHECK_INVARIANT(tmp==3,""); a2->getProp("prop2",tmp); CHECK_INVARIANT(tmp==4,""); a3->getProp("prop1",tmp); CHECK_INVARIANT(tmp==3,""); a3->getProp("prop2",tmp); CHECK_INVARIANT(tmp==4,""); // ceck for computed properties a1->setProp("cprop1", 1, true); a1->setProp("cprop2", 2, true); STR_VECT cplst; a1->getProp("__computedProps", cplst); CHECK_INVARIANT(cplst.size() == 2, ""); CHECK_INVARIANT(cplst[0] == "cprop1", ""); CHECK_INVARIANT(cplst[1] == "cprop2", ""); a1->clearProp("cprop1"); CHECK_INVARIANT(!a1->hasProp("cprop1"), ""); a1->getProp("__computedProps", cplst); CHECK_INVARIANT(cplst.size() == 1, ""); a1->clearComputedProps(); CHECK_INVARIANT(!a1->hasProp("cprop2"), ""); a1->getProp("__computedProps", cplst); CHECK_INVARIANT(cplst.size() == 0, ""); BOOST_LOG(rdInfoLog) << "Finished" << std::endl; } void testBondProps() { BOOST_LOG(rdInfoLog) << "-----------------------\n Testing Bond Property Caches" << std::endl; RWMol m2; m2.addAtom(new Atom(6)); m2.addAtom(new Atom(6)); m2.addBond(0,1,Bond::TRIPLE); Bond * b1 = m2.getBondWithIdx(0); Bond * b2 = m2.getBondWithIdx(0); CHECK_INVARIANT(!b1->hasProp("prop1"),""); CHECK_INVARIANT(!b1->hasProp("prop2"),""); CHECK_INVARIANT(!b2->hasProp("prop1"),""); CHECK_INVARIANT(!b2->hasProp("prop2"),""); b1->setProp("prop1",3); b1->setProp("prop2",4); CHECK_INVARIANT(b1->hasProp("prop1"),""); CHECK_INVARIANT(b1->hasProp("prop2"),""); CHECK_INVARIANT(b2->hasProp("prop1"),""); CHECK_INVARIANT(b2->hasProp("prop2"),""); CHECK_INVARIANT(!b1->hasProp("bogus"),""); CHECK_INVARIANT(!b2->hasProp("bogus"),""); int tmp; b1->getProp("prop1",tmp); CHECK_INVARIANT(tmp==3,""); b1->getProp("prop2",tmp); CHECK_INVARIANT(tmp==4,""); b2->getProp("prop1",tmp); CHECK_INVARIANT(tmp==3,""); b2->getProp("prop2",tmp); CHECK_INVARIANT(tmp==4,""); // check for computed properties b1->setProp("cprop1", 1, true); b1->setProp("cprop2", 2, true); STR_VECT cplst; b1->getProp("__computedProps", cplst); CHECK_INVARIANT(cplst.size() == 2, ""); CHECK_INVARIANT(cplst[0] == "cprop1", ""); CHECK_INVARIANT(cplst[1] == "cprop2", ""); b1->clearProp("cprop1"); CHECK_INVARIANT(!b1->hasProp("cprop1"), ""); b1->getProp("__computedProps", cplst); CHECK_INVARIANT(cplst.size() == 1, ""); b1->clearComputedProps(); CHECK_INVARIANT(!b1->hasProp("cprop2"), ""); b1->getProp("__computedProps", cplst); CHECK_INVARIANT(cplst.size() == 0, ""); BOOST_LOG(rdInfoLog) << "Finished" << std::endl; } // this is here because there was at one time a problem with crashes when doing // this stuff void testPropLeak() { BOOST_LOG(rdInfoLog) << "-----------------------\n Testing Atom and Bond Property Caches" << std::endl; RWMol m2; m2.addAtom(new Atom(6)); m2.addAtom(new Atom(6)); m2.addBond(0,1,Bond::TRIPLE); Atom *a1 = m2.getAtomWithIdx(0); Atom *a2 = m2.getAtomWithIdx(0); CHECK_INVARIANT(!a1->hasProp("prop1"),""); CHECK_INVARIANT(!a1->hasProp("prop2"),""); CHECK_INVARIANT(!a2->hasProp("prop1"),""); CHECK_INVARIANT(!a2->hasProp("prop2"),""); a1->setProp("prop1",3); a1->setProp("prop2",4); CHECK_INVARIANT(a1->hasProp("prop1"),""); CHECK_INVARIANT(a1->hasProp("prop2"),""); CHECK_INVARIANT(a2->hasProp("prop1"),""); CHECK_INVARIANT(a2->hasProp("prop2"),""); CHECK_INVARIANT(!a1->hasProp("bogus"),""); CHECK_INVARIANT(!a2->hasProp("bogus"),""); int tmp; a1->getProp("prop1",tmp); CHECK_INVARIANT(tmp==3,""); a1->getProp("prop2",tmp); CHECK_INVARIANT(tmp==4,""); a2->getProp("prop1",tmp); CHECK_INVARIANT(tmp==3,""); a2->getProp("prop2",tmp); CHECK_INVARIANT(tmp==4,""); Bond * b1 = m2.getBondWithIdx(0); Bond * b2 = m2.getBondWithIdx(0); CHECK_INVARIANT(!b1->hasProp("prop1"),""); CHECK_INVARIANT(!b1->hasProp("prop2"),""); CHECK_INVARIANT(!b2->hasProp("prop1"),""); CHECK_INVARIANT(!b2->hasProp("prop2"),""); b1->setProp("prop1",3); b1->setProp("prop2",4); CHECK_INVARIANT(b1->hasProp("prop1"),""); CHECK_INVARIANT(b1->hasProp("prop2"),""); CHECK_INVARIANT(b2->hasProp("prop1"),""); CHECK_INVARIANT(b2->hasProp("prop2"),""); CHECK_INVARIANT(!b1->hasProp("bogus"),""); CHECK_INVARIANT(!b2->hasProp("bogus"),""); b1->getProp("prop1",tmp); CHECK_INVARIANT(tmp==3,""); b1->getProp("prop2",tmp); CHECK_INVARIANT(tmp==4,""); b2->getProp("prop1",tmp); CHECK_INVARIANT(tmp==3,""); b2->getProp("prop2",tmp); CHECK_INVARIANT(tmp==4,""); BOOST_LOG(rdInfoLog) << "Finished" << std::endl; } void testMisc() { BOOST_LOG(rdInfoLog) << "-----------------------\n Testing Misc Properties" << std::endl; RWMol m2; m2.addAtom(new Atom(6)); m2.addAtom(new Atom(6)); m2.addAtom(new Atom(6)); m2.addAtom(new Atom(6)); m2.addBond(0,1,Bond::SINGLE); m2.addBond(1,2,Bond::SINGLE); m2.addBond(0,2,Bond::SINGLE); m2.addBond(2,3,Bond::SINGLE); MolOps::sanitizeMol(m2); Bond * bnd; bnd = m2.getBondBetweenAtoms(0,1); CHECK_INVARIANT(bnd,""); bnd = m2.getBondBetweenAtoms(1,0); CHECK_INVARIANT(bnd,""); bnd = m2.getBondBetweenAtoms(3,0); CHECK_INVARIANT(!bnd,""); bnd = m2.getBondBetweenAtoms(0,3); CHECK_INVARIANT(!bnd,""); const Bond *cbnd; cbnd = m2.getBondBetweenAtoms(0,1); CHECK_INVARIANT(cbnd,""); cbnd = m2.getBondBetweenAtoms(1,0); CHECK_INVARIANT(cbnd,""); cbnd = m2.getBondBetweenAtoms(0,3); CHECK_INVARIANT(!cbnd,""); cbnd = m2.getBondBetweenAtoms(3,0); CHECK_INVARIANT(!cbnd,""); CHECK_INVARIANT(m2.getAtomWithIdx(0)->getTotalNumHs()==2,""); // we'll check atom deletion and handling of bookmarks on deletion // simultaneously: // (The bookmark thing was the root of Issue 96) m2.setAtomBookmark(m2.getAtomWithIdx(0),2342); m2.setBondBookmark(m2.getBondWithIdx(0),2343); m2.removeAtom(static_cast(0)); CHECK_INVARIANT(!m2.hasAtomBookmark(2342),""); CHECK_INVARIANT(!m2.hasBondBookmark(2343),""); CHECK_INVARIANT(m2.getNumAtoms()==3,""); CHECK_INVARIANT(m2.getNumBonds()==2,""); MolOps::sanitizeMol(m2); CHECK_INVARIANT(m2.getAtomWithIdx(0)->getTotalNumHs()==3,""); m2.addAtom(new Atom(1)); m2.addBond(2,3,Bond::SINGLE); MolOps::sanitizeMol(m2); CHECK_INVARIANT(m2.getAtomWithIdx(0)->getTotalNumHs()==3,""); CHECK_INVARIANT(m2.getAtomWithIdx(0)->getTotalNumHs(true)==3,""); CHECK_INVARIANT(m2.getAtomWithIdx(2)->getTotalNumHs()==2,""); CHECK_INVARIANT(m2.getAtomWithIdx(2)->getTotalNumHs(true)==3,""); Atom *other=m2.getBondWithIdx(1)->getOtherAtom(m2.getAtomWithIdx(1)); CHECK_INVARIANT(other,""); const Atom *at = m2.getAtomWithIdx(1); ROMol::OEDGE_ITER begin,end; boost::tie(begin,end) = m2.getAtomBonds(at); while(begin!=end){ const Atom *at2 = m2[*begin]->getOtherAtom(at); TEST_ASSERT(at2); begin++; } ROMol::VERTEX_ITER atBegin,atEnd; boost::tie(atBegin,atEnd) = m2.getVertices(); TEST_ASSERT(atBegin!=atEnd); while(atBegin!=atEnd){ const ATOM_SPTR at2=m2[*atBegin]; TEST_ASSERT(at2->getIdx()>=0); atBegin++; } BOOST_LOG(rdInfoLog) << "Finished" << std::endl; } void testDegree() { BOOST_LOG(rdInfoLog) << "-----------------------\n Testing degree operations" << std::endl; RWMol *m; m= new RWMol(); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addBond(0,1,Bond::SINGLE); m->addBond(1,2,Bond::SINGLE); m->addBond(0,2,Bond::SINGLE); m->addBond(2,3,Bond::SINGLE); MolOps::sanitizeMol(*m); TEST_ASSERT(m->getAtomWithIdx(0)->getDegree()==2); TEST_ASSERT(m->getAtomWithIdx(0)->getTotalNumHs()==2); TEST_ASSERT(m->getAtomWithIdx(0)->getTotalDegree()==4); TEST_ASSERT(m->getAtomWithIdx(2)->getDegree()==3); TEST_ASSERT(m->getAtomWithIdx(2)->getTotalNumHs()==1); TEST_ASSERT(m->getAtomWithIdx(2)->getTotalDegree()==4); delete m; m= new RWMol(); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(1)); m->addBond(0,1,Bond::SINGLE); m->addBond(1,2,Bond::SINGLE); m->addBond(0,2,Bond::SINGLE); m->addBond(2,3,Bond::SINGLE); m->addBond(0,4,Bond::SINGLE); MolOps::sanitizeMol(*m); TEST_ASSERT(m->getAtomWithIdx(0)->getDegree()==3); TEST_ASSERT(m->getAtomWithIdx(0)->getTotalNumHs()==1); TEST_ASSERT(m->getAtomWithIdx(0)->getTotalNumHs(true)==2); TEST_ASSERT(m->getAtomWithIdx(0)->getTotalDegree()==4); TEST_ASSERT(m->getAtomWithIdx(2)->getDegree()==3); TEST_ASSERT(m->getAtomWithIdx(2)->getTotalNumHs()==1); TEST_ASSERT(m->getAtomWithIdx(2)->getTotalDegree()==4); BOOST_LOG(rdInfoLog) << "Finished" << std::endl; } void testIssue1993296(){ RWMol *m=new RWMol(); bool ok; BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "Testing Issue 1993296" << std::endl; m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addBond(0,1,Bond::SINGLE); ok=false; try{ m->addBond(0,1,Bond::SINGLE); } catch (...) { ok=true; } TEST_ASSERT(ok); ok=false; try{ m->addBond(1,0,Bond::SINGLE); } catch (...) { ok=true; } TEST_ASSERT(ok); // not technically part of 1993296, but related: we also throw // on adding self bonds ok=false; try{ m->addBond(1,1,Bond::SINGLE); } catch (...) { ok=true; } Bond *newB=new Bond(); newB->setBeginAtomIdx(0); newB->setEndAtomIdx(1); newB->setBondType(Bond::SINGLE); ok=false; try{ m->addBond(newB); } catch (...) { ok=true; } TEST_ASSERT(ok); // not technically part of 1993296, but related: we also throw // on adding self bonds newB->setBeginAtomIdx(0); newB->setEndAtomIdx(0); ok=false; try{ m->addBond(newB); } catch (...) { ok=true; } TEST_ASSERT(ok); delete newB; BOOST_LOG(rdInfoLog) << "\tdone" << std::endl; } void testIssue2381580(){ BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "Testing Issue 2381580" << std::endl; { RWMol *m=new RWMol(); m->addAtom(new Atom(5)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addBond(0,1,Bond::SINGLE); m->addBond(0,2,Bond::SINGLE); m->addBond(0,3,Bond::SINGLE); MolOps::sanitizeMol(*m); TEST_ASSERT(m->getAtomWithIdx(0)->getFormalCharge()==0); TEST_ASSERT(m->getAtomWithIdx(0)->getExplicitValence()==3); TEST_ASSERT(m->getAtomWithIdx(0)->getNumImplicitHs()==0); delete m; } { RWMol *m=new RWMol(); m->addAtom(new Atom(5)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addBond(0,1,Bond::SINGLE); m->addBond(0,2,Bond::SINGLE); m->addBond(0,3,Bond::SINGLE); m->addBond(0,4,Bond::SINGLE); m->getAtomWithIdx(0)->setFormalCharge(-1); MolOps::sanitizeMol(*m); TEST_ASSERT(m->getAtomWithIdx(0)->getFormalCharge()==-1); TEST_ASSERT(m->getAtomWithIdx(0)->getExplicitValence()==4); TEST_ASSERT(m->getAtomWithIdx(0)->getNumImplicitHs()==0); delete m; } { RWMol *m=new RWMol(); m->addAtom(new Atom(5)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addBond(0,1,Bond::SINGLE); m->addBond(0,2,Bond::SINGLE); m->addBond(0,3,Bond::SINGLE); m->addBond(0,4,Bond::SINGLE); bool ok=false; try{ MolOps::sanitizeMol(*m); } catch (MolSanitizeException &e) { ok=true; } TEST_ASSERT(ok); delete m; } { RWMol *m=new RWMol(); m->addAtom(new Atom(5)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addBond(0,1,Bond::SINGLE); m->addBond(0,2,Bond::SINGLE); m->addBond(0,3,Bond::SINGLE); m->addBond(0,4,Bond::SINGLE); m->getAtomWithIdx(0)->setFormalCharge(+1); bool ok=false; try{ MolOps::sanitizeMol(*m); } catch (MolSanitizeException &e) { ok=true; } TEST_ASSERT(ok); delete m; } { RWMol *m=new RWMol(); m->addAtom(new Atom(5)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addBond(0,1,Bond::SINGLE); m->addBond(0,2,Bond::SINGLE); m->getAtomWithIdx(0)->setFormalCharge(+1); MolOps::sanitizeMol(*m); TEST_ASSERT(m->getAtomWithIdx(0)->getFormalCharge()==1); TEST_ASSERT(m->getAtomWithIdx(0)->getExplicitValence()==2); TEST_ASSERT(m->getAtomWithIdx(0)->getNumImplicitHs()==0); delete m; } { RWMol *m=new RWMol(); m->addAtom(new Atom(5)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addBond(0,1,Bond::SINGLE); m->addBond(0,2,Bond::SINGLE); m->addBond(0,3,Bond::SINGLE); m->getAtomWithIdx(0)->setFormalCharge(-1); MolOps::sanitizeMol(*m); TEST_ASSERT(m->getAtomWithIdx(0)->getFormalCharge()==-1); TEST_ASSERT(m->getAtomWithIdx(0)->getExplicitValence()==3); TEST_ASSERT(m->getAtomWithIdx(0)->getNumImplicitHs()==1); delete m; } BOOST_LOG(rdInfoLog) << "\tdone" << std::endl; } void testIssue2840217(){ BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "Testing Issue 2840217" << std::endl; { RWMol *m=new RWMol(); for(unsigned int i=0;i<200;++i){ m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); m->addAtom(new Atom(6)); for(unsigned int j=0;j<5;++j){ m->addBond(i*6+j,i*6+j+1,Bond::AROMATIC); } m->addBond(i*6,i*6+5,Bond::AROMATIC); } TEST_ASSERT(m->getNumBonds()==1200); MolOps::sanitizeMol(*m); TEST_ASSERT(m->getNumAtoms()==1200); delete m; } BOOST_LOG(rdInfoLog) << "\tdone" << std::endl; } void test1(){ RWMol m; Atom *newAtom = new Atom(8); m.addAtom(newAtom); CHECK_INVARIANT(m.getAtomWithIdx(0)->getIdx()==0,""); newAtom = new Atom(6); m.addAtom(newAtom); CHECK_INVARIANT(m.getAtomWithIdx(0)->getIdx()==0,""); CHECK_INVARIANT(m.getAtomWithIdx(1)->getIdx()==1,""); newAtom = new Atom(7); m.addAtom(newAtom); CHECK_INVARIANT(m.getAtomWithIdx(0)->getIdx()==0,""); CHECK_INVARIANT(m.getAtomWithIdx(1)->getIdx()==1,""); CHECK_INVARIANT(m.getAtomWithIdx(2)->getIdx()==2,""); CHECK_INVARIANT(m.getAtomWithIdx(1)->getOwningMol().getAtomWithIdx(1)->getIdx()==1,""); m.addBond(0,1,Bond::SINGLE); m.addBond(1,2,Bond::DOUBLE); CHECK_INVARIANT(m.getBondWithIdx(0)->getIdx()==0,""); CHECK_INVARIANT(m.getBondWithIdx(1)->getIdx()==1,""); CHECK_INVARIANT(m.getBondWithIdx(0)->getBondType()==Bond::SINGLE,""); CHECK_INVARIANT(m.getBondWithIdx(1)->getBondType()==Bond::DOUBLE,""); CHECK_INVARIANT(m.getBondWithIdx(0)->getBeginAtom()->getIdx()==0,""); CHECK_INVARIANT(m.getBondWithIdx(0)->getEndAtom()->getIdx()==1,""); CHECK_INVARIANT(m.getBondWithIdx(1)->getBeginAtom()->getIdx()==1,""); CHECK_INVARIANT(m.getBondWithIdx(1)->getEndAtom()->getIdx()==2,""); testBookmarks(m); // Using operator<< on a non-sanitized molecule is a test of Issue156: ROMol::ADJ_ITER ai1,ai2; boost::tie(ai1,ai2) = m.getAtomNeighbors(m.getAtomWithIdx(1)); m.updatePropertyCache(); boost::logging::disable_logs("rdApp.info"); while(ai1!=ai2){ BOOST_LOG(rdInfoLog) << *m.getAtomWithIdx(*ai1) << endl; ai1++; } m.addAtom(new Atom(6)); Bond *bsp = m.createPartialBond(2); m.setBondBookmark(bsp,47); m.finishPartialBond(3,47,Bond::SINGLE); m.clearBondBookmark(47); BOOST_LOG(rdInfoLog) << "partial bond added:" << endl; unsigned int i; m.updatePropertyCache(); for(i=0;isetAtomicNum(7); //m2.addAtom(qA); m2.addAtom(new QueryAtom(7)); m2.addBond(0,1,Bond::TRIPLE); m2.addBond(1,2,Bond::SINGLE); m.insertMol(m2); m.updatePropertyCache(); BOOST_LOG(rdInfoLog) << "post-insert:" << endl; for(i=0;igetDefaultValence(6)==4); TEST_ASSERT(PeriodicTable::getTable()->getNouterElecs(6)==4); TEST_ASSERT(PeriodicTable::getTable()->getMostCommonIsotope(6)==12); TEST_ASSERT(PeriodicTable::getTable()->getMostCommonIsotopeMass(6)==12.0); TEST_ASSERT(PeriodicTable::getTable()->getDefaultValence(26)==-1); TEST_ASSERT(PeriodicTable::getTable()->getDefaultValence(57)==-1); // this was sf.net issue 269 int anum; anum = PeriodicTable::getTable()->getAtomicNumber("C"); TEST_ASSERT(anum==6); try { anum = PeriodicTable::getTable()->getAtomicNumber("Xx"); } catch (...) { anum=-1; } TEST_ASSERT(anum==-1); BOOST_LOG(rdInfoLog) << "Finished" << std::endl; } void testAddAtomWithConf() { BOOST_LOG(rdInfoLog) << "-----------------------\n"; BOOST_LOG(rdInfoLog) << "Testing issue 264: adding atoms to molecules that already have conformers" << std::endl; { RWMol m; m.addAtom(new Atom(6)); m.addAtom(new Atom(6)); Conformer *conf = new Conformer(m.getNumAtoms()); m.addConformer(conf); m.addAtom(new Atom(6)); TEST_ASSERT(m.getConformer().getNumAtoms()==m.getNumAtoms()); } { RWMol m; m.addAtom(new Atom(6)); m.addAtom(new Atom(6)); Conformer *conf = new Conformer(m.getNumAtoms()); m.addConformer(conf); m.addAtom(); TEST_ASSERT(m.getConformer().getNumAtoms()==m.getNumAtoms()); } { // make sure things are ok even if there is no conformer RWMol m; m.addAtom(new Atom(6)); m.addAtom(new Atom(6)); m.addAtom(new Atom(6)); TEST_ASSERT(m.getNumConformers()==0); } BOOST_LOG(rdInfoLog) << "Finished" << std::endl; } void testIssue267() { BOOST_LOG(rdInfoLog) << "-----------------------\n"; BOOST_LOG(rdInfoLog) << "Testing issue 267: default valence of *" << std::endl; { RWMol m; m.addAtom(new Atom(0)); m.updatePropertyCache(); TEST_ASSERT(m.getAtomWithIdx(0)->getImplicitValence()==0); } { RWMol m; m.addAtom(new Atom(0)); for(unsigned int i=0;i<8;++i){ m.addAtom(new Atom(1)); m.addBond(0,i+1,Bond::SINGLE); } m.updatePropertyCache(); } BOOST_LOG(rdInfoLog) << "Finished" << std::endl; } // ------------------------------------------------------------------- int main() { RDLog::InitLogs(); //boost::logging::enable_logs("rdApp.info"); // test1(); // <- this doesn't seem to actually do anything #if 1 testPropLeak(); testMolProps(); testAtomProps(); testBondProps(); testMisc(); testDegree(); testIssue1993296(); testIssue2381580(); testIssue2840217(); #endif testPeriodicTable(); testAddAtomWithConf(); testIssue267(); return 0; }