Example #1
0
bool OpExtraOut::Do(OBBase* pOb, const char* OptionText, OpMap* pmap, OBConversion* pConv)
{
  /*
    OptionText contains an output filename with a format extension.
    Make an OBConversion object with this as output destination.
    Make a copy the current OBConversion and replace the output format by
    an instance of ExtraFormat. This then does all the subsequent work.
  */
  if(!pConv || !OptionText || *OptionText=='\0')
    return true; //silent no-op. false would prevent the main output

  if(pConv->IsFirstInput())
  {
    OBConversion* pExtraConv = new OBConversion(*pConv); //copy ensures OBConversion::Index>-1
    std::ofstream* ofs;
    if( (ofs = new std::ofstream(OptionText)) ) // extra parens to indicate truth value
      pExtraConv->SetOutStream(ofs);
    if(!ofs || !pExtraConv->SetOutFormat(OBConversion::FormatFromExt(OptionText)))
    {
      obErrorLog.ThrowError(__FUNCTION__, "Error setting up extra output file", obError);
      return true;
    }
    OBConversion* pOrigConv = new OBConversion(*pConv);

    //Make an instance of ExtraFormat and divert the output to it. It will delete itself.
    pConv->SetOutFormat(new ExtraFormat(pOrigConv, pExtraConv));
  }
  return true;
}
Example #2
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;
  }