Added symbols for actions
1
.gitignore
vendored
@ -22,3 +22,4 @@ brent_test
|
||||
tasmet
|
||||
tasmet_automoc.dir
|
||||
tasmet_solvemodel
|
||||
tasmet_autogen
|
||||
|
@ -1,5 +1,5 @@
|
||||
# CMakeList.txt for TaSMET
|
||||
cmake_minimum_required (VERSION 3.6)
|
||||
cmake_minimum_required (VERSION 2.8.5)
|
||||
project(TaSMET)
|
||||
set(PACKAGE_VERSION 0.1)
|
||||
message("Running Cmake for TaSMET version ${PACKAGE_VERSION}")
|
||||
|
4
Doxyfile
@ -51,14 +51,14 @@ PROJECT_BRIEF = "Thermoacoustic System Modeling Environment"
|
||||
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
|
||||
# the logo to the output directory.
|
||||
|
||||
PROJECT_LOGO = /home/anne/wip/tasmet/src/gui/images/tasmet_small.png
|
||||
PROJECT_LOGO = src/gui/images/tasmet_small.png
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||
# into which the generated documentation will be written. If a relative path is
|
||||
# entered, it will be relative to the location where doxygen was started. If
|
||||
# left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = /home/anne/wip/tasmet/doc
|
||||
OUTPUT_DIRECTORY = doc
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
|
||||
# directories (in 2 levels) under the output directory of each output format and
|
||||
|
0
doc/fig/tasys_artist.eps
Executable file → Normal file
0
doc/fig/tasys_artist.png
Executable file → Normal file
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
0
gui/__init__.py
Normal file
83
gui/about_dialog.py
Normal file
@ -0,0 +1,83 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'about_dialog.ui'
|
||||
#
|
||||
# Created by: PyQt4 UI code generator 4.12
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
def _fromUtf8(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
except AttributeError:
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
|
||||
class Ui_about_dialog(object):
|
||||
def setupUi(self, about_dialog):
|
||||
about_dialog.setObjectName(_fromUtf8("about_dialog"))
|
||||
about_dialog.resize(318, 582)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(about_dialog.sizePolicy().hasHeightForWidth())
|
||||
about_dialog.setSizePolicy(sizePolicy)
|
||||
self.verticalLayout = QtGui.QVBoxLayout(about_dialog)
|
||||
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
|
||||
self.label = QtGui.QLabel(about_dialog)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(_fromUtf8("DejaVu Sans Mono"))
|
||||
font.setPointSize(14)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.label.setFont(font)
|
||||
self.label.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label.setObjectName(_fromUtf8("label"))
|
||||
self.verticalLayout.addWidget(self.label)
|
||||
self.label_4 = QtGui.QLabel(about_dialog)
|
||||
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_4.setObjectName(_fromUtf8("label_4"))
|
||||
self.verticalLayout.addWidget(self.label_4)
|
||||
self.label_5 = QtGui.QLabel(about_dialog)
|
||||
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_5.setObjectName(_fromUtf8("label_5"))
|
||||
self.verticalLayout.addWidget(self.label_5)
|
||||
self.label_2 = QtGui.QLabel(about_dialog)
|
||||
self.label_2.setMinimumSize(QtCore.QSize(300, 433))
|
||||
self.label_2.setMaximumSize(QtCore.QSize(300, 433))
|
||||
self.label_2.setStyleSheet(_fromUtf8("background-color: rgb(255, 255, 255)"))
|
||||
self.label_2.setFrameShape(QtGui.QFrame.Box)
|
||||
self.label_2.setText(_fromUtf8(""))
|
||||
self.label_2.setPixmap(QtGui.QPixmap(_fromUtf8("images/tasmet.png")))
|
||||
self.label_2.setScaledContents(True)
|
||||
self.label_2.setObjectName(_fromUtf8("label_2"))
|
||||
self.verticalLayout.addWidget(self.label_2)
|
||||
self.label_3 = QtGui.QLabel(about_dialog)
|
||||
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_3.setObjectName(_fromUtf8("label_3"))
|
||||
self.verticalLayout.addWidget(self.label_3)
|
||||
self.pushButton = QtGui.QPushButton(about_dialog)
|
||||
self.pushButton.setObjectName(_fromUtf8("pushButton"))
|
||||
self.verticalLayout.addWidget(self.pushButton)
|
||||
|
||||
self.retranslateUi(about_dialog)
|
||||
QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), about_dialog.accept)
|
||||
QtCore.QMetaObject.connectSlotsByName(about_dialog)
|
||||
|
||||
def retranslateUi(self, about_dialog):
|
||||
about_dialog.setWindowTitle(_translate("about_dialog", "About TaSMET", None))
|
||||
self.label.setText(_translate("about_dialog", "TaSMET", None))
|
||||
self.label_4.setText(_translate("about_dialog", "Thermoacoustic System", None))
|
||||
self.label_5.setText(_translate("about_dialog", "Modeling Environment Twente", None))
|
||||
self.label_3.setText(_translate("about_dialog", "Copyright (c) 2017 Anne de Jong", None))
|
||||
self.pushButton.setText(_translate("about_dialog", "OK", None))
|
||||
|
130
gui/about_dialog.ui
Normal file
@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>about_dialog</class>
|
||||
<widget class="QDialog" name="about_dialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>318</width>
|
||||
<height>582</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About TaSMET</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
<pointsize>14</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TaSMET</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Thermoacoustic System</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Modeling Environment Twente</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>433</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>433</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(255, 255, 255)</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>images/tasmet.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Copyright (c) 2017 Anne de Jong</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>pushButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>about_dialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>158</x>
|
||||
<y>562</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>158</x>
|
||||
<y>290</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
BIN
images/document-new.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
images/document-open.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
images/document-save-as.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
images/document-save.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
images/tasmet.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
images/tasmet_small.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
images/tasmet_transparent.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
0
src/gui/images/tasmet.png
Executable file → Normal file
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
0
src/gui/images/tasmet_small.png
Executable file → Normal file
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
@ -11,14 +11,6 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <QString>
|
||||
#include <QSettings>
|
||||
#include <QWidget>
|
||||
#include <QDoubleValidator>
|
||||
#include <QIntValidator>
|
||||
#include <QFileDialog>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "tasmet_config.h"
|
||||
#include "tasmet_tracer.h"
|
||||
#include "tasmet_assert.h"
|
||||
@ -31,6 +23,16 @@
|
||||
#include "solver_dialog.h"
|
||||
#include "message_tools.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QSettings>
|
||||
#include <QWidget>
|
||||
#include <QDoubleValidator>
|
||||
#include <QIntValidator>
|
||||
#include <QFileDialog>
|
||||
#include <QStandardPaths>
|
||||
#include <QProcess>
|
||||
|
||||
|
||||
const QString default_model_name = QString("Unsaved TaSMET Model") +
|
||||
constants::model_fileext;
|
||||
const QString default_segment_name = "Unnamed segment";
|
||||
@ -38,6 +40,7 @@ const QString start_file_location = QStandardPaths::
|
||||
writableLocation(QStandardPaths::DocumentsLocation);
|
||||
const QString filetype = QString("TaSMET Model files (*") + constants::model_fileext + ")";
|
||||
const QString window_title_part = "TaSMET Model Builder - ";
|
||||
|
||||
namespace {
|
||||
|
||||
int saveFileFirstQuestion(QWidget* parent) {
|
||||
@ -55,6 +58,7 @@ namespace {
|
||||
TaSMETMainWindow::TaSMETMainWindow():
|
||||
_window(new Ui::MainWindow()),
|
||||
_model(pb::Model::default_instance()),
|
||||
_saved_model(_model),
|
||||
_system(*_model.mutable_system())
|
||||
{
|
||||
|
||||
@ -120,6 +124,7 @@ TaSMETMainWindow::~TaSMETMainWindow(){
|
||||
void TaSMETMainWindow::newModel() {
|
||||
TRACE(15,"newModel");
|
||||
_model = pb::Model::default_instance();
|
||||
_saved_model = _model;
|
||||
_filepath = "";
|
||||
set(_model);
|
||||
}
|
||||
@ -148,7 +153,11 @@ void TaSMETMainWindow::loadModel(const string* filepath_s) {
|
||||
try {
|
||||
TRACE(15,"Setting loaded model");
|
||||
_filepath = *filepath_s;
|
||||
set(loadMessage<pb::Model>(*filepath_s));
|
||||
_model = loadMessage<pb::Model>(*filepath_s);
|
||||
_saved_model = _model;
|
||||
_system = *_model.mutable_system();
|
||||
set(_model);
|
||||
|
||||
}
|
||||
catch(TaSMETError &e) {
|
||||
_filepath = "";
|
||||
@ -172,6 +181,7 @@ void TaSMETMainWindow::saveModel(string* filepath) {
|
||||
}
|
||||
try {
|
||||
saveMessage<pb::Model>(*filepath,_model);
|
||||
_saved_model = _model;
|
||||
_filepath = *filepath;
|
||||
changed();
|
||||
}
|
||||
@ -282,8 +292,6 @@ void TaSMETMainWindow::set(const pb::Model& model) {
|
||||
|
||||
_window->backlog->setPlainText(QString::fromStdString(model.backlog()));
|
||||
|
||||
_model = model;
|
||||
_system = *_model.mutable_system();
|
||||
_init = false;
|
||||
|
||||
changed();
|
||||
@ -311,6 +319,9 @@ void TaSMETMainWindow::closeEvent(QCloseEvent *event) {
|
||||
}
|
||||
}
|
||||
|
||||
// If we are here, the model is not dirty anymore. We can savely
|
||||
// close the application.
|
||||
|
||||
// Save window configuration to settings
|
||||
QSettings settings(company,appname);
|
||||
settings.setValue("geometry", saveGeometry());
|
||||
@ -470,10 +481,12 @@ void TaSMETMainWindow::on_actionSolve_triggered() {
|
||||
void TaSMETMainWindow::on_actionPostprocess_model_triggered() {
|
||||
|
||||
try {
|
||||
|
||||
TaSystem sys(_model.system());
|
||||
if(_model.solution_size() == 0)
|
||||
throw TaSMETError("No solution found");
|
||||
vd sol(_model.solution_size());
|
||||
|
||||
for(us i=0;i<sol.size();i++) {
|
||||
sol(i) = _model.solution(i);
|
||||
}
|
||||
@ -483,6 +496,21 @@ void TaSMETMainWindow::on_actionPostprocess_model_triggered() {
|
||||
throw TaSMETError("Model has not yet been saved");
|
||||
sys.exportHDF5(_filepath + ".h5");
|
||||
|
||||
QString command = "python";
|
||||
QString appfilepath = QCoreApplication::applicationDirPath();
|
||||
QString postprocessor_program = appfilepath +
|
||||
QDir::separator() + "tasmet_postprocessor.py";
|
||||
QString filepath_post = QString::fromStdString(_filepath) + ".h5";
|
||||
|
||||
QStringList params;
|
||||
params << postprocessor_program;
|
||||
params << filepath_post;
|
||||
|
||||
// Start the process, which is destroyed whenever the program
|
||||
// is killed
|
||||
QProcess *p = new QProcess(this);
|
||||
// connect(p,&QProcess::finished,p,&QProcess::deleteLater);
|
||||
p->startDetached(command,params);
|
||||
}
|
||||
catch(TaSMETError &e) {
|
||||
e.show_user("Postprocessing failed");
|
||||
@ -491,18 +519,7 @@ void TaSMETMainWindow::on_actionPostprocess_model_triggered() {
|
||||
}
|
||||
bool TaSMETMainWindow::isDirty() const {
|
||||
TRACE(15,"isDirty()");
|
||||
if(_filepath.size()==0) return true;
|
||||
|
||||
try {
|
||||
pb::Model filemodel = loadMessage<pb::Model>(_filepath);
|
||||
bool dirty = !compareMessage<pb::Model>(filemodel,_model);
|
||||
VARTRACE(15,dirty);
|
||||
return dirty;
|
||||
}
|
||||
catch(TaSMETError& e) {
|
||||
TRACE(15,"Files could not be compared");
|
||||
return true;
|
||||
}
|
||||
return !compareMessage(_model,_saved_model);
|
||||
}
|
||||
|
||||
void TaSMETMainWindow::on_actionAbout_triggered(){
|
||||
|
@ -26,6 +26,10 @@ class TaSMETMainWindow: public QMainWindow {
|
||||
// In-memory model
|
||||
pb::Model _model;
|
||||
|
||||
pb::Model _saved_model; /**< Last saved state of the model, to
|
||||
compare with to check whether we
|
||||
are dirty yes or no */
|
||||
|
||||
pb::System& _system; /**< In constructor set to the
|
||||
_model.mutable_system() */
|
||||
|
||||
|
@ -348,7 +348,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>683</width>
|
||||
<height>18</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@ -456,7 +456,7 @@
|
||||
</action>
|
||||
<action name="actionPostprocess_model">
|
||||
<property name="text">
|
||||
<string>Create postprocessing file</string>
|
||||
<string>Start &postprocessor...</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
|
@ -96,7 +96,7 @@ public:
|
||||
// add two Variableiables
|
||||
Variable operator+(const Variable& other) const;
|
||||
//Subtract two Variableiables
|
||||
Variable operator-(const Variable& Variable2) const;
|
||||
Variable operator-(const Variable& other) const;
|
||||
// with Note multiplication is defined outside of the class
|
||||
|
||||
// If we need to multiply two numbers in frequency domain, this
|
||||
|
@ -457,10 +457,11 @@ void TaSystem::exportHDF5(const string& filename) const {
|
||||
// H5Eset_auto(error_stack, old_func, old_client_data); /// Disable HDF5 error printing
|
||||
|
||||
if(file_id < 0)
|
||||
throw TaSMETError("Creation of export file failed. "
|
||||
"This could mean that the file is blocked "
|
||||
"by another program, or the user has insufficient "
|
||||
"privileges to create the file at the given path."
|
||||
throw TaSMETError("Creation of export file failed. This is probably "
|
||||
"because the postprocessor is already running. "
|
||||
"However, this could also mean that the file is blocked "
|
||||
"by another program, or you have insufficient "
|
||||
"privileges to create the postprocessing file."
|
||||
);
|
||||
|
||||
/// Enable HDF5 error printing
|
||||
|
131
tasmet_postprocessor.py
Executable file → Normal file
@ -5,17 +5,26 @@ Created on Thu Feb 2 08:33:53 2017
|
||||
|
||||
@author: anne
|
||||
"""
|
||||
|
||||
qt = 5
|
||||
# Here we provide the necessary imports.
|
||||
# The basic GUI widgets are located in QtGui module.
|
||||
import sys, h5py
|
||||
import numpy as np
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.QtGui import QIcon,QDoubleValidator
|
||||
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
||||
from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar
|
||||
if qt==4:
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
|
||||
from matplotlib.backends.backend_qt4 import NavigationToolbar2QT as NavigationToolbar
|
||||
else:
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.QtGui import QIcon,QDoubleValidator
|
||||
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
||||
from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar
|
||||
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
import time
|
||||
from matplotlib.animation import FuncAnimation
|
||||
from gui.about_dialog import Ui_about_dialog
|
||||
|
||||
scale = [('nano',-9,'n'),
|
||||
@ -68,7 +77,7 @@ class TaSMETFigure(Figure):
|
||||
|
||||
def __init__(self, width=5, height=4, dpi=100):
|
||||
|
||||
Figure.__init__(self,figsize=(width, height), dpi=dpi)
|
||||
Figure.__init__(self, figsize=(width, height), dpi=dpi)
|
||||
|
||||
self._axes = self.add_subplot(111)
|
||||
|
||||
@ -76,6 +85,9 @@ class TaSMETFigure(Figure):
|
||||
|
||||
self._plots = []
|
||||
self._grid = False
|
||||
def setCanvas(self,canvas):
|
||||
self._canvas = canvas
|
||||
|
||||
def addPlot(self,plot,one):
|
||||
if one:
|
||||
self._plots = [plot]
|
||||
@ -94,7 +106,8 @@ class TaSMETFigure(Figure):
|
||||
|
||||
self._axes.grid(self._grid,'both')
|
||||
|
||||
self.canvas.draw_idle()
|
||||
self.canvas.draw()
|
||||
|
||||
def setGrid(self,grid):
|
||||
self._grid = grid
|
||||
self.rePlot()
|
||||
@ -107,7 +120,44 @@ class TaSMETFigure(Figure):
|
||||
self._plots = []
|
||||
self.rePlot()
|
||||
|
||||
def animate(self, data):
|
||||
line = self._axes.get_lines()[0]
|
||||
|
||||
max_val = np.max(data)
|
||||
min_val = np.min(data)
|
||||
|
||||
self._axes.set_ylim((min_val,max_val))
|
||||
|
||||
# Number of frames available in a period
|
||||
frames_per_period = data.shape[1]
|
||||
|
||||
# Time to pass to show one period
|
||||
time_per_period = 1.0
|
||||
|
||||
# interval in seconds
|
||||
interval = time_per_period/frames_per_period
|
||||
|
||||
# We need a max, here because due to a bug intervals lower than 200
|
||||
# are going plain wrong in matplotlib
|
||||
interval_ms = max(int(interval*1000),200)
|
||||
|
||||
def animate_i(i):
|
||||
line.set_ydata(data[:,i%frames_per_period])
|
||||
return line,
|
||||
|
||||
ani = FuncAnimation(self,
|
||||
animate_i,
|
||||
interval = max(200,interval_ms),
|
||||
frames = frames_per_period,
|
||||
blit=True,
|
||||
repeat = True,
|
||||
save_count = 300 # High value here as animate_i repeats itself
|
||||
)
|
||||
self.canvas.draw()
|
||||
# for i in range(100):
|
||||
# print(i)
|
||||
# animate_i(i)
|
||||
#
|
||||
class TaSMETCanvas(FigureCanvas):
|
||||
|
||||
def __init__(self, parent, figure):
|
||||
@ -120,7 +170,7 @@ class TaSMETCanvas(FigureCanvas):
|
||||
QSizePolicy.Expanding)
|
||||
|
||||
FigureCanvas.updateGeometry(self)
|
||||
|
||||
figure.setCanvas(self)
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
|
||||
@ -277,7 +327,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
# Plot menu
|
||||
plot_menu = QMenu('&Plot', self)
|
||||
self._grid_option = QAction('Enable grid')
|
||||
self._grid_option = QAction('Enable grid',plot_menu)
|
||||
self._grid_option.setCheckable(True)
|
||||
self._grid_option.triggered.connect(self._figure.setGrid)
|
||||
plot_menu.addAction(self._grid_option)
|
||||
@ -335,8 +385,28 @@ class MainWindow(QMainWindow):
|
||||
def output(self):
|
||||
print('output')
|
||||
|
||||
def disableAll(self):
|
||||
self._seg_box.setEnabled(False)
|
||||
self._qty_box.setEnabled(False)
|
||||
self._vspos.setEnabled(False)
|
||||
self._vstime.setEnabled(False)
|
||||
self._vs_instance.setEnabled(False)
|
||||
self._plot_button.setEnabled(False)
|
||||
self._output_button.setEnabled(False)
|
||||
self._animate_button.setEnabled(False)
|
||||
|
||||
def animate(self):
|
||||
print('animate')
|
||||
self.disableAll()
|
||||
self._hold_button.setChecked(False)
|
||||
self.plot()
|
||||
try:
|
||||
data,datatype = self.getCurrentData()
|
||||
except:
|
||||
return
|
||||
|
||||
self._figure.animate(data[:,:])
|
||||
|
||||
self.qtyItemChanged()
|
||||
|
||||
def getCurrentData(self):
|
||||
"""
|
||||
@ -353,13 +423,12 @@ class MainWindow(QMainWindow):
|
||||
datatype = data.attrs['datatype'].decode('utf-8')
|
||||
return data,datatype
|
||||
|
||||
|
||||
|
||||
|
||||
def segItemChanged(self,item):
|
||||
|
||||
def segItemChanged(self,item=None):
|
||||
"""
|
||||
Update the combobox with quantities
|
||||
"""
|
||||
|
||||
self._suppressed = True
|
||||
self._qty_box.clear()
|
||||
one = False
|
||||
@ -373,14 +442,14 @@ class MainWindow(QMainWindow):
|
||||
|
||||
self._suppressed = False
|
||||
self._qty_box.setCurrentIndex(0)
|
||||
self.qtyItemChanged(0)
|
||||
self.qtyItemChanged()
|
||||
|
||||
def qtyItemChanged(self,item):
|
||||
def qtyItemChanged(self,item=None):
|
||||
"""
|
||||
The quantity item has been changed
|
||||
"""
|
||||
|
||||
if self._suppressed: return
|
||||
|
||||
try:
|
||||
data,datatype = self.getCurrentData()
|
||||
except:
|
||||
@ -388,16 +457,15 @@ class MainWindow(QMainWindow):
|
||||
|
||||
segitemno = self._seg_box.currentText()
|
||||
|
||||
if data is None:
|
||||
self._vstime.setChecked(False)
|
||||
self._vspos.setEnabled(False)
|
||||
self._vstime.setEnabled(False)
|
||||
self._vs_instance.setEnabled(False)
|
||||
self._plot_button.setEnabled(False)
|
||||
self._output_button.setEnabled(False)
|
||||
self._animate_button.setEnabled(False)
|
||||
return
|
||||
self.disableAll()
|
||||
|
||||
self._seg_box.setEnabled(True)
|
||||
self._qty_box.setEnabled(True)
|
||||
|
||||
if data is None:
|
||||
return
|
||||
|
||||
|
||||
self._plot_button.setEnabled(True)
|
||||
self._output_button.setEnabled(True)
|
||||
|
||||
@ -405,9 +473,6 @@ class MainWindow(QMainWindow):
|
||||
if datatype == 'time':
|
||||
self._vstime.setChecked(True)
|
||||
self._vspos.setEnabled(False)
|
||||
self._vstime.setEnabled(False)
|
||||
self._vs_instance.setEnabled(False)
|
||||
self._animate_button.setEnabled(False)
|
||||
|
||||
elif datatype == 'pos':
|
||||
self._vspos.setChecked(True)
|
||||
@ -429,6 +494,7 @@ class MainWindow(QMainWindow):
|
||||
self._vspos.setEnabled(True)
|
||||
self._vstime.setEnabled(True)
|
||||
self._vs_instance.setEnabled(True)
|
||||
self._animate_button.setEnabled(True)
|
||||
|
||||
def initGui(self):
|
||||
self.defaultOutput()
|
||||
@ -552,8 +618,7 @@ def usage():
|
||||
if __name__ == '__main__':
|
||||
if(len(sys.argv) < 2):
|
||||
usage()
|
||||
file_ = '../second_duct_sinomgt.tasmet.h5'
|
||||
# return -1
|
||||
exit(-1)
|
||||
else:
|
||||
file_ = sys.argv[1]
|
||||
|
||||
@ -573,4 +638,4 @@ if __name__ == '__main__':
|
||||
|
||||
w.show() # The show() method displays the widget on the screen.
|
||||
|
||||
sys.exit(app.exec_()) # Finally, we enter the mainloop of the application.
|
||||
sys.exit(app.exec_()) # Finally, we enter the mainloop of the application.
|
||||
|