#include <openbabel/babelconfig.h>
#include <openbabel/obmolecformat.h>
#include <openbabel/mol.h>
#include <openbabel/atom.h>
#include <openbabel/bond.h>
#include <openbabel/elements.h>
using namespace std;
namespace OpenBabel
{
class CacheFormat : public OBMoleculeFormat
{
public:
CacheFormat()
{
OBConversion::RegisterFormat("cac",this);
OBConversion::RegisterFormat("cache",this);
}
virtual const char* Description() {
return
"CAChe MolStruct format\n"
"No comments yet\n";
};
virtual const char* SpecificationURL()
{return "";};
virtual const char* GetMIMEType()
{ return "chemical/x-cache"; };
virtual unsigned int Flags()
{
return NOTREADABLE;
};
virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
};
CacheFormat theCacheFormat;
bool CacheFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
{
OBMol* pmol = dynamic_cast<OBMol*>(pOb);
if (pmol == nullptr)
return false;
ostream &ofs = *pConv->GetOutStream();
OBMol &mol = *pmol;
char type_name[16];
char buffer[BUFF_SIZE];
ofs << "molstruct88_Apr_30_1993_11:02:29 <molecule> 0x1d00\n";
ofs << "Written by Molecular Editor on <date>\n";
ofs << "Using data dictionary 9/9/93 4:47 AM\n";
ofs << "Version 6\n";
ofs << "local_transform\n";
ofs << "0.100000 0.000000 0.000000 0.000000\n";
ofs << "0.000000 0.100000 0.000000 0.000000\n";
ofs << "0.000000 0.000000 0.100000 0.000000\n";
ofs << "0.000000 0.000000 0.000000 1.000000\n";
ofs << "object_class atom\n";
ofs << "property xyz_coordinates MoleculeEditor angstrom 6 3 FLOAT\n";
ofs << "property anum MoleculeEditor unit 0 1 INTEGER\n";
ofs << "property sym MoleculeEditor noUnit 0 2 STRING\n";
ofs << "property chrg MoleculeEditor charge_au 0 1 INTEGER\n";
ofs << "property rflag MoleculeEditor noUnit 0 1 HEX\n";
ofs << "ID xyz_coordinates anum sym chrg rflag\n";
OBAtom *atom;
vector<OBAtom*>::iterator i;
for(atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
{
strncpy(type_name,OBElements::GetSymbol(atom->GetAtomicNum()), 16);
type_name[15] = '\0';
snprintf(buffer, BUFF_SIZE, "%3d %10.6f %10.6f %10.6f %2d %2s %2d 0x7052",
atom->GetIdx(),
atom->x(),
atom->y(),
atom->z(),
atom->GetAtomicNum(),
type_name,
atom->GetFormalCharge());
ofs << buffer << endl;
}
ofs << "property_flags:\n";
ofs << "object_class bond\n";
ofs << "property rflag MoleculeEditor noUnit 0 1 HEX\n";
ofs << "property type MoleculeEditor noUnit 0 1 NAME\n";
ofs << "property bond_order MoleculeEditor noUnit 4 1 FLOAT\n";
ofs << "ID rflag type bond_order\n";
char bstr[16];
OBBond *bond;
vector<OBBond*>::iterator j;
for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j))
{
switch (bond->GetBondOrder())
{
case 1:
strcpy(bstr,"single");
break;
case 2:
strcpy(bstr,"double");
break;
case 3:
strcpy(bstr,"triple");
break;
default:
strcpy(bstr,"weak");
}
snprintf(buffer, BUFF_SIZE, "%3d 0x7005 %s\n", bond->GetIdx()+1,bstr);
ofs << buffer;
}
ofs << "property_flags:\n";
ofs << "object_class connector\n";
ofs << "property dflag MoleculeEditor noUnit 0 1 HEX\n";
ofs << "property objCls1 MoleculeEditor noUnit 0 1 NAME\n";
ofs << "property objCls2 MoleculeEditor noUnit 0 1 NAME\n";
ofs << "property objID1 MoleculeEditor noUnit 0 1 INTEGER\n";
ofs << "property objID2 MoleculeEditor noUnit 0 1 INTEGER\n";
ofs << "ID dflag objCls1 objCls2 objID1 objID2\n";
int k;
for (bond = mol.BeginBond(j),k=1;bond;bond = mol.NextBond(j))
{
snprintf(buffer, BUFF_SIZE, "%3d 0xa1 atom bond %d %d\n",
k++,bond->GetBeginAtomIdx(),bond->GetIdx()+1);
ofs << buffer;
snprintf(buffer, BUFF_SIZE, "%3d 0xa1 atom bond %d %d\n",
k++,bond->GetEndAtomIdx(),bond->GetIdx()+1);
ofs << buffer;
}
ofs << "property_flags:\n";
return(true);
}
}