Wed 28 Aug 21:38:52 CEST 2024
This commit is contained in:
parent
0496c7c6ff
commit
e7516ce500
836
src/SimNDT/gui/MainWindow.py
Normal file
836
src/SimNDT/gui/MainWindow.py
Normal file
|
@ -0,0 +1,836 @@
|
||||||
|
import sys, os, datetime
|
||||||
|
import numpy as np
|
||||||
|
from scipy.io import savemat, loadmat
|
||||||
|
|
||||||
|
from PySide.QtCore import *
|
||||||
|
from PySide.QtGui import *
|
||||||
|
|
||||||
|
from SimNDT.gui.ui_mainwindow import Ui_MainWindow
|
||||||
|
|
||||||
|
from SimNDT.gui import HelperMethods
|
||||||
|
from SimNDT.gui import managerFile
|
||||||
|
|
||||||
|
from SimNDT.gui.managerDialogsController import ManagerDialogs
|
||||||
|
from SimNDT.gui.managerPlotsController import ManagerPlots
|
||||||
|
from SimNDT.gui.Warnings import WarningParms
|
||||||
|
from SimNDT.gui.checkOpenCL import isOpenCL
|
||||||
|
|
||||||
|
from SimNDT.gui.statusBarWidget import StatusBarWidget
|
||||||
|
from SimNDT.gui.treeWidget import TreeWidget
|
||||||
|
from SimNDT.gui.helpForm import HelpForm
|
||||||
|
|
||||||
|
from SimNDT.graphics.graphicView import GraphicView
|
||||||
|
|
||||||
|
from SimNDT.core.scenario import Scenario
|
||||||
|
from SimNDT.core.material import Material
|
||||||
|
from SimNDT.core.boundary import Boundary
|
||||||
|
from SimNDT.core.geometryObjects import Ellipse, Circle, Inclusions, Rectangle, Square
|
||||||
|
from SimNDT.core.geometryObjects import Concrete2Phase, Concrete2PhaseImmersion, Concrete3Phase, Concrete3PhaseImmersion
|
||||||
|
from SimNDT.core.inspectionMethods import Source, LinearScan, Transmission, PulseEcho, Tomography
|
||||||
|
from SimNDT.core.signal import Signals
|
||||||
|
from SimNDT.core.receivers import Receivers
|
||||||
|
from SimNDT.core.transducer import Transducer
|
||||||
|
from SimNDT.core.simulation import Simulation
|
||||||
|
|
||||||
|
|
||||||
|
import jsonpickle
|
||||||
|
import math
|
||||||
|
|
||||||
|
YEAR = 2080
|
||||||
|
MONTH = 12
|
||||||
|
|
||||||
|
|
||||||
|
class Info:
|
||||||
|
def __init__(self):
|
||||||
|
self.version = "0.63.2"
|
||||||
|
self.date = "07-05-2024"
|
||||||
|
|
||||||
|
|
||||||
|
info = Info()
|
||||||
|
|
||||||
|
class MainWindow(QMainWindow, Ui_MainWindow, ManagerDialogs, ManagerPlots):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
|
||||||
|
super(MainWindow, self).__init__(parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
self.init()
|
||||||
|
|
||||||
|
self.createMenus()
|
||||||
|
self.createToolBar()
|
||||||
|
self.setupGraphicView()
|
||||||
|
self.setupStatusBar()
|
||||||
|
self.tree()
|
||||||
|
self.setupConnections()
|
||||||
|
self.initSettings()
|
||||||
|
|
||||||
|
isOpenCL(self.statusBarWidget.openclIcon, self.statusBarWidget.openclLabel)
|
||||||
|
self.OnLicence()
|
||||||
|
|
||||||
|
self.updateFileMenu()
|
||||||
|
|
||||||
|
self.OpenSimFile = False
|
||||||
|
QTimer.singleShot(0, self.loadInitialFile)
|
||||||
|
|
||||||
|
if self.filename is None:
|
||||||
|
self.initSim()
|
||||||
|
|
||||||
|
def OnLicence(self):
|
||||||
|
year = datetime.datetime.today().year
|
||||||
|
month = datetime.datetime.today().month
|
||||||
|
if year >= YEAR and month >= MONTH:
|
||||||
|
dial = WarningParms('Get the new version!!!!, please contact to: sbosse@uni-bremen.de')
|
||||||
|
if dial.exec_():
|
||||||
|
self.close()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
def createObjects(self):
|
||||||
|
|
||||||
|
self.SimNDT_Scenario = None
|
||||||
|
self.SimNDT_ObjectList = None
|
||||||
|
self.SimNDT_Materials = None
|
||||||
|
self.SimNDT_Boundaries = None
|
||||||
|
self.SimNDT_Transducers = None
|
||||||
|
self.SimNDT_Inspection = None
|
||||||
|
self.SimNDT_Source = None
|
||||||
|
self.SimNDT_Signal = None
|
||||||
|
self.SimNDT_Simulation = None
|
||||||
|
self.SimNDT_Receivers = None
|
||||||
|
self.SimNDT_SnapShots = None
|
||||||
|
|
||||||
|
self.SimNDT_ConcreteMicrostructure = None
|
||||||
|
|
||||||
|
def setupConnections(self):
|
||||||
|
self.actionNew_Geometry_Model.triggered.connect(self.newGeometryModel)
|
||||||
|
self.actionPreview_Labeled_Scenario.triggered.connect(self.previewScenario)
|
||||||
|
self.actionAdd_Ellipse.triggered.connect(self.addEllipse)
|
||||||
|
self.actionAdd_Rectangle.triggered.connect(self.addRectangle)
|
||||||
|
self.actionShow_Scenario.triggered.connect(self.showScenario)
|
||||||
|
self.actionLoad_Scenario_From_Image.triggered.connect(self.loadImage)
|
||||||
|
self.actionRotate_The_Scenario_90_Clockwise.triggered.connect(self.rotateScenarioClockwise)
|
||||||
|
self.actionRotate_The_Scenario_90_Counter_Clockwise.triggered.connect(self.rotateScenarioCounterClockwise)
|
||||||
|
|
||||||
|
self.actionTwo_Phase_Model_Dry_Case.triggered.connect(self.twoPhaseModelDryCase)
|
||||||
|
self.actionThree_Phase_Model_Dry_Case.triggered.connect(self.threePhaseModelDryCase)
|
||||||
|
self.actionTwo_Phase_Model_Immersion_Case.triggered.connect(self.twoPhaseModelImmersionCase)
|
||||||
|
self.actionThree_Phase_Model_Immersion_Case.triggered.connect(self.threePhaseModelImmersionCase)
|
||||||
|
|
||||||
|
self.actionMaterials_Setup.triggered.connect(self.materialSetup)
|
||||||
|
self.actionBoundaty_Conditions_Setup.triggered.connect(self.boundarySetup)
|
||||||
|
self.actionSingle_Launch_Inspection.triggered.connect(self.singleLaunchSetup)
|
||||||
|
self.actionLinear_Scan_Inspections.triggered.connect(self.linearScanSetup)
|
||||||
|
self.actionTomography_Inspections.triggered.connect(self.tomographySetup)
|
||||||
|
self.actionSignal.triggered.connect(self.signalSetup)
|
||||||
|
self.actionSimulation_Setup.triggered.connect(self.simulationSetup)
|
||||||
|
self.actionCheck_Simulation_Setup.triggered.connect(self.checkSimulation)
|
||||||
|
self.actionRun_Simulation.triggered.connect(self.runSimulation)
|
||||||
|
|
||||||
|
self.actionPlot_Receiver_Signals_SingleLaunch.triggered.connect(self.plotSingleLaunch)
|
||||||
|
self.actionPlot_Receiver_Signals_Spectra.triggered.connect(self.spectraSingleLaunch)
|
||||||
|
self.actionPlot_Receivers_Signals_LinearScan.triggered.connect(self.plotLinearScan)
|
||||||
|
self.actionPlot_Receivers_Signals_Tomography.triggered.connect(self.plotTomoSignals)
|
||||||
|
|
||||||
|
self.actionCreate_Video_from_Images.triggered.connect(self.generateVideo)
|
||||||
|
|
||||||
|
self.GraphicView.refreshZoom.zoomed.connect(self.statusBarWidget.zoomSpinBox.setValue)
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
|
||||||
|
self.SimNDT_Info = Info()
|
||||||
|
self.SimNDT_Check = False
|
||||||
|
|
||||||
|
self.dirty = False
|
||||||
|
self.reset = False
|
||||||
|
self.filename = None
|
||||||
|
self.recentFiles = []
|
||||||
|
|
||||||
|
self.StopSimulation = False
|
||||||
|
self.PauseSimulation = False
|
||||||
|
|
||||||
|
self.setGeometry(100, 100, 900, 600)
|
||||||
|
self.setMinimumSize(400, 400)
|
||||||
|
|
||||||
|
self.setWindowTitle('SimNDT2 v' + self.SimNDT_Info.version)
|
||||||
|
self.setWindowFlags(self.windowFlags())
|
||||||
|
|
||||||
|
def setTitle(self, fname):
|
||||||
|
title = os.path.basename(fname)
|
||||||
|
self.setWindowTitle('SimNDT2 v' + self.SimNDT_Info.version + ': ' + title)
|
||||||
|
|
||||||
|
def loadInitialFile(self):
|
||||||
|
settings = QSettings()
|
||||||
|
fname = settings.value("LastFile")
|
||||||
|
if fname and QFile.exists(fname):
|
||||||
|
self.loadFile(fname)
|
||||||
|
|
||||||
|
def createMenus(self):
|
||||||
|
|
||||||
|
newFileAction = HelperMethods.createAction(self, "&New Simulation", self.fileNew,
|
||||||
|
QKeySequence.New, "document-new.png", self.tr("New Simulation File"))
|
||||||
|
fileOpenAction = HelperMethods.createAction(self, "&Open existing Simulation", self.fileOpen,
|
||||||
|
QKeySequence.Open, 'document-open.png',
|
||||||
|
self.tr("Open an existing Simulation"))
|
||||||
|
fileSaveAction = HelperMethods.createAction(self, "&Save Simulation", self.fileSave,
|
||||||
|
QKeySequence.Save, "document-save.png",
|
||||||
|
self.tr("Save the current Simulation"))
|
||||||
|
fileSaveAsAction = HelperMethods.createAction(self, "Save &As", self.fileSaveAs,
|
||||||
|
QKeySequence.SaveAs, icon="document-save-as.png",
|
||||||
|
tip=self.tr("Save Simulation File As"))
|
||||||
|
|
||||||
|
fileOpenAction.setIcon(self.style().standardIcon(QStyle.SP_DirOpenIcon))
|
||||||
|
# fileSaveAction.setIcon(self.style().standardIcon(QStyle.SP_FileDialogNewFolder))
|
||||||
|
|
||||||
|
|
||||||
|
fileImportJSONAction = HelperMethods.createAction(self, "&Import from .json", self.importJSON,
|
||||||
|
QKeySequence.Open, 'document-open.png',
|
||||||
|
self.tr("Import .json Simulation"))
|
||||||
|
fileExportJSONAction = HelperMethods.createAction(self, "Export in .json File", self.exportJSON,
|
||||||
|
"Ctrl+J", icon="exportMatlab.png",
|
||||||
|
tip=self.tr("Export in .json File"))
|
||||||
|
|
||||||
|
fileExportMatlabAction = HelperMethods.createAction(self, "Export in .mat File", self.exportMatlab,
|
||||||
|
"Ctrl+E", icon="exportMatlab.png",
|
||||||
|
tip=self.tr("Export in .mat File"))
|
||||||
|
|
||||||
|
fileResetAction = HelperMethods.createAction(self, "Reset Settings", self.resetSettings, icon="reset.png")
|
||||||
|
|
||||||
|
fileQuitAction = HelperMethods.createAction(self, "&Quit", self.close,
|
||||||
|
"Ctrl+Q", "close", self.tr("Close the application"))
|
||||||
|
|
||||||
|
self.fileMenuActions = (newFileAction, fileOpenAction,
|
||||||
|
fileSaveAction, fileSaveAsAction, fileImportJSONAction, fileExportJSONAction, fileExportMatlabAction, None, fileResetAction,
|
||||||
|
fileQuitAction)
|
||||||
|
|
||||||
|
HelperMethods.setEnabled(self.fileMenuActions[2:4], False)
|
||||||
|
HelperMethods.setEnabled(self.fileMenuActions[5:6], False)
|
||||||
|
self.connect(self.menuFile, SIGNAL("aboutToShow()"), self.updateFileMenu)
|
||||||
|
|
||||||
|
self.geometryMenuActions = (
|
||||||
|
self.actionNew_Geometry_Model, None, self.actionAdd_Ellipse, self.actionAdd_Rectangle,
|
||||||
|
self.actionShow_Scenario, None, self.actionShow_Scenario,
|
||||||
|
self.actionLoad_Scenario_From_Image, None, self.actionPreview_Labeled_Scenario,
|
||||||
|
self.actionRotate_The_Scenario_90_Clockwise, self.actionRotate_The_Scenario_90_Counter_Clockwise)
|
||||||
|
|
||||||
|
HelperMethods.setEnabled(self.menuNew_Simulation_Scenario, False)
|
||||||
|
HelperMethods.setEnabled(self.geometryMenuActions, False)
|
||||||
|
|
||||||
|
self.configurationMenuActions = (self.actionMaterials_Setup, self.actionBoundaty_Conditions_Setup)
|
||||||
|
HelperMethods.setEnabled(self.configurationMenuActions, False)
|
||||||
|
|
||||||
|
self.inspectionMenuActions = (
|
||||||
|
self.actionSingle_Launch_Inspection, self.actionLinear_Scan_Inspections, self.actionTomography_Inspections)
|
||||||
|
inspectionGroup = QActionGroup(self)
|
||||||
|
HelperMethods.addActions(inspectionGroup, self.inspectionMenuActions)
|
||||||
|
|
||||||
|
HelperMethods.setEnabled(self.menuInspection_Setup, False)
|
||||||
|
HelperMethods.setEnabled(self.actionSimulation_Setup, False)
|
||||||
|
HelperMethods.setEnabled(self.actionCheck_Simulation_Setup, False)
|
||||||
|
HelperMethods.setEnabled(self.actionRun_Simulation, False)
|
||||||
|
|
||||||
|
self.actionSignal = HelperMethods.createAction(self, "&Signal Setup", self.signalSetup,
|
||||||
|
"Ctrl+Shift+p", "signal.png", self.tr("Signal Setup"))
|
||||||
|
|
||||||
|
self.simulationMenuActions = (self.actionNew_Geometry_Model, self.actionMaterials_Setup,
|
||||||
|
self.actionBoundaty_Conditions_Setup, self.actionSingle_Launch_Inspection,
|
||||||
|
self.actionLinear_Scan_Inspections, self.actionTomography_Inspections,
|
||||||
|
self.actionSimulation_Setup, self.actionCheck_Simulation_Setup,
|
||||||
|
self.actionRun_Simulation)
|
||||||
|
|
||||||
|
self.menuPlotting_Tools.menuAction().setVisible(False)
|
||||||
|
|
||||||
|
# self.menuAdd_Microstructure.menuAction().setVisible(False)
|
||||||
|
# self.menuTools.menuAction().setVisible(False)
|
||||||
|
|
||||||
|
|
||||||
|
helpAboutAction = HelperMethods.createAction(self, "&About SimNDT", self.helpAbout)
|
||||||
|
helpHelpAction = HelperMethods.createAction(self, self.tr("&Help"), self.helpHelp, QKeySequence.HelpContents)
|
||||||
|
|
||||||
|
helpMenu = self.menubar.addMenu(self.tr("&Help"))
|
||||||
|
HelperMethods.addActions(helpMenu, (helpAboutAction, helpHelpAction))
|
||||||
|
|
||||||
|
def updateFileMenu(self):
|
||||||
|
|
||||||
|
self.menuFile.clear()
|
||||||
|
HelperMethods.addActions(self.menuFile, self.fileMenuActions[0:-2])
|
||||||
|
current = self.filename if self.filename is not None else None
|
||||||
|
recentFiles = []
|
||||||
|
|
||||||
|
for fname in self.recentFiles:
|
||||||
|
if fname != current and QFile.exists(fname):
|
||||||
|
recentFiles.append(fname)
|
||||||
|
if recentFiles:
|
||||||
|
self.menuFile.addSeparator()
|
||||||
|
for i, fname in enumerate(recentFiles):
|
||||||
|
action = QAction(QIcon(":/logo_SimNDT.png"), "&%d %s" % (
|
||||||
|
i + 1, QFileInfo(fname).fileName()), self)
|
||||||
|
action.setData(fname)
|
||||||
|
self.connect(action, SIGNAL("triggered()"),
|
||||||
|
self.loadFile)
|
||||||
|
self.menuFile.addAction(action)
|
||||||
|
|
||||||
|
self.menuFile.addSeparator()
|
||||||
|
self.menuFile.addAction(self.fileMenuActions[-2])
|
||||||
|
self.menuFile.addAction(self.fileMenuActions[-1])
|
||||||
|
|
||||||
|
def okToContinue(self):
|
||||||
|
|
||||||
|
if self.dirty:
|
||||||
|
reply = QMessageBox.question(self,
|
||||||
|
"SimNDT - Unsaved Changes",
|
||||||
|
"Save unsaved changes?",
|
||||||
|
QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
|
||||||
|
|
||||||
|
if reply == QMessageBox.Cancel:
|
||||||
|
return False
|
||||||
|
elif reply == QMessageBox.Yes:
|
||||||
|
self.fileSave()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def loadFile(self, fname=None):
|
||||||
|
|
||||||
|
if fname is None:
|
||||||
|
action = self.sender()
|
||||||
|
if isinstance(action, QAction):
|
||||||
|
fname = action.data()
|
||||||
|
if not self.okToContinue():
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
if fname:
|
||||||
|
self.filename = None
|
||||||
|
self.addRecentFile(fname)
|
||||||
|
self.filename = fname
|
||||||
|
self.dirty = False
|
||||||
|
HelperMethods.setEnabled(self.fileMenuActions[2:4], True)
|
||||||
|
HelperMethods.setEnabled(self.fileMenuActions[5:6], True)
|
||||||
|
self.setTitle(fname)
|
||||||
|
if fname.endswith('.json'):
|
||||||
|
self.importSim(fname)
|
||||||
|
else:
|
||||||
|
self.openSim()
|
||||||
|
|
||||||
|
def addRecentFile(self, fname):
|
||||||
|
|
||||||
|
if fname is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not self.recentFiles.count(fname):
|
||||||
|
self.recentFiles.insert(0, fname)
|
||||||
|
while len(self.recentFiles) > 9:
|
||||||
|
self.recentFiles.pop()
|
||||||
|
|
||||||
|
def createToolBar(self):
|
||||||
|
|
||||||
|
self.fileToolBar = self.addToolBar("File Tools")
|
||||||
|
self.fileToolBar.setObjectName("FileToolBar")
|
||||||
|
HelperMethods.addActions(self.fileToolBar, self.fileMenuActions[:-2])
|
||||||
|
|
||||||
|
def simulationToolBar(self, numWidgets):
|
||||||
|
|
||||||
|
if not hasattr(self, 'SimToolBar'):
|
||||||
|
self.SimToolBar = QToolBar(self.tr("Simulation Tools"))
|
||||||
|
self.SimToolBar.setObjectName("SimToolBar")
|
||||||
|
self.SimToolBar.setAllowedAreas(
|
||||||
|
Qt.TopToolBarArea | Qt.BottomToolBarArea | Qt.LeftToolBarArea | Qt.RightToolBarArea)
|
||||||
|
|
||||||
|
self.SimToolBar.clear()
|
||||||
|
HelperMethods.addActions(self.SimToolBar, self.simulationMenuActions[0:numWidgets])
|
||||||
|
self.addToolBar(Qt.TopToolBarArea, self.SimToolBar)
|
||||||
|
|
||||||
|
def geometryToolBar(self, reset=False, LoadImage=False):
|
||||||
|
if not hasattr(self, 'GeometryToolBar'):
|
||||||
|
self.GeometryToolBar = QToolBar(self.tr("Geometry Tools"))
|
||||||
|
self.GeometryToolBar.setObjectName("GeometryToolBar")
|
||||||
|
self.GeometryToolBar.setAllowedAreas(
|
||||||
|
Qt.TopToolBarArea | Qt.BottomToolBarArea | Qt.LeftToolBarArea | Qt.RightToolBarArea)
|
||||||
|
|
||||||
|
self.GeometryToolBar.clear()
|
||||||
|
if LoadImage:
|
||||||
|
HelperMethods.addActions(self.GeometryToolBar, self.geometryMenuActions[4])
|
||||||
|
self.addToolBar(Qt.RightToolBarArea, self.GeometryToolBar)
|
||||||
|
return
|
||||||
|
|
||||||
|
if reset:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
HelperMethods.addActions(self.GeometryToolBar, self.geometryMenuActions[2:])
|
||||||
|
# self.addToolBarBreak(Qt.TopToolBarArea)
|
||||||
|
self.addToolBar(Qt.RightToolBarArea, self.GeometryToolBar)
|
||||||
|
|
||||||
|
def setupGraphicView(self):
|
||||||
|
|
||||||
|
self.GraphicView = GraphicView(self)
|
||||||
|
self.setCentralWidget(self.GraphicView)
|
||||||
|
|
||||||
|
def setupStatusBar(self):
|
||||||
|
|
||||||
|
self.status = self.statusBar()
|
||||||
|
self.status.setSizeGripEnabled(False)
|
||||||
|
|
||||||
|
self.statusBarWidget = StatusBarWidget()
|
||||||
|
self.connect(self.statusBarWidget.zoomSpinBox, SIGNAL("valueChanged(int)"), self.GraphicView,
|
||||||
|
SLOT("setZoom(int)"))
|
||||||
|
|
||||||
|
self.status.insertPermanentWidget(0, self.statusBarWidget.statusFrame)
|
||||||
|
self.status.showMessage("Ready", 15000)
|
||||||
|
|
||||||
|
self.connect(self.statusBarWidget.StopStatusBar, SIGNAL("clicked()"), self.stopFunc)
|
||||||
|
self.connect(self.statusBarWidget.StartPauseStatusBar, SIGNAL("clicked()"), self.startPauseFunc)
|
||||||
|
|
||||||
|
self.StopSimulation = False
|
||||||
|
self.PauseSimulation = False
|
||||||
|
|
||||||
|
def tree(self):
|
||||||
|
|
||||||
|
self.treeWidget = TreeWidget()
|
||||||
|
self.treeDockWidget = QDockWidget(self.tr("Simulation Parameters"))
|
||||||
|
self.treeDockWidget.setObjectName("treeDockWidget")
|
||||||
|
self.treeDockWidget.setWidget(self.treeWidget)
|
||||||
|
self.treeDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
|
||||||
|
|
||||||
|
self.treeWidget.deleteDone.sig.connect(self.updateUI)
|
||||||
|
|
||||||
|
def initSettings(self):
|
||||||
|
|
||||||
|
settings = QSettings()
|
||||||
|
self.recentFiles = [] # settings.value("RecentFiles",[])
|
||||||
|
size = settings.value("MainWindow/Size", QSize(900, 600))
|
||||||
|
position = settings.value("MainWindow/Position", QPoint(50, 50))
|
||||||
|
self.restoreState(settings.value("MainWindow/State"))
|
||||||
|
zoom = float(settings.value("Graphics/Zoom", 100.0))
|
||||||
|
|
||||||
|
if self.recentFiles is None:
|
||||||
|
self.recentFiles = []
|
||||||
|
|
||||||
|
self.resize(size)
|
||||||
|
self.move(position)
|
||||||
|
|
||||||
|
# self.GraphicView.setupZoom(zoom)
|
||||||
|
self.statusBarWidget.zoomSpinBox.setValue(zoom)
|
||||||
|
|
||||||
|
def resetSettings(self):
|
||||||
|
|
||||||
|
settings = QSettings()
|
||||||
|
settings.clear()
|
||||||
|
self.reset = True
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def fileNew(self):
|
||||||
|
|
||||||
|
if not self.okToContinue():
|
||||||
|
return
|
||||||
|
|
||||||
|
fname = managerFile.fileNew(self.filename)
|
||||||
|
|
||||||
|
if fname:
|
||||||
|
HelperMethods.setEnabled(self.fileMenuActions[2:4], True)
|
||||||
|
self.filename = fname
|
||||||
|
self.dirty = True
|
||||||
|
self.setTitle(fname)
|
||||||
|
self.newSim()
|
||||||
|
|
||||||
|
def fileOpen(self):
|
||||||
|
|
||||||
|
if not self.okToContinue():
|
||||||
|
return
|
||||||
|
|
||||||
|
fname = managerFile.fileOpen(self.filename)
|
||||||
|
if fname:
|
||||||
|
self.loadFile(fname)
|
||||||
|
|
||||||
|
def fileSave(self):
|
||||||
|
|
||||||
|
if self.filename is None:
|
||||||
|
self.fileSaveAs()
|
||||||
|
else:
|
||||||
|
self.dirty = False
|
||||||
|
self.saveSim()
|
||||||
|
|
||||||
|
def fileSaveAs(self):
|
||||||
|
|
||||||
|
fname = managerFile.fileSaveAs(self.filename)
|
||||||
|
|
||||||
|
if fname:
|
||||||
|
if "." not in fname:
|
||||||
|
fname += ".sim"
|
||||||
|
|
||||||
|
self.addRecentFile(fname)
|
||||||
|
self.filename = fname
|
||||||
|
self.setTitle(self.filename)
|
||||||
|
self.saveSim()
|
||||||
|
|
||||||
|
def importJSON(self):
|
||||||
|
|
||||||
|
fname = managerFile.importJSON(self.filename)
|
||||||
|
|
||||||
|
if fname:
|
||||||
|
if "." not in fname:
|
||||||
|
fname += ".json"
|
||||||
|
|
||||||
|
self.importSim(fname)
|
||||||
|
|
||||||
|
def exportMatlab(self):
|
||||||
|
|
||||||
|
fname = managerFile.exportMatlab(self.filename)
|
||||||
|
|
||||||
|
if fname:
|
||||||
|
if "." not in fname:
|
||||||
|
fname += ".mat"
|
||||||
|
|
||||||
|
self.exportSimulation(fname)
|
||||||
|
|
||||||
|
def exportJSON(self):
|
||||||
|
|
||||||
|
fname = managerFile.exportJSON(self.filename)
|
||||||
|
|
||||||
|
if fname:
|
||||||
|
if "." not in fname:
|
||||||
|
fname += ".json"
|
||||||
|
|
||||||
|
self.exportSimulation(fname)
|
||||||
|
|
||||||
|
def initSim(self):
|
||||||
|
|
||||||
|
self.createObjects()
|
||||||
|
self.treeWidget.clear()
|
||||||
|
|
||||||
|
self.statusBarWidget.zoomSpinBox.setVisible(False)
|
||||||
|
self.GraphicView.clearUpdate()
|
||||||
|
self.removeDockWidget(self.treeDockWidget)
|
||||||
|
|
||||||
|
def newSim(self):
|
||||||
|
|
||||||
|
self.initSim()
|
||||||
|
|
||||||
|
self.simulationToolBar(1)
|
||||||
|
self.geometryToolBar(reset=True)
|
||||||
|
|
||||||
|
HelperMethods.setEnabled(self.menuNew_Simulation_Scenario, True)
|
||||||
|
HelperMethods.setEnabled(self.geometryMenuActions[0], True)
|
||||||
|
HelperMethods.setEnabled(self.geometryMenuActions[4], True)
|
||||||
|
|
||||||
|
# Show loadImage in Geometric Toolbar
|
||||||
|
self.geometryToolBar(LoadImage=True)
|
||||||
|
self.updateUI()
|
||||||
|
|
||||||
|
def openSim(self):
|
||||||
|
data2load = {}
|
||||||
|
data2load = loadmat(self.filename, squeeze_me=True, struct_as_record=False)
|
||||||
|
|
||||||
|
self.OpenSimFile = True
|
||||||
|
if "Info" in data2load:
|
||||||
|
self.SimNDT_Info = HelperMethods.mat2Obj(data2load["Info"], Info())
|
||||||
|
|
||||||
|
if "Scenario" in data2load:
|
||||||
|
Width = getattr(data2load["Scenario"], 'Width')
|
||||||
|
Height = getattr(data2load["Scenario"], 'Height')
|
||||||
|
Pixel_mm = getattr(data2load["Scenario"], 'Pixel_mm')
|
||||||
|
Label = getattr(data2load["Scenario"], 'Label')
|
||||||
|
self.SimNDT_Scenario = Scenario(Width=Width, Height=Height, Pixel_mm=Pixel_mm, Label=Label)
|
||||||
|
self.SimNDT_Scenario = HelperMethods.mat2Obj(data2load["Scenario"], self.SimNDT_Scenario)
|
||||||
|
|
||||||
|
self.SimNDT_Materials = HelperMethods.loadDataFromList(data2load, 'Materials', Material())
|
||||||
|
self.SimNDT_Boundaries = HelperMethods.loadDataFromList(data2load, "Boundaries", Boundary())
|
||||||
|
self.SimNDT_Transducers = HelperMethods.loadDataFromList(data2load, "Transducers", Transducer())
|
||||||
|
|
||||||
|
geoLabels = ["ellipse", "circle", "square", "rectangle"]
|
||||||
|
geoObjects = [Ellipse(), Circle(), Square(), Rectangle()]
|
||||||
|
self.SimNDT_ObjectList = HelperMethods.loadDataFromListWithLabels(data2load, 'GeometricObjects', geoLabels,
|
||||||
|
geoObjects)
|
||||||
|
|
||||||
|
ConcreteLabels = ["Concrete2Phase", "Concrete2PhaseImmersion", "Concrete3Phase", "Concrete3PhaseImmersion"]
|
||||||
|
ConcreteObjects = [Concrete2Phase(), Concrete2PhaseImmersion(), Concrete3Phase(), Concrete3PhaseImmersion()]
|
||||||
|
|
||||||
|
if "ConcreteMicrostructure" in data2load:
|
||||||
|
self.SimNDT_ConcreteMicrostructure = HelperMethods.loadDataWithLabels(data2load, 'ConcreteMicrostructure',
|
||||||
|
ConcreteLabels, ConcreteObjects)
|
||||||
|
|
||||||
|
if "Inspection" in data2load:
|
||||||
|
inspLabels = ['Transmission', 'PulseEcho', 'LinearScan', 'Tomography']
|
||||||
|
inspObjects = [Transmission(), PulseEcho(), LinearScan(), Tomography()]
|
||||||
|
self.SimNDT_Inspection = HelperMethods.loadDataWithLabels(data2load, "Inspection", inspLabels, inspObjects)
|
||||||
|
|
||||||
|
if "Source" in data2load:
|
||||||
|
self.SimNDT_Source = HelperMethods.mat2Obj(data2load["Source"], Source())
|
||||||
|
|
||||||
|
if "Signal" in data2load:
|
||||||
|
self.SimNDT_Signal = HelperMethods.mat2Obj(data2load["Signal"], Signals())
|
||||||
|
|
||||||
|
if "Simulation" in data2load:
|
||||||
|
self.SimNDT_Simulation = HelperMethods.mat2Obj(data2load["Simulation"], Simulation())
|
||||||
|
|
||||||
|
if "Receivers" in data2load:
|
||||||
|
self.SimNDT_Receivers = HelperMethods.mat2Obj(data2load["Receivers"], Receivers())
|
||||||
|
|
||||||
|
self.setPlotInspectionsMenu()
|
||||||
|
|
||||||
|
self.updateUI()
|
||||||
|
|
||||||
|
def importSim(self,filename):
|
||||||
|
data2load = {}
|
||||||
|
with open(filename, 'r') as file:
|
||||||
|
data2load = jsonpickle.decode(file.read()) # loadmat(self.filename, squeeze_me=True, struct_as_record=False)
|
||||||
|
|
||||||
|
self.OpenSimFile = True
|
||||||
|
self.filename = filename
|
||||||
|
|
||||||
|
if "Info" in data2load:
|
||||||
|
self.SimNDT_Info = data2load["Info"]
|
||||||
|
|
||||||
|
if "Scenario" in data2load:
|
||||||
|
Width = getattr(data2load["Scenario"], 'Width')
|
||||||
|
Height = getattr(data2load["Scenario"], 'Height')
|
||||||
|
Pixel_mm = getattr(data2load["Scenario"], 'Pixel_mm')
|
||||||
|
Label = getattr(data2load["Scenario"], 'Label')
|
||||||
|
self.SimNDT_Scenario = Scenario(Width=Width, Height=Height, Pixel_mm=Pixel_mm, Label=Label)
|
||||||
|
self.SimNDT_Scenario = data2load["Scenario"]
|
||||||
|
|
||||||
|
self.SimNDT_Materials = data2load['Materials']
|
||||||
|
self.SimNDT_Boundaries = data2load["Boundaries"]
|
||||||
|
self.SimNDT_Transducers = data2load["Transducers"]
|
||||||
|
|
||||||
|
self.SimNDT_ObjectList = data2load['GeometricObjects']
|
||||||
|
|
||||||
|
if "Inspection" in data2load:
|
||||||
|
self.SimNDT_Inspection = data2load["Inspection"]
|
||||||
|
|
||||||
|
if "Source" in data2load:
|
||||||
|
self.SimNDT_Source = data2load["Source"]
|
||||||
|
|
||||||
|
if "Signal" in data2load:
|
||||||
|
self.SimNDT_Signal = data2load["Signal"]
|
||||||
|
|
||||||
|
if "Simulation" in data2load:
|
||||||
|
self.SimNDT_Simulation = data2load["Simulation"]
|
||||||
|
|
||||||
|
if "Receivers" in data2load:
|
||||||
|
self.SimNDT_Receivers = data2load["Receivers"]
|
||||||
|
|
||||||
|
self.setPlotInspectionsMenu()
|
||||||
|
|
||||||
|
self.updateUI()
|
||||||
|
|
||||||
|
def saveSim(self):
|
||||||
|
self._saveSimulation(self.filename)
|
||||||
|
|
||||||
|
def exportSimulation(self, filename):
|
||||||
|
self._saveSimulation(filename)
|
||||||
|
|
||||||
|
def _saveSimulation(self, filename):
|
||||||
|
|
||||||
|
data2save = {}
|
||||||
|
|
||||||
|
if self.SimNDT_Info is not None:
|
||||||
|
data2save['Info'] = self.SimNDT_Info
|
||||||
|
|
||||||
|
if self.SimNDT_Scenario is not None:
|
||||||
|
data2save['Scenario'] = self.SimNDT_Scenario
|
||||||
|
|
||||||
|
if self.SimNDT_ObjectList is not None:
|
||||||
|
data2save["GeometricObjects"] = self.SimNDT_ObjectList
|
||||||
|
|
||||||
|
if self.SimNDT_ConcreteMicrostructure is not None:
|
||||||
|
data2save["ConcreteMicrostructure"] = self.SimNDT_ConcreteMicrostructure
|
||||||
|
|
||||||
|
if self.SimNDT_Materials is not None:
|
||||||
|
data2save["Materials"] = self.SimNDT_Materials
|
||||||
|
|
||||||
|
if self.SimNDT_Boundaries is not None:
|
||||||
|
data2save["Boundaries"] = self.SimNDT_Boundaries
|
||||||
|
|
||||||
|
if self.SimNDT_Transducers is not None:
|
||||||
|
data2save["Transducers"] = self.SimNDT_Transducers
|
||||||
|
|
||||||
|
if self.SimNDT_Inspection is not None:
|
||||||
|
data2save["Inspection"] = self.SimNDT_Inspection
|
||||||
|
|
||||||
|
if self.SimNDT_Source is not None:
|
||||||
|
data2save["Source"] = self.SimNDT_Source
|
||||||
|
|
||||||
|
if self.SimNDT_Signal is not None:
|
||||||
|
data2save["Signal"] = self.SimNDT_Signal
|
||||||
|
|
||||||
|
if self.SimNDT_Simulation is not None:
|
||||||
|
data2save["Simulation"] = self.SimNDT_Simulation
|
||||||
|
|
||||||
|
if self.SimNDT_Receivers is not None:
|
||||||
|
data2save["Receivers"] = self.SimNDT_Receivers
|
||||||
|
|
||||||
|
if filename.endswith('.json'):
|
||||||
|
# savemat('/tmp/_simndt.mat', data2save, appendmat=False)
|
||||||
|
# mat2json('/tmp/_simndt.mat',filename)
|
||||||
|
with open(filename, 'w') as f:
|
||||||
|
f.write(jsonpickle.encode(data2save))
|
||||||
|
else:
|
||||||
|
savemat(filename, data2save, appendmat=False)
|
||||||
|
self.dirty = False
|
||||||
|
|
||||||
|
def stopFunc(self):
|
||||||
|
self.StopSimulation = True
|
||||||
|
|
||||||
|
def startPauseFunc(self):
|
||||||
|
self.PauseSimulation = not self.PauseSimulation
|
||||||
|
if self.PauseSimulation:
|
||||||
|
self.statusBarWidget.StartPauseStatusBar.setIcon(QIcon(":/play.png"))
|
||||||
|
else:
|
||||||
|
self.statusBarWidget.StartPauseStatusBar.setIcon(QIcon(":/pause.png"))
|
||||||
|
|
||||||
|
def helpAbout(self):
|
||||||
|
|
||||||
|
QMessageBox.about(self, "About SimNDT",
|
||||||
|
""" <b> SimNDT </b> v{0}X, date: {1}
|
||||||
|
<p> Copyright © 2014 M. Molero (original author v0.52) </p>
|
||||||
|
<p> Copyright © 2024 Dr. Stefan Bosse (> 0.60) </p>
|
||||||
|
<p> Ultrasonic Simulation Software - Plus
|
||||||
|
<p> info:
|
||||||
|
<p> sbosse@uni-bremen.de
|
||||||
|
<p>
|
||||||
|
<p>
|
||||||
|
<p> if you use SimNDT Software in your research, we would appreciate the citation of the following article:
|
||||||
|
<p> M. Molero, U. Iturraran-Viveros, S. Sofia, M.G. Hernandez,
|
||||||
|
<p> Optimized OpenCL implementation of the Elastodynamic Finite Integration Technique for viscoelastic media,
|
||||||
|
<p> Computer Physics Communications Volume 185, Issue 10, October 2014, Pages 2683-2696
|
||||||
|
""".format(info.version, info.date))
|
||||||
|
|
||||||
|
def helpHelp(self):
|
||||||
|
|
||||||
|
dlg = HelpForm("index.html", self)
|
||||||
|
dlg.show()
|
||||||
|
|
||||||
|
def closeEvent(self, event):
|
||||||
|
|
||||||
|
if self.reset:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.okToContinue():
|
||||||
|
settings = QSettings()
|
||||||
|
filename = self.filename if self.filename is not None else None
|
||||||
|
settings.setValue("LastFile", filename)
|
||||||
|
recentFiles = self.recentFiles if self.recentFiles else None
|
||||||
|
settings.setValue("RecentFiles", recentFiles)
|
||||||
|
settings.setValue("MainWindow/Size", self.size())
|
||||||
|
settings.setValue("MainWindow/Position", self.pos())
|
||||||
|
settings.setValue("MainWindow/State", self.saveState())
|
||||||
|
settings.setValue("Graphics/Zoom", self.GraphicView.getZoom())
|
||||||
|
|
||||||
|
else:
|
||||||
|
event.ignore()
|
||||||
|
|
||||||
|
def setPlotInspectionsMenu(self):
|
||||||
|
|
||||||
|
HelperMethods.setEnabled(self.actionPlot_Receiver_Signals_SingleLaunch, False)
|
||||||
|
HelperMethods.setEnabled(self.actionPlot_Receiver_Signals_Spectra, False)
|
||||||
|
|
||||||
|
HelperMethods.setEnabled(self.actionPlot_Receivers_Signals_LinearScan, False)
|
||||||
|
HelperMethods.setEnabled(self.actionPlot_Receivers_Signals_Tomography, False)
|
||||||
|
|
||||||
|
Name = self.SimNDT_Inspection.Name
|
||||||
|
if Name == "Transmission" or Name == "PulseEcho":
|
||||||
|
self.menuPlotting_Tools.menuAction().setVisible(True)
|
||||||
|
HelperMethods.setEnabled(self.actionPlot_Receiver_Signals_SingleLaunch, True)
|
||||||
|
elif Name == "LinearScan":
|
||||||
|
self.menuPlotting_Tools.menuAction().setVisible(True)
|
||||||
|
HelperMethods.setEnabled(self.actionPlot_Receivers_Signals_LinearScan, True)
|
||||||
|
elif Name == 'Tomography':
|
||||||
|
self.menuPlotting_Tools.menuAction().setVisible(True)
|
||||||
|
HelperMethods.setEnabled(self.actionPlot_Receivers_Signals_Tomography, True)
|
||||||
|
|
||||||
|
def updateUI(self):
|
||||||
|
|
||||||
|
if self.SimNDT_Scenario is not None:
|
||||||
|
try:
|
||||||
|
self.GraphicView.imshow(self.SimNDT_Scenario.I)
|
||||||
|
except Exception as e:
|
||||||
|
msgBox = WarningParms("Unable to display GRAPHICS!!!. Incompatible Graphic Card, %s" % e)
|
||||||
|
if msgBox.exec_():
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
HelperMethods.setEnabled(self.menuNew_Simulation_Scenario, True)
|
||||||
|
HelperMethods.setEnabled(self.fileMenuActions[2:5], True)
|
||||||
|
HelperMethods.setEnabled(self.geometryMenuActions[0:], True)
|
||||||
|
HelperMethods.setEnabled(self.configurationMenuActions[0], True)
|
||||||
|
|
||||||
|
self.addDockWidget(Qt.LeftDockWidgetArea, self.treeDockWidget)
|
||||||
|
self.treeDockWidget.show()
|
||||||
|
|
||||||
|
self.geometryToolBar()
|
||||||
|
self.simulationToolBar(2)
|
||||||
|
self.statusBarWidget.zoomSpinBox.setVisible(True)
|
||||||
|
|
||||||
|
if self.SimNDT_Materials is not None:
|
||||||
|
HelperMethods.setEnabled(self.configurationMenuActions[1], True)
|
||||||
|
self.simulationToolBar(3)
|
||||||
|
|
||||||
|
if self.SimNDT_Boundaries is not None:
|
||||||
|
if np.size(self.SimNDT_Scenario.Iabs) == 1:
|
||||||
|
self.GraphicView.imshow(self.SimNDT_Scenario.Iabs)
|
||||||
|
else:
|
||||||
|
self.GraphicView.imshow(self.SimNDT_Scenario.Iabs)
|
||||||
|
HelperMethods.setEnabled(self.menuInspection_Setup, True)
|
||||||
|
HelperMethods.setEnabled(self.inspectionMenuActions[:], True)
|
||||||
|
self.simulationToolBar(6)
|
||||||
|
|
||||||
|
if self.SimNDT_Inspection is not None:
|
||||||
|
HelperMethods.setEnabled(self.simulationMenuActions[6], True)
|
||||||
|
self.simulationToolBar(7)
|
||||||
|
|
||||||
|
if self.SimNDT_Simulation is not None:
|
||||||
|
HelperMethods.setEnabled(self.simulationMenuActions[7], True)
|
||||||
|
self.simulationToolBar(8)
|
||||||
|
|
||||||
|
if self.SimNDT_Check:
|
||||||
|
HelperMethods.setEnabled(self.actionRun_Simulation, True)
|
||||||
|
if not self.OpenSimFile:
|
||||||
|
self.simulationToolBar(9)
|
||||||
|
|
||||||
|
self.treeWidget.update(self.SimNDT_Scenario,
|
||||||
|
self.SimNDT_ObjectList,
|
||||||
|
self.SimNDT_Materials,
|
||||||
|
self.SimNDT_Boundaries,
|
||||||
|
self.SimNDT_Inspection,
|
||||||
|
self.SimNDT_Source,
|
||||||
|
self.SimNDT_Transducers,
|
||||||
|
self.SimNDT_Signal,
|
||||||
|
self.SimNDT_Simulation)
|
||||||
|
def showScenario(self):
|
||||||
|
self.SimNDT_Scenario.resetImage()
|
||||||
|
|
||||||
|
for obj in self.SimNDT_ObjectList:
|
||||||
|
self.SimNDT_Scenario.addObject(obj)
|
||||||
|
|
||||||
|
if self.SimNDT_Boundaries is not None:
|
||||||
|
self.SimNDT_Scenario.createBoundaries(self.SimNDT_Boundaries)
|
||||||
|
|
||||||
|
self.updateUI()
|
||||||
|
# @blab+ Add transducer as circle and show I/Iabs copy
|
||||||
|
I=self.SimNDT_Scenario.addTransducer(self.SimNDT_Scenario.Width/2+self.SimNDT_Transducers[0].CenterOffset,
|
||||||
|
self.SimNDT_Transducers[0].BorderOffset,
|
||||||
|
self.SimNDT_Transducers[0].Size, 240)
|
||||||
|
if self.SimNDT_SnapShots is not None:
|
||||||
|
if len(self.SimNDT_SnapShots.sensorShape) == 2:
|
||||||
|
xn = self.SimNDT_Scenario.Width
|
||||||
|
yn = self.SimNDT_Scenario.Height
|
||||||
|
dx = 1 # sensor delta
|
||||||
|
dy = 1
|
||||||
|
ox = 0 # offset
|
||||||
|
oy = 0
|
||||||
|
# size of sensor matrix
|
||||||
|
sx = self.SimNDT_SnapShots.sensorShape[0]
|
||||||
|
sy = self.SimNDT_SnapShots.sensorShape[1]
|
||||||
|
S = np.zeros([sy,sx])
|
||||||
|
if len(self.SimNDT_SnapShots.sensorPlacement) == 4:
|
||||||
|
p=self.SimNDT_SnapShots.sensorPlacement
|
||||||
|
ox=p[0]
|
||||||
|
dx=p[1]
|
||||||
|
oy=p[2]
|
||||||
|
dy=p[3]
|
||||||
|
else:
|
||||||
|
ox=dx=round(xn/(sx+1.0))
|
||||||
|
oy=dy=round(yn/(sy+1.0))
|
||||||
|
for x in range(0,sx):
|
||||||
|
for y in range(0,sy):
|
||||||
|
self.SimNDT_Scenario.addSensor(I,ox+x*dx,oy+y*dy,10, 255)
|
||||||
|
self.GraphicView.clearUpdate()
|
||||||
|
self.GraphicView.imshow(I)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user