// Helper function -- handle SMARTS selections // Called by performAction() void SelectExtension::selectSMARTS(GLWidget *widget) { bool ok; QString pattern = QInputDialog::getText(qobject_cast<QWidget*>(parent()), tr("SMARTS Selection"), tr("SMARTS pattern to select"), QLineEdit::Normal, "", &ok); if (ok && !pattern.isEmpty()) { OBSmartsPattern smarts; smarts.Init(pattern.toStdString()); OpenBabel::OBMol obmol = m_molecule->OBMol(); smarts.Match(obmol); // if we have matches, select them if(smarts.NumMatches() != 0) { QList<Primitive *> matchedAtoms; vector< vector <int> > mapList = smarts.GetUMapList(); vector< vector <int> >::iterator i; // a set of matching atoms vector<int>::iterator j; // atom ids in each match for (i = mapList.begin(); i != mapList.end(); ++i) { for (j = i->begin(); j != i->end(); ++j) { matchedAtoms.append(m_molecule->atom(obmol.GetAtom(*j)->GetIdx()-1)); } } widget->clearSelected(); widget->setSelected(matchedAtoms, true); widget->update(); } // end matches } return; }
int main() { OBAtom a, b, c; a.SetAtomicNum(8); b.SetAtomicNum(6); c.SetAtomicNum(8); OBMol mol; mol.AddAtom(a); mol.AddAtom(b); mol.AddAtom(c); mol.AddBond(1,2,2); mol.AddBond(2,3,2); OBConversion conv; conv.SetOutFormat("SMI"); cout << conv.WriteString(&mol,1) << endl; OBSmartsPattern sp; sp.Init ("C~*"); sp.Match (mol,false); cout << sp.NumMatches() << endl; cout << sp.GetUMapList().size() << endl; return EXIT_SUCCESS; }
double Predict(OBBase* pOb, string* param=NULL) { OBMol* pmol = dynamic_cast<OBMol*> (pOb); if(!pmol) return 0; OBSmartsPattern sp; if (sp.Init(_smarts) && sp.Match(*pmol)) return sp.GetUMapList().size(); else return 0.0; }
bool GetFingerprint(OBBase* pOb, vector<unsigned int>&fp, int nbits) { OBMol* pmol = dynamic_cast<OBMol*>(pOb); unsigned int o=0; unsigned int m=0; unsigned int i=0; unsigned int n=0; if(!pmol) return false; //Read patterns file if it has not been done already if(smartsStrings.empty()) ReadPatternFile(_patternsfile, smartsStrings); //Make fp size the smallest power of two to contain the patterns //unsigned int n=Getbitsperint(); //while(n<smartsStrings.size())n*=2; //fp.resize(n/Getbitsperint()); fp.resize(16); for(n=0;n<smartsStrings.size();++n) { OBSmartsPattern sp; sp.Init(smartsStrings[n]); if(sp.Match(*pmol)) { m=sp.GetUMapList().size(); //m=sp.NumMatches(); o=n*8; for(i=0;i<8;++i) { if(i<m) {SetBit(fp, o+i); //cout << "1"; } //cout << endl; } } } if(nbits) Fold(fp, nbits); return true; };
/////////////////////////////////////////////////////////////////////////////// //! \brief Find the molecule(s) with or without a given SMART pattern int main(int argc,char **argv) { char c; unsigned int ntimes=0; // number of times SMARTS matches in a molecule unsigned int numMatching = 0; // number of matching molecules (for -c flag) bool pattern_matched=false, ntimes_matched=true; bool count=false, invert=false, full=false, name_only=false; char *FileIn = NULL, *Pattern = NULL; char *program_name = argv[0]; char *iext; bool useInFile = true; OBConversion conv(&cin,&cout); OBFormat *pFormat = conv.FindFormat("smi"); // default format is SMILES // Parse options while ((c = getopt(argc, argv, "t:nvcfi:-")) != -1) { #ifdef _WIN32 char optopt = c; #endif switch (c) { case 't': // request ntimes unique matches c = sscanf(optarg, "%d", &ntimes); if (c != 1 ) { cerr << program_name << ": unable to parse -t option" << endl; exit (-1); } break; case 'i': iext = optarg; //The ID provided by the OBFormat class is used as // the identifying file extension. This is a slight // reduction in flexibility (which is not currently used) pFormat = conv.FindFormat(iext); if(pFormat==NULL) { cerr << program_name << ": cannot read input format!" << endl; exit(-1); } break; case 'n': // print the molecule name only name_only = true; break; case 'c': // count the number of match count = true; break; case 'v': // match only the molecules without the pattern invert = true; break; case 'f': full = true; break; case '-': useInFile = false; break; case '?': if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return 1; } } int index = optind; if (argc-index != 2 && argc-index != 1) { string err = "Usage: "; err += program_name; err += " [options] \"PATTERN\" <filename>\n"; err += "If no filename is supplied, then obgrep will use stdin instead.\n"; err += "Options:\n"; err += " -v Invert the matching, print non-matching molecules\n"; err += " -c Print the number of matched molecules\n"; err += " -i <format> Specify the input and output format\n"; err += " -f Full match, print matching-molecules when the number\n"; err += " of heavy atoms is equal to the number of PATTERN atoms\n"; err += " -n Only print the name of the molecules\n"; err += " -t NUM Print a molecule only if the PATTERN occurs NUM times inside the molecule\n"; cerr << err << ends; exit(-1); } else { Pattern = argv[index++]; if (argc - index == 1) FileIn = argv[index]; } ifstream ifs; if (useInFile && FileIn != NULL) { // Read the file ifs.open(FileIn); if (!ifs) { cerr << program_name << ": cannot read input file!" << endl; exit (-1); } conv.SetInStream(&ifs); // Find Input filetype if (pFormat == NULL) { pFormat = conv.FormatFromExt(FileIn); if (pFormat == NULL) { cerr << program_name << ": cannot read input format!" << endl; return (-1); } } } if (! conv.SetInAndOutFormats(pFormat, pFormat)) { cerr << program_name << ": cannot read or write to this file format" << endl; return (-1); } // Match the SMART OBSmartsPattern sp; vector< vector <int> > maplist; // list of matched atoms sp.Init(Pattern); OBMol mol; bool impossible_match; // Search for pattern for (c=0;;) { mol.Clear(); conv.Read(&mol); if (mol.Empty()) break; //////////////////////////////////////////////////////////////// // Do not loose time trying to match the pattern if the matching // is impossible. // It is impossible to make a full match if the number of atoms is // different if (full ) impossible_match = (sp.NumAtoms() == mol.NumHvyAtoms()) ? false : true; else impossible_match = false; if (impossible_match) { // -> avoid useless SMART matching attempt if (invert) { if (!count) { if ( name_only ) cout << mol.GetTitle() << endl; else conv.Write(&mol, &cout); } numMatching++; } continue; } //////////////////////////////////////////////////////////////// // perform SMART matching pattern_matched = sp.Match(mol); // the number of times the match occured may matter if ( ntimes ) { // ntimes is a positive integer of requested matches // Here, a match mean a unique match (same set of atoms) // so we need to get the unique match list size maplist = sp.GetUMapList(); if( maplist.size() == ntimes ) ntimes_matched = true; else ntimes_matched = false; } else { // ntimes == 0, we don't care about the number of matches ntimes_matched = true; } //////////////////////////////////////////////////////////////// // perform a set of tests to guess what to print out if ( pattern_matched == true && ntimes_matched == true) { if (!invert) { // do something only when invert flag is off if (!count) { if ( name_only ) cout << mol.GetTitle() << endl; else conv.Write(&mol, &cout); } numMatching++; } } else { // The SMART pattern do not occur as many times as requested if (invert) { // do something only if invert flag is on if (!count) { if ( name_only ) cout << mol.GetTitle() << endl; else conv.Write(&mol, &cout); } numMatching++; } } } // end for loop //////////////////////////////////////////////////////////////// // Only print the number of matched molecules as requested if (count) { cout << numMatching << endl; } return(1); }
/////////////////////////////////////////////////////////////////////////////// //! \brief Set a tortional bond to a given angle int main(int argc,char **argv) { const char *Pattern=NULL; unsigned int i, t, errflg = 0; int c; char flags[255]; string err; bool graphOutput=false; // parse the command line -- optional -a flag to change all matching torsions if (argc < 3 || argc > 4) { errflg++; } else { FileIn = argv[1]; Pattern = "[!$(*#*)&!D1]-!@[!$(*#*)&!D1]"; // Read the atom position c = sscanf(argv[2], "%d", &angleSum); angle = 360./angleSum; if (argc == 4) { c = sscanf(argv[3], "%s", flags); int flagid=1; while (flags[flagid]!=0) switch (flags[flagid++]) { case 'g': graphOutput=true; case 'e': forceField=OBForceField::FindForceField("MMFF94"); isEnergyCalcing=true; break; } } } if (errflg) { cerr << "Usage: rkrotate <filename> <angle> [options]" << endl; exit(-1); } // create pattern OBSmartsPattern sp; sp.Init(Pattern); OBFormat* format = conv.FormatFromExt(FileIn); if(!(format && conv.SetInAndOutFormats(format, format))) { //in and out formats same cerr << "obrotate: cannot read and/or write this file format!" << endl; exit (-1); } //...NF //Open the molecule file ifstream ifs; // Read the file ifs.open(FileIn); if (!ifs) { cerr << "obrotate: cannot read input file!" << endl; exit (-1); } OBMol mol; vector< vector <int> > maplist; // list of matched atoms // vector< vector <int> >::iterator m; // and its iterators // int tindex; // Set the angles for (;;) { mol.Clear(); //NF ifs >> mol; // Read molecule conv.Read(&mol,&ifs); //NF if (mol.Empty()) break; if (sp.Match(mol)) { // if match perform rotation maplist = sp.GetUMapList(); // get unique matches if (maplist.size() > 1) cerr << "obrotate: Found " << maplist.size() << " matches." << endl; energySheet=new MultiVector<double>(degrees=maplist.size(),angleSum); indexSheet=new int[maplist.size()]; for (int EXO=0;EXO<maplist.size();++EXO) totalSum*=angleSum+EXO; // look at all the mapping atom but save only the last one. turnMol(mol,maplist,maplist.size()-1); if (graphOutput) { ofstream ofs("energyGraph.mlog"); int ind[degrees]; for (int i=0;i<degrees;++i) ind[i]=0; do { for (int i=0;i<degrees;++i) ofs<<ind[i]<<'\t'; ofs<<energySheet->getVectorValue(ind)<<endl; } while(energySheet->incressIndex(ind)); } if (isEnergyCalcing) { std::vector<int*> lowEnergySheet; totalSum=energySheet->getMinValues(lowEnergySheet); if (totalSum) outputMol(lowEnergySheet,mol,maplist,maplist.size()-1); else cerr << "rkrotate: No low energy conformation found." << endl; } cout << sum; } else { cerr << "obrotate: Found 0 matches for the SMARTS pattern." << endl; exit(-1); } //NF cout << mol; } return(0); }
void OBBondTyper::AssignFunctionalGroupBonds(OBMol &mol) { if (!_init) Init(); OBSmartsPattern *currentPattern; OBBond *b1, *b2; OBAtom *a1,*a2, *a3; double angle, dist1, dist2; vector<int> assignments; vector<vector<int> > mlist; vector<vector<int> >::iterator matches, l; vector<pair<OBSmartsPattern*, vector<int> > >::iterator i; unsigned int j; // Loop through for all the functional groups and assign bond orders for (i = _fgbonds.begin();i != _fgbonds.end();++i) { currentPattern = i->first; assignments = i->second; if (currentPattern && currentPattern->Match(mol)) { mlist = currentPattern->GetUMapList(); for (matches = mlist.begin(); matches != mlist.end(); ++matches) { // Now loop through the bonds to assign from _fgbonds for (j = 0; j < assignments.size(); j += 3) { // along the assignments vector: atomID1 atomID2 bondOrder a1 = mol.GetAtom((*matches)[ assignments[j] ]); a2 = mol.GetAtom((*matches)[ assignments[j+1 ] ]); if (!a1 || !a2) continue; b1 = a1->GetBond(a2); if (!b1) continue; b1->SetBO(assignments[j+2]); } // bond order assignments } // each match } // current pattern matches } // for(functional groups) // FG with distance and/or bond criteria // Carbonyl oxygen C=O OBSmartsPattern carbo; carbo.Init("[#8D1][#6](*)(*)"); if (carbo.Match(mol)) { mlist = carbo.GetUMapList(); for (l = mlist.begin(); l != mlist.end(); ++l) { a1 = mol.GetAtom((*l)[0]); a2 = mol.GetAtom((*l)[1]); angle = a2->AverageBondAngle(); dist1 = a1->GetDistance(a2); // carbonyl geometries ? if (angle > 115 && angle < 150 && dist1 < 1.28) { if ( !a1->HasDoubleBond() ) {// no double bond already assigned b1 = a1->GetBond(a2); if (!b1 ) continue; b1->SetBO(2); } } } } // Carbonyl oxygen // thione C=S OBSmartsPattern thione; thione.Init("[#16D1][#6](*)(*)"); if (thione.Match(mol)) { mlist = thione.GetUMapList(); for (l = mlist.begin(); l != mlist.end(); ++l) { a1 = mol.GetAtom((*l)[0]); a2 = mol.GetAtom((*l)[1]); angle = a2->AverageBondAngle(); dist1 = a1->GetDistance(a2); // thione geometries ? if (angle > 115 && angle < 150 && dist1 < 1.72) { if ( !a1->HasDoubleBond() ) {// no double bond already assigned b1 = a1->GetBond(a2); if (!b1 ) continue; b1->SetBO(2); } } } } // thione // Isocyanate N=C=O or Isothiocyanate bool dist1OK; OBSmartsPattern isocyanate; isocyanate.Init("[#8,#16;D1][#6D2][#7D2]"); if (isocyanate.Match(mol)) { mlist = isocyanate.GetUMapList(); for (l = mlist.begin(); l != mlist.end(); ++l) { a1 = mol.GetAtom((*l)[0]); a2 = mol.GetAtom((*l)[1]); a3 = mol.GetAtom((*l)[2]); angle = a2->AverageBondAngle(); dist1 = a1->GetDistance(a2); dist2 = a2->GetDistance(a3); // isocyanate geometry or Isotiocyanate geometry ? if (a1->IsOxygen()) dist1OK = dist1 < 1.28; else dist1OK = dist1 < 1.72; if (angle > 150 && dist1OK && dist2 < 1.34) { b1 = a1->GetBond(a2); b2 = a2->GetBond(a3); if (!b1 || !b2) continue; b1->SetBO(2); b2->SetBO(2); } } } // Isocyanate // oxime C=S OBSmartsPattern oxime; oxime.Init("[#6D3][#7D2][#8D2]"); if (oxime.Match(mol)) { mlist = oxime.GetUMapList(); for (l = mlist.begin(); l != mlist.end(); ++l) { a1 = mol.GetAtom((*l)[0]); a2 = mol.GetAtom((*l)[1]); angle = a2->AverageBondAngle(); dist1 = a1->GetDistance(a2); // thione geometries ? if (angle > 110 && angle < 150 && dist1 < 1.4) { if ( !a1->HasDoubleBond() ) {// no double bond already assigned b1 = a1->GetBond(a2); if (!b1 ) continue; b1->SetBO(2); } } } } // oxime }