Beispiel #1
0
  Molecule * OpenbabelWrapper::openFile(const QString &fileName,
                                        const QString &fileType,
                                        const QString &fileOptions)
  {
    // Check that the file can be read from disk
    if (!canOpen(fileName, QFile::ReadOnly | QFile::Text))
      return 0;

    // Construct the OpenBabel objects, set the file type
    OBConversion conv;
    OBFormat *inFormat;
    if (!fileType.isEmpty() && !conv.SetInFormat(fileType.toAscii().data()))
      // Input format not supported
      return 0;
    else {
      inFormat = conv.FormatFromExt(fileName.toAscii().data());
      if (!conv.SetInFormat(inFormat))
        // Input format not supported
        return 0;
    }

    // set any options
    if (!fileOptions.isEmpty()) {
      foreach(const QString &option,
              fileOptions.split('\n', QString::SkipEmptyParts)) {
        conv.AddOption(option.toAscii().data(), OBConversion::INOPTIONS);
      }
    }
// Helper function to read molecule from file
shared_ptr<OBMol> GetMol(const std::string &filename)
{
  // Create the OBMol object.
  shared_ptr<OBMol> mol(new OBMol);

  // Create the OBConversion object.
  OBConversion conv;
  OBFormat *format = conv.FormatFromExt(filename.c_str());
  if (!format || !conv.SetInFormat(format)) {
    std::cout << "Could not find input format for file " << filename << std::endl;
    return mol;
  }

  // Open the file.
  std::ifstream ifs(filename.c_str());
  if (!ifs) {
    std::cout << "Could not open " << filename << " for reading." << std::endl;
    return mol;
  }
  // Read the molecule.
  if (!conv.Read(mol.get(), &ifs)) {
    std::cout << "Could not read molecule from file " << filename << std::endl;
    return mol;
  }

  return mol;
}
Beispiel #3
0
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 InputFileExtension::readOutputFile(const QString filename)
  {
    QApplication::setOverrideCursor(Qt::WaitCursor);
    OBConversion conv;
    OBFormat     *inFormat = conv.FormatFromExt( filename.toAscii() );
    if ( !inFormat || !conv.SetInFormat( inFormat ) ) {
      QApplication::restoreOverrideCursor();
      QMessageBox::warning(m_widget, tr("Avogadro"),
        tr("Cannot read file format of file %1.").arg(filename));
      return;
    }

    // TODO: Switch to MoleculeFile
    ifstream ifs;
    ifs.open(QFile::encodeName(filename));
    if (!ifs) { // shouldn't happen, already checked file above
      QApplication::restoreOverrideCursor();
      QMessageBox::warning(m_widget, tr("Avogadro"),
        tr("Cannot read file %1.").arg( filename ) );
      return;
    }

    OBMol *obmol = new OBMol;
    if (conv.Read(obmol, &ifs)) {
      Molecule *mol = new Molecule;
      mol->setOBMol(obmol);
      mol->setFileName(filename);
      emit moleculeChanged(mol, Extension::DeleteOld);
      m_molecule = mol;
    }

    QApplication::restoreOverrideCursor();
  }
Beispiel #5
0
int main(int argc,char **argv)
{
  char *program_name= argv[0];
  int c;
  char *FileIn = NULL;

  if (argc != 2) {
    cerr << " Usage: " << program_name << " <input file>\n";
    exit(-1);
  }
  else {
      FileIn  = argv[1];
  }

  // Find Input filetype
  OBConversion conv;
  OBFormat *inFormat = conv.FormatFromExt(FileIn);
    
  if (!inFormat || !conv.SetInFormat(inFormat)) {
    cerr << program_name << ": cannot read input format!" << endl;
    exit (-1);
  }

  ifstream ifs;

  // Read the file
  ifs.open(FileIn);
  if (!ifs) {
    cerr << program_name << ": cannot read input file!" << endl;
    exit (-1);
  }

  OBMol mol;
  OBPointGroup pg;

  for (c = 1;; ++c)
    {
      mol.Clear();
      conv.Read(&mol, &ifs);
      if (mol.Empty())
        break;
      
      // not needed by OBPointGroup, but useful for external programs
      mol.Center();
      mol.ToInertialFrame();

      pg.Setup(&mol);
      cout << "Point Group: " << pg.IdentifyPointGroup() << endl;

    } // end for loop
  
  return(1);
}
Beispiel #6
0
int main(int argc, char **argv)
{
  OBFunctionFactory *factory = OBFunctionFactory::GetFactory("MMFF94");
  OBFunction *function = factory->NewInstance();
  if (!function) {
    cout << "ERROR: could not find MMFF94 function" << endl;
    return -1;
  }

  if (argc < 2) {
    cout << "Usage: " << argv[0] << " <filename>" << endl;
    return -1;    
  }

  OBMol mol;
  OBConversion conv;
  OBFormat *format = conv.FormatFromExt(argv[1]);
  if (!format || !conv.SetInFormat(format)) {
    cout << "ERROR: could not find format for file " << argv[1] << endl;
    return -1;
  }

  std::ifstream ifs;
  ifs.open(argv[1]);
  conv.Read(&mol, &ifs);
  ifs.close();

  cout << "# atoms = " << mol.NumAtoms() << endl;
  function->GetLogFile()->SetOutputStream(&std::cout);
  function->GetLogFile()->SetLogLevel(OBLogFile::Low);

  // read options file
  if (argc == 3) {
    std::ifstream cifs;
    cifs.open(argv[2]);
    std::stringstream options;
    std::string line;
    while (std::getline(cifs, line))
      options << line << std::endl;

    function->SetOptions(options.str());
  }


  function->Setup(mol);

  OBMinimize minimize(function);

  minimize.SteepestDescent(50);


}
Beispiel #7
0
int main(int argc, char **argv)
{
  if (argc < 2) {
    std::cerr << "Usage: " << argv[0] << " filename" << std::endl;
    return -1;
  }

  // read a molecule
  OBConversion conv;
  OBFormat *format = conv.FormatFromExt(argv[1]);
  conv.SetInFormat(format);

  std::string filename(argv[1]);
  std::ifstream ifs;
  ifs.open(filename.c_str());
  if (!ifs) {
    std::cerr << "Could not open " << filename << std::endl;
    return -1;
  }

  CairoPainter *painter = new CairoPainter;
  OBDepict depictor(painter);
 
  string::size_type pos = filename.find_last_of(".");
  if (pos != string::npos)
    filename = filename.substr(0, pos);

  OBMol mol;
  unsigned int count = 1;
  while (conv.Read(&mol, &ifs)) {
    // depict the molecule
    depictor.DrawMolecule(&mol);
    depictor.AddAtomLabels(OBDepict::AtomSymmetryClass);
    
    std::stringstream ss;
    ss << filename << count << ".png";
    painter->WriteImage(ss.str());

    count++;
  }

  return 0;
}
Beispiel #8
0
bool verifyLSSR(const std::string &filename, const LSSR &ref)
{
  cout << "Verify LSSR: " << filename << endl;
  std::string file = OBTestUtil::GetFilename(filename);
  // read a smiles string
  OBMol mol;
  OBConversion conv;
  OBFormat *format = conv.FormatFromExt(file.c_str());
  OB_REQUIRE( format );
  OB_REQUIRE( conv.SetInFormat(format) );

  std::ifstream ifs;
  ifs.open(file.c_str());
  OB_REQUIRE( ifs );
  OB_REQUIRE( conv.Read(&mol, &ifs) );

  std::vector<int> ringSizeCount(20, 0); 
  std::vector<OBRing*> lssr = mol.GetLSSR();

  for (unsigned int i = 0; i < lssr.size(); ++i) {
    ringSizeCount[lssr[i]->_path.size()]++;
  }

  /*
  cout << "ringSize: ringCount" << endl;
  cout << "3: " << ringSizeCount[3] << endl;
  cout << "4: " << ringSizeCount[4] << endl;
  cout << "5: " << ringSizeCount[5] << endl;
  cout << "6: " << ringSizeCount[6] << endl;
  */

  bool fail = false;
  for (unsigned int i = 0; i < ref.size_count.size(); ++i) {
    const LSSR::Size_Count &size_count = ref.size_count[i];
    OB_ASSERT( ringSizeCount[size_count.ringSize] == size_count.ringCount );
  }

  return true;
}
Beispiel #9
0
bool doShuffleTestMultiFile(const std::string &filename)
{
  cout << "Shuffling: " << filename << endl;
  std::string file = OBTestUtil::GetFilename(filename);
  // read a smiles string
  OBMol mol;
  OBConversion conv;
  OBFormat *format = conv.FormatFromExt(file.c_str());
  OB_REQUIRE( format );
  OB_REQUIRE( conv.SetInFormat(format) );

  std::ifstream ifs;
  ifs.open(file.c_str());
  OB_REQUIRE( ifs );
 
  bool result = true;
  while (conv.Read(&mol, &ifs)) {
    bool res = doShuffleTestMolecule(mol);
    if (!res)
      result = res;
  }

  return result;
}
Beispiel #10
0
int main(int argc,char **argv)
{
  char *program_name= argv[0];
  int c;
  int verbose = 0;
  bool hydrogens = false;
  string basename, filename = "", option, option2, ff = "";
  OBConversion conv;

  if (argc < 2) {
    cout << "Usage: obenergy [options] <filename>" << endl << endl;
    cout << "options:      description:" << endl << endl;
    cout << "  -v          verbose: print out indivual energy interactions" << endl << endl;
    cout << "  -h          add hydrogens before calculating energy" << endl << endl;
    cout << "  -ff ffid    select a forcefield" << endl << endl;
    cout << "              available forcefields:" << endl << endl;
    OBPlugin::List("forcefields", "verbose");
    exit(-1);
  } else {
    int ifile = 1;
    for (int i = 1; i < argc; i++) {
      option = argv[i];
      
      if (option == "-v") {
        verbose = 1;
        ifile++;
        break;
      }

      if (option == "-h") {
        hydrogens = true;
        ifile++;
      }

      if ((option == "-ff") && (argc > (i+1))) {
        ff = argv[i+1];
        ifile += 2;
      }
    }
    
    basename = filename = argv[ifile];
    size_t extPos = filename.rfind('.');
    size_t startPos = 0;

    if (extPos!= string::npos) {
      basename = filename.substr(startPos, extPos);
    }


  }


  // Find Input filetype
  OBFormat *format_in = conv.FormatFromExt(filename.c_str());
    
  if (!format_in || !conv.SetInFormat(format_in)) {
    cerr << program_name << ": cannot read input format!" << endl;
    exit (-1);
  }

  ifstream ifs;
  ofstream ofs;

  // Read the file
  ifs.open(filename.c_str());
  if (!ifs) {
    cerr << program_name << ": cannot read input file!" << endl;
    exit (-1);
  }

  OBForceField* pFF = OBForceField::FindForceField(ff);
  if (!pFF) {
    cerr << program_name << ": could not find forcefield '" << ff << "'." <<endl;
    exit (-1);
  }
  pFF->SetLogFile(&cout);
  pFF->SetLogLevel(OBFF_LOGLVL_NONE);
//  if (verbose)
//    pFF->SetLogLevel(OBFF_LOGLVL_HIGH);
//  else
//    pFF->SetLogLevel(OBFF_LOGLVL_MEDIUM);

  Timer totalTimer, readTimer, setupTimer, computeTimer;
  double totalTime, readTime, setupTime, computeTime;
  int nthreads = 1; // single core is just one thread
  unsigned int totalSteps = 1; // total steps is only used when doing minimization


	#ifdef _OPENMP // START OPENMP DEBUG
	#pragma omp parallel default(none) shared(nthreads)
	{
	  nthreads = omp_get_num_threads(); // determine the number of threads
	} // parallel region completes
	#endif // END OPENMP DEBUG

	// This code only deals with creating a file to store the timings for
	// the execution of the program along with other interesting statistics
	char cwd[1024]; // a reasonably large current working directory (cwd)
	char filepath[1100]; // a reasonably large file name plus cwd
	const char * statsfile = "obenergy_runstats";
	std::ofstream output;
	if (getcwd(cwd, sizeof (cwd)) != NULL) {
		std::cout << "Current working dir: " << cwd << std::endl;
	} else {
		std::cout << "The getcwd() method failed. Aborting." << std::endl;
		exit(1);
	}//if(getcwd()

	sprintf(filepath, "%s/%s_%s_t%d.mat", cwd, statsfile, ff.c_str(), nthreads);
	std::cout << "Writing output file to: " << filepath << std::endl;
	output.open(filepath, ios::out | ios::app ); // The file is open in append mode

	//              1     2       3        4        5          6          7        8         9          10        11    12
	output << "#METHOD: " << ff << " DATASET: " << filename.c_str() << std::endl;
	output << "#THREADS ENERGY MOL_MASS NUM_ATOMS NUM_ROTORS NUM_CONF TOT_TIME TIME_READ TIME_SETUP TIME_COMPUTE STEPS #MOL_NAME " << std::endl;

	// A second file is created to store information on the timings of specific parts
	// from the MMFF94 calculation routines. breakdown of time spent in calculations
	char filepath2[1100];
	std::ofstream output2;
	sprintf(filepath2, "%s/%s_%s_t%d_compute.mat", cwd, statsfile, ff.c_str(), nthreads);
	std::cout << "Writing method breakdown detail file to: " << filepath2 << std::endl;
	output2.open(filepath2, ios::out | ios::app ); // The file is open in append mode

  //           1      2       3        4         5     6     7      8       9         10         11      12
  output2 << "#METHOD: " << ff << " THREADS: " << nthreads << " DATASET: " << filename.c_str() << std::endl;
  output2 << "#E_BOND E_ANGLE E_STRBND E_TORSION E_OOP E_VDW E_ELEC N_ATOMS PAIRS_VDW PAIRS_ELEC MEM_VDW MEM_ELEC " << std::endl;

	// A third file is created to store information on the memory allocation of data structures
	// from the MMFF94 calculation routines. breakdown of memory allocated for each calculation type
	char filepath3[1100];
	std::ofstream output3;
	sprintf(filepath3, "%s/%s_%s_t%d_malloc.mat", cwd, statsfile, ff.c_str(), nthreads);
	std::cout << "Writing memory allocation breakdown detail file to: " << filepath3 << std::endl;
	output3.open(filepath3, ios::out | ios::app ); // The file is open in append mode

	//           1     2      3       4        5         6     7     8      9      10      11       12        13    14    15
	output3 << "#METHOD: " << ff << " THREADS: " << nthreads << " DATASET: " << filename.c_str() << std::endl;
	output3 << "#ATOMS M_BOND M_ANGLE M_STRBND M_TORSION M_OOP M_VDW M_ELEC C_BOND C_ANGLE C_STRBND C_TORSION C_OOP C_VDW C_ELEC" << std::endl;

  double bondCalcTime, angleCalcTime, strbndCalcTime, torsionCalcTime, oopCalcTime, vdwCalcTime, electrostaticCalcTime;
  int numPairsVDW, numPairsElectrostatic;

  OBMol mol;
  double energy;
  for (c=1;;c++) {
    mol.Clear();

    totalTimer.start();
    readTimer.start();

    if (!conv.Read(&mol, &ifs))
      break;
    if (mol.Empty())
      break;

    if (hydrogens)
      mol.AddHydrogens();
       
    readTime = readTimer.get();
    setupTimer.start();


    if (!pFF->Setup(mol)) {
      cerr << program_name << ": could not setup force field." << endl;
      exit (-1);
    }

    setupTime = setupTimer.get();
    computeTimer.start();
    
    energy = pFF->Energy(false);

    computeTime = computeTimer.get();
    totalTime = totalTimer.get();

    // THREADS  ENERGY  MOL_MASS  NUM_ATOMS  NUM_ROTORS  NUM_CONF  TOT_TIME  TIME_READ  TIME_SETUP  TIME_COMPUTE STEPS  #MOL_NAME
    output << nthreads << " " << energy << " " << mol.GetExactMass() << " " << mol.NumAtoms()
    		<< " " << mol.NumRotors() << "  " <<  mol.NumConformers() << " "
    		<< totalTime <<  " " << readTime << " " << " " << setupTime << " " << computeTime << " "
    		<< totalSteps << " #" << mol.GetTitle()  // comment added to avoid errors when reading matrix in Octave
    		<< std::endl;

    map<string, double> timings = pFF->getTimings();
    map<string, size_t> memalloc = pFF->getAllocatedMemory();
    MapKeys mk;
    // 1      2       3        4         5     6     7      8       9         10         11      12
    // E_BOND E_ANGLE E_STRBND E_TORSION E_OOP E_VDW E_ELEC N_ATOMS PAIRS_VDW PAIRS_ELEC MEM_VDW MEM_ELEC
    output2 << timings[mk.TIME_BOND_CALCULATIONS] << " "  // 1
    		<< timings[mk.TIME_ANGLE_CALCULATIONS] << " " // 2
    		<< timings[mk.TIME_STRBND_CALCULATIONS] << " " // 3
    		<< timings[mk.TIME_TORSION_CALCULATIONS] << " " // 4
    		<< timings[mk.TIME_OOP_CALCULATIONS] << " " // 5
    		<< timings[mk.TIME_VDW_CALCULATIONS] << " " // 6
    		<< timings[mk.TIME_ELECTROSTATIC_CALCULATIONS] << " " // 7
    		<< mol.NumAtoms() << " " // 8
    		<< timings[mk.TOTAL_VDW_CALCULATIONS] << " " // 9
    		<< timings[mk.TOTAL_ELECTROSTATIC_CALCULATIONS] << " " // 10
    		<< memalloc[mk.MEM_VDW_CALCULATIONS] << " " // 11
    		<< memalloc[mk.MEM_ELECTROSTATIC_CALCULATIONS] << std::endl; // 12

	// 1     2      3       4        5         6     7     8      9      10      11       12        13    14    15
    // ATOMS M_BOND M_ANGLE M_STRBND M_TORSION M_OOP M_VDW M_ELEC C_BOND C_ANGLE C_STRBND C_TORSION C_OOP C_VDW C_ELEC
    output3 << mol.NumAtoms() << " " // 1
    		<< memalloc[mk.MEM_BOND_CALCULATIONS] << " " // 2
    		<< memalloc[mk.MEM_ANGLE_CALCULATIONS] << " " // 3
    		<< memalloc[mk.MEM_STRBND_CALCULATIONS] << " " // 4
    		<< memalloc[mk.MEM_TORSION_CALCULATIONS] << " " // 5
    		<< memalloc[mk.MEM_OOP_CALCULATIONS] << " " // 6
    		<< memalloc[mk.MEM_VDW_CALCULATIONS] << " " // 7
    		<< memalloc[mk.MEM_ELECTROSTATIC_CALCULATIONS] << " " // 8
    		<< timings[mk.TOTAL_BOND_CALCULATIONS] << " " // 9
    		<< timings[mk.TOTAL_ANGLE_CALCULATIONS] << " " // 10
    		<< timings[mk.TOTAL_STRBND_CALCULATIONS] << " " // 11
    		<< timings[mk.TOTAL_TORSION_CALCULATIONS] << " " // 12
    		<< timings[mk.TOTAL_OOP_CALCULATIONS] << " " // 13
    		<< timings[mk.TOTAL_VDW_CALCULATIONS] << " " // 14
    		<< timings[mk.TOTAL_ELECTROSTATIC_CALCULATIONS] << " " // 15
    		<< std::endl;

    if (!isfinite(energy)) {
      cerr << " Title: " << mol.GetTitle() << endl;
      FOR_ATOMS_OF_MOL(atom, mol) {
        cerr << " x: " << atom->x() << " y: " << atom->y() << " z: " << atom->z() << endl;
      }
    }

  } // end for loop
Beispiel #11
0
int main(int argc, char **argv)
{
  if (argc < 3) {
    std::cerr << "Usage: " << argv[0] << " <molecule_file> <output_score_file>" << std::endl;
    return 1;
  }

  unsigned long numAtoms = 0;
  unsigned long numAromaticAtoms = 0;
  unsigned long numCyclicAtoms = 0;
  std::map<int, unsigned long> mass;
  std::map<int, unsigned long> elem;
  std::map<int, unsigned long> aromelem;
  std::map<int, unsigned long> aliphelem;
  std::map<int, unsigned long> hcount;
  std::map<int, unsigned long> charge;
  std::map<int, unsigned long> connect;
  std::map<int, unsigned long> degree;
  std::map<int, unsigned long> implicit;
  std::map<int, unsigned long> rings;
  std::map<int, unsigned long> size;
  std::map<int, unsigned long> valence;
  std::map<int, unsigned long> chiral;
  std::map<int, unsigned long> hyb;
  std::map<int, unsigned long> ringconnect;

  unsigned long numBonds = 0;
  unsigned long numSingleBonds = 0;
  unsigned long numDoubleBonds = 0;
  unsigned long numTripleBonds = 0;
  unsigned long numAromaticBonds = 0;
  unsigned long numRingBonds = 0;

  OBConversion conv;
  conv.SetInFormat(conv.FormatFromExt(argv[1]));
  std::ifstream ifs(argv[1]);
  conv.SetInStream(&ifs);

  OBMol mol;
  unsigned long molecule = 0;
  while (conv.Read(&mol)) {
    ++molecule;
    //if ((molecule % 1000) == 0)
    //  std::cout << molecule << std::endl;

    FOR_ATOMS_OF_MOL (atom, mol) {
      numAtoms++;
      if (atom->IsAromatic()) {
        numAromaticAtoms++;
        aromelem[atom->GetAtomicNum()]++;
      } else
        aliphelem[atom->GetAtomicNum()]++;
      if (atom->IsInRing())
        numCyclicAtoms++;
      mass[atom->GetIsotope()]++;
      elem[atom->GetAtomicNum()]++;
      hcount[atom->ExplicitHydrogenCount() + atom->ImplicitHydrogenCount()]++;
      charge[atom->GetFormalCharge()]++;
      connect[atom->GetImplicitValence()]++;
      degree[atom->GetValence()]++;
      implicit[atom->ImplicitHydrogenCount()]++;
      rings[atom->MemberOfRingCount()]++;
      for (int i = 3; i < 25; ++i)
        if (atom->IsInRingSize(i))
          size[i]++;
      valence[atom->KBOSum() - (atom->GetSpinMultiplicity() ? atom->GetSpinMultiplicity() - 1 : 0)]++;
      hyb[atom->GetHyb()]++;
      ringconnect[atom->CountRingBonds()]++;    
    }

    FOR_BONDS_OF_MOL (bond, mol) {
      numBonds++;
      if (bond->IsSingle())
        numSingleBonds++;
      else if (bond->IsDouble())
        numDoubleBonds++;
      else if (bond->IsTriple())
        numTripleBonds++;
      if (bond->IsAromatic())
        numAromaticBonds++;
      if (bond->IsInRing())
        numRingBonds++;;
    }
Beispiel #12
0
///////////////////////////////////////////////////////////////////////////////
//! \brief  Generate rough 3D coordinates for SMILES (or other 0D files).
//
int main(int argc,char **argv)
{
  char *program_name= argv[0];
  int c;
  string basename, filename = "", option, option2, ff = "MMFF94";

  list<string> argl(argv+1, argv+argc);

  list<string>::iterator optff = find(argl.begin(), argl.end(), "-ff");
  if (optff != argl.end()) {
    list<string>::iterator optffarg = optff;
    ++optffarg;

    if (optffarg != argl.end()) {
      ff = *optffarg;

      argl.erase(optff,++optffarg);
    } else {
      argl.erase(optff);
    }
  }

  if (argl.empty()) {
    cout << "Usage: obgen <filename> [options]" << endl;
    cout << endl;
    cout << "options:      description:" << endl;
    cout << endl;
    cout << "  -ff         select a forcefield" << endl;
    cout << endl;
    OBPlugin::List("forcefields", "verbose");
    exit(-1);
  }

  basename = filename = *argl.begin();
  size_t extPos = filename.rfind('.');

  if (extPos!= string::npos) {
    basename = filename.substr(0, extPos);
  }

  // Find Input filetype
  OBConversion conv;
  OBFormat *format_in = conv.FormatFromExt(filename.c_str());
  OBFormat *format_out = conv.FindFormat("sdf");

  if (!format_in || !format_out || !conv.SetInAndOutFormats(format_in, format_out)) {
    cerr << program_name << ": cannot read input/output format!" << endl;
    exit (-1);
  }

  ifstream ifs;
  ofstream ofs;

  // Read the file
  ifs.open(filename.c_str());
  if (!ifs) {
    cerr << program_name << ": cannot read input file!" << endl;
    exit (-1);
  }

  OBMol mol;

  for (c=1;;c++) {
      mol.Clear();
      if (!conv.Read(&mol, &ifs))
        break;
      if (mol.Empty())
        break;

      OBForceField* pFF = OBForceField::FindForceField(ff);
      if (!pFF) {
        cerr << program_name << ": could not find forcefield '" << ff << "'." <<endl;
        exit (-1);
      }

      //mol.AddHydrogens(false, true); // hydrogens must be added before Setup(mol) is called

      pFF->SetLogFile(&cerr);
      pFF->SetLogLevel(OBFF_LOGLVL_LOW);

      //pFF->GenerateCoordinates();
      OBBuilder builder;
      builder.Build(mol);

      mol.AddHydrogens(false, true); // hydrogens must be added before Setup(mol) is called
      if (!pFF->Setup(mol)) {
        cerr << program_name << ": could not setup force field." << endl;
        exit (-1);
      }

      pFF->SteepestDescent(500, 1.0e-4);
      pFF->WeightedRotorSearch(250, 50);
      pFF->SteepestDescent(500, 1.0e-6);

      pFF->UpdateCoordinates(mol);
      //pFF->ValidateGradients();
      //pFF->SetLogLevel(OBFF_LOGLVL_HIGH);
      //pFF->Energy();


      //char FileOut[32];
      //sprintf(FileOut, "%s_obgen.pdb", basename.c_str());
      //ofs.open(FileOut);
      //conv.Write(&mol, &ofs);
      //ofs.close();
      conv.Write(&mol, &cout);
  } // end for loop

  return(0);
}
Beispiel #13
0
int main(int argc,char **argv)
{
  char *program_name= argv[0];
  int c;
  char *FileIn = NULL;

  if (argc != 2)
    {
      string err = "Usage: ";
      err += program_name;
      err += " <filename>\n"
      "Output format:\n"
        "name NAME\n"
        "formula  FORMULA\n"
        "mol_weight MOLECULAR_WEIGHT\n"
        "exact_mass ISOTOPIC MASS\n"
        "canonical_SMILES STRING\n"
        "InChI  STRING\n"
        "num_atoms  NUM\n"
        "num_bonds  NUM\n"
        "num_residues  NUM\n"
	"num_rotors NUM\n"
        "sequence RESIDUE_SEQUENCE\n"
        "num_rings NUMBER_OF_RING_(SSSR)\n"
        "logP   NUM\n"
        "PSA    POLAR_SURFACE_AREA\n"
        "MR     MOLAR REFRACTIVITY";
      err += "$$$$";
//      ThrowError(err); wasn't being output because error level too low
      cerr << err; //Why not do directly
      exit(-1);
    }
  else
    {
      FileIn  = argv[1];
    }

  // Find Input filetype
  OBConversion conv;
  OBFormat *format = conv.FormatFromExt(FileIn);
    
  if (!format || !conv.SetInFormat(format))
    {
      cerr << program_name << ": cannot read input format!" << endl;
      exit (-1);
    }

  ifstream ifs;

  // Read the file
  ifs.open(FileIn);
  if (!ifs)
    {
      cerr << program_name << ": cannot read input file!" << endl;
      exit (-1);
    }
  
  OBMol mol;
  OBFormat *canSMIFormat = conv.FindFormat("can");
  OBFormat *inchiFormat = conv.FindFormat("inchi");


  ////////////////////////////////////////////////////////////////////////////
  // List of properties
  // Name
  // Molecular weight (Standard molar mass given by IUPAC atomic masses)
  // Number of rings : the size of the smallest set of smallest rings (SSSR)
  
  //.....ADD YOURS HERE.....
  
  for (c = 1;; ++c)
    {
      mol.Clear();
      conv.Read(&mol, &ifs);
      if (mol.Empty())
        break;
      
      if (!mol.HasHydrogensAdded())
        mol.AddHydrogens();
      // Print the properties
      if (strlen(mol.GetTitle()) != 0)
        cout << "name             " << mol.GetTitle() << endl;
      else 
        cout << "name             " << FileIn << " " << c << endl;

      cout << "formula          " << mol.GetFormula() << endl;
      cout << "mol_weight       " << mol.GetMolWt() << endl;
      cout << "exact_mass       " << mol.GetExactMass() << endl;

      string smilesString = "-";
      if (canSMIFormat) {
        conv.SetOutFormat(canSMIFormat);
        smilesString = conv.WriteString(&mol);
        if ( smilesString.length() == 0 )
        {
          smilesString = "-";
        }
      }
      cout << "canonical_SMILES " << smilesString << endl;

      string inchiString = "-";
      if (inchiFormat) {
        conv.SetOutFormat(inchiFormat);
        inchiString = conv.WriteString(&mol);
        if ( inchiString.length() == 0 )
        {
          inchiString = "-";
        }
      }
      cout << "InChI            " << inchiString << endl;

      cout << "num_atoms        " << mol.NumAtoms() << endl;
      cout << "num_bonds        " << mol.NumBonds() << endl;
      cout << "num_residues     " << mol.NumResidues() << endl;
      cout << "num_rotors       " << mol.NumRotors() << endl;
      if (mol.NumResidues() > 0)
        cout << "sequence         " << sequence(mol) << endl;
      else
        cout << "sequence         " << "-" << endl;

      cout << "num_rings        " << nrings(mol) << endl;

      OBDescriptor* pDesc;
      pDesc= OBDescriptor::FindType("logP");
      if(pDesc)
        cout << "logP             " << pDesc->Predict(&mol) << endl;

      pDesc = OBDescriptor::FindType("TPSA");
      if(pDesc)
        cout << "PSA              " << pDesc->Predict(&mol) << endl;

      pDesc = OBDescriptor::FindType("MR");
      if(pDesc)
        cout << "MR               " << pDesc->Predict(&mol) << endl;

      cout << "$$$$" << endl; // SDF like end of compound descriptor list
      
      //Other OBDescriptors could be output here, even ones that were rarely
      // used. Since these are plugin classes, they may not be loaded, but
      // then with code like the above they are just ignored.
    } // end for loop
  
  return(0);
}
Beispiel #14
0
  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;
  }
Beispiel #15
0
int main(int argc,char **argv)
{
  char  *program_name = argv[0];
  int    Nsymm = 0, Nrot = 0;
  bool   bKJ   = false;
  double dBdT  = 0;
  string filename, option;
  OBConversion conv;
  double unit_factor = 1;
  string e_unit("kcal/mol");
  string s_unit("cal/mol K");
  
  if (argc < 2) {
    cout << "Usage: obthermo [options] <filename>" << endl;
    cout << endl;
    cout << "options:      description:" << endl;
    cout << endl;
    cout << "  --symm N    override symmetry number used in input file" << endl;
    cout << endl;
    cout << "  --nrot N    number of rotatable bonds for conformational entropy" << endl;
    cout << endl;
    cout << "  --dbdt x    temperature derivative of second virial coefficient for cp calculation" << endl;
    cout << endl;
    cout << "  --kj        output kJ/mol related units (default kcal/mol)" << endl;
    cout << endl;
    exit(-1);
  } else {
    int i;
    for (i = 1; i < argc; ) {
      option = argv[i];

      if ((option == "--symm") && (argc > (i+1))) {
        Nsymm = atoi(argv[i+1]);
        if (Nsymm < 1) {
            cerr << program_name << ": the symmetry number should be >= 1!" << endl;
            exit(-1);
        }
        i += 2;
      }
      else if ((option == "--nrot") && (argc > (i+1))) {
        Nrot = atoi(argv[i+1]);
        if (Nrot < 0) {
            cerr << program_name << ": the number of rotatable bonds should be >= 0!" << endl;
            exit(-1);
        }
        i += 2;
      }
      else if ((option == "--dbdt") && (argc > (i+1))) {
        dBdT = atof(argv[i+1]);
        if (dBdT < 0) {
            cerr << program_name << ": the derivative of the second virial coefficient with respect to temperature should be >= 0!" << endl;
            exit(-1);
        }
        i += 2;
      }
      else if (option == "--kj") {
        bKJ          = true;
        unit_factor  = 4.184;
        e_unit.assign("kJ/mol");
        s_unit.assign("J/mol K");
        i += 1;
      }
      else {
        filename.assign(argv[i]);
        i += 1;
      }
    }
  }
  if (filename.size() == 0) {
    cerr << program_name << ": no filename specified" << endl;
    exit (-1);
  }
  // Find Input filetype
  OBFormat *format_in = conv.FormatFromExt(filename.c_str());

  if (!format_in || !conv.SetInFormat(format_in)) {
    cerr << program_name << ": cannot read input format in file \"" << filename << "\"" << endl;
    exit (-1);
  }

  ifstream ifs;

  // Read the file
  ifs.open(filename.c_str());
  if (!ifs) {
    cerr << program_name << ": cannot read input file!" << endl;
    exit (-1);
  }
  OBMol mol;
  if ((conv.Read(&mol, &ifs)) && ! mol.Empty())
  {
      OBPointGroup obPG;
      double temperature, DeltaHf0, DeltaHfT, DeltaGfT, DeltaSfT, S0T, CVT, CPT, ZPVE;
      std::vector<double> Scomponents;
      
      obPG.Setup(&mol);
      printf("obthermo - extract thermochemistry data from quantum chemistry logfiles\n");
      printf("Number of rotatable bonds: %d\n", Nrot);
      if (dBdT == 0)
      {
          printf("Please supply --dbdt option to get reliable heat capacity at constant pressure.\n");
      }
      printf("Point group according to OpenBabel: %s\n", 
             obPG.IdentifyPointGroup());
      bool bVerbose = true;
      if (extract_thermochemistry(mol, 
                                  bVerbose,
                                  &Nsymm,
                                  Nrot,
                                  dBdT,
                                  &temperature,
                                  &DeltaHf0,
                                  &DeltaHfT,
                                  &DeltaGfT,
                                  &DeltaSfT,
                                  &S0T,
                                  &CVT,
                                  &CPT,
                                  Scomponents,
                                  &ZPVE))
      {
          double Rgas  = 1.9872041; // cal/mol K
          printf("DeltaHform(0K)  %10g  %s\n", DeltaHf0*unit_factor, e_unit.c_str());
          printf("Temperature     %10g  K\n", temperature);
          printf("DeltaHform(T)   %10g  %s\n", DeltaHfT*unit_factor, e_unit.c_str());
          printf("DeltaGform(T)   %10g  %s\n", DeltaGfT*unit_factor, e_unit.c_str());
          printf("DeltaSform(T)   %10g  %s\n", DeltaSfT*unit_factor, s_unit.c_str());
          printf("cv(T)           %10g  %s\n", CVT*unit_factor, s_unit.c_str());
          printf("cp(T)           %10g  %s\n", CPT*unit_factor, s_unit.c_str());
          printf("Strans(T)       %10g  %s\n", Scomponents[0]*unit_factor, s_unit.c_str());
          printf("Srot(T)         %10g  %s\n", Scomponents[1]*unit_factor, s_unit.c_str());
          printf("Svib(T)         %10g  %s\n", Scomponents[2]*unit_factor, s_unit.c_str());
          if (Scomponents[3] != 0) 
          {
              printf("Ssymm           %10g  %s\n", Scomponents[3]*unit_factor, s_unit.c_str());
          }
          if (Scomponents[4] != 0) 
          {
              printf("Sconf           %10g  %s\n", Scomponents[4]*unit_factor, s_unit.c_str());
          }
          printf("S0(T)           %10g  %s\n", S0T*unit_factor, s_unit.c_str());
      }
      else
      {
          printf("Could not find all necessary information to determine thermochemistry values.\n");
      }
  }
  ifs.close();
  
  return 0;
}
Beispiel #16
0
bool OBReader::readFile(QString fileName)
{
    using namespace OpenBabel;

    OBConversion conv;

    OBFormat *format = conv.FormatFromExt(fileName.toStdString());

    if (!format || !conv.SetInFormat(format))
    {
        qDebug() << "Unsupported File Format.";
        return false;
    }

    std::ifstream ifs;
    ifs.open(fileName.toStdString());

    if (!ifs)
    {
        qDebug() << "Could not open the file.";
        return false;
    }

    OBMol obMol;
    if (!conv.Read(&obMol, &ifs))
    {
        qDebug() << "Error occured while reading the file.";
        return false;
    }

    if (!obMol.Has3D())
    {
        static bool showMsgBox = true;
        if (showMsgBox)
        {
            QMessageBox msgBox;
            msgBox.setWindowTitle(tr("OBReader"));
            msgBox.setText(tr("No 3D coordinate values present in this file."));
            msgBox.setInformativeText(tr("OBReader will generate the rough molecular geometry."));
            msgBox.setCheckBox(new QCheckBox(tr("Don’t show this message again.")));
            msgBox.setIcon(QMessageBox::Information);
            msgBox.exec();

            showMsgBox = !msgBox.checkBox()->isChecked();
        }

        if (!buildGeometry(&obMol))
        {
            qDebug() << "Error in buildGeometry()";
            return false;
        }
    }

    if (!toMolecule(&obMol))
    {
        qDebug() << "Could not convert OBMol to Molecule.";
        return false;
    }

    return true;
}
Beispiel #17
0
int main(int argc,char **argv)
{
  char *program_name= argv[0];
  int c;
  int verbose = 0;
  bool hydrogens = false;
  string basename, filename = "", option, option2, ff = "";

  if (argc < 2) {
    cout << "Usage: obenergy [options] <filename>" << endl;
    cout << endl;
    cout << "options:      description:" << endl;
    cout << endl;
    cout << "  -v          verbose: print out indivual energy interactions" << endl;
    cout << endl;
    cout << "  -h          add hydrogens before calculating energy" << endl;
    cout << endl;
    cout << "  -ff ffid    select a forcefield" << endl;
    cout << endl;
    cout << "              available forcefields:" << endl;
    cout << endl;
    OBPlugin::List("forcefields", "verbose");
    exit(-1);
  } else {
    int ifile = 1;
    for (int i = 1; i < argc; i++) {
      option = argv[i];
      
      if (option == "-v") {
        verbose = 1;
        ifile++;
        break;
      }

      if (option == "-h") {
        hydrogens = true;
        ifile++;
      }

      if ((option == "-ff") && (argc > (i+1))) {
        ff = argv[i+1];
        ifile += 2;
      }
    }
    
    basename = filename = argv[ifile];
    size_t extPos = filename.rfind('.');

    if (extPos!= string::npos) {
      basename = filename.substr(0, extPos);
    }


  }

  // Find Input filetype
  OBConversion conv;
  OBFormat *format_in = conv.FormatFromExt(filename.c_str());
    
  if (!format_in || !conv.SetInFormat(format_in)) {
    cerr << program_name << ": cannot read input format!" << endl;
    exit (-1);
  }

  ifstream ifs;
  ofstream ofs;

  // Read the file
  ifs.open(filename.c_str());
  if (!ifs) {
    cerr << program_name << ": cannot read input file!" << endl;
    exit (-1);
  }

  OBForceField* pFF = OBForceField::FindForceField(ff);
  if (!pFF) {
    cerr << program_name << ": could not find forcefield '" << ff << "'." <<endl;
    exit (-1);
  }
  pFF->SetLogFile(&cout);
  if (verbose)
    pFF->SetLogLevel(OBFF_LOGLVL_HIGH);
  else
    pFF->SetLogLevel(OBFF_LOGLVL_MEDIUM);

  OBMol mol;
  double energy;
  for (c=1;;c++) {
    mol.Clear();
    if (!conv.Read(&mol, &ifs))
      break;
    if (mol.Empty())
      break;

    if (hydrogens)
      mol.AddHydrogens();
       
    if (!pFF->Setup(mol)) {
      cerr << program_name << ": could not setup force field." << endl;
      exit (-1);
    }
    
    energy = pFF->Energy(false);
    if (!isfinite(energy)) {
      cerr << " Title: " << mol.GetTitle() << endl;
      FOR_ATOMS_OF_MOL(atom, mol) {
        cerr << " x: " << atom->x() << " y: " << atom->y() << " z: " << atom->z() << endl;
      }
    }

  } // end for loop
Beispiel #18
0
///////////////////////////////////////////////////////////////////////////////
//! \brief compute rms between chemically identical molecules
int main(int argc, char **argv)
{
	bool firstOnly = false;
	if (argc != 3 && argc != 4)
	{
		cerr << "Usage: " << argv[0]
				<< " [-firstonly] <reference structure(s)> <comparison structure(s)>\n";
		cerr << "Computes the heavy-atom RMSD of identical compound structures.\n";
		cerr << "Structures in multi-structure files are compared one-by-one unless -firstonly\n" 
		<< "is passed, in which case only the first structure in the reference file is used.\n";
		exit(-1);
	}

	char *fileRef = argv[1];
	char *fileTest = argv[2];

	if (argc == 4)
	{
		//if iterate is passed as first command, try to match structures in first file to strucutres in second
		if (strcmp("-firstonly", argv[1]) != 0)
		{
			cerr << "Usage: " << argv[0]
					<< " [-firstonly] <reference structure(s)> <comparison structure(s)>\n";
			exit(-1);
		}

		fileRef = argv[2];
		fileTest = argv[3];
		firstOnly = true;
	}

	//open mols
	OBConversion refconv;
	OBFormat *refFormat = refconv.FormatFromExt(fileRef);
	if (!refFormat || !refconv.SetInFormat(refFormat)
			|| !refconv.SetOutFormat("SMI"))
	{
		cerr << "Cannot read reference molecule format!" << endl;
		exit(-1);
	}

	OBConversion testconv;
	OBFormat *testFormat = testconv.FormatFromExt(fileTest);
	if (!testFormat || !testconv.SetInAndOutFormats(testFormat, testFormat))
	{
		cerr << "Cannot read reference molecule format!" << endl;
		exit(-1);
	}

	//read reference
	ifstream ifsref;
	OBMol molref;

	ifsref.open(fileRef);
	if (!ifsref)
	{
		cerr << "Cannot read fixed molecule file: " << fileRef << endl;
		exit(-1);
	}

	//check comparison file
	ifstream ifstest;
	ifstest.open(fileTest);
	if (!ifstest)
	{
		cerr << "Cannot read file: " << fileTest << endl;
		exit(-1);
	}

	while (refconv.Read(&molref, &ifsref))
	{
		processMol(molref);
		Matcher matcher(molref);// create the matcher
		OBMol moltest;
		while (testconv.Read(&moltest, &ifstest))
		{
			if (moltest.Empty())
				break;

			processMol(moltest);

			double rmsd = matcher.computeRMSD(moltest);

			cout << "RMSD " << moltest.GetTitle() << " " << rmsd << "\n";
			if (!firstOnly)
			{
				break;
			}
		}
	}
	return (0);
}
Beispiel #19
0
int main(int argc,char **argv)
{
  char *program_name= argv[0];
  char *FileIn = NULL;

  if (argc != 2)
    {
      cout << "Usage: " << program_name << " <filename>" << endl;
      exit(-1);
    }
  else
    {
      FileIn  = argv[1];
      //   const char* p = strrchr(FileIn,'.');
    }

  // Find Input filetype
  OBConversion conv;
  OBFormat *format = conv.FormatFromExt(FileIn);
    
  if (!format || !conv.SetInAndOutFormats(format, format))
    {
      cerr << program_name << ": cannot read input format!" << endl;
      exit (-1);
    }

  ifstream ifs;

  // Read the file
  ifs.open(FileIn);
  if (!ifs)
    {
      cerr << program_name << ": cannot read input file!" << endl;
      exit (-1);
    }

  OBMol mol;
  OBAtom *atom;

  for (int c=1;;++c) // big for loop (replace with do while?)
    {
      mol.Clear();
      conv.Read(&mol, &ifs);
      if (mol.Empty())
        break;
      cout << "Molecule "<< c << ": " << mol.GetTitle() << endl;
      //mol.FindChiralCenters(); // labels all chiral atoms
      vector<OBAtom*>::iterator i; // iterate over all atoms
      for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
        {
          if(!atom->IsChiral())continue; // aborts if atom isn't chiral
          cout << "Atom " << atom->GetIdx() << " Is Chiral ";
          cout << atom->GetType()<<endl;
        
          OBChiralData* cd = (OBChiralData*)atom->GetData(OBGenericDataType::ChiralData);
        
          if (cd){
            vector<unsigned int> x=cd->GetAtom4Refs(input);
            size_t n=0;
            cout <<"Atom4refs:";
            for (n=0;n<x.size();++n)
              cout <<" "<<x[n];
            cout <<endl;
          }
          else{cd=new OBChiralData;atom->SetData(cd);}
          vector<unsigned int> _output;
          unsigned int n;
          for(n=1;n<5;++n) _output.push_back(n);
          cd->SetAtom4Refs(_output,output);
          /* // MOLV3000 uses 1234 unless an H then 123H
             if (atom->GetHvyValence()==3)
             {
             OBAtom *nbr;
             int Hid=1000;// max Atom ID +1 should be used here
             vector<unsigned int> nbr_atms;
             vector<OBBond*>::iterator i;
             for (nbr = atom->BeginNbrAtom(i);nbr;nbr = atom->NextNbrAtom(i))
             {
             if (nbr->IsHydrogen()){Hid=nbr->GetIdx();continue;}
             nbr_atms.push_back(nbr->GetIdx());
             }
             sort(nbr_atms.begin(),nbr_atms.end());
             nbr_atms.push_back(Hid);
             OBChiralData* cd=(OBChiralData*)atom->GetData(OBGenericDataType::ChiralData);
             cd->SetAtom4Refs(nbr_atms,output);   
             } 
             else if (atom->GetHvyValence()==4)
             {
             OBChiralData* cd=(OBChiralData*)atom->GetData(OBGenericDataType::ChiralData);
             vector<unsigned int> nbr_atms;
             int n;
             for(n=1;n<5;++n)nbr_atms.push_back(n);
             cd->SetAtom4Refs(nbr_atms,output); 
             } */
    /* FIXME          
          if (!mol.HasNonZeroCoords())
            {
              cout << "Calcing 0D chirality "<< CorrectChirality(mol,atom)<<endl;
            }
          else {
            cout << "Volume= "<< CalcSignedVolume(mol,atom) << endl;
            OBChiralData* cd=(OBChiralData*)atom->GetData(OBGenericDataType::ChiralData);
            size_t n;
            vector<unsigned int> refs=cd->GetAtom4Refs(output);
            cout<<"Atom refs=";
            for(n=0;n<refs.size();++n)cout<<" "<<refs[n];
            cout<<endl;
          }
          cout << "Clockwise? " << atom->IsClockwise() << endl;
          */
        } // end iterating over atoms

    } // end big for loop

  return(0);
} // end main
Beispiel #20
0
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);

  OBConversion conv;
  OBFormat *inFormat, *canFormat;
  OBMol mol;
  ifstream ifs;
  vector<OBMol> fragments;
  unsigned int fragmentCount = 0; // track how many in library -- give a running count
  map<string, int> index; // index of cansmi
  string currentCAN;
  unsigned int size;
  OBAtom *atom;
  OBBond *bond;
  bool nonRingAtoms, nonRingBonds;
  char buffer[BUFF_SIZE];

  canFormat = conv.FindFormat("can");
  conv.SetOutFormat(canFormat);

  if (argc < 2)
    {
      cout << "Usage: obfragment <file>" << endl;
      return(-1);
    }

  for (int i = 1; i < argc; i++) {
    cerr << " Reading file " << argv[i] << endl;

    inFormat = conv.FormatFromExt(argv[i]);
    if(inFormat==NULL || !conv.SetInFormat(inFormat))
      {
        cerr << " Cannot read file format for " << argv[i] << endl;
        continue; // try next file
      }
    
    ifs.open(argv[i]);
    
    if (!ifs)
      {
        cerr << "Cannot read input file: " << argv[i] << endl;
        continue;
      }
    
    
    while(ifs.peek() != EOF && ifs.good())
      {
        conv.Read(&mol, &ifs);
        if (!mol.Has3D()) continue; // invalid coordinates!
        mol.DeleteHydrogens(); // remove these before we do anything else
        
        do {
          nonRingAtoms = false;
          size = mol.NumAtoms();
          for (unsigned int i = 1; i <= size; ++i)
            {
              atom = mol.GetAtom(i);
              if (!atom->IsInRing()) {
                mol.DeleteAtom(atom);
                nonRingAtoms = true;
                break; // don't know how many atoms there are
              } 
              // Previously, we changed atoms to carbon here.
              // Now we perform this alchemy in terms of string-rewriting
              // once the canonical SMILES is generated
            }
        } while (nonRingAtoms);
        
        if (mol.NumAtoms() < 3)
          continue;
        
        if (mol.NumBonds() == 0)
          continue;
        
        do {
          nonRingBonds = false;
          size = mol.NumBonds();
          for (unsigned int i = 0; i < size; ++i)
            {
              bond = mol.GetBond(i);
              if (!bond->IsInRing()) {
                mol.DeleteBond(bond);
                nonRingBonds = true;
                break; // don't know how many bonds there are
              }
            }        
        } while (nonRingBonds);

        fragments = mol.Separate();
        for (unsigned int i = 0; i < fragments.size(); ++i)
          {
            if (fragments[i].NumAtoms() < 3) // too small to care
              continue;
              
            currentCAN = conv.WriteString(&fragments[i], true);
            currentCAN = RewriteSMILES(currentCAN); // change elements to "a/A" for compression
            if (index.find(currentCAN) != index.end()) { // already got this
              index[currentCAN] += 1; // add to the count for bookkeeping
              continue;
            }

            index[currentCAN] = 1; // don't ever write this ring fragment again

            // OK, now retrieve the canonical ordering for the fragment
            vector<string> canonical_order;
            if (fragments[i].HasData("Canonical Atom Order")) {
              OBPairData *data = (OBPairData*)fragments[i].GetData("Canonical Atom Order");
              tokenize(canonical_order, data->GetValue().c_str());
            }

            // Write out an XYZ-style file with the CANSMI as the title
            cout << fragments[i].NumAtoms() << '\n';
            cout << currentCAN << '\n'; // endl causes a flush

            vector<string>::iterator can_iter;
            unsigned int order;
            OBAtom *atom;

            fragments[i].Center();
            fragments[i].ToInertialFrame();

            for (unsigned int index = 0; index < canonical_order.size(); 
                 ++index) {
              order = atoi(canonical_order[index].c_str());
              atom = fragments[i].GetAtom(order);
              
              snprintf(buffer, BUFF_SIZE, "C%8.3f%8.3f%8.3f\n",
                       atom->x(), atom->y(), atom->z());
              cout << buffer;
            }

          }
        fragments.clear();
        if (index.size() > fragmentCount) {
          fragmentCount = index.size();
          cerr << " Fragments: " << fragmentCount << endl;
        }

      } // while reading molecules (in this file)
    ifs.close();
    ifs.clear();
  } // while reading files

  // loop through the map and output frequencies
  map<string, int>::const_iterator indexItr;
  for (indexItr = index.begin(); indexItr != index.end(); ++indexItr) {
    cerr << (*indexItr).second << " INDEX " << (*indexItr).first << "\n";
  }
    
  return(0);
}
Beispiel #21
0
int main(int argc,char **argv)
{
  char *program_name= argv[0];
  int c;
  int steps = 2500;
  double crit = 1e-6;
  bool sd = false;
  bool cut = false;
  bool newton = false;
  bool hydrogens = false;
  double rvdw = 6.0;
  double rele = 10.0;
  int freq = 10;
  string basename, filename = "", option, option2, ff = "MMFF94";
  char *oext;
  OBConversion conv;
  OBFormat *format_out = conv.FindFormat("pdb"); // default output format

  if (argc < 2) {
    cout << "Usage: obminimize [options] <filename>" << endl;
    cout << endl;
    cout << "options:      description:" << endl;
    cout << endl;
    cout << "  -c crit     set convergence criteria (default=1e-6)" << endl;
    cout << endl;
    cout << "  -cg         use conjugate gradients algorithm (default)" << endl;
    cout << endl;
    cout << "  -sd         use steepest descent algorithm" << endl;
    cout << endl;
    cout << "  -newton     use Newton2Num linesearch (default=Simple)" << endl;
    cout << endl;
    cout << "  -ff ffid    select a forcefield:" << endl;
    cout << endl;
    cout << "  -h          add hydrogen atoms" << endl;
    cout << endl;
    cout << "  -n steps    specify the maximum numer of steps (default=2500)" << endl;
    cout << endl;
    cout << "  -cut        use cut-off (default=don't use cut-off)" << endl;
    cout << endl;
    cout << "  -rvdw rvdw  specify the VDW cut-off distance (default=6.0)" << endl;
    cout << endl;
    cout << "  -rele rele  specify the Electrostatic cut-off distance (default=10.0)" << endl;
    cout << endl;
    cout << "  -pf freq    specify the frequency to update the non-bonded pairs (default=10)" << endl;
    cout << endl;
    OBPlugin::List("forcefields", "verbose");
    exit(-1);
  } else {
    int ifile = 1;
    for (int i = 1; i < argc; i++) {
      option = argv[i];

      // steps
      if ((option == "-n") && (argc > (i+1))) {
        steps = atoi(argv[i+1]);
        ifile += 2;
      }
      // vdw cut-off
      if ((option == "-rvdw") && (argc > (i+1))) {
        rvdw = atof(argv[i+1]);
        ifile += 2;
      }
      // ele cut-off
      if ((option == "-rele") && (argc > (i+1))) {
        rele = atof(argv[i+1]);
        ifile += 2;
      }
      // pair update frequency
      if ((option == "-pf") && (argc > (i+1))) {
        freq = atoi(argv[i+1]);
        ifile += 2;
      }
      // steepest descent
      if (option == "-sd") {
        sd = true;
        ifile++;
      }
      // enable cut-off
      if (option == "-cut") {
        cut = true;
        ifile++;
      }
      // enable Newton2Num
      if (option == "-newton") {
        newton = true;
        ifile++;
      }

      if (strncmp(option.c_str(), "-o", 2) == 0) {
        oext = argv[i] + 2;
        if(!*oext) {
          oext = argv[++i]; //space left after -o: use next argument
          ifile++;
        }

        format_out = conv.FindFormat(oext);
        ifile++;
      }

      if (option == "-h") {
        hydrogens = true;
        ifile++;
      }

      if (option == "-cg") {
        sd = false;
        ifile++;
      }

      if ((option == "-c") && (argc > (i+1))) {
        crit = atof(argv[i+1]);
        ifile += 2;
      }

      if ((option == "-ff") && (argc > (i+1))) {
        ff = argv[i+1];
        ifile += 2;
      }
    }

    basename = filename = argv[ifile];
    size_t extPos = filename.rfind('.');

    if (extPos!= string::npos) {
      basename = filename.substr(0, extPos);
    }
  }

  // Find Input filetype
  OBFormat *format_in = conv.FormatFromExt(filename.c_str());

  if (!format_in || !format_out || !conv.SetInAndOutFormats(format_in, format_out)) {
    cerr << program_name << ": cannot read input/output format!" << endl;
    exit (-1);
  }

  ifstream ifs;
  ofstream ofs;

  // Read the file
  ifs.open(filename.c_str());
  if (!ifs) {
    cerr << program_name << ": cannot read input file!" << endl;
    exit (-1);
  }

  OBForceField* pFF = OBForceField::FindForceField(ff);
  if (!pFF) {
    cerr << program_name << ": could not find forcefield '" << ff << "'." <<endl;
    exit (-1);
  }

  // set some force field variables
  pFF->SetLogFile(&cerr);
  pFF->SetLogLevel(OBFF_LOGLVL_LOW);
  pFF->SetVDWCutOff(rvdw);
  pFF->SetElectrostaticCutOff(rele);
  pFF->SetUpdateFrequency(freq);
  pFF->EnableCutOff(cut);
  if (newton)
    pFF->SetLineSearchType(LineSearchType::Newton2Num);

  OBMol mol;

  for (c=1;;c++) {
    mol.Clear();
    if (!conv.Read(&mol, &ifs))
      break;
    if (mol.Empty())
      break;

    if (hydrogens)
      mol.AddHydrogens();

    if (!pFF->Setup(mol)) {
      cerr << program_name << ": could not setup force field." << endl;
      exit (-1);
    }

    bool done = true;
    OBStopwatch timer;
    timer.Start();
    if (sd) {
      pFF->SteepestDescentInitialize(steps, crit);
    } else {
      pFF->ConjugateGradientsInitialize(steps, crit);
    }

    unsigned int totalSteps = 1;
    while (done) {
      if (sd)
        done = pFF->SteepestDescentTakeNSteps(1);
      else
        done = pFF->ConjugateGradientsTakeNSteps(1);
      totalSteps++;

      if (pFF->DetectExplosion()) {
        cerr << "explosion has occured!" << endl;
        conv.Write(&mol, &cout);
        return(1);
      } else
        pFF->GetCoordinates(mol);
    }
    double timeElapsed = timer.Elapsed();

    pFF->GetCoordinates(mol);

    conv.Write(&mol, &cout);
    cerr << "Time: " << timeElapsed << "seconds. Iterations per second: " <<  double(totalSteps) / timeElapsed << endl;
  } // end for loop

  return(0);
}
Beispiel #22
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);
}
Beispiel #23
0
int main(int argc,char **argv)
{
  OBForceField* pFF = OBForceField::FindForceField("Ghemical");
  pFF->SetLogFile(&cout);
  pFF->SetLogLevel(OBFF_LOGLVL_LOW);

  OBMol mol;
  mol.Clear();

  char commandline[100];
  vector<string> vs;

  cout << endl;
  cout << "openbabel                            " << endl;
  cout << "M O L E C U L A R   M E C H A N I C S" << endl;
  cout << "                              program" << endl;
  cout << "                v 0.1                " << endl << endl;

  while (1) {

    cout << "command > ";
    cin.getline(commandline, 100);

    //
    // commands with no parameters
    //
    if (EQn(commandline, "quit", 4) || cin.eof()) {
      cout << "bye." << endl;
      exit(0);
    }
    
    if (EQn(commandline, "help", 4) || cin.eof()) {
      cout << endl;
      cout << "commands:            description:" << endl;
      cout << "load <filename>      load a molecule from filename" << endl;
      cout << "save <filename>      save currently loaded molecule to filename" << endl;
      cout << "ff <forcefield>      select the force field" << endl;
      cout << "forcefields          print the available forcefields" << endl;
      cout << endl;
      cout << "energy               calculate the energy" << endl;
      cout << "ebond                calculate the bond stretching energy" << endl;
      cout << "eangle               calculate the angle bending energy" << endl;
      cout << "estrbnd              calculate the stretch-bending enregy" << endl;
      cout << "eoop                 calculate the out-of-plane bending energy" << endl;
      cout << "etorsion             calculate the torsional energy" << endl;
      cout << "evdw                 calculate the Van der Waals energy" << endl;
      cout << "eeq                  calculate the electrostatic energy" << endl;
      cout << endl;
      cout << "sd <n>               steepest descent energy minimization for n steps" << endl;
      cout << "cg <n>               conjugate gradients energy minimization for n steps" << endl;
      cout << "" << endl;
      cout << "addH                 add hydrogens" << endl;
      cout << "delH                 delete hydrogens" << endl;
      cout << endl;
      cout << "gen                  generate/minimize a (random) structure" << endl;
      cout << "rs                   rotate around all rotatable bonds" << endl;
      cout << "nconf                print the number of conformers" << endl;
      cout << "conf <n>             select conformer n" << endl;
      cout << endl;
      cout << "quit                 quit" << endl;
      cout << endl;
      continue;
    }

    // calculate the energy
    if (EQn(commandline, "energy", 6)) {
      if (mol.Empty()) {
        cout << "no molecule loaded." << endl;
        continue;
      }
      cout << endl << "  total energy = " << pFF->Energy() << " " << pFF->GetUnit() << endl << endl;
      continue;
    }

    if (EQn(commandline, "ebond", 5)) {
      if (mol.Empty()) {
        cout << "no molecule loaded." << endl;
        continue;
      }
      cout << endl << "  bond stretching energy = " << pFF->E_Bond() << " " << pFF->GetUnit() << endl << endl;
      continue;
    }

    if (EQn(commandline, "eangle", 6)) {
      if (mol.Empty()) {
        cout << "no molecule loaded." << endl;
        continue;
      }
      cout << endl << "  angle bending energy = " << pFF->E_Angle() << " " << pFF->GetUnit() << endl << endl;
      continue;
    }

    if (EQn(commandline, "estrbnd", 7)) {
      if (mol.Empty()) {
        cout << "no molecule loaded." << endl;
        continue;
      }
      cout << endl << "  stretch-bending energy = " << pFF->E_StrBnd() << " " << pFF->GetUnit() << endl << endl;
      continue;
    }

    if (EQn(commandline, "eoop", 4)) {
      if (mol.Empty()) {
        cout << "no molecule loaded." << endl;
        continue;
      }
      cout << endl << "  out-of-plane bending energy = " << pFF->E_OOP() << " " << pFF->GetUnit() << endl << endl;
      continue;
    }

    if (EQn(commandline, "etorsion", 8)) {
      if (mol.Empty()) {
        cout << "no molecule loaded." << endl;
        continue;
      }
      cout << endl << "  torsional energy = " << pFF->E_Torsion() << " " << pFF->GetUnit() << endl << endl;
      continue;
    }

    if (EQn(commandline, "evdw", 4)) {
      if (mol.Empty()) {
        cout << "no molecule loaded." << endl;
        continue;
      }
      cout << endl << "  Van der Waals energy = " << pFF->E_VDW() << " " << pFF->GetUnit() << endl << endl;
      continue;
    }
    
    if (EQn(commandline, "eeq", 3)) {
      if (mol.Empty()) {
        cout << "no molecule loaded." << endl;
        continue;
      }
      cout << endl << "  electrostatic energy = " << pFF->E_Electrostatic() << " " << pFF->GetUnit() << endl << endl;
      continue;
    }
    
    if (EQn(commandline, "addH", 4)) {
      int num1, num2;
      num1 = mol.NumAtoms();
      mol.AddHydrogens(false, true);
      num2 = mol.NumAtoms();
      cout << (num2 - num1) << " hydrogens added." << endl;
      
      if (!pFF->Setup(mol)) {
        cout << "error while initializing the force field for this molecule." <<endl;
        continue;
      }
      continue;
    }
    
    if (EQn(commandline, "delH", 4)) {
      int num1, num2;
      num1 = mol.NumAtoms();
      mol.DeleteHydrogens();
      num2 = mol.NumAtoms();
      cout << (num1 - num2) << " hydrogens deleted." << endl;
      
      if (!pFF->Setup(mol)) {
        cout << "error while initializing the force field for this molecule." <<endl;
        continue;
      }
      continue;
    }
    
    if (EQn(commandline, "gen", 3)) {
      //pFF->GenerateCoordinates();
      pFF->UpdateCoordinates(mol);
      continue;
    }
    
    if (EQn(commandline, "rs", 2)) {
      pFF->SystematicRotorSearch();
      pFF->UpdateCoordinates(mol);
      continue;
    }
    
    if (EQn(commandline, "nconf", 5)) {
      cout << endl << "  number of conformers = " << mol.NumConformers() << endl << endl;
      continue;
    }


    //
    // commands with parameters
    //
    tokenize(vs, commandline);
    
    // select forcefield
    if (EQn(commandline, "ff", 2)) {
      if (vs.size() < 2) {
        cout << "no <forcefield> specified." << endl;
        continue;
      }
      
      pFF = OBForceField::FindForceField(vs[1]);

      if (!mol.Empty())
        if (!pFF->Setup(mol))
          cout << "error while initializing the force field (" << vs[1] << ") for this molecule." <<endl;

      continue;
    }

   
    // load <filename>
    if (EQn(commandline, "load", 4)) {
      if (vs.size() < 2) {
        cout << "no <filename> specified." << endl;
        continue;
      }
      
      ifstream ifs;
      OBConversion conv;
      OBFormat *format_in = conv.FormatFromExt(vs[1].c_str());
   
      if (!format_in || !conv.SetInFormat(format_in)) {
        cout << "could not detect format." << endl;
        continue;
      }
       
      ifs.open(vs[1].c_str());
      if (!ifs) {
        cout << "could not open '" << vs[1] << "'." <<endl;
        continue;
      }
      
      mol.Clear();
      if (!conv.Read(&mol, &ifs)) {
        cout << "could not read a molecule from '" << vs[1] << "'." <<endl;
        continue;
      }
      
      if (mol.Empty()) {
        cout << "this molecule is empty." <<endl;
        continue;
      }

      if (!pFF->Setup(mol)) {
        cout << "error while initializing the force field for this molecule." <<endl;
        continue;
      }

      cout << "molecule succesfully loaded." << endl;
      cout << "  " << mol.NumAtoms() << " atoms" << endl;
      cout << "  " << mol.NumBonds() << " bonds" << endl;

      ifs.close();
 
      continue;
    }
    
    // save <filename>
    if (EQn(commandline, "save", 4)) {
      if (vs.size() < 2) {
        cout << "no <filename> specified." << endl;
        continue;
      }
      
      ofstream ofs;
      OBConversion conv;
      OBFormat *format_out = conv.FormatFromExt(vs[1].c_str());
   
      if (!format_out || !conv.SetOutFormat(format_out)) {
        cout << "could not detect format." << endl;
        continue;
      }
       
      ofs.open(vs[1].c_str());
      if (!ofs) {
        cout << "could not open '" << vs[1] << "'." <<endl;
        continue;
      }
      
      if (!conv.Write(&mol, &ofs)) {
        cout << "could not read a molecule from '" << vs[1] << "'." <<endl;
        continue;
      }
      
      cout << "molecule succesfully saved." << endl;
      cout << "  " << mol.NumAtoms() << " atoms" << endl;
      cout << "  " << mol.NumBonds() << " bonds" << endl;

      ofs.close();
 
      continue;
    }

    // steepest descent
    if (EQn(commandline, "sd", 2)) {
      if (vs.size() < 2) {
        cout << "no <n> steps specified." << endl;
        continue;
      }

      pFF->SteepestDescent(atoi(vs[1].c_str()), OBFF_ANALYTICAL_GRADIENT);
      pFF->UpdateCoordinates(mol);

      continue;
    }

    // conjugate gradients
    if (EQn(commandline, "cg", 2)) {
      if (vs.size() < 2) {
        cout << "no <n> steps specified." << endl;
        continue;
      }

      pFF->ConjugateGradients(atoi(vs[1].c_str()), OBFF_ANALYTICAL_GRADIENT);
      pFF->UpdateCoordinates(mol);

      continue;
    }

    cout << "invalid command." << endl;
  }

  return(1);
}