ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/openbabel/xyzformat.cpp
(Generate patch)

Comparing trunk/src/openbabel/xyzformat.cpp (file contents):
Revision 770 by tim, Fri Dec 2 15:38:03 2005 UTC vs.
Revision 1081 by gezelter, Thu Oct 19 20:49:05 2006 UTC

# Line 1 | Line 1 | Copyright (C) 2000 by OpenEye Scientific Software, Inc
1   /**********************************************************************
2   Copyright (C) 2000 by OpenEye Scientific Software, Inc.
3 < Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison
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
# Line 13 | Line 13 | GNU General Public License for more details.
13   GNU General Public License for more details.
14   ***********************************************************************/
15  
16 < #include "xyzformat.hpp"
16 > #include "mol.hpp"
17 > #include "obconversion.hpp"
18 > #include "obmolecformat.hpp"
19  
20 + #include <sstream>
21  
22   using namespace std;
23   namespace OpenBabel
24   {
25  
26 < bool XYZFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
27 < {
26 >  class XYZFormat : public OBMoleculeFormat
27 >  {
28 >  public:
29 >    //Register this format type ID
30 >    XYZFormat()
31 >    {
32 >      OBConversion::RegisterFormat("xyz", this, "chemical/x-xyz");
33 >    }
34 >
35 >    virtual const char* Description() //required
36 >    {
37 >      return
38 >        "XYZ cartesian coordinates format\n \
39 >       Read Options e.g. -as\n\
40 >        s  Output single bonds only\n\
41 >        b  Disable bonding entirely\n\n";
42 >    };
43 >
44 >    virtual const char* SpecificationURL()
45 >    {return "http://openbabel.sourceforge.net/formats/xyz.shtml";}; //optional
46 >
47 >    virtual const char* GetMIMEType()
48 >    { return "chemical/x-xyz"; };
49 >
50 >    //*** This section identical for most OBMol conversions ***
51 >    ////////////////////////////////////////////////////
52 >    /// The "API" interface functions
53 >    virtual bool ReadMolecule(OBBase* pOb, OBConversion* pConv);
54 >    virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
55 >  };
56 >  //***
57 >
58 >  //Make an instance of the format class
59 >  XYZFormat theXYZFormat;
60 >
61 >  /////////////////////////////////////////////////////////////////
62 >  bool XYZFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv)
63 >  {
64      OBMol* pmol = dynamic_cast<OBMol*>(pOb);
65      if(pmol==NULL)
66 <        return false;
66 >      return false;
67  
68      //Define some references so we can use the old parameter names
69      istream &ifs = *pConv->GetInStream();
70      OBMol &mol = *pmol;
71      const char* title = pConv->GetTitle();
72 +
73      char buffer[BUFF_SIZE];
74  
35 #ifdef HAVE_SSTREAM
75      stringstream errorMsg;
37 #else
38    strstream errorMsg;
39 #endif
76  
77      unsigned int natoms;        // [ejk] assumed natoms could not be -ve
78  
79      if (!ifs.getline(buffer,BUFF_SIZE))
80        {
81 <        obErrorLog.ThrowError(__FUNCTION__,
82 <                              "Problems reading an XYZ file: Cannot read the first line.", obWarning);
83 <        return(false);
81 >        obErrorLog.ThrowError(__func__,
82 >                              "Problems reading an XYZ file: Cannot read the first line.", obWarning);
83 >        return(false);
84        }
85  
86      if (sscanf(buffer, "%d", &natoms) == 0 || !natoms)
87 <    {
88 <      obErrorLog.ThrowError(__FUNCTION__,
89 <                            "Problems reading an XYZ file: The first line must contain the number of atoms.", obWarning);
90 <      return(false);
91 <    }
87 >      {
88 >        obErrorLog.ThrowError(__func__,
89 >                              "Problems reading an XYZ file: The first line must contain the number of atoms.", obWarning);
90 >        return(false);
91 >      }
92  
93      mol.ReserveAtoms(natoms);
94  
# Line 60 | Line 96 | bool XYZFormat::ReadMolecule(OBBase* pOb, OBConversion
96      // as the title for the molecule if the line is not
97      // empty. Otherwise, use the title given by the calling function.
98      if (!ifs.getline(buffer,BUFF_SIZE))
99 <    {
100 <      obErrorLog.ThrowError(__FUNCTION__,
101 <                            "Problems reading an XYZ file: Could not read the second line (title/comments).", obWarning);
99 >      {
100 >        obErrorLog.ThrowError(__func__,
101 >                              "Problems reading an XYZ file: Could not read the second line (title/comments).", obWarning);
102          return(false);
103 <    }
104 <    if (strlen(buffer) != 0)
105 <        mol.SetTitle(buffer);
103 >      }
104 >    string readTitle(buffer);
105 >    string::size_type location = readTitle.find("Energy");
106 >    if (location != string::npos)
107 >      readTitle.erase(location);
108 >    Trim(readTitle);
109 >
110 >    location = readTitle.find_first_not_of(" \t\n\r");
111 >    if (location != string::npos)
112 >      mol.SetTitle(readTitle);
113      else
114 <        mol.SetTitle(title);
114 >      mol.SetTitle(title);
115  
116      mol.BeginModify();
117  
# Line 76 | Line 119 | bool XYZFormat::ReadMolecule(OBBase* pOb, OBConversion
119      // spaces: the atom type, and the coordinates of the atom
120      vector<string> vs;
121      for (unsigned int i = 1; i <= natoms; i ++)
122 <    {
122 >      {
123          if (!ifs.getline(buffer,BUFF_SIZE))
124 <        {
125 <          errorMsg << "Problems reading an XYZ file: "
126 <                   << "Could not read line #" << i+2 << ", file error." << endl
127 <                   << " According to line one, there should be " << natoms
128 <                   << " atoms, and therefore " << natoms+2 << " lines in the file.";
124 >          {
125 >            errorMsg << "Problems reading an XYZ file: "
126 >                     << "Could not read line #" << i+2 << ", file error." << endl
127 >                     << " According to line one, there should be " << natoms
128 >                     << " atoms, and therefore " << natoms+2 << " lines in the file.";
129  
130 <          obErrorLog.ThrowError(__FUNCTION__, errorMsg.str() , obWarning);
131 <          return(false);
132 <        }
130 >            obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
131 >            return(false);
132 >          }
133          tokenize(vs,buffer);
134 <        if (vs.size() < 4)
135 <        {
136 <          errorMsg << "Problems reading an XYZ file: "
137 <                   << "Could not read line #" << i+2 << "." << endl
138 <                   << "OpenBabel found the line '" << buffer << "'" << endl
139 <                   << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
140 <                   << "However, OpenBabel found " << vs.size() << " items.";
134 >        if (vs.size() != 4)
135 >          {
136 >            errorMsg << "Problems reading an XYZ file: "
137 >                     << "Could not read line #" << i+2 << "." << endl
138 >                     << "OpenBabel found the line '" << buffer << "'" << endl
139 >                     << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
140 >                     << "However, OpenBabel found " << vs.size() << " items.";
141  
142 <          obErrorLog.ThrowError(__FUNCTION__, errorMsg.str() , obWarning);
143 <          return(false);
144 <        }
142 >            obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
143 >            return(false);
144 >          }
145  
146          // Atom Type: get the atomic number from the element table, using
147          // the first entry in the currently read line. If the entry makes
# Line 111 | Line 154 | bool XYZFormat::ReadMolecule(OBBase* pOb, OBConversion
154          int atomicNum = etab.GetAtomicNum(vs[0].c_str());
155          atom->SetAtomicNum(atomicNum); //set atomic number, or '0' if the atom type is not recognized
156          if (atomicNum == 0)
157 <            atom->SetType(vs[0]);
157 >          atom->SetType(vs[0]);
158  
159          // Read the atom coordinates
160          char *endptr;
161          double x = strtod((char*)vs[1].c_str(),&endptr);
162          if (endptr == (char*)vs[1].c_str())
163 <        {
164 <          errorMsg << "Problems reading an XYZ file: "
165 <                   << "Could not read line #" << i+2 << "." << endl
166 <                   << "OpenBabel found the line '" << buffer << "'" << endl
167 <                   << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
168 <                   << "OpenBabel could not interpret item #1 as a number.";
163 >          {
164 >            errorMsg << "Problems reading an XYZ file: "
165 >                     << "Could not read line #" << i+2 << "." << endl
166 >                     << "OpenBabel found the line '" << buffer << "'" << endl
167 >                     << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
168 >                     << "OpenBabel could not interpret item #1 as a number.";
169  
170 <          obErrorLog.ThrowError(__FUNCTION__, errorMsg.str() , obWarning);
171 <          return(false);
172 <        }
170 >            obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
171 >            return(false);
172 >          }
173          double y = strtod((char*)vs[2].c_str(),&endptr);
174          if (endptr == (char*)vs[2].c_str())
175 <        {
176 <          errorMsg << "Problems reading an XYZ file: "
177 <                   << "Could not read line #" << i+2 << "." << endl
178 <                   << "OpenBabel found the line '" << buffer << "'" << endl
179 <                   << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
180 <                   << "OpenBabel could not interpret item #2 as a number.";
175 >          {
176 >            errorMsg << "Problems reading an XYZ file: "
177 >                     << "Could not read line #" << i+2 << "." << endl
178 >                     << "OpenBabel found the line '" << buffer << "'" << endl
179 >                     << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
180 >                     << "OpenBabel could not interpret item #2 as a number.";
181  
182 <          obErrorLog.ThrowError(__FUNCTION__, errorMsg.str() , obWarning);
183 <          return(false);
184 <        }
182 >            obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
183 >            return(false);
184 >          }
185          double z = strtod((char*)vs[3].c_str(),&endptr);
186          if (endptr == (char*)vs[3].c_str())
187 <        {
188 <          errorMsg << "Problems reading an XYZ file: "
189 <                   << "Could not read line #" << i+2 << "." << endl
190 <                   << "OpenBabel found the line '" << buffer << "'" << endl
191 <                   << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
192 <                   << "OpenBabel could not interpret item #3 as a number.";
187 >          {
188 >            errorMsg << "Problems reading an XYZ file: "
189 >                     << "Could not read line #" << i+2 << "." << endl
190 >                     << "OpenBabel found the line '" << buffer << "'" << endl
191 >                     << "According to the specifications, this line should contain exactly 4 entries, separated by white space." << endl
192 >                     << "OpenBabel could not interpret item #3 as a number.";
193  
194 <          obErrorLog.ThrowError(__FUNCTION__, errorMsg.str() , obWarning);
195 <          return(false);
196 <        }
194 >            obErrorLog.ThrowError(__func__, errorMsg.str() , obWarning);
195 >            return(false);
196 >          }
197          atom->SetVector(x,y,z); //set coordinates
198 <    }
198 >      }
199  
200      // clean out any remaining blank lines
201      while(ifs.peek() != EOF && ifs.good() &&
202 <          (ifs.peek() == '\n' || ifs.peek() == '\r'))
202 >          (ifs.peek() == '\n' || ifs.peek() == '\r'))
203        ifs.getline(buffer,BUFF_SIZE);
204  
205      if (!pConv->IsOption("b",OBConversion::INOPTIONS))
# Line 167 | Line 210 | bool XYZFormat::ReadMolecule(OBBase* pOb, OBConversion
210      mol.EndModify();
211  
212      return(true);
213 < }
213 >  }
214  
215 < ////////////////////////////////////////////////////////////////
215 >  ////////////////////////////////////////////////////////////////
216  
217 < bool XYZFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
218 < {
217 >  bool XYZFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
218 >  {
219      OBMol* pmol = dynamic_cast<OBMol*>(pOb);
220      if(pmol==NULL)
221 <        return false;
221 >      return false;
222  
223      //Define some references so we can use the old parameter names
224      ostream &ofs = *pConv->GetOutStream();
# Line 184 | Line 227 | bool XYZFormat::WriteMolecule(OBBase* pOb, OBConversio
227      unsigned int i;
228      char buffer[BUFF_SIZE];
229  
230 <    sprintf(buffer,"%d", mol.NumAtoms());
230 >    snprintf(buffer, BUFF_SIZE, "%d", mol.NumAtoms());
231      ofs << buffer << endl;
232 <    sprintf(buffer,"%s\tEnergy: %15.7f", mol.GetTitle(), mol.GetEnergy());
232 >    if (fabs(mol.GetEnergy()) > 1.0e-3) // nonzero energy field
233 >      snprintf(buffer, BUFF_SIZE, "%s\tEnergy: %15.7f",
234 >               mol.GetTitle(), mol.GetEnergy());
235 >    else
236 >      snprintf(buffer, BUFF_SIZE, "%s", mol.GetTitle());
237      ofs << buffer << endl;
238  
239      OBAtom *atom;
240      string str,str1;
241      for(i = 1;i <= mol.NumAtoms(); i++)
242 <    {
242 >      {
243          atom = mol.GetAtom(i);
244 <        sprintf(buffer,"%3s%15.5f%15.5f%15.5f",
245 <                etab.GetSymbol(atom->GetAtomicNum()),
246 <                atom->GetX(),
247 <                atom->GetY(),
248 <                atom->GetZ());
244 >        snprintf(buffer, BUFF_SIZE, "%3s%15.5f%15.5f%15.5f",
245 >                 etab.GetSymbol(atom->GetAtomicNum()),
246 >                 atom->GetX(),
247 >                 atom->GetY(),
248 >                 atom->GetZ());
249          ofs << buffer << endl;
250 <    }
250 >      }
251  
252      return(true);
253 < }
253 >  }
254  
255   } //namespace OpenBabel

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines