void testPdbOccupancies() { // See https://github.com/openbabel/openbabel/pull/1558 OBConversion conv; OBMol mol; conv.SetInFormat("cif"); conv.SetOutFormat("pdb"); conv.ReadFile(&mol, GetFilename("test08.cif")); string pdb = conv.WriteString(&mol); conv.AddOption("o", OBConversion::OUTOPTIONS); pdb = conv.WriteString(&mol); OB_ASSERT(pdb.find("HETATM 1 NA UNL 1 0.325 0.000 4.425 0.36") != string::npos); OB_ASSERT(pdb.find("HETATM 17 O UNL 8 1.954 8.956 3.035 1.00") != string::npos); OBMol mol_pdb; conv.SetInFormat("pdb"); conv.ReadFile(&mol_pdb, GetFilename("test09.pdb")); pdb = conv.WriteString(&mol_pdb); OB_ASSERT(pdb.find("HETATM 1 NA UNL 1 0.325 0.000 4.425 0.36") != string::npos); OB_ASSERT(pdb.find("HETATM 2 NA UNL 1 0.002 8.956 1.393 0.10") != string::npos); OB_ASSERT(pdb.find("HETATM 17 O UNL 8 1.954 8.956 3.035 1.00") != string::npos); }
bool MakeQueriesFromMolInFile(vector<OBQuery*>& queries, const std::string& filename, int* pnAtoms, bool noH) { OBMol patternMol; patternMol.SetIsPatternStructure(); OBConversion patternConv; OBFormat* pFormat; //Need to distinguish between filename and SMARTS. Not infallable... if( filename.empty() || filename.find('.')==string::npos || !(pFormat = patternConv.FormatFromExt(filename.c_str())) || !patternConv.SetInFormat(pFormat) || !patternConv.ReadFile(&patternMol, filename) || patternMol.NumAtoms()==0) return false; if(noH) patternMol.DeleteHydrogens(); do { *pnAtoms = patternMol.NumHvyAtoms(); queries.push_back(CompileMoleculeQuery(&patternMol)); }while(patternConv.Read(&patternMol)); return true; }
void LinMorphExtension::loadFile(QString file) { qDebug("LinMorphExtension::loadFile()"); if (file.isEmpty()) return; if (!m_secondMolecule) m_secondMolecule = new Molecule; OBConversion conv; OBFormat *inFormat = OBConversion::FormatFromExt(( file.toAscii() ).data() ); if ( !inFormat || !conv.SetInFormat( inFormat ) ) { QMessageBox::warning( NULL, tr( "Avogadro" ), tr( "Cannot read file format of file %1." ) .arg( file ) ); return; } if (!conv.ReadFile(m_secondMolecule, file.toStdString())) { QMessageBox::warning( NULL, tr( "Avogadro" ), tr( "Read mol file %1 failed." ) .arg( file ) ); return; } qDebug("LinMorphExtension::loadFile complete"); computeConformers(m_secondMolecule); m_linMorphDialog->setFrame(1); m_timeLine->setFrameRange(1, m_frameCount); setDuration(m_linMorphDialog->fps()); }
void testSpaceGroupClean() { // See https://github.com/openbabel/openbabel/pull/254 OBConversion conv; OBMol mol; conv.SetInFormat("cif"); conv.SetOutFormat("pdb"); conv.ReadFile(&mol, GetFilename("test02.cif")); OBUnitCell* pUC = (OBUnitCell*)mol.GetData(OBGenericDataType::UnitCell); const SpaceGroup* pSG = pUC->GetSpaceGroup(); SpaceGroup* sg = new SpaceGroup(*pSG); pSG = SpaceGroup::Find(sg); OB_ASSERT( pSG != NULL ); // Check also for errors and warnings string summary = obErrorLog.GetMessageSummary(); OB_ASSERT( summary.find("error") == string::npos); OB_ASSERT( summary.find("warning") == string::npos); OB_ASSERT( pSG->GetId() == 166 ); string pdb = conv.WriteString(&mol); pdb = conv.WriteString(&mol); OB_ASSERT(pdb.find("H -3 m") != string::npos); }
void ColoredMol::color() { OBConversion conv; std::string ext = boost::filesystem::extension(ligName); if(ext.compare(".pdb") == 0) { conv.SetInFormat("PDB"); } else if(ext.compare(".pdbqt") == 0) { conv.SetInFormat("PDBQT"); } else { std::cout << "File extension not supported: " << ligName << '\n'; std::cout << "Please use .pdb or .pdbqt for ligand\n"; exit(0); } conv.ReadFile(&ligMol, ligName); ext = boost::filesystem::extension(recName); if(ext.compare(".pdb") == 0) { conv.SetInFormat("PDB"); } else { std::cout << "File extension not supported: " << recName << '\n'; std::cout << "Please use .pdb for receptor\n"; exit(0); } conv.ReadFile(&recMol, recName); addHydrogens(); ligCenter(); removeResidues(); removeEachAtom(); }
void testCIFMolecules() { // See https://github.com/openbabel/openbabel/pull/1558 OBConversion conv; OBMol mol; conv.SetInFormat("cif"); conv.SetOutFormat("smi"); // check for disconnected fragments conv.ReadFile(&mol, GetFilename("1519159.cif")); string smi = conv.WriteString(&mol); // never, never disconnected fragments from a molecule OB_ASSERT(smi.find(".") == string::npos); }
void testPdbRemSpacesHMName() { // See https://github.com/openbabel/openbabel/pull/1558 OBConversion conv; OBMol mol; conv.SetInFormat("cif"); conv.SetOutFormat("pdb"); conv.ReadFile(&mol, GetFilename("test07.cif")); string pdb = conv.WriteString(&mol); conv.AddOption("o", OBConversion::OUTOPTIONS); pdb = conv.WriteString(&mol); OB_ASSERT(pdb.find("I41/amd:2") != string::npos); }
void testPdbOutHexagonalAlternativeOrigin2() { // See https://github.com/openbabel/openbabel/pull/1558 OBConversion conv; OBMol mol; conv.SetInFormat("cif"); conv.SetOutFormat("pdb"); conv.ReadFile(&mol, GetFilename("test06.cif")); string pdb = conv.WriteString(&mol); conv.AddOption("o", OBConversion::OUTOPTIONS); pdb = conv.WriteString(&mol); OB_ASSERT(pdb.find("H -3 m") != string::npos); }
void testAlternativeOrigin() { // See https://github.com/openbabel/openbabel/pull/1558 OBConversion conv; OBMol mol; conv.SetInFormat("cif"); conv.ReadFile(&mol, GetFilename("test04.cif")); OBUnitCell* pUC = (OBUnitCell*)mol.GetData(OBGenericDataType::UnitCell); const SpaceGroup* pSG = pUC->GetSpaceGroup(); SpaceGroup* sg = new SpaceGroup(*pSG); pSG = SpaceGroup::Find(sg); string summary = obErrorLog.GetMessageSummary(); OB_ASSERT( summary.find("warning") == string::npos); OB_ASSERT( pSG != NULL ); OB_ASSERT( pSG->GetOriginAlternative() == 1); }
void testPdbOutAlternativeOrigin() { // See https://github.com/openbabel/openbabel/pull/1558 OBConversion conv; OBMol mol; conv.SetInFormat("cif"); conv.SetOutFormat("pdb"); conv.ReadFile(&mol, GetFilename("test04.cif")); string pdb = conv.WriteString(&mol); // ending space is needed to check that there is no origin set OB_ASSERT(pdb.find("P 4/n b m ") != string::npos); conv.AddOption("o", OBConversion::OUTOPTIONS); pdb = conv.WriteString(&mol); OB_ASSERT(pdb.find("P 4/n b m:1") != string::npos); }
void testDecayToP1() { // See https://github.com/openbabel/openbabel/pull/261 OBConversion conv; OBMol mol; conv.SetInFormat("cif"); conv.ReadFile(&mol, GetFilename("test03.cif")); OBUnitCell* pUC = (OBUnitCell*)mol.GetData(OBGenericDataType::UnitCell); const SpaceGroup* pSG = pUC->GetSpaceGroup(); SpaceGroup* sg = new SpaceGroup(*pSG); pSG = SpaceGroup::Find(sg); OB_ASSERT( pSG != NULL ); // Check also for errors and warnings string summary = obErrorLog.GetMessageSummary(); OB_ASSERT( summary.find("2 warnings") != string::npos); OB_ASSERT( pSG->GetId() == 1 ); }
int main(int argc, char *argv[]) { string prog_name(argv[0]); string root; string::size_type i = prog_name.find_last_of("/\\"); if(i == string::npos) root = "./"; else root = prog_name.substr(0,i+1); if(argc<3 || argc>7) { cerr << endl << " OBJ : to find maximum common subgraph between mol1 and mol2" << endl << endl << " Usage: " << argv[0] << "[options] mol1 mol2" << endl << " [options]" << endl << " --rmax n: stop recursion after 'n' steps" << endl << " (default: do not stop)" << endl << " --atom file: where atom types are defined" << endl << " (default: " << root << "atom_type.txt)" << endl << endl << " Attention: for molecules with lots of atoms, it could be very time-consuming!" << endl << " In that case, you can use './mcs' to get a quasi-MCS instead!" << endl << endl; exit(EXIT_FAILURE); } int rmax = 0; atom_type_file = root + "atom_type.txt"; int ii; for(ii=1; ii<argc; ) { if(strncmp(argv[ii],"--",2) != 0) break; if(strcmp(argv[ii],"--rmax") == 0) rmax = atoi(argv[ii+1]); else if(strcmp(argv[ii],"--atom") == 0) atom_type_file = argv[ii+1]; else { cerr << "Error: invalid option <" << argv[ii] << ">" << endl; exit(EXIT_FAILURE); } ii += 2; } if(argc-ii != 2) { cerr << "Error: invalid number of arguments, need 2 molecule files" << endl; exit(EXIT_FAILURE); } string name1(argv[ii]); string name2(argv[ii+1]); string format1 = name1.substr(name1.rfind(".")+1); string format2 = name2.substr(name2.rfind(".")+1); OBConversion conv; OBMol mol1,mol2; if(!conv.SetInFormat(format1.c_str()) || !conv.ReadFile(&mol1,name1)) { cerr << "Error: failed to read molecule from " << name1 << endl; exit(EXIT_FAILURE); } if(!conv.SetInFormat(format2.c_str()) || !conv.ReadFile(&mol2,name2)) { cerr << "Error: failed to read molecule from " << name2 << endl; exit(EXIT_FAILURE); } vector<pair<vector<int>,vector<int> > > graph_indices = mcs(mol1,mol2,rmax); for(vector<pair<vector<int>,vector<int> > >::iterator i=graph_indices.begin(); i!=graph_indices.end(); ++i) { cout << endl << "atom mapping:" << endl; cout << " g1:"; for(vector<int>::iterator j=(*i).first.begin();j!=(*i).first.end();++j) printf(" %-2d",*j+1); cout << endl << " g2:"; for(vector<int>::iterator j=(*i).second.begin();j!=(*i).second.end();++j) printf(" %-2d",*j+1); cout << endl; } cout << endl << "totally " << graph_indices.size() << " atom mappings for MCS" << endl << endl; return 0; }
int main(int argc, char* argv[]) { // Check the required number of command line arguments. if (argc != 5) { cout << "usr host user pwd jobs_path" << endl; return 0; } // Fetch command line arguments. const auto host = argv[1]; const auto user = argv[2]; const auto pwd = argv[3]; const path jobs_path = argv[4]; // Connect to host and authenticate user. DBClientConnection conn; { cout << local_time() << "Connecting to " << host << " and authenticating " << user << endl; string errmsg; if ((!conn.connect(host, errmsg)) || (!conn.auth("istar", user, pwd, errmsg))) { cerr << local_time() << errmsg << endl; return 1; } } // Initialize constants. cout << local_time() << "Initializing" << endl; const auto collection = "istar.usr"; const auto epoch = date(1970, 1, 1); const size_t num_usrs = 2; constexpr array<size_t, num_usrs> qn{{ 12, 60 }}; constexpr array<double, num_usrs> qv{{ 1.0 / qn[0], 1.0 / qn[1] }}; const size_t num_references = 4; const size_t num_subsets = 5; const array<string, num_subsets> SubsetSMARTS {{ "[!#1]", // heavy "[#6+0!$(*~[#7,#8,F]),SH0+0v2,s+0,S^3,Cl+0,Br+0,I+0]", // hydrophobic "[a]", // aromatic "[$([O,S;H1;v2]-[!$(*=[O,N,P,S])]),$([O,S;H0;v2]),$([O,S;-]),$([N&v3;H1,H2]-[!$(*=[O,N,P,S])]),$([N;v3;H0]),$([n,o,s;+0]),F]", // acceptor "[N!H0v3,N!H0+v4,OH+0,SH+0,nH+0]", // donor }}; // Initialize variables. array<array<double, qn.back()>, 1> qw; array<array<double, qn.back()>, 1> lw; auto q = qw[0]; auto l = lw[0]; // Read ZINC ID file. const string_array<size_t> zincids("16_zincid.txt"); const auto num_ligands = zincids.size(); // Read SMILES file. const string_array<size_t> smileses("16_smiles.txt"); assert(smileses.size() == num_ligands); // Read supplier file. const string_array<size_t> suppliers("16_supplier.txt"); assert(suppliers.size() == num_ligands); // Read property files of floating point types and integer types. const auto zfproperties = read<array<float, 4>>("16_zfprop.f32"); assert(zfproperties.size() == num_ligands); const auto ziproperties = read<array<int16_t, 5>>("16_ziprop.i16"); assert(ziproperties.size() == num_ligands); // Open files for subsequent reading. std::ifstream usrcat_bin("16_usrcat.f64"); stream_array<size_t> ligands("16_ligand.pdbqt"); assert(ligands.size() == num_ligands); array<vector<double>, 2> scores {{ vector<double>(num_ligands, 0), vector<double>(num_ligands, 0) }}; const auto& u0scores = scores[0]; const auto& u1scores = scores[1]; vector<size_t> scase(num_ligands); // Enter event loop. cout << local_time() << "Entering event loop" << endl; bool sleeping = false; while (true) { // Fetch an incompleted job in a first-come-first-served manner. if (!sleeping) cout << local_time() << "Fetching an incompleted job" << endl; BSONObj info; conn.runCommand("istar", BSON("findandmodify" << "usr" << "query" << BSON("done" << BSON("$exists" << false) << "started" << BSON("$exists" << false)) << "sort" << BSON("submitted" << 1) << "update" << BSON("$set" << BSON("started" << Date_t(duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count())))), info); // conn.findAndModify() is available since MongoDB C++ Driver legacy-1.0.0 const auto value = info["value"]; if (value.isNull()) { // No incompleted jobs. Sleep for a while. if (!sleeping) cout << local_time() << "Sleeping" << endl; sleeping = true; this_thread::sleep_for(chrono::seconds(10)); continue; } sleeping = false; const auto job = value.Obj(); // Obtain job properties. const auto _id = job["_id"].OID(); cout << local_time() << "Executing job " << _id.str() << endl; const auto job_path = jobs_path / _id.str(); const auto format = job["format"].String(); const auto email = job["email"].String(); // Parse the user-supplied ligand. OBMol obMol; OBConversion obConversion; obConversion.SetInFormat(format.c_str()); obConversion.ReadFile(&obMol, (job_path / ("ligand." + format)).string()); const auto num_atoms = obMol.NumAtoms(); // obMol.AddHydrogens(); // Adding hydrogens does not seem to affect SMARTS matching. // Classify subset atoms. array<vector<int>, num_subsets> subsets; for (size_t k = 0; k < num_subsets; ++k) { auto& subset = subsets[k]; subset.reserve(num_atoms); OBSmartsPattern smarts; smarts.Init(SubsetSMARTS[k]); smarts.Match(obMol); for (const auto& map : smarts.GetMapList()) { subset.push_back(map.front()); } } const auto& subset0 = subsets.front(); // Check user-provided ligand validity. if (subset0.empty()) { // Record job completion time stamp. const auto millis_since_epoch = duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count(); conn.update(collection, BSON("_id" << _id), BSON("$set" << BSON("done" << Date_t(millis_since_epoch)))); // Send error notification email. cout << local_time() << "Sending an error notification email to " << email << endl; MailMessage message; message.setSender("usr <*****@*****.**>"); message.setSubject("Your usr job has failed"); message.setContent("Description: " + job["description"].String() + "\nSubmitted: " + to_simple_string(ptime(epoch, boost::posix_time::milliseconds(job["submitted"].Date().millis))) + " UTC\nFailed: " + to_simple_string(ptime(epoch, boost::posix_time::milliseconds(millis_since_epoch))) + " UTC\nReason: failed to parse the provided ligand."); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, email)); SMTPClientSession session("137.189.91.190"); session.login(); session.sendMessage(message); session.close(); continue; } // Calculate the four reference points. const auto n = subset0.size(); const auto v = 1.0 / n; array<vector3, num_references> references{}; auto& ctd = references[0]; auto& cst = references[1]; auto& fct = references[2]; auto& ftf = references[3]; for (const auto i : subset0) { ctd += obMol.GetAtom(i)->GetVector(); } ctd *= v; double cst_dist = numeric_limits<double>::max(); double fct_dist = numeric_limits<double>::lowest(); double ftf_dist = numeric_limits<double>::lowest(); for (const auto i : subset0) { const auto& a = obMol.GetAtom(i)->GetVector(); const auto this_dist = a.distSq(ctd); if (this_dist < cst_dist) { cst = a; cst_dist = this_dist; } if (this_dist > fct_dist) { fct = a; fct_dist = this_dist; } } for (const auto i : subset0) { const auto& a = obMol.GetAtom(i)->GetVector(); const auto this_dist = a.distSq(fct); if (this_dist > ftf_dist) { ftf = a; ftf_dist = this_dist; } } // Precalculate the distances between each atom and each reference point. array<vector<double>, num_references> dista; for (size_t k = 0; k < num_references; ++k) { const auto& reference = references[k]; auto& dists = dista[k]; dists.resize(1 + num_atoms); // OpenBabel atom index starts from 1. dists[0] is dummy. for (size_t i = 0; i < n; ++i) { dists[subset0[i]] = sqrt(obMol.GetAtom(subset0[i])->GetVector().distSq(reference)); } } // Calculate USR and USRCAT features of the input ligand. size_t qo = 0; for (const auto& subset : subsets) { const auto n = subset.size(); for (size_t k = 0; k < num_references; ++k) { const auto& distp = dista[k]; vector<double> dists(n); for (size_t i = 0; i < n; ++i) { dists[i] = distp[subset[i]]; } array<double, 3> m{}; if (n > 2) { const auto v = 1.0 / n; for (size_t i = 0; i < n; ++i) { const auto d = dists[i]; m[0] += d; } m[0] *= v; for (size_t i = 0; i < n; ++i) { const auto d = dists[i] - m[0]; m[1] += d * d; } m[1] = sqrt(m[1] * v); for (size_t i = 0; i < n; ++i) { const auto d = dists[i] - m[0]; m[2] += d * d * d; } m[2] = cbrt(m[2] * v); } else if (n == 2) { m[0] = 0.5 * (dists[0] + dists[1]); m[1] = 0.5 * fabs(dists[0] - dists[1]); } else if (n == 1) { m[0] = dists[0]; } #pragma unroll for (const auto e : m) { q[qo++] = e; } } } assert(qo == qn.back()); // Compute USR and USRCAT scores. usrcat_bin.seekg(0); for (size_t k = 0; k < num_ligands; ++k) { usrcat_bin.read(reinterpret_cast<char*>(l.data()), sizeof(l)); double s = 0; #pragma unroll for (size_t i = 0, u = 0; u < num_usrs; ++u) { #pragma unroll for (const auto qnu = qn[u]; i < qnu; ++i) { s += fabs(q[i] - l[i]); } scores[u][k] = s; } } assert(usrcat_bin.tellg() == sizeof(l) * num_ligands); // Sort ligands by USRCAT score and then by USR score and then by ZINC ID. iota(scase.begin(), scase.end(), 0); sort(scase.begin(), scase.end(), [&](const size_t val0, const size_t val1) { const auto u1score0 = u1scores[val0]; const auto u1score1 = u1scores[val1]; if (u1score0 == u1score1) { const auto u0score0 = u0scores[val0]; const auto u0score1 = u0scores[val1]; if (u0score0 == u0score1) { return zincids[val0] < zincids[val1]; } return u0score0 < u0score1; } return u1score0 < u1score1; }); // Write results. filtering_ostream log_csv_gz; log_csv_gz.push(gzip_compressor()); log_csv_gz.push(file_sink((job_path / "log.csv.gz").string())); log_csv_gz.setf(ios::fixed, ios::floatfield); log_csv_gz << "ZINC ID,USR score,USRCAT score\n" << setprecision(8); filtering_ostream ligands_pdbqt_gz; ligands_pdbqt_gz.push(gzip_compressor()); ligands_pdbqt_gz.push(file_sink((job_path / "ligands.pdbqt.gz").string())); ligands_pdbqt_gz.setf(ios::fixed, ios::floatfield); for (size_t t = 0; t < 10000; ++t) { const size_t k = scase[t]; const auto zincid = zincids[k].substr(0, 8); // Take another substr() to get rid of the trailing newline. const auto u0score = 1 / (1 + scores[0][k] * qv[0]); const auto u1score = 1 / (1 + scores[1][k] * qv[1]); log_csv_gz << zincid << ',' << u0score << ',' << u1score << '\n'; // Only write conformations of the top ligands to ligands.pdbqt.gz. if (t >= 1000) continue; const auto zfp = zfproperties[k]; const auto zip = ziproperties[k]; ligands_pdbqt_gz << "MODEL " << '\n' << "REMARK 911 " << zincid << setprecision(3) << ' ' << setw(8) << zfp[0] << ' ' << setw(8) << zfp[1] << ' ' << setw(8) << zfp[2] << ' ' << setw(8) << zfp[3] << ' ' << setw(3) << zip[0] << ' ' << setw(3) << zip[1] << ' ' << setw(3) << zip[2] << ' ' << setw(3) << zip[3] << ' ' << setw(3) << zip[4] << '\n' << "REMARK 912 " << smileses[k] // A newline is already included in smileses[k]. << "REMARK 913 " << suppliers[k] // A newline is already included in suppliers[k]. << setprecision(8) << "REMARK 951 USR SCORE: " << setw(10) << u0score << '\n' << "REMARK 952 USRCAT SCORE: " << setw(10) << u1score << '\n' ; const auto lig = ligands[k]; ligands_pdbqt_gz.write(lig.data(), lig.size()); ligands_pdbqt_gz << "ENDMDL\n"; } // Update progress. cout << local_time() << "Setting done time" << endl; const auto millis_since_epoch = duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count(); conn.update(collection, BSON("_id" << _id), BSON("$set" << BSON("done" << Date_t(millis_since_epoch)))); // Send completion notification email. cout << local_time() << "Sending a completion notification email to " << email << endl; MailMessage message; message.setSender("istar <*****@*****.**>"); message.setSubject("Your usr job has completed"); message.setContent("Description: " + job["description"].String() + "\nSubmitted: " + to_simple_string(ptime(epoch, boost::posix_time::milliseconds(job["submitted"].Date().millis))) + " UTC\nCompleted: " + to_simple_string(ptime(epoch, boost::posix_time::milliseconds(millis_since_epoch))) + " UTC\nResult: http://istar.cse.cuhk.edu.hk/usr/iview/?" + _id.str()); message.addRecipient(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, email)); SMTPClientSession session("137.189.91.190"); session.login(); session.sendMessage(message); session.close(); } }
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; }
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); }
extern "C" int readgrid_(float *vdata, int *nx, int *ny, int *nz, float *x0, float *y0, float *z0, float *xx, float *yy, float *zz, char *file, int fsize) { float dx,dy,dz; int gsize; float v, vmin, vmax, vavg; int navg = 0; OBMol mol; OBConversion conv; conv.SetInFormat("cube"); std::string fname = file; int blank = fname.find(" "); //printf("%d,'%s'\n", blank, fname.substr(0,blank).c_str()); conv.ReadFile(&mol, fname.substr(0,blank).c_str()); //cout << mol.NumAtoms() << " atoms." << endl; if (mol.HasData(OBGenericDataType::GridData)) { std::vector<OBGenericData*> grids = mol.GetAllData(OBGenericDataType::GridData); OBGridData *grid = dynamic_cast<OBGridData *> (grids[0]); gsize = grid->GetNumberOfPoints(); grid->GetNumberOfPoints(*nx, *ny, *nz); vector3 origin = grid->GetOriginVector(); *x0 = origin[0]; *y0 = origin[1]; *z0 = origin[2]; vector3 maxv = grid->GetMaxVector(); *xx = maxv[0]; *yy = maxv[1]; *zz = maxv[2]; dx=(*xx-*x0)/(*nx-1); dy=(*yy-*y0)/(*ny-1); dz=(*zz-*z0)/(*nz-1); printf("%s %d=%d*%d*%d\n", grid->GetAttribute().c_str(), gsize, *nx, *ny, *nz); printf("%f %f\n", grid->GetMinValue(), grid->GetMaxValue()); printf("%f,%f,%f\n", *x0,*y0,*z0); printf("%f,%f,%f\n", *xx,*yy,*zz); printf("%f,%f,%f\n", dx,dy,dz); //vdata = (float *)calloc(gsize, sizeof(float)); /* this is for fortran, so reverse sense of slowest/fastest moving dimensions */ //for (int i=0; i<*nx; ++i) { vmin = grid->GetValue(0,0,0); vmax = vmin; for (int i=0; i<*nz; ++i) { for (int j=0; j<*ny; ++j) { //for (int k=0; k<*nz; ++k) { for (int k=0; k<*nx; ++k) { //*vdata++ = grid->GetValue(i,j,k); v = grid->GetValue(k,j,i); if (v < 1e30 && v > -1e30) { if (v < vmin) vmin = v; if (v > vmax) vmax = v; ++navg; vavg += v; } else { v = vmax * 1000; // just a guess } *vdata++ = v; } } } } vavg = vavg/navg; printf("min/avg/max = %f/%f/%f\n", vmin, vavg, vmax); return 0; }