Exemple #1
0
void help()
{
  cout << "Open Babel converts chemical structures from one file format to another"<< endl << endl;
  cout << "Usage: " << endl;
  cout << program_name << "[-i<input-type>] <infilename> [-o<output-type>] -O<outfilename> [Options]" << endl;
  cout << "The extension of a file decides the format, unless it is overridden" <<endl;
  cout << " by -i or -o options, e.g. -icml, or -o smi" << endl;
  cout << "See below for available format-types, which are the same as the " << endl;
  cout << "file extensions and are case independent." << endl; 
  cout << "If no input or output file is given stdin or stdout are used instead." << endl << endl; 
  cout << "More than one input file can be specified and their names can contain" <<endl;
  cout << "wildcard chars (* and ?). The format of each file can be different unless" <<endl;
  cout << "the -i option has been used, when they are all the same." <<endl;
  cout << "By default, the molecules are aggregated in the output file," << endl;
  cout << " but see -m option, Splitting, below.\n" << endl;

  cout << "Options, other than -i -o -O -m, must come after the input files.\n" <<endl;
  cout << OBConversion::Description(); // Conversion options
  cout << "-H Outputs this help text" << endl;
  cout << "-Hxxx (xxx is file format ID e.g. -Hcml) gives format info" <<endl; 
  cout << "-Hall Outputs details of all formats" <<endl; 
  cout << "-V Outputs version number" <<endl; 
  cout << "-L <category> Lists plugin classes of this category, e.g. <formats>" << endl;
  cout << "   Use just -L for a list of plugin categories." << endl; 
  cout << "   Use -L <ID> e.g. -L sdf for details of a format or other plugin." << endl; 
  cout << "-m Produces multiple output files, to allow:" <<endl;
  cout << "    Splitting: e.g.        " << program_name << " infile.mol -O new.smi -m" <<endl;
  cout << "      puts each molecule into new1.smi new2.smi etc" <<endl;
  cout << "    Batch conversion: e.g. " << program_name << " *.mol -osmi -m" <<endl;
  cout << "      converts each input file to a .smi file" << endl;
#ifdef _WIN32
  cout << "   In Windows these can also be done using the forms" <<endl;
  cout << "     " << program_name << " infile.mol -O new*.smi and " << program_name << " *.mol -O *.smi respectively.\n" <<endl;
#endif
  
  OBFormat* pDefault = OBConversion::GetDefaultFormat();
  if(pDefault)
    cout << pDefault->TargetClassDescription();// some more options probably for OBMol
  
  OBFormat* pAPI= OBConversion::FindFormat("obapi");
  if(pAPI)
    cout << pAPI->Description();
  
  cout << "To see a list of recognized file formats use\n  babel -L formats [read] [write]\n"
       << "To see details and specific options for a particular format, e.g CML, use\n  babel -L cml\n"
       << endl;
  //cout << "The following file formats are recognized:" << endl;
  //OBPlugin::List("formats");
  //cout << "\nSee further specific info and options using -H<format-type>, e.g. -Hcml" << endl;
}
Exemple #2
0
void help()
{
  cout << "Open Babel converts chemical structures from one file format to another"<< endl << endl;
  cout << "Usage: " << program_name << " <input spec> <output spec> [Options]" << endl << endl;

  deprecation();
  cout << endl;

  cout << "Each spec can be a file whose extension decides the format." << endl;
  cout << "Optionally the format can be specified by preceding the file by" << endl;
  cout << "-i<format-type> e.g. -icml, for input and -o<format-type> for output" << endl << endl;
  cout << "See below for available format-types, which are the same as the " << endl;
  cout << "file extensions and are case independent." << endl;
  cout << "If no input or output file is given stdin or stdout are used instead." << endl << endl;
  cout << "More than one input file can be specified and their names can contain" <<endl;
  cout << "wildcard chars (* and ?).The molecules are aggregated in the output file.\n" << endl;
  cout << OBConversion::Description(); // Conversion options
  cout << "-H Outputs this help text" << endl;
  cout << "-V Outputs version number" <<endl;
  cout << "-L <category> Lists plugin classes of this category, e.g. <formats>" << endl;
  cout << "   Use just -L for a list of plugin categories." << endl;
  cout << "   Use -L <ID> e.g. -L sdf for details of a format or other plugin." << endl;
  cout << "-m Produces multiple output files, to allow:" <<endl;
  cout << "   Splitting: e.g.        " << program_name << " infile.mol new.smi -m" <<endl;
  cout << "     puts each molecule into new1.smi new2.smi etc" <<endl;
  cout << "   Batch conversion: e.g. " << program_name << " *.mol -osmi -m" <<endl;
  cout << "     converts each input file to a .smi file" << endl;
#ifdef _WIN32
  cout << "   In Windows these can also be done using the forms" <<endl;
  cout << "     " << program_name << " infile.mol new*.smi and " << program_name << " *.mol *.smi respectively.\n" <<endl;
#endif

  OBFormat* pDefault = OBConversion::GetDefaultFormat();
  if(pDefault)
    cout << pDefault->TargetClassDescription();// some more options probably for OBMol

  OBFormat* pAPI= OBConversion::FindFormat("obapi");
  if(pAPI)
    cout << pAPI->Description();

  cout << "To see a list of recognized file formats use\n  babel -L formats\n"
       << "To see details and specific options for a particular format, e.g CML, use\n  babel -L cml\n"
       << endl;
  //cout << "The following file formats are recognized:" << endl;
  //OBPlugin::List("formats");
  //cout << "\nSee further specific info and options using -H<format-type>, e.g. -Hcml" << endl;
}
Exemple #3
0
bool RXNFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
{
    //It's really a reaction, not a molecule.
    //Cast output object to the class type need, i.e. OBReaction
    OBReaction* pReact = dynamic_cast<OBReaction*>(pOb);
    if(pReact==NULL)
        return false;

    OBConversion MolConv(*pConv); //new copy to use to write associated MOL
    MolConv.AddOption("no$$$$",OBConversion::OUTOPTIONS);
    MolConv.SetAuxConv(NULL); //temporary until a proper OBConversion copy constructor written

    OBFormat* pMolFormat = pConv->FindFormat("MOL");
    if(pMolFormat==NULL)
    {
      obErrorLog.ThrowError(__FUNCTION__, "MDL MOL format not available", obError);
        return false;
    }

    ostream &ofs = *pConv->GetOutStream();

    ofs << "$RXN" << endl;
    ofs << pReact->GetTitle() << endl;
    ofs << "  OpenBabel" << endl;
    ofs << pReact->GetComment() <<endl;

    ofs << setw(3) << pReact->NumReactants() << setw(3) << pReact->NumProducts() << endl;

    unsigned i;
    for(i=0;i<pReact->NumReactants();i++)
    {
      ofs << "$MOL" << endl;
      //Write reactant in MOL format
      pMolFormat->WriteMolecule(pReact->GetReactant(i).get(), &MolConv);
    }

    for(i=0;i<pReact->NumProducts();i++)
    {
      ofs << "$MOL" << endl;
      //Write reactant in MOL format
      pMolFormat->WriteMolecule(pReact->GetProduct(i).get(), &MolConv);
    }

    return true;
}
Exemple #4
0
  bool OutputFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
  {
    // so we want to read through the file until we can figure out
    // what program actually created it
    // if we get to the end, emit a warning
    istream &ifs = *pConv->GetInStream();
    char buffer[BUFF_SIZE];
    OBFormat *pFormat = NULL;
    std::string formatName;

    // the detection strings are from the Chemical MIME project
    // http://chemical-mime.sourceforge.net/chemical-mime-data.html
    while (ifs.getline(buffer,BUFF_SIZE)) {
      if ((strstr(buffer,"GAMESS execution script") != NULL) ||
          (strstr(buffer,"PC GAMESS") != NULL) ||
          (strstr(buffer,"GAMESS VERSION") != NULL)) {
        // GAMESS output
        formatName = "gamout";
        break;
      } else if (strstr(buffer,"===  G A M E S S - U K    === ") != NULL) {
        // GAMESS-UK output
        formatName = "gukout";
        break;
      } else if (strstr(buffer,"Gaussian, Inc") != NULL) {
        // Gaussian output
        formatName = "g03";
        break;
      } else if (strstr(buffer,"GENERAL UTILITY LATTICE PROGRAM") != NULL) {
        // GULP output -- not currently supported
        break;
      } else if (strstr(buffer,"MOPAC") != NULL) {
        // MOPAC output
        formatName = "mopout";
        break;
      } else if (strstr(buffer,"Program PWSCF") != NULL) {
        // PWSCF
        formatName = "pwscf";
        break;
      } else if (strstr(buffer,"Welcome to Q-Chem") != NULL) {
        // Q-Chem output
        formatName = "qcout";
        break;
      } else if (strstr(buffer,"Amsterdam Density Functional") != NULL) {
        // ADF output
        // Determine the kind of ADF output
        while (ifs.getline(buffer, BUFF_SIZE)) {
          if (strstr(buffer, "|     A D F     |") != NULL) {
            formatName = "adfout";
            break;
          } else if (strstr(buffer, "|     B A N D     |") != NULL) {
            formatName = "adfband";
            break;
          } else if (strstr(buffer, "|     D F T B     |") != NULL) {
            formatName = "adfdftb";
            break;
          } else if (strstr(buffer, "DFTB Engine") != NULL) {
            // "|     D F T B     |" is no longer printed in ADF 2018
            // Hopefully, "DFTB Engine" will work fine...
            formatName = "adfdftb";
            break;
          }
        }
        break;
      } else if (strstr(buffer,"Northwest Computational Chemistry") != NULL) {
        // NWChem output
        formatName = "nwo";
        break;
      } else if (strstr(buffer,"MPQC: Massively Parallel Quantum Chemistry") != NULL) {
        // MPQC output
        formatName = "mpqc";
        break;
      } else if (strstr(buffer,"PROGRAM SYSTEM MOLPRO") != NULL) {
        // MOLPRO output
        formatName = "mpo";
        break;
      } else if ((strstr(buffer,"Schrodinger, Inc.") != NULL) &&
                 (strstr(buffer,"Jaguar") != NULL)) {
        // Jaguar
        formatName = "jout";
        break;
      } else if (strstr(buffer, "ABINIT") != NULL) {
        // Abinit
        formatName = "abinit";
        break;
      } else if (strstr(buffer, "ACES2") != NULL) {
        // ACESII
        formatName = "acesout";
        break;
      } else if (strstr(buffer, "CRYSTAL06") != NULL ||
                 strstr(buffer, "CRYSTAL09") != NULL) {
        // CRYSTAL09
        formatName = "c09out";
        break;
      } else if (strstr(buffer, "* O   R   C   A *") != NULL) {
        // ORCA
        formatName = "orca";
        break;
      } else if (strstr(buffer, "WELCOME TO SIESTA") != NULL) {
        // SIESTA
        formatName = "siesta";
        break;
      }
    }

    // if we assigned something above, let's try to find it
    if (formatName.length())
      pFormat = pConv->FindFormat(formatName);

    if (pFormat) {
      ifs.seekg (0, ios::beg); // reset the stream to the beginning
      ifs.clear();
      bool success = pFormat->ReadMolecule(pOb, pConv);

      // Tag the molecule with the format (e.g., if a program wants to know the kind of "out" or "log" file)
      // We have to do this *after* ReadMolecule returns, or the data might be cleared
      if (pOb) {
        OBPairData *dp = new OBPairData;
        dp->SetAttribute("File Format");
        dp->SetValue(formatName);
        dp->SetOrigin(fileformatInput);
        pOb->SetData(dp);
      }

      return success;
    }

    obErrorLog.ThrowError(__FUNCTION__,
                          "Problems reading an output file: Could not determine the format of this file. Please report it to the openbabel-discuss @ lists.sourceforge.net mailing list.", obError);
    return(false); // we couldn't figure out the format
  }
Exemple #5
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;
}
Exemple #6
0
bool RXNFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
{
    OBMol* pmol = pOb->CastAndClear<OBMol>();
    if (pmol == NULL)
      return false;

    OBFormat* pMolFormat = pConv->FindFormat("MOL");
    if (pMolFormat==NULL)
      return false;

    istream &ifs = *pConv->GetInStream();
    string ln;
    // When MDLFormat reads the last product it may also read and discard
    // the line with $RXN for the next reaction. But it then sets $RXNread option.
    if(pConv->IsOption("$RXNread"))
      pConv->RemoveOption("$RXNread", OBConversion::OUTOPTIONS);
    else
    {
      if (!getline(ifs,ln))
        return(false);
      if(Trim(ln).find("$RXN")!=0)
        return false; //Has to start with $RXN
    }
    if (!getline(ifs,ln))
      return false; //reaction title
    pmol->SetTitle(Trim(ln));

    if (!getline(ifs,ln))
      return false; //creator
    if (!getline(ifs, ln))
      return false; //comment
    // Originally the comment was added to the reaction via:
    //     pmol->SetComment(Trim(ln));

    if (!getline(ifs, ln))
      return false; // num reactants, products, and optionally agents

    unsigned int nReactants = 0, nProducts = 0, nAgents = 0;
    bool ok = ParseComponent(ln.c_str() + 0, &nReactants);
    if (!ok)
      return false;
    ok = ParseComponent(ln.c_str() + 3, &nProducts);
    if (!ok)
      return false;
    if (ln[6] != '\0') { // optional agents
      ok = ParseComponent(ln.c_str() + 6, &nAgents);
      if (!ok)
        return false;
    }

    if(nReactants + nProducts + nAgents)
    {
      //Read the first $MOL. The others are read at the end of the previous MOL
      if(!getline(ifs, ln))
        return false;
      if(Trim(ln).find("$MOL")==string::npos)
        return false;
    }

    OBReactionFacade rxnfacade(pmol);

    // Note: If we supported it, we could read each of the rxn components directly
    // into the returned OBMol instead of having to do a copy. Unfortunately,
    // this isn't possible at the moment (MOL format will need some work first).
    // Here is some example code to do it:
    //
    //unsigned int old_numatoms = 0;
    //unsigned int compid = 1;
    //for (int i = 0; i<nReactants; i++)
    //{
    //  //Read a MOL file	using the same OBConversion object but with a different format
    //  if (!pMolFormat->ReadMolecule(pmol, pConv))
    //    obErrorLog.ThrowError(__FUNCTION__, "Failed to read a reactant", obWarning);
    //  unsigned int numatoms = pmol->NumAtoms();
    //  for (unsigned int idx = old_numatoms + 1; idx <= numatoms; ++idx) {
    //    OBAtom* atom = pmol->GetAtom(idx);
    //    rxnfacade.SetRole(atom, REACTANT);
    //    rxnfacade.SetComponentId(atom, compid);
    //  }
    //  old_numatoms = numatoms;
    //  compid++;
    //}

    const char* type[3] = {"a reactant", "a product", "an agent"};
    OBReactionRole role;
    unsigned int num_components;
    for(unsigned int N=0; N<3; N++) {
      switch(N) {
      case 0:
        role = REACTANT;
        num_components = nReactants;
        break;
      case 1:
        role = PRODUCT;
        num_components = nProducts;
        break;
      case 2:
        role = AGENT;
        num_components = nAgents;
        break;
      }
      for (int i=0; i<num_components; i++)
      {
        //Read a MOL file	using the same OBConversion object but with a different format
        OBMol mol;
        if (!pMolFormat->ReadMolecule(&mol, pConv)) {
          std::string error = "Failed to read ";
          error += type[N];
          obErrorLog.ThrowError(__FUNCTION__, error, obWarning);
          continue;
        }
        if (mol.NumAtoms() == 0) {
          OBAtom* dummy = mol.NewAtom(); // Treat the empty OBMol as having a single dummy atom
          OBPairData *pd = new OBPairData();
          pd->SetAttribute("rxndummy");
          pd->SetValue("");
          pd->SetOrigin(fileformatInput);
          dummy->SetData(pd);
        }

        rxnfacade.AddComponent(&mol, role);
      }
    }

    pmol->SetIsReaction();
    return true;
}
Exemple #7
0
bool OpSplit::Do(OBBase* pOb, const char* OptionText, OpMap* pOptions, OBConversion* pConv)
{
  if(!strcmp(OptionText, "inactive"))
  {
    ++_inputCount;
    return true;
  }

  if(!pConv)
    return false;
  
    if(pConv->IsFirstInput())
  {
    _inputCount=0;
    _optionText = OptionText; //because gets overwritten by "inactive"
    _pDesc = *OptionText ? OBDescriptor::FindType(OptionText) : NULL;
    _realOutFormat = pConv->GetOutFormat();

    // If there is an output file specified, delete the file,close and invalidate the outstream so OBConversion is not confused.
    std::ofstream* oldfs = dynamic_cast<std::ofstream*>(pConv->GetOutStream());
    if(oldfs && oldfs->is_open())
    {
      oldfs->close();
      oldfs->setstate(std::ios::failbit);
      remove(pConv->GetOutFilename().c_str());
    }

    // If there is an output file name, use its path and its extension for the output files.
    // Otherwise use current directory and the ID of the output format.
    _outExt = _outPath = pConv->GetOutFilename(); //This may not be present yet in OBConversion
    std::string::size_type pos = _outPath.find_last_of("\\/");
    if(pos!=std::string::npos)
      _outPath.erase(pos+1);
    else
      _outPath.clear();
    pos = _outExt.rfind('.');
    if(pos!=std::string::npos)
      _outExt.erase(0, pos+1);
    else
      _outExt = _realOutFormat->GetID();

    /* Need to call this op after all other options because it outputs directly
       rather than letting OBConversion do the writing. Use the trick of
       the op deactivating itself and setting output to DeferredFormat. When this
       is written to, it immediately calls back this function, which writes to
       an individual file of the real output format.
    */
    pConv->AddOption(GetID(),OBConversion::GENOPTIONS,"inactive");//removing messes up DoOps()
    new DeferredFormat(pConv, this, true); //it will delete itself
    return true;
  }

  //The following is called from Deferred Format

  std::ofstream ofs;
  std::stringstream filename;
  filename.str("");
  filename << _outPath;
  std::string name;

  if(!_pDesc && _optionText.empty()) //no param, use title
  {
    const char* pFilename = pOb->GetTitle();
    name = pFilename;
  }
  else if(_pDesc) //use descriptor
  {
    std::string s;
    _pDesc->GetStringValue(pOb, s);
    name = s;
  }
  else //use OBPairData property
  {
    if(pOb->HasData(_optionText))
      name = pOb->GetData(_optionText)->GetValue();
  }

  bool filenameok = !name.empty() && name.find_first_of("/\\:*|?\"") == std::string::npos;
  if(filenameok)
  {
    filename << name << '.' << _outExt;
    std::string fname(filename.str()); //DEBUG
    ofs.open(fname.c_str());
  }
  if(!filenameok || !ofs)
  {
    //filename is empty or contain an illegal character or failed to open. Use "n.xxx"
    obErrorLog.ThrowError(__FUNCTION__,
      "The fallback filename, based on input index, has been used for at least one object.", obWarning, onceOnly);
    std::stringstream ss;
    ss << _outPath << _inputCount << '.' << _outExt;
    ofs.clear();
    if(ofs.is_open())
      ofs.close();
    ofs.open(ss.str().c_str());
    if(!ofs)
    {
      obErrorLog.ThrowError(__FUNCTION__, "Cannot open file " + ss.str(), obError);
       pConv->SetOneObjectOnly(); //stop all conversion
      return false;
    }
  }
  pConv->SetOutStream(&ofs);
  //Output the object now - do not use the normal queue of two.
  _realOutFormat->WriteChemObject(pConv);
  //Correct for second call to GetChemObject(), which increments index, in above.
  //GetChemObject() already called in DeferredFormat
  pConv->SetOutputIndex(pConv->GetOutputIndex()-1);

  ofs.close();
  return false; //do not store anything in DeferredFormat
}
Exemple #8
0
bool OpAlign::Do(OBBase* pOb, const char* OptionText, OpMap* pmap, OBConversion* pConv)
{
  OBMol* pmol = dynamic_cast<OBMol*>(pOb);
  if(!pmol)
    return false;

  map<string,string>::const_iterator itr;

  // Is there an -s option?
  if(pConv->IsFirstInput())
  {
    _pOpIsoM = NULL; //assume no -s option
    itr = pmap->find("s");
    if(itr!=pmap->end())
    {
      //There is an -s option; check it is ok
      _pOpIsoM = static_cast<OpNewS*>(OBOp::FindType("s"));
      _stext = itr->second; //get its parameter(s)
      if(!_pOpIsoM || _stext.empty())
      {
        obErrorLog.ThrowError(__FUNCTION__,
        "No parameter on -s option, or its OBOp version is not loaded", obError);
        pConv->SetOneObjectOnly(); //to finish
        return false;
      }
    }
  }

  // If the output format is a 2D depiction format, then we should align
  // on the 2D coordinates and not the 3D coordinates (if present). This
  //means we need to generate the 2D coordinates at this point.
  if(pmol->GetDimension()==3 && (pConv->GetOutFormat()->Flags() & DEPICTION2D))
  {
    OBOp* pgen = OBOp::FindType("gen2D");
    if(pgen)
      pgen->Do(pmol);
  }

  // All molecules must have coordinates, so add them if 0D
  // They may be added again later when gen2D or gen3D is called, but they will be the same.
  // It would be better if this op was called after them, which would happen
  // if its name was alphabetically after "gen" (and before "s").
  if(pmol->GetDimension()==0)
  {
    //Will the coordinates be 2D or 3D?
    itr = pmap->find("gen3D");
    OBOp* pgen = (itr==pmap->end()) ? OBOp::FindType("gen2D") : OBOp::FindType("gen3D");
    if(pgen)
      pgen->Do(pmol);
  }

  //Do the alignment in 2D if the output format is svg, png etc. and there is no -xn option
  if(pmol->GetDimension()==3 && pConv && !pConv->IsOption("n"))
  {
    OBFormat* pOutFormat = pConv->GetOutFormat();
    if(pOutFormat->Flags() & DEPICTION2D)
    {
      OBOp* pgen = OBOp::FindType("gen2D");
      if(pgen)
        pgen->Do(pmol);
    }
  }

  if(pConv->IsFirstInput() || _refMol.NumAtoms()==0)
  {
    _refvec.clear();
    // Reference molecule is basically the first molecule
    _refMol = *pmol;
    if(!_pOpIsoM)
     //no -s option. Use a molecule reference.
     _align.SetRefMol(_refMol);
    else
    {
      //If there is a -s option, reference molecule has only those atoms that are matched
      //Call the -s option from here
      bool ret = _pOpIsoM->Do(pmol, _stext.c_str(), pmap, pConv);
      // Get the atoms that were matched
      vector<int> ats = _pOpIsoM->GetMatchAtoms();
      if(!ats.empty())
      {
        // Make a vector of the matching atom coordinates...
        for(vector<int>::iterator iter=ats.begin(); iter!=ats.end(); ++iter)
          _refvec.push_back((pmol->GetAtom(*iter))->GetVector());
        // ...and use a vector reference
        _align.SetRef(_refvec);
      }
      // Stop -s option being called normally, although it will still be called once
      //  in the DoOps loop already started for the current (first) molecule.
      pConv->RemoveOption("s",OBConversion::GENOPTIONS);
      if(!ret)
      {
        // the first molecule did not match the -s option so a reference molecule
        // could not be made. Keep trying.
        _refMol.Clear();
        //obErrorLog.ThrowError(__FUNCTION__, "The first molecule did not match the -s option\n"
        //  "so the reference structure was not derived from it", obWarning, onceOnly);
        return false; //not matched
      }
    }
  }

  //All molecules
  if(pmol->GetDimension()!= _refMol.GetDimension())
  {
    stringstream ss;
    ss << "The molecule" << pmol->GetTitle()
       << " does not have the same dimensions as the reference molecule "
       << _refMol.GetTitle() << " and is ignored.";
       obErrorLog.ThrowError(__FUNCTION__, ss.str().c_str(), obError);
    return false;
  }

  if(_pOpIsoM) //Using -s option
  {
    //Ignore mol if it does not pass -s option
    if(!_pOpIsoM->Do(pmol, "", pmap, pConv)) // "" means will use existing parameters
      return false;

    // Get the atoms equivalent to those in ref molecule
    vector<int> ats = _pOpIsoM->GetMatchAtoms();

    // Make a vector of their coordinates and get the centroid
    vector<vector3> vec;
    vector3 centroid;
    for(vector<int>::iterator iter=ats.begin(); iter!=ats.end(); ++iter) {
      vector3 v = pmol->GetAtom(*iter)->GetVector();
      centroid += v;
      vec.push_back(v);
    }
    centroid /= vec.size();

    // Do the alignment
    _align.SetTarget(vec);
    if(!_align.Align())
      return false;

    // Get the centroid of the reference atoms
    vector3 ref_centroid;
    for(vector<vector3>::iterator iter=_refvec.begin(); iter!=_refvec.end(); ++iter)
      ref_centroid += *iter;
    ref_centroid /= _refvec.size();

    //subtract the centroid, rotate the target molecule, then add the centroid
    matrix3x3 rotmatrix = _align.GetRotMatrix();
    for (unsigned int i = 1; i <= pmol->NumAtoms(); ++i)
    {
      vector3 tmpvec = pmol->GetAtom(i)->GetVector();
      tmpvec -= centroid;
      tmpvec *= rotmatrix; //apply the rotation
      tmpvec += ref_centroid;
      pmol->GetAtom(i)->SetVector(tmpvec);
    }
  }
  else //Not using -s option)
  {
    _align.SetTargetMol(*pmol);
    if(!_align.Align())
      return false;
    _align.UpdateCoords(pmol);
  }

  //Save rmsd as a property
  OBPairData* dp = new OBPairData;
  dp->SetAttribute("rmsd");
  double val = _align.GetRMSD();
  if(val<1e-12)
    val = 0.0;
  dp->SetValue(toString(val));
  dp->SetOrigin(local);
  pmol->SetData(dp);

  return true;
}
bool CMLReactFormat::DoElement(const string& name)
{
  double val;

  if(name=="reaction")
  {
    _spmol.reset();
    _preact->SetTitle(_pxmlConv->GetAttribute("id"));
  }

  else if(name=="molecule")
  {
    string reference = _pxmlConv->GetAttribute("ref");
    if(!reference.empty())
    {
      _spmol = IMols[reference];
      pmol = _spmol.get();
      if(!pmol)
      {
        cerr << " Molecule reference \"" << reference <<"\" not found" << endl;
        return false;
      }
    }
    else
    {
      shared_ptr<OBMol> sp(new OBMol);	
      OBFormat* pCMLFormat = OBConversion::FindFormat("cml");
      if(!pCMLFormat)
        return false;
      _pxmlConv->_SkipNextRead=true;
      pCMLFormat->ReadMolecule(sp.get(), _pxmlConv);

      //Store smart pointers to all molecules in map
      _spmol=sp;
      AddMolToList(_spmol,IMols);
    }
  }
  else if(name=="rateParameters")
  {
    _pRD = new OBRateData; //to store rate constant data
   _preact->SetData(_pRD);

    string rt = _pxmlConv->GetAttribute("reactionType");
    OBRateData::reaction_type enumrt=OBRateData::ARRHENIUS;
    if(rt=="arrhenius")       enumrt=OBRateData::ARRHENIUS;
    else if(rt=="lindermann") enumrt=OBRateData::LINDERMANN;
    else if(rt=="troe")       enumrt=OBRateData::TROE;
    else if(rt=="sri")        enumrt=OBRateData::SRI;
    else if(rt=="threeBody")  enumrt=OBRateData::THREEBODY;
    else
      obErrorLog.ThrowError(__FUNCTION__, rt + " is not a known reactionType", obWarning);
    _pRD->ReactionType = enumrt;

    if(_pxmlConv->GetAttribute("reversible")=="true")
      _preact->SetReversible();
  }

  else if(_pRD && name=="A")
  {
    if(_pxmlConv->GetContentDouble(val))
      _pRD->SetRate(OBRateData::A, val);
  }
  else if(_pRD && name=="n")
  {
    if(_pxmlConv->GetContentDouble(val))
      _pRD->SetRate(OBRateData::n, val);
  }
  else if(_pRD && name=="E")
  {
    if(_pxmlConv->GetContentDouble(val))
      _pRD->SetRate(OBRateData::E, val);
  }
  else if(_pRD && name=="loA")
  {
    if(_pxmlConv->GetContentDouble(val))
      _pRD->SetLoRate(OBRateData::A, val);
  }
  else if(_pRD && name=="lon")
  {
    if(_pxmlConv->GetContentDouble(val))
      _pRD->SetLoRate(OBRateData::n, val);
  }
  else if(_pRD && name=="loE")
  {
    if(_pxmlConv->GetContentDouble(val))
      _pRD->SetLoRate(OBRateData::E, val);
  }
  else if(_pRD && name=="troeParams")
  {
    string txt(_pxmlConv->GetContent());
    if(!txt.empty())
    {
      stringstream ss(txt);
      for(int i=0;i<4;++i)
      {
        ss >>val;
        _pRD->SetTroeParams(i, val);
      }
    }
Exemple #10
0
  bool PQSFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
  {

    OBMol* pmol = pOb->CastAndClear<OBMol>();
    if(pmol==NULL)
      return false;

    //Define some references so we can use the old parameter names
    istream &ifs = *pConv->GetInStream();
    OBMol &mol = *pmol;
    const char* title = pConv->GetTitle();

    char buffer[BUFF_SIZE];
    char coord_file[256];
    char full_coord_path[256]="\0";
    ifstream coordFileStream;
    double bohr_to_angstrom=1.0;
    unsigned int input_style, atom_count=0; //CM i removed
    bool geom_found;

    geom_found=false;
    while (!geom_found && ifs.getline(buffer,BUFF_SIZE))
      {
        lowerit(buffer);      //look for geom except in title or text
        if (strstr(buffer,"geom")!=NULL &&
            (strncmp(buffer,"text",4)!=0 && strncmp(buffer,"titl",4)!=0))
          {
            geom_found=true;
            lowerit(buffer);

            if (strstr(buffer,"bohr")!=NULL)
              bohr_to_angstrom=0.529177249;
            else
              bohr_to_angstrom=1.0;
            input_style=0;
            if (strstr(buffer,"=tx90")!=NULL)
              input_style=1;
            if (strstr(buffer,"=tx92")!=NULL)
              input_style=0;
            if (strstr(buffer,"=pqs" )!=NULL)
              input_style=0;

            if (strstr(buffer,"file=")!=NULL)
              {  //external geometry file
                strncpy(coord_file,strstr(buffer,"file=")+5, sizeof(coord_file));
                coord_file[sizeof(coord_file) - 1] = '\0';
                if (strrchr(coord_file,' ')!=NULL)
                  *strrchr(coord_file,' ')='\0';
                if (coord_file[0]!='/')
                  {
                    strncpy(full_coord_path,title, sizeof(full_coord_path));
                    full_coord_path[sizeof(full_coord_path)-1] = '\0';
                    if (strrchr(full_coord_path,'/')!=NULL)
                      *(strrchr(full_coord_path,'/')+1)='\0';
                    else
                      full_coord_path[0] = '\0';
                  }
                strcat(full_coord_path,coord_file);
                full_coord_path[sizeof(full_coord_path) - 1] = '\0';
                stringstream errorMsg;
                errorMsg <<"External geometry file referenced: "<< \
                  full_coord_path<<endl;
                obErrorLog.ThrowError(__FUNCTION__, errorMsg.str(), obInfo);

                coordFileStream.open(full_coord_path);
                if (!coordFileStream)
                  {
                    obErrorLog.ThrowError(__FUNCTION__, "Cannot read external geometry file!", obError);
                    return(false);
                    //                    exit (-1);
                  }
                else
                  {
                    ifs.seekg(0, ios::end); //move .inp file pointer to the end of file

                    //New framework mods
                    OBConversion coordconv(&coordFileStream);
                    OBFormat* pFormat;
                    if (strstr(buffer,"=car" )!=NULL)
                      pFormat =OBConversion::FindFormat("BIOSYM");
                    if (strstr(buffer,"=hin" )!=NULL)
                      pFormat = OBConversion::FindFormat("HIN");
                    if (strstr(buffer,"=pdb" )!=NULL)
                      pFormat = OBConversion::FindFormat("PDB");
                    if (strstr(buffer,"=mop" )!=NULL)
                      pFormat = OBConversion::FindFormat("MOPAC");
                    return pFormat->ReadMolecule(&mol,&coordconv);

                    /*         if (strstr(buffer,"=car" )!=NULL)
                               return ReadBiosymCAR(coordFileStream, mol, title);
                               if (strstr(buffer,"=hin" )!=NULL)
                               return ReadHIN(coordFileStream, mol, title);
                               if (strstr(buffer,"=pdb" )!=NULL)
                               return ReadPDB(coordFileStream, mol, title);
                               if (strstr(buffer,"=mop" )!=NULL)
                               return ReadMOPAC(coordFileStream, mol, title);
                    */
                    //end new framework mods

                    //probably pqs's own xyz format
                    atom_count=ReadPQS_geom(coordFileStream,mol,title,
                                            input_style,bohr_to_angstrom);
                  }
              }
          }
      }

    if (geom_found)
      {
        if (atom_count==0)        //read directly form .inp file
          atom_count=ReadPQS_geom(ifs,mol,title,input_style,bohr_to_angstrom);
        if (atom_count==0)
          {   //try .coord file
            strncpy(coord_file,title, sizeof(coord_file));
            coord_file[sizeof(coord_file) - 1] = '\0';
            if (strrchr(coord_file,'.')!=NULL)
              *strrchr(coord_file,'.')='\0';
            strcat(coord_file,".coord");
            coordFileStream.open(coord_file);
            if (!coordFileStream)
              {
                stringstream errorMsg;
                errorMsg <<"ReadPQS: cannot read external "<<coord_file<<" file!"<<endl;
                obErrorLog.ThrowError(__FUNCTION__, errorMsg.str(), obError);
                return(false);
                //                exit (-1);
              }
            else
              atom_count=ReadPQS_geom(coordFileStream,mol,title,0,
                                      bohr_to_angstrom);
          }
      }
    else
      obErrorLog.ThrowError(__FUNCTION__, "Error reading PQS file.  GEOM card not found!", obWarning);

    ifs.seekg(0, ios::end); //move .inp file pointer to the end of file
    if (atom_count>0)
      return true;
    else
      return false;
  }
Exemple #11
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;
}