コード例 #1
0
ファイル: xyz.cpp プロジェクト: daju1/winlibghemical
bool WriteXYZ(ostream &ofs,OBMol &mol)
{
  unsigned int i;
  char buffer[BUFF_SIZE];
  
  sprintf(buffer,"%d", mol.NumAtoms());
  ofs << buffer << endl;
  sprintf(buffer,"%s\tEnergy: %15.7f", mol.GetTitle(), mol.GetEnergy());
  ofs << buffer << endl;

  OBAtom *atom;
  string str,str1;
  for(i = 1;i <= mol.NumAtoms(); i++)
  {
    atom = mol.GetAtom(i);
    sprintf(buffer,"%3s%15.5f%15.5f%15.5f",
	    etab.GetSymbol(atom->GetAtomicNum()),
	    atom->GetX(),
	    atom->GetY(),
	    atom->GetZ());
    ofs << buffer << endl;
  }

  return(true);
}
コード例 #2
0
ファイル: PQSformat.cpp プロジェクト: Reinis/openbabel
  bool PQSFormat::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];
    OBAtom *atom;
    ofs<<"TEXT="<<mol.GetTitle()<<endl;
    ofs<<"GEOM=PQS"<<endl;
    for (i=1; i<=mol.NumAtoms(); i++)
      {
        atom=mol.GetAtom(i);
        snprintf(buffer, BUFF_SIZE, "%s           %10.6lf   %10.6lf   %10.6lf",
                OBElements::GetSymbol(atom->GetAtomicNum()),
                atom->GetX(),
                atom->GetY(),
                atom->GetZ());
        ofs<<buffer<<endl;
      }
    return(true);
  }
コード例 #3
0
ファイル: viewmol.cpp プロジェクト: daju1/winlibghemical
bool WriteViewMol(ostream &ofs,OBMol &mol)
{
  unsigned int i;
  char buffer[BUFF_SIZE];
  
  if (strlen(mol.GetTitle()) > 0)
    ofs << "$title" << endl << mol.GetTitle() << endl;

  ofs << "$coord 1.0" << endl;

  OBAtom *atom;
  for(i = 1;i <= mol.NumAtoms(); i++)
  {
    atom = mol.GetAtom(i);
    sprintf(buffer,"%22.14f%22.14f%22.14f %s",
	    atom->GetX(),
	    atom->GetY(),
	    atom->GetZ(),
	    etab.GetSymbol(atom->GetAtomicNum()));
    ofs << buffer << endl;
  }

  ofs << "$end" << endl;

  return(true);

}
コード例 #4
0
ファイル: turbomoleformat.cpp プロジェクト: Reinis/openbabel
bool TurbomoleFormat::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;
    double UnitConv=AAU;
    if(pConv->IsOption("a"))
      UnitConv=1;

    ofs << "$coord" <<endl;

    char buffer[BUFF_SIZE];
    OBAtom *atom;
    vector<OBAtom*>::iterator i;
    for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
    {
      char symb[8];
      strcpy(symb,OBElements::GetSymbol(atom->GetAtomicNum()));
        snprintf(buffer, BUFF_SIZE, "%20.14f  %20.14f  %20.14f      %s",
                atom->GetX()/UnitConv,
                atom->GetY()/UnitConv,
                atom->GetZ()/UnitConv,
                strlwr(symb) );
        ofs << buffer << endl;
    }
    ofs << "$end" << endl;

    return true;
}
コード例 #5
0
ファイル: ring.cpp プロジェクト: arkose/openbabel
  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;
  }
コード例 #6
0
ファイル: jaguarformat.cpp プロジェクト: annulen/openbabel
  bool JaguarInputFormat::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];
    OBAtom *atom;

    ofs << mol.GetTitle() << endl << endl;
    ofs << "&gen" << endl;
    ofs << "&" << endl;
    ofs << "&zmat" << endl;

    for (i = 1;i <= mol.NumAtoms(); i++)
      {
        atom = mol.GetAtom(i);
        snprintf(buffer, BUFF_SIZE, "  %s%d   %12.7f  %12.7f  %12.7f",
                 etab.GetSymbol(atom->GetAtomicNum()), i,
                 atom->GetX(),
                 atom->GetY(),
                 atom->GetZ());
        ofs << buffer << endl;
      }

    ofs << "&" << endl;
    return(true);
  }
コード例 #7
0
ファイル: finger2.cpp プロジェクト: arkose/openbabel
void fingerprint2::getFragments(vector<int> levels, vector<int> curfrag,
					int level, OBAtom* patom, OBBond* pbond)
{
	//Recursive routine to analyse schemical structure and populate fragset and ringset
	//Hydrogens,charges(except dative bonds), spinMultiplicity ignored
	const int Max_Fragment_Size = 7;
	int bo=0;
	if(pbond)
	{
		bo = pbond->IsAromatic() ? 5 : pbond->GetBO();

//		OBAtom* pprevat = pbond->GetNbrAtom(patom);
//		if(patom->GetFormalCharge() && (patom->GetFormalCharge() == -pprevat->GetFormalCharge()))
//			++bo; //coordinate (dative) bond eg C[N+]([O-])=O is seen as CN(=O)=O
	}
	curfrag.push_back(bo);
	curfrag.push_back(patom->GetAtomicNum());
	levels[patom->GetIdx()-1] = level;

	vector<OBEdgeBase*>::iterator itr;
	OBBond *pnewbond;
//	PrintFpt(curfrag,(int)patom);
	for (pnewbond = patom->BeginBond(itr);pnewbond;pnewbond = patom->NextBond(itr))
	{
		if(pnewbond==pbond) continue; //don't retrace steps
		OBAtom* pnxtat = pnewbond->GetNbrAtom(patom);
		if(pnxtat->GetAtomicNum() == OBElements::Hydrogen) continue;

		int atlevel = levels[pnxtat->GetIdx()-1];
		if(atlevel) //ring
		{
			if(atlevel==1)
			{
				//If complete ring (last bond is back to starting atom) add bond at front
				//and save in ringset
				curfrag[0] = pnewbond->IsAromatic() ? 5 : pnewbond->GetBO();
				ringset.insert(curfrag);
 				curfrag[0] = 0;
			}
		}
		else //no ring
		{
			if(level<Max_Fragment_Size)
			{
//				TRACE("level=%d size=%d %p frag[0]=%p\n",level, curfrag.size(),&curfrag, &(curfrag[0]));
				//Do the next atom; levels, curfrag are passed by value and hence copied
				getFragments(levels, curfrag, level+1, pnxtat, pnewbond);
			}
		}
	}

	//do not save C,N,O single atom fragments
	if(curfrag[0]==0 &&
		(level>1 || patom->GetAtomicNum()>8  || patom->GetAtomicNum()<6))
	{
		fragset.insert(curfrag); //curfrag ignored if an identical fragment already present
//		PrintFpt(curfrag,level);
	}
}
コード例 #8
0
ファイル: rxnformat.cpp プロジェクト: fredrikw/openbabel
static void WriteMolFile(OBMol* pmol, OBConversion* pconv, OBFormat* pformat)
{
  ostream &ofs = *pconv->GetOutStream();
  ofs << "$MOL" << '\n';
  // Treat a dummy atom with "rxndummy" as the empty file
  if (pmol->NumAtoms() == 1) {
    OBAtom *atm = pmol->GetFirstAtom();
    if (atm->GetAtomicNum() == 0 && atm->HasData("rxndummy"))
      pmol->DeleteAtom(atm);
  }
  pformat->WriteMolecule(pmol, pconv);
}
コード例 #9
0
ファイル: gromos96.cpp プロジェクト: daju1/winlibghemical
bool WriteGromos96(ostream &ofs,OBMol &mol,double fac)
{ 
  char type_name[10];
  char res_name[10],padded_name[10];
  char buffer[BUFF_SIZE];
  int res_num;

  sprintf(buffer,"#GENERATED BY OPEN BABEL %s",BABEL_VERSION);
  ofs << buffer << endl;

  /* GROMOS wants a TITLE block, so let's write one*/
  sprintf(buffer,"TITLE\n%s\nEND",mol.GetTitle());
  ofs << buffer << endl;
  ofs << "POSITION" << endl;

  OBAtom *atom;
  OBResidue *res;
  vector<OBNodeBase*>::iterator i;

  for(atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
    {
      if (res = atom->GetResidue())
	{
	  strcpy(res_name,(char*)res->GetName().c_str());
	  strcpy(type_name,(char*)res->GetAtomID(atom).c_str());
	  res_num = res->GetNum();
	}
      else
	{
	  strcpy(type_name,etab.GetSymbol(atom->GetAtomicNum()));
	  strcpy(res_name,"UNK");
	  sprintf(padded_name,"%2s",type_name);
	  strcpy(type_name,padded_name);
	  res_num = 1;
	}
      
      sprintf(buffer,"%5d %5s %5s %6d %15.5f %15.5f %15.5f",
	      res_num,res_name,type_name,atom->GetIdx(),
	      atom->x()*fac,atom->y()*fac,atom->z()*fac);
      ofs << buffer << endl;

      if (!(atom->GetIdx()%10))
      {
	sprintf(buffer,"# %d",atom->GetIdx());
	ofs << buffer << endl;
      }
    }

  ofs << "END" << endl;

  return(true);
}
コード例 #10
0
void ChemDrawXMLFormat::EnsureEndElement(void)
{
    if (_tempAtom.GetAtomicNum() != 0)
    {
        _pmol->AddAtom(_tempAtom);
        atoms[_tempAtom.GetIdx()] = _pmol->NumAtoms();
        _tempAtom.Clear();
    }
    else if (Order >= 0)
    {
        _pmol->AddBond(Begin, End, Order, Flag);
        Order = -1;
    }
}
コード例 #11
0
ファイル: report.cpp プロジェクト: daju1/winlibghemical
  void WriteCharges(ostream &ofs,OBMol &mol)
  {
    unsigned int i;
    OBAtom *atom;
    char buffer[BUFF_SIZE];
    
    for(i = 1;i <= mol.NumAtoms(); i++)
      {
	atom = mol.GetAtom(i);
	sprintf(buffer,"%4s%4d   % 2.10f",
		etab.GetSymbol(atom->GetAtomicNum()),
		i,
		atom->GetPartialCharge());
	
	ofs << buffer << endl;
      }
  }
コード例 #12
0
ファイル: reportformat.cpp プロジェクト: Reinis/openbabel
  void ReportFormat::WriteCharges(ostream &ofs,OBMol &mol)
  {
    unsigned int i;
    OBAtom *atom;
    char buffer[BUFF_SIZE];

    for(i = 1;i <= mol.NumAtoms(); i++)
      {
        atom = mol.GetAtom(i);
        snprintf(buffer, BUFF_SIZE, "%4s%4d   % 2.10f",
                OBElements::GetSymbol(atom->GetAtomicNum()),
                i,
                atom->GetPartialCharge());

        ofs << buffer << "\n";
      }
  }
コード例 #13
0
ファイル: report.cpp プロジェクト: daju1/winlibghemical
  void WriteChiral(ostream &ofs,OBMol &mol)
  {
    OBAtom *atom;
    vector<OBNodeBase*>::iterator i;
    char buffer[BUFF_SIZE];

    for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
      {
	if (atom->IsChiral())
	  {
	    sprintf(buffer,"%4s %5d is chiral: %s",
		    etab.GetSymbol(atom->GetAtomicNum()),
		    atom->GetIdx(),
		    (atom->IsClockwise() ? "clockwise" : "counterclockwise"));
	
	    ofs << buffer << endl;
	  }
      }
  }
コード例 #14
0
ファイル: cacaoformat.cpp プロジェクト: annulen/openbabel
  bool CacaoFormat::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;

    OBAtom *atom;
    char buffer[BUFF_SIZE];
    vector<OBAtom*>::iterator i;

    snprintf(buffer, BUFF_SIZE, "%s\n",mol.GetTitle());
    ofs << buffer;
    snprintf(buffer, BUFF_SIZE, "%3d   DIST  0  0  0\n",mol.NumAtoms());
    ofs << buffer;

    if (!mol.HasData(OBGenericDataType::UnitCell))
      ofs << "CELL 1.,1.,1.,90.,90.,90.\n";
    else
      {
        OBUnitCell *uc = (OBUnitCell*)mol.GetData(OBGenericDataType::UnitCell);
        snprintf(buffer, BUFF_SIZE, "CELL %f,%f,%f,%f,%f,%f\n",
                 uc->GetA(), uc->GetB(), uc->GetC(),
                 uc->GetAlpha(), uc->GetBeta(), uc->GetGamma());
        ofs << buffer;
      }

    for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
      {
        snprintf(buffer,BUFF_SIZE,"%2s %7.4f, %7.4f, %7.4f\n",
                 etab.GetSymbol(atom->GetAtomicNum()),
                 atom->x(),
                 atom->y(),
                 atom->z());
        ofs << buffer;
      }

    return(true);
  }
コード例 #15
0
ファイル: finger2.cpp プロジェクト: arkose/openbabel
bool fingerprint2::GetFingerprint(OBBase* pOb, vector<unsigned int>&fp, int nbits)
{
	OBMol* pmol = dynamic_cast<OBMol*>(pOb);
	if(!pmol) return false;
	fp.resize(1024/Getbitsperint());
	fragset.clear();//needed because now only one instance of fp class
	ringset.clear();
 
	//identify fragments starting at every atom
	OBAtom *patom;
	vector<OBNodeBase*>::iterator i;
	for (patom = pmol->BeginAtom(i);patom;patom = pmol->NextAtom(i))
	{
		if(patom->GetAtomicNum() == OBElements::Hydrogen) continue;
		vector<int> curfrag;
		vector<int> levels(pmol->NumAtoms());
		getFragments(levels, curfrag, 1, patom, NULL);
	}

//	TRACE("%s %d frags before; ",pmol->GetTitle(),fragset.size());

	//Ensure that each chemically identical fragment is present only in a single
	DoRings();
	DoReverses();

	SetItr itr;
  _ss.str("");
	for(itr=fragset.begin();itr!=fragset.end();++itr)
	{
		//Use hash of fragment to set a bit in the fingerprint
		int hash = CalcHash(*itr);
		SetBit(fp,hash);
		if(!(Flags() & FPT_NOINFO))
      PrintFpt(*itr,hash);
	}
	if(nbits)
		Fold(fp, nbits);

//	TRACE("%d after\n",fragset.size());
	return true;
}
コード例 #16
0
ファイル: hin.cpp プロジェクト: daju1/winlibghemical
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);
}
コード例 #17
0
ファイル: feat.cpp プロジェクト: daju1/winlibghemical
bool WriteFeat(ostream &ofs,OBMol &mol)
{ 
  char buffer[BUFF_SIZE];
  
  ofs << mol.NumAtoms() << endl;
  ofs << mol.GetTitle() << endl;

  OBAtom *atom;
  vector<OBNodeBase*>::iterator i;
  for(atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
  {
    sprintf(buffer,"%-3s %8.5f  %8.5f  %8.5f ",
	    etab.GetSymbol(atom->GetAtomicNum()),
	    atom->x(),
	    atom->y(),
	    atom->z());
    ofs << buffer << endl;
  }

  return(true);
}
コード例 #18
0
ファイル: povrayformat.cpp プロジェクト: candycode/openbabel
  void OutputAtoms(ostream &ofs, OBMol &mol, string prefix)
  {
    /* ---- Write all coordinates ---- */
    ofs << "//Coodinates of atoms 1 - " << mol.NumAtoms() << endl;
    unsigned int i;
    for(i = 1; i <= mol.NumAtoms(); ++i)
      {

        /* ---- Get a pointer to ith atom ---- */
        OBAtom *atom = mol.GetAtom(i);

        /* ---- Write position of atom i ---- */
        ofs << "#declare " << prefix << "_pos_" << i << " = <"
            << atom -> GetX() << ","
            << atom -> GetY() << ","
            << atom -> GetZ()
            << ">;" << endl;

      }

    /* ---- Write povray-description of all atoms ---- */
    ofs << endl << "//Povray-description of atoms 1 - " << mol.NumAtoms() << endl;
    for(i = 1; i <= mol.NumAtoms(); ++i)
      {

        /* ---- Get a pointer to ith atom ---- */
        OBAtom *atom = mol.GetAtom(i);

        /* ---- Write full description of atom i ---- */
        ofs << "#declare " << prefix << "_atom" << i << " = ";
        ofs << "object {" << endl
            << "\t  Atom_" << etab.GetSymbol(atom->GetAtomicNum()) << endl
            << "\t  translate " << prefix << "_pos_" << i << endl << "\t }" << endl;

      }

    /* ---- Add empty line ---- */
    ofs << endl;

  }
コード例 #19
0
//copy data needed to write out pmol from obmol
void PMolCreator::copyFrom(OBMol& mol, bool deleteH)
{
	static OBIsotopeTable isotable;

	name = mol.GetTitle();
	//first construct atoms
	int typeindex[256]; //position in atoms vector of an atom type, indexed by atomic number
	int tmpatomindex[mol.NumAtoms()]; //position within the atom type vector
	memset(typeindex, -1, sizeof(typeindex));
	memset(tmpatomindex, -1, sizeof(tmpatomindex));


	for (OBAtomIterator aitr = mol.BeginAtoms(); aitr != mol.EndAtoms(); ++aitr)
	{
		OBAtom *atom = *aitr;
		unsigned int idx = atom->GetIdx();
		unsigned anum = atom->GetAtomicNum();
		assert(anum < 256);
		if(deleteH && anum == 1)
			continue;
		int pos = typeindex[anum];
		if (pos < 0) // no vector for this type yet
		{
			pos = typeindex[anum] = atoms.size();
			atoms.push_back(AtomGroup(anum));
		}

		tmpatomindex[idx] = atoms[pos].coords.size();
		atoms[pos].coords.push_back(FloatCoord(atom->x(), atom->y(), atom->z()));
	}
	//create mapping to actual atom index
	numAtoms = 0;
	BOOST_FOREACH(AtomGroup& ag, atoms)
	{	ag.startIndex = numAtoms;
		numAtoms += ag.coords.size();
	}
コード例 #20
0
ファイル: tinkerformat.cpp プロジェクト: Reinis/openbabel
  bool TinkerFormat::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;
    bool mm2Types = false;
    bool mmffTypes = pConv->IsOption("m",OBConversion::OUTOPTIONS) != NULL;
    bool mm3Types = pConv->IsOption("3",OBConversion::OUTOPTIONS) != NULL;
    bool classTypes = pConv->IsOption("c", OBConversion::OUTOPTIONS) != NULL;

    unsigned int i;
    char buffer[BUFF_SIZE];
    OBBond *bond;
    vector<OBBond*>::iterator j;

    // Before we try output of MMFF94 atom types, check if it works
    OBForceField *ff = OpenBabel::OBForceField::FindForceField("MMFF94");
    if (mmffTypes && ff && ff->Setup(mol))
      mmffTypes = ff->GetAtomTypes(mol);
    else
      mmffTypes = false; // either the force field isn't available, or it doesn't work

    if (!mmffTypes && !mm3Types && !classTypes) {
      snprintf(buffer, BUFF_SIZE, "%6d %-20s   MM2 parameters\n",mol.NumAtoms(),mol.GetTitle());
      mm2Types = true;
    }
    else if (mm3Types)
      snprintf(buffer, BUFF_SIZE, "%6d %-20s   MM3 parameters\n",mol.NumAtoms(),mol.GetTitle());
    else if (classTypes)
      snprintf(buffer, BUFF_SIZE, "%6d %-20s   Custom parameters\n",mol.NumAtoms(),mol.GetTitle());
    else
      snprintf(buffer, BUFF_SIZE, "%6d %-20s   MMFF94 parameters\n",mol.NumAtoms(),mol.GetTitle());
    ofs << buffer;

    ttab.SetFromType("INT");

    OBAtom *atom;
    string str,str1;
    int atomType;
    for(i = 1;i <= mol.NumAtoms(); i++)
      {
        atom = mol.GetAtom(i);
        str = atom->GetType();
        atomType = 0; // Something is very wrong if this doesn't get set below

        if (mm2Types) {
          ttab.SetToType("MM2");
          ttab.Translate(str1,str);
          atomType = atoi((char*)str1.c_str());
        }
        if (mmffTypes) {
          // Override the MM2 typing
          OBPairData *type = (OpenBabel::OBPairData*)atom->GetData("FFAtomType");
          if (type) {
            str1 = type->GetValue().c_str();
            atomType = atoi((char*)str1.c_str());
          }
        }
        if (mm3Types) {
          // convert to integer for MM3 typing
          atomType = SetMM3Type(atom);
        }
        if (classTypes) {
          // Atom classes are set by the user, so use those
          OBGenericData *data = atom->GetData("Atom Class");
          if (data) {
            OBPairInteger* acdata = dynamic_cast<OBPairInteger*>(data); // Could replace with C-style cast if willing to live dangerously
            if (acdata) {
              int ac = acdata->GetGenericValue();
              if (ac >= 0)
                atomType = ac;
            }
          }
        }

        snprintf(buffer, BUFF_SIZE, "%6d %2s  %12.6f%12.6f%12.6f %5d",
                 i,
                 OBElements::GetSymbol(atom->GetAtomicNum()),
                 atom->GetX(),
                 atom->GetY(),
                 atom->GetZ(),
                 atomType);
        ofs << buffer;

        for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j))
          {
            snprintf(buffer, BUFF_SIZE, "%6d", (bond->GetNbrAtom(atom))->GetIdx());
            ofs << buffer;
          }

        ofs << endl;
      }

    return(true);
  }
コード例 #21
0
  bool MOL2Format::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;
    bool ligandsOnly = pConv->IsOption("l", OBConversion::OUTOPTIONS)!=NULL;
 
    //The old code follows....
    string str,str1;
    char buffer[BUFF_SIZE],label[BUFF_SIZE];
    char rnum[BUFF_SIZE],rlabel[BUFF_SIZE];

    ofs << "@<TRIPOS>MOLECULE" << endl;
    str = mol.GetTitle();
    if (str.empty())
      ofs << "*****" << endl;
    else
      ofs << str << endl;

    snprintf(buffer, BUFF_SIZE," %d %d 0 0 0", mol.NumAtoms(),mol.NumBonds());
    ofs << buffer << endl;
    ofs << "SMALL" << endl;

    OBPairData *dp = (OBPairData*)mol.GetData("PartialCharges");
    if (dp != NULL) {
        // Tripos spec says:
        // NO_CHARGES, DEL_RE, GASTEIGER, GAST_HUCK, HUCKEL, PULLMAN, 
        // GAUSS80_CHARGES, AMPAC_CHARGES, MULLIKEN_CHARGES, DICT_ CHARGES,
        // MMFF94_CHARGES, USER_CHARGES
      if (dp->GetValue() == "Mulliken")
        ofs << "MULLIKEN_CHARGES" << endl;
      else // should pick from the Tripos types
        ofs << "GASTEIGER" << endl;
    }
    else { // No idea what these charges are... all our code sets "PartialCharges"
        ofs << "GASTEIGER" << endl;
    }

    ofs << "Energy = " << mol.GetEnergy() << endl;

    if (mol.HasData(OBGenericDataType::CommentData))
      {
        OBCommentData *cd = (OBCommentData*)mol.GetData(OBGenericDataType::CommentData);
        ofs << cd->GetData();
      }

    ofs << endl;
    ofs << "@<TRIPOS>ATOM" << endl;

    OBAtom *atom;
    OBResidue *res;

    vector<OBAtom*>::iterator i;
    vector<int> labelcount;
    labelcount.resize( etab.GetNumberOfElements() );

    ttab.SetFromType("INT");
    ttab.SetToType("SYB");

    for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
      {

        //
        //  Use sequentially numbered atom names if no residues
        //

        snprintf(label,BUFF_SIZE, "%s%d",
                 etab.GetSymbol(atom->GetAtomicNum()),
                 ++labelcount[atom->GetAtomicNum()]);
        strcpy(rlabel,"<1>");
        strcpy(rnum,"1");

        str = atom->GetType();
        ttab.Translate(str1,str);

        //
        //  Use original atom names if there are residues
        //

        if (!ligandsOnly && (res = atom->GetResidue()) )
          {
            // use original atom names defined by residue
            snprintf(label,BUFF_SIZE,"%s",(char*)res->GetAtomID(atom).c_str());
            // make sure that residue name includes its number
            snprintf(rlabel,BUFF_SIZE,"%s%d",res->GetName().c_str(), res->GetNum());
            snprintf(rnum,BUFF_SIZE,"%d",res->GetNum());
          }

        snprintf(buffer,BUFF_SIZE,"%7d%1s%-6s%12.4f%10.4f%10.4f%1s%-5s%4s%1s %-8s%10.4f",
                 atom->GetIdx(),"",label,
                 atom->GetX(),atom->GetY(),atom->GetZ(),
                 "",str1.c_str(),
                 rnum,"",rlabel,
                 atom->GetPartialCharge());
        ofs << buffer << endl;
      }

    ofs << "@<TRIPOS>BOND" << endl;
    OBBond *bond;
    vector<OBBond*>::iterator j;
    OBSmartsPattern pat;
    string s1, s2;
    for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j))
      {
        s1 = bond->GetBeginAtom()->GetType();
        s2 = bond->GetEndAtom()->GetType();
        if (bond->IsAromatic() || s1 == "O.co2" || s2 == "O.co2") 
          strcpy(label,"ar");
        else if (bond->IsAmide())
          strcpy(label,"am");
        else
          snprintf(label,BUFF_SIZE,"%d",bond->GetBO());

        snprintf(buffer, BUFF_SIZE,"%6d%6d%6d%3s%2s",
                 bond->GetIdx()+1,bond->GetBeginAtomIdx(),bond->GetEndAtomIdx(),
                 "",label);
        ofs << buffer << endl;
      }
    // NO trailing blank line (PR#1868929).
    //    ofs << endl;

    return(true);
  }
コード例 #22
0
ファイル: hinformat.cpp プロジェクト: annulen/openbabel
  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);
  }
コード例 #23
0
ファイル: tinkerformat.cpp プロジェクト: Reinis/openbabel
  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;
  }
コード例 #24
0
ファイル: gromos96format.cpp プロジェクト: yishutu/openbabel
  bool GROMOS96Format::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;
    double fac = pConv->IsOption("n") ? 0.1 : 1.0; //new framework

    char type_name[16];
    char res_name[16];
    char buffer[BUFF_SIZE];
    string res_num;

    snprintf(buffer, BUFF_SIZE, "#GENERATED BY OPEN BABEL %s\n",BABEL_VERSION);
    ofs << buffer;

    /* GROMOS wants a TITLE block, so let's write one*/
    ofs << "TITLE\n" << mol.GetTitle() << "\nEND\n";
    ofs << "POSITION\n";

    OBAtom *atom;
    OBResidue *res;
    vector<OBAtom*>::iterator i;

    for(atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
      {
        if ( (res = atom->GetResidue()) )
          {
            // 16 = sizeof(res_name) and sizeof(type_name)
            strncpy(res_name,(char*)res->GetName().c_str(), 16);
            res_name[15] = '\0';
            strncpy(type_name,(char*)res->GetAtomID(atom).c_str(), 16);
            type_name[15] = '\0';
            res_num = res->GetNumString();
          }
        else
          {
            strncpy(type_name,OBElements::GetSymbol(atom->GetAtomicNum()), 16);
            strcpy(res_name,"UNK");
            res_num = "1";
          }

        snprintf(buffer, BUFF_SIZE, "%5s %5s %5s %6d %15.5f %15.5f %15.5f\n",
                res_num.c_str(),res_name,type_name,atom->GetIdx(),
                atom->x()*fac,atom->y()*fac,atom->z()*fac);
        ofs << buffer;

        if (!(atom->GetIdx()%10))
          {
            snprintf(buffer, BUFF_SIZE, "# %d\n",atom->GetIdx());
            ofs << buffer;
          }
      }

    ofs << "END\n";

    return(true);
  }
コード例 #25
0
ファイル: tinkerformat.cpp プロジェクト: annulen/openbabel
bool TinkerFormat::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;
    bool mmffTypes = pConv->IsOption("m",OBConversion::OUTOPTIONS) != NULL;

    unsigned int i;
    char buffer[BUFF_SIZE];
    OBBond *bond;
    vector<OBBond*>::iterator j;

    // Before we try output of MMFF94 atom types, check if it works
    OBForceField *ff = OpenBabel::OBForceField::FindForceField("MMFF94");
    if (mmffTypes && ff && ff->Setup(mol))
      mmffTypes = ff->GetAtomTypes(mol);
    else
      mmffTypes = false; // either the force field isn't available, or it doesn't work

    if (!mmffTypes)
      snprintf(buffer, BUFF_SIZE, "%6d %-20s   MM2 parameters\n",mol.NumAtoms(),mol.GetTitle());
    else
      snprintf(buffer, BUFF_SIZE, "%6d %-20s   MMFF94 parameters\n",mol.NumAtoms(),mol.GetTitle());
    ofs << buffer;

    ttab.SetFromType("INT");

    OBAtom *atom;
    string str,str1;
    for(i = 1;i <= mol.NumAtoms(); i++)
    {
        atom = mol.GetAtom(i);
        str = atom->GetType();
        ttab.SetToType("MM2");
        ttab.Translate(str1,str);

        if (mmffTypes) {
          // Override the MM2 typing
          OBPairData *type = (OpenBabel::OBPairData*)atom->GetData("FFAtomType");
          if (type)
            str1 = type->GetValue().c_str();
        }

        snprintf(buffer, BUFF_SIZE, "%6d %2s  %12.6f%12.6f%12.6f %5d",
                i,
                etab.GetSymbol(atom->GetAtomicNum()),
                atom->GetX(),
                atom->GetY(),
                atom->GetZ(),
                atoi((char*)str1.c_str()));
        ofs << buffer;

        for (bond = atom->BeginBond(j); bond; bond = atom->NextBond(j))
        {
            snprintf(buffer, BUFF_SIZE, "%6d", (bond->GetNbrAtom(atom))->GetIdx());
            ofs << buffer;
        }

        ofs << endl;
    }

    return(true);
}
コード例 #26
0
ファイル: eqeq.cpp プロジェクト: CooperLiu/openbabel
  //! \return whether partial charges were successfully assigned to this molecule
  bool EQEqCharges::ComputeCharges(OBMol &mol)
  {
    int i, j, a, c, N = mol.NumAtoms();
    double cellVolume;
    VectorXf chi(N), J(N), b(N), x(N);
    MatrixXf J_ij(N, N), A(N, N);
    OBUnitCell *obuc;
    matrix3x3 unitcell, fourier;
    vector3 dx;
    int numNeighbors[3];
    OBAtom *atom;

    // If parameters have not yet been loaded, do that
    if (!_paramFileLoaded)
    {
      if (ParseParamFile())
      {
        _paramFileLoaded = true;
      } else
      {
        return false;
      }
    }

    // Calculate atomic properties based around their ionic charge
    for (i = 0; i < N; i++)
    {
      atom = mol.GetAtom(i + 1);
      a = atom->GetAtomicNum();
      c = _chargeCenter[a];

      // Fail if ionization data is missing for any atom in the molecule
      if (_ionizations[a][c + 1] == -1 || _ionizations[a][c] == -1 || a > TABLE_OF_ELEMENTS_SIZE)
      {
        obErrorLog.ThrowError(__FUNCTION__, "Insufficient ionization data for atoms in the given molecule. Update `data/eqeqIonizations.txt` with missing information and re-run this function.", obError);
        return false;
      }

      J(i) = _ionizations[a][c + 1] - _ionizations[a][c];
      chi(i) = 0.5 * (_ionizations[a][c + 1] + _ionizations[a][c]) - (a == 1? 0 : c * J(i));
    }

    // If a unit cell is defined, use the periodic Ewald calculation
    if (mol.HasData(OBGenericDataType::UnitCell))
    {
      // Get unit cell and calculate its Fourier transform + volume
      obuc = (OBUnitCell *) mol.GetData(OBGenericDataType::UnitCell);
      unitcell = obuc->GetCellMatrix();
      fourier = (2 * PI * unitcell.inverse()).transpose();
      cellVolume = obuc->GetCellVolume();

      // Get the number of radial unit cells to use in x, y, and z
      numNeighbors[0] = int(ceil(minCellLength / (2.0 * (obuc->GetA())))) - 1;
      numNeighbors[1] = int(ceil(minCellLength / (2.0 * (obuc->GetB())))) - 1;
      numNeighbors[2] = int(ceil(minCellLength / (2.0 * (obuc->GetC())))) - 1;

      for (i = 0; i < N; i++)
      {
        atom = mol.GetAtom(i + 1);
        for (j = 0; j < N; j++)
        {
          dx = atom->GetVector() - (mol.GetAtom(j + 1))->GetVector();
          J_ij(i, j) = GetPeriodicEwaldJij(J(i), J(j), dx, (i == j), unitcell, fourier, cellVolume, numNeighbors);
        }
      }
    // If no unit cell, use the simplified nonperiodic calculation
    } else
    {
      for (i = 0; i < N; i++)
      {
        atom = mol.GetAtom(i + 1);
        for (j = 0; j < N; j++)
        {
          J_ij(i, j) = GetNonperiodicJij(J(i), J(j), atom->GetDistance(j + 1), (i == j));
        }
        return false;
      }
    }

    // Formulate problem as A x = b, where x is the calculated partial charges
    // First equation is a simple overall balance: sum(Q) = 0
    A.row(0) = VectorXf::Ones(N);
    b(0) = 0;

    // Remaining equations are based off of the fact that, at equilibrium, the
    // energy of the system changes equally for a change in any charge:
    //     dE/dQ_1 = dE/dQ_2 = ... = dE/dQ_N
    A.block(1, 0, N - 1, N) = J_ij.block(0, 0, N - 1, N) - J_ij.block(1, 0, N - 1, N);
    b.tail(N - 1) = chi.tail(N - 1) - chi.head(N - 1);

    // The solution is a list of charges in the system
    x = A.colPivHouseholderQr().solve(b);

    // Now we are done calculating, pass all this back to OpenBabel molecule
    mol.SetPartialChargesPerceived();
    OBPairData *dp = new OBPairData;
    dp->SetAttribute("PartialCharges");
    dp->SetValue("EQEq");
    dp->SetOrigin(perceived);
    mol.SetData(dp);

    m_partialCharges.clear();
    m_partialCharges.reserve(N);
    m_formalCharges.clear();
    m_formalCharges.reserve(N);

    for (i = 0; i < N; i ++)
    {
      atom = mol.GetAtom(i + 1);
      atom->SetPartialCharge(x(i));
      m_partialCharges.push_back(x(i));
      m_formalCharges.push_back(atom->GetFormalCharge());
    }

    obErrorLog.ThrowError(__FUNCTION__, "EQEq charges successfully assigned.", obInfo);
    return true;
  }
コード例 #27
0
ファイル: pdbformat.cpp プロジェクト: Acpharis/openbabel
  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);
  }
コード例 #28
0
bool ChemDrawXMLFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
{
    static const xmlChar C_MOLECULE[]         = "fragment";
    static const xmlChar C_CDXML[]            = "CDXML";
    static const xmlChar C_BONDLENGTH[]       = "BondLength";
    static const xmlChar C_PAGE[]             = "page";
    static const xmlChar C_ATOM[]             = "n";
    static const xmlChar C_BOND[]             = "b";
    static const xmlChar C_ID[]               = "id";

    static const xmlChar C_CHARGE[]           = "Charge";
    static const xmlChar C_COORDS[]           = "p";
    static const xmlChar C_ELEMENT[]          = "Element";
    static const xmlChar C_ORDER[]            = "Order";
    static const xmlChar C_BEGIN[]            = "B";
    static const xmlChar C_END[]              = "E";
    static const xmlChar C_DISPLAY[]          = "Display";

    _pxmlConv = XMLConversion::GetDerived(pConv,false);
    if(!_pxmlConv)
        return false;

    OBMol* pmol = dynamic_cast<OBMol*>(pOb);
    if(pmol==NULL)
        return false;
    OBMol &mol = *pmol;

    OBBond *pbond;
    vector<OBBond*>::iterator j;
    if(_pxmlConv->GetOutputIndex() == 1)
    {
        xmlTextWriterStartDocument(writer(), NULL, NULL, NULL);
        xmlTextWriterWriteDTD(writer(), BAD_CAST "CDXML", NULL, BAD_CAST "http://www.camsoft.com/xml/cdxml.dtd", NULL);
        xmlTextWriterStartElement(writer(), C_CDXML);
        xmlTextWriterWriteFormatAttribute(writer(), C_BONDLENGTH , "30");
        xmlTextWriterStartElement(writer(), C_PAGE); // put everything on one page
        // now guess the average bond size for the first molecule and scale to 30.
        _scale = 0.;
        if (mol.NumBonds())
        {
            for (pbond = mol.BeginBond(j); pbond; pbond = mol.NextBond(j))
                _scale += pbond->GetLength();
            _scale /= mol.NumBonds();
        }
        else
            _scale = 1.; // FIXME: what happens if the molecule has no bond?
        _scale = 30. / _scale;
        _offset = 0;
    }

    xmlTextWriterStartElement(writer(), C_MOLECULE);

    OBAtom *patom;
    vector<OBAtom*>::iterator i;
    int n;
    for (patom = mol.BeginAtom(i); patom; patom = mol.NextAtom(i))
    {
        xmlTextWriterStartElement(writer(), C_ATOM);

        xmlTextWriterWriteFormatAttribute(writer(), C_ID , "%d", patom->GetIdx() + _offset);
        xmlTextWriterWriteFormatAttribute(writer(), C_COORDS , "%f %f", patom->GetX() * _scale, patom->GetY() * _scale);
        n = patom->GetAtomicNum();
        if (n != 6)
        {
            xmlTextWriterWriteFormatAttribute(writer(), C_ELEMENT , "%d", n);
        }
        n = patom->GetFormalCharge();
        if (n != 0)
        {
            xmlTextWriterWriteFormatAttribute(writer(), C_CHARGE , "%d", n);
        }
        xmlTextWriterEndElement(writer());
    }

    for (pbond = mol.BeginBond(j); pbond; pbond = mol.NextBond(j))
    {
        xmlTextWriterStartElement(writer(), C_BOND);
        patom = pbond->GetBeginAtom();
        xmlTextWriterWriteFormatAttribute(writer(), C_BEGIN , "%d", patom->GetIdx() + _offset);
        patom = pbond->GetEndAtom();
        xmlTextWriterWriteFormatAttribute(writer(), C_END , "%d", patom->GetIdx() + _offset);
        n = pbond->GetBO();
        if (n != 1)
        {
            xmlTextWriterWriteFormatAttribute(writer(), C_ORDER , "%d", n);
        }
        if (pbond->IsHash())
            xmlTextWriterWriteFormatAttribute(writer(), C_DISPLAY , "WedgeBegin");
        else if (pbond->IsWedge())
            xmlTextWriterWriteFormatAttribute(writer(), C_DISPLAY , "WedgedHashEnd");
        xmlTextWriterEndElement(writer());
    }
    _offset += mol.NumAtoms ();

    xmlTextWriterEndElement(writer());//molecule

    //TODO: Writing property block

    if(_pxmlConv->IsLast())
    {
        xmlTextWriterEndDocument(writer()); // page
        xmlTextWriterEndDocument(writer()); //document
        OutputToStream();
    }
    return true;
}
コード例 #29
0
ファイル: depict.cpp プロジェクト: RitaDo/pgchem
  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;
  }
コード例 #30
0
ファイル: bgfformat.cpp プロジェクト: Acpharis/openbabel
  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);
  }