void testTetrahedralStereo1() { cout << "testTetrahedralStereo1()" << endl; // read a smiles string OBMol mol; OBConversion conv; OB_REQUIRE( conv.SetInFormat("smi") ); cout << "smiles: C[C@H](O)N" << endl; OB_REQUIRE( conv.ReadString(&mol, "C[C@H](O)N") ); // get the stereo data OB_REQUIRE( mol.HasData(OBGenericDataType::StereoData) ); std::vector<OBGenericData *> stereoData = mol.GetAllData(OBGenericDataType::StereoData); OB_REQUIRE( stereoData.size() == 1 ); // convert to tetrahedral data OB_REQUIRE( ((OBStereoBase*)stereoData[0])->GetType() == OBStereo::Tetrahedral ); OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(stereoData[0]); OB_REQUIRE( ts ); // print the configuration cout << *ts << endl; // construct a valid configuration here // // C[C@H](O)N // 0 1 2 3 4 <- ids // OBTetrahedralStereo::Config cfg(1, 0, OBStereo::MakeRefs(4, 3, 2), OBStereo::Clockwise); // compare stereochemistry OB_REQUIRE( ts->GetConfig() == cfg ); cout << endl; }
void testIsomorphism1() { OBMol mol; OBConversion conv; conv.SetInFormat("smi"); conv.ReadString(&mol, "CC1CCC(C)CC1"); OBQuery *query = CompileMoleculeQuery(&mol); OBIsomorphismMapper *mapper = OBIsomorphismMapper::GetInstance(query); OBIsomorphismMapper::Mappings maps; mapper->MapAll(&mol, maps); OB_ASSERT( maps.size() == 4 ); delete query; delete mapper; query = CompileSmilesQuery("C1(C)CCC(C)CC1"); mapper = OBIsomorphismMapper::GetInstance(query); OBIsomorphismMapper::Mapping map; mapper->MapFirst(&mol, map); OB_ASSERT( map.size() == 8 ); mapper->MapUnique(&mol, maps); OB_ASSERT( maps.size() == 1 ); mapper->MapAll(&mol, maps); OB_ASSERT( maps.size() == 4 ); delete query; delete mapper; }
void CheckValidDipeptide(OBConversion &conv, const string &test, unsigned int testCount) { OBMol mol; OBResidue *res; ostringstream os; mol.Clear(); conv.ReadString(&mol, test); chainsparser.PerceiveChains(mol); if (mol.NumResidues() != 2) { os << "not ok " << testCount << " # expected 2 residues, but found " << mol.NumResidues() << '\n'; os << "# "; FOR_RESIDUES_OF_MOL(res, mol) os << res->GetName() << " "; os << endl; BOOST_CHECK_MESSAGE( 0, os.str().c_str() ); } else { res = mol.GetResidue(0); BOOST_CHECK_MESSAGE( res, "Get first AA from dipeptide" ); res = mol.GetResidue(1); BOOST_CHECK_MESSAGE( res, "Get second AA from dipeptide" ); } }
// Delete hydrogens should not remove charged or isotopic hydrogens or [H][H] or [Cu][H][Cu] // or hydrogens with assigned atom classes void test_Issue178_DeleteHydrogens() { OBConversion conv; conv.SetInFormat("smi"); OBMol mol; // Test DeleteHydrogens() and DeleteNonPolarHydrogens() static const char *smi[] = { "C[H]", "[H][H]", "C[1H]", "C[H]C", "C[H+]" }; int numHs[] = { 0, 2, 1, 1, 1 }; for (int i = 0; i < 5; ++i) { for (int j = 0; j < 2; ++j) { conv.ReadString(&mol, smi[i]); if (j == 0) mol.DeleteHydrogens(); else mol.DeleteNonPolarHydrogens(); int myNumHs = 0; FOR_ATOMS_OF_MOL(atom, mol) if (atom->IsHydrogen()) myNumHs++; OB_COMPARE(myNumHs, numHs[i]); } } // Test DeletePolarHydrogens() static const char *smiB[] = { "N[H]", "[H][H]", "N[1H]", "N[H]C", "N[H+]" }; int numHsB[] = { 0, 2, 1, 1, 1 }; for (int i = 0; i < 5; ++i) { conv.ReadString(&mol, smiB[i]); mol.DeletePolarHydrogens(); int myNumHs = 0; FOR_ATOMS_OF_MOL(atom, mol) if (atom->IsHydrogen()) myNumHs++; OB_COMPARE(myNumHs, numHsB[i]); } // Test atom class // Currently, the SMILES parser does not retain atom classes for hydrogens on reading so... conv.ReadString(&mol, "C[H]"); OBAtomClassData *ac = new OBAtomClassData; ac->Add(2, 99); // Assign the hydrogen (atom 2) a class of 99 mol.SetData(ac); mol.DeleteHydrogens(); int myNumHs = 0; FOR_ATOMS_OF_MOL(atom, mol) if (atom->IsHydrogen()) myNumHs++; OB_COMPARE(myNumHs, 1); }
// Reading an InChI and then adding hydrogens messed up the structure void test_Issue134_InChI_addH() { OBConversion conv; conv.SetInFormat("inchi"); OBMol mol; conv.ReadString(&mol, "InChI=1S/C2H7NO/c1-2(3)4/h2,4H,3H2,1H3/t2-/m0/s1"); OB_ASSERT(!mol.HasData(OBGenericDataType::VirtualBondData)); mol.AddHydrogens(); conv.SetOutFormat("smi"); std::string res = conv.WriteString(&mol, true); OB_COMPARE(res, "C[C@@H](N)O"); }
void testAutomorphismPreMapping() { cout << "testAutomorphismPreMapping" << endl; OBMol mol; OBConversion conv; conv.SetInFormat("smi"); conv.ReadString(&mol, "c1(C)c(C)c(C)c(C)c(C)c1"); Automorphisms aut; FindAutomorphisms((OBMol*)&mol, aut); cout << aut.size() << endl; OB_ASSERT( aut.size() == 2 ); }
// A segfault was occuring when a Universal SMILES was output after an InChIfied SMILES. // This was due to short-circuit caching of InChIs on reading. The fix was to limit // the situations when the cached value was used, but also to delete the cached value // in this particular instance. void test_Issue135_UniversalSmiles() { // Test writing U smiles after I smiles OBConversion conv; conv.SetInFormat("smi"); OBMol mol; conv.ReadString(&mol, "C(=O)([O-])C(=O)O"); conv.SetOutFormat("smi"); conv.SetOptions("I", OBConversion::OUTOPTIONS); std::string res = conv.WriteString(&mol, true); OB_COMPARE(res, "C(=O)(C(=O)O)[O-]"); conv.SetOptions("U", OBConversion::OUTOPTIONS); res = conv.WriteString(&mol, true); OB_COMPARE(res, "C(=O)(C(=O)[O-])O"); }
int main(int argc, char **argv) { // Define location of file formats for testing #ifdef FORMATDIR char env[BUFF_SIZE]; snprintf(env, BUFF_SIZE, "BABEL_LIBDIR=%s", FORMATDIR); putenv(env); #endif std::ifstream ifs(GetFilename("canonstable.can").c_str()); OB_REQUIRE( ifs ); OBMol mol; OBConversion conv; conv.SetInFormat("smi"); conv.SetOutFormat("can"); std::string line; while (std::getline(ifs, line)) { OB_REQUIRE( conv.ReadString(&mol, line.c_str()) ); std::vector<OBAtom*> atoms; FOR_ATOMS_OF_MOL(atom, mol) atoms.push_back(&*atom); for (int i = 0; i < 5; ++i) { // shuffle the atoms std::random_shuffle(atoms.begin(), atoms.end()); mol.RenumberAtoms(atoms); // get can smiles mol.SetTitle(""); std::string cansmi = conv.WriteString(&mol, true); // comapare with ref if (cansmi != line) { cout << "ref = " << line << endl; cout << "can = " << cansmi << endl; OB_ASSERT( cansmi == line ); } } } return 0; }
void testIsomorphism4() { cout << "testIsomorphism4" << endl; OBMol mol; OBConversion conv; conv.SetInFormat("smi"); conv.ReadString(&mol, "C12C(C2)C1"); OBQuery *query = CompileSmilesQuery("C1CC1"); OBIsomorphismMapper *mapper = OBIsomorphismMapper::GetInstance(query); OBIsomorphismMapper::Mappings maps; mapper->MapUnique(&mol, maps); cout << maps.size() << endl; OB_ASSERT( maps.size() == 2 ); delete query; delete mapper; }
int main() { // Create an OBConversion object. OBConversion conv; // Set the input format. if (!conv.SetInFormat("smi")) { // Handle error. return 1; } // Create the OBMol object. OBMol mol; // Read the smiles string. if (conv.ReadString(&mol, "CCCC")) { // Handle error. return 1; } // ...Use OBMol object... }
void CheckInvalidResidue(OBConversion &conv, const string &test, unsigned int testCount) { OBMol mol; mol.Clear(); conv.ReadString(&mol, test); chainsparser.PerceiveChains(mol); if (mol.NumResidues() != 0) { OBResidue *res = mol.GetResidue(0); if (res->GetName() == "LIG") { // ligand, not residue cout << "ok " << testCount << " # found ligand, not residue " << test << '\n'; } else { cout << "not ok " << testCount << " # expected 0 residues, found " << mol.NumResidues() << '\n'; cout << "# " << res->GetName() << endl; } } else cout << "ok " << testCount << " # correctly rejected " << test << '\n'; }
bool OBReader::readSmiString(QString smiString) { using namespace OpenBabel; OBConversion conv; if (!conv.SetInFormat("smi")) { qDebug() << "Error in conv.SetInFormat()."; return false; } OBMol obMol; if (!conv.ReadString(&obMol, smiString.toStdString())) { qDebug() << "Error occured while reading the smi string."; return false; } if (!obMol.Has3D()) { if (!buildGeometry(&obMol)) { qDebug() << "Error in buildGeometry()"; return false; } } if (!toMolecule(&obMol)) { qDebug() << "Could not convert OBMol to Molecule."; return false; } return true; }
void CheckInvalidResidue(OBConversion &conv, const string &test, unsigned int testCount) { OBMol mol; ostringstream os; mol.Clear(); conv.ReadString(&mol, test); chainsparser.PerceiveChains(mol); if (mol.NumResidues() != 0) { OBResidue *res = mol.GetResidue(0); if (res->GetName() == "LIG") { // ligand, not residue BOOST_CHECK( 1 ); } else { os << "not ok " << testCount << " # expected 0 residues, found " << mol.NumResidues() << '\n'; os << "# " << res->GetName() << endl; BOOST_CHECK_MESSAGE( 0, os.str().c_str() ); } } else BOOST_CHECK( 1 ); }
void CheckValidDipeptide(OBConversion &conv, const string &test, unsigned int testCount) { OBMol mol; mol.Clear(); conv.ReadString(&mol, test); chainsparser.PerceiveChains(mol); if (mol.NumResidues() != 2) { cout << "not ok " << testCount << " # expected 2 residues, but found " << mol.NumResidues() << '\n'; cout << "# "; FOR_RESIDUES_OF_MOL(res, mol) cout << res->GetName() << " "; cout << endl; } else { OBResidue *res; res = mol.GetResidue(0); cout << "ok " << testCount << " # " << res->GetName(); res = mol.GetResidue(1); cout << " " << res->GetName() << '\n'; } }
bool OpNewS::Do(OBBase* pOb, const char* OptionText, OpMap* pmap, OBConversion* pConv) { OBMol* pmol = dynamic_cast<OBMol*>(pOb); if(!pmol) return false; // The SMARTS and any other parameters are extracted on the first molecule // and stored in the member variables. The parameter is cleared so that // the original -s option in transform.cpp is inactive //string txt(pmap->find(GetID())->second); // ID can be "s" or "v" vector<OBQuery*>::iterator qiter; if(OptionText && *OptionText)//(!pConv || pConv->IsFirstInput()) { //Set up on first call queries.clear(); query=NULL; nPatternAtoms=0; inv=false; tokenize(vec, OptionText); inv = GetID()[0]=='v'; if(vec[0][0]=='~') { inv = true; vec[0].erase(0,1); } //Do not filter out any molecules if there is a parameter "showall"; //allows -s option to be used for highlighting substructures (--highlight also does this) vector<string>::iterator it = std::remove(vec.begin(), vec.end(),"showall"); showAll = it != vec.end(); if(showAll) vec.erase(it); //Store the number of matches required, if as a number in the second parameter, else 0. nmatches = 0; comparechar = '\0'; if(vec.size()>1) { comparechar = vec[1][0]; if(comparechar=='>' || comparechar=='<') vec[1].erase(0,1); else comparechar = '\0'; nmatches = atoi(vec[1].c_str()); if(nmatches) //remove this parameter to still allow coloring vec.erase(vec.begin()+1); } //Interpret as a filename if possible MakeQueriesFromMolInFile(queries, vec[0], &nPatternAtoms, strstr(OptionText,"noH")); vec.erase(remove(vec.begin(),vec.end(),"noH"),vec.end());//to prevent "noH2" being seen as a color if(queries.empty()) { //SMARTS supplied // Explicit H in SMARTS requires explicit H in the molecule. // Calling AddHydrogens() on a copy of the molecule is done in parsmart.cpp // only when SMARTS contains [H]. Doing more has complications with atom typing, // so AddHydrogens here on the molecule (not a copy) when #1 detected. addHydrogens = (vec[0].find("#1]")!=string::npos); // If extra target mols have been supplied, make a composite SMARTS // to test for any of the targets. if(ExtraMols.size()>0) { for(unsigned i=0;i<ExtraMols.size();++i) { OBConversion extraConv; extraConv.AddOption("h"); if(!extraConv.SetOutFormat("smi")) return false; // Add option which avoids implicit H being added to the SMARTS. // The parameter must be present but can be anything. extraConv.AddOption("h",OBConversion::OUTOPTIONS, "X"); xsmarts += ",$(" + extraConv.WriteString(ExtraMols[i], true) + ")"; } } string ysmarts = xsmarts.empty() ? vec[0] : "[$(" + vec[0] + ")" + xsmarts +"]"; xsmarts.clear(); if(!sp.Init(ysmarts)) { string msg = ysmarts + " cannot be interpreted as either valid SMARTS " "or the name of a file with an extension known to OpenBabel " "that contains one or more pattern molecules."; obErrorLog.ThrowError(__FUNCTION__, msg, obError, onceOnly); delete pmol; pmol = NULL; pConv->SetOneObjectOnly(); //stop conversion return false; } } else { // Target is in a file. Add extra targets if any supplied for(unsigned i=0;i<ExtraMols.size();++i) queries.push_back(CompileMoleculeQuery(static_cast<OBMol*>(ExtraMols[i]))); ExtraMols.clear(); } if(vec.size()>1 && vec[1]=="exact") { if(queries.empty()) { //Convert SMARTS to SMILES to count number of atoms OBConversion conv; OBMol patmol; if(!conv.SetInFormat("smi") || !conv.ReadString(&patmol, vec[0])) { obErrorLog.ThrowError(__FUNCTION__, "Cannot read the parameter of -s option, " "which has to be valid SMILES when the exact option is used.", obError, onceOnly); delete pmol; if(pConv) pConv->SetOneObjectOnly(); //stop conversion return false; } nPatternAtoms = patmol.NumHvyAtoms(); } } else nPatternAtoms = 0; //disable old versions if(pConv) pConv->AddOption(GetID(), OBConversion::GENOPTIONS, ""); } bool match = false; //These are a vector of each mapping, each containing atom indxs. vector<vector<int> > vecatomvec; vector<vector<int> >* pMappedAtoms = NULL; if(nPatternAtoms) if(pmol->NumHvyAtoms() != nPatternAtoms) return false; unsigned int imol=0; //index of mol in pattern file if(!queries.empty()) //filename supplied { //match is set true if any of the structures match - OR behaviour for(qiter=queries.begin();qiter!=queries.end();++qiter, ++imol) { OBIsomorphismMapper* mapper = OBIsomorphismMapper::GetInstance(*qiter); OBIsomorphismMapper::Mappings mappings; mapper->MapUnique(pmol, mappings); if( (match = !mappings.empty()) ) // extra parens to indicate truth value { OBIsomorphismMapper::Mappings::iterator ita; OBIsomorphismMapper::Mapping::iterator itb; for(ita=mappings.begin(); ita!=mappings.end();++ita)//each mapping { vector<int> atomvec; for(itb=ita->begin(); itb!=ita->end();++itb)//each atom index atomvec.push_back(itb->second+1); vecatomvec.push_back(atomvec); atomvec.clear(); } pMappedAtoms = &vecatomvec; break; } } } else //SMARTS supplied { if(addHydrogens) pmol->AddHydrogens(false,false); if( (match = sp.Match(*pmol)) ) // extra parens to indicate truth value { pMappedAtoms = &sp.GetMapList(); if(nmatches!=0) { int n = sp.GetUMapList().size(); if(comparechar=='>') match = (n > nmatches); else if(comparechar=='<') match = (n < nmatches); else match = (n == nmatches); } } } if((!showAll && (!match && !inv)) || (match && inv)) { //delete a non-matching mol delete pmol; pmol = NULL; return false; } if(match) //Copy the idxes of the first match to a member variable so that it can be retrieved from outside firstmatch.assign(pMappedAtoms->begin()->begin(), pMappedAtoms->begin()->end()); else firstmatch.clear(); if(match && !inv && vec.size()>=2 && !vec[1].empty() && !nPatternAtoms) { vector<vector<int> >::iterator iter; if (vec[1]=="extract" || (vec.size()>3 && vec[2]=="extract")) { //Delete all unmatched atoms. Use only the first match ExtractSubstruct(pmol, *pMappedAtoms->begin()); return true; } // color the substructure if there is a second parameter which is not "exact" or "extract" or "noH" // with multiple color parameters use the one corresponding to the query molecule, or the last if(imol>vec.size()-2) imol = vec.size()-2; for(iter=pMappedAtoms->begin();iter!=pMappedAtoms->end();++iter)//each match AddDataToSubstruct(pmol, *iter, "color", vec[imol+1]); return true; } if(pConv && pConv->IsLast()) { for(qiter=queries.begin();qiter!=queries.end();++qiter) delete *qiter; queries.clear(); } return true; }
bool FastSearchFormat::ObtainTarget(OBConversion* pConv, vector<OBMol>& patternMols, const string& indexname) { //Obtains an OBMol from: // the filename in the -s option or // the SMARTS string in the -s option or // by converting the file in the -S or -aS options (deprecated). // If there is no -s -S or -aS option, information on the index file is displayed. OBMol patternMol; patternMol.SetIsPatternStructure(); const char* p = pConv->IsOption("s",OBConversion::GENOPTIONS); bool OldSOption=false; //If no -s option, make OBMol from file in -S option or -aS option (both deprecated) if(!p) { p = pConv->IsOption("S",OBConversion::GENOPTIONS); if(!p) p = pConv->IsOption("S",OBConversion::INOPTIONS);//for GUI mainly OldSOption = true; } if(p) { vector<string> vec; tokenize(vec, p); //ignore leading ~ (not relevant to fastsearch) if(vec[0][0]=='~') vec[0].erase(0,1); if(vec.size()>1 && vec[1]=="exact") pConv->AddOption("e", OBConversion::INOPTIONS); OBConversion patternConv; OBFormat* pFormat; //Interpret as a filename if possible string& txt =vec [0]; if( txt.empty() || txt.find('.')==string::npos || !(pFormat = patternConv.FormatFromExt(txt.c_str())) || !patternConv.SetInFormat(pFormat) || !patternConv.ReadFile(&patternMol, txt) || patternMol.NumAtoms()==0) //if false, have a valid patternMol from a file { //is SMARTS/SMILES //Replace e.g. [#6] in SMARTS by C so that it can be converted as SMILES //for the fingerprint phase, but allow more generality in the SMARTS phase. for(;;) { string::size_type pos1, pos2; pos1 = txt.find("[#"); if(pos1==string::npos) break; pos2 = txt.find(']'); int atno; if(pos2!=string::npos && (atno = atoi(txt.substr(pos1+2, pos2-pos1-2).c_str())) && atno>0) txt.replace(pos1, pos2-pos1+1, etab.GetSymbol(atno)); else { obErrorLog.ThrowError(__FUNCTION__,"Ill-formed [#n] atom in SMARTS", obError); return false; } } bool hasTildeBond; if( (hasTildeBond = (txt.find('~')!=string::npos)) ) // extra parens to indicate truth value { //Find ~ bonds and make versions of query molecule with a single and aromatic bonds //To avoid having to parse the SMILES here, replace ~ by $ (quadruple bond) //and then replace this in patternMol. Check first that there are no $ already //Sadly, isocynanides may have $ bonds. if(txt.find('$')!=string::npos) { obErrorLog.ThrowError(__FUNCTION__, "Cannot use ~ bonds in patterns with $ (quadruple) bonds.)", obError); return false; } replace(txt.begin(),txt.end(), '~' , '$'); } //read as standard SMILES patternConv.SetInFormat("smi"); if(!patternConv.ReadString(&patternMol, vec[0])) { obErrorLog.ThrowError(__FUNCTION__,"Cannot read the SMILES string",obError); return false; } if(hasTildeBond) { AddPattern(patternMols, patternMol, 0); //recursively add all combinations of tilde bond values return true; } } else { // target(s) are in a file patternMols.push_back(patternMol); while(patternConv.Read(&patternMol)) patternMols.push_back(patternMol); return true; } } if(OldSOption) //only when using deprecated -S and -aS options { //make -s option for later SMARTS test OBConversion conv; if(conv.SetOutFormat("smi")) { string optiontext = conv.WriteString(&patternMol, true); pConv->AddOption("s", OBConversion::GENOPTIONS, optiontext.c_str()); } } if(!p) { //neither -s or -S options provided. Output info rather than doing search const FptIndexHeader& header = fs.GetIndexHeader(); string id(header.fpid); if(id.empty()) id = "default"; clog << indexname << " is an index of\n " << header.datafilename << ".\n It contains " << header.nEntries << " molecules. The fingerprint type is " << id << " with " << OBFingerprint::Getbitsperint() * header.words << " bits.\n" << "Typical usage for a substructure search:\n" << "obabel indexfile.fs -osmi -sSMILES\n" << "(-s option in GUI is 'Convert only if match SMARTS or mols in file')" << endl; return false; } patternMols.push_back(patternMol); return true; }
bool OpNewS::Do(OBBase* pOb, const char* OptionText, OpMap* pmap, OBConversion* pConv) { OBMol* pmol = dynamic_cast<OBMol*>(pOb); if(!pmol) return false; // The SMARTS and any other parameters are extracted on the first molecule // and stored in the static variables vec, inv. The parameter is cleared so that: // (a) the original -s option in transform.cpp is inactive, and // (b) the parsing does not have to be done again for multi-molecule files string txt(pmap->find(GetID())->second); // ID can be "s" or "v" static vector<string> vec; static bool inv; static int nPatternAtoms; //non-zero for exact matches static OBQuery* query; static vector<OBQuery*> queries; vector<OBQuery*>::iterator qiter; if(!txt.empty()) { //Set up on first call tokenize(vec, txt); inv = GetID()[0]=='v'; if(vec[0][0]=='~') { inv = true; vec[0].erase(0,1); } //Interpret as a filename if possible MakeQueriesFromMolInFile(queries, vec[0], &nPatternAtoms); if(vec.size()>1 && vec[1]=="exact") { if(queries.empty()) { //Convert SMARTS to SMILES to count number of atoms OBConversion conv; OBMol patmol; if(!conv.SetInFormat("smi") || !conv.ReadString(&patmol, vec[0])) { obErrorLog.ThrowError(__FUNCTION__, "Cannot read the parameter of -s option, " "which has to be valid SMILES when the exact option is used.", obError, onceOnly); delete pmol; pConv->SetOneObjectOnly(); //stop conversion return false; } nPatternAtoms = patmol.NumHvyAtoms(); } } else nPatternAtoms = 0; //disable old versions pConv->AddOption(GetID(), OBConversion::GENOPTIONS, ""); } bool match; //These are a vector of each mapping, each containing atom indxs. vector<vector<int> > vecatomvec; vector<vector<int> >* pMappedAtoms = NULL; OBSmartsPattern sp; if(nPatternAtoms) if(pmol->NumHvyAtoms() != nPatternAtoms) return false; int imol=0; //index of mol in pattern file if(!queries.empty()) //filename supplied { //match is set true if any of the structures match - OR behaviour for(qiter=queries.begin();qiter!=queries.end();++qiter, ++imol) { OBIsomorphismMapper* mapper = OBIsomorphismMapper::GetInstance(*qiter); OBIsomorphismMapper::Mappings mappings; mapper->MapUnique(pmol, mappings); if( (match = !mappings.empty()) ) // extra parens to indicate truth value { OBIsomorphismMapper::Mappings::iterator ita; OBIsomorphismMapper::Mapping::iterator itb; for(ita=mappings.begin(); ita!=mappings.end();++ita)//each mapping { vector<int> atomvec; for(itb=ita->begin(); itb!=ita->end();++itb)//each atom index atomvec.push_back(itb->second+1); vecatomvec.push_back(atomvec); atomvec.clear(); } pMappedAtoms = &vecatomvec; break; } } } else //SMARTS supplied { if(!sp.Init(vec[0])) { string msg = vec[0] + " cannot be interpreted as either valid SMARTS " "or the name of a file with an extension known to OpenBabel " "that contains one or more pattern molecules."; obErrorLog.ThrowError(__FUNCTION__, msg, obError, onceOnly); delete pmol; pmol = NULL; pConv->SetOneObjectOnly(); //stop conversion return false; } if( (match = sp.Match(*pmol)) ) // extra parens to indicate truth value pMappedAtoms = &sp.GetMapList(); } if((!match && !inv) || (match && inv)) { //delete a non-matching mol delete pmol; pmol = NULL; return false; } if(!inv && vec.size()>=2 && !vec[1].empty() && !nPatternAtoms) { vector<vector<int> >::iterator iter; if(vec[1]=="extract") { //Delete all unmatched atoms. Use only the first match ExtractSubstruct(pmol, *pMappedAtoms->begin()); return true; } // color the substructure if there is a second parameter which is not "exact" or "extract" // with multiple color parameters use the one corresponding to the query molecule, or the last if(imol>vec.size()-2) imol = vec.size()-2; for(iter=pMappedAtoms->begin();iter!=pMappedAtoms->end();++iter)//each match AddDataToSubstruct(pmol, *iter, "color", vec[imol+1]); return true; } if(pConv && pConv->IsLast()) { for(qiter=queries.begin();qiter!=queries.end();++qiter) delete *qiter; queries.clear(); } return true; }
void residue_test() { cout << "# Unit tests for OBResidue \n"; // OBResidue isolation tests OBResidue emptyResidue, testRes1; // chains parser tests // PR#1515198 static const string loopTest1("C1(C(NC(C(N1C(C(NC(C=Cc1ccccc1)=O)C)=O)Cc1ccccc1)=O)Cc1ccccc1)=O"); OBConversion conv; OBMol mol; OBFormat *inFormat = conv.FindFormat("SMI"); conv.SetInFormat(inFormat); conv.ReadString(&mol, loopTest1); chainsparser.PerceiveChains(mol); // parse common residues unsigned int testCount = 3; static const string ala("NC(C)C(O)(=O)"); CheckValidResidue(conv, ala, ++testCount); static const string arg("NC(CCCNC(N)=N)C(O)(=O)"); CheckValidResidue(conv, arg, ++testCount); static const string asn("NC(CC(N)=O)C(O)(=O)"); CheckValidResidue(conv, asn, ++testCount); static const string asp("NC(CC(O)=O)C(O)(=O)"); CheckValidResidue(conv, asp, ++testCount); static const string cys("NC(CS)C(O)(=O)"); CheckValidResidue(conv, cys, ++testCount); static const string glu("NC(CCC(O)=O)C(O)(=O)"); CheckValidResidue(conv, glu, ++testCount); static const string gln("NC(CCC(N)=O)C(O)(=O)"); CheckValidResidue(conv, gln, ++testCount); static const string gly("NC([H])C(O)(=O)"); CheckValidResidue(conv, gly, ++testCount); static const string his("NC(CC1=CNC=N1)C(O)(=O)"); CheckValidResidue(conv, his, ++testCount); static const string ile("NC(C(CC)C)C(O)(=O)"); CheckValidResidue(conv, ile, ++testCount); static const string leu("NC(CC(C)C)C(O)(=O)"); CheckValidResidue(conv, leu, ++testCount); static const string lys("NC(CCCCN)C(O)(=O)"); CheckValidResidue(conv, lys, ++testCount); static const string met("NC(CCSC)C(O)(=O)"); CheckValidResidue(conv, met, ++testCount); static const string phe("NC(CC1=CC=CC=C1)C(O)(=O)"); CheckValidResidue(conv, phe, ++testCount); static const string pro("OC(C1CCCN1)(=O)"); CheckValidResidue(conv, pro, ++testCount); static const string ser("NC(CO)C(O)(=O)"); CheckValidResidue(conv, ser, ++testCount); static const string thr("NC(C(C)O)C(O)(=O)"); CheckValidResidue(conv, thr, ++testCount); static const string trp("NC(CC1=CNC2=C1C=CC=C2)C(O)(=O)"); CheckValidResidue(conv, trp, ++testCount); static const string tyr("NC(CC1=CC=C(O)C=C1)C(O)(=O)"); CheckValidResidue(conv, tyr, ++testCount); static const string val("NC(C(C)C)C(O)(=O)"); CheckValidResidue(conv, val, ++testCount); // nucleics static const string a("OC[C@H]1O[C@H](C[C@@H]1O)n1cnc2c(ncnc12)N"); CheckValidResidue(conv, a, ++testCount); static const string g("OC[C@H]1O[C@H](C[C@@H]1O)n1c(nc(cc1)N)=O"); CheckValidResidue(conv, g, ++testCount); static const string c("OC[C@H]1O[C@H](C[C@@H]1O)n1cnc2c([nH]c(nc12)N)=O"); CheckValidResidue(conv, c, ++testCount); static const string t("OC[C@H]1O[C@H](C[C@@H]1O)n1c([nH]c(c(c1)C)=O)=O"); CheckValidResidue(conv, t, ++testCount); static const string u("OC[C@H]1O[C@H]([C@@H]([C@@H]1O)O)n1c([nH]c(cc1)=O)=O"); CheckValidResidue(conv, u, ++testCount); // invalid residues static const string benzene("c1ccccc1"); CheckInvalidResidue(conv, benzene, ++testCount); static const string pyrrole("c1cccn[H]1"); CheckInvalidResidue(conv, pyrrole, ++testCount); static const string amine("CC(=O)CCN"); CheckInvalidResidue(conv, amine, ++testCount); // check some dipeptides static const string ala_val("NC(C)C(=O)NC(C(C)C)C(=O)O"); CheckValidDipeptide(conv, ala_val, ++testCount); static const string cys_leu("NC(CS)C(=O)NC(CC(C)C)C(=O)O"); CheckValidDipeptide(conv, cys_leu, ++testCount); }
int main(int argc,char *argv[]) { // turn off slow sync with C-style output (we don't use it anyway). std::ios::sync_with_stdio(false); if (argc != 1) { cout << "Usage: conversion" << endl; cout << " Unit tests for OBConversion " << endl; return(-1); } cout << "# Unit tests for OBConversion \n"; // the number of tests for "prove" cout << "1..9\n"; cout << "ok 1\n"; // for loading tests OBMol obMol; OBConversion obConversion; obConversion.SetInAndOutFormats("smi", "mdl"); cout << "ok 2\n"; obConversion.ReadString(&obMol, "C1=CC=CS1"); cout << "ok 3\n"; if (obMol.NumAtoms() == 5) { cout << "ok 4\n"; } else { cout << "not ok 4\n"; } obMol.AddHydrogens(); if (obMol.NumAtoms() == 9) { cout << "ok 5\n"; } else { cout << "not ok 5\n"; } if ( (obConversion.WriteString(&obMol)).length() > 0) cout << "ok 6\n"; else cout << "not ok 6\n"; // PR#1474265 obConversion.WriteFile(&obMol, "test.mdl"); ifstream ifs("test.mdl"); if (ifs.good()) cout << "ok 7\n"; else cout << "not ok 7\n"; // PR#143577 obConversion.SetInFormat("mdl"); obConversion.ReadFile(&obMol, "test.mdl"); if ( remove("test.mdl") != -1) cout << "ok 8\n"; else cout << "not ok 8\n"; // gzip input // gzip output // multi-molecule reading // PR#1465586 // aromatics.smi // attype.00.smi //ReadFile() //Read() //WriteString() // GetOutputIndex() // IsLast //ReadString() //IsFirstInput //Read() // splitting // splitting using gzip-input // PR#1357705 // size 0 input // PR#1250900 // RegisterFormat // FindFormat // FormatFromExt // FormatFromMIME // GetNextFormat // GetDefaultFormat // BatchFileName // IncrementedFileName // option handling // AddOption // IsOption // RemoveOption // IsOption // SetOptions // IsOption // RegisterOptionParam // GetOptionParams // GetInStream // GetOutStream // SetInStream // SetOutStream // nasty tests obConversion.ReadString(&obMol, ""); obConversion.Read(&obMol); cout << "ok 9\n"; return(0); }
void genericSmilesCanonicalTest(const std::string &smiles) { cout << "Testing generic smiles <-> canonical smiles" << endl; // read a smiles string OBMol mol; OBConversion conv; OB_REQUIRE( conv.SetInFormat("smi") ); OB_REQUIRE( conv.SetOutFormat("can") ); cout << "smiles: " << smiles << endl; // read a smiles string OB_REQUIRE( conv.ReadString(&mol, smiles) ); // store the stereo data for the smiles string using unique symmetry ids std::vector<OBTetrahedralStereo::Config> tetrahedral1; std::vector<OBCisTransStereo::Config> cistrans1; std::vector<OBSquarePlanarStereo::Config> squareplanar1; // get the stereo data OB_ASSERT( mol.HasData(OBGenericDataType::StereoData) ); std::vector<OBGenericData *> stereoData = mol.GetAllData(OBGenericDataType::StereoData); std::vector<unsigned int> canlbls; std::vector<unsigned int> symclasses; OBGraphSym gs1(&mol); gs1.GetSymmetry(symclasses); CanonicalLabels(&mol, symclasses, canlbls); cout << "mol.NumAtoms = " << mol.NumAtoms() << endl; for (std::vector<OBGenericData*>::iterator data = stereoData.begin(); data != stereoData.end(); ++data) { if (((OBStereoBase*)*data)->GetType() == OBStereo::Tetrahedral) { // convert to tetrahedral data OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(*data); OB_REQUIRE( ts ); OB_ASSERT( ts->IsValid() ); if (!ts->IsValid()) continue; OBTetrahedralStereo::Config config = ts->GetConfig(); // convert atom ids to symmetry ids if (mol.GetAtomById(config.center)) config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 ); if (mol.GetAtomById(config.from)) config.from = canlbls.at( mol.GetAtomById(config.from)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; tetrahedral1.push_back(config); } else if (((OBStereoBase*)*data)->GetType() == OBStereo::CisTrans) { // convert to tetrahedral data OBCisTransStereo *ct = dynamic_cast<OBCisTransStereo*>(*data); OB_REQUIRE( ct ); OB_ASSERT( ct->IsValid() ); OBCisTransStereo::Config config = ct->GetConfig(); // convert atom ids to symmetry ids config.begin = canlbls.at( mol.GetAtomById(config.begin)->GetIdx() - 1 ); config.end = canlbls.at( mol.GetAtomById(config.end)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[3])) config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; cistrans1.push_back(config); } else if (((OBStereoBase*)*data)->GetType() == OBStereo::SquarePlanar) { // convert to tetrahedral data OBSquarePlanarStereo *sp = dynamic_cast<OBSquarePlanarStereo*>(*data); OB_REQUIRE( sp ); OB_ASSERT( sp->IsValid() ); if (!sp->IsValid()) continue; OBSquarePlanarStereo::Config config = sp->GetConfig(); // convert atom ids to symmetry ids if (mol.GetAtomById(config.center)) config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[3])) config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; squareplanar1.push_back(config); } } // write to can smiles std::string canSmiles = conv.WriteString(&mol); cout << "canSmiles: " << canSmiles; // read can smiles in again OB_REQUIRE( conv.ReadString(&mol, canSmiles) ); // store the stereo data for the smiles string using unique symmetry ids std::vector<OBTetrahedralStereo::Config> tetrahedral2; std::vector<OBCisTransStereo::Config> cistrans2; std::vector<OBSquarePlanarStereo::Config> squareplanar2; // get the stereo data OB_ASSERT( mol.HasData(OBGenericDataType::StereoData) ); stereoData = mol.GetAllData(OBGenericDataType::StereoData); OBGraphSym gs2(&mol); gs2.GetSymmetry(symclasses); CanonicalLabels(&mol, symclasses, canlbls); cout << "mol.NumAtoms = " << mol.NumAtoms() << endl; for (std::vector<OBGenericData*>::iterator data = stereoData.begin(); data != stereoData.end(); ++data) { if (((OBStereoBase*)*data)->GetType() == OBStereo::Tetrahedral) { // convert to tetrahedral data OBTetrahedralStereo *ts = dynamic_cast<OBTetrahedralStereo*>(*data); OB_REQUIRE( ts ); OB_ASSERT( ts->IsValid() ); OBTetrahedralStereo::Config config = ts->GetConfig(); // convert atom ids to symmetry ids if (mol.GetAtomById(config.center)) config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 ); if (mol.GetAtomById(config.from)) config.from = canlbls.at( mol.GetAtomById(config.from)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; tetrahedral2.push_back(config); } if (((OBStereoBase*)*data)->GetType() == OBStereo::CisTrans) { // convert to tetrahedral data OBCisTransStereo *ct = dynamic_cast<OBCisTransStereo*>(*data); OB_REQUIRE( ct ); OB_ASSERT( ct->IsValid() ); OBCisTransStereo::Config config = ct->GetConfig(); // convert atom ids to symmetry ids config.begin = canlbls.at( mol.GetAtomById(config.begin)->GetIdx() - 1 ); config.end = canlbls.at( mol.GetAtomById(config.end)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[3])) config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; cistrans2.push_back(config); } else if (((OBStereoBase*)*data)->GetType() == OBStereo::SquarePlanar) { // convert to tetrahedral data OBSquarePlanarStereo *sp = dynamic_cast<OBSquarePlanarStereo*>(*data); OB_REQUIRE( sp ); OB_ASSERT( sp->IsValid() ); OBSquarePlanarStereo::Config config = sp->GetConfig(); // convert atom ids to symmetry ids if (mol.GetAtomById(config.center)) config.center = canlbls.at( mol.GetAtomById(config.center)->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[0])) config.refs[0] = canlbls.at( mol.GetAtomById(config.refs[0])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[1])) config.refs[1] = canlbls.at( mol.GetAtomById(config.refs[1])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[2])) config.refs[2] = canlbls.at( mol.GetAtomById(config.refs[2])->GetIdx() - 1 ); if (mol.GetAtomById(config.refs[3])) config.refs[3] = canlbls.at( mol.GetAtomById(config.refs[3])->GetIdx() - 1 ); cout << "Config with symmetry ids: " << config << endl; squareplanar2.push_back(config); } } // compare the tetrahedral structs OB_ASSERT( tetrahedral1.size() == tetrahedral2.size() ); for (unsigned int i = 0; i < tetrahedral1.size(); ++i) { for (unsigned int j = 0; j < tetrahedral2.size(); ++j) { if (tetrahedral1[i].center == tetrahedral2[j].center) OB_ASSERT( tetrahedral1[i] == tetrahedral2[j] ); if ( tetrahedral1[i] != tetrahedral2[j] ) { cout << "1 = " << tetrahedral1[i] << endl; cout << "2 = " << tetrahedral2[j] << endl; } } } // compare the cistrans structs OB_ASSERT( cistrans1.size() == cistrans2.size() ); for (unsigned int i = 0; i < cistrans1.size(); ++i) { for (unsigned int j = 0; j < cistrans2.size(); ++j) { if ((cistrans1[i].begin == cistrans2[j].begin) && (cistrans1[i].end == cistrans2[j].end)) OB_ASSERT( cistrans1[i] == cistrans2[j] ); if ((cistrans1[i].begin == cistrans2[j].end) && (cistrans1[i].end == cistrans2[j].begin)) OB_ASSERT( cistrans1[i] == cistrans2[j] ); } } // compare the square-planar structs OB_ASSERT( squareplanar1.size() == squareplanar2.size() ); for (unsigned int i = 0; i < squareplanar1.size(); ++i) { for (unsigned int j = 0; j < squareplanar2.size(); ++j) { if (squareplanar1[i].center == squareplanar2[j].center) OB_ASSERT( squareplanar1[i] == squareplanar2[j] ); if ( squareplanar1[i] != squareplanar2[j] ) { cout << "1 = " << squareplanar1[i] << endl; cout << "2 = " << squareplanar2[j] << endl; } } } cout << "." << endl << endl; }
int main(int argc,char *argv[]) { // turn off slow sync with C-style output (we don't use it anyway). std::ios::sync_with_stdio(false); if (argc != 1) { cout << "Usage: residue" << endl; cout << " Unit tests for OBResidue " << endl; return(-1); } cout << "# Unit tests for OBResidue \n"; cout << "ok 1\n"; // for loading tests // OBResidue isolation tests OBResidue emptyResidue, testRes1; cout << "ok 2\n"; // ctor works // chains parser tests // PR#1515198 static const string loopTest1("C1(C(NC(C(N1C(C(NC(C=Cc1ccccc1)=O)C)=O)Cc1ccccc1)=O)Cc1ccccc1)=O"); OBConversion conv; OBMol mol; OBFormat *inFormat = conv.FindFormat("SMI"); conv.SetInFormat(inFormat); conv.ReadString(&mol, loopTest1); chainsparser.PerceiveChains(mol); // OK if it doesn't crash cout << "ok 3\n"; // parse common residues unsigned int testCount = 3; static const string ala("NC(C)C(O)(=O)"); CheckValidResidue(conv, ala, ++testCount); static const string arg("NC(CCCNC(N)=N)C(O)(=O)"); CheckValidResidue(conv, arg, ++testCount); static const string asn("NC(CC(N)=O)C(O)(=O)"); CheckValidResidue(conv, asn, ++testCount); static const string asp("NC(CC(O)=O)C(O)(=O)"); CheckValidResidue(conv, asp, ++testCount); static const string cys("NC(CS)C(O)(=O)"); CheckValidResidue(conv, cys, ++testCount); static const string glu("NC(CCC(O)=O)C(O)(=O)"); CheckValidResidue(conv, glu, ++testCount); static const string gln("NC(CCC(N)=O)C(O)(=O)"); CheckValidResidue(conv, gln, ++testCount); static const string gly("NC([H])C(O)(=O)"); CheckValidResidue(conv, gly, ++testCount); static const string his("NC(CC1=CNC=N1)C(O)(=O)"); CheckValidResidue(conv, his, ++testCount); static const string ile("NC(C(CC)C)C(O)(=O)"); CheckValidResidue(conv, ile, ++testCount); static const string leu("NC(CC(C)C)C(O)(=O)"); CheckValidResidue(conv, leu, ++testCount); static const string lys("NC(CCCCN)C(O)(=O)"); CheckValidResidue(conv, lys, ++testCount); static const string met("NC(CCSC)C(O)(=O)"); CheckValidResidue(conv, met, ++testCount); static const string phe("NC(CC1=CC=CC=C1)C(O)(=O)"); CheckValidResidue(conv, phe, ++testCount); static const string pro("OC(C1CCCN1)(=O)"); CheckValidResidue(conv, pro, ++testCount); static const string ser("NC(CO)C(O)(=O)"); CheckValidResidue(conv, ser, ++testCount); static const string thr("NC(C(C)O)C(O)(=O)"); CheckValidResidue(conv, thr, ++testCount); static const string trp("NC(CC1=CNC2=C1C=CC=C2)C(O)(=O)"); CheckValidResidue(conv, trp, ++testCount); static const string tyr("NC(CC1=CC=C(O)C=C1)C(O)(=O)"); CheckValidResidue(conv, tyr, ++testCount); static const string val("NC(C(C)C)C(O)(=O)"); CheckValidResidue(conv, val, ++testCount); // nucleics static const string a("OC[C@H]1O[C@H](C[C@@H]1O)n1cnc2c(ncnc12)N"); CheckValidResidue(conv, a, ++testCount); static const string g("OC[C@H]1O[C@H](C[C@@H]1O)n1c(nc(cc1)N)=O"); CheckValidResidue(conv, g, ++testCount); static const string c("OC[C@H]1O[C@H](C[C@@H]1O)n1cnc2c([nH]c(nc12)N)=O"); CheckValidResidue(conv, c, ++testCount); static const string t("OC[C@H]1O[C@H](C[C@@H]1O)n1c([nH]c(c(c1)C)=O)=O"); CheckValidResidue(conv, t, ++testCount); static const string u("OC[C@H]1O[C@H]([C@@H]([C@@H]1O)O)n1c([nH]c(cc1)=O)=O"); CheckValidResidue(conv, u, ++testCount); // invalid residues static const string benzene("c1ccccc1"); CheckInvalidResidue(conv, benzene, ++testCount); static const string pyrrole("c1cccn[H]1"); CheckInvalidResidue(conv, pyrrole, ++testCount); static const string amine("CC(=O)CCN"); CheckInvalidResidue(conv, amine, ++testCount); // check some dipeptides static const string ala_val("NC(C)C(=O)NC(C(C)C)C(=O)O"); CheckValidDipeptide(conv, ala_val, ++testCount); static const string cys_leu("NC(CS)C(=O)NC(CC(C)C)C(=O)O"); CheckValidDipeptide(conv, cys_leu, ++testCount); // the number of tests for "prove" cout << "1.." << testCount << "\n"; return(0); }
void phmodel_test() { OBMol mol; OBConversion conv; conv.SetInFormat("smi"); conv.SetOutFormat("smi"); unsigned int test = 0; // amine acid COOH pKa = 4.0 (carboxylic acid entry in phmodel.txt) // amino acid NH3+ pKa = 10.0 (amine entry in phmodel.txt) // // Aspartic acid (sidechain COOH pKa = 3.8) // conv.ReadString(&mol, "NC(CC(O)=O)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 1.0); // NH3+ COOH COOH //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 17, "Aspartic acid pH 1.0" ); conv.ReadString(&mol, "NC(CC(O)=O)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 3.9); // NH3+ COOH COO- //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 16, "Aspartic acid pH 3.9" ); conv.ReadString(&mol, "NC(CC(O)=O)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 7.4); // NH3+ COO- COO- //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 15, "Aspartic acid pH 7.4" ); conv.ReadString(&mol, "NC(CC(O)=O)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 13.0); // NH2 COO- COO- //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 14, "Aspartic acid pH 13.0" ); // // Glutamic acid (sidechain COOH pKa = 4.3) // conv.ReadString(&mol, "NC(CCC(O)=O)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 1.0); // NH3+ COOH COOH //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 20, "Glutamic acid pH 1.0" ); conv.ReadString(&mol, "NC(CCC(O)=O)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 4.15); // NH3+ COOH COO- //conv.Write(&mol, &cout); // known bug BOOST_CHECK_MESSAGE( mol.NumAtoms() == 19, "Glutamic acid pH 4.15" ); conv.ReadString(&mol, "NC(CCC(O)=O)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 7.4); // NH3+ COO- COO- //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 18, "Glutamic acid pH 7.4" ); conv.ReadString(&mol, "NC(CCC(O)=O)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 13.0); // NH2 COO- COO- //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 17, "Glutamic acid pH 13.0" ); // // Histidine (sidechain nH+ pKa = 6.08) // conv.ReadString(&mol, "NC(Cc1ncnc1)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 1.0); // NH3+ COOH nH+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 22, "Histidine pH 1.0" ); conv.ReadString(&mol, "NC(Cc1ncnc1)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 5.0); // NH3+ COO- nH+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 21, "Histidine pH 5.0" ); conv.ReadString(&mol, "NC(Cc1ncnc1)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 7.4); // NH3+ COO- n: //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 20, "Histidine pH 7.4" ); conv.ReadString(&mol, "NC(Cc1ncnc1)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 13.0); // NH2 COO- n: //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 19, "Histidine pH 13.0" ); // // Lysine (sidechain NH3+ pKa = 8.28) // conv.ReadString(&mol, "NC(CCCCN)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 1.0); // NH3+ COOH NH3+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 26, "Lysine pH 1.0" ); conv.ReadString(&mol, "NC(CCCCN)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 7.4); // NH3+ COO- NH3+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 25, "Lysine pH 7.4" ); conv.ReadString(&mol, "NC(CCCCN)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 9.0); // NH3+ COO- NH2 //conv.Write(&mol, &cout); // known bug BOOST_CHECK_MESSAGE( mol.NumAtoms() == 24, "Lysine pH 9.0" ); conv.ReadString(&mol, "NC(CCCCN)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 13.0); // NH2 COO- NH2 //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 23, "Lysine pH 13.0" ); // // Tyrosine (sidechain OH pKa = 10.1) // conv.ReadString(&mol, "NC(Cc1ccc(O)cc1)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 1.0); // NH3+ COOH NH3+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 25, "Tyrosine pH 1.0" ); conv.ReadString(&mol, "NC(Cc1ccc(O)cc1)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 7.4); // NH3+ COO- NH3+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 24, "Tyrosine pH 7.4" ); conv.ReadString(&mol, "NC(Cc1ccc(O)cc1)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 10.05); // NH3+ COO- NH2 //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 23, "Tyrosine pH 10.05" ); conv.ReadString(&mol, "NC(Cc1ccc(O)cc1)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 13.0); // NH2 COO- NH2 //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 22, "Tyrosine pH 13.0" ); // // Arginine (sidechain =NH2+ pKa = 12.0) // conv.ReadString(&mol, "NC(CCCNC(N)=N)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 1.0); // NH3+ COOH =NH2+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 28, "Arginine pH 1.0" ); conv.ReadString(&mol, "NC(CCCNC(N)=N)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 7.4); // NH3+ COO- NH3+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 27, "Arginine pH 7.4" ); conv.ReadString(&mol, "NC(CCCNC(N)=N)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 11.0); // NH3+ COO- NH2 //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 26, "Arginine pH 11.0" ); conv.ReadString(&mol, "NC(CCCNC(N)=N)C(O)=O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 13.0); // NH2 COO- NH2 //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 25, "Arginine pH 13.0" ); // // Gly-Gly (terminal NH3+, COOH and the amide bond) // conv.ReadString(&mol, "NCC(=O)NCC(=O)O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 1.0); // NH3+ COOH =NH2+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 18, "Gly-Gly pH 1.0" ); conv.ReadString(&mol, "NCC(=O)NCC(=O)O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 7.4); // NH3+ COO- NH3+ //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 17, "Gly-Gly pH 7.4" ); conv.ReadString(&mol, "NCC(=O)NCC(=O)O"); mol.SetAutomaticFormalCharge(true); mol.AddHydrogens(false, true, 13.0); // NH2 COO- NH2 //conv.Write(&mol, &cout); BOOST_CHECK_MESSAGE( mol.NumAtoms() == 16, "Gly-Gly pH 13.0" ); }
void readSmiles(const std::string &smiles, OBMol &mol) { OBConversion conv; conv.SetInFormat("smi"); conv.ReadString(&mol, smiles); }