1 /**********************************************************************
2 Copyright (C) 2004 by Chris Morley
3
4 This file is part of the Open Babel project.
5 For more information, see <http://openbabel.org/>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 2 of the License.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 ***********************************************************************/
16 #include <openbabel/babelconfig.h>
17
18 #include <openbabel/obmolecformat.h>
19 #include <openbabel/mol.h>
20 #include <openbabel/atom.h>
21 #include <openbabel/bond.h>
22 #include <openbabel/obiter.h>
23 #include <openbabel/elements.h>
24
25
26 const double AAU = 0.5291772108; // �ngstr�m per bohr (CODATA 2002)
27
28 using namespace std;
29 namespace OpenBabel
30 {
31
32 class TurbomoleFormat : public OBMoleculeFormat
33 {
34 public:
35 //Register this format type ID
TurbomoleFormat()36 TurbomoleFormat()
37 {
38 OBConversion::RegisterFormat("tmol",this);
39 OBConversion::RegisterOptionParam("a", this, OBConversion::INOPTIONS);
40 }
41
Description()42 virtual const char* Description() //required
43 {
44 return
45 "TurboMole Coordinate format\n"
46 "Write options e.g.-xa\n"
47 " a Output Angstroms\n\n"
48 "Read Options e.g. -as\n"
49 " s Output single bonds only\n"
50 " b Disable bonding entirely\n"
51 " a Input in Angstroms\n\n" ;
52 };
53
SpecificationURL()54 virtual const char* SpecificationURL()
55 {return "http://www.cosmologic.de/QuantumChemistry/main_qChemistry.html";};
56
57 //Flags() can return be any the following combined by | or be omitted if none apply
58 // NOTREADABLE READONEONLY NOTWRITABLE WRITEONEONLY
Flags()59 virtual unsigned int Flags()
60 {
61 return READONEONLY | WRITEONEONLY;
62 };
63
64 //*** This section identical for most OBMol conversions ***
65 ////////////////////////////////////////////////////
66 /// The "API" interface functions
67 virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv);
68 virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
69 };
70 //***
71
72 //Make an instance of the format class
73 TurbomoleFormat theTurbomoleFormat;
74
75 /////////////////////////////////////////////////////////////////
ReadMolecule(OBBase * pOb,OBConversion * pConv)76 bool TurbomoleFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
77 {
78 OBMol* pmol = pOb->CastAndClear<OBMol>();
79 if (pmol == nullptr)
80 return false;
81
82 //Define some references so we can use the old parameter names
83 istream &ifs = *pConv->GetInStream();
84 OBMol &mol = *pmol;
85 double UnitConv=AAU;
86 if(pConv->IsOption("a", OBConversion::INOPTIONS))
87 UnitConv=1;
88
89
90 char buffer[BUFF_SIZE];
91 do
92 {
93 ifs.getline(buffer,BUFF_SIZE);
94 if (ifs.peek() == EOF || !ifs.good())
95 return false;
96 }
97 while(strncmp(buffer,"$coord",6));
98
99 mol.BeginModify();
100 OBAtom atom;
101 while(!(!ifs))
102 {
103 ifs.getline(buffer,BUFF_SIZE);
104 if(*buffer=='$')
105 break;
106 if(*buffer=='#')
107 continue;
108 float x,y,z;
109 char atomtype[8];
110 if(sscanf(buffer,"%f %f %f %7s",&x,&y,&z,atomtype)!=4)
111 return false;
112
113 atom.SetVector(x*UnitConv, y*UnitConv, z*UnitConv);
114 atom.SetAtomicNum(OBElements::GetAtomicNum(atomtype));
115 atom.SetType(atomtype);
116
117 if(!mol.AddAtom(atom))
118 return false;
119 atom.Clear();
120 }
121 while(!(!ifs) && strncmp(buffer,"$end",4))
122 ifs.getline(buffer,BUFF_SIZE);
123
124 if (!pConv->IsOption("b",OBConversion::INOPTIONS))
125 mol.ConnectTheDots();
126 if (!pConv->IsOption("s",OBConversion::INOPTIONS) && !pConv->IsOption("b",OBConversion::INOPTIONS))
127 mol.PerceiveBondOrders();
128
129 // clean out remaining blank lines
130 std::streampos ipos;
131 do
132 {
133 ipos = ifs.tellg();
134 ifs.getline(buffer,BUFF_SIZE);
135 }
136 while(strlen(buffer) == 0 && !ifs.eof() );
137 ifs.seekg(ipos);
138
139 mol.EndModify();
140 return true;
141 }
142
143 ////////////////////////////////////////////////////////////////
144
strlwr(char * s)145 char *strlwr(char *s)
146 {
147 if (s != nullptr)
148 {
149 char *p;
150 for (p = s; *p; ++p)
151 *p = tolower(*p);
152 }
153 return s;
154 }
155
156
WriteMolecule(OBBase * pOb,OBConversion * pConv)157 bool TurbomoleFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
158 {
159 OBMol* pmol = dynamic_cast<OBMol*>(pOb);
160 if (pmol == nullptr)
161 return false;
162
163 //Define some references so we can use the old parameter names
164 ostream &ofs = *pConv->GetOutStream();
165 OBMol &mol = *pmol;
166 double UnitConv=AAU;
167 if(pConv->IsOption("a"))
168 UnitConv=1;
169
170 ofs << "$coord" <<endl;
171
172 char buffer[BUFF_SIZE];
173 OBAtom *atom;
174 vector<OBAtom*>::iterator i;
175 for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i))
176 {
177 char symb[8];
178 strcpy(symb,OBElements::GetSymbol(atom->GetAtomicNum()));
179 snprintf(buffer, BUFF_SIZE, "%20.14f %20.14f %20.14f %s",
180 atom->GetX()/UnitConv,
181 atom->GetY()/UnitConv,
182 atom->GetZ()/UnitConv,
183 strlwr(symb) );
184 ofs << buffer << endl;
185 }
186 ofs << "$end" << endl;
187
188 return true;
189 }
190
191 } //namespace OpenBabel
192