ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-3.0/src/openbabel/xyzformat.cpp
Revision: 2518
Committed: Fri Dec 16 21:52:50 2005 UTC (18 years, 7 months ago) by tim
File size: 7350 byte(s)
Log Message:
changed __FUNCTION__ to __func__ to match C99 standard, and then added
an autoconf test to check for __func__ usability.  Changed some default
compile flags for the Sun architecture

File Contents

# Content
1 /**********************************************************************
2 Copyright (C) 2000 by OpenEye Scientific Software, Inc.
3 Some portions Copyright (C) 2001-2005 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 "xyzformat.hpp"
17
18
19 using namespace std;
20 namespace OpenBabel
21 {
22
23 bool XYZFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
24 {
25 OBMol* pmol = dynamic_cast<OBMol*>(pOb);
26 if(pmol==NULL)
27 return false;
28
29 //Define some references so we can use the old parameter names
30 istream &ifs = *pConv->GetInStream();
31 OBMol &mol = *pmol;
32 const char* title = pConv->GetTitle();
33 char buffer[BUFF_SIZE];
34
35 #ifdef HAVE_SSTREAM
36 stringstream errorMsg;
37 #else
38 strstream errorMsg;
39 #endif
40
41 unsigned int natoms; // [ejk] assumed natoms could not be -ve
42
43 if (!ifs.getline(buffer,BUFF_SIZE))
44 {
45 obErrorLog.ThrowError(__func__,
46 "Problems reading an XYZ file: Cannot read the first line.", obWarning);
47 return(false);
48 }
49
50 if (sscanf(buffer, "%d", &natoms) == 0 || !natoms)
51 {
52 obErrorLog.ThrowError(__func__,
53 "Problems reading an XYZ file: The first line must contain the number of atoms.", obWarning);
54 return(false);
55 }
56
57 mol.ReserveAtoms(natoms);
58
59 // The next line contains a title string for the molecule. Use this
60 // as the title for the molecule if the line is not
61 // empty. Otherwise, use the title given by the calling function.
62 if (!ifs.getline(buffer,BUFF_SIZE))
63 {
64 obErrorLog.ThrowError(__func__,
65 "Problems reading an XYZ file: Could not read the second line (title/comments).", obWarning);
66 return(false);
67 }
68 if (strlen(buffer) != 0)
69 mol.SetTitle(buffer);
70 else
71 mol.SetTitle(title);
72
73 mol.BeginModify();
74
75 // The next lines contain four items each, separated by white
76 // spaces: the atom type, and the coordinates of the atom
77 vector<string> vs;
78 for (unsigned int i = 1; i <= natoms; i ++)
79 {
80 if (!ifs.getline(buffer,BUFF_SIZE))
81 {
82 errorMsg << "Problems reading an XYZ file: "
83 << "Could not read line #" << i+2 << ", file error." << endl
84 << " According to line one, there should be " << natoms
85 << " atoms, and therefore " << natoms+2 << " lines in the file.";
86
87 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
88 return(false);
89 }
90 tokenize(vs,buffer);
91 if (vs.size() < 4)
92 {
93 errorMsg << "Problems reading an XYZ file: "
94 << "Could not read line #" << i+2 << "." << endl
95 << "OpenBabel found the line '" << buffer << "'" << endl
96 << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
97 << "However, OpenBabel found " << vs.size() << " items.";
98
99 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
100 return(false);
101 }
102
103 // Atom Type: get the atomic number from the element table, using
104 // the first entry in the currently read line. If the entry makes
105 // sense, set the atomic number and leave the atomic type open
106 // (the type is then later faulted in when atom->GetType() is
107 // called). If the entry does not make sense to use, set the atom
108 // type manually, assuming that the author of the xyz-file had
109 // something "special" in mind.
110 OBAtom *atom = mol.NewAtom();
111 int atomicNum = etab.GetAtomicNum(vs[0].c_str());
112 atom->SetAtomicNum(atomicNum); //set atomic number, or '0' if the atom type is not recognized
113 if (atomicNum == 0)
114 atom->SetType(vs[0]);
115
116 // Read the atom coordinates
117 char *endptr;
118 double x = strtod((char*)vs[1].c_str(),&endptr);
119 if (endptr == (char*)vs[1].c_str())
120 {
121 errorMsg << "Problems reading an XYZ file: "
122 << "Could not read line #" << i+2 << "." << endl
123 << "OpenBabel found the line '" << buffer << "'" << endl
124 << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
125 << "OpenBabel could not interpret item #1 as a number.";
126
127 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
128 return(false);
129 }
130 double y = strtod((char*)vs[2].c_str(),&endptr);
131 if (endptr == (char*)vs[2].c_str())
132 {
133 errorMsg << "Problems reading an XYZ file: "
134 << "Could not read line #" << i+2 << "." << endl
135 << "OpenBabel found the line '" << buffer << "'" << endl
136 << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
137 << "OpenBabel could not interpret item #2 as a number.";
138
139 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
140 return(false);
141 }
142 double z = strtod((char*)vs[3].c_str(),&endptr);
143 if (endptr == (char*)vs[3].c_str())
144 {
145 errorMsg << "Problems reading an XYZ file: "
146 << "Could not read line #" << i+2 << "." << endl
147 << "OpenBabel found the line '" << buffer << "'" << endl
148 << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
149 << "OpenBabel could not interpret item #3 as a number.";
150
151 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
152 return(false);
153 }
154 atom->SetVector(x,y,z); //set coordinates
155 }
156
157 // clean out any remaining blank lines
158 while(ifs.peek() != EOF && ifs.good() &&
159 (ifs.peek() == '\n' || ifs.peek() == '\r'))
160 ifs.getline(buffer,BUFF_SIZE);
161
162 if (!pConv->IsOption("b",OBConversion::INOPTIONS))
163 mol.ConnectTheDots();
164 if (!pConv->IsOption("s",OBConversion::INOPTIONS) && !pConv->IsOption("b",OBConversion::INOPTIONS))
165 mol.PerceiveBondOrders();
166
167 mol.EndModify();
168
169 return(true);
170 }
171
172 ////////////////////////////////////////////////////////////////
173
174 bool XYZFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
175 {
176 OBMol* pmol = dynamic_cast<OBMol*>(pOb);
177 if(pmol==NULL)
178 return false;
179
180 //Define some references so we can use the old parameter names
181 ostream &ofs = *pConv->GetOutStream();
182 OBMol &mol = *pmol;
183
184 unsigned int i;
185 char buffer[BUFF_SIZE];
186
187 sprintf(buffer,"%d", mol.NumAtoms());
188 ofs << buffer << endl;
189 sprintf(buffer,"%s\tEnergy: %15.7f", mol.GetTitle(), mol.GetEnergy());
190 ofs << buffer << endl;
191
192 OBAtom *atom;
193 string str,str1;
194 for(i = 1;i <= mol.NumAtoms(); i++)
195 {
196 atom = mol.GetAtom(i);
197 sprintf(buffer,"%3s%15.5f%15.5f%15.5f",
198 etab.GetSymbol(atom->GetAtomicNum()),
199 atom->GetX(),
200 atom->GetY(),
201 atom->GetZ());
202 ofs << buffer << endl;
203 }
204
205 return(true);
206 }
207
208 } //namespace OpenBabel