#include <openbabel/babelconfig.h>
#include <openbabel/obmolecformat.h>
#include <openbabel/mol.h>
#include <openbabel/atom.h>
#include <openbabel/bond.h>
#include <openbabel/elements.h>
#include <cstdlib>
using namespace std;
namespace OpenBabel
{
class ChemDrawFormat : public OBMoleculeFormat
{
public:
ChemDrawFormat()
{
OBConversion::RegisterFormat("ct",this);
}
virtual const char* Description() {
return
"ChemDraw Connection Table format\n"
"No comments yet\n";
};
virtual const char* SpecificationURL()
{return "";};
virtual unsigned int Flags()
{
return READONEONLY | WRITEONEONLY;
};
virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv);
virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
};
ChemDrawFormat theChemDrawFormat;
bool ChemDrawFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
{
OBMol* pmol = dynamic_cast<OBMol*>(pOb);
if (pmol == nullptr)
return false;
ostream &ofs = *pConv->GetOutStream();
OBMol &mol = *pmol;
char buffer[BUFF_SIZE];
ofs << mol.GetTitle() << endl;
ofs << " " << mol.NumAtoms() << " " << mol.NumBonds() << endl;
OBAtom *atom;
vector<OBAtom*>::iterator i;
for(atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
{
snprintf(buffer, BUFF_SIZE, " %9.4f %9.4f 0.0000 %-1s",
atom->x(),
atom->y(),
OBElements::GetSymbol(atom->GetAtomicNum()));
ofs << buffer << endl;
}
OBBond *bond;
vector<OBBond*>::iterator j;
for(bond = mol.BeginBond(j);bond;bond = mol.NextBond(j))
{
snprintf(buffer, BUFF_SIZE, "%3d%3d%3d%3d",
bond->GetBeginAtomIdx(),
bond->GetEndAtomIdx(),
bond->GetBondOrder(), bond->GetBondOrder());
ofs << buffer << endl;
}
return(true);
}
bool ChemDrawFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
{
OBMol* pmol = pOb->CastAndClear<OBMol>();
if (pmol == nullptr)
return false;
istream &ifs = *pConv->GetInStream();
OBMol &mol = *pmol;
const char* title = pConv->GetTitle();
char buffer[BUFF_SIZE];
unsigned int natoms, nbonds;
unsigned int bgn, end, order;
vector<string> vs;
OBAtom *atom;
double x, y, z;
mol.SetDimension(2);
mol.BeginModify();
ifs.getline(buffer,BUFF_SIZE);
if (strlen(buffer) == 0)
mol.SetTitle(buffer);
else
mol.SetTitle(title);
ifs.getline(buffer,BUFF_SIZE);
sscanf(buffer," %d %d", &natoms, &nbonds);
for (unsigned int i = 1; i <= natoms; i ++)
{
if (!ifs.getline(buffer,BUFF_SIZE)) return(false);
tokenize(vs,buffer);
if (vs.size() != 4) return(false);
atom = mol.NewAtom();
x = atof((char*)vs[0].c_str());
y = atof((char*)vs[1].c_str());
z = atof((char*)vs[2].c_str());
atom->SetVector(x,y,z); atom->SetAtomicNum(OBElements::GetAtomicNum(vs[3].c_str()));
}
if (nbonds != 0)
for (unsigned int i = 0; i < nbonds; i++)
{
if (!ifs.getline(buffer,BUFF_SIZE)) return(false);
tokenize(vs,buffer);
if (vs.size() != 4) return(false);
if (!sscanf(buffer,"%d%d%d%*d",&bgn,&end,&order)) return (false);
mol.AddBond(bgn,end,order);
}
std::streampos ipos;
do
{
ipos = ifs.tellg();
ifs.getline(buffer,BUFF_SIZE);
}
while(strlen(buffer) == 0 && !ifs.eof() );
ifs.seekg(ipos);
mol.EndModify();
return(true);
}
}