Skip to content

Commit

Permalink
Merge pull request #603 from ghutchis/read-extended-xyz
Browse files Browse the repository at this point in the history
Transparent support for ASE "extended XYZ" files
  • Loading branch information
ghutchis authored Jun 2, 2021
2 parents 7f195a3 + e1dbd34 commit 11c98d1
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 37 deletions.
83 changes: 58 additions & 25 deletions avogadro/io/xyzformat.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
/******************************************************************************
This source file is part of the Avogadro project.
Copyright 2013 Kitware, Inc.
This source code is released under the New BSD License, (the "License").
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#include "xyzformat.h"

#include <avogadro/core/elements.h>
#include <avogadro/core/molecule.h>
#include <avogadro/core/unitcell.h>
#include <avogadro/core/utilities.h>
#include <avogadro/core/vector.h>

Expand All @@ -31,10 +21,10 @@

using json = nlohmann::json;

using std::string;
using std::endl;
using std::getline;
using std::string;
using std::string;
using std::vector;

namespace Avogadro {
Expand All @@ -52,13 +42,9 @@ using Core::trimmed;
using std::isalpha;
#endif

XyzFormat::XyzFormat()
{
}
XyzFormat::XyzFormat() {}

XyzFormat::~XyzFormat()
{
}
XyzFormat::~XyzFormat() {}

bool XyzFormat::read(std::istream& inStream, Core::Molecule& mol)
{
Expand All @@ -80,6 +66,31 @@ bool XyzFormat::read(std::istream& inStream, Core::Molecule& mol)
if (!buffer.empty())
mol.setData("name", trimmed(buffer));

// check for Lattice= in an extended XYZ from ASE and company
// e.g. Lattice="H11 H21 H31 H12 H22 H32 H13 H23 H33"
// https://atomsk.univ-lille.fr/doc/en/format_xyz.html
// https://gitlab.com/ase/ase/-/merge_requests/62
std::size_t start = buffer.find("Lattice=\"");
if (start != std::string::npos) {
// step through bit by bit until we hit the next quote character
start = start + 9;
std::size_t end = buffer.find('\"', start);
std::string lattice = buffer.substr(start, (end - start));

vector<string> tokens(split(lattice, ' '));
if (tokens.size() == 9) {
Vector3 v1(lexicalCast<double>(tokens[0]), lexicalCast<double>(tokens[1]),
lexicalCast<double>(tokens[2]));
Vector3 v2(lexicalCast<double>(tokens[3]), lexicalCast<double>(tokens[4]),
lexicalCast<double>(tokens[5]));
Vector3 v3(lexicalCast<double>(tokens[6]), lexicalCast<double>(tokens[7]),
lexicalCast<double>(tokens[8]));

Core::UnitCell* cell = new Core::UnitCell(v1, v2, v3);
mol.setUnitCell(cell);
}
}

// Parse atoms
for (size_t i = 0; i < numAtoms; ++i) {
getline(inStream, buffer);
Expand Down Expand Up @@ -162,10 +173,31 @@ bool XyzFormat::write(std::ostream& outStream, const Core::Molecule& mol)
size_t numAtoms = mol.atomCount();

outStream << numAtoms << std::endl;
if (mol.data("name").toString().length())
outStream << mol.data("name").toString() << endl;
else
outStream << "XYZ file generated by Avogadro.\n";

if (mol.unitCell()) {
// default to including Lattice for extended XYZ if present
// https://atomsk.univ-lille.fr/doc/en/format_xyz.html
// https://gitlab.com/ase/ase/-/merge_requests/62
outStream << "Lattice=\"";
outStream << mol.unitCell()->aVector().x() << ' ';
outStream << mol.unitCell()->aVector().y() << ' ';
outStream << mol.unitCell()->aVector().z() << ' ';

outStream << mol.unitCell()->bVector().x() << ' ';
outStream << mol.unitCell()->bVector().y() << ' ';
outStream << mol.unitCell()->bVector().z() << ' ';

outStream << mol.unitCell()->cVector().x() << ' ';
outStream << mol.unitCell()->cVector().y() << ' ';
outStream << mol.unitCell()->cVector().z();

outStream << "\" Properties=species:S:1:pos:R:3" << endl;
} else {
if (mol.data("name").toString().length())
outStream << mol.data("name").toString() << endl;
else
outStream << "XYZ file generated by Avogadro.\n";
}

for (size_t i = 0; i < numAtoms; ++i) {
Atom atom = mol.atom(i);
Expand All @@ -190,6 +222,7 @@ std::vector<std::string> XyzFormat::fileExtensions() const
{
std::vector<std::string> ext;
ext.push_back("xyz");
ext.push_back("extxyz");
return ext;
}

Expand All @@ -200,5 +233,5 @@ std::vector<std::string> XyzFormat::mimeTypes() const
return mime;
}

} // end Io namespace
} // end Avogadro namespace
} // namespace Io
} // namespace Avogadro
13 changes: 1 addition & 12 deletions avogadro/io/xyzformat.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
/******************************************************************************
This source file is part of the Avogadro project.
Copyright 2013 Kitware, Inc.
This source code is released under the New BSD License, (the "License").
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#ifndef AVOGADRO_IO_XYZFORMAT_H
Expand Down

0 comments on commit 11c98d1

Please sign in to comment.