Skip to content

Commit

Permalink
Merge pull request #937 from ghutchis/use-cjson-openbabel
Browse files Browse the repository at this point in the history
Check for Open Babel CJSON support: use it if available
  • Loading branch information
ghutchis authored Jun 10, 2022
2 parents 51b26ae + 643e624 commit d092955
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 109 deletions.
73 changes: 39 additions & 34 deletions avogadro/qtplugins/openbabel/obfileformat.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
/******************************************************************************
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 "obfileformat.h"

#include "obprocess.h"

#include <avogadro/io/cmlformat.h>
#include <avogadro/io/pdbformat.h>

#include <nlohmann/json.hpp>

#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
#include <QtCore/QTimer>

Expand Down Expand Up @@ -81,11 +68,12 @@ OBFileFormat::OBFileFormat(const std::string& name_,
const std::string& specificationUrl_,
const std::vector<std::string> fileExtensions_,
const std::vector<std::string> mimeTypes_,
bool fileOnly_)
const std::string& defaultFormat_, bool fileOnly_)
: Io::FileFormat(), m_description(description_),
m_fileExtensions(fileExtensions_), m_mimeTypes(mimeTypes_),
m_identifier(identifier_), m_name(name_),
m_specificationUrl(specificationUrl_), m_fileOnly(fileOnly_)
m_specificationUrl(specificationUrl_), m_defaultFormat(defaultFormat_),
m_fileOnly(fileOnly_)
{}

OBFileFormat::~OBFileFormat() {}
Expand Down Expand Up @@ -132,8 +120,10 @@ bool OBFileFormat::read(std::istream& in, Core::Molecule& molecule)
}

// check if we're going to read to a different format
// default is CML
QString format = QString::fromStdString(opts.value("format", "cml"));
// default is CML or CJSON
QString format =
QString::fromStdString(opts.value("format", m_defaultFormat));
qDebug() << "Reading to format: " << format << m_defaultFormat.c_str();

if (!m_fileOnly) {
// Determine length of data
Expand Down Expand Up @@ -187,17 +177,22 @@ bool OBFileFormat::read(std::istream& in, Core::Molecule& molecule)
}

if (format == "cml") {
Io::CmlFormat cmlReader;
if (!cmlReader.readString(std::string(output.constData()), molecule)) {
if (!m_cmlFormat.readString(std::string(output.constData()), molecule)) {
appendError(std::string("Error while reading OpenBabel-generated CML:"));
appendError(cmlReader.error());
appendError(m_cmlFormat.error());
return false;
}
} else if (format == "cjson") {
if (!m_cjsonFormat.readString(std::string(output.constData()), molecule)) {
appendError(
std::string("Error while reading OpenBabel-generated CJSON:"));
appendError(m_cjsonFormat.error());
return false;
}
} else if (format == "pdb") {
Io::PdbFormat pdbReader;
if (!pdbReader.readString(std::string(output.constData()), molecule)) {
if (!m_pdbFormat.readString(std::string(output.constData()), molecule)) {
appendError(std::string("Error while reading OpenBabel-generated PDB:"));
appendError(pdbReader.error());
appendError(m_pdbFormat.error());
return false;
}
} else {
Expand Down Expand Up @@ -225,13 +220,22 @@ bool OBFileFormat::write(std::ostream& out, const Core::Molecule& molecule)
}
}

// Generate CML to give to OpenBabel
std::string cml;
Io::CmlFormat cmlWriter;
if (!cmlWriter.writeString(cml, molecule)) {
appendError(std::string("Error while writing CML:"));
appendError(cmlWriter.error());
return false;
qDebug() << " writing to " << m_defaultFormat.c_str();

// Generate CML or CJSON to give to OpenBabel
std::string outputString;
if (m_defaultFormat == "cml") {
if (!m_cmlFormat.writeString(outputString, molecule)) {
appendError(std::string("Error while writing CML:"));
appendError(m_cmlFormat.error());
return false;
}
} else if (m_defaultFormat == "cjson") {
if (!m_cjsonFormat.writeString(outputString, molecule)) {
appendError(std::string("Error while writing CJSON:"));
appendError(m_cjsonFormat.error());
return false;
}
}

// Block until the OpenBabel conversion finishes:
Expand All @@ -246,7 +250,8 @@ bool OBFileFormat::write(std::ostream& out, const Core::Molecule& molecule)
appendError("Internal error: No file extensions set.");
return false;
}
proc.convert(QByteArray(cml.c_str()), "cml",

proc.convert(QByteArray(outputString.c_str()), m_defaultFormat.c_str(),
QString::fromStdString(m_fileExtensions.front()), options);

QByteArray output;
Expand Down Expand Up @@ -274,7 +279,7 @@ Io::FileFormat* OBFileFormat::newInstance() const
{
return new OBFileFormat(m_name, m_identifier, m_description,
m_specificationUrl, m_fileExtensions, m_mimeTypes,
m_fileOnly);
m_defaultFormat, m_fileOnly);
}

} // namespace QtPlugins
Expand Down
24 changes: 12 additions & 12 deletions avogadro/qtplugins/openbabel/obfileformat.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
/******************************************************************************
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_QTPLUGINS_OBFILEFORMAT_H
#define AVOGADRO_QTPLUGINS_OBFILEFORMAT_H

#include <avogadro/io/fileformat.h>

#include <avogadro/io/cjsonformat.h>
#include <avogadro/io/cmlformat.h>
#include <avogadro/io/pdbformat.h>

namespace Avogadro {
namespace QtPlugins {

Expand All @@ -34,6 +27,7 @@ class OBFileFormat : public Avogadro::Io::FileFormat
const std::string& specificationUrl_,
const std::vector<std::string> fileExtensions_,
const std::vector<std::string> mimeTypes_,
const std::string& defaultFormat_,
bool fileOnly_ = false);
~OBFileFormat() override;

Expand Down Expand Up @@ -81,7 +75,13 @@ class OBFileFormat : public Avogadro::Io::FileFormat
std::string m_identifier;
std::string m_name;
std::string m_specificationUrl;
std::string m_defaultFormat;
bool m_fileOnly;

// internal format objects for interchange with obabel
Io::CjsonFormat m_cjsonFormat;
Io::CmlFormat m_cmlFormat;
Io::PdbFormat m_pdbFormat;
};

} // namespace QtPlugins
Expand Down
13 changes: 1 addition & 12 deletions avogadro/qtplugins/openbabel/obforcefielddialog.cpp
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").
******************************************************************************/

#include "obforcefielddialog.h"
Expand Down
13 changes: 1 addition & 12 deletions avogadro/qtplugins/openbabel/obforcefielddialog.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_QTPLUGINS_OBFORCEFIELDDIALOG_H
Expand Down
14 changes: 10 additions & 4 deletions avogadro/qtplugins/openbabel/obprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,17 +325,23 @@ void OBProcess::queryChargesPrepare()
}

bool OBProcess::optimizeGeometry(const QByteArray& mol,
const QStringList& options)
const QStringList& options,
const std::string format)
{
if (!tryLockProcess()) {
qWarning() << "OBProcess::optimizeGeometry(): process already in use.";
return false;
}

QStringList realOptions;
realOptions << "-icml"
<< "-ocml"
<< "--minimize"
if (format == "cjson") {
realOptions << "-icjson"
<< "-ocjson";
} else {
realOptions << "-icml"
<< "-ocml";
}
realOptions << "--minimize"
<< "--noh" // new in OB 3.0.1
<< "--log" << options;

Expand Down
4 changes: 2 additions & 2 deletions avogadro/qtplugins/openbabel/obprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ public slots:
* optimization finishes, optimizeGeometryFinished will be emitted with the
* result of the optimization.
*
* The optimization is started with
* The optimization is started with, e.g.
* `obabel -icml -ocml --minimize <options>`
*
* The standard output is recorded and returned by optimizeGeometryFinished.
Expand All @@ -279,7 +279,7 @@ public slots:
*
* @return True if the process started successfully, false otherwise.
*/
bool optimizeGeometry(const QByteArray& cml, const QStringList& options);
bool optimizeGeometry(const QByteArray& cml, const QStringList& options, std::string format = "cml");
signals:
/**
* Emitted with the standard output of the process when it finishes.
Expand Down
Loading

0 comments on commit d092955

Please sign in to comment.