add restart file inspector showing system info, data file, and snapshot image

This commit is contained in:
Axel Kohlmeyer
2024-08-05 20:04:44 -04:00
parent 7561e05218
commit 0216692698
10 changed files with 117 additions and 15 deletions

View File

@ -5,10 +5,6 @@ LAMMPS-GUI TODO list:
- figure out how widgets can be resized to fraction of available screen size. - figure out how widgets can be resized to fraction of available screen size.
- figure out stacking order of frames and whether it can be more flexible - figure out stacking order of frames and whether it can be more flexible
- figure out how to avoid corrupted cached thermo data while reading it. - figure out how to avoid corrupted cached thermo data while reading it.
- add an "Inspect restart file" feature that will execute "read_restart" do a "run 0"
and then launch the image viewer. also we can capture the output from the info command
and use "write_data" and view the data file as well.
ideally, this would be done without having to drop the existing buffer in the editor.
- implement a timed "Auto-Save" feature that saves after some idle time. set timeout in Editor preferences. - implement a timed "Auto-Save" feature that saves after some idle time. set timeout in Editor preferences.
- bundle or download? LAMMPS tutorial input files - bundle or download? LAMMPS tutorial input files
- add a "Colors" menu to the image viewer to adjust color settings for the - add a "Colors" menu to the image viewer to adjust color settings for the

View File

@ -770,6 +770,17 @@ void CodeEditor::contextMenuEvent(QContextMenuEvent *event)
QString word = line.mid(begin, end - begin).trimmed(); QString word = line.mid(begin, end - begin).trimmed();
QFileInfo fi(word); QFileInfo fi(word);
if (fi.exists() && fi.isFile()) { if (fi.exists() && fi.isFile()) {
// check if file is a LAMMPS restart
char magic[16] = " ";
QFile file(word);
QDataStream in(&file);
in.readRawData(magic, 16);
if (strcmp(magic, LAMMPS_MAGIC) != 0) {
auto *action = menu->addAction(QString("Inspect restart file '%1'").arg(word));
action->setIcon(QIcon(":/icons/document-open.png"));
action->setData(word);
connect(action, &QAction::triggered, this, &CodeEditor::inspect_file);
} else {
auto *action = menu->addAction(QString("View file '%1'").arg(word)); auto *action = menu->addAction(QString("View file '%1'").arg(word));
action->setIcon(QIcon(":/icons/document-open.png")); action->setIcon(QIcon(":/icons/document-open.png"));
action->setData(word); action->setData(word);
@ -777,6 +788,7 @@ void CodeEditor::contextMenuEvent(QContextMenuEvent *event)
} }
} }
} }
}
auto *action = menu->addAction(QString("LAMMPS Manual")); auto *action = menu->addAction(QString("LAMMPS Manual"));
action->setIcon(QIcon(":/icons/help-browser.png")); action->setIcon(QIcon(":/icons/help-browser.png"));
@ -1246,11 +1258,20 @@ void CodeEditor::open_url()
QDesktopServices::openUrl(QUrl(act->data().toString())); QDesktopServices::openUrl(QUrl(act->data().toString()));
} }
// forward requests to view or inspect files to the corresponding LammpsGui methods
void CodeEditor::view_file() void CodeEditor::view_file()
{ {
auto *act = qobject_cast<QAction *>(sender()); auto *act = qobject_cast<QAction *>(sender());
auto *viewer = new FileViewer(act->data().toString()); auto *guimain = qobject_cast<LammpsGui *>(parent());
viewer->show(); guimain->view_file(act->data().toString());
}
void CodeEditor::inspect_file()
{
auto *act = qobject_cast<QAction *>(sender());
auto *guimain = qobject_cast<LammpsGui *>(parent());
guimain->inspect_file(act->data().toString());
} }
// Local Variables: // Local Variables:

View File

@ -89,6 +89,7 @@ private slots:
void open_help(); void open_help();
void open_url(); void open_url();
void view_file(); void view_file();
void inspect_file();
void reformatCurrentLine(); void reformatCurrentLine();
void runCompletion(); void runCompletion();
void insertCompletedCommand(const QString &completion); void insertCompletedCommand(const QString &completion);

View File

@ -29,7 +29,7 @@
#include <QTextCursor> #include <QTextCursor>
#include <QTextStream> #include <QTextStream>
FileViewer::FileViewer(const QString &_filename, QWidget *parent) : FileViewer::FileViewer(const QString &_filename, QString title, QWidget *parent) :
QPlainTextEdit(parent), fileName(_filename) QPlainTextEdit(parent), fileName(_filename)
{ {
auto *action = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q), this); auto *action = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q), this);
@ -99,7 +99,10 @@ FileViewer::FileViewer(const QString &_filename, QWidget *parent) :
setLineWrapMode(NoWrap); setLineWrapMode(NoWrap);
setMinimumSize(800, 500); setMinimumSize(800, 500);
setWindowIcon(QIcon(":/icons/lammps-icon-128x128.png")); setWindowIcon(QIcon(":/icons/lammps-icon-128x128.png"));
if (title.isEmpty())
setWindowTitle("LAMMPS-GUI - Viewer - " + fileName); setWindowTitle("LAMMPS-GUI - Viewer - " + fileName);
else
setWindowTitle(title);
} }
void FileViewer::quit() void FileViewer::quit()

View File

@ -20,7 +20,7 @@ class FileViewer : public QPlainTextEdit {
Q_OBJECT Q_OBJECT
public: public:
FileViewer(const QString &filename, QWidget *parent = nullptr); FileViewer(const QString &filename, QString title = "", QWidget *parent = nullptr);
private slots: private slots:
void quit(); void quit();

View File

@ -133,7 +133,7 @@ static int get_pte_from_mass(double mass)
static const QString blank(" "); static const QString blank(" ");
ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidget *parent) : ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QString title, QWidget *parent) :
QDialog(parent), menuBar(new QMenuBar), imageLabel(new QLabel), scrollArea(new QScrollArea), QDialog(parent), menuBar(new QMenuBar), imageLabel(new QLabel), scrollArea(new QScrollArea),
saveAsAct(nullptr), copyAct(nullptr), cmdAct(nullptr), zoomInAct(nullptr), zoomOutAct(nullptr), saveAsAct(nullptr), copyAct(nullptr), cmdAct(nullptr), zoomInAct(nullptr), zoomOutAct(nullptr),
normalSizeAct(nullptr), lammps(_lammps), group("all"), filename(fileName), useelements(false), normalSizeAct(nullptr), lammps(_lammps), group("all"), filename(fileName), useelements(false),
@ -600,6 +600,7 @@ void ImageViewer::createImage()
dumpcmd += " axes no 0.0 0.0"; dumpcmd += " axes no 0.0 0.0";
dumpcmd += QString(" center s %1 %2 %3").arg(xcenter).arg(ycenter).arg(zcenter); dumpcmd += QString(" center s %1 %2 %3").arg(xcenter).arg(ycenter).arg(zcenter);
dumpcmd += " noinit";
dumpcmd += " modify boxcolor " + settings.value("boxcolor", "yellow").toString(); dumpcmd += " modify boxcolor " + settings.value("boxcolor", "yellow").toString();
dumpcmd += " backcolor " + settings.value("background", "black").toString(); dumpcmd += " backcolor " + settings.value("background", "black").toString();
if (useelements) dumpcmd += blank + elements + blank + adiams + blank; if (useelements) dumpcmd += blank + elements + blank + adiams + blank;

View File

@ -34,7 +34,7 @@ class ImageViewer : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit ImageViewer(const QString &fileName, LammpsWrapper *_lammps, explicit ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QString title = "",
QWidget *parent = nullptr); QWidget *parent = nullptr);
private slots: private slots:

View File

@ -26,8 +26,10 @@
#include "stdcapture.h" #include "stdcapture.h"
#include "ui_lammpsgui.h" #include "ui_lammpsgui.h"
#include <QByteArray>
#include <QClipboard> #include <QClipboard>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDataStream>
#include <QDesktopServices> #include <QDesktopServices>
#include <QEvent> #include <QEvent>
#include <QFileDialog> #include <QFileDialog>
@ -198,6 +200,7 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) :
connect(ui->actionSave, &QAction::triggered, this, &LammpsGui::save); connect(ui->actionSave, &QAction::triggered, this, &LammpsGui::save);
connect(ui->actionSave_As, &QAction::triggered, this, &LammpsGui::save_as); connect(ui->actionSave_As, &QAction::triggered, this, &LammpsGui::save_as);
connect(ui->actionView, &QAction::triggered, this, &LammpsGui::view); connect(ui->actionView, &QAction::triggered, this, &LammpsGui::view);
connect(ui->actionInspect, &QAction::triggered, this, &LammpsGui::inspect);
connect(ui->actionQuit, &QAction::triggered, this, &LammpsGui::quit); connect(ui->actionQuit, &QAction::triggered, this, &LammpsGui::quit);
connect(ui->actionCopy, &QAction::triggered, this, &LammpsGui::copy); connect(ui->actionCopy, &QAction::triggered, this, &LammpsGui::copy);
connect(ui->actionCut, &QAction::triggered, this, &LammpsGui::cut); connect(ui->actionCut, &QAction::triggered, this, &LammpsGui::cut);
@ -406,6 +409,12 @@ void LammpsGui::view()
view_file(fileName); view_file(fileName);
} }
void LammpsGui::inspect()
{
QString fileName = QFileDialog::getOpenFileName(this, "Open the restart file");
inspect_file(fileName);
}
void LammpsGui::open_recent() void LammpsGui::open_recent()
{ {
auto *act = qobject_cast<QAction *>(sender()); auto *act = qobject_cast<QAction *>(sender());
@ -666,6 +675,58 @@ void LammpsGui::view_file(const QString &fileName)
} }
} }
// read restart file into LAMMPS instance and launch image viewer
void LammpsGui::inspect_file(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::warning(this, "Warning",
"Cannot open file " + fileName + ": " + file.errorString() + ".\n");
return;
}
char magic[16] = " ";
QDataStream in(&file);
in.readRawData(magic, 16);
file.close();
if (strcmp(magic, LAMMPS_MAGIC) != 0) {
QMessageBox::warning(this, "Warning",
"File " + fileName + " is not a LAMMPS restart file.\n");
return;
}
// LAMMPS is not re-entrant, so we can only query LAMMPS when it is not running a simulation
if (!lammps.is_running()) {
start_lammps();
lammps.command("clear");
lammps.command(QString("read_restart %1").arg(fileName).toLocal8Bit());
capturer->BeginCapture();
lammps.command("info system comm group compute fix");
capturer->EndCapture();
auto info = capturer->GetCapture();
auto infolog = QString("%1.info.log").arg(fileName);
QFile dumpinfo(infolog);
if (dumpinfo.open(QIODevice::WriteOnly)) {
auto shortName = QFileInfo(fileName).fileName();
auto infodata = QString("%1.tmp.data").arg(fileName);
dumpinfo.write(info.c_str(), info.size());
dumpinfo.close();
auto *infoviewer =
new FileViewer(infolog, QString("LAMMPS-GUI: restart info for %1").arg(shortName));
infoviewer->show();
dumpinfo.remove();
lammps.command(QString("write_data %1 noinit").arg(infodata).toLocal8Bit());
auto *dataviewer =
new FileViewer(infodata, QString("LAMMPS-GUI: data file for %1").arg(shortName));
dataviewer->show();
QFile(infodata).remove();
auto *inspect_image = new ImageViewer(
fileName, &lammps, QString("LAMMPS-GUI: Image for %1").arg(shortName));
inspect_image->show();
}
}
}
// write file and update CWD to its folder // write file and update CWD to its folder
void LammpsGui::write_file(const QString &fileName) void LammpsGui::write_file(const QString &fileName)

View File

@ -27,6 +27,11 @@
#include "lammpswrapper.h" #include "lammpswrapper.h"
// identifier for LAMMPS restart files
#if !defined(LAMMPS_MAGIC)
#define LAMMPS_MAGIC "LammpS RestartT"
#endif
// forward declarations // forward declarations
class GeneralTab; class GeneralTab;
@ -64,6 +69,7 @@ public:
protected: protected:
void open_file(const QString &filename); void open_file(const QString &filename);
void view_file(const QString &filename); void view_file(const QString &filename);
void inspect_file(const QString &filename);
void write_file(const QString &filename); void write_file(const QString &filename);
void update_recents(const QString &filename = ""); void update_recents(const QString &filename = "");
void update_variables(); void update_variables();
@ -82,6 +88,7 @@ private slots:
void new_document(); void new_document();
void open(); void open();
void view(); void view();
void inspect();
void open_recent(); void open_recent();
void start_exe(); void start_exe();
void save(); void save();

View File

@ -38,6 +38,7 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionOpen"/> <addaction name="actionOpen"/>
<addaction name="actionView"/> <addaction name="actionView"/>
<addaction name="actionInspect"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_1"/> <addaction name="action_1"/>
<addaction name="action_2"/> <addaction name="action_2"/>
@ -138,6 +139,17 @@
<string>Ctrl+Shift+F</string> <string>Ctrl+Shift+F</string>
</property> </property>
</action> </action>
<action name="actionInspect">
<property name="icon">
<iconset theme=":/icons/document-open.png"/>
</property>
<property name="text">
<string>Inspect &amp;Restart</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+R</string>
</property>
</action>
<action name="actionSave"> <action name="actionSave">
<property name="icon"> <property name="icon">
<iconset theme=":/icons/document-save.png"/> <iconset theme=":/icons/document-save.png"/>