diff --git a/avogadro/io/CMakeLists.txt b/avogadro/io/CMakeLists.txt index 3429260bc1..213cecfe3d 100644 --- a/avogadro/io/CMakeLists.txt +++ b/avogadro/io/CMakeLists.txt @@ -31,6 +31,7 @@ set(HEADERS fileformat.h fileformatmanager.h gromacsformat.h + mdcrdformat.h mdlformat.h pdbformat.h poscarformat.h @@ -46,6 +47,7 @@ set(SOURCES fileformat.cpp fileformatmanager.cpp gromacsformat.cpp + mdcrdformat.cpp mdlformat.cpp pdbformat.cpp poscarformat.cpp diff --git a/avogadro/io/fileformatmanager.cpp b/avogadro/io/fileformatmanager.cpp index c308fc2d17..3fc98e9fa8 100644 --- a/avogadro/io/fileformatmanager.cpp +++ b/avogadro/io/fileformatmanager.cpp @@ -23,6 +23,7 @@ #include "dcdformat.h" #include "gromacsformat.h" #include "lammpsformat.h" +#include "mdcrdformat.h" #include "mdlformat.h" #include "pdbformat.h" #include "poscarformat.h" @@ -162,7 +163,7 @@ bool FileFormatManager::addFormat(FileFormat* format) namespace { // Lookup each key from "keys" in "map", and remove "val" from the Map's // data value (which is a vector of ValueType) -template +template void removeFromMap(Map& map, const VectorOfKeys& keys, const ValueType& val) { typedef typename VectorOfKeys::const_iterator KeysIter; @@ -180,7 +181,7 @@ void removeFromMap(Map& map, const VectorOfKeys& keys, const ValueType& val) } } } -} +} // namespace bool FileFormatManager::removeFormat(const std::string& identifier) { @@ -291,6 +292,7 @@ FileFormatManager::FileFormatManager() addFormat(new CmlFormat); addFormat(new CjsonFormat); addFormat(new GromacsFormat); + addFormat(new MdcrdFormat); addFormat(new MdlFormat); addFormat(new PdbFormat); addFormat(new PoscarFormat); @@ -385,5 +387,5 @@ void FileFormatManager::appendError(const std::string& errorMessage) m_error += errorMessage + "\n"; } -} // end Io namespace -} // end Avogadro namespace +} // namespace Io +} // namespace Avogadro diff --git a/avogadro/io/mdcrdformat.cpp b/avogadro/io/mdcrdformat.cpp new file mode 100644 index 0000000000..2b883c0124 --- /dev/null +++ b/avogadro/io/mdcrdformat.cpp @@ -0,0 +1,103 @@ +/****************************************************************************** + + 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. + +******************************************************************************/ + +#include "mdcrdformat.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using std::endl; +using std::getline; +using std::map; +using std::string; +using std::to_string; +using std::vector; + +namespace Avogadro { +namespace Io { + +using Core::Array; +using Core::Atom; +using Core::Elements; +using Core::lexicalCast; +using Core::Molecule; +using Core::split; +using Core::trimmed; +using Core::UnitCell; + +#ifndef _WIN32 +using std::isalpha; +#endif + +#define MDCRD_EOF -1 + +MdcrdFormat::MdcrdFormat() {} + +MdcrdFormat::~MdcrdFormat() {} + +bool MdcrdFormat::read(std::istream& inStream, Core::Molecule& mol) +{ + string title; + float x, y, z; + + typedef map AtomTypeMap; + AtomTypeMap atomTypes; + + Array positions; + + getline(inStream, title); + mol.setData("name", title); + + while (inStream >> x >> y >> z) { + Vector3 pos(x, y, z); + positions.push_back(pos); + } + + mol.setCoordinate3d(positions, 0); + return true; +} + +bool MdcrdFormat::write(std::ostream& outStream, const Core::Molecule& mol) +{ + return false; +} + +std::vector MdcrdFormat::fileExtensions() const +{ + std::vector ext; + ext.push_back("mdcrd"); + return ext; +} + +std::vector MdcrdFormat::mimeTypes() const +{ + std::vector mime; + mime.push_back("N/A"); + return mime; +} + +} // namespace Io +} // namespace Avogadro \ No newline at end of file diff --git a/avogadro/io/mdcrdformat.h b/avogadro/io/mdcrdformat.h new file mode 100644 index 0000000000..4e655777ec --- /dev/null +++ b/avogadro/io/mdcrdformat.h @@ -0,0 +1,62 @@ +/****************************************************************************** + + 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. + +******************************************************************************/ + +#ifndef AVOGADRO_IO_MDCRDFORMAT_H +#define AVOGADRO_IO_MDCRDFORMAT_H + +#include "fileformat.h" + +namespace Avogadro { +namespace Io { + +/** + * @class MdcrdFormat mdcrdformat.h + * @brief Implementation of the generic mdcrd format. + * @author David C. Lonie + */ + +class AVOGADROIO_EXPORT MdcrdFormat : public FileFormat +{ +public: + MdcrdFormat(); + ~MdcrdFormat() override; + + Operations supportedOperations() const override + { + return ReadWrite | MultiMolecule | File | Stream | String; + } + + FileFormat* newInstance() const override { return new MdcrdFormat; } + std::string identifier() const override { return "Avogadro: AMBER MDCRD"; } + std::string name() const override { return "MDCRD"; } + std::string description() const override + { + return "Generic format that tabulates atomic symbols and 3D positions."; + } + + std::string specificationUrl() const override { return ""; } + + std::vector fileExtensions() const override; + std::vector mimeTypes() const override; + + bool read(std::istream& inStream, Core::Molecule& molecule) override; + bool write(std::ostream& outStream, const Core::Molecule& molecule) override; +}; + +} // namespace Io +} // namespace Avogadro + +#endif // AVOGADRO_IO_MDCRDFORMAT_H diff --git a/avogadro/qtgui/CMakeLists.txt b/avogadro/qtgui/CMakeLists.txt index 2c7f87a683..2e5291774a 100644 --- a/avogadro/qtgui/CMakeLists.txt +++ b/avogadro/qtgui/CMakeLists.txt @@ -44,6 +44,7 @@ set(HEADERS interfacewidget.h meshgenerator.h molecule.h + moleculeinfodialog.h moleculemodel.h multiviewwidget.h periodictableview.h @@ -74,6 +75,7 @@ set(SOURCES interfacewidget.cpp meshgenerator.cpp molecule.cpp + moleculeinfodialog.cpp moleculemodel.cpp multiviewwidget.cpp periodictablescene_p.cpp @@ -90,6 +92,7 @@ set(SOURCES set(UIS customelementdialog.ui + moleculeinfodialog.ui ) qt5_wrap_ui(UI_SOURCES ${UIS}) list(APPEND SOURCES ${UI_SOURCES}) diff --git a/avogadro/qtgui/moleculeinfodialog.cpp b/avogadro/qtgui/moleculeinfodialog.cpp new file mode 100644 index 0000000000..ed85e6304f --- /dev/null +++ b/avogadro/qtgui/moleculeinfodialog.cpp @@ -0,0 +1,161 @@ +/****************************************************************************** + + This source file is part of the MoleQueue 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. + +******************************************************************************/ + +#include "moleculeinfodialog.h" +#include "ui_moleculeinfodialog.h" + +#include "molecule.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +using std::endl; +using std::getline; +using std::map; +using std::string; +using std::to_string; +using std::vector; + +namespace Avogadro { +namespace QtGui { + +using Core::Array; +using Core::Atom; +using Core::Elements; +using Core::lexicalCast; +using Core::split; +using Core::trimmed; +using Core::UnitCell; + +using QtGui::Molecule; + +MoleculeInfoDialog::MoleculeInfoDialog(QWidget* p) + : QDialog(p), m_ui(new Ui::MoleculeInfoDialog), m_currentVolume(0.) +{ + m_ui->setupUi(this); +} + +MoleculeInfoDialog::~MoleculeInfoDialog() +{ + delete m_ui; +} + +int MoleculeInfoDialog::atomCount() const +{ + return m_ui->numAtoms->value(); +} + +bool MoleculeInfoDialog::hasBoxCoordinates() const +{ + return m_ui->boxCheck->isChecked(); +} + +bool MoleculeInfoDialog::resolve(QWidget* p, Molecule& mol, QString fname) +{ + if (fname.toStdString() == "mdcrd") { + MoleculeInfoDialog dlg(p); + int reply = dlg.exec(); + if (reply != QDialog::Accepted) + return false; + + typedef map AtomTypeMap; + AtomTypeMap atomTypes; + unsigned char customElementCounter = CustomElementMin; + int coordSet = 0; + + size_t natoms = dlg.atomCount(); + + Array positions; + positions.reserve(natoms); + + mol.setCoordinate3d(0); + Array molData = mol.atomPositions3d(); + + size_t j = 0, i = 0; + + while (j < molData.size()) { + if (coordSet == 0) { + Vector3 pos(molData[j][0], molData[j][1], molData[j][2]); + + AtomTypeMap::const_iterator it; + atomTypes.insert(std::make_pair(to_string(i), customElementCounter++)); + it = atomTypes.find(to_string(i)); + Atom newAtom = mol.addAtom(it->second); + newAtom.setPosition3d(pos); + } else { + Vector3 pos(molData[j][0], molData[j][1], molData[j][2]); + positions.push_back(pos); + } + + ++i; + ++j; + + if (i == natoms) { + i = 0; + if (coordSet == 0) { + // Set the custom element map if needed + if (!atomTypes.empty()) { + Molecule::CustomElementMap elementMap; + for (AtomTypeMap::const_iterator it = atomTypes.begin(), + itEnd = atomTypes.end(); + it != itEnd; ++it) { + elementMap.insert( + std::make_pair(it->second, "Atom " + it->first)); + } + mol.setCustomElementMap(elementMap); + } + mol.setCoordinate3d(mol.atomPositions3d(), coordSet++); + } else { + mol.setCoordinate3d(positions, coordSet++); + positions.clear(); + } + + if (dlg.hasBoxCoordinates()) { + mol.setUnitCell(new UnitCell(Vector3(molData[j][0], 0, 0), + Vector3(0, molData[j][1], 0), + Vector3(0, 0, molData[j][2]))); + ++j; + } + } + } + + // We need to check whether the end of the coordinates coincides with + // completion of a timestep frame. If i != 0, it implies an incomplete + // timestep frame and there is discrepancy with the parameters inputted in + // the dialog. + if (i == 0) { + return true; + } else { + QMessageBox::warning(p, tr("Cannot import trajectory"), + tr("Error parsing trajectory input. Please check " + "the inputs specified.")); + return false; + } + } + return false; +} + +} // namespace QtGui +} // namespace Avogadro diff --git a/avogadro/qtgui/moleculeinfodialog.h b/avogadro/qtgui/moleculeinfodialog.h new file mode 100644 index 0000000000..e6c978d5f0 --- /dev/null +++ b/avogadro/qtgui/moleculeinfodialog.h @@ -0,0 +1,57 @@ +/****************************************************************************** + + This source file is part of the MoleQueue 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. + +******************************************************************************/ + +#ifndef AVOGADRO_QTGUI_MOLECULEINFODIALOG_H +#define AVOGADRO_QTGUI_MOLECULEINFODIALOG_H + +#include "avogadroqtguiexport.h" +#include + +namespace Avogadro { +namespace QtGui { + +class Molecule; + +namespace Ui { +class MoleculeInfoDialog; +} + +/** + * @brief The MoleculeInfoDialog class provides a dialog with options for + * adjusting the volume of a Molecule's UnitCell. + */ +class AVOGADROQTGUI_EXPORT MoleculeInfoDialog : public QDialog +{ + Q_OBJECT + +public: + explicit MoleculeInfoDialog(QWidget* parent = 0); + ~MoleculeInfoDialog(); + + int atomCount() const; + bool hasBoxCoordinates() const; + + static bool resolve(QWidget* p, Molecule& mol, QString fname); + +private: + Ui::MoleculeInfoDialog* m_ui; + double m_currentVolume; +}; + +} // namespace QtGui +} // namespace Avogadro + +#endif // AVOGADRO_QTGUI_MOLECULEINFODIALOG_H diff --git a/avogadro/qtgui/moleculeinfodialog.ui b/avogadro/qtgui/moleculeinfodialog.ui new file mode 100644 index 0000000000..71ae7d907e --- /dev/null +++ b/avogadro/qtgui/moleculeinfodialog.ui @@ -0,0 +1,129 @@ + + + Avogadro::QtGui::MoleculeInfoDialog + + + + 0 + 0 + 348 + 51 + + + + Additional Molecule Information + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + &Number of Atoms: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + numAtoms + + + + + + + 1 + + + 99999 + + + 1 + + + 1 + + + + + + + + + &Trajectory contains box coordinates + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + numAtoms + boxCheck + buttonBox + + + + + buttonBox + accepted() + Avogadro::QtGui::MoleculeInfoDialog + accept() + + + 374 + 222 + + + 157 + 274 + + + + + buttonBox + rejected() + Avogadro::QtGui::MoleculeInfoDialog + reject() + + + 385 + 228 + + + 286 + 274 + + + + +