Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read ORCA coordinate sets #1808

Merged
merged 6 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions avogadro/core/variant-inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ inline Variant::Variant(const Vector3f& v) : m_type(Vector)
m_value.vector = _v;
}

template <>
inline Variant::Variant(const std::vector<double>& v) : m_type(Matrix)
{
MatrixX* m = new MatrixX(v.size(), 1);
for (size_t i = 0; i < v.size(); ++i)
m->coeffRef(i, 0) = v[i];
m_value.matrix = m;
}

inline Variant::Variant(const Variant& variant) : m_type(variant.type())
{
if (m_type == String)
Expand Down Expand Up @@ -92,6 +101,18 @@ inline bool Variant::setValue(double x, double y, double z)
return true;
}

inline bool Variant::setValue(const std::vector<double>& v)
{
clear();

m_type = Matrix;
m_value.matrix = new MatrixX(v.size(), 1);
for (size_t i = 0; i < v.size(); ++i)
m_value.matrix->coeffRef(i, 0) = v[i];

return true;
}

template <typename T>
inline bool Variant::setValue(T v)
{
Expand Down Expand Up @@ -415,6 +436,19 @@ inline const Vector3& Variant::value() const
return nullVector;
}

template <>
inline std::vector<double> Variant::value() const
{
if (m_type == Matrix && m_value.matrix->cols() == 1) {
std::vector<double> list(m_value.matrix->rows());
for (int i = 0; i < m_value.matrix->rows(); ++i)
list[i] = m_value.matrix->coeff(i, 0);
return list;
}

return std::vector<double>();
}

inline void Variant::clear()
{
if (m_type == String) {
Expand Down Expand Up @@ -516,6 +550,11 @@ inline Vector3 Variant::toVector3() const
return value<Vector3>();
}

inline std::vector<double> Variant::toList() const
{
return value<std::vector<double>>();
}

// --- Operators ----------------------------------------------------------- //
inline Variant& Variant::operator=(const Variant& variant)
{
Expand Down
6 changes: 6 additions & 0 deletions avogadro/core/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ class AVOGADROCORE_EXPORT Variant
/** Sets the value of the variant to a 3D vector */
bool setValue(double x, double y, double z);

/** Sets the value of the variant to a vector<double> */
bool setValue(const std::vector<double>& v);

/** @return the value of the variant in the type given by \c T. */
template <typename T>
T value() const;
Expand Down Expand Up @@ -126,6 +129,9 @@ class AVOGADROCORE_EXPORT Variant
/** @return the value of the variant as a Vector3 */
inline Vector3 toVector3() const;

/** @return the value as a vector<double> */
inline std::vector<double> toList() const;

/**
* @return a reference to the value of the variant as a MatrixX.
* This method will not perform any casting -- if type() is not exactly
Expand Down
48 changes: 46 additions & 2 deletions avogadro/io/xyzformat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,34 @@ using Core::trimmed;
using std::isalpha;
#endif

bool findEnergy(const std::string& buffer, double& energyValue)
{
// Check for energy in the comment line
// orca uses E -680.044112849966 (with spaces)
// xtb uses energy: -680.044112849966
// Open Babel uses Energy: -680.044112849966
std::size_t energyStart = buffer.find("energy:");
std::size_t offset = 7;
if (energyStart == std::string::npos) {
energyStart = buffer.find("Energy:");
}
if (energyStart == std::string::npos) {
energyStart = buffer.find(" E ");
offset = 3;
}

if (energyStart != std::string::npos) {
// find the next whitespace or end of the string
std::size_t energyEnd = buffer.find_first_of(" \t", energyStart + offset);
if (energyEnd == std::string::npos)
energyEnd = buffer.size();
std::string energy = buffer.substr(energyStart + offset, energyEnd);
energyValue = lexicalCast<double>(energy);
return true;
}
return false;
}

bool XyzFormat::read(std::istream& inStream, Core::Molecule& mol)
{
json opts;
Expand All @@ -53,10 +81,17 @@ bool XyzFormat::read(std::istream& inStream, Core::Molecule& mol)

string buffer;
getline(inStream, buffer); // Finish the first line
getline(inStream, buffer);
getline(inStream, buffer); // comment or name or energy
if (!buffer.empty())
mol.setData("name", trimmed(buffer));

double energy = 0.0;
std::vector<double> energies;
if (findEnergy(buffer, energy)) {
mol.setData("totalEnergy", energy);
energies.push_back(energy);
}

// 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
Expand Down Expand Up @@ -171,7 +206,12 @@ bool XyzFormat::read(std::istream& inStream, Core::Molecule& mol)
}

if ((numAtoms2 = lexicalCast<int>(buffer)) && numAtoms == numAtoms2) {
getline(inStream, buffer); // Skip the blank
getline(inStream, buffer); // comment line
// check for properties in the comment line
if (findEnergy(buffer, energy)) {
energies.push_back(energy);
}

mol.setCoordinate3d(mol.atomPositions3d(), 0);
int coordSet = 1;
bool done = false;
Expand Down Expand Up @@ -240,6 +280,10 @@ bool XyzFormat::read(std::istream& inStream, Core::Molecule& mol)
mol.setPartialCharges("From File", chargesMatrix);
}

if (energies.size() > 1) {
mol.setData("energies", energies);
}

return true;
}

Expand Down
25 changes: 25 additions & 0 deletions avogadro/quantumio/orca.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ bool ORCAOutput::read(std::istream& in, Core::Molecule& molecule)
molecule.setSpectra("NMR", nmrData);
}

// this should be the final coordinate set (e.g. the optimized geometry)
molecule.setCoordinate3d(molecule.atomPositions3d(), 0);
if (m_coordSets.size() > 1) {
for (unsigned int i = 0; i < m_coordSets.size(); i++) {
Array<Vector3> positions;
positions.reserve(molecule.atomCount());
for (size_t j = 0; j < molecule.atomCount(); ++j) {
positions.push_back(m_coordSets[i][j] * BOHR_TO_ANGSTROM);
}
molecule.setCoordinate3d(positions, i + 1);
}
}

// guess bonds and bond orders
molecule.perceiveBondsSimple();
molecule.perceiveBondOrders();
Expand Down Expand Up @@ -133,6 +146,9 @@ bool ORCAOutput::read(std::istream& in, Core::Molecule& molecule)
molecule.setData("totalCharge", m_charge);
molecule.setData("totalSpinMultiplicity", m_spin);
molecule.setData("dipoleMoment", m_dipoleMoment);
molecule.setData("totalEnergy", m_totalEnergy);
if (m_energies.size() > 1)
molecule.setData("energies", m_energies);

return true;
}
Expand All @@ -152,6 +168,10 @@ void ORCAOutput::processLine(std::istream& in, GaussianSet* basis)
if (Core::contains(key, "CARTESIAN COORDINATES (A.U.)")) {
m_coordFactor = 1.; // leave the coords in BOHR ....
m_currentMode = Atoms;
// if there are any current coordinates, push them back
if (m_atomPos.size() > 0) {
m_coordSets.push_back(m_atomPos);
}
m_atomPos.clear();
m_atomNums.clear();
m_atomLabel.clear();
Expand Down Expand Up @@ -197,6 +217,11 @@ void ORCAOutput::processLine(std::istream& in, GaussianSet* basis)
list = Core::split(key, ' ');
if (list.size() > 3)
m_spin = Core::lexicalCast<int>(list[3]);
} else if (Core::contains(key, "FINAL SINGLE POINT ENERGY")) {
list = Core::split(key, ' ');
if (list.size() > 4)
m_totalEnergy = Core::lexicalCast<double>(list[4]);
m_energies.push_back(m_totalEnergy);
} else if (Core::contains(key, "TOTAL NUMBER OF BASIS SET")) {
m_currentMode = NotParsing; // no longer reading GTOs
} else if (Core::contains(key, "NUMBER OF CARTESIAN GAUSSIAN BASIS")) {
Expand Down
3 changes: 3 additions & 0 deletions avogadro/quantumio/orca.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@

std::vector<int> m_atomNums;
std::vector<Eigen::Vector3d> m_atomPos;
std::vector<std::vector<Eigen::Vector3d>> m_coordSets;

Check notice on line 64 in avogadro/quantumio/orca.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/quantumio/orca.h#L64

class member 'ORCAOutput::m_coordSets' is never used.
std::vector<double> m_energies;

Check notice on line 65 in avogadro/quantumio/orca.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/quantumio/orca.h#L65

class member 'ORCAOutput::m_energies' is never used.

Vector3 m_dipoleMoment;

Expand Down Expand Up @@ -103,6 +105,7 @@
int m_homo;
int m_charge;
int m_spin;
double m_totalEnergy;

Check notice on line 108 in avogadro/quantumio/orca.h

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

avogadro/quantumio/orca.h#L108

class member 'ORCAOutput::m_totalEnergy' is never used.

int m_currentAtom;
unsigned int m_numBasisFunctions;
Expand Down
Loading