1 /**********************************************************************
2 Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
3 Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison
4 Some portions Copyright (C) 2004 by Chris Morley
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 2 of the License.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 ***********************************************************************/
15 #include <openbabel/babelconfig.h>
16 #include <openbabel/obmolecformat.h>
17 #include <openbabel/mol.h>
18 #include <openbabel/atom.h>
19 #include <openbabel/bond.h>
20 #include <openbabel/elements.h>
21 
22 
23 using namespace std;
24 namespace OpenBabel
25 {
26 
27   class CacheFormat : public OBMoleculeFormat
28   {
29   public:
30     //Register this format type ID
CacheFormat()31     CacheFormat()
32     {
33       OBConversion::RegisterFormat("cac",this);
34       OBConversion::RegisterFormat("cache",this);
35     }
36 
Description()37     virtual const char* Description() //required
38     {
39       return
40         "CAChe MolStruct format\n"
41         "No comments yet\n";
42     };
43 
SpecificationURL()44     virtual const char* SpecificationURL()
45     {return "";}; //optional
46 
GetMIMEType()47     virtual const char* GetMIMEType()
48     { return "chemical/x-cache"; };
49 
50     //Flags() can return be any the following combined by | or be omitted if none apply
51     // NOTREADABLE  READONEONLY  NOTWRITABLE  WRITEONEONLY
Flags()52     virtual unsigned int Flags()
53     {
54       return NOTREADABLE;
55     };
56 
57     ////////////////////////////////////////////////////
58     /// The "API" interface functions
59     virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
60 
61     ////////////////////////////////////////////////////
62   };
63 
64   //Make an instance of the format class
65   CacheFormat theCacheFormat;
66 
67   ////////////////////////////////////////////////////////////////
68 
WriteMolecule(OBBase * pOb,OBConversion * pConv)69   bool CacheFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
70   {
71     OBMol* pmol = dynamic_cast<OBMol*>(pOb);
72     if (pmol == nullptr)
73       return false;
74 
75     //Define some references so we can use the old parameter names
76     ostream &ofs = *pConv->GetOutStream();
77     OBMol &mol = *pmol;
78 
79     char type_name[16];
80     char buffer[BUFF_SIZE];
81 
82     ofs << "molstruct88_Apr_30_1993_11:02:29 <molecule> 0x1d00\n";
83     ofs << "Written by Molecular Editor on <date>\n";
84     ofs << "Using data dictionary         9/9/93  4:47 AM\n";
85     ofs << "Version 6\n";
86     ofs << "local_transform\n";
87     ofs << "0.100000 0.000000 0.000000 0.000000\n";
88     ofs << "0.000000 0.100000 0.000000 0.000000\n";
89     ofs << "0.000000 0.000000 0.100000 0.000000\n";
90     ofs << "0.000000 0.000000 0.000000 1.000000\n";
91     ofs << "object_class atom\n";
92     ofs << "property xyz_coordinates MoleculeEditor angstrom 6 3 FLOAT\n";
93     ofs << "property anum MoleculeEditor unit 0 1 INTEGER\n";
94     ofs << "property sym MoleculeEditor noUnit 0 2 STRING\n";
95     ofs << "property chrg MoleculeEditor charge_au 0 1 INTEGER\n";
96     ofs << "property rflag MoleculeEditor noUnit 0 1 HEX\n";
97     ofs << "ID xyz_coordinates             anum sym	chrg rflag\n";
98 
99     OBAtom *atom;
100     vector<OBAtom*>::iterator i;
101     for(atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
102       {
103         // 16 = sizeof(type_name)
104         strncpy(type_name,OBElements::GetSymbol(atom->GetAtomicNum()), 16);
105         // sizeof(type_name) - 1)
106         type_name[15] = '\0';
107 
108         snprintf(buffer, BUFF_SIZE, "%3d %10.6f %10.6f %10.6f %2d %2s %2d 0x7052",
109                 atom->GetIdx(),
110                 atom->x(),
111                 atom->y(),
112                 atom->z(),
113                 atom->GetAtomicNum(),
114                 type_name,
115                 atom->GetFormalCharge());
116         ofs << buffer << endl;
117       }
118 
119     ofs << "property_flags:\n";
120     ofs << "object_class bond\n";
121     ofs << "property rflag MoleculeEditor noUnit 0 1 HEX\n";
122     ofs << "property type MoleculeEditor noUnit 0 1 NAME\n";
123     ofs << "property bond_order MoleculeEditor noUnit 4 1 FLOAT\n";
124     ofs << "ID rflag type bond_order\n";
125 
126     char bstr[16];
127     OBBond *bond;
128     vector<OBBond*>::iterator j;
129     for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j))
130       {
131         switch (bond->GetBondOrder())
132           {
133           case 1:
134             strcpy(bstr,"single");
135             break;
136           case 2:
137             strcpy(bstr,"double");
138             break;
139           case 3:
140             strcpy(bstr,"triple");
141             break;
142           default:
143             strcpy(bstr,"weak");
144           }
145 
146         snprintf(buffer, BUFF_SIZE, "%3d 0x7005 %s\n", bond->GetIdx()+1,bstr);
147         ofs << buffer;
148       }
149 
150     ofs << "property_flags:\n";
151     ofs << "object_class connector\n";
152     ofs << "property dflag MoleculeEditor noUnit 0 1 HEX\n";
153     ofs << "property objCls1 MoleculeEditor noUnit 0 1 NAME\n";
154     ofs << "property objCls2 MoleculeEditor noUnit 0 1 NAME\n";
155     ofs << "property objID1 MoleculeEditor noUnit 0 1 INTEGER\n";
156     ofs << "property objID2 MoleculeEditor noUnit 0 1 INTEGER\n";
157     ofs << "ID dflag objCls1 objCls2 objID1 objID2\n";
158 
159 
160     int k;
161     for (bond = mol.BeginBond(j),k=1;bond;bond = mol.NextBond(j))
162       {
163         snprintf(buffer, BUFF_SIZE, "%3d 0xa1 atom bond %d %d\n",
164                 k++,bond->GetBeginAtomIdx(),bond->GetIdx()+1);
165         ofs << buffer;
166         snprintf(buffer, BUFF_SIZE, "%3d 0xa1 atom bond %d %d\n",
167                 k++,bond->GetEndAtomIdx(),bond->GetIdx()+1);
168         ofs << buffer;
169       }
170 
171     ofs << "property_flags:\n";
172     return(true);
173   }
174 
175 } //namespace OpenBabel
176