Example #1
0
extern "C" char *
ob_V3000_to_mol (char *V3000)
{
  OBMol mol;
  OBConversion conv;
  string tmpStr (V3000);
  string outstring;
  istringstream V3000stream (tmpStr);
  ostringstream molstream;
  char *tmpMolfile;

  conv.SetInAndOutFormats ("MDL", "MDL");
  conv.AddOption ("3", OBConversion::INOPTIONS);
  conv.AddOption ("2", OBConversion::OUTOPTIONS);

  conv.Read (&mol, &V3000stream);
  conv.Write (&mol, &molstream);

  outstring = molstream.str ();

  // remove the trailling $$$$\n from the SDFile
  if (outstring.find ("$$$$\n", 0) != string::npos)
    {
      outstring = outstring.substr (0, outstring.length () - 5);
    }
  else if (outstring.find ("$$$$\r\n", 0) != string::npos)
    {
      outstring = outstring.substr (0, outstring.length () - 6);
    }

  tmpMolfile = strdup (outstring.c_str ());

  return (tmpMolfile);
}
Example #2
0
extern "C" char *
ob_mol_to_canonical_smiles (char *molfile, int omit_iso_and_chiral_markings)
{
  OBMol mol;
  OBConversion conv;
  string tmpStr (molfile);
  string outstring;
  istringstream molstream (tmpStr);
  ostringstream smilesstream;
  char *tmpSmiles;

  conv.SetInAndOutFormats ("MDL", "CAN");
  conv.AddOption ("n", OBConversion::OUTOPTIONS);
  //conv.AddOption ("c", OBConversion::OUTOPTIONS);
  if (omit_iso_and_chiral_markings != 0)
    {
      conv.AddOption ("i", OBConversion::OUTOPTIONS);
    }

  conv.Read (&mol, &molstream);

  if (mol.Empty ())
    return NULL;

  conv.Write (&mol, &smilesstream);

  outstring = smilesstream.str ();

  outstring = outstring.substr (0, outstring.length () - 1);

  tmpSmiles = strdup (outstring.c_str ());

  return (tmpSmiles);
}
Example #3
0
extern "C" char *
ob_add_hydrogens (char *smiles, int polaronly, int correct4PH)
{
  OBMol mol;
  OBConversion conv;
  string tmpStr (smiles);
  string outstring;
  istringstream molstream1 (tmpStr);
  ostringstream molstream2;
  char *tmpMolfile;

  conv.SetInAndOutFormats ("SMI", "SMI");

  conv.Read (&mol, &molstream1);

  mol.AddHydrogens (polaronly != 0, correct4PH != 0);

  conv.Write (&mol, &molstream2);

  outstring = molstream2.str ();

  // remove the trailling $$$$\n from the SDFile
  if (outstring.find ("$$$$\n", 0) != string::npos)
    {
      outstring = outstring.substr (0, outstring.length () - 5);
    }
  else if (outstring.find ("$$$$\r\n", 0) != string::npos)
    {
      outstring = outstring.substr (0, outstring.length () - 6);
    }

  tmpMolfile = strdup (outstring.c_str ());

  return (tmpMolfile);
}
Example #4
0
void turnMol(OBMol& mol,vector< vector <int> >& maplist,int k)
{
	if (k<0)
		return;
	if (k>=maplist.size())
		return;

	OBAtom *a1, *a2, *a3, *a4;
	double energy;

	string fileName;
	ostringstream oss(fileName);
	for (int i=0;i<angleSum;++i) {
		fileName = "";
		a2 = mol.GetAtom(maplist[k][0]);
		a3 = mol.GetAtom(maplist[k][1]);
		std::vector<OBEdgeBase*>::iterator temp = a2->BeginBonds();
		a1 = a2->BeginNbrAtom(temp);
		if (a1==a3)
			a1 = a2->NextNbrAtom(temp);
		temp = a3->BeginBonds();
		a4 = a3->BeginNbrAtom(temp);
		if (a4==a2)
			a4 = a3->NextNbrAtom(temp);
		if ( !a2->IsConnected(a3) ) {
			cerr << "obrotate: The atoms of the rotating bond must be bonded." << endl;
			exit(-1);
		}

		mol.SetTorsion(a1, a2, a3, a4, i * angle * DEG_TO_RAD);

		if (isEnergyCalcing)
		{
			indexSheet[k]=i;
			forceField->Setup(mol);
			energy = forceField->Energy(false);
			energySheet->getVectorValue(indexSheet)=energy;
		}
		else
		{
			oss.str("");
			pthread_mutex_lock(&sum_lock);
			oss << sum++ << "," << FileIn ;
			pthread_mutex_unlock(&sum_lock);
			ofstream ofs(oss.str().c_str());
			cerr << "Outputing file no." << sum << "/" << totalSum << endl;
			conv.Write(&mol,&ofs); //NF
		}
		turnMol(mol,maplist,k-1);
	}
}
int main(int argc, char **argv)
{
  if (argc < 2) {
    std::cout << "Usage: " << argv[0] << " <filename>" << std::endl;
    return 1;
  }

  // Read the file
  shared_ptr<OBMol> mol = GetMol(argv[1]);

  // Create the OBConformerSearch object
  OBConformerSearch cs;
  
  // Setup 
  std::cout << "Setting up conformer searching..." << std::endl
            << "   conformers:  30" << std::endl
            << "   children:    5" << std::endl
            << "   mutability:  5" << std::endl
            << "   convergence: 25" << std::endl;
  cs.Setup(*mol.get(),
           30, // numConformers
           5, // numChildren
           5, // mutability
           25); // convergence

  // Perform searching
  cs.Search();

  // Print the rotor keys
  RotorKeys keys = cs.GetRotorKeys();
  for (RotorKeys::iterator key = keys.begin(); key != keys.end(); ++key) {
    for (unsigned int i = 1; i < key->size(); ++i)
      std::cout << key->at(i) << " ";
    std::cout << std::endl;
  }

  // Get the conformers
  cs.GetConformers(*mol.get());

  std::cout << mol->NumConformers() << std::endl;
  OBConversion conv;
  conv.SetOutFormat("sdf");
  for (unsigned int c = 0; c < mol->NumConformers(); ++c) {
    mol->SetConformer(c);
    conv.Write(mol.get(), &std::cerr);
  }

}
Example #6
0
extern "C" char *
ob_delete_hydrogens (char *smiles, int nonpolaronly)
{
  OBMol mol;
  OBConversion conv;
  string tmpStr (smiles);
  string outstring;
  istringstream molstream1 (tmpStr);
  ostringstream molstream2;
  char *tmpMolfile;

  conv.SetInAndOutFormats ("SMI", "SMI");

  conv.Read (&mol, &molstream1);

  if(mol.NumHvyAtoms () > 0) {
    if (nonpolaronly != 0)
      {
	mol.DeleteNonPolarHydrogens ();
      }
    else
      {
	mol.DeleteHydrogens ();
      }
  } else {
    cout << "Warning: Cannot remove hydrogens. Resulting molecule would be empty!" << endl;
  }        

  conv.Write (&mol, &molstream2);

  outstring = molstream2.str ();

  // remove the trailling $$$$\n from the SDFile
  if (outstring.find ("$$$$\n", 0) != string::npos)
    {
      outstring = outstring.substr (0, outstring.length () - 5);
    }
  else if (outstring.find ("$$$$\r\n", 0) != string::npos)
    {
      outstring = outstring.substr (0, outstring.length () - 6);
    }

  tmpMolfile = strdup (outstring.c_str ());

  return (tmpMolfile);
}
Example #7
0
void outputMol(vector<int*>& mols,OBMol& mol,vector< vector <int> >& maplist,int k)
{
	if (k<0)
		return;
	if (k>=maplist.size())
		return;

	OBAtom *a1, *a2, *a3, *a4;
	double energy;

	string fileName;
	ostringstream oss(fileName);
	for (int i=0;i<angleSum;++i) {
		fileName = "";
		a2 = mol.GetAtom(maplist[k][0]);
		a3 = mol.GetAtom(maplist[k][1]);
		std::vector<OBEdgeBase*>::iterator temp = a2->BeginBonds();
		a1 = a2->BeginNbrAtom(temp);
		if (a1==a3)
			a1 = a2->NextNbrAtom(temp);
		temp = a3->BeginBonds();
		a4 = a3->BeginNbrAtom(temp);
		if (a4==a2)
			a4 = a3->NextNbrAtom(temp);
		
		mol.SetTorsion(a1, a2, a3, a4, i * angle * DEG_TO_RAD);

		indexSheet[k]=i;
		if (isContained(mols,indexSheet))
		{
			oss.str("");
			pthread_mutex_lock(&sum_lock);
			oss << sum++ << "," << FileIn;
			pthread_mutex_unlock(&sum_lock);
			ofstream ofs(oss.str().c_str());
			cerr << "Outputing low energy file no." << sum << "/" << totalSum << endl;
			conv.Write(&mol,&ofs); //NF
		}
		outputMol(mols,mol,maplist,k-1);
	}
}
Example #8
0
extern "C" char *
ob_inchi_to_mol (char *inchi)
{
  OBMol mol;
  OBConversion conv;
  string tmpStr (inchi);
  string outstring;
  istringstream inchistream (tmpStr);
  ostringstream molstream;
  char *tmpMolfile;

  conv.SetInAndOutFormats ("INCHI", "MDL");

  conv.Read (&mol, &inchistream);

  if (mol.Empty ())
    return NULL;

  conv.Write (&mol, &molstream);

  outstring = molstream.str ();

  // remove the trailling $$$$\n from the SDFile
  if (outstring.find ("$$$$\n", 0) != string::npos)
    {
      outstring = outstring.substr (0, outstring.length () - 5);
    }
  else if (outstring.find ("$$$$\r\n", 0) != string::npos)
    {
      outstring = outstring.substr (0, outstring.length () - 6);
    }

  tmpMolfile = strdup (outstring.c_str ());

  return (tmpMolfile);
}
Example #9
0
int main(int argc,char *argv[])
{
  OBConversion Conv(&cin, &cout); //default input and output are console 

  OBFormat* pInFormat = NULL;
  OBFormat* pOutFormat = NULL;
  vector<string> FileList, OutputFileList;
  string OutputFileName;

  // Parse commandline
  bool gotInType = false, gotOutType = false;
  bool SplitOrBatch=false;

  char *oext = NULL;
  char *iext = NULL;

  //Save name of program without its path (and .exe)
  string pn(argv[0]);
  string::size_type pos;
#ifdef _WIN32
  pos = pn.find(".exe");
  if(pos!=string::npos)
    argv[0][pos]='\0';
#endif
  pos = pn.find_last_of("/\\");
  if(pos==string::npos)
    program_name=argv[0];
  else
    program_name=argv[0]+pos+1;

  const char* p;
  int arg;
  for (arg = 1; arg < argc; ++arg)
    {
      if (argv[arg])
        {
          if (argv[arg][0] == '-')
            {
              char opchar[2]="?";
              opchar[0]=argv[arg][1];
              switch (opchar[0])
                {

                case 'V':
                  {
                    cout << "Open Babel " << BABEL_VERSION << " -- " 
                         << __DATE__ << " -- " << __TIME__ << endl;
                    exit(0);
                  }

                case 'i':
                  //Parameter is the input format which overrides any file extensions
                  gotInType = true;
                  iext = argv[arg] + 2;
                  if(!*iext)
                    iext = argv[++arg]; //space left after -i: use next argument

                  if (strncasecmp(iext, "MIME", 4) == 0)
                    {
                      // get the MIME type from the next argument
                      iext = argv[++arg];
                      pInFormat = Conv.FormatFromMIME(iext);
                    }
                  else
                      pInFormat = Conv.FindFormat(iext);
                  if(pInFormat==NULL)
                    {
                      cerr << program_name << ": cannot read input format!" << endl;
                      usage();
                    }
                  break;

                case 'o':
                  //Parameter is the output format which overrides any file extension
                  gotOutType = true;
                  oext = argv[arg] + 2;
                  if(!*oext)
                    oext = argv[++arg]; //space left after -i: use next argument

                  if (strncasecmp(oext, "MIME", 4) == 0)
                    {
                      // get the MIME type from the next argument
                      oext = argv[++arg];
                      pOutFormat = Conv.FormatFromMIME(oext);
                    }
                  else
                    pOutFormat = Conv.FindFormat(oext);

                  if(pOutFormat==NULL)
                    {
                      cerr << program_name << ": cannot write output format!" << endl;
                      usage();
                    }
                  break;

                case 'O':
                  OutputFileName = argv[arg] + 2;
                  if(OutputFileName.size()<3)
                    OutputFileName = argv[++arg]; //space left after -O: use next argument
                  break;

                case 'L': //display a list of plugin type or classes
                  {
                    const char* param=NULL;
                    if(argc>arg+1)
                      param = argv[arg+2];

                    // First assume first arg is a plugin type and
                    // param is a subtype, like babel -L ops gen3D
                    // or first arg is a plugin ID, like babel -L cml
                    OBPlugin* plugin;
                    if(OBPlugin::GetPlugin("plugins", argv[arg+1])
                      && (plugin = OBPlugin::GetPlugin(argv[arg+1], param))
                      || (plugin = OBPlugin::GetPlugin(NULL, argv[arg+1])))
                    {
                      //Output details of subtype
                      string txt;
                      plugin->Display(txt, "verbose", argv[arg+1]);
                      cout << "One of the " << plugin->TypeID() << '\n' << txt << endl;
                      return 0;
                    }
                    //...otherwise assume it is a plugin type, like babel -L forcefields
                    //Output list of subtypes
                    OBPlugin::List(argv[arg+1], param);
                    return 0;
                  }

                case '?':
                case 'H':
                  if(isalnum(argv[arg][2]) || arg==argc-2)
                    {
                      if(strncasecmp(argv[arg]+2,"all",3))
                        {
                          OBFormat* pFormat
                            = (arg==argc-2) ? Conv.FindFormat(argv[arg+1]) : Conv.FindFormat(argv[arg]+2);
                          if(pFormat)
                            {
                              cout << argv[arg]+2 << "  " << pFormat->Description() << endl;
                              if(pFormat->Flags() & NOTWRITABLE)
                                cout << " This format is Read-only" << endl;
                              if(pFormat->Flags() & NOTREADABLE)
                                cout << " This format is Write-only" << endl;

                              if(strlen(pFormat->SpecificationURL()))
                                cout << "Specification at: " << pFormat->SpecificationURL() << endl;
                            }
                          else
                            cout << "Format type: " << argv[arg]+2 << " was not recognized" <<endl;
                        }
                      else
                        {
                          OBPlugin::List("formats","verbose");
                        }
                    }
                  else
                    help();
                  return 0;

                case '-': //long option --name text
                  {
                    //Option's text is in the next and subsequent args, until one starts with -
                    char* nam = argv[arg]+2;
                    if(!strcasecmp(nam, "help")) //special case handled here
                    {
                      help();
                      return 0;
                    }
                    if(*nam != '\0') //Do nothing if name is empty
                      {
                        string txt;
                        while(arg<argc-1 && *argv[arg+1]!='-')
                          {
                            //use text from subsequent args
                            if(!txt.empty())txt += ' '; //..space separated if more than one
                            txt += argv[++arg]; 
                          }

                        // If a API directive, e.g.---errorlevel
                        // send to the pseudoformat "obapi" (without any leading -)
                        if(*nam=='-')
                          {
                            OBConversion apiConv;
                            OBFormat* pAPI= OBConversion::FindFormat("obapi");
                            if(pAPI)
                              {
                                apiConv.SetOutFormat(pAPI);
                                apiConv.AddOption(nam+1, OBConversion::GENOPTIONS, txt.c_str());
                                apiConv.Write(NULL, &std::cout);
                              }
                          }
                        else
                          // Is a normal long option name, e.g --addtotitle
                          Conv.AddOption(nam,OBConversion::GENOPTIONS,txt.c_str());
                      }
                  }
                  break;
					
                case 'm': //multiple output files
                  SplitOrBatch=true;
                  break;
					
                case 'a': //single character input option
                  p = argv[arg]+2;
                  DoOption(p,Conv,OBConversion::INOPTIONS,arg,argc,argv);
                  break;

                case 'x': //single character output option
                  p = argv[arg]+2;
                  DoOption(p,Conv,OBConversion::OUTOPTIONS,arg,argc,argv);
                  break;

                //Not essential, but allows these options to be before input filenames
                //since we know they take one parameter, and are the most likely options to be misplaced
                case 'f':
                case 'l':
                  p = argv[arg] + 2;
                  if(!*p)
                    p = argv[++arg]; //space left after -f: use next argument
                  Conv.AddOption(opchar, OBConversion::GENOPTIONS, p);
                  break;
                
                case ':':
                  //e.g. -:c1ccccc1. SMILES passed as a file name and handled in OBConversion
                  FileList.push_back(argv[arg]);
                  break;

                default: //single character general option
                  p = argv[arg]+1;
                  DoOption(p,Conv,OBConversion::GENOPTIONS,arg,argc,argv);
                  break;
                }
            }
          else //filenames
              FileList.push_back(argv[arg]);
        }
    }

#ifdef _WIN32
  //Expand wildcards in input filenames and add to FileList
  vector<string> tempFileList(FileList);
  FileList.clear();
  vector<string>::iterator itr;
  for(itr=tempFileList.begin();itr!=tempFileList.end();++itr)
  {
    if((*itr)[0]=='-')
      FileList.push_back(*itr);
    else
      DLHandler::findFiles (FileList, *itr);
  }
#endif
  
  if (!gotInType)
    {
      if(FileList.empty())
        {
          cerr << "No input file or format spec or possibly a misplaced option.\n"
            "Options, other than -i -o -O -m, must come after the input files.\n" <<endl;
          usage();
        }
    }

  if (!gotOutType)
    {
      //check there is a valid output format, but the extension will be re-interpreted in OBConversion
      pOutFormat = Conv.FormatFromExt(OutputFileName.c_str());
      if(OutputFileName.empty() || pOutFormat==NULL)
        {
          cerr << "Missing or unknown output file or format spec or possibly a misplaced option.\n"
            "Options, other than -i -o -O -m, must come after the input files.\n" <<endl;
          usage();
        }
    }
  
    if(!Conv.SetInFormat(pInFormat))
    {
      cerr << "Invalid input format" << endl;
      usage();
    }
    if(!Conv.SetOutFormat(pOutFormat))
    {
      cerr << "Invalid output format" << endl;
      usage();
    }

  if(SplitOrBatch)
    {
      //Put * into output file name before extension (or ext.gz)
      if(OutputFileName.empty())
        {
          OutputFileName = "*.";
          OutputFileName += oext;
        }
      else
        {
          string::size_type pos = OutputFileName.rfind(".gz");
          if(pos==string::npos)
            pos = OutputFileName.rfind('.');
          else
            pos = OutputFileName.rfind('.',pos-1);
          if(pos==string::npos)
            OutputFileName += '*';
          else
            OutputFileName.insert(pos,"*");
        }
    }

  int count = Conv.FullConvert(FileList, OutputFileName, OutputFileList);
 
  Conv.ReportNumberConverted(count);

  if(OutputFileList.size()>1)
    {
      clog << OutputFileList.size() << " files output. The first is " << OutputFileList[0] <<endl;
    }

  //std::string messageSummary = obErrorLog.GetMessageSummary();
  //if (messageSummary.size())
  //  {
  //    clog << messageSummary << endl;
  //  }

#ifdef _DEBUG
  //CM keep window open
  cout << "Press any key to finish" <<endl;
  getch();
#endif
  
  return 0;
}
Example #10
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);
}
Example #11
0
  bool ReactionInChIFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
  {
    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
    if (pmol == NULL || !pmol->IsReaction())
      return false;
    ostream &ofs = *pConv->GetOutStream();

    OBFormat* pInChIFormat = OBConversion::FindFormat("inchi");
    if (!pInChIFormat)
      return false;

    bool isEquilibrium = pConv->IsOption("e");

    OBConversion inchiconv;
    inchiconv.SetOutFormat(pInChIFormat);
    stringstream ss;
    inchiconv.SetOutStream(&ss);

#define M_REACTANTS 0
#define M_PRODUCTS 1
#define M_AGENTS 2

    OBReactionFacade facade(pmol);

    std::vector<std::vector<std::string> > inchis(3);
    unsigned int nonInchi[3] = { 0, 0, 0 };
    bool hasNonInchi = false;
    OBMol mol;
    for (int part = 0; part <= 2; ++part) {
      unsigned int N;
      switch (part) {
      case M_REACTANTS: N = facade.NumComponents(REACTANT); break;
      case M_PRODUCTS: N = facade.NumComponents(PRODUCT); break;
      case M_AGENTS: N = facade.NumComponents(AGENT); break;
      }
      for (unsigned int i = 0; i < N; ++i) {
        mol.Clear();
        switch (part) {
        case M_REACTANTS: facade.GetComponent(&mol, REACTANT, i); break;
        case M_PRODUCTS: facade.GetComponent(&mol, PRODUCT, i); break;
        case M_AGENTS: facade.GetComponent(&mol, AGENT, i); break;
        }
        if (mol.NumAtoms() == 1 && mol.GetFirstAtom()->GetAtomicNum() == 0) {
          // This represents an unknown component
          nonInchi[part]++;
          hasNonInchi = true;
        }
        else {
          bool ok = inchiconv.Write(&mol);
          if (!ok) {
            nonInchi[part]++;
            hasNonInchi = true;
          }
          else {
            string inchi = ss.str();
            if (strncmp(inchi.c_str(), "InChI=1S/", 9) != 0)
              return false;
            inchis[part].push_back(TrimInChI(inchi.c_str()));
          }
          ss.str("");
        }
      }
    }

    std::sort(inchis[M_REACTANTS].begin(), inchis[M_REACTANTS].end());
    std::sort(inchis[M_PRODUCTS].begin(), inchis[M_PRODUCTS].end());
    std::sort(inchis[M_AGENTS].begin(), inchis[M_AGENTS].end());

    std::string reactants_string = "";
    const int rsize = inchis[M_REACTANTS].size();
    for (int i = 0; i < rsize; ++i) {
      if (i > 0)
        reactants_string += '!';
      reactants_string += inchis[M_REACTANTS][i];
    }
    std::string products_string = "";
    const int psize = inchis[M_PRODUCTS].size();
    for (int i = 0; i < psize; ++i) {
      if (i > 0)
        products_string += '!';
      products_string += inchis[M_PRODUCTS][i];
    }

    bool reactants_first = reactants_string <= products_string;

    ofs << RINCHI_VERSION_STRING;
    if (rsize > 0 || psize > 0 || !inchis[M_AGENTS].empty()) {
      ofs << (reactants_first ? reactants_string : products_string);
      ofs << "<>";
      ofs << (reactants_first ? products_string : reactants_string);
      if (!inchis[M_AGENTS].empty()) {
        ofs << "<>";
        for (std::vector<std::string>::const_iterator vit = inchis[M_AGENTS].begin(); vit != inchis[M_AGENTS].end(); ++vit) {
          if (vit != inchis[M_AGENTS].begin())
            ofs << '!';
          ofs << *vit;
        }
      }
    }
    ofs << "/d";
    if (isEquilibrium)
      ofs << '=';
    else
      ofs << (reactants_first ? '+' : '-');
    if (hasNonInchi) {
      ofs << "/u" << (reactants_first ? nonInchi[M_REACTANTS] : nonInchi[M_PRODUCTS]) << '-'
        << (reactants_first ? nonInchi[M_PRODUCTS] : nonInchi[M_REACTANTS]) << '-'
        << nonInchi[M_AGENTS];
    }

    ofs << '\n';
    return true;
  }
Example #12
0
// This function will call the Babel library to add 
// hydrogens to the residues
void PDB::addHydrogensToPair(AminoAcid& a, AminoAcid& b, int cd1, int cd2)
{
  OBMol mol;
  string addedH;
  istringstream tempss;
  bool ligand;
  if(b.atom[0]->line.find("HETATM") != string::npos)
    {
      ligand = true;
    }
  else
    {
      ligand = false;
    }

  // This section is just to suppress all of the 
  // warning message that aren't important to us
  {
    OBConversion apiConv;
    OBFormat* pAPI = OBConversion::FindFormat("obapi");
    if(pAPI)
      {
        apiConv.SetOutFormat(pAPI);
        apiConv.AddOption("errorlevel", OBConversion::GENOPTIONS, "0");
        apiConv.Write(NULL, &std::cout);
      }
  }

  // Now, let's pack up the information into a string
  string packedFile="";
  for(unsigned int i=0; i < a.altlocs[cd1].size(); i++)
    {
      if( !a.altlocs[cd1][i]->skip )
        {
          packedFile += a.altlocs[cd1][i]->line + "\n";
        }
    }
  
  int cd2_al = cd2;
  if(b.residue == "ASP" || b.residue == "GLU")
    {
      cd2_al = cd2%(b.altlocs.size());
    }

  for(unsigned int i=0; i < b.altlocs[cd2_al].size(); i++)
    {
      if( !b.altlocs[cd2_al][i]->skip )
        {
            packedFile += b.altlocs[cd2_al][i]->line + "\n";
        }
    }
  packedFile += a.makeConect(cd1);
  packedFile += b.makeConect(cd2_al);


  // Now, let's set up some Babel information
  // First, we get the PDB format to tell
  // Babel how to read the information and 
  // how to output it
  OBFormat* pdbformat = this->conv.FindFormat("pdb");
  this->conv.SetInFormat(pdbformat);
  this->conv.SetOutFormat(pdbformat);

  // Here is where Babel reads everything
  // and adds hydrogens to the pair
  // TO ADD: option to set pH
  this->conv.ReadString(&mol,packedFile);
  mol.AddHydrogens(false,true,PH_LEVEL);

  // Let's write the newly written hydrogens to 
  // a string and parse it
  addedH = this->conv.WriteString(&mol);
  tempss.str(addedH);

  // This ensures that the ligand hydrogens are labeled as
  // HETATM instead of ATOM just for the sake of STAAR. 
  // This may be wrong, but it should be fine since we are
  // stripping out that information later when we write 
  // the GAMESS inp files
  if( ligand )
    {
      string line;
      string f = "";
      while( getline(tempss,line) )
        {
          if( line.find(b.residue) != string::npos )
            {
              line.replace(0,6,"HETATM");
            }
          f += line + "\n";
        }
      tempss.seekg(ios_base::beg);
      tempss.clear();
      tempss.str(f);
    }

  this->failure = false;
  this->parsePDB(tempss,99999.99);

  // This is just to ensure that all of the atoms
  // are grouped together because Babel just 
  // appends the H to the end of the file
  if( !ligand )
      this->sortAtoms();

  // Split the atoms up into amino acids and chains
  this->populateChains(true);
}
Example #13
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);
}
Example #14
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);
}
Example #15
0
int main(int argc,char *argv[])
{
  OBConversion Conv(&cin, &cout); //default input and output are console

  OBFormat* pInFormat = NULL;
  OBFormat* pOutFormat = NULL;
  bool inGzip = false;
  bool outGzip = false;
  vector<string> FileList, OutputFileList;
  string OutputFileName;

  // Parse commandline
  bool gotInType = false, gotOutType = false;
  bool SplitOrBatch=false;

  char *oext = NULL;
  char *iext = NULL;

  //load plugs to fully initialize option parameters
  OBPlugin::LoadAllPlugins();

  //Save name of program without its path (and .exe)
  string pn(argv[0]);
  string::size_type pos;
#ifdef _WIN32
  pos = pn.find(".exe");
  if(pos!=string::npos)
    argv[0][pos]='\0';
#endif
  pos = pn.find_last_of("/\\");
  if(pos==string::npos)
    program_name=argv[0];
  else
    program_name=argv[0]+pos+1;

  const char* p;
  int arg;
  for (arg = 1; arg < argc; ++arg)
    {
      if (argv[arg])
        {
          if (argv[arg][0] == '-')
            {
              switch (argv[arg][1])
                {

                case 'V':
                  {
                    cout << "Open Babel " << BABEL_VERSION << " -- "
                         << __DATE__ << " -- " << __TIME__ << endl;
                    exit(0);
                  }

                case 'i':
                  gotInType = true;
                  iext = argv[arg] + 2;
                  if(!*iext)
                    iext = argv[++arg]; //space left after -i: use next argument

                  if (strncasecmp(iext, "MIME", 4) == 0)
                    {
                      // get the MIME type from the next argument
                      iext = argv[++arg];
                      pInFormat = Conv.FormatFromMIME(iext);
                    }
                  else
                    {
                      //The ID provided by the OBFormat class is used as the identifying file extension
                      pInFormat = Conv.FindFormat(iext);
                    }
                  if(pInFormat==NULL)
                    {
                      cerr << program_name << ": cannot read input format!" << endl;
                      usage();
                    }
                  break;

                case 'o':
                  gotOutType = true;
                  oext = argv[arg] + 2;
                  if(!*oext)
                    oext = argv[++arg]; //space left after -i: use next argument

                  if (arg >= argc)
                    usage(); // error in parsing command-line

                  if (strncasecmp(oext, "MIME", 4) == 0)
                    {
                      // get the MIME type from the next argument
                      oext = argv[++arg];
                      pOutFormat = Conv.FormatFromMIME(oext);
                    }
                  else
                    pOutFormat = Conv.FindFormat(oext);

                  if(pOutFormat==NULL)
                    {
                      cerr << program_name << ": cannot write output format!" << endl;
                      usage();
                    }
                  break;

                case 'L': //display a list of plugin type or classes
                  {
                    const char* param=NULL;
                    if(argc>arg+1)
                      param = argv[arg+2];

                    // First assume first arg is a plugin type and
                    // param is a subtype, like babel -L ops gen3D
                    // or first arg is a plugin ID, like babel -L cml
                    OBPlugin* plugin;
                    if ((OBPlugin::GetPlugin("plugins", argv[arg+1]) &&
                         (plugin = OBPlugin::GetPlugin(argv[arg+1], param))) ||
                        (plugin = OBPlugin::GetPlugin(NULL, argv[arg+1])))
                    {
                      //Output details of subtype
                      string txt;
                      plugin->Display(txt, "verbose", argv[arg+1]);
                      cout << "One of the " << plugin->TypeID() << '\n' << txt << endl;
                      return 0;
                    }
                    //...otherwise assume it is a plugin type, like babel -L forcefields
                    //Output list of subtypes
                    OBPlugin::List(argv[arg+1], param);
                    return 0;
                  }
                case '?':
                case 'H':
                  if(isalnum(argv[arg][2]) || arg==argc-2)
                    {
                      if(strncasecmp(argv[arg]+2,"all",3))
                        {
                          const char* pID= (arg==argc-2) ? argv[arg+1] : argv[arg]+2;
                          OBFormat* pFormat = Conv.FindFormat(pID);
                          if(pFormat)
                            {
                              cout << pID << "  " << pFormat->Description() << endl;
                              if(pFormat->Flags() & NOTWRITABLE)
                                cout << " This format is Read-only" << endl;
                              if(pFormat->Flags() & NOTREADABLE)
                                cout << " This format is Write-only" << endl;

                              if(strlen(pFormat->SpecificationURL()))
                                cout << "Specification at: " << pFormat->SpecificationURL() << endl;
                            }
                          else
                            cout << "Format type: " << pID << " was not recognized" <<endl;
                        }
                      else
                        {
                          OBPlugin::List("formats","verbose");
                        }
                    }
                  else
                    help();
                  return 0;

                case '-': //long option --name text
                  {
                    //Do nothing if name is empty
                    //Option's text is the next arg provided it doesn't start with -
                    char* nam = argv[arg]+2;
                    if(*nam != '\0')
                      {
                        string txt;
                        int i;
                        for(i=0; i<Conv.GetOptionParams(nam, OBConversion::GENOPTIONS)
                              && arg<argc-1 && argv[arg+1];++i) //removed  && *argv[arg+1]!='-'
                          {
                            if(!txt.empty()) txt+=' ';
                            txt += argv[++arg];
                          }
                        if(*nam=='-')
                          {
                            // Is a API directive, e.g.---errorlevel
                            //Send to the pseudoformat "obapi" (without any leading -)
                            OBConversion apiConv;
                            OBFormat* pAPI= OBConversion::FindFormat("obapi");
                            if(pAPI)
                              {
                                apiConv.SetOutFormat(pAPI);
                                apiConv.AddOption(nam+1, OBConversion::GENOPTIONS, txt.c_str());
                                apiConv.Write(NULL, &std::cout);
                              }
                          }
                        else
                          // Is a long option name, e.g --addtotitle
                          Conv.AddOption(nam,OBConversion::GENOPTIONS,txt.c_str());
                      }
                  }
                  break;

                case 'm': //multiple output files
                  SplitOrBatch=true;
                  break;

                case 'a': //single character input option
                  p = argv[arg]+2;
                  DoOption(p,Conv,OBConversion::INOPTIONS,arg,argc,argv);
                  break;

                case 'x': //single character output option
                  p = argv[arg]+2;
                  DoOption(p,Conv,OBConversion::OUTOPTIONS,arg,argc,argv);
                  break;

                default: //single character general option
                  p = argv[arg]+1;
                  DoOption(p,Conv,OBConversion::GENOPTIONS,arg,argc,argv);
                  break;
                }
            }
          else
            {
              //filenames
              if(!gotOutType)
                FileList.push_back(argv[arg]);
              else
                OutputFileName = argv[arg];
            }
        }
    }

  if(!gotOutType) //the last file is the output
    {
      if(FileList.empty())
        {
          cerr << "No output file or format spec!" << endl;
          usage();
        }
      OutputFileName = FileList.back();
      FileList.pop_back();
    }

#if defined(_WIN32) && defined(USING_DYNAMIC_LIBS)
  //Expand wildcards in input filenames and add to FileList
  vector<string> tempFileList(FileList);
  FileList.clear();
  vector<string>::iterator itr;
  for(itr=tempFileList.begin();itr!=tempFileList.end();++itr)
    DLHandler::findFiles (FileList, *itr);
#endif

  if (!gotInType)
    {
      if(FileList.empty())
        {
          cerr << "No input file or format spec!" <<endl;
          usage();
        }
    }

  if (!gotOutType)
    {
      pOutFormat = Conv.FormatFromExt(OutputFileName.c_str(), outGzip);
      if(pOutFormat==NULL)
        {
          cerr << program_name << ": cannot write output format!" << endl;
          usage();
        }
    }

    if(!Conv.SetInFormat(pInFormat))
    {
      cerr << "Invalid input format" << endl;
      usage();
    }
    if(!Conv.SetOutFormat(pOutFormat, outGzip))
    {
      cerr << "Invalid output format" << endl;
      usage();
    }

  if(SplitOrBatch)
    {
      //Put * into output file name before extension (or ext.gz)
      if(OutputFileName.empty())
        {
          OutputFileName = "*.";
          if (oext != NULL)
            OutputFileName += oext;
        }
      else
        {
          string::size_type pos = OutputFileName.rfind(".gz");
          if(pos==string::npos)
            pos = OutputFileName.rfind('.');
          else
            pos = OutputFileName.rfind('.',pos-1);
          if(pos==string::npos)
            OutputFileName += '*';
          else
            OutputFileName.insert(pos,"*");
        }
    }

  int count = Conv.FullConvert(FileList, OutputFileName, OutputFileList);

  Conv.ReportNumberConverted(count);

  if(OutputFileList.size()>1)
    {
      clog << OutputFileList.size() << " files output. The first is " << OutputFileList[0] <<endl;
    }

  std::string messageSummary = obErrorLog.GetMessageSummary();
  if (messageSummary.size())
    {
      clog << messageSummary << endl;
    }

#ifdef _DEBUG
  //CM keep window open
  cout << "Press any key to finish" <<endl;
  getch();
#endif

  return 0;
}