Files
rdkit/Code/GraphMol/FileParsers/test1.cpp
Jan Holst Jensen 5616dc2597 Add support for dative bonds. (#1190)
* Add support for dative bonds to molfile reader plus writer and to SMILES reader (SMILES writer already supports it).
Initial V3000 molfile reader and writer dative bond support by Esben Jannik Bjerrum.

* first pass at adding -> as dative bond in smiles/smarts
more testing required

* all tests pass

* update .cmake files for lex
2016-12-14 09:44:18 +01:00

4980 lines
157 KiB
C++

//
// Copyright (C) 2002-2016 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 <RDGeneral/RDLog.h>
#include <GraphMol/RDKitBase.h>
#include <GraphMol/Canon.h>
#include <GraphMol/MonomerInfo.h>
#include "FileParsers.h"
#include "SequenceParsers.h"
#include "SequenceWriters.h"
#include "MolFileStereochem.h"
#include "ProximityBonds.h"
#include <GraphMol/SmilesParse/SmilesParse.h>
#include <GraphMol/SmilesParse/SmilesWrite.h>
#include <GraphMol/SmilesParse/SmartsWrite.h>
#include <GraphMol/Substruct/SubstructMatch.h>
#include <RDGeneral/FileParseException.h>
#include <RDGeneral/BadFileException.h>
#include <RDGeneral/LocaleSwitcher.h>
#include <clocale>
#include <cstdlib>
#include <string>
#include <fstream>
#include <boost/lexical_cast.hpp>
using namespace RDKit;
void test1() {
BOOST_LOG(rdInfoLog) << "testing atom query parsing" << std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/list-query.mol";
RWMol *m = MolFileToMol(fName, false);
// MolOps::sanitizeMol(*m);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 6);
std::string smi = MolToSmiles(*m);
TEST_ASSERT(smi == "C1=CC=CC=C1");
m->updatePropertyCache();
smi = MolToSmarts(*m);
TEST_ASSERT(smi == "[#6]1=[#6]-[#6]=[#6]-[#6]=[#6,#7,#15]-1");
smi = "C1=CC=CC=C1";
RWMol *m2 = SmilesToMol(smi, false, false);
MatchVectType mv;
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 6);
// sanitize it, which will aromatize the bonds... we will not match:
MolOps::sanitizeMol(*m2);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "N1=CC=CC=C1";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 6);
delete m2;
smi = "S1=CC=CC=C1";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "P1=CC=CC=C1";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 6);
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/not-list-query.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC(=C)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "CC(=O)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CC(=N)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CC(=O)C(=C)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "C(=C)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
// make sure new-style atom lists override old-style atom lists:
delete m;
fName = rdbase +
"/Code/GraphMol/FileParsers/test_data/conflicting-list-query.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC(=C)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "CC(=O)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
// longer list queries, this was issue 2413431:
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/list-query-long.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(14)->hasQuery());
smi = "C1COC2=CC3=CC4=C(C=CC=C4)C=C3C=C2C1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1C[Se]C2=CC3=CC4=C(C=CC=C4)C=C3C=C2C1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1C[Te]C2=CC3=CC4=C(C=CC=C4)C=C3C=C2C1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1C[As]C2=CC3=CC4=C(C=CC=C4)C=C3C=C2C1";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void test2() {
BOOST_LOG(rdInfoLog) << "testing bond query parsing" << std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/bond-query.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getNumAtoms() == 5);
std::string smi = MolToSmiles(*m);
TEST_ASSERT(smi == "C=CC~CC");
smi = "C1=CC=CC=C1";
RWMol *m2 = SmilesToMol(smi, false, false);
MatchVectType mv;
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
// sanitize it (making bonds aromatic) ... we will not match:
MolOps::sanitizeMol(*m2);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C=CC=CC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "C=CCCC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/RingBondQuery.mol";
delete m;
m = MolFileToMol(fName);
TEST_ASSERT(m->getNumAtoms() == 5);
delete m2;
smi = "C1CCC1C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1CC2C1C2";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ChainBondQuery.mol";
delete m;
m = MolFileToMol(fName);
TEST_ASSERT(m->getNumAtoms() == 5);
delete m2;
smi = "C1CCC1C";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "C1CC2C1C2";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
// - - - - - - - - - - - - - - - - - - - - - - - -
// this was github issue #269
// - - - - - - - - - - - - - - - - - - - - - - - -
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/bond-query4.mol";
delete m;
m = MolFileToMol(fName);
TEST_ASSERT(m->getNumAtoms() == 5);
delete m2;
smi = "C1CCC1C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1CCC1=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "C1C=CC1=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "C1C#CC1=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CCCC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CC=CC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CC#CC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/bond-query5.mol";
delete m;
m = MolFileToMol(fName);
TEST_ASSERT(m->getNumAtoms() == 5);
delete m2;
smi = "C1CCC1C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1CCC1=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1C=CC1=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1C#CC1=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CCCC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "CC=CC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "CC#CC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/bond-query6.mol";
delete m;
m = MolFileToMol(fName);
TEST_ASSERT(m->getNumAtoms() == 5);
delete m2;
smi = "C1CCC1C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1CCC1=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1C=CC1=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1C#CC1=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CCCC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "CC=CC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "CC#CC=C";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void test4() {
// basic writing test
BOOST_LOG(rdInfoLog) << " ----------> Test4 " << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
std::string fName = rdbase + "test_data/mol1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
std::string smi = MolToSmiles(*m);
CHECK_INVARIANT(smi == "c1cc[cH-]c1", smi);
TEST_ASSERT(m->getConformer().is3D() == false);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
smi = MolToSmiles(*m);
CHECK_INVARIANT(smi == "c1cc[cH-]c1", smi);
TEST_ASSERT(m->getConformer().is3D() == false);
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void test5() {
// formerly problematic molecules
BOOST_LOG(rdInfoLog) << " ----------> Test5 " << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
std::string fName = rdbase + "test_data/issue123.mol";
RWMol *m = MolFileToMol(fName);
CHECK_INVARIANT(m, "");
TEST_ASSERT(m->getNumAtoms() == 23);
TEST_ASSERT(m->getConformer().is3D() == true);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 23);
TEST_ASSERT(m->getConformer().is3D() == true);
delete m;
// now try without removing the Hs:
m = MolFileToMol(fName, true, false);
CHECK_INVARIANT(m, "");
TEST_ASSERT(m->getNumAtoms() == 39);
}
void test6() {
BOOST_LOG(rdInfoLog) << "testing chirality parsing" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
std::string fName = rdbase + "test_data/chiral1.mol";
RWMol *m;
std::string smi, cip;
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@](F)(Cl)Br");
delete m;
fName = rdbase + "test_data/chiral1a.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@](F)(Cl)Br");
delete m;
fName = rdbase + "test_data/chiral2.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@@](F)(Cl)Br");
delete m;
fName = rdbase + "test_data/chiral2a.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@@](F)(Cl)Br");
delete m;
fName = rdbase + "test_data/chiral3.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
MolOps::assignStereochemistry(*m);
TEST_ASSERT(m->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(0)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "R");
#if 1
smi = MolToSmiles(*m, true);
// BOOST_LOG(rdInfoLog) << " smi: " << smi << std::endl;
TEST_ASSERT(smi == "C[C@H](F)Cl");
#endif
delete m;
fName = rdbase + "test_data/chiral3a.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
MolOps::assignStereochemistry(*m);
TEST_ASSERT(m->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(0)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "R");
#if 1
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@H](F)Cl");
#endif
delete m;
fName = rdbase + "test_data/chiral4.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
MolOps::assignStereochemistry(*m);
TEST_ASSERT(m->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(0)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
#if 1
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@@H](F)Cl");
#endif
delete m;
fName = rdbase + "test_data/chiral4a.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
MolOps::assignStereochemistry(*m);
TEST_ASSERT(m->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(0)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
#if 1
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@@H](F)Cl");
#endif
delete m;
fName = rdbase + "test_data/chiral5.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
MolOps::assignStereochemistry(*m);
TEST_ASSERT(!m->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
#if 1
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "CC(C)(Cl)Br");
#endif
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void test7() {
BOOST_LOG(rdInfoLog) << "testing roundtrip chirality parsing" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
RWMol *m, *m2;
std::string fName;
std::string smi, molBlock, smi2, cip;
fName = rdbase + "test_data/chiral1.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@](F)(Cl)Br");
molBlock = MolToMolBlock(*m);
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2)
smi2 = MolToSmiles(*m2, true);
TEST_ASSERT(smi == smi2);
delete m;
delete m2;
fName = rdbase + "test_data/chiral2.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@@](F)(Cl)Br");
molBlock = MolToMolBlock(*m);
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2)
smi2 = MolToSmiles(*m2, true);
TEST_ASSERT(smi == smi2);
delete m;
delete m2;
fName = rdbase + "test_data/chiral3.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
MolOps::assignStereochemistry(*m);
TEST_ASSERT(m->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(0)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "R");
#if 1
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@H](F)Cl");
molBlock = MolToMolBlock(*m);
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2)
MolOps::assignStereochemistry(*m2);
TEST_ASSERT(m2->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
m2->getAtomWithIdx(0)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "R");
smi2 = MolToSmiles(*m2, true);
TEST_ASSERT(smi == smi2);
delete m2;
#endif
delete m;
fName = rdbase + "test_data/chiral4.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
MolOps::assignStereochemistry(*m);
TEST_ASSERT(m->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(0)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
#if 1
smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C[C@@H](F)Cl");
molBlock = MolToMolBlock(*m);
// BOOST_LOG(rdInfoLog) << molBlock << std::endl;
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2)
MolOps::assignStereochemistry(*m2);
TEST_ASSERT(m2->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
m2->getAtomWithIdx(0)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
// smi2 = MolToSmiles(*m2,true);
// TEST_ASSERT(smi==smi2);
delete m2;
#endif
delete m;
fName = rdbase + "test_data/Issue142d.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
MolOps::assignStereochemistry(*m);
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(1)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "R");
#if 1
smi = MolToSmiles(*m, true);
m2 = SmilesToMol(smi);
smi2 = MolToSmiles(*m2, true);
if (smi != smi2) {
BOOST_LOG(rdInfoLog) << "\n " << smi << "\n !=\n " << smi2 << std::endl;
}
TEST_ASSERT(smi == smi2);
delete m2;
BOOST_LOG(rdInfoLog) << "SMI: " << smi << std::endl;
std::cout << "***************************************" << std::endl;
molBlock = MolToMolBlock(*m);
std::cout << "***************************************" << std::endl;
BOOST_LOG(rdInfoLog) << molBlock << std::endl;
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2)
smi2 = MolToSmiles(*m2, true);
if (smi != smi2) {
BOOST_LOG(rdInfoLog) << "\n " << smi << "\n !=\n " << smi2 << std::endl;
}
TEST_ASSERT(smi == smi2);
delete m2;
#endif
delete m;
fName = rdbase + "test_data/Issue142b.mol";
m = MolFileToMol(fName);
// BOOST_LOG(rdInfoLog) << m->getNumAtoms() << "\n";
// BOOST_LOG(rdInfoLog) << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-" <<
// std::endl;
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 9);
MolOps::assignStereochemistry(*m);
TEST_ASSERT(m->getAtomWithIdx(0)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(0)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "R");
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(1)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "R");
TEST_ASSERT(m->getAtomWithIdx(3)->hasProp(common_properties::_CIPCode));
m->getAtomWithIdx(3)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "R");
#if 1
smi = MolToSmiles(*m, true);
m2 = SmilesToMol(smi);
smi2 = MolToSmiles(*m2, true);
if (smi != smi2) {
BOOST_LOG(rdInfoLog) << "\n " << smi << "\n !=\n " << smi2 << std::endl;
}
TEST_ASSERT(smi == smi2);
delete m2;
// BOOST_LOG(rdInfoLog) << "SMI: "<< smi << std::endl;
BOOST_LOG(rdInfoLog) << m->getNumAtoms() << " "
<< m->getConformer().getNumAtoms() << "\n";
molBlock = MolToMolBlock(*m);
// BOOST_LOG(rdInfoLog) << molBlock << std::endl;
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2)
smi2 = MolToSmiles(*m2, true);
if (smi != smi2) {
BOOST_LOG(rdInfoLog) << "\n " << smi << "\n !=\n " << smi2 << std::endl;
}
TEST_ASSERT(smi == smi2);
delete m2;
#endif
delete m;
fName = rdbase + "test_data/issue142a.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 28);
#if 1
smi = MolToSmiles(*m, true);
m2 = SmilesToMol(smi);
smi2 = MolToSmiles(*m2, true);
if (smi != smi2) {
BOOST_LOG(rdInfoLog) << "\n " << smi << "\n !=\n " << smi2 << std::endl;
}
TEST_ASSERT(smi == smi2);
delete m2;
molBlock = MolToMolBlock(*m);
// BOOST_LOG(rdInfoLog) << molBlock << std::endl;
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2)
smi2 = MolToSmiles(*m2, true);
if (smi != smi2) {
BOOST_LOG(rdInfoLog) << "\n " << smi << "\n !=\n " << smi2 << std::endl;
}
TEST_ASSERT(smi == smi2);
delete m2;
#endif
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void test8() {
BOOST_LOG(rdInfoLog) << "testing reading without sanitization" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
RWMol *m;
std::string fName;
std::string smi, molBlock, smi2;
// in this case the test means to not remove Hs:
fName = rdbase + "test_data/unsanitary.mol";
m = MolFileToMol(fName, false);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 6);
delete m;
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 3);
delete m;
fName = rdbase + "test_data/unsanitary2.mol";
m = MolFileToMol(fName, false);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 9);
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue145() {
BOOST_LOG(rdInfoLog) << "testing Issue145:\n Mol parsing: molecule yields "
"non-canonical smiles from mol block"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
RWMol *m, *m2;
std::string fName;
std::string smi, molBlock, smi2;
fName = rdbase + "test_data/issue145.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 19);
smi = MolToSmiles(*m, true);
m2 = SmilesToMol(smi);
smi2 = MolToSmiles(*m2, true);
if (smi != smi2) {
BOOST_LOG(rdInfoLog) << "\n " << smi << "\n !=\n " << smi2 << std::endl;
}
TEST_ASSERT(smi == smi2);
delete m2;
molBlock = MolToMolBlock(*m);
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2)
smi2 = MolToSmiles(*m2, true);
if (smi != smi2) {
BOOST_LOG(rdInfoLog) << "\n " << smi << "\n !=\n " << smi2 << std::endl;
}
TEST_ASSERT(smi == smi2);
delete m;
delete m2;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue148() {
BOOST_LOG(rdInfoLog) << "testing Issue148:\n Mol files containing mis-drawn "
"nitro groups not properly parsed"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
RWMol *m;
std::string fName;
std::string smi, molBlock, smi2;
fName = rdbase + "test_data/issue148.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 9);
TEST_ASSERT(m->getAtomWithIdx(0)->getFormalCharge() == 1);
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue180() {
BOOST_LOG(rdInfoLog) << "testing Issue180: bad Z/E assignments" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
RWMol *m;
std::string fName;
std::string code;
Bond *bond;
fName = rdbase + "test_data/Issue180.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
bond = m->getBondWithIdx(2);
TEST_ASSERT(bond->getBondType() == Bond::DOUBLE);
TEST_ASSERT(bond->getStereo() == Bond::STEREOZ);
bond = m->getBondWithIdx(5);
TEST_ASSERT(bond->getBondType() == Bond::DOUBLE);
TEST_ASSERT(bond->getStereo() == Bond::STEREOE);
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue264() {
BOOST_LOG(rdInfoLog) << "testing Issue264: bad stereochemistry from mol files"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
RWMol *m1, *m2;
std::string smi1, smi2;
std::string fName;
fName = rdbase + "test_data/Issue264-1.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
fName = rdbase + "test_data/Issue264-2.mol";
m2 = MolFileToMol(fName);
TEST_ASSERT(m2);
smi1 = MolToSmiles(*m1, false);
smi2 = MolToSmiles(*m2, false);
TEST_ASSERT(smi1 == smi2);
smi1 = MolToSmiles(*m1, true);
smi2 = MolToSmiles(*m2, true);
BOOST_LOG(rdInfoLog) << smi1 << std::endl;
BOOST_LOG(rdInfoLog) << smi2 << std::endl;
TEST_ASSERT(smi1 != smi2);
delete m1;
delete m2;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue399() {
BOOST_LOG(rdInfoLog) << "testing Issue399: bond wedging cleanup" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
RWMol *m1;
std::string smi1, smi2;
std::string fName;
fName = rdbase + "Issue399a.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
#if 1
smi1 = MolToSmiles(*m1, true);
TEST_ASSERT(smi1 == "C[C@H]1CO1");
#endif
MolOps::assignStereochemistry(*m1);
TEST_ASSERT(m1->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
m1->getAtomWithIdx(1)->getProp(common_properties::_CIPCode, smi2);
TEST_ASSERT(smi2 == "S");
#if 1
WedgeMolBonds(*m1, &m1->getConformer());
TEST_ASSERT(m1->getBondWithIdx(0)->getBondDir() == Bond::BEGINWEDGE);
TEST_ASSERT(m1->getBondWithIdx(1)->getBondDir() == Bond::NONE);
TEST_ASSERT(m1->getBondWithIdx(2)->getBondDir() == Bond::NONE);
TEST_ASSERT(m1->getBondWithIdx(3)->getBondDir() == Bond::NONE);
#endif
delete m1;
// make sure we prefer wedging bonds to Hs:
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
MolOps::addHs(*m1, false, true);
TEST_ASSERT(m1->getAtomWithIdx(7)->getAtomicNum() == 1);
TEST_ASSERT(m1->getBondBetweenAtoms(1, 7));
TEST_ASSERT(m1->getBondBetweenAtoms(1, 7)->getBondType() == Bond::SINGLE);
TEST_ASSERT(m1->getBondBetweenAtoms(1, 7)->getBondDir() == Bond::NONE);
WedgeMolBonds(*m1, &m1->getConformer());
TEST_ASSERT(m1->getBondBetweenAtoms(1, 7)->getBondDir() == Bond::BEGINDASH);
delete m1;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileChgLines() {
BOOST_LOG(rdInfoLog) << "testing handling of charge lines" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
// SF.Net Issue1603923: problems with multiple chg lines
{
RWMol *m1;
std::string fName;
fName = rdbase + "MolFileChgBug.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getAtomWithIdx(24)->getFormalCharge() == -1);
TEST_ASSERT(m1->getAtomWithIdx(25)->getFormalCharge() == -1);
delete m1;
}
// many charges in one molecule:
{
RWMol *m1;
std::string fName;
fName = rdbase + "manycharges.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getAtomWithIdx(0)->getFormalCharge() == -1);
TEST_ASSERT(m1->getAtomWithIdx(13)->getFormalCharge() == -1);
std::string molBlock = MolToMolBlock(*m1);
// std::cerr<<molBlock<<std::endl;
delete m1;
m1 = MolBlockToMol(molBlock);
// m1->debugMol(std::cerr);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getAtomWithIdx(0)->getFormalCharge() == -1);
TEST_ASSERT(m1->getAtomWithIdx(13)->getFormalCharge() == -1);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testDblBondStereochem() {
BOOST_LOG(rdInfoLog) << "testing basic double bond stereochemistry"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
RWMol *m1;
std::string fName = rdbase + "simple_z.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondWithIdx(0)->getStereo() == Bond::STEREOZ);
delete m1;
}
{
RWMol *m1;
std::string fName = rdbase + "simple_e.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondWithIdx(0)->getStereo() == Bond::STEREOE);
delete m1;
}
{
RWMol *m1;
std::string fName = rdbase + "simple_either.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondWithIdx(0)->getStereo() == Bond::STEREOANY);
TEST_ASSERT(m1->getBondWithIdx(0)->getBondDir() == Bond::EITHERDOUBLE);
delete m1;
}
// the next group for sf.net issue 3009836
BOOST_LOG(rdInfoLog) << " sub-test for issue 3099836" << std::endl;
{
RWMol *m1;
std::string fName = rdbase + "Issue3009836.1.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondBetweenAtoms(3, 4)->getStereo() == Bond::STEREOZ);
delete m1;
}
{
RWMol *m1;
std::string fName = rdbase + "Issue3009836.2.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondBetweenAtoms(3, 4)->getStereo() == Bond::STEREOZ);
delete m1;
}
{
RWMol *m1;
std::string fName = rdbase + "Issue3009836.3.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondBetweenAtoms(6, 7)->getStereo() == Bond::STEREOE);
TEST_ASSERT(m1->getBondBetweenAtoms(10, 11)->getStereo() == Bond::STEREOZ);
delete m1;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testSymmetricDblBondStereochem() {
// this was sf.net issue 1718794:
// http://sourceforge.net/tracker/index.php?func=detail&aid=1718794&group_id=160139&atid=814650)
BOOST_LOG(rdInfoLog) << "testing double bonds with symmetric substituents"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
RWMol *m1;
std::string fName, smi;
fName = rdbase + "cistrans.1a.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondWithIdx(0)->getStereo() == Bond::STEREOE);
smi = MolToSmiles(*m1, true);
TEST_ASSERT(smi == "C/C=C/Cl");
fName = rdbase + "cistrans.2a.mol";
delete m1;
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondWithIdx(0)->getStereo() == Bond::STEREOZ);
smi = MolToSmiles(*m1, true);
TEST_ASSERT(smi == "C/C=C\\Cl");
fName = rdbase + "cistrans.1.mol";
delete m1;
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondWithIdx(0)->getStereo() == Bond::STEREOE);
smi = MolToSmiles(*m1, true);
TEST_ASSERT(smi == "C/C=C/C");
fName = rdbase + "cistrans.2.mol";
delete m1;
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondWithIdx(0)->getStereo() == Bond::STEREOZ);
smi = MolToSmiles(*m1, true);
TEST_ASSERT(smi == "C/C=C\\C");
fName = rdbase + "cistrans.3.mol";
delete m1;
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getBondWithIdx(0)->getStereo() == Bond::STEREOANY);
smi = MolToSmiles(*m1, true);
TEST_ASSERT(smi == "CC=CC");
delete m1;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testRingDblBondStereochem() {
// this was sf.net issue 1725068:
// http://sourceforge.net/tracker/index.php?func=detail&aid=1725068&group_id=160139&atid=814650
BOOST_LOG(rdInfoLog)
<< "testing double bonds in rings with stereochem specifications"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
RWMol *m1;
std::string fName, smi;
fName = rdbase + "badringstereochem3.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
smi = MolToSmiles(*m1, true);
TEST_ASSERT(smi.find("/", 0) == std::string::npos);
TEST_ASSERT(smi.find("\\", 0) == std::string::npos);
delete m1;
fName = rdbase + "badringstereochem2.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
smi = MolToSmiles(*m1, true);
TEST_ASSERT(smi.find("/", 0) == std::string::npos);
TEST_ASSERT(smi.find("\\", 0) == std::string::npos);
delete m1;
fName = rdbase + "badringstereochem.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
smi = MolToSmiles(*m1, true);
TEST_ASSERT(smi.find("/", 0) == std::string::npos);
TEST_ASSERT(smi.find("\\", 0) == std::string::npos);
delete m1;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileRGroups() {
BOOST_LOG(rdInfoLog) << "testing mol file R-group parsing" << std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/rgroups1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
unsigned int idx;
std::string label;
TEST_ASSERT(m->getAtomWithIdx(3)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(3)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 2);
TEST_ASSERT(m->getAtomWithIdx(3)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(3)->getIsotope(), 2));
TEST_ASSERT(m->getAtomWithIdx(4)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(4)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 1);
TEST_ASSERT(m->getAtomWithIdx(4)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(4)->getIsotope(), 1));
// test sf.net issue 3316600:
TEST_ASSERT(m->getAtomWithIdx(3)->hasProp(common_properties::dummyLabel));
m->getAtomWithIdx(3)->getProp(common_properties::dummyLabel, label);
TEST_ASSERT(label == "R2");
TEST_ASSERT(m->getAtomWithIdx(3)->getSymbol() == "R2");
TEST_ASSERT(m->getAtomWithIdx(4)->hasProp(common_properties::dummyLabel));
m->getAtomWithIdx(4)->getProp(common_properties::dummyLabel, label);
TEST_ASSERT(label == "R1");
TEST_ASSERT(m->getAtomWithIdx(4)->getSymbol() == "R1");
RWMol *m2;
MatchVectType mv;
std::string smi;
smi = "C1C(O)C1C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "C1CC(O)C1C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1C(CO)C1CC";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "CC(=O)CC";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/rgroups2.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(3)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(3)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 1);
TEST_ASSERT(m->getAtomWithIdx(3)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(3)->getIsotope(), 1));
TEST_ASSERT(m->getAtomWithIdx(4)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(4)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 1);
TEST_ASSERT(m->getAtomWithIdx(4)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(4)->getIsotope(), 1));
smi = "C1C(O)C1C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "C1CC(O)C1C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "C1C(CO)C1CC";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 5);
delete m2;
smi = "CC(=O)CC";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/rgroups3.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(3)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(3)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 11);
TEST_ASSERT(m->getAtomWithIdx(3)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(3)->getIsotope(), 11));
TEST_ASSERT(m->getAtomWithIdx(4)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(4)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 503);
TEST_ASSERT(m->getAtomWithIdx(4)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(4)->getIsotope(), 503));
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileDegreeQueries() {
BOOST_LOG(rdInfoLog) << "testing mol file degree queries" << std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/subst1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
RWMol *m2;
MatchVectType mv;
std::string smi;
smi = "CC(=O)O";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "CC(=O)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "CC(=O)";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/subst2.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC(=O)O";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "CC(=O)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "CC(O)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "CC(O)";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CC(O)(C)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/subst3.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC(=O)O";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 3);
delete m2;
smi = "CC(=O)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 3);
delete m2;
smi = "CC(O)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
smi = "CC(O)";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CC(O)(C)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/subst4.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC(=O)O";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
{
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/combined.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC(=O)[CH-]C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "CC(=O)[C-](C)C";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "CC(=O)CC";
m2 = SmilesToMol(smi, false, false);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
}
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileRBCQueries() {
BOOST_LOG(rdInfoLog) << "testing mol file ring-bond count queries"
<< std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName;
RWMol *m;
RWMol *m2;
MatchVectType mv;
std::string smi;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_2.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C1CCC1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 2);
delete m2;
smi = "C12C3C4C1C5C2C3C45";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_3.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C1CCC1";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C12C3C4C1C5C2C3C45";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 2);
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_0.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 2);
delete m2;
smi = "C1CCC1";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_4.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C1CCC1";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C12C3C4C1C5C2C3C45";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C1CS234C5CC2CC13CC4C5";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 2);
delete m2;
smi = "C1C2CC3CC4CC1S234";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 2);
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_star.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 2);
delete m2;
smi = "C1CCC1";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_star2.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C1CCC1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "C1CC2C1CC2";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "C12C3C4C1C5C2C3C45";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_star3.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CC";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C1CCC1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 4);
delete m2;
smi = "C1CC2C1CC2";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C12C3C4C1C5C2C3C45";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileUnsaturationQueries() {
BOOST_LOG(rdInfoLog) << "testing mol file unsaturation queries" << std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName;
RWMol *m;
RWMol *m2;
MatchVectType mv;
std::string smi;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/unsaturation.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
smi = "CO";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C=O";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 2);
delete m2;
smi = "CCO";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 0);
delete m2;
smi = "C=CO";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 2);
delete m2;
smi = "C#CO";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 2);
delete m2;
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileQueryToSmarts() {
BOOST_LOG(rdInfoLog) << "testing mol file queries -> SMARTS " << std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName;
RWMol *m;
std::string sma;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_2.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
sma = MolToSmarts(*m, true);
TEST_ASSERT(sma == "[#6&x2]-[#6]")
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_3.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
sma = MolToSmarts(*m, true);
TEST_ASSERT(sma == "[#6&x3]-[#6]")
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_0.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
sma = MolToSmarts(*m, true);
TEST_ASSERT(sma == "[#6&x0]-[#6]")
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_4.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
sma = MolToSmarts(*m, true);
TEST_ASSERT(sma == "[#16&x4]-[#6]")
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_star.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
sma = MolToSmarts(*m, true);
TEST_ASSERT(sma == "[#6&x0]-[#6]")
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/ringcount_star2.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
sma = MolToSmarts(*m, true);
TEST_ASSERT(sma.find("[#6&x2]") != std::string::npos);
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/unsaturation.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
sma = MolToSmarts(*m, true);
TEST_ASSERT(sma == "[#6;$(*=,:,#*)]~[#8]")
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMissingFiles() {
BOOST_LOG(rdInfoLog) << "testing handling of missing files" << std::endl;
std::string fName;
bool ok;
RWMol *m;
(void)m;
fName = "bogus_file.mol";
ok = false;
try {
m = MolFileToMol(fName);
} catch (BadFileException &e) {
ok = true;
}
TEST_ASSERT(ok);
ok = false;
try {
m = TPLFileToMol(fName);
} catch (BadFileException &e) {
ok = true;
}
TEST_ASSERT(ok);
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue1965035() {
BOOST_LOG(rdInfoLog)
<< "testing issue Issue1965035: problems with WedgeMolBonds "
<< std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName;
RWMol *m;
std::string sma;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue1965035.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
// the mol file parser removes bond wedging info:
TEST_ASSERT(m->getBondWithIdx(4)->getBondDir() == Bond::NONE);
// but a chiral tag is assigned:
TEST_ASSERT(m->getAtomWithIdx(2)->getChiralTag() == Atom::CHI_TETRAHEDRAL_CW);
WedgeMolBonds(*m, &m->getConformer());
TEST_ASSERT(m->getBondWithIdx(4)->getBondDir() == Bond::BEGINDASH);
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testRadicals() {
BOOST_LOG(rdInfoLog) << "testing handling of radicals " << std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName;
RWMol *m;
std::string smiles;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/radical.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(0)->getNumRadicalElectrons() == 0);
TEST_ASSERT(m->getAtomWithIdx(1)->getNumRadicalElectrons() == 1);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(0)->getNumRadicalElectrons() == 0);
TEST_ASSERT(m->getAtomWithIdx(1)->getNumRadicalElectrons() == 1);
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testBadBondOrders() {
BOOST_LOG(rdInfoLog)
<< "testing handling of bogus bond orders (issue 2337369)" << std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName;
RWMol *m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/bondorder0.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondBetweenAtoms(0, 1)->getBondType() == Bond::UNSPECIFIED);
TEST_ASSERT(!m->getBondBetweenAtoms(0, 1)->hasQuery());
delete m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/bondorder9.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondBetweenAtoms(0, 1)->hasQuery());
TEST_ASSERT(m->getBondBetweenAtoms(0, 1)->getQuery()->getDescription() ==
"BondNull");
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testAtomParity() {
BOOST_LOG(rdInfoLog) << "testing handling of atom stereo parity flags"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
int parity;
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/parity.simple1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(!m->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 1);
// if we don't perceive the stereochem first, no parity
// flags end up in the output:
std::string molBlock = MolToMolBlock(*m);
RWMol *m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2);
TEST_ASSERT(!m2->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(!m2->getAtomWithIdx(1)->hasProp(common_properties::molParity));
delete m2;
// now perceive stereochem, then look for the parity
// flags:
MolOps::assignChiralTypesFrom3D(*m);
molBlock = MolToMolBlock(*m);
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2);
TEST_ASSERT(!m2->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m2->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m2->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 1);
delete m2;
delete m;
}
{
int parity;
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/parity.simple2.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(!m->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 2);
MolOps::assignChiralTypesFrom3D(*m);
std::string molBlock = MolToMolBlock(*m);
RWMol *m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2);
TEST_ASSERT(!m2->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m2->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m2->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 2);
delete m2;
delete m;
}
{
// a case with an H on the chiral center:
int parity;
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/parity.simpleH1.mol";
RWMol *m = MolFileToMol(fName, true, false);
TEST_ASSERT(m);
TEST_ASSERT(!m->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 1);
MolOps::assignChiralTypesFrom3D(*m);
std::string molBlock = MolToMolBlock(*m);
RWMol *m2 = MolBlockToMol(molBlock, true, false);
TEST_ASSERT(m2);
TEST_ASSERT(!m2->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m2->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m2->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 1);
delete m2;
// if we remove the H and write things out, we should
// still get the right answer back:
m2 = (RWMol *)MolOps::removeHs(*((ROMol *)m));
molBlock = MolToMolBlock(*m2);
delete m2;
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2);
TEST_ASSERT(!m2->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m2->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m2->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 1);
delete m2;
delete m;
}
{
// a case with an H on the chiral center:
int parity;
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/parity.simpleH2.mol";
RWMol *m = MolFileToMol(fName, true, false);
TEST_ASSERT(m);
TEST_ASSERT(!m->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 2);
MolOps::assignChiralTypesFrom3D(*m);
std::string molBlock = MolToMolBlock(*m);
RWMol *m2 = MolBlockToMol(molBlock, true, false);
TEST_ASSERT(m2);
TEST_ASSERT(!m2->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m2->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m2->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 2);
delete m2;
m2 = (RWMol *)MolOps::removeHs(*((ROMol *)m));
molBlock = MolToMolBlock(*m2);
delete m2;
m2 = MolBlockToMol(molBlock);
TEST_ASSERT(m2);
TEST_ASSERT(!m2->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m2->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m2->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 2);
delete m2;
delete m;
}
{
// a case with an N as the "chiral" center
int parity;
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/parity.nitrogen.mol";
RWMol *m = MolFileToMol(fName, true, false);
TEST_ASSERT(m);
TEST_ASSERT(!m->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::molParity));
m->getAtomWithIdx(1)->getProp(common_properties::molParity, parity);
TEST_ASSERT(parity == 1);
MolOps::assignChiralTypesFrom3D(*m);
std::string molBlock = MolToMolBlock(*m);
RWMol *m2 = MolBlockToMol(molBlock, true, false);
TEST_ASSERT(m2);
TEST_ASSERT(!m2->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(!m2->getAtomWithIdx(1)->hasProp(common_properties::molParity));
delete m2;
delete m;
}
{
// a case with two Hs on the chiral center:
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/parity.twoHs.mol";
RWMol *m = MolFileToMol(fName, true, false);
TEST_ASSERT(m);
TEST_ASSERT(!m->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(!m->getAtomWithIdx(1)->hasProp(common_properties::molParity));
// add a bogus chiral spec:
m->getAtomWithIdx(0)->setChiralTag(Atom::CHI_TETRAHEDRAL_CW);
std::string molBlock = MolToMolBlock(*m);
RWMol *m2 = (RWMol *)MolOps::removeHs(*((ROMol *)m));
molBlock = MolToMolBlock(*m2);
delete m2;
m2 = MolBlockToMol(molBlock, true, false);
TEST_ASSERT(m2);
TEST_ASSERT(!m2->getAtomWithIdx(0)->hasProp(common_properties::molParity));
TEST_ASSERT(!m2->getAtomWithIdx(1)->hasProp(common_properties::molParity));
delete m2;
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue2692246() {
// basic writing test
BOOST_LOG(rdInfoLog) << " Testing issue 2692246 " << std::endl;
std::string smiles(120, 'C');
smiles += "[CH3+]";
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 121);
TEST_ASSERT(m->getAtomWithIdx(120)->getFormalCharge() == 1);
delete m;
BOOST_LOG(rdInfoLog) << " done" << std::endl;
}
void testKekulizationSkip() {
// basic writing test
BOOST_LOG(rdInfoLog) << " Testing mol blocks without kekulization "
<< std::endl;
std::string smiles("c1ccccc1");
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
std::string molBlock = MolToMolBlock(*m, true, -1, false);
TEST_ASSERT(molBlock.find("1 2 4") != std::string::npos);
TEST_ASSERT(molBlock.find("2 3 4") != std::string::npos);
TEST_ASSERT(molBlock.find("3 4 4") != std::string::npos);
molBlock = MolToMolBlock(*m);
TEST_ASSERT(molBlock.find("1 2 4") == std::string::npos);
TEST_ASSERT(molBlock.find("2 3 4") == std::string::npos);
TEST_ASSERT(molBlock.find("3 4 4") == std::string::npos);
delete m;
BOOST_LOG(rdInfoLog) << " done" << std::endl;
}
void testMolFileAtomValues() {
BOOST_LOG(rdInfoLog) << "testing atom values in mol files" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/";
{
RWMol *m;
std::string fName, val;
fName = rdbase + "test_data/AtomProps1.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(
!m->getAtomWithIdx(0)->hasProp(common_properties::molFileValue));
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::molFileValue));
m->getAtomWithIdx(1)->getProp(common_properties::molFileValue, val);
TEST_ASSERT(val == "acidchloride");
TEST_ASSERT(getAtomValue(m->getAtomWithIdx(1)) == "acidchloride")
TEST_ASSERT(
m->getAtomWithIdx(0)->hasProp(common_properties::molAtomMapNumber));
TEST_ASSERT(
m->getAtomWithIdx(1)->hasProp(common_properties::molAtomMapNumber));
TEST_ASSERT(
m->getAtomWithIdx(2)->hasProp(common_properties::molAtomMapNumber));
TEST_ASSERT(
!m->getAtomWithIdx(3)->hasProp(common_properties::molAtomMapNumber));
TEST_ASSERT(m->getAtomWithIdx(0)->getAtomMapNum() == 1);
TEST_ASSERT(m->getAtomWithIdx(1)->getAtomMapNum() == 2);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomMapNum() == 3);
TEST_ASSERT(m->getAtomWithIdx(3)->getAtomMapNum() == 0);
// round trip
m->getAtomWithIdx(0)->setAtomMapNum(4);
setAtomRLabel(m->getAtomWithIdx(3), 1);
setAtomAlias(m->getAtomWithIdx(0), "acidchloride");
setAtomValue(m->getAtomWithIdx(0), "foobar");
RWMol *m2 = MolBlockToMol(MolToMolBlock(*m));
TEST_ASSERT(m2);
TEST_ASSERT(m->getAtomWithIdx(0)->getAtomMapNum() == 4);
TEST_ASSERT(m->getAtomWithIdx(1)->getAtomMapNum() == 2);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomMapNum() == 3);
TEST_ASSERT(m->getAtomWithIdx(3)->getAtomMapNum() == 0);
TEST_ASSERT(getAtomRLabel(m->getAtomWithIdx(3)) == 1);
TEST_ASSERT(getAtomAlias(m->getAtomWithIdx(0)) == "acidchloride");
TEST_ASSERT(getAtomValue(m->getAtomWithIdx(0)) == "foobar");
delete m;
delete m2;
}
{
RWMol *m;
std::string fName, val;
fName = rdbase + "test_data/AtomProps2.mol";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(
!m->getAtomWithIdx(0)->hasProp(common_properties::molFileValue));
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::molFileValue));
m->getAtomWithIdx(1)->getProp(common_properties::molFileValue, val);
TEST_ASSERT(val == "acidchloride");
TEST_ASSERT(m->getAtomWithIdx(2)->hasProp(common_properties::molFileValue));
m->getAtomWithIdx(2)->getProp(common_properties::molFileValue, val);
TEST_ASSERT(val == "testing");
TEST_ASSERT(m->getAtomWithIdx(3)->getFormalCharge() == -1);
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileAtomQueries() {
BOOST_LOG(rdInfoLog) << "testing handling of A, Q, and * in mol files"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/query_star.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
RWMol *m2;
MatchVectType mv;
std::string smi;
smi = "[H]c1ccccc1";
m2 = SmilesToMol(smi, false, false);
MolOps::sanitizeMol(*m2);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 7);
delete m2;
smi = "Cc1ccccc1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 7);
delete m2;
smi = "Clc1ccccc1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 7);
delete m2;
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/query_A.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
RWMol *m2;
MatchVectType mv;
std::string smi;
smi = "[H]c1ccccc1";
m2 = SmilesToMol(smi, false, false);
MolOps::sanitizeMol(*m2);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "Cc1ccccc1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 7);
delete m2;
smi = "Clc1ccccc1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 7);
delete m2;
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/query_Q.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
RWMol *m2;
MatchVectType mv;
std::string smi;
smi = "[H]c1ccccc1";
m2 = SmilesToMol(smi, false, false);
MolOps::sanitizeMol(*m2);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "Cc1ccccc1";
m2 = SmilesToMol(smi);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smi = "Clc1ccccc1";
m2 = SmilesToMol(smi);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 7);
delete m2;
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testListsAndValues() {
BOOST_LOG(rdInfoLog)
<< "testing handling of mol files with atom lists and values"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/lists_plus_values.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
std::string value;
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::molFileValue));
m->getAtomWithIdx(1)->getProp(common_properties::molFileValue, value);
TEST_ASSERT(value == "halogen");
TEST_ASSERT(m->getAtomWithIdx(1)->hasQuery());
TEST_ASSERT(m->getAtomWithIdx(1)->getQuery()->getDescription() == "AtomOr");
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void test1V3K() {
BOOST_LOG(rdInfoLog) << "testing basic handling of v3000 mol files"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 8);
TEST_ASSERT(m->getNumBonds() == 8);
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.3.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 9);
TEST_ASSERT(m->getNumBonds() == 9);
TEST_ASSERT(m->getAtomWithIdx(4)->getFormalCharge() == -1);
TEST_ASSERT(m->getAtomWithIdx(4)->getIsotope() == 17);
// m->debugMol(std::cerr);
// TEST_ASSERT(m->getBondWithIdx(8)->getBondDir()==Bond::BEGINWEDGE);
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.5a.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
TEST_ASSERT(m->getNumBonds() == 4);
TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag() != Atom::CHI_UNSPECIFIED);
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.5b.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
TEST_ASSERT(m->getNumBonds() == 4);
TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag() == Atom::CHI_UNSPECIFIED);
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.6a.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
TEST_ASSERT(m->getNumBonds() == 3);
TEST_ASSERT(m->getBondWithIdx(0)->getStereo() == Bond::STEREOE);
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.6b.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
TEST_ASSERT(m->getNumBonds() == 3);
TEST_ASSERT(m->getBondWithIdx(0)->getStereo() == Bond::STEREOANY);
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.crash1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 7);
TEST_ASSERT(m->getNumBonds() == 7);
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void test2V3K() {
BOOST_LOG(rdInfoLog) << "testing more queries from v3000 mol files"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.2.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 8);
TEST_ASSERT(m->getNumBonds() == 8);
std::string smiles = "O=C(O)C1OCCC1";
RWMol *m2 = SmilesToMol(smiles);
MatchVectType mv;
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "O=C(O)C1OCCC1";
m2 = SmilesToMol(smiles);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "O=C(O)C1SCCS1";
m2 = SmilesToMol(smiles);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "O=C(O)C1OCCN1";
m2 = SmilesToMol(smiles);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "O=C(O)C1OCCO1";
m2 = SmilesToMol(smiles);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.4a.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 2);
TEST_ASSERT(m->getNumBonds() == 1);
std::string smiles = "OC1OCC1";
RWMol *m2 = SmilesToMol(smiles);
MatchVectType mv;
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "C1OCC1";
m2 = SmilesToMol(smiles);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "COCC";
m2 = SmilesToMol(smiles);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.4b.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 2);
TEST_ASSERT(m->getNumBonds() == 1);
std::string smiles = "OC1OCC1";
RWMol *m2 = SmilesToMol(smiles);
MatchVectType mv;
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "C1OCC1";
m2 = SmilesToMol(smiles);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "COCC";
m2 = SmilesToMol(smiles);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/v3k.rbc.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 3);
TEST_ASSERT(m->getNumBonds() == 2);
std::string smiles = "C1CC1";
RWMol *m2 = SmilesToMol(smiles);
TEST_ASSERT(m2);
MatchVectType mv;
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "CCC";
m2 = SmilesToMol(smiles);
TEST_ASSERT(m2);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
smiles = "N1NC2NNC12";
m2 = SmilesToMol(smiles);
TEST_ASSERT(m2);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/chebi_15469.v3k.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 53);
TEST_ASSERT(m->getNumBonds() == 55);
TEST_ASSERT(m->getAtomWithIdx(52)->getAtomicNum() == 0);
TEST_ASSERT(!m->getAtomWithIdx(52)->hasQuery());
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/chebi_57262.v3k.2.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 22);
TEST_ASSERT(m->getNumBonds() == 21);
TEST_ASSERT(m->getAtomWithIdx(18)->getAtomicNum() == 0);
TEST_ASSERT(!m->getAtomWithIdx(18)->hasQuery());
TEST_ASSERT(m->getAtomWithIdx(18)->getIsotope() == 1);
TEST_ASSERT(m->getAtomWithIdx(21)->getAtomicNum() == 0);
TEST_ASSERT(!m->getAtomWithIdx(21)->hasQuery());
TEST_ASSERT(m->getAtomWithIdx(21)->getIsotope() == 2);
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/chebi_57262.v3k.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 22);
TEST_ASSERT(m->getNumBonds() == 21);
TEST_ASSERT(m->getAtomWithIdx(18)->getAtomicNum() == 0);
TEST_ASSERT(!m->getAtomWithIdx(18)->hasQuery());
TEST_ASSERT(m->getAtomWithIdx(18)->getIsotope() == 1);
TEST_ASSERT(m->getAtomWithIdx(21)->getAtomicNum() == 0);
TEST_ASSERT(!m->getAtomWithIdx(21)->hasQuery());
TEST_ASSERT(m->getAtomWithIdx(21)->getIsotope() == 2);
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void test3V3K() {
BOOST_LOG(rdInfoLog) << "testing basic writing of v3000 mol files"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
std::string fName;
{
// charges
fName = rdbase + "issue148.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 9);
TEST_ASSERT(m->getAtomWithIdx(0)->getFormalCharge() == 1);
std::string mb = MolToMolBlock(*m, true, -1, true, true);
delete m;
m = MolBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 9);
TEST_ASSERT(m->getAtomWithIdx(0)->getFormalCharge() == 1);
delete m;
}
{
// multiple charge lines
fName = rdbase + "MolFileChgBug.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(24)->getFormalCharge() == -1);
TEST_ASSERT(m->getAtomWithIdx(25)->getFormalCharge() == -1);
std::string mb = MolToMolBlock(*m, true, -1, true, true);
delete m;
m = MolBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(24)->getFormalCharge() == -1);
TEST_ASSERT(m->getAtomWithIdx(25)->getFormalCharge() == -1);
delete m;
}
{
// radicals
fName = rdbase + "radical.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(0)->getNumRadicalElectrons() == 0);
TEST_ASSERT(m->getAtomWithIdx(1)->getNumRadicalElectrons() == 1);
std::string mb = MolToMolBlock(*m, true, -1, true, true);
delete m;
m = MolBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(0)->getNumRadicalElectrons() == 0);
TEST_ASSERT(m->getAtomWithIdx(1)->getNumRadicalElectrons() == 1);
delete m;
}
{
// radical and valence
fName = rdbase + "CH.v3k.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 1);
TEST_ASSERT(m->getAtomWithIdx(0)->getNoImplicit());
TEST_ASSERT(m->getAtomWithIdx(0)->getNumExplicitHs() == 1);
TEST_ASSERT(m->getAtomWithIdx(0)->getNumRadicalElectrons() == 1);
std::string mb = MolToMolBlock(*m, true, -1, true, true);
delete m;
// no bonds in this one, make sure there's no bond block:
TEST_ASSERT(mb.find("BEGIN ATOM") != std::string::npos);
TEST_ASSERT(mb.find("BEGIN BOND") == std::string::npos);
m = MolBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 1);
TEST_ASSERT(m->getAtomWithIdx(0)->getNoImplicit());
TEST_ASSERT(m->getAtomWithIdx(0)->getNumExplicitHs() == 1);
TEST_ASSERT(m->getAtomWithIdx(0)->getNumRadicalElectrons() == 1);
delete m;
}
{
// R Groups
fName = rdbase + "rgroups1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
unsigned int idx;
std::string label;
TEST_ASSERT(
m->getAtomWithIdx(3)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(3)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 2);
TEST_ASSERT(m->getAtomWithIdx(3)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(3)->getIsotope(), 2));
TEST_ASSERT(
m->getAtomWithIdx(4)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(4)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 1);
TEST_ASSERT(m->getAtomWithIdx(4)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(4)->getIsotope(), 1));
TEST_ASSERT(m->getAtomWithIdx(3)->hasProp(common_properties::dummyLabel));
m->getAtomWithIdx(3)->getProp(common_properties::dummyLabel, label);
TEST_ASSERT(label == "R2");
TEST_ASSERT(m->getAtomWithIdx(3)->getSymbol() == "R2");
TEST_ASSERT(m->getAtomWithIdx(4)->hasProp(common_properties::dummyLabel));
m->getAtomWithIdx(4)->getProp(common_properties::dummyLabel, label);
TEST_ASSERT(label == "R1");
TEST_ASSERT(m->getAtomWithIdx(4)->getSymbol() == "R1");
std::string mb = MolToMolBlock(*m, true, -1, true, true);
delete m;
m = MolBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(
m->getAtomWithIdx(3)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(3)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 2);
TEST_ASSERT(m->getAtomWithIdx(3)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(3)->getIsotope(), 2));
TEST_ASSERT(
m->getAtomWithIdx(4)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(4)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 1);
TEST_ASSERT(m->getAtomWithIdx(4)->getAtomicNum() == 0);
TEST_ASSERT(feq(m->getAtomWithIdx(4)->getIsotope(), 1));
TEST_ASSERT(m->getAtomWithIdx(3)->hasProp(common_properties::dummyLabel));
m->getAtomWithIdx(3)->getProp(common_properties::dummyLabel, label);
TEST_ASSERT(label == "R2");
TEST_ASSERT(m->getAtomWithIdx(3)->getSymbol() == "R2");
TEST_ASSERT(m->getAtomWithIdx(4)->hasProp(common_properties::dummyLabel));
m->getAtomWithIdx(4)->getProp(common_properties::dummyLabel, label);
TEST_ASSERT(label == "R1");
TEST_ASSERT(m->getAtomWithIdx(4)->getSymbol() == "R1");
delete m;
}
{
// automatic cut over to v3k
std::string smiles(1024, 'C');
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 1024);
std::string mb = MolToMolBlock(*m);
TEST_ASSERT(mb.find("V2000") == std::string::npos);
TEST_ASSERT(mb.find("V3000") != std::string::npos);
delete m;
}
{
// D in CTAB
fName = rdbase + "D_in_CTAB.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 3);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomicNum() == 1);
TEST_ASSERT(m->getAtomWithIdx(2)->getIsotope() == 2);
std::string mb = MolToMolBlock(*m, true, -1, true, true);
delete m;
m = MolBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 3);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomicNum() == 1);
TEST_ASSERT(m->getAtomWithIdx(2)->getIsotope() == 2);
delete m;
}
{
// T in CTAB
fName = rdbase + "T_in_CTAB.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 3);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomicNum() == 1);
TEST_ASSERT(m->getAtomWithIdx(2)->getIsotope() == 3);
std::string mb = MolToMolBlock(*m, true, -1, true, true);
delete m;
m = MolBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 3);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomicNum() == 1);
TEST_ASSERT(m->getAtomWithIdx(2)->getIsotope() == 3);
delete m;
}
{
// atom list
fName = rdbase + "list-query.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 6);
std::string sma = MolToSmarts(*m);
TEST_ASSERT(sma == "[#6]1:[#6]:[#6]:[#6]:[#6]:[#6,#7,#15]:1");
std::string mb = MolToMolBlock(*m, true, -1, true, true);
delete m;
m = MolBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 6);
sma = MolToSmarts(*m);
TEST_ASSERT(sma == "[#6]1:[#6]:[#6]:[#6]:[#6]:[#6,#7,#15]:1");
}
{
// not atom list
fName = rdbase + "not-list-query.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
std::string sma = MolToSmarts(*m);
TEST_ASSERT(sma == "[#6]-[#6](-[#6])=[!#7&!#8]");
std::string mb = MolToMolBlock(*m, true, -1, true, true);
delete m;
m = MolBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
sma = MolToSmarts(*m);
TEST_ASSERT(sma == "[#6]-[#6](-[#6])=[!#7&!#8]");
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue2963522() {
BOOST_LOG(rdInfoLog) << " Testing issue 2963522 " << std::endl;
{
std::string smiles = "CC=CC";
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREONONE);
Conformer *conf = new Conformer(m->getNumAtoms());
conf->setAtomPos(0, RDGeom::Point3D(-1, 1, 0));
conf->setAtomPos(1, RDGeom::Point3D(0, 1, 0));
conf->setAtomPos(2, RDGeom::Point3D(0, -1, 0));
conf->setAtomPos(3, RDGeom::Point3D(1, -1, 0));
m->addConformer(conf, true);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREOANY);
delete m;
}
{
std::string smiles = "C/C=C\\C";
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREOZ);
Conformer *conf = new Conformer(m->getNumAtoms());
conf->setAtomPos(0, RDGeom::Point3D(-1, 1, 0));
conf->setAtomPos(1, RDGeom::Point3D(0, 1, 0));
conf->setAtomPos(2, RDGeom::Point3D(0, -1, 0));
conf->setAtomPos(3, RDGeom::Point3D(-1, -1, 0));
m->addConformer(conf, true);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREOZ);
delete m;
}
{
std::string smiles = "C/C=C/C";
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREOE);
Conformer *conf = new Conformer(m->getNumAtoms());
conf->setAtomPos(0, RDGeom::Point3D(-1, 1, 0));
conf->setAtomPos(1, RDGeom::Point3D(0, 1, 0));
conf->setAtomPos(2, RDGeom::Point3D(0, -1, 0));
conf->setAtomPos(3, RDGeom::Point3D(1, -1, 0));
m->addConformer(conf, true);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREOE);
delete m;
}
{
std::string smiles = "C1C=CC1";
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREONONE);
Conformer *conf = new Conformer(m->getNumAtoms());
conf->setAtomPos(0, RDGeom::Point3D(-1, 1, 0));
conf->setAtomPos(1, RDGeom::Point3D(0, 1, 0));
conf->setAtomPos(2, RDGeom::Point3D(0, -1, 0));
conf->setAtomPos(3, RDGeom::Point3D(-1, -1, 0));
m->addConformer(conf, true);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREONONE);
delete m;
}
{
// this was issue 3009756:
std::string smiles = "CC(=O)C";
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREONONE);
Conformer *conf = new Conformer(m->getNumAtoms());
conf->setAtomPos(0, RDGeom::Point3D(-1, 0, 0));
conf->setAtomPos(1, RDGeom::Point3D(0, 0, 0));
conf->setAtomPos(2, RDGeom::Point3D(0, 1, 0));
conf->setAtomPos(3, RDGeom::Point3D(1, 0, 0));
m->addConformer(conf, true);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREONONE);
delete m;
}
{
// this was issue 3009756:
std::string smiles = "CC(=C)Cl";
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREONONE);
Conformer *conf = new Conformer(m->getNumAtoms());
conf->setAtomPos(0, RDGeom::Point3D(-1, 0, 0));
conf->setAtomPos(1, RDGeom::Point3D(0, 0, 0));
conf->setAtomPos(2, RDGeom::Point3D(0, 1, 0));
conf->setAtomPos(3, RDGeom::Point3D(1, 0, 0));
m->addConformer(conf, true);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(1)->getStereo() == Bond::STEREONONE);
delete m;
}
BOOST_LOG(rdInfoLog) << " done" << std::endl;
}
void testIssue3073163() {
BOOST_LOG(rdInfoLog) << " Testing issue 3073163 " << std::endl;
{
std::string smiles = "C[2H]";
RWMol *m = SmilesToMol(smiles);
TEST_ASSERT(m);
smiles = "[2#1]";
RWMol *p = SmartsToMol(smiles);
TEST_ASSERT(p);
MatchVectType mv;
TEST_ASSERT(SubstructMatch(*m, *p, mv));
std::string mb = MolToMolBlock(*m);
// std::cerr<<"mb:\n"<<mb<<"----\n";
RWMol *m2 = MolBlockToMol(mb);
TEST_ASSERT(m2);
// std::cerr<<" mol: "<<MolToSmiles(*m,true)<<std::endl;
// std::cerr<<" mol2: "<<MolToSmiles(*m2,true)<<std::endl;
TEST_ASSERT(SubstructMatch(*m2, *p, mv));
delete m2;
delete m;
delete p;
}
BOOST_LOG(rdInfoLog) << " done" << std::endl;
}
void testIssue3154208() {
BOOST_LOG(rdInfoLog) << " Testing Issue3154208 (a large mol failure)"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/largemol.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 476);
TEST_ASSERT(m->getNumBonds() == 531);
std::cerr << "generating smiles" << std::endl;
std::string smiles = MolToSmiles(*m, false, false, -1, false);
std::cerr << "smiles: " << smiles << std::endl;
std::cerr << "converting back" << std::endl;
RWMol *m2 = SmilesToMol(smiles);
TEST_ASSERT(m2);
TEST_ASSERT(m2->getNumAtoms() == 476);
TEST_ASSERT(m2->getNumBonds() == 531);
MatchVectType mv;
std::cerr << "check isomorphism" << std::endl;
TEST_ASSERT(SubstructMatch(*m, *m2, mv));
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
#if 1
BOOST_LOG(rdInfoLog) << "Large molecule canonical smiles test" << std::endl;
std::string csmiles = MolToSmiles(*m);
for (unsigned int i = 0; i < 50; ++i) {
if (!(i % 10)) {
BOOST_LOG(rdInfoLog) << "Iteration: " << i + 1 << " of 50" << std::endl;
}
std::string nsmiles = MolToSmiles(*m, false, false, 2 * i, false);
RWMol *nm = SmilesToMol(nsmiles);
TEST_ASSERT(nm);
TEST_ASSERT(nm->getNumAtoms() == 476);
TEST_ASSERT(nm->getNumBonds() == 531);
nsmiles = MolToSmiles(*m);
if (nsmiles != csmiles) {
std::cerr << "MISMATCH:\n" << nsmiles << "\n" << csmiles << "\n";
}
TEST_ASSERT(nsmiles == csmiles);
delete nm;
}
#endif
delete m;
}
BOOST_LOG(rdInfoLog) << " done" << std::endl;
}
void testIssue3228150() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Issue 3228150: round-trip stereochemistry failure"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName;
RWMol *m;
fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3228150.sdf";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(0)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(0)->getStereo() == Bond::STEREOZ);
TEST_ASSERT(m->getBondWithIdx(2)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(2)->getStereo() == Bond::STEREOZ);
std::string smi1 = MolToSmiles(*m, true);
BOOST_LOG(rdInfoLog) << " : " << smi1 << std::endl;
m->clearComputedProps();
m->updatePropertyCache();
std::string smi2 = MolToSmiles(*m, true);
BOOST_LOG(rdInfoLog) << " : " << smi2 << std::endl;
TEST_ASSERT(smi1 == smi2);
delete m;
}
{
std::string fName;
RWMol *m;
fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3228150.full.sdf";
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(2)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(2)->getStereo() == Bond::STEREOZ);
TEST_ASSERT(m->getBondWithIdx(4)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(4)->getStereo() == Bond::STEREOZ);
TEST_ASSERT(m->getBondWithIdx(6)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(6)->getStereo() == Bond::STEREOZ);
TEST_ASSERT(m->getBondWithIdx(8)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(8)->getStereo() == Bond::STEREOZ);
std::string smi1 = MolToSmiles(*m, true);
BOOST_LOG(rdInfoLog) << " : " << smi1 << std::endl;
MolOps::assignStereochemistry(*m, true, true);
TEST_ASSERT(m->getBondWithIdx(2)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(2)->getStereo() == Bond::STEREOZ);
TEST_ASSERT(m->getBondWithIdx(4)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(4)->getStereo() == Bond::STEREOZ);
TEST_ASSERT(m->getBondWithIdx(6)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(6)->getStereo() == Bond::STEREOZ);
TEST_ASSERT(m->getBondWithIdx(8)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(8)->getStereo() == Bond::STEREOZ);
std::string smi2 = MolToSmiles(*m, true);
smi2 = MolToSmiles(*m, true);
BOOST_LOG(rdInfoLog) << " : " << smi2 << std::endl;
TEST_ASSERT(smi1 == smi2);
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue3313540() {
BOOST_LOG(rdInfoLog) << "testing writing mol file R-groups (issue 3313540)"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/rgroups1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
unsigned int idx;
TEST_ASSERT(
m->getAtomWithIdx(3)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(3)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 2);
TEST_ASSERT(
m->getAtomWithIdx(4)->hasProp(common_properties::_MolFileRLabel));
m->getAtomWithIdx(4)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 1);
std::string mb = MolToMolBlock(*m);
RWMol *m2 = MolBlockToMol(mb);
TEST_ASSERT(m2);
TEST_ASSERT(
m2->getAtomWithIdx(3)->hasProp(common_properties::_MolFileRLabel));
m2->getAtomWithIdx(3)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 2);
TEST_ASSERT(
m2->getAtomWithIdx(4)->hasProp(common_properties::_MolFileRLabel));
m2->getAtomWithIdx(4)->getProp(common_properties::_MolFileRLabel, idx);
TEST_ASSERT(idx == 1);
delete m;
delete m2;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue3359739() {
// basic writing test
BOOST_LOG(rdInfoLog) << " ----------> Test issue 3359739 " << std::endl;
std::string smi = "[C]C";
RWMol *m = SmilesToMol(smi);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(0)->getNumRadicalElectrons() == 3);
std::string molBlock = MolToMolBlock(*m);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
// NOTE: the following is correct according to the current
// state of the code and what the CTAB format supports,
// but it's definitely not chemically correct
TEST_ASSERT(m->getAtomWithIdx(0)->getNumRadicalElectrons() == 1);
delete m;
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testIssue3374639() {
// basic writing test
BOOST_LOG(rdInfoLog) << " ----------> Test issue 3374639 " << std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3374639.2.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
std::string cip;
m->getAtomWithIdx(1)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3374639.1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
std::string cip;
m->getAtomWithIdx(1)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3374639.full.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getAtomWithIdx(16)->hasProp(common_properties::_CIPCode));
std::string cip;
m->getAtomWithIdx(16)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
delete m;
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testThreeCoordinateChirality() {
// basic writing test
BOOST_LOG(rdInfoLog) << " ----------> Test three-coordinate chirality "
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/three_coordinate_chirality.1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
std::string cip;
m->getAtomWithIdx(1)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
delete m;
}
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/three_coordinate_chirality.2.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
std::string cip;
m->getAtomWithIdx(1)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
delete m;
}
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/three_coordinate_chirality.3.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(!m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
delete m;
}
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/three_coordinate_chirality.4.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(!m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
delete m;
}
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/three_coordinate_chirality.5.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
std::string cip;
m->getAtomWithIdx(1)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
delete m;
}
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/three_coordinate_chirality.6.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
std::string cip;
m->getAtomWithIdx(1)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
delete m;
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testIssue3375647() {
// basic writing test
BOOST_LOG(rdInfoLog) << " ----------> Test issue 3375647 " << std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3375647.1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getBondBetweenAtoms(2, 11)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondBetweenAtoms(2, 11)->getBondDir() !=
Bond::EITHERDOUBLE);
TEST_ASSERT(m->getBondBetweenAtoms(2, 11)->getStereo() == Bond::STEREOZ);
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3375647.2.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getBondBetweenAtoms(2, 11)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondBetweenAtoms(2, 11)->getBondDir() !=
Bond::EITHERDOUBLE);
TEST_ASSERT(m->getBondBetweenAtoms(2, 11)->getStereo() == Bond::STEREOE);
delete m;
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testIssue3375684() {
// basic writing test
BOOST_LOG(rdInfoLog) << " ----------> Test issue 3375684 " << std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3375684.1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getBondBetweenAtoms(6, 7)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondBetweenAtoms(6, 7)->getBondDir() ==
Bond::EITHERDOUBLE);
delete m;
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3375684.2.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m->getBondBetweenAtoms(3, 9)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondBetweenAtoms(3, 9)->getBondDir() !=
Bond::EITHERDOUBLE);
TEST_ASSERT(m->getBondBetweenAtoms(3, 9)->getStereo() == Bond::STEREOE);
delete m;
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testChiralPhosphorous() {
// basic writing test
BOOST_LOG(rdInfoLog) << " ----------> Test handling of chiral phosphorous "
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/chiral_phosphorous.1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(5)->hasProp(common_properties::_CIPCode));
std::string cip;
m->getAtomWithIdx(5)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "R");
delete m;
}
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/chiral_phosphorous.2.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(5)->hasProp(common_properties::_CIPCode));
std::string cip;
m->getAtomWithIdx(5)->getProp(common_properties::_CIPCode, cip);
TEST_ASSERT(cip == "S");
delete m;
}
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/chiral_phosphorous.3.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(!m->getAtomWithIdx(5)->hasProp(common_properties::_CIPCode));
delete m;
}
{
std::string fName =
rdbase +
"/Code/GraphMol/FileParsers/test_data/chiral_phosphorous.4.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(!m->getAtomWithIdx(5)->hasProp(common_properties::_CIPCode));
delete m;
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testIssue3392107() {
// basic writing test
BOOST_LOG(rdInfoLog) << " ----------> Test issue 3392107 " << std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3392107.1.mol";
RWMol *m = MolFileToMol(fName);
std::string smi;
MatchVectType mv;
RWMol *m2;
smi = "C1CCCCC1";
m2 = SmilesToMol(smi);
TEST_ASSERT(m2);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 6);
delete m2;
smi = "C1CCCCN1";
m2 = SmilesToMol(smi);
TEST_ASSERT(m2);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 6);
delete m2;
smi = "C1CCNCN1";
m2 = SmilesToMol(smi);
TEST_ASSERT(m2);
TEST_ASSERT(SubstructMatch(*m2, *m, mv));
TEST_ASSERT(mv.size() == 6);
delete m2;
smi = "C1NCNCN1";
m2 = SmilesToMol(smi);
TEST_ASSERT(m2);
TEST_ASSERT(!SubstructMatch(*m2, *m, mv));
delete m2;
delete m;
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testIssue3432136() {
BOOST_LOG(rdInfoLog) << " ----------> Test issue 3432136 " << std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3432136_1.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(!m);
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3432136_1.v3k.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(!m);
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3432136_2.v3k.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3432136_2.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testIssue3477283() {
BOOST_LOG(rdInfoLog) << " ----------> Test issue 3477283 " << std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3477283.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testIssue3484552() {
BOOST_LOG(rdInfoLog) << " ----------> Test issue 3484552 " << std::endl;
{
std::string smi = "C[13CH3]";
RWMol *m = SmilesToMol(smi);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(1)->getMass() > 12.999);
std::string molBlock = MolToMolBlock(*m);
TEST_ASSERT(molBlock.find("M ISO") != std::string::npos);
delete m;
m = MolBlockToMol(molBlock);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(1)->getMass() > 12.999);
delete m;
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testIssue3514824() {
BOOST_LOG(rdInfoLog) << " ----------> Test issue 3514824 " << std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3514824.2.mol";
RWMol *m = MolFileToMol(fName, false);
TEST_ASSERT(m);
m->updatePropertyCache();
MolOps::findSSSR(*m);
TEST_ASSERT(m->getRingInfo());
TEST_ASSERT(m->getRingInfo()->isInitialized());
TEST_ASSERT(m->getRingInfo()->numRings() == 6);
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3514824.mol";
RWMol *m = MolFileToMol(fName, false);
TEST_ASSERT(m);
m->updatePropertyCache();
MolOps::findSSSR(*m);
TEST_ASSERT(m->getRingInfo());
TEST_ASSERT(m->getRingInfo()->isInitialized());
TEST_ASSERT(m->getRingInfo()->numRings() == 8);
}
BOOST_LOG(rdInfoLog) << " Finished <---------- " << std::endl;
}
void testIssue3525799() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Issue 3525799: bad smiles for r groups" << std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3525799.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
std::string smiles = MolToSmiles(*m, true);
std::cerr << "smiles: " << smiles << std::endl;
TEST_ASSERT(smiles ==
"[1*]c1c([2*])c([3*])c([4*])c(-c2c([9*])oc3c([8*])c([7*])c([6*]"
")c([5*])c3c2=O)c1[10*]");
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue3557675() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Bad issue 3557676: handling of D and T in CTABs"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/D_in_CTAB.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 3);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomicNum() == 1);
TEST_ASSERT(m->getAtomWithIdx(2)->getIsotope() == 2);
}
{
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/T_in_CTAB.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 3);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomicNum() == 1);
TEST_ASSERT(m->getAtomWithIdx(2)->getIsotope() == 3);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testSkipLines() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing skip lines in CTABs" << std::endl;
std::string rdbase = getenv("RDBASE");
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/SkipLines.sdf";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 1);
delete m;
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testIssue269() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Bad issue 269: handling of bad atom symbols in CTABs"
<< std::endl;
std::string rdbase = getenv("RDBASE");
{
// since the new elements were added, the original version of this no longer
// fails. The test input file has been updated to still have an atomic
// symbol that is not recognized. We'll be ok until Mv is an element. :-)
std::string fName =
rdbase + "/Code/GraphMol/FileParsers/test_data/Issue269.mol";
RWMol *m = 0;
try {
m = MolFileToMol(fName);
} catch (...) {
}
TEST_ASSERT(!m);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileChiralFlag() {
BOOST_LOG(rdInfoLog) << "testing handling of chiral flags" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
// SF.Net Issue1603923: problems with multiple chg lines
{
RWMol *m1;
std::string fName;
fName = rdbase + "chiral_flag.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->hasProp(common_properties::_MolFileChiralFlag));
unsigned int cflag;
m1->getProp(common_properties::_MolFileChiralFlag, cflag);
TEST_ASSERT(cflag == 1);
delete m1;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileTotalValence() {
BOOST_LOG(rdInfoLog) << "testing handling of mol file valence flags"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
RWMol *m1;
std::string fName;
fName = rdbase + "Na.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getNumAtoms() == 1);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNoImplicit());
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumExplicitHs() == 0);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumRadicalElectrons() == 1);
delete m1;
}
{
RWMol *m1;
std::string fName;
fName = rdbase + "CH.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getNumAtoms() == 1);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNoImplicit());
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumExplicitHs() == 1);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumRadicalElectrons() == 1);
delete m1;
}
{
RWMol *m1;
std::string fName;
fName = rdbase + "CH2.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getNumAtoms() == 1);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNoImplicit());
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumExplicitHs() == 2);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumRadicalElectrons() == 2);
delete m1;
}
{
RWMol *m1;
std::string fName;
fName = rdbase + "CH3.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getNumAtoms() == 1);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNoImplicit());
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumExplicitHs() == 3);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumRadicalElectrons() == 1);
delete m1;
}
{
// make sure we get it for v3k mol blocks too:
RWMol *m1;
std::string fName;
fName = rdbase + "CH.v3k.mol";
m1 = MolFileToMol(fName);
TEST_ASSERT(m1);
TEST_ASSERT(m1->getNumAtoms() == 1);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNoImplicit());
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumExplicitHs() == 1);
TEST_ASSERT(m1->getAtomWithIdx(0)->getNumRadicalElectrons() == 1);
delete m1;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testGithub88() {
BOOST_LOG(rdInfoLog)
<< "testing github issue 88: M END not being read from V3K ctabs"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "github88.v3k.mol";
bool ok = false;
try {
MolFileToMol(fName);
} catch (FileParseException &e) {
ok = true;
}
TEST_ASSERT(ok);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testGithub82() {
BOOST_LOG(rdInfoLog) << "testing github issue 82: stereochemistry only "
"perceived if sanitization is done"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "github82.1.mol";
ROMol *m;
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(2)->getChiralTag() != Atom::CHI_UNSPECIFIED);
TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag() != Atom::CHI_UNSPECIFIED);
TEST_ASSERT(m->getAtomWithIdx(4)->getChiralTag() == Atom::CHI_UNSPECIFIED);
delete m;
m = MolFileToMol(fName, true, false);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(2)->getChiralTag() != Atom::CHI_UNSPECIFIED);
TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag() != Atom::CHI_UNSPECIFIED);
TEST_ASSERT(m->getAtomWithIdx(4)->getChiralTag() == Atom::CHI_UNSPECIFIED);
delete m;
m = MolFileToMol(fName, false, false);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(2)->getChiralTag() != Atom::CHI_UNSPECIFIED);
TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag() != Atom::CHI_UNSPECIFIED);
TEST_ASSERT(m->getAtomWithIdx(4)->getChiralTag() == Atom::CHI_UNSPECIFIED);
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileWithHs() {
BOOST_LOG(rdInfoLog) << "testing impact of Hs in mol files on stereochemistry"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "chiral_3h.mol";
ROMol *m;
m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag() != Atom::CHI_UNSPECIFIED);
delete m;
m = MolFileToMol(fName, true, false);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag() != Atom::CHI_UNSPECIFIED);
delete m;
m = MolFileToMol(fName, false, false);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag() != Atom::CHI_UNSPECIFIED);
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileWithRxn() {
BOOST_LOG(rdInfoLog) << "testing reading reactions in mol files" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "rxn1.mol";
ROMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 18);
TEST_ASSERT(m->getNumBonds() == 16);
TEST_ASSERT(m->getAtomWithIdx(0)->hasProp(common_properties::molRxnRole));
TEST_ASSERT(
m->getAtomWithIdx(0)->getProp<int>(common_properties::molRxnRole) == 1);
TEST_ASSERT(
m->getAtomWithIdx(0)->hasProp(common_properties::molRxnComponent));
TEST_ASSERT(m->getAtomWithIdx(0)->getProp<int>(
common_properties::molRxnComponent) == 1);
TEST_ASSERT(m->getAtomWithIdx(17)->hasProp(common_properties::molRxnRole));
TEST_ASSERT(m->getAtomWithIdx(17)->getProp<int>(
common_properties::molRxnRole) == 2);
TEST_ASSERT(
m->getAtomWithIdx(17)->hasProp(common_properties::molRxnComponent));
TEST_ASSERT(m->getAtomWithIdx(17)->getProp<int>(
common_properties::molRxnComponent) == 3);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testPDBFile() {
BOOST_LOG(rdInfoLog) << "testing reading pdb files" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "1CRN.pdb";
ROMol *m = PDBFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 327);
TEST_ASSERT(m->getNumBonds() == 337);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo());
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getSerialNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getResidueNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(9)->getMonomerInfo())
->getSerialNumber() == 10);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(9)->getMonomerInfo())
->getResidueNumber() == 2);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getName() == " N ");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getResidueName() == "THR");
TEST_ASSERT(feq(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getTempFactor(),
13.79));
TEST_ASSERT(m->getNumConformers() == 1);
TEST_ASSERT(feq(m->getConformer().getAtomPos(0).x, 17.047));
TEST_ASSERT(feq(m->getConformer().getAtomPos(0).y, 14.099));
TEST_ASSERT(feq(m->getConformer().getAtomPos(0).z, 3.625));
std::string mb = MolToPDBBlock(*m);
delete m;
m = PDBBlockToMol(mb);
TEST_ASSERT(m->getNumAtoms() == 327);
TEST_ASSERT(m->getNumBonds() == 337);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo());
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getSerialNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getResidueNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(9)->getMonomerInfo())
->getSerialNumber() == 10);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(9)->getMonomerInfo())
->getResidueNumber() == 2);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getName() == " N ");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getResidueName() == "THR");
TEST_ASSERT(feq(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getTempFactor(),
13.79));
TEST_ASSERT(m->getNumConformers() == 1);
TEST_ASSERT(feq(m->getConformer().getAtomPos(0).x, 17.047));
TEST_ASSERT(feq(m->getConformer().getAtomPos(0).y, 14.099));
TEST_ASSERT(feq(m->getConformer().getAtomPos(0).z, 3.625));
}
{
std::string fName;
fName = rdbase + "2FVD.pdb";
ROMol *m = PDBFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 2501);
TEST_ASSERT(m->getNumBonds() == 2383);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo());
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getSerialNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getResidueNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getIsHeteroAtom() == 0);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getSerialNumber() == 2294);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getResidueNumber() == 299);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getIsHeteroAtom() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getChainId() == "A");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getName() == " CA ");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getResidueName() == "MET");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getName() == " N1 ");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getResidueName() == "LIA");
std::string mb = MolToPDBBlock(*m, -1, 32);
delete m;
m = PDBBlockToMol(mb);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 2501);
TEST_ASSERT(m->getNumBonds() == 2383);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo());
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getSerialNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getResidueNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getIsHeteroAtom() == 0);
// FIX:
// TEST_ASSERT(static_cast<AtomPDBResidueInfo
// *>(m->getAtomWithIdx(2292)->getMonomerInfo())->getSerialNumber()==2294);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getResidueNumber() == 299);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getIsHeteroAtom() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getChainId() == "A");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getName() == " CA ");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getResidueName() == "MET");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getName() == " N1 ");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2292)->getMonomerInfo())
->getResidueName() == "LIA");
}
{ // DNA
std::string fName;
fName = rdbase + "4BNA.pdb";
ROMol *m = PDBFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumHeavyAtoms() == 602);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo());
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getSerialNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getResidueName() == " DC");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(57)->getMonomerInfo())
->getResidueName() == " DG");
std::string mb = MolToPDBBlock(*m);
delete m;
m = PDBBlockToMol(mb);
TEST_ASSERT(m->getNumHeavyAtoms() == 602);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo());
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getResidueName() == " DC");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(57)->getMonomerInfo())
->getResidueName() == " DG");
delete m;
}
{ // RNA
std::string fName;
fName = rdbase + "4TNA.pdb";
ROMol *m = PDBFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumHeavyAtoms() == 1656);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo());
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getSerialNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getResidueName() == " G");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(90)->getMonomerInfo())
->getResidueName() == " A");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(197)->getMonomerInfo())
->getResidueName() == "2MG");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(197)->getMonomerInfo())
->getIsHeteroAtom());
std::string mb = MolToPDBBlock(*m);
delete m;
m = PDBBlockToMol(mb);
TEST_ASSERT(m->getNumHeavyAtoms() == 1656);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getSerialNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getResidueName() == " G");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(90)->getMonomerInfo())
->getResidueName() == " A");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(197)->getMonomerInfo())
->getResidueName() == "2MG");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(197)->getMonomerInfo())
->getIsHeteroAtom());
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testSequences() {
BOOST_LOG(rdInfoLog) << "testing reading sequences" << std::endl;
{
std::string seq = "CGCGAATTACCGCG"; // made up
int flavor = 6; // DNA
ROMol *m = SequenceToMol(seq, true, flavor);
TEST_ASSERT(m);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getSerialNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getResidueName() == " DC");
seq = MolToSequence(*m);
TEST_ASSERT(seq == "CGCGAATTACCGCG");
seq = MolToHELM(*m);
// std::cerr << seq << std::endl;
TEST_ASSERT(seq ==
"RNA1{[dR](C)P.[dR](G)P.[dR](C)P.[dR](G)P.[dR](A)P.[dR](A)P.["
"dR](T)P.[dR](T)P.[dR](A)P.[dR](C)P.[dR](C)P.[dR](G)P.[dR](C)P."
"[dR](G)}$$$$");
{
std::string lseq = MolToHELM(*m);
TEST_ASSERT(lseq == seq);
ROMol *m2 = HELMToMol(seq);
TEST_ASSERT(m2)
lseq = MolToSequence(*m2);
TEST_ASSERT(lseq == "CGCGAATTACCGCG");
lseq = MolToHELM(*m2);
TEST_ASSERT(lseq == seq);
delete m2;
}
{
ROMol *nm = MolOps::addHs(*m);
TEST_ASSERT(nm);
std::string pdb = MolToPDBBlock(*nm);
delete nm;
nm = PDBBlockToMol(pdb);
TEST_ASSERT(nm);
std::string lseq = MolToSequence(*nm);
TEST_ASSERT(lseq == "CGCGAATTACCGCG");
delete nm;
}
delete m;
}
{
std::string seq = "CGCGAAUUACCGCG"; // made up
int flavor = 2; // RNA
ROMol *m = SequenceToMol(seq, true, flavor);
TEST_ASSERT(m);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo())
->getSerialNumber() == 1);
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())
->getResidueName() == " C");
seq = MolToSequence(*m);
TEST_ASSERT(seq == "CGCGAAUUACCGCG");
seq = MolToHELM(*m);
TEST_ASSERT(seq ==
"RNA1{R(C)P.R(G)P.R(C)P.R(G)P.R(A)P.R(A)P.R(U)P.R(U)P.R(A)P.R("
"C)P.R(C)P.R(G)P.R(C)P.R(G)}$$$$");
{
std::string lseq = MolToHELM(*m);
TEST_ASSERT(lseq == seq);
ROMol *m2 = HELMToMol(seq);
TEST_ASSERT(m2)
lseq = MolToSequence(*m2);
TEST_ASSERT(lseq == "CGCGAAUUACCGCG");
lseq = MolToHELM(*m2);
TEST_ASSERT(lseq == seq);
delete m2;
}
{
ROMol *nm = MolOps::addHs(*m);
TEST_ASSERT(nm);
std::string pdb = MolToPDBBlock(*nm);
delete nm;
nm = PDBBlockToMol(pdb);
TEST_ASSERT(nm);
std::string lseq = MolToSequence(*nm);
TEST_ASSERT(lseq == "CGCGAAUUACCGCG");
delete nm;
}
delete m;
}
}
void testGithub1023() {
BOOST_LOG(rdInfoLog) << "GetSSSR interrupted by segmentation fault"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "github1023.pdb";
bool sanitize = false;
ROMol *m = PDBFileToMol(fName, sanitize);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 119);
TEST_ASSERT(m->getNumBonds() == 399);
bool ok = false;
try {
// the "molecule" isn't something we can properly handle. Expect a
// ValueErrorException
MolOps::findSSSR(*m); // this was seg faulting
} catch (const ValueErrorException &e) {
ok = true;
}
TEST_ASSERT(ok);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testGithub166() {
BOOST_LOG(rdInfoLog)
<< "testing Github 166: skipping sanitization on reading pdb files"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "1CRN.pdb";
ROMol *m = PDBFileToMol(fName, false, false);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 327);
TEST_ASSERT(m->getNumBonds() == 337);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testZBO() {
BOOST_LOG(rdInfoLog) << "testing ZBO parsing" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "FeCO5.mol";
ROMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 11);
TEST_ASSERT(m->getNumBonds() == 10);
TEST_ASSERT(m->getBondWithIdx(0)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(2)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(6)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(7)->getBondType() == Bond::ZERO);
}
{
std::string fName;
fName = rdbase + "CrBz.mol";
ROMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 7);
TEST_ASSERT(m->getNumBonds() == 12);
TEST_ASSERT(m->getBondWithIdx(6)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(7)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(8)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(9)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(10)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(11)->getBondType() == Bond::ZERO);
// make sure we don't screw up aromaticity:
TEST_ASSERT(m->getBondWithIdx(0)->getIsAromatic());
}
{
std::string fName;
fName = rdbase + "CrBz2.mol";
ROMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 13);
TEST_ASSERT(m->getNumBonds() == 24);
TEST_ASSERT(m->getBondWithIdx(6)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(7)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(8)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(9)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(10)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(11)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(18)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(19)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(20)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(21)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(22)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getBondWithIdx(23)->getBondType() == Bond::ZERO);
}
{
std::string fName;
fName = rdbase + "H3BNH3.mol";
ROMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 2);
TEST_ASSERT(m->getNumBonds() == 1);
TEST_ASSERT(m->getBondWithIdx(0)->getBondType() == Bond::ZERO);
TEST_ASSERT(m->getAtomWithIdx(0)->getFormalCharge() == 0);
TEST_ASSERT(m->getAtomWithIdx(1)->getFormalCharge() == 0);
TEST_ASSERT(m->getAtomWithIdx(0)->getNumExplicitHs() == 3);
TEST_ASSERT(m->getAtomWithIdx(1)->getNumExplicitHs() == 0);
TEST_ASSERT(m->getAtomWithIdx(0)->getTotalNumHs() == 3);
TEST_ASSERT(m->getAtomWithIdx(1)->getTotalNumHs() == 3);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testGithub164() {
BOOST_LOG(rdInfoLog) << "testing Github 164: problems with Xe from mol files"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "Github164.mol";
ROMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 3);
TEST_ASSERT(m->getNumBonds() == 2);
TEST_ASSERT(m->getAtomWithIdx(0)->getExplicitValence() == 2);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
namespace RDKit {
bool SamePDBResidue(AtomPDBResidueInfo *p, AtomPDBResidueInfo *q);
}
void testGithub194() {
BOOST_LOG(rdInfoLog) << "testing github issue 194: bad bond types from pdb"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "1CRN.pdb";
ROMol *m = PDBFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 327);
TEST_ASSERT(m->getNumBonds() == 337);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo());
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
// the root cause: problems in SamePDBResidue:
TEST_ASSERT(SamePDBResidue(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo()),
static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(1)->getMonomerInfo())));
TEST_ASSERT(SamePDBResidue(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo()),
static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2)->getMonomerInfo())));
TEST_ASSERT(!SamePDBResidue(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(0)->getMonomerInfo()),
static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(9)->getMonomerInfo())));
// the symptom, bond orders:
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(2)->getMonomerInfo())
->getName() == " C ");
TEST_ASSERT(static_cast<AtomPDBResidueInfo *>(
m->getAtomWithIdx(3)->getMonomerInfo())
->getName() == " O ");
TEST_ASSERT(m->getBondBetweenAtoms(2, 3));
TEST_ASSERT(m->getBondBetweenAtoms(2, 3)->getBondType() == Bond::DOUBLE);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testGithub196() {
BOOST_LOG(rdInfoLog)
<< "testing github issue 196: left justitified bond topology"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "github196.mol";
ROMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 19);
TEST_ASSERT(m->getNumBonds() == 20);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testGithub191() {
BOOST_LOG(rdInfoLog) << "-----------------------\n Testing github issue 191: "
"wavy bonds to Hs should affect attached double bond "
"stereochemistry."
<< std::endl;
{
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *m = MolFileToMol(pathName + "github191.1.mol");
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(0)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(0)->getStereo() == Bond::STEREOE);
std::string smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "C/C=C/C");
delete m;
}
{
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *m = MolFileToMol(pathName + "github191.2.mol");
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(0)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(0)->getStereo() == Bond::STEREOANY);
std::string smi = MolToSmiles(*m, true);
TEST_ASSERT(smi == "CC=CC");
delete m;
}
BOOST_LOG(rdInfoLog) << "Finished" << std::endl;
}
void testGithub210() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing Github 210: flag possible stereocenters "
"when calling assignStereochemistry()"
<< std::endl;
{
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *m = MolFileToMol(pathName + "github210.mol");
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(1)->hasProp(common_properties::_CIPCode));
TEST_ASSERT(
m->getAtomWithIdx(4)->hasProp(common_properties::_ChiralityPossible));
delete m;
}
BOOST_LOG(rdInfoLog) << "Finished" << std::endl;
}
namespace {
std::string getResidue(const ROMol &, const Atom *at) {
if (at->getMonomerInfo()->getMonomerType() != AtomMonomerInfo::PDBRESIDUE)
return "";
return static_cast<const AtomPDBResidueInfo *>(at->getMonomerInfo())
->getResidueName();
}
}
void testPDBResidues() {
BOOST_LOG(rdInfoLog) << "testing splitting on PDB residues" << std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{
std::string fName;
fName = rdbase + "2NW4.pdb";
ROMol *m = PDBFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
std::map<std::string, boost::shared_ptr<ROMol> > res =
MolOps::getMolFragsWithQuery(*m, getResidue, false);
TEST_ASSERT(res.size() == 22);
TEST_ASSERT(res.find(std::string("8NH")) != res.end());
TEST_ASSERT(res.find(std::string("ALA")) != res.end());
TEST_ASSERT(res[std::string("8NH")]->getNumAtoms() == 21);
const ROMol *lig = res[std::string("8NH")].get();
TEST_ASSERT(lig->getNumConformers() == 1);
TEST_ASSERT(feq(lig->getConformer().getAtomPos(0).x, 23.517));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(0).y, 5.263));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(0).z, 4.399));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(11).x, 27.589));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(11).y, -0.311));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(11).z, 3.743));
}
{
std::string fName;
fName = rdbase + "2NW4.pdb";
ROMol *m = PDBFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
std::vector<std::string> keep;
keep.push_back("8NH");
std::map<std::string, boost::shared_ptr<ROMol> > res =
MolOps::getMolFragsWithQuery(*m, getResidue, false, &keep);
TEST_ASSERT(res.size() == 1);
TEST_ASSERT(res.find(std::string("8NH")) != res.end());
TEST_ASSERT(res[std::string("8NH")]->getNumAtoms() == 21);
const ROMol *lig = res[std::string("8NH")].get();
TEST_ASSERT(lig->getNumConformers() == 1);
TEST_ASSERT(feq(lig->getConformer().getAtomPos(0).x, 23.517));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(0).y, 5.263));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(0).z, 4.399));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(11).x, 27.589));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(11).y, -0.311));
TEST_ASSERT(feq(lig->getConformer().getAtomPos(11).z, 3.743));
}
{
std::string fName;
fName = rdbase + "2NW4.pdb";
ROMol *m = PDBFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getAtomWithIdx(0)->getMonomerInfo()->getMonomerType() ==
AtomMonomerInfo::PDBRESIDUE);
std::vector<std::string> keep;
keep.push_back("8NH");
std::map<std::string, boost::shared_ptr<ROMol> > res =
MolOps::getMolFragsWithQuery(*m, getResidue, false, &keep, true);
TEST_ASSERT(res.size() == 21);
TEST_ASSERT(res.find(std::string("8NH")) == res.end());
TEST_ASSERT(res.find(std::string("ALA")) != res.end());
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testGithub337() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing Github 337: No double bond stereo "
"perception from CTABs when sanitization is turned "
"off"
<< std::endl;
{
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *m = MolFileToMol(pathName + "unsanitized_stereo.mol", false);
TEST_ASSERT(m);
TEST_ASSERT(m->getBondWithIdx(0)->getStereo() == Bond::STEREONONE);
std::string molBlock = MolToMolBlock(*m);
TEST_ASSERT(molBlock.find(" 1 2 2 0") != std::string::npos);
delete m;
}
BOOST_LOG(rdInfoLog) << "Finished" << std::endl;
}
void testGithub360() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing Github 360: Computed props on non-sanitized "
"molecule interfering with substructure matching"
<< std::endl;
{
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *dbm = SmilesToMol("C1Cc2ccccc2CN1");
TEST_ASSERT(dbm);
RWMol *tmpl = MolFileToMol(pathName + "github360.mol", false);
TEST_ASSERT(tmpl);
MatchVectType mv;
TEST_ASSERT(SubstructMatch(*dbm, *tmpl, mv));
delete dbm;
delete tmpl;
}
BOOST_LOG(rdInfoLog) << "Finished" << std::endl;
}
void testGithub741() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing Github 741: Support CTABs where the second "
"letter in atom symbols is capitalized"
<< std::endl;
{
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *mol = MolFileToMol(pathName + "github741.mol");
TEST_ASSERT(mol);
TEST_ASSERT(mol->getAtomWithIdx(1)->getSymbol() == "Br");
TEST_ASSERT(mol->getAtomWithIdx(2)->getSymbol() == "Br");
delete mol;
}
{
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *mol = MolFileToMol(pathName + "github741.v3k.mol");
TEST_ASSERT(mol);
TEST_ASSERT(mol->getAtomWithIdx(1)->getSymbol() == "Br");
TEST_ASSERT(mol->getAtomWithIdx(2)->getSymbol() == "Br");
delete mol;
}
BOOST_LOG(rdInfoLog) << "Finished" << std::endl;
}
void testGithub188() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing Github 188: Bad E/Z assignment from CTAB"
<< std::endl;
{
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *mol = MolFileToMol(pathName + "github188.mol");
TEST_ASSERT(mol);
TEST_ASSERT(mol->getBondBetweenAtoms(16, 17));
TEST_ASSERT(mol->getBondBetweenAtoms(16, 17)->getStereo() == Bond::STEREOZ);
TEST_ASSERT(mol->getBondBetweenAtoms(13, 14));
TEST_ASSERT(mol->getBondBetweenAtoms(13, 14)->getStereo() == Bond::STEREOZ);
delete mol;
}
{
std::cerr << "----------------------------------" << std::endl;
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *mol = MolFileToMol(pathName + "github188_2.mol");
TEST_ASSERT(mol);
TEST_ASSERT(mol->getBondBetweenAtoms(16, 17));
TEST_ASSERT(mol->getBondBetweenAtoms(16, 17)->getStereo() == Bond::STEREOZ);
TEST_ASSERT(mol->getBondBetweenAtoms(13, 14));
TEST_ASSERT(mol->getBondBetweenAtoms(13, 14)->getStereo() == Bond::STEREOZ);
delete mol;
}
{
std::cerr << "----------------------------------" << std::endl;
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *mol = MolFileToMol(pathName + "github192.mol");
TEST_ASSERT(mol);
for (unsigned int i = 0; i < mol->getNumBonds(); ++i) {
const Bond *bnd = mol->getBondWithIdx(i);
if (bnd->getBondType() == Bond::DOUBLE &&
i != mol->getBondBetweenAtoms(26, 27)->getIdx() &&
i != mol->getBondBetweenAtoms(6, 8)->getIdx()) {
TEST_ASSERT(bnd->getStereo() == Bond::STEREOE);
}
}
delete mol;
}
BOOST_LOG(rdInfoLog) << "Finished" << std::endl;
}
void testRCSBSdf() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing right-aligned elements in RCSB SDF files"
<< std::endl;
std::string pathName = getenv("RDBASE");
pathName += "/Code/GraphMol/FileParsers/test_data/";
RWMol *mol = MolFileToMol(pathName + "s58_rcsb.mol");
TEST_ASSERT(mol);
delete mol;
}
void testParseCHG() {
// BAD PDB Ligand with CHG line too long (>8) and right and mid-justified
// symbols
const std::string molblock_chg =
"2D1G_DVT_B_2001\n"
" RCSB PDB01151500373D\n"
"Coordinates from PDB:2D1G:B:2001 Model:1 without hydrogens\n"
" 38 60 0 0 0 0 999 V2000\n"
" 19.0320 93.5880 16.2640 O 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 19.6400 94.8240 15.4350 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 18.1700 95.2990 14.2790 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 19.6000 96.2720 16.5920 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 20.3140 97.8870 15.9210 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 20.1880 98.9370 17.1150 O 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 21.5140 94.4720 15.5850 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 22.5590 95.9150 15.0470 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 20.6050 96.4040 14.1390 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 22.1700 97.4330 15.9940 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 23.1150 97.3160 13.7160 O 0 3 0 0 0 0 0 0 0 0 0 0\n"
" 23.9960 95.5550 15.6610 O 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 22.6470 94.8660 13.3320 O 0 3 0 0 0 0 0 0 0 0 0 0\n"
" 23.7710 96.1210 12.1910 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 24.0950 97.6940 11.3470 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 25.2350 95.8110 12.7760 O 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 23.5040 94.7850 10.9890 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 22.0160 95.1170 9.8340 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 20.1580 95.5900 9.6670 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 22.2300 94.0400 8.6680 O 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 22.6710 96.7240 9.1340 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 20.8370 94.9790 12.6510 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 21.1160 93.9980 11.2840 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 20.1410 93.8410 13.6860 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 21.6740 96.5770 11.6070 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 22.5990 98.1610 10.2810 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 23.1590 99.4050 9.4060 O 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 22.1350 99.1410 12.0500 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 21.4440 98.0120 13.0890 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 21.1330 99.0140 14.4480 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 19.1670 95.7180 12.0250 O 0 3 0 0 0 0 0 0 0 0 0 0\n"
" 19.7240 97.0880 10.6480 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 20.7360 98.5460 10.1630 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 18.2530 97.4600 10.0390 O 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 19.6430 98.1340 12.3760 O 0 3 0 0 0 0 0 0 0 0 0 0\n"
" 18.5370 96.9390 13.5530 V 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 18.8160 98.2640 14.7770 O 0 0 0 0 0 0 0 0 0 0 0 0\n"
" 17.0530 97.2880 13.0100 O 0 5 0 0 0 0 0 0 0 0 0 0\n"
" 1 2 1 0 0 0 0\n"
" 2 3 1 0 0 0 0\n"
" 2 4 1 0 0 0 0\n"
" 2 7 1 0 0 0 0\n"
" 2 9 1 0 0 0 0\n"
" 2 24 1 0 0 0 0\n"
" 3 36 1 0 0 0 0\n"
" 4 5 1 0 0 0 0\n"
" 5 6 1 0 0 0 0\n"
" 5 9 1 0 0 0 0\n"
" 5 10 1 0 0 0 0\n"
" 5 30 1 0 0 0 0\n"
" 5 37 1 0 0 0 0\n"
" 7 8 1 0 0 0 0\n"
" 8 9 1 0 0 0 0\n"
" 8 10 1 0 0 0 0\n"
" 8 11 1 0 0 0 0\n"
" 8 12 1 0 0 0 0\n"
" 8 13 1 0 0 0 0\n"
" 9 22 1 0 0 0 0\n"
" 9 29 1 0 0 0 0\n"
" 9 36 1 0 0 0 0\n"
" 11 14 1 0 0 0 0\n"
" 11 29 1 0 0 0 0\n"
" 13 14 1 0 0 0 0\n"
" 13 22 1 0 0 0 0\n"
" 14 15 1 0 0 0 0\n"
" 14 16 1 0 0 0 0\n"
" 14 17 1 0 0 0 0\n"
" 14 28 1 0 0 0 0\n"
" 15 26 1 0 0 0 0\n"
" 17 18 1 0 0 0 0\n"
" 18 19 1 0 0 0 0\n"
" 18 20 1 0 0 0 0\n"
" 18 21 1 0 0 0 0\n"
" 18 23 1 0 0 0 0\n"
" 18 28 1 0 0 0 0\n"
" 19 32 1 0 0 0 0\n"
" 21 26 1 0 0 0 0\n"
" 22 23 1 0 0 0 0\n"
" 22 24 1 0 0 0 0\n"
" 22 28 1 0 0 0 0\n"
" 22 31 1 0 0 0 0\n"
" 25 26 1 0 0 0 0\n"
" 25 29 1 0 0 0 0\n"
" 26 27 1 0 0 0 0\n"
" 26 28 1 0 0 0 0\n"
" 26 33 1 0 0 0 0\n"
" 28 29 1 0 0 0 0\n"
" 28 32 1 0 0 0 0\n"
" 29 30 1 0 0 0 0\n"
" 29 35 1 0 0 0 0\n"
" 31 32 1 0 0 0 0\n"
" 31 36 1 0 0 0 0\n"
" 32 33 1 0 0 0 0\n"
" 32 34 1 0 0 0 0\n"
" 32 35 1 0 0 0 0\n"
" 35 36 1 0 0 0 0\n"
" 36 37 1 0 0 0 0\n"
" 36 38 1 0 0 0 0\n"
"M CHG 24 1 -1 2 -1 5 -1 6 -1 8 -1 9 4 11 1 12 "
"-1 13 1 14 -1 16 -1 18 -1 20 -1 22 -1 26 -1 27 -1 28 "
" 4 29 -1 31 1 32 -1 34 -1 35 1 36 -1 38 -1\n"
"M END\n";
const int charges[] = {1, -1, 2, -1, 5, -1, 6, -1, 8, -1, 9, 4, 11,
1, 12, -1, 13, 1, 14, -1, 16, -1, 18, -1, 20, -1,
22, -1, 26, -1, 27, -1, 28, 4, 29, -1, 31, 1, 32,
-1, 34, -1, 35, 1, 36, -1, 38, -1, 0, 0};
// Shouldn't seg fault, throw exception or have a null mol
RWMol *m = MolBlockToMol(molblock_chg);
size_t i = 0;
while (1) {
if (charges[i] == 0) break;
TEST_ASSERT(
m->getAtomWithIdx((unsigned int)charges[i] - 1)->getFormalCharge() ==
charges[i + 1]);
i += 2;
}
TEST_ASSERT(m);
std::string out = MolToMolBlock(*m);
const std::string sub = "M CHG";
std::vector<size_t> positions;
size_t pos = out.find(sub, 0);
while (pos != std::string::npos) {
positions.push_back(pos);
size_t num_entries = strtol(out.substr(pos + sub.size(), 3).c_str(), 0, 10);
TEST_ASSERT(num_entries == 8);
pos = out.find(sub, pos + 1);
}
TEST_ASSERT(positions.size() == 3); // 24/3 == 8
delete m;
}
void testMDLAtomProps() {
std::string smi = "CC";
ROMOL_SPTR mol(SmilesToMol(smi, false, false));
setAtomAlias(mol->getAtomWithIdx(0), "foo");
setAtomValue(mol->getAtomWithIdx(0), "bar");
setAtomRLabel(mol->getAtomWithIdx(0), 1);
mol.reset(MolBlockToMol(MolToMolBlock(*mol.get())));
TEST_ASSERT(getAtomAlias(mol->getAtomWithIdx(0)) == "foo");
TEST_ASSERT(getAtomValue(mol->getAtomWithIdx(0)) == "bar");
TEST_ASSERT(getAtomRLabel(mol->getAtomWithIdx(0)) == 1);
try {
setAtomRLabel(mol->getAtomWithIdx(0), 100);
TEST_ASSERT(0);
} catch (...) {
}
}
void testSupplementalSmilesLabel() {
std::string smi = "C";
ROMOL_SPTR mol(SmilesToMol(smi, false, false));
setSupplementalSmilesLabel(mol->getAtomWithIdx(0), "xxx");
smi = MolToSmiles(*mol.get());
TEST_ASSERT(smi == "Cxxx");
TEST_ASSERT(getSupplementalSmilesLabel(mol->getAtomWithIdx(0)) == "xxx");
}
void testGithub1034() {
BOOST_LOG(rdInfoLog)
<< "Test github 1034: Squiggle bonds from CTABs lost post-parsing"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{ // double bond
std::string fName;
fName = rdbase + "github1034.1.mol";
bool sanitize = true;
RWMol *m = MolFileToMol(fName, sanitize);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
TEST_ASSERT(m->getBondWithIdx(0)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(0)->getStereo() == Bond::STEREOANY);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::SINGLE);
TEST_ASSERT(m->getBondWithIdx(2)->getBondType() == Bond::SINGLE);
TEST_ASSERT(m->getBondWithIdx(2)->getBondDir() != Bond::UNKNOWN);
TEST_ASSERT(
m->getBondWithIdx(2)->hasProp(common_properties::_UnknownStereo));
}
{ // double bond
std::string fName;
fName = rdbase + "github1034.1.mol";
bool sanitize = false;
RWMol *m = MolFileToMol(fName, sanitize);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 4);
TEST_ASSERT(m->getBondWithIdx(2)->getBondType() == Bond::SINGLE);
TEST_ASSERT(m->getBondWithIdx(2)->getBondDir() == Bond::UNKNOWN);
MolOps::sanitizeMol(*m);
TEST_ASSERT(m->getBondWithIdx(0)->getBondType() == Bond::DOUBLE);
TEST_ASSERT(m->getBondWithIdx(0)->getStereo() == Bond::STEREONONE);
TEST_ASSERT(m->getBondWithIdx(1)->getBondType() == Bond::SINGLE);
TEST_ASSERT(m->getBondWithIdx(1)->getBondDir() == Bond::NONE);
TEST_ASSERT(m->getBondWithIdx(2)->getBondType() == Bond::SINGLE);
TEST_ASSERT(m->getBondWithIdx(2)->getBondDir() == Bond::UNKNOWN);
MolOps::assignStereochemistry(*m, true, true);
TEST_ASSERT(m->getBondWithIdx(0)->getStereo() == Bond::STEREOANY);
}
{ // chiral center
std::string fName;
fName = rdbase + "github1034.2.mol";
bool sanitize = true;
RWMol *m = MolFileToMol(fName, sanitize);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag() == Atom::CHI_UNSPECIFIED);
TEST_ASSERT(m->getBondWithIdx(3)->getBondType() == Bond::SINGLE);
TEST_ASSERT(m->getBondWithIdx(3)->getBondDir() == Bond::NONE);
TEST_ASSERT(
m->getBondWithIdx(3)->hasProp(common_properties::_UnknownStereo));
}
{ // chiral center
std::string fName;
fName = rdbase + "github1034.2.mol";
bool sanitize = false;
RWMol *m = MolFileToMol(fName, sanitize);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 5);
TEST_ASSERT(m->getBondWithIdx(3)->getBondType() == Bond::SINGLE);
TEST_ASSERT(m->getBondWithIdx(3)->getBondDir() == Bond::UNKNOWN);
MolOps::sanitizeMol(*m);
TEST_ASSERT(m->getBondWithIdx(3)->getBondType() == Bond::SINGLE);
TEST_ASSERT(m->getBondWithIdx(3)->getBondDir() == Bond::UNKNOWN);
TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag() == Atom::CHI_UNSPECIFIED);
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testGithub1049() {
BOOST_LOG(rdInfoLog) << "Test github 1049: MolOps::cleanUp() being called by "
"CTAB parser even when sanitization isn't on"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
{ // no stereo (this one worked before)
std::string fName;
fName = rdbase + "github1049.1.mol";
bool sanitize = false;
RWMol *m = MolFileToMol(fName, sanitize);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 7);
TEST_ASSERT(m->getAtomWithIdx(1)->getAtomicNum() == 7);
TEST_ASSERT(m->getAtomWithIdx(1)->getFormalCharge() == 0);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomicNum() == 8);
TEST_ASSERT(m->getAtomWithIdx(2)->getFormalCharge() == 0);
TEST_ASSERT(m->getAtomWithIdx(3)->getAtomicNum() == 8);
TEST_ASSERT(m->getAtomWithIdx(3)->getFormalCharge() == 0);
MolOps::sanitizeMol(*m);
TEST_ASSERT(m->getAtomWithIdx(1)->getFormalCharge() == 1);
TEST_ASSERT((m->getAtomWithIdx(2)->getFormalCharge() == -1 &&
m->getAtomWithIdx(3)->getFormalCharge() == 0) ||
(m->getAtomWithIdx(2)->getFormalCharge() == 0 &&
m->getAtomWithIdx(3)->getFormalCharge() == -1));
delete m;
}
{ // with stereo (this one did not work)
std::string fName;
fName = rdbase + "github1049.2.mol";
bool sanitize = false;
RWMol *m = MolFileToMol(fName, sanitize);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumAtoms() == 7);
TEST_ASSERT(m->getAtomWithIdx(1)->getAtomicNum() == 7);
TEST_ASSERT(m->getAtomWithIdx(1)->getFormalCharge() == 0);
TEST_ASSERT(m->getAtomWithIdx(2)->getAtomicNum() == 8);
TEST_ASSERT(m->getAtomWithIdx(2)->getFormalCharge() == 0);
TEST_ASSERT(m->getAtomWithIdx(3)->getAtomicNum() == 8);
TEST_ASSERT(m->getAtomWithIdx(3)->getFormalCharge() == 0);
MolOps::sanitizeMol(*m);
TEST_ASSERT(m->getAtomWithIdx(1)->getFormalCharge() == 1);
TEST_ASSERT((m->getAtomWithIdx(2)->getFormalCharge() == -1 &&
m->getAtomWithIdx(3)->getFormalCharge() == 0) ||
(m->getAtomWithIdx(2)->getFormalCharge() == 0 &&
m->getAtomWithIdx(3)->getFormalCharge() == -1));
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void testMolFileDativeBonds() {
BOOST_LOG(rdInfoLog) << "Test MDL molfiles with dative bonds (V3000 only)"
<< std::endl;
std::string rdbase = getenv("RDBASE");
rdbase += "/Code/GraphMol/FileParsers/test_data/";
// Read molfiles with dative bonds.
{
std::string fName = rdbase + "dative_bonds_one.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumBonds() == 5);
TEST_ASSERT(m->getBondWithIdx(4)->getBondType() == Bond::DATIVE);
std::string smiles = MolToSmiles(*m);
TEST_ASSERT(smiles == "CCC(=O)O->[Cu]");
delete m;
}
{
std::string fName = rdbase + "dative_bonds_two.mol";
RWMol *m = MolFileToMol(fName);
TEST_ASSERT(m);
TEST_ASSERT(m->getNumBonds() == 10);
TEST_ASSERT(m->getBondWithIdx(8)->getBondType() == Bond::DATIVE);
TEST_ASSERT(m->getBondWithIdx(9)->getBondType() == Bond::DATIVE);
std::string smiles = MolToSmiles(*m);
TEST_ASSERT(smiles == "CCC(=O)O->[Cu]<-OC(O)CC");
delete m;
}
BOOST_LOG(rdInfoLog) << "done" << std::endl;
}
void RunTests() {
#if 1
test1();
test2();
test4();
test5();
test6();
testIssue145();
testIssue148();
test7();
test8();
testIssue180();
testIssue264();
testIssue399();
testMolFileChgLines();
testDblBondStereochem();
testSymmetricDblBondStereochem();
testRingDblBondStereochem();
testMolFileRGroups();
testMolFileDegreeQueries();
testMolFileRBCQueries();
testMolFileUnsaturationQueries();
testMolFileQueryToSmarts();
testMissingFiles();
testIssue1965035();
testRadicals();
testBadBondOrders();
testAtomParity();
testIssue2692246();
testKekulizationSkip();
testMolFileAtomValues();
testMolFileAtomQueries();
testListsAndValues();
// testCrash();
test1V3K();
testIssue2963522();
testIssue3073163();
testIssue3154208();
testIssue3228150();
testIssue3313540();
testIssue3359739();
testIssue3374639();
testThreeCoordinateChirality();
testIssue3375647();
testIssue3375684();
testChiralPhosphorous();
testIssue3392107();
testIssue3432136();
testIssue3477283();
testIssue3484552();
testIssue3514824();
testIssue3525799();
testSkipLines();
testIssue269();
testMolFileChiralFlag();
testMolFileTotalValence();
testGithub88();
testGithub82();
testMolFileWithHs();
testMolFileWithRxn();
testGithub166();
testZBO();
testGithub164();
testGithub194();
testGithub196();
testIssue3557675();
test3V3K();
test2V3K();
testGithub191();
testGithub210();
testPDBResidues();
testGithub337();
testGithub360();
testGithub741();
testGithub188();
testRCSBSdf();
testParseCHG();
testMDLAtomProps();
testSupplementalSmilesLabel();
testGithub1023();
testGithub1034();
testGithub1049();
#endif
testPDBFile();
testSequences();
// testSequenceReaders();
testMolFileDativeBonds();
}
// must be in German Locale for test...
void testLocaleSwitcher() {
float d = -1.0;
char buffer[1024];
sprintf(buffer, "%0.2f", d);
if (std::string(buffer) != "-1,00") {
BOOST_LOG(rdInfoLog) << " ---- no German locale support (skipping) ---- "
<< std::endl;
return;
}
{
RDKit::Utils::LocaleSwitcher ls;
sprintf(buffer, "%0.2f", d);
CHECK_INVARIANT(std::string(buffer) == "-1.00", "Locale Switcher Fail");
// test locale switcher recursion
{
RDKit::Utils::LocaleSwitcher ls;
sprintf(buffer, "%0.2f", d);
CHECK_INVARIANT(std::string(buffer) == "-1.00", "Locale Switcher Fail");
}
// should still be in the "C" variant
sprintf(buffer, "%0.2f", d);
CHECK_INVARIANT(std::string(buffer) == "-1.00", "Locale Switcher Fail");
}
// Should be back in German Locale
sprintf(buffer, "%0.2f", d);
CHECK_INVARIANT(std::string(buffer) == "-1,00", "Locale Switcher Fail");
}
#ifdef RDK_TEST_MULTITHREADED
#include <RDGeneral/BoostStartInclude.h>
#include <boost/thread.hpp>
#include <RDGeneral/BoostEndInclude.h>
namespace {
void runblock() { testLocaleSwitcher(); }
}
void testMultiThreadedSwitcher() {
BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdErrorLog) << " Test multithreading Locale Switching"
<< std::endl;
boost::thread_group tg;
unsigned int count = 100;
for (unsigned int i = 0; i < count; ++i) {
tg.add_thread(new boost::thread(runblock));
}
tg.join_all();
BOOST_LOG(rdErrorLog) << " Test multithreading (Done)" << std::endl;
BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
}
#else
void testMultiThreadedSwitcher() {
BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << " ---- Multithreaded tests disabled ---- "
<< std::endl;
}
#endif
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
// std::locale::global(std::locale("de_DE.UTF-8"));
RDLog::InitLogs();
BOOST_LOG(rdInfoLog) << " ---- Running with POSIX locale ----- " << std::endl;
RunTests(); // run with C locale
BOOST_LOG(rdInfoLog) << " ---- Running with German locale ----- "
<< std::endl;
setlocale(LC_ALL, "de_DE.UTF-8");
std::cout << setlocale(LC_ALL, NULL) << std::endl;
testLocaleSwitcher(); // must be the last test
testMultiThreadedSwitcher();
RunTests();
return 0;
}