Exemple #1
0
  unsigned int OBRing::GetRootAtom()
  {
    vector<int>::iterator i;
    OBMol *mol = (OBMol*)GetParent();

    //if (!IsAromatic())
    //  return 0;

    if (Size() == 6)
      for (i = _path.begin();i != _path.end();++i)
        if (mol->GetAtom(*i)->GetAtomicNum() != OBElements::Carbon)
	        return (*i);

    if (Size() == 5)
      for (i = _path.begin();i != _path.end();++i) {
        OBAtom *atom = mol->GetAtom(*i);
        switch (atom->GetAtomicNum()) {
        case OBElements::Sulfur:
          if (atom->GetValence() == 2)
            return (*i);
          break;
        case OBElements::Oxygen:
          if (atom->GetValence() == 2)
            return (*i);
          break;
        case OBElements::Nitrogen:
          if (atom->BOSum() == atom->GetValence())
            return (*i);
          break;
        }
      }

    return 0;
  }
Exemple #2
0
  unsigned int OBRing::GetRootAtom()
  {
    vector<int>::iterator i;
    OBMol *mol = (OBMol*)GetParent();

    //if (!IsAromatic())
    //  return 0;

    if (Size() == 6)
      for (i = _path.begin();i != _path.end();++i)
        if (!(mol->GetAtom(*i))->IsCarbon())
	  return (*i);
    
    if (Size() == 5)
      for (i = _path.begin();i != _path.end();++i) {
        OBAtom *atom = mol->GetAtom(*i);
        if (atom->IsSulfur() && (atom->GetValence() == 2))
	  return (*i);
        if (atom->IsOxygen() && (atom->GetValence() == 2))
	  return (*i);
        if (atom->IsNitrogen() && (atom->BOSum() == atom->GetValence()))
	  return (*i);
      }
      
    return 0;
  }
Exemple #3
0
  void OBAtomTyper::AssignImplicitValence(OBMol &mol)
  {
    // FF Make sure that valence has not been perceived
    if(mol.HasImplicitValencePerceived())
      return;

    if (!_init)
      Init();

    mol.SetImplicitValencePerceived();
    obErrorLog.ThrowError(__FUNCTION__,
                          "Ran OpenBabel::AssignImplicitValence", obAuditMsg);

    // FF Ensure that the aromatic typer will not be called
    int oldflags = mol.GetFlags(); // save the current state flags
    mol.SetAromaticPerceived();    // and set the aromatic perceived flag on

    OBAtom *atom;
    vector<OBAtom*>::iterator k;
    for (atom = mol.BeginAtom(k);atom;atom = mol.NextAtom(k))
      atom->SetImplicitValence(atom->GetValence());

    vector<vector<int> >::iterator j;
    vector<pair<OBSmartsPattern*,int> >::iterator i;

    for (i = _vimpval.begin();i != _vimpval.end();++i)
      if (i->first->Match(mol))
        {
          _mlist = i->first->GetMapList();
          for (j = _mlist.begin();j != _mlist.end();++j)
            mol.GetAtom((*j)[0])->SetImplicitValence(i->second);
        }

    if (!mol.HasAromaticCorrected())
      CorrectAromaticNitrogens(mol);

    for (atom = mol.BeginAtom(k);atom;atom = mol.NextAtom(k))
      {
        if (atom->GetImplicitValence() < atom->GetValence())
          atom->SetImplicitValence(atom->GetValence());
      }

    // FF Come back to the initial flags
    mol.SetFlags(oldflags);

    return;
  }
Exemple #4
0
bool WriteHIN(ostream &ofs,OBMol &mol)
{
  unsigned int i, file_num = 1;
  string str,str1;
  char buffer[BUFF_SIZE];
  OBAtom *atom;
  OBBond *bond;
  vector<OBEdgeBase*>::iterator j;
  char bond_char;

  ofs << "mol " << file_num << " " << mol.GetTitle() << endl;;
  for(i = 1;i <= mol.NumAtoms(); i++)
  {
    atom = mol.GetAtom(i);
    sprintf(buffer,"atom %d - %-3s **  - %8.5f %8.5f  %8.5f  %8.5f %d ",
	    i,
	    etab.GetSymbol(atom->GetAtomicNum()),
	    atom->GetPartialCharge(),
	    atom->GetX(),
	    atom->GetY(),
	    atom->GetZ(),
	    atom->GetValence());
    ofs << buffer;
    for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j))
    {
      switch(bond->GetBO())
      {
      case 1 : bond_char = 's'; break;
      case 2 : bond_char = 'd'; break;
      case 3 : bond_char = 't'; break;
      case 5 : bond_char = 'a'; break;
      default: bond_char = 's'; break;
      }
      sprintf(buffer,"%d %c ", (bond->GetNbrAtom(atom))->GetIdx(), bond_char);
      ofs << buffer;
    }
    ofs << endl;
  }
  ofs << "endmol " << file_num << endl;
  return(true);
}
Exemple #5
0
  bool PDBFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
  {
    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
    if(pmol==NULL)
      return false;

    //Define some references so we can use the old parameter names
    ostream &ofs = *pConv->GetOutStream();
    OBMol &mol = *pmol;

    unsigned int i;
    char buffer[BUFF_SIZE];
    char type_name[10], padded_name[10];
    char the_res[10];
    char the_chain = ' ';
    const char *element_name;
    int res_num;
    bool het=true;
    int model_num = 0;
    if (!pConv->IsLast() || pConv->GetOutputIndex() > 1)
      { // More than one molecule record
        model_num = pConv->GetOutputIndex(); // MODEL 1-based index
        snprintf(buffer, BUFF_SIZE, "MODEL %8d", model_num);
        ofs << buffer << endl;
      }

    // write back all fields (REMARKS, HELIX, SHEET, SITE, ...)
    bool compndWritten = false;
    bool authorWritten = false;
    std::vector<OBGenericData*> pairData = mol.GetAllData(OBGenericDataType::PairData);
    for (std::vector<OBGenericData*>::iterator data = pairData.begin(); data != pairData.end(); ++data) {
      OBPairData *pd = static_cast<OBPairData*>(*data);
      string attr = pd->GetAttribute();

      // filter to make sure we are writing pdb fields only
      if (attr != "HEADER" && attr != "OBSLTE" && attr != "TITLE" && attr != "SPLIT" &&
          attr != "CAVEAT" && attr != "COMPND" && attr != "SOURCE" && attr != "KEYWDS" &&
          attr != "EXPDTA" && attr != "NUMMDL" && attr != "MDLTYP" && attr != "AUTHOR" &&
          attr != "REVDAT" && attr != "SPRSDE" && attr != "JRNL" && attr != "REMARK" &&
          attr != "DBREF" && attr != "DBREF1" && attr != "DBREF2" && attr != "SEQADV" &&
          attr != "SEQRES" && attr != "MODRES" && attr != "HET" && attr != "HETNAM" &&
          attr != "HETSYN" && attr != "FORMUL" && attr != "HELIX" && attr != "SHEET" &&
          attr != "SSBOND" && attr != "LINK" && attr != "CISPEP" && attr != "SITE" &&
          attr != "ORIGX1" && attr != "ORIGX2" && attr != "ORIGX3" && attr != "SCALE1" &&
          attr != "SCALE2" && attr != "SCALE3" && attr != "MATRIX1" && attr != "MATRIX2" &&
          attr != "MATRIX3" && attr != "MODEL")
        continue;

      if (attr == "COMPND")
        compndWritten = true;
      if (attr == "AUTHOR")
        authorWritten = true;

      // compute spacing needed. HELIX, SITE, HET, ... are trimmed when reading
      int nSpacing = 6 - attr.size();
      for (int i = 0; i < nSpacing; ++i)
        attr += " ";


      std::string lines = pd->GetValue();
      string::size_type last = 0;
      string::size_type pos = lines.find('\n');
      while (last != string::npos) {
        string line = lines.substr(last, pos - last);
        if (pos == string::npos)
          last = string::npos;
        else
          last = pos + 1;
        pos = lines.find('\n', last);

        ofs << attr << line << endl;
      }
    }

    if (!compndWritten) {
      if (strlen(mol.GetTitle()) > 0)
        snprintf(buffer, BUFF_SIZE, "COMPND    %s ",mol.GetTitle());
      else
        snprintf(buffer, BUFF_SIZE, "COMPND    UNNAMED");
      ofs << buffer << endl;
    }

    if (!authorWritten) {
      snprintf(buffer, BUFF_SIZE, "AUTHOR    GENERATED BY OPEN BABEL %s",BABEL_VERSION);
      ofs << buffer << endl;
    }

    // Write CRYST1 record, containing unit cell parameters, space group
    // and Z value (supposed to be 1)
    if (pmol->HasData(OBGenericDataType::UnitCell))
      {
        OBUnitCell *pUC = (OBUnitCell*)pmol->GetData(OBGenericDataType::UnitCell);
        if(pUC->GetSpaceGroup()){
          string tmpHM=pUC->GetSpaceGroup()->GetHMName();
          // Do we have an extended HM symbol, with origin choice as ":1" or ":2" ? If so, remove it.
          size_t n=tmpHM.find(":");
          if(n!=string::npos) tmpHM=tmpHM.substr(0,n);
          snprintf(buffer, BUFF_SIZE,
                   "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1",
                   pUC->GetA(), pUC->GetB(), pUC->GetC(),
                   pUC->GetAlpha(), pUC->GetBeta(), pUC->GetGamma(),
                   tmpHM.c_str());
        }
        else
          snprintf(buffer, BUFF_SIZE,
                   "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1",
                   pUC->GetA(), pUC->GetB(), pUC->GetC(),
                   pUC->GetAlpha(), pUC->GetBeta(), pUC->GetGamma(),
                   "P1");

        ofs << buffer << endl;
      }

    // before we write any records, we should check to see if any coord < -1000
    // which will cause errors in the formatting

    double minX, minY, minZ;
    minX = minY = minZ = -999.0f;
    FOR_ATOMS_OF_MOL(a, mol)
      {
        if (a->GetX() < minX)
          minX = a->GetX();
        if (a->GetY() < minY)
          minY = a->GetY();
        if (a->GetZ() < minZ)
          minZ = a->GetZ();
      }
    vector3 transV = VZero;
    if (minX < -999.0)
      transV.SetX(-1.0*minX - 900.0);
    if (minY < -999.0)
      transV.SetY(-1.0*minY - 900.0);
    if (minZ < -999.0)
      transV.SetZ(-1.0*minZ - 900.0);

    // if minX, minY, or minZ was never changed, shift will be 0.0f
    // otherwise, move enough so that smallest coord is > -999.0f
    mol.Translate(transV);

    OBAtom *atom;
    OBResidue *res;
    for (i = 1; i <= mol.NumAtoms(); i++)
      {
        atom = mol.GetAtom(i);
        strncpy(type_name, etab.GetSymbol(atom->GetAtomicNum()), sizeof(type_name));
        type_name[sizeof(type_name) - 1] = '\0';

        //two char. elements are on position 13 and 14 one char. start at 14
        if (strlen(type_name) > 1)
          type_name[1] = toupper(type_name[1]);
        else
          {
            char tmp[10];
            strncpy(tmp, type_name, 9); // make sure to null-terminate tmp
            snprintf(type_name, sizeof(type_name), " %-3s", tmp);
          }

        if ( (res = atom->GetResidue()) != 0 )
          {
            het = res->IsHetAtom(atom);
            snprintf(the_res,4,"%s",(char*)res->GetName().c_str());
            the_res[4] = '\0';
            snprintf(type_name,5,"%s",(char*)res->GetAtomID(atom).c_str());
            the_chain = res->GetChain();

            //two char. elements are on position 13 and 14 one char. start at 14
            if (strlen(etab.GetSymbol(atom->GetAtomicNum())) == 1)
              {
                if (strlen(type_name) < 4)
                  {
                    char tmp[10];
                    strncpy(tmp, type_name, 9); // make sure to null-terminate tmp
                    snprintf(padded_name, sizeof(padded_name), " %-3s", tmp);
                    strncpy(type_name,padded_name,4);
                    type_name[4] = '\0';
                  }
                else
                  {
                    /*
                      type_name[4] = type_name[3];
                      type_name[3] = type_name[2];
                      type_name[2] = type_name[1];
                      type_name[1] = type_name[0];
                      type_name[0] = type_name[4];
                    */
                    type_name[4] = '\0';
                  }
              }
            res_num = res->GetNum();
          }
        else
          {
            strcpy(the_res,"UNK");
            the_res[3] = '\0';
            snprintf(padded_name,sizeof(padded_name), "%s",type_name);
            strncpy(type_name,padded_name,4);
            type_name[4] = '\0';
            res_num = 1;
          }

        element_name = etab.GetSymbol(atom->GetAtomicNum());

        int charge = atom->GetFormalCharge();
        char scharge[3] = { ' ', ' ', '\0' };
        if(0 != charge)
          {
            snprintf(scharge, 3, "%+d", charge);
            char tmp = scharge[1];
            scharge[1] = scharge[0];
            scharge[0] = tmp;
          }
        snprintf(buffer, BUFF_SIZE, "%s%5d %-4s %-3s %c%4d    %8.3f%8.3f%8.3f  1.00  0.00          %2s%2s\n",
                 het?"HETATM":"ATOM  ",
                 i,
                 type_name,
                 the_res,
                 the_chain,
                 res_num,
                 atom->GetX(),
                 atom->GetY(),
                 atom->GetZ(),
                 element_name,
                 scharge);
        ofs << buffer;
      }

    OBAtom *nbr;
    vector<OBBond*>::iterator k;
    for (i = 1; i <= mol.NumAtoms(); i ++)
      {
        atom = mol.GetAtom(i);
        if (atom->GetValence() == 0)
          continue; // no need to write a CONECT record -- no bonds

        snprintf(buffer, BUFF_SIZE, "CONECT%5d", i);
        ofs << buffer;
        // Write out up to 4 real bonds per line PR#1711154
        int currentValence = 0;
        for (nbr = atom->BeginNbrAtom(k);nbr;nbr = atom->NextNbrAtom(k))
          {
            snprintf(buffer, BUFF_SIZE, "%5d", nbr->GetIdx());
            ofs << buffer;
            if (++currentValence % 4 == 0) {
              // Add the trailing space to finish this record
              ofs << "                                       \n";
              // write the start of a new CONECT record
              snprintf(buffer, BUFF_SIZE, "CONECT%5d", i);
              ofs << buffer;
            }
          }

        // Add trailing spaces
        int remainingValence = atom->GetValence() % 4;
        for (int count = 0; count < (4 - remainingValence); count++) {
          snprintf(buffer, BUFF_SIZE, "     ");
          ofs << buffer;
        }
        ofs << "                                       \n";
      }

    snprintf(buffer, BUFF_SIZE, "MASTER        0    0    0    0    0    0    0    0 ");
    ofs << buffer;
    snprintf(buffer, BUFF_SIZE, "%4d    0 %4d    0\n",mol.NumAtoms(),mol.NumAtoms());
    ofs << buffer;

    ofs << "END\n";
    if (model_num) {
      ofs << "ENDMDL" << endl;
    }

    return(true);
  }
Exemple #6
0
  bool BGFFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
  {
    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
    if(pmol==NULL)
      return false;

    //Define some references so we can use the old parameter names
    ostream &ofs = *pConv->GetOutStream();
    OBMol &mol = *pmol;

    vector<OBAtom*>::iterator i;
    int max_val;
    OBAtom *atom;
    char buffer[BUFF_SIZE];
    char elmnt_typ[8], dreid_typ[8], atm_sym[16], max_val_str[8];

    mol.Kekulize();

    ofs << "BIOGRF 200\n";
    snprintf(buffer, BUFF_SIZE, "DESCRP %s\n",mol.GetTitle());
    ofs << buffer;
    snprintf(buffer, BUFF_SIZE, "REMARK BGF file created by Open Babel %s\n",BABEL_VERSION);
    ofs << "FORCEFIELD DREIDING  \n";

    // write unit cell if available
    if (mol.HasData(OBGenericDataType::UnitCell))
      {
        OBUnitCell *uc = (OBUnitCell*)mol.GetData(OBGenericDataType::UnitCell);
        // e.g. CRYSTX    49.30287   49.23010   25.45631   90.00008   89.99995   57.10041
        snprintf(buffer, BUFF_SIZE,
                 "CRYSTX%12.5f%12.5f%12.5f%12.5f%12.5f%12.5f",
                 uc->GetA(), uc->GetB(), uc->GetC(),
                 uc->GetAlpha() , uc->GetBeta(), uc->GetGamma());
        ofs << buffer << "\n";
      }

    ofs << "FORMAT ATOM   (a6,1x,i5,1x,a5,1x,a3,1x,a1,1x,a5,3f10.5,1x,a5,i3,i2,1x,f8.5)\n";

    ttab.SetFromType("INT");

    for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
      {
        strncpy(elmnt_typ,etab.GetSymbol(atom->GetAtomicNum()), 7); // make sure to null-terminate
        elmnt_typ[sizeof(elmnt_typ) - 1] = '0';
        ToUpper(elmnt_typ);

        ttab.SetToType("DRE");
        ttab.Translate(dreid_typ,atom->GetType());
        ttab.SetToType("HAD");
        ttab.Translate(max_val_str,atom->GetType());
        max_val = atoi(max_val_str);
        if (max_val == 0)
          max_val = 1;
        snprintf(atm_sym,16,"%s%d",elmnt_typ,atom->GetIdx());
        snprintf(buffer,BUFF_SIZE,"%6s %5d %-5s %3s %1s %5s%10.5f%10.5f%10.5f %-5s%3d%2d %8.5f\n",
                "HETATM",
                atom->GetIdx(),
                atm_sym,
                "RES",
                "A",
                "444",
                atom->GetX(),
                atom->GetY(),
                atom->GetZ(),
                dreid_typ,
                max_val,
                0,
                atom->GetPartialCharge());
        ofs << buffer;
      }
    ofs<< "FORMAT CONECT (a6,12i6)\n\n";

    OBAtom *nbr;
    vector<OBBond*>::iterator j;
    for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
      if (atom->GetValence())
        {
          snprintf(buffer,BUFF_SIZE,"CONECT%6d",atom->GetIdx());
          ofs << buffer;
          for (nbr = atom->BeginNbrAtom(j);nbr;nbr = atom->NextNbrAtom(j))
            {
              snprintf(buffer,BUFF_SIZE,"%6d",nbr->GetIdx());
              ofs << buffer;
            }
          ofs << endl;

          snprintf(buffer,BUFF_SIZE,"ORDER %6d",atom->GetIdx());
          ofs << buffer;
          for (nbr = atom->BeginNbrAtom(j);nbr;nbr = atom->NextNbrAtom(j))
            {
              snprintf(buffer,BUFF_SIZE,"%6d",(*j)->GetBO());
              ofs << buffer;
            }
          ofs << endl;
        }

    ofs << "END" << endl;
    return(true);
  }
Exemple #7
0
  bool OBDepict::DrawMolecule(OBMol *mol)
  {
    if (!d->painter)
      return false;

    d->mol = mol;

    double width=0.0, height=0.0;

    OBAtom *atom;
    OBBondIterator j;
    OBAtomIterator i;

    if(mol->NumAtoms()>0) {
      // scale bond lengths
      double bondLengthSum = 0.0;
      for (OBBond *bond = mol->BeginBond(j); bond; bond = mol->NextBond(j))
        bondLengthSum += bond->GetLength();
      const double averageBondLength = bondLengthSum / mol->NumBonds();
      const double f = mol->NumBonds() ? d->bondLength / averageBondLength : 1.0;
      for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i))
        atom->SetVector(atom->GetX() * f, atom->GetY() * f, 0.0);

      // find min/max values
      double min_x, max_x;
      double min_y, max_y;
      atom = mol->BeginAtom(i);
      min_x = max_x = atom->GetX();
      min_y = max_y = atom->GetY();
      for (atom = mol->NextAtom(i); atom; atom = mol->NextAtom(i)) {
        min_x = std::min(min_x, atom->GetX());
        max_x = std::max(max_x, atom->GetX());
        min_y = std::min(min_y, atom->GetY());
        max_y = std::max(max_y, atom->GetY());
      }

      const double margin = 40.0;
      // translate all atoms so the bottom-left atom is at margin,margin
      for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i))
        atom->SetVector(atom->GetX() - min_x + margin, atom->GetY() - min_y + margin, 0.0);

      width  = max_x - min_x + 2*margin;
      height = max_y - min_y + 2*margin;
      
      //d->painter->SetPenWidth(d->penWidth);
      //d->painter->SetPenColor(d->pen));
      //d->painter->SetFillColor(OBColor("black"));
    }

    d->painter->NewCanvas(width, height);
    
    // draw bonds
    if(d->options & genWedgeHash)
      d->SetWedgeAndHash(mol);
    for (OBBond *bond = mol->BeginBond(j); bond; bond = mol->NextBond(j)) {
      OBAtom *begin = bond->GetBeginAtom();
      OBAtom *end = bond->GetEndAtom();

      if((d->options & internalColor) && bond->HasData("color"))
        d->painter->SetPenColor(OBColor(bond->GetData("color")->GetValue()));
      else
        d->painter->SetPenColor(d->bondColor);

      if (bond->IsWedge()) {
        d->DrawWedge(begin, end);
      } else if (bond->IsHash()) {
        d->DrawHash(begin, end);
      } else if (!bond->IsInRing()) {
        d->DrawSimpleBond(begin, end, bond->GetBO());
      }
    }
    
    // draw ring bonds
    std::vector<OBRing*> rings(mol->GetSSSR());
    OBBitVec drawnBonds;
    for (std::vector<OBRing*>::iterator k = rings.begin(); k != rings.end(); ++k) {
      OBRing *ring = *k;
      std::vector<int> indexes = ring->_path;
      vector3 center(VZero);
      for (std::vector<int>::iterator l = indexes.begin(); l != indexes.end(); ++l) {
        center += mol->GetAtom(*l)->GetVector();        
      }
      center /= indexes.size();

      for (unsigned int l = 0; l < indexes.size(); ++l) {
        OBAtom *begin = mol->GetAtom(indexes[l]);
        OBAtom *end;
        if (l+1 < indexes.size())
          end = mol->GetAtom(indexes[l+1]);
        else
          end = mol->GetAtom(indexes[0]);

        OBBond *ringBond = mol->GetBond(begin, end);
        if (drawnBonds.BitIsSet(ringBond->GetId()))
          continue;

        if((d->options & internalColor) && ringBond->HasData("color"))
          d->painter->SetPenColor(OBColor(ringBond->GetData("color")->GetValue()));
        else
          d->painter->SetPenColor(d->bondColor);

        d->DrawRingBond(begin, end, center, ringBond->GetBO());
        drawnBonds.SetBitOn(ringBond->GetId());
      }

    }

    // draw atom labels
    for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) {
      double x = atom->GetX();
      double y = atom->GetY();

      int alignment = GetLabelAlignment(atom);
      bool rightAligned = false;
      switch (alignment) {
        case TopRight:
        case CenterRight:
        case BottomRight:
          rightAligned = true;
        default:
          break;
      }

      if((d->options & internalColor) && atom->HasData("color"))
        d->painter->SetPenColor(OBColor(atom->GetData("color")->GetValue()));
      else if(d->options & bwAtoms)
        d->painter->SetPenColor(d->bondColor);
      else
        d->painter->SetPenColor(OBColor(etab.GetRGB(atom->GetAtomicNum())));

      //charge and radical
      int charge = atom->GetFormalCharge();
      int spin = atom->GetSpinMultiplicity();
      if(charge || spin) {
        OBFontMetrics metrics = d->painter->GetFontMetrics("N");
        double yoffset = d->HasLabel(atom) ? 0.4 * metrics.height : 0.0;
        switch (GetLabelAlignment(atom)) {
          case TopCenter:
          case TopRight:
          case TopLeft:
          case CenterLeft:
          case CenterRight:
            yoffset = - 1.2 * metrics.height;
        }
        stringstream ss;
        if(charge) {
          if(abs(charge)!=1)
            ss << abs(charge);
          ss << (charge>0 ? "+" : "-") ;
        }
        if(spin) {
          ss << (spin==2 ? "." : "..");
          yoffset += 0.5 * metrics.height;
        }
        if(spin || charge<0)
          d->painter->SetFontSize(2 * metrics.fontSize);
        d->painter->DrawText(x-0.4*metrics.width, y-yoffset, ss.str());
        d->painter->SetFontSize(metrics.fontSize);//restore
      }
 
      if (atom->IsCarbon()) { 
        if(!(d->options & drawAllC))
        {
          if (atom->GetValence() > 1)
            continue;
          if ((atom->GetValence() == 1) && !(d->options & drawTermC))//!d->drawTerminalC)
            continue;
        }
      }

      stringstream ss;
      AliasData* ad = NULL;
      if(d->aliasMode && atom->HasData(AliasDataType))
        ad = static_cast<AliasData*>(atom->GetData(AliasDataType));
      
      //For unexpanded aliases use appropriate form of alias instead of element symbol, Hs, etc
      if(ad && !ad->IsExpanded())
      {
        ss <<ad->GetAlias(rightAligned);
        OBColor aliasColor = !ad->GetColor().empty() ? ad->GetColor() : d->bondColor; 
          d->painter->SetPenColor(aliasColor);
      }
      else {
        const char* atomSymbol;
        if(atom->IsHydrogen() && atom->GetIsotope()>1)
          atomSymbol = atom->GetIsotope()==2 ? "D" : "T";
        else
          atomSymbol = etab.GetSymbol(atom->GetAtomicNum());

        unsigned int hCount = atom->ImplicitHydrogenCount();
        // rightAligned:  
        //   false  CH3
        //   true   H3C
        if (hCount && rightAligned)
          ss << "H";
        if ((hCount > 1) && rightAligned)
          ss << hCount;
        ss << atomSymbol;
        if (hCount && !rightAligned)
          ss << "H";
        if ((hCount > 1) && !rightAligned)
          ss << hCount;
      }
      d->DrawAtomLabel(ss.str(), alignment, vector3(x, y, 0.0));
    }

    return true;
  }
Exemple #8
0
  bool HINFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
  {
    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
    if(pmol==NULL)
      return false;

    //Define some references so we can use the old parameter names
    ostream &ofs = *pConv->GetOutStream();
    OBMol &mol = *pmol;

    unsigned int i, file_num = 1;
    string str,str1;
    char buffer[BUFF_SIZE];
    OBAtom *atom;
    OBBond *bond;
    vector<OBBond*>::iterator j;
    char bond_char;

    // make sure to escape titles in double quotes
    // PR#1501694
    ofs << "mol " << file_num << " \"" << mol.GetTitle() << "\"\n";

    for(i = 1;i <= mol.NumAtoms(); i++)
      {
        atom = mol.GetAtom(i);
        snprintf(buffer, BUFF_SIZE, "atom %d - %-3s **  - %8.5f %8.5f  %8.5f  %8.5f %d ",
                i,
                etab.GetSymbol(atom->GetAtomicNum()),
                atom->GetPartialCharge(),
                atom->GetX(),
                atom->GetY(),
                atom->GetZ(),
                atom->GetValence());
        ofs << buffer;
        for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j))
          {
            switch(bond->GetBO())
              {
              case 1 :
                bond_char = 's';
                break;
              case 2 :
                bond_char = 'd';
                break;
              case 3 :
                bond_char = 't';
                break;
              case 5 :
                bond_char = 'a';
                break;
              default:
                bond_char = 's';
                break;
              }
            if (bond->IsAromatic())
              bond_char = 'a';

            snprintf(buffer,BUFF_SIZE, "%d %c ", (bond->GetNbrAtom(atom))->GetIdx(), bond_char);
            ofs << buffer;
          }
        ofs << endl;
      }
    ofs << "endmol " << file_num << endl;
    return(true);
  }
Exemple #9
0
  bool OBCisTransStereo::IsOnSameAtom(unsigned long id1, unsigned long id2) const
  {
    const OBMol *mol = GetMolecule();
    if (!mol) {
      obErrorLog.ThrowError(__FUNCTION__, "OBCisTransStereo::IsOnSameAtom : No valid molecule set", obError);
      return false;
    }

    OBAtom *begin = mol->GetAtomById(m_cfg.begin);
    if (!begin) {
      obErrorLog.ThrowError(__FUNCTION__, "OBCisTransStereo::IsOnSameAtom : Begin reference id is not valid.", obError);
      return false;
    }
    OBAtom *end = mol->GetAtomById(m_cfg.end);
    if (!end) {
      obErrorLog.ThrowError(__FUNCTION__, "OBCisTransStereo::IsOnSameAtom : End reference id is not valid.", obError);
      return false;
    }

    OBAtom *a = mol->GetAtomById(id1);
    OBAtom *b = mol->GetAtomById(id2);

    if (a && b) {
      // both on begin atom?
      if (a->IsConnected(begin) && b->IsConnected(begin))
          return true;
      // both on end atom?
      if (a->IsConnected(end) && b->IsConnected(end))
          return true;
      return false;
    } else {
      if (a) {
        // b atom not found, could be a deleted hydrogen...
        if (a->IsConnected(begin)) {
          // a is connected to begin. if this is the atom missing a hydrogen, return false
          if (begin->GetValence() == 2)
            return true;
          // check if the end atom really is missing an atom
          if (end->GetValence() != 2) {
            obErrorLog.ThrowError(__FUNCTION__,
                "OBCisTransStereo::IsOnSameAtom : id2 is not valid and is not a missing hydrogen.", obError);
            return false;
          }
          // inform user we are treating id2 as deleted hydrogen
          obErrorLog.ThrowError(__FUNCTION__,
              "OBCisTransStereo::IsOnSameAtom : Atom with id2 doesn't exist anymore, must be a (deleted) hydrogen.", obInfo);
        } else if (a->IsConnected(end)) {
          // a is connected to end. again, if this is the atom missing a hydrogen, return false
          if (end->GetValence() == 2)
            return true;
          // check if the begin atom really is missing an atom
          if (begin->GetValence() != 2) {
            obErrorLog.ThrowError(__FUNCTION__,
                "OBCisTransStereo::IsOnSameAtom : id2 is not valid and is not a missing hydrogen.", obError);
            return true;
          }
          // inform user we are treating id2 as deleted hydrogen
          obErrorLog.ThrowError(__FUNCTION__,
              "OBCisTransStereo::IsOnSameAtom : Atom with id2 doesn't exist, must be a (deleted) hydrogen.", obInfo);

        } else {
          obErrorLog.ThrowError(__FUNCTION__,
              "OBCisTransStereo::IsOnSameAtom : Atom with id1 isn't connected to the begin or end atom.", obError);
          return true;
        }
      } else if (b) {
        // a atom not found, could be a deleted hydrogen...
        if (b->IsConnected(begin)) {
          // b is connected to begin. if this is the atom missing a hydrogen, return false
          if (begin->GetValence() == 2)
            return true;
          // check if the end atom really is missing an atom
          if (end->GetValence() != 2) {
            obErrorLog.ThrowError(__FUNCTION__,
                "OBCisTransStereo::IsOnSameAtom : id1 is not valid and is not a missing hydrogen.", obError);
            return true;
          }
          // inform user we are treating id1 as deleted hydrogen
          obErrorLog.ThrowError(__FUNCTION__,
              "OBCisTransStereo::IsOnSameAtom : Atom with id1 doesn't exist, must be a (deleted) hydrogen.", obInfo);
        } else if (b->IsConnected(end)) {
          // a is connected to end. again, if this is the atom missing a hydrogen, return false
          if (end->GetValence() == 2)
            return true;
          // check if the begin atom really is missing an atom
          if (begin->GetValence() != 2) {
            obErrorLog.ThrowError(__FUNCTION__,
                "OBCisTransStereo::IsOnSameAtom : id1 is not valid and is not a missing hydrogen.", obError);
            return true;
          }
          // inform user we are treating id2 as deleted hydrogen
          obErrorLog.ThrowError(__FUNCTION__,
              "OBCisTransStereo::IsOnSameAtom : Atom with id1 doesn't exist, must be a (deleted) hydrogen.", obInfo);
        } else {
          obErrorLog.ThrowError(__FUNCTION__,
              "OBCisTransStereo::IsOnSameAtom : Atom with id1 isn't connected to the begin or end atom.", obError);
          return true;
        }
      } else {
        OBAtom *c = 0, *d = 0;
        // no a & b, check the remaining ids which will reveal same info
        for (int i = 0; i < 4; ++i) {
          if ((m_cfg.refs.at(i) == id1) || (m_cfg.refs.at(i) == id2))
            continue;
          if (!c) {
            c = mol->GetAtomById(m_cfg.refs.at(i));
          } else {
            d = mol->GetAtomById(m_cfg.refs.at(i));
          }
        }
        if (!c || !d) {
          obErrorLog.ThrowError(__FUNCTION__, "OBCisTransStereo::IsOnSameAtom : invalid stereochemistry!", obError);
          return true;
        }
        if ((begin->GetValence() != 2) || (end->GetValence() != 2)) {
          obErrorLog.ThrowError(__FUNCTION__, "OBCisTransStereo::IsOnSameAtom : invalid stereochemistry!", obError);
          return true;
        }
        obErrorLog.ThrowError(__FUNCTION__,
            "OBCisTransStereo::IsOnSameAtom : Atoms with id1 & id2 don't exist, must be a (deleted) hydrogens.", obInfo);
        return IsOnSameAtom(c->GetId(), d->GetId());
      }
    }

    return false;
  }
Exemple #10
0
  int SetMM3Type(OBAtom *atom)
  {
    OBAtom *b; // neighbor
    OBBondIterator i, j;
    int countNeighborO, countNeighborS, countNeighborN, countNeighborC;
    countNeighborO = countNeighborS = countNeighborN = countNeighborC = 0;

    // The MM2 typing isn't very good, so we do this ourselves for the most common atom types
    switch (atom->GetAtomicNum()) {
    case 1: // Hydrogen
      b = atom->BeginNbrAtom(j);
      if (b->IsCarboxylOxygen())
        return 24;
      if (b->GetAtomicNum() == OBElements::Sulfur)
        return 44;
      if (b->GetAtomicNum() == OBElements::Nitrogen) {
        if (b->IsAmideNitrogen())
          return 28;
        if (b->GetValence() > 3)
          return 48;// ammonium
        return 23; // default amine/imine
      }
      if (b->GetAtomicNum() == OBElements::Carbon && b->GetHyb() == 1)
        return 124; // acetylene

      if (b->GetAtomicNum() == OBElements::Oxygen) {
        if (b->HasAlphaBetaUnsat())
          return 73; // includes non-enol/phenol, but has the right spirit
        return 21; // default alcohol
      }

      return 5; // default H
      break;

    case 2: // Helium
      return 51; break;
    case 3: // Li
      return 163; break;

    case 5: // B
      if (atom->GetValence() >= 4)
        return 27; // tetrahedral
      return 26; break;

    case 6: // C
      if (atom->IsInRingSize(3)) { // cyclopropane / cyclopropene
        if (atom->GetHyb() == 3)
          return 22;
        if (atom->GetHyb() == 2) {
          if (atom->CountFreeOxygens() == 1) // propanone
            return 67;
          return 38; // propane
        }
      }
      if (atom->IsInRingSize(4)) { // cyclobutane or cyclobutene
        if (atom->GetHyb() == 3)
          return 56;
        if (atom->GetHyb() == 2) {
          if (atom->CountFreeOxygens() == 1) // butanone
            return 58;
          return 57; // regular cyclobutane
        }
      }

      if (atom->CountBondsOfOrder(2) == 2) { // allene
        if (atom->CountFreeOxygens() == 1) // ketene
          return 106;
        return 68;
      }

      if (atom->GetFormalCharge() == +1)
        return 30;
      if (atom->GetSpinMultiplicity() == 2)
        return 29;

      if (atom->GetHyb() == 3)
        return 1;
      else if (atom->GetHyb() == 2) {
        if (atom->CountFreeOxygens() >= 1)
          return 3;
        return 2;
      }
      else if (atom->GetHyb() == 1)
        return 4;
      break;

    case 7: // N
      // TODO
      if (atom->IsAmideNitrogen())
        return 151;
      if (atom->IsAromatic()) {
        if (atom->GetFormalCharge() == 1)
          return 111;
        if (atom->IsInRingSize(5)) // pyrrole
          return 40;
        if (atom->IsInRingSize(6)) // pyridine
          return 37;
      }

      if (atom->CountFreeOxygens() == 2) // nitro
        return 46;

      if (atom->GetHyb() == 3) {
        if (atom->GetValence() > 3)
          return 39; // ammonium
        return 8;
      }
      else if (atom->GetHyb() == 2)
        return 9;
      else if (atom->GetHyb() == 1)
        return 10;
      break;

    case 8: // O
      //TODO
      if (atom->IsPhosphateOxygen())
        return 159;
      if (atom->IsCarboxylOxygen())
        return 75;
      if (atom->IsInRingSize(3))
        return 49; // epoxy

      b = atom->BeginNbrAtom(j);
      if (atom->HasBondOfOrder(2) && b->GetAtomicNum() == OBElements::Carbon) { // O=C
        return 7;
      }

      if (atom->IsAromatic())
        return 41; // furan
      return 6;
      break;

    case 9: // F
      return 11; break;
    case 10: // Ne
      return 52; break;
    case 12: // Mg
      return 59; break;
    case 14: // Si
      return 19; break;

    case 15: // P
      if (atom->CountFreeOxygens() > 0)
        return 153; // phosphate
      if (atom->BOSum() > 3)
        return 60; // phosphorus V
      return 25; break;

    case 16: // S
      if (atom->IsAromatic())
        return 42; // thiophene
      if (atom->GetFormalCharge() == 1)
        return 16; // sulfonium

    // look at the neighbors
    for (b = atom->BeginNbrAtom(j); b; b = atom->NextNbrAtom(j))
      {
        switch (b->GetAtomicNum()) {
        case 6:
          if (b->GetHyb() == 2) // S=C
            countNeighborC++; break;
        case 7:
          countNeighborN++; break;
        case 8:
          if (b->GetHvyValence() == 1)
            countNeighborO++;
          break;
        case 16:
          countNeighborS++; break;
        default:
          continue;
        }
      }

      if (countNeighborO == 1)
        return 17; // sulfoxide
      if (countNeighborO >= 2) {
        if (countNeighborN)
          return 154; // sulfonamide
        return 18; // sulfone or sulfate
      }
      if (countNeighborC)
        return 74; // S=C
      if (countNeighborS == 1)
        return 104; // S-S disulfide
      else if (countNeighborS > 1)
        return 105;

      return 15; break;

    case 17: // Cl
      return 12; break;
    case 18: // Ar
      return 153; break;
    case 20: // Ca
      return 125; break;
    case 26: // Fe
      if (atom->GetFormalCharge() == 2)
        return 61;
      return 62; break;
    case 27: // Co
      if (atom->GetFormalCharge() == 2)
        return 65;
      return 66; break;
    case 28: // Ni
      if (atom->GetFormalCharge() == 2)
        return 63;
      return 64; break;

    case 32: // Ge
      return 31; break;
    case 34: // Se
      return 34; break;
    case 35: // Br
      return 13; break;
    case 36: // Kr
      return 54; break;
    case 38: // Sr
      return 126; break;
    case 50: // Sn
      return 32; break;
    case 52: // Te
      return 35; break;
    case 53: // I
      return 14; break;
    case 54: // Xe
      return 55; break;

    case 56: // Ba
      return 127; break;
    case 57:
      return 128; break;
    case 58:
      return 129; break;
    case 59:
      return 130; break;
    case 60:
      return 131; break;
    case 61:
      return 132; break;
    case 62:
      return 133; break;
    case 63:
      return 134; break;
    case 64:
      return 135; break;
    case 65:
      return 136; break;
    case 66:
      return 137; break;
    case 67:
      return 138; break;
    case 68:
      return 139; break;
    case 69:
      return 140; break;
    case 70:
      return 141; break;
    case 71:
      return 142; break;

    case 82: // Pb
      return 33; break;


    default:
      break;
    }
    return 0;
  }
  bool PDBFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
  {
    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
    if(pmol==NULL)
      return false;

    //Define some references so we can use the old parameter names
    ostream &ofs = *pConv->GetOutStream();
    OBMol &mol = *pmol;

    unsigned int i;
    char buffer[BUFF_SIZE];
    char type_name[10], padded_name[10];
    char the_res[10];
    char the_chain = ' ';
    const char *element_name;
    int res_num;
    bool het=true;
    int model_num = 0;
    if (!pConv->IsLast() || pConv->GetOutputIndex() > 1)
      { // More than one molecule record
        model_num = pConv->GetOutputIndex(); // MODEL 1-based index
        snprintf(buffer, BUFF_SIZE, "MODEL %8d", model_num);
        ofs << buffer << endl;
      }

    if (strlen(mol.GetTitle()) > 0)
      snprintf(buffer, BUFF_SIZE, "COMPND    %s ",mol.GetTitle());
    else
      snprintf(buffer, BUFF_SIZE, "COMPND    UNNAMED");
    ofs << buffer << endl;

    snprintf(buffer, BUFF_SIZE, "AUTHOR    GENERATED BY OPEN BABEL %s",BABEL_VERSION);
    ofs << buffer << endl;

    // Write CRYST1 record, containing unit cell parameters, space group
    // and Z value (supposed to be 1)
    if (pmol->HasData(OBGenericDataType::UnitCell))
      {
        OBUnitCell *pUC = (OBUnitCell*)pmol->GetData(OBGenericDataType::UnitCell);
	
        snprintf(buffer, BUFF_SIZE,
                 "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s 1",
                 pUC->GetA(), pUC->GetB(), pUC->GetC(),
                 pUC->GetAlpha(), pUC->GetBeta(), pUC->GetGamma(),
                 pUC->GetSpaceGroup() ?
                 pUC->GetSpaceGroup()->GetHMName().c_str() : "P1");
        ofs << buffer << endl;
      }

    // before we write any records, we should check to see if any coord < -1000
    // which will cause errors in the formatting

    double minX, minY, minZ;
    minX = minY = minZ = -999.0f;
    FOR_ATOMS_OF_MOL(a, mol)
      {
        if (a->GetX() < minX)
          minX = a->GetX();
        if (a->GetY() < minY)
          minY = a->GetY();
        if (a->GetZ() < minZ)
          minZ = a->GetZ();
      }
    vector3 transV = VZero;
    if (minX < -999.0)
      transV.SetX(-1.0*minX - 900.0);
    if (minY < -999.0)
      transV.SetY(-1.0*minY - 900.0);
    if (minZ < -999.0)
      transV.SetZ(-1.0*minZ - 900.0);

    // if minX, minY, or minZ was never changed, shift will be 0.0f
    // otherwise, move enough so that smallest coord is > -999.0f
    mol.Translate(transV);

    OBAtom *atom;
    OBResidue *res;
    for (i = 1; i <= mol.NumAtoms(); i++)
      {
        atom = mol.GetAtom(i);
        strncpy(type_name, etab.GetSymbol(atom->GetAtomicNum()), sizeof(type_name));
        type_name[sizeof(type_name) - 1] = '\0';

        //two char. elements are on position 13 and 14 one char. start at 14
        if (strlen(type_name) > 1)
          type_name[1] = toupper(type_name[1]);
        else
          {
            char tmp[10];
            strncpy(tmp, type_name, 10);
            snprintf(type_name, sizeof(type_name), " %-3s", tmp);
          }

        if ( (res = atom->GetResidue()) != 0 )
          {
            het = res->IsHetAtom(atom);
            snprintf(the_res,4,"%s",(char*)res->GetName().c_str());
            snprintf(type_name,5,"%s",(char*)res->GetAtomID(atom).c_str());
            the_chain = res->GetChain();

            //two char. elements are on position 13 and 14 one char. start at 14
            if (strlen(etab.GetSymbol(atom->GetAtomicNum())) == 1)
              {
                if (strlen(type_name) < 4)
                  {
                    char tmp[16];
                    strncpy(tmp, type_name, 16);
                    snprintf(padded_name, sizeof(padded_name), " %-3s", tmp);
                    strncpy(type_name,padded_name,4);
                    type_name[4] = '\0';
                  }
                else
                  {
                    /*
                      type_name[4] = type_name[3];
                      type_name[3] = type_name[2];
                      type_name[2] = type_name[1];
                      type_name[1] = type_name[0];
                      type_name[0] = type_name[4];
                    */
                    type_name[4] = '\0';
                  }
              }
            res_num = res->GetNum();
          }
        else
          {
            strcpy(the_res,"UNK");
            snprintf(padded_name,sizeof(padded_name), "%s",type_name);
            strncpy(type_name,padded_name,4);
            type_name[4] = '\0';
            res_num = 1;
          }

        element_name = etab.GetSymbol(atom->GetAtomicNum());
        
        int charge = atom->GetFormalCharge();
        char scharge[3] = { ' ', ' ', '\0' };
        if(0 != charge)
          {
            snprintf(scharge, 3, "%+d", charge);
            char tmp = scharge[1];
            scharge[1] = scharge[0];
            scharge[0] = tmp;
          }
        snprintf(buffer, BUFF_SIZE, "%s%5d %-4s %-3s %c%4d    %8.3f%8.3f%8.3f  1.00  0.00          %2s%2s\n",
                 het?"HETATM":"ATOM  ",
                 i,
                 type_name,
                 the_res,
                 the_chain,
                 res_num,
                 atom->GetX(),
                 atom->GetY(),
                 atom->GetZ(),
                 element_name,
                 scharge);
        ofs << buffer;
      }

    OBAtom *nbr;
    vector<OBBond*>::iterator k;
    for (i = 1; i <= mol.NumAtoms(); i ++)
      {
        atom = mol.GetAtom(i);
        if (atom->GetValence() == 0)
          continue; // no need to write a CONECT record -- no bonds

        snprintf(buffer, BUFF_SIZE, "CONECT%5d", i);
        ofs << buffer;
        // Write out up to 4 real bonds per line PR#1711154
        unsigned int currentValence = 0;
        for (nbr = atom->BeginNbrAtom(k);nbr;nbr = atom->NextNbrAtom(k))
          {
            unsigned int order = mol.GetBond(atom, nbr)->GetBondOrder();
            unsigned int it_order = 0;
            for( it_order = 0; it_order < order; it_order++ )
              {
                if (0 != currentValence && 0 == currentValence % 4)
                  {
                    // Add the trailing space to finish this record
                    ofs << "                                       \n";
                    // write the start of a new CONECT record
                    snprintf(buffer, BUFF_SIZE, "CONECT%5d", i);
                    ofs << buffer;              
                  }
                currentValence++;
                snprintf(buffer, BUFF_SIZE, "%5d", nbr->GetIdx());
                ofs << buffer;
              }
          }

        // Add trailing spaces
        unsigned int remainingValence = currentValence % 4;
        if( 0 < remainingValence )
          {
            for (int count = 0; count < (4 - remainingValence); count++) 
              {
                snprintf(buffer, BUFF_SIZE, "     ");
                ofs << buffer;
              }
          }
        ofs << "                                                 \n";
      }

    snprintf(buffer, BUFF_SIZE, "MASTER        0    0    0    0    0    0    0    0 ");
    ofs << buffer;
    snprintf(buffer, BUFF_SIZE, "%4d    0 %4d    0\n",mol.NumAtoms(),mol.NumAtoms());
    ofs << buffer;

    ofs << "END\n";
    if (model_num) {
      ofs << "ENDMDL" << endl;
    }

    return(true);
  }