24#include "io/XYZFormat.hpp" 
   34#include "utils/Trim.hpp" 
   35#include "utils/simError.h" 
   39  bool XYZFormat::ReadMolecule(std::istream& ifs) {
 
   40    char buffer[BUFF_SIZE];
 
   42    std::stringstream errorMsg;
 
   47    if (!ifs.getline(buffer, BUFF_SIZE)) {
 
   48      strcpy(painCave.errMsg,
 
   49             "Problems reading an XYZ file: Cannot read the first line.\n");
 
   54    if (sscanf(buffer, 
"%d", &natoms) == 0 || !natoms) {
 
   55      strcpy(painCave.errMsg, 
"Problems reading an XYZ file: The first line " 
   56                              "must contain the number of atoms.\n");
 
   66    if (!ifs.getline(buffer, BUFF_SIZE)) {
 
   67      strcpy(painCave.errMsg, 
"Problems reading an XYZ file: Could not read " 
   68                              "the second line (title/comments).\n");
 
   72    std::string readTitle(buffer);
 
   73    std::string::size_type location = readTitle.find(
"Energy");
 
   74    if (location != std::string::npos) readTitle.erase(location);
 
   75    Utils::trim(readTitle);
 
   77    location = readTitle.find_first_not_of(
" \t\n\r");
 
   78    if (location != std::string::npos)
 
   85    for (
unsigned int i = 1; i <= natoms; i++) {
 
   86      if (!ifs.getline(buffer, BUFF_SIZE)) {
 
   87        errorMsg << 
"Problems reading an XYZ file: " 
   88                 << 
"Could not read line #" << i + 2 << 
", file error.\n" 
   89                 << 
" According to line one, there should be " << natoms
 
   90                 << 
" atoms, and therefore " << natoms + 2
 
   91                 << 
" lines in the file.";
 
   93        strcpy(painCave.errMsg, errorMsg.str().c_str());
 
   95        painCave.severity = OPENMD_WARNING;
 
   99      StringTokenizer tokenizer(buffer, 
" ;,\t\n\r");
 
  100      std::vector<std::string> vs = tokenizer.getAllTokens();
 
  103        errorMsg << 
"Problems reading an XYZ file: " 
  104                 << 
"Could not read line #" << i + 2 << 
".\n" 
  105                 << 
"OpenBabel found the line '" << buffer << 
"'\n" 
  106                 << 
"According to the specifications, this line should contain " 
  107                    "exactly 4 entries, separated by white space.\n" 
  108                 << 
"However, OpenBabel found " << vs.size() << 
" items.";
 
  110        strcpy(painCave.errMsg, errorMsg.str().c_str());
 
  111        painCave.isFatal  = 0;
 
  112        painCave.severity = OPENMD_WARNING;
 
  125      XYZAtom* atom = 
new XYZAtom();
 
  126      mol_.push_back(atom);
 
  130      if (atomicNum == 0) {
 
  134        atomicNum = atoi(vs[0].c_str());
 
  137      atom->atomicNum = atomicNum;
 
  143      double x = strtod((
char*)vs[1].c_str(), &endptr);
 
  144      if (endptr == (
char*)vs[1].c_str()) {
 
  145        errorMsg << 
"Problems reading an XYZ file: " 
  146                 << 
"Could not read line #" << i + 2 << 
".\n" 
  147                 << 
"OpenBabel found the line '" << buffer << 
"'\n" 
  148                 << 
"According to the specifications, this line should contain " 
  149                    "exactly 4 entries, separated by white space.\n" 
  150                 << 
"OpenBabel could not interpret item #1 as a number.";
 
  152        strcpy(painCave.errMsg, errorMsg.str().c_str());
 
  153        painCave.isFatal = 1;
 
  156      double y = strtod((
char*)vs[2].c_str(), &endptr);
 
  157      if (endptr == (
char*)vs[2].c_str()) {
 
  158        errorMsg << 
"Problems reading an XYZ file: " 
  159                 << 
"Could not read line #" << i + 2 << 
".\n" 
  160                 << 
"OpenBabel found the line '" << buffer << 
"'\n" 
  161                 << 
"According to the specifications, this line should contain " 
  162                    "exactly 4 entries, separated by white space.\n" 
  163                 << 
"OpenBabel could not interpret item #2 as a number.";
 
  165        strcpy(painCave.errMsg, errorMsg.str().c_str());
 
  166        painCave.isFatal = 1;
 
  169      double z = strtod((
char*)vs[3].c_str(), &endptr);
 
  170      if (endptr == (
char*)vs[3].c_str()) {
 
  171        errorMsg << 
"Problems reading an XYZ file: " 
  172                 << 
"Could not read line #" << i + 2 << 
".\n" 
  173                 << 
"OpenBabel found the line '" << buffer << 
"'\n" 
  174                 << 
"According to the specifications, this line should contain " 
  175                    "exactly 4 entries, separated by white space.\n" 
  176                 << 
"OpenBabel could not interpret item #3 as a number.";
 
  178        strcpy(painCave.errMsg, errorMsg.str().c_str());
 
  179        painCave.isFatal  = 0;
 
  180        painCave.severity = OPENMD_WARNING;
 
  184      atom->pos = Vector3d(x, y, z);  
 
  188        std::string::size_type decimal = vs[4].find(
'.');
 
  189        if (decimal != std::string::npos) {  
 
  190          double charge = strtod((
char*)vs[4].c_str(), &endptr);
 
  191          if (endptr != (
char*)vs[4].c_str()) atom->charge = charge;
 
  200      ifs.getline(buffer, BUFF_SIZE);
 
  201    } 
while (strlen(buffer) == 0 && !ifs.eof());
 
This basic Periodic Table class was originally taken from the data.h file in OpenBabel.
 
int GetAtomicNum(const char *str)
 
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.