ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.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

# User Rev Content
1 tim 2440 /**********************************************************************
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 tim 2445 #include "xyzformat.hpp"
17 tim 2440
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 tim 2518 obErrorLog.ThrowError(__func__,
46 tim 2440 "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 tim 2518 obErrorLog.ThrowError(__func__,
53 tim 2440 "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 tim 2518 obErrorLog.ThrowError(__func__,
65 tim 2440 "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 tim 2518 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
88 tim 2440 return(false);
89     }
90     tokenize(vs,buffer);
91 tim 2469 if (vs.size() < 4)
92 tim 2440 {
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 tim 2518 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
100 tim 2440 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 tim 2518 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
128 tim 2440 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 tim 2518 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
140 tim 2440 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 tim 2518 obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
152 tim 2440 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