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 
16 #include <openbabel/babelconfig.h>
17 #include <openbabel/obmolecformat.h>
18 #include <openbabel/mol.h>
19 #include <openbabel/atom.h>
20 #include <openbabel/elements.h>
21 #include <openbabel/internalcoord.h>
22 
23 
24 using namespace std;
25 namespace OpenBabel
26 {
27 
28 class FenskeZmatFormat : public OBMoleculeFormat
29 {
30 public:
31     //Register this format type ID
FenskeZmatFormat()32     FenskeZmatFormat()
33     {
34         OBConversion::RegisterFormat("fh",this);
35     }
36 
Description()37     virtual const char* Description() //required
38     {
39         return
40           "Fenske-Hall Z-Matrix format\n"
41           "No comments yet\n";
42     };
43 
SpecificationURL()44   virtual const char* SpecificationURL()
45   {return "";}; //optional
46 
47     //Flags() can return be any the following combined by | or be omitted if none apply
48     // NOTREADABLE  READONEONLY  NOTWRITABLE  WRITEONEONLY
Flags()49     virtual unsigned int Flags()
50     {
51         return NOTREADABLE | WRITEONEONLY;
52     };
53 
54     ////////////////////////////////////////////////////
55     /// The "API" interface functions
56     virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
57 
58 };
59 
60 //Make an instance of the format class
61 FenskeZmatFormat theFenskeZmatFormat;
62 
63 /////////////////////////////////////////////////////////////////
64 
WriteMolecule(OBBase * pOb,OBConversion * pConv)65 bool FenskeZmatFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
66 {
67     OBMol* pmol = dynamic_cast<OBMol*>(pOb);
68     if (pmol == nullptr)
69         return false;
70 
71     //Define some references so we can use the old parameter names
72     ostream &ofs = *pConv->GetOutStream();
73     OBMol &mol = *pmol;
74 
75     OBAtom *atom,*a,*b,*c;
76     char type[16],buffer[BUFF_SIZE];
77     vector<OBAtom*>::iterator i;
78 
79     vector<OBInternalCoord*> vic;
80     vic.push_back(nullptr);
81     for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
82         vic.push_back(new OBInternalCoord);
83 
84     CartesianToInternal(vic,mol);
85 
86     ofs << endl << mol.NumAtoms() << endl;
87 
88     double r,w,t;
89     for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
90     {
91         a = vic[atom->GetIdx()]->_a;
92         b = vic[atom->GetIdx()]->_b;
93         c = vic[atom->GetIdx()]->_c;
94         r = vic[atom->GetIdx()]->_dst;
95         w = vic[atom->GetIdx()]->_ang;
96         t = vic[atom->GetIdx()]->_tor;
97         //  16 = sizeof(type)
98         strncpy(type,OBElements::GetSymbol(atom->GetAtomicNum()), 16);
99         type[15] = '\0';
100 
101         if (atom->GetIdx() == 1)
102         {
103             snprintf(buffer, BUFF_SIZE, "%-2s  1\n",type);
104             ofs << buffer;
105             continue;
106         }
107 
108         if (atom->GetIdx() == 2)
109         {
110             snprintf(buffer, BUFF_SIZE, "%-2s%3d%6.3f\n",
111                     type, a->GetIdx(), r);
112             ofs << buffer;
113             continue;
114         }
115 
116         if (atom->GetIdx() == 3)
117         {
118             snprintf(buffer, BUFF_SIZE, "%-2s%3d%6.3f%3d%8.3f\n",
119                     type, a->GetIdx(), r, b->GetIdx(), w);
120             ofs << buffer;
121             continue;
122         }
123 
124         if (t < 0)
125             t += 360;
126         snprintf(buffer, BUFF_SIZE, "%-2s%3d%6.3f%3d%8.3f%3d%6.1f\n",
127                 type, a->GetIdx(), r, b->GetIdx(), w, c->GetIdx(), t);
128         ofs << buffer;
129     }
130 
131     return(true);
132 }
133 
134 } //namespace OpenBabel
135