// 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;
  }
示例#2
0
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;
    }
示例#4
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;
  };
示例#5
0
///////////////////////////////////////////////////////////////////////////////
//! \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);
}
示例#6
0
///////////////////////////////////////////////////////////////////////////////
//! \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

  }