Commit a986b897 authored by Maximilian Schanner's avatar Maximilian Schanner
Browse files

Annotation and minors.

parent 2cd05488
......@@ -26,7 +26,8 @@ from pathlib import Path
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, \
QLineEdit, QVBoxLayout, QHBoxLayout, QComboBox, QFrame, QFileDialog
QLineEdit, QVBoxLayout, QHBoxLayout, QComboBox, QFrame, QFileDialog, \
QRadioButton
from PyQt5.QtGui import QDoubleValidator, QValidator
import matplotlib
......@@ -47,9 +48,9 @@ titleStyle = 'font-size: 18pt; font-weight: bold;'
class MainWindow(QWidget):
def __init__(self, parser):
def __init__(self):
super().__init__()
self.parser = parser
self.parser = argument_parser()
self.saveWindow = SaveWindow()
self.initUI()
......@@ -113,43 +114,46 @@ class MainWindow(QWidget):
self.show()
def updateModel(self):
''' updates the model, when the selected model changes '''
model = Model(self.modelSelector.currentText())
# update the range
self.epoch.min = model.t_min
self.epoch.min = model.t_max
self.epoch.default = int((model.t_max + model.t_min) / 2)
self.range.setText(f'[{model.t_min}, {model.t_max}]')
# update the model for saving
self.saveWindow.model = model
def modelSelect(self):
''' Model selection widget '''
# Title string
# title string
title = QLabel('Select model')
title.setStyleSheet(titleStyle)
title.setAlignment(Qt.AlignCenter)
# Drop down menu
# drop down menu
self.modelSelector = QComboBox()
self.modelSelector.addItems(built_in_models().keys())
self.modelSelector.currentIndexChanged.connect(self.updateModel)
self.modelSelector.currentIndexChanged.connect(self.plotDipole)
self.modelSelector.setFixedHeight(25)
# HOTFIX: this fixed scaling issues with the text...
self.modelSelector.setStyleSheet("QAbstractItemView {"
" selection-background-color:"
" lightgray;"
"}")
# Show the model range
# show the model range
rangeLabel = QLabel('Time range (yrs.):')
rangeLabel.setAlignment(Qt.AlignCenter)
self.range = QLabel()
self.range.setAlignment(Qt.AlignCenter)
# Put into widget
# put into widget
hbox = QVBoxLayout()
hbox.addWidget(title)
hbox.addWidget(self.modelSelector)
hbox.addWidget(rangeLabel)
hbox.addWidget(self.range)
hbox.setAlignment(Qt.AlignTop)
# return a widget containing the selector
q = QWidget()
q.setLayout(hbox)
q.setFixedHeight(140)
......@@ -157,11 +161,11 @@ class MainWindow(QWidget):
def localMenu(self):
''' Local plot widget '''
# Title string
# title string
title = QLabel('Local plots')
title.setStyleSheet(titleStyle)
title.setAlignment(Qt.AlignCenter)
# Lat lon input fields
# lat and lon input fields
latLonLabel = QLabel('Position (lat, lon)')
latLonLabel.setAlignment(Qt.AlignCenter)
......@@ -171,12 +175,26 @@ class MainWindow(QWidget):
self.lon = QRangeEdit('0', -180, 180)
self.lon.setFixedWidth(50)
self.lon.setFixedHeight(22)
# set up a layout (looks nicer than adding the widgets directly)
latLonBox = QHBoxLayout()
latLonBox.addWidget(self.lat)
latLonBox.addWidget(self.lon)
latLonWidget = QWidget()
latLonWidget.setLayout(latLonBox)
# radio buttons for field type
typeLabel = QLabel('Field type')
typeLabel.setAlignment(Qt.AlignCenter)
self.locNezButton = QRadioButton("NEZ")
self.locDifButton = QRadioButton("DIF")
self.locDifButton.setChecked(True)
# set up a layout
typeBox = QHBoxLayout()
typeBox.addWidget(self.locNezButton)
typeBox.addWidget(self.locDifButton)
typeBox.setAlignment(Qt.AlignCenter)
typeWidget = QWidget()
typeWidget.setLayout(typeBox)
# Plot button
sButton = QPushButton('Plot local')
sButton.clicked.connect(self.plotLocal)
......@@ -185,94 +203,142 @@ class MainWindow(QWidget):
vbox.addWidget(title)
vbox.addWidget(latLonLabel)
vbox.addWidget(latLonWidget)
vbox.addWidget(typeLabel)
vbox.addWidget(typeWidget)
vbox.addWidget(sButton)
vbox.setAlignment(Qt.AlignTop)
# return a widget containing the local stuff
q = QWidget()
q.setLayout(vbox)
q.setFixedHeight(180)
q.setFixedHeight(240)
return q
def globalMenu(self):
''' Local plot widget '''
# Title string
''' Global plot widget '''
# title string
title = QLabel('Global plots')
title.setStyleSheet(titleStyle)
title.setAlignment(Qt.AlignCenter)
# Epoch input field
# epoch input field
epochLabel = QLabel('Epoch [yrs.]')
epochLabel.setAlignment(Qt.AlignCenter)
self.epoch = QRangeEdit('1900', -1000, 2000)
self.epoch.setFixedWidth(100)
self.epoch.setFixedHeight(22)
# radio buttons for field type
typeLabel = QLabel('Field type')
typeLabel.setAlignment(Qt.AlignCenter)
self.mapNezButton = QRadioButton("NEZ")
self.mapDifButton = QRadioButton("DIF")
self.mapDifButton.setChecked(True)
typeBox = QHBoxLayout()
typeBox.addWidget(self.mapNezButton)
typeBox.addWidget(self.mapDifButton)
typeBox.setAlignment(Qt.AlignCenter)
typeWidget = QWidget()
typeWidget.setLayout(typeBox)
# redundant, but looks better as the location selector is in a hbox
epochBox = QHBoxLayout()
epochBox.addWidget(self.epoch)
epochWidget = QWidget()
epochWidget.setLayout(epochBox)
# Buttons for map and dipole
# buttons for map and dipole
gButton = QPushButton('Plot map')
gButton.clicked.connect(self.plotMap)
dButton = QPushButton('Plot dipole')
dButton.clicked.connect(self.plotDipole)
# Put into widget
# put into widget
vbox = QVBoxLayout()
vbox.addWidget(title)
vbox.addWidget(epochLabel)
vbox.addWidget(epochWidget)
vbox.addWidget(typeLabel)
vbox.addWidget(typeWidget)
vbox.addWidget(gButton)
vbox.addWidget(dButton)
vbox.setAlignment(Qt.AlignTop)
# return a widget containing the global stuff
q = QWidget()
q.setLayout(vbox)
q.setFixedHeight(200)
q.setFixedHeight(270)
return q
def saveMenu(self):
''' Save button widget '''
# title string
title = QLabel('Model output')
title.setStyleSheet(titleStyle)
title.setAlignment(Qt.AlignCenter)
# the button will open another window, which handles the output
gButton = QPushButton('Generate')
gButton.clicked.connect(self.saveWindow.show)
vbox = QVBoxLayout()
vbox.addWidget(title)
vbox.addWidget(gButton)
# return the save button widget
q = QWidget()
q.setLayout(vbox)
q.setFixedHeight(120)
return q
def plotLocal(self):
''' This will update the plotting section, when the plot local button
is pressed. It basically turns the inputs into arguments for the CLI.
'''
# clear the figure
self.fig.clf()
# get the field type
if self.locDifButton.isChecked():
_type = 'dif'
else:
_type = 'nez'
# run the _command with the respective arguments
local_curve(self.parser.parse_args(['local',
'--type',
_type,
self.lat.text(),
self.lon.text(),
self.modelSelector.currentText()]),
fig=self.fig)
# update the plotting canvas
self.canvas.draw()
def plotMap(self):
''' This will update the plotting section, when the plot map button
is pressed. It basically turns the inputs into arguments for the CLI.
'''
# clear the figure
self.fig.clf()
# set up and configure grid for the maps
self.fig.add_subplot(221, projection=ccrs.Mollweide())
self.fig.add_subplot(222, projection=ccrs.Mollweide())
self.fig.add_subplot(212, projection=ccrs.Mollweide())
self.fig.tight_layout()
self.fig.subplots_adjust(top=0.9, bottom=0.1, hspace=0.4)
# get the field type
if self.mapDifButton.isChecked():
_type = 'dif'
else:
_type = 'nez'
# run the _command with the respective arguments
maps(self.parser.parse_args(['map',
'--type',
_type,
self.epoch.text(),
self.modelSelector.currentText()]),
fig=self.fig)
# update the canvas
self.canvas.draw()
def plotDipole(self):
''' This will update the plotting section, when the plot dipole button
is pressed. It basically turns the inputs into arguments for the CLI.
'''
self.fig.clf()
dipole_series(self.parser.parse_args(['dipole',
self.modelSelector
......@@ -284,25 +350,28 @@ class MainWindow(QWidget):
class SaveWindow(QWidget):
def __init__(self):
''' This is another window, handling the output '''
super().__init__()
# set up a custom parser
self.parser = argument_parser()
# set up an initial model
self.model = Model('gufm1')
# configure the window
self.resize(300, 300)
self.setWindowTitle('pymagglobal - output')
# set up a dict for the dropdown menu
self.selectorDict = {'model coefficients at an epoch': 'coeffs-epoch',
'field values at a specific location': 'local'}
# drop down menu of what to store
self.typeSelector = QComboBox()
self.typeSelector.addItems(self.selectorDict.keys())
self.typeSelector.currentIndexChanged.connect(self.updateInputBox)
# title string
info = QLabel('I want to store')
info.setAlignment(Qt.AlignLeft)
# dummy widget, will be updated according to the dropdown
self.inputWidget = QLabel()
# a button for storing
gButton = QPushButton('Store')
gButton.clicked.connect(self.save)
......@@ -320,28 +389,42 @@ class SaveWindow(QWidget):
self.updateInputBox()
def save(self):
''' This will assemble the selections and pass them to the
argument_parser '''
# get the type of output
selected = self.selectorDict[self.typeSelector.currentText()]
# depending on the type of output, assemble the arguments
if selected == 'local':
params = self.lat.text() + ' ' + self.lon.text()
if self.saveDifButton.isChecked():
_type = 'dif'
else:
_type = 'nez'
params = '--type ' + _type + ' ' + self.lat.text() + ' ' \
+ self.lon.text()
elif selected == 'coeffs-epoch':
params = self.epoch.text()
else:
params = 'XXX'
# get an ouput filename
fname, _ = QFileDialog.getSaveFileName(self, 'Choose filename',
str(Path.home()))
# fname will be empty, if the cancel button is pressed or the dialog
# is closed. In this case, go back to the window (do nothing)
# otherwise, pass the arguments to the parser and close
if fname != '':
parse = selected + ' --no-show --output ' + fname + ' ' + params \
+ ' ' + self.model.name
parse = selected + ' --no-show --output ' + fname + ' ' + params \
+ ' ' + self.model.name
args = self.parser.parse_args(parse.split())
args.func(args)
self.close()
args = self.parser.parse_args(parse.split())
args.func(args)
self.close()
def updateInputBox(self):
''' This will update the argument inputs, depending on the dropdown
selection '''
# first clear the widget
self.inputWidget.deleteLater()
# get the input
selected = self.selectorDict[self.typeSelector.currentText()]
# according to the input, set up a new widget
if selected == 'local':
self.inputWidget = self.locSelector()
elif selected == 'coeffs-epoch':
......@@ -349,11 +432,14 @@ class SaveWindow(QWidget):
else:
self.inputWidget = QLabel(self.selectorDict[self.typeSelector
.currentText()])
# insert the widget after the dropdown (position 3)
self.swBox.insertWidget(3, self.inputWidget)
# update
self.swBox.update()
self.updateGeometry()
def locSelector(self):
''' The argument widget for local output '''
latLonLabel = QLabel('Position (lat, lon)')
latLonLabel.setAlignment(Qt.AlignCenter)
......@@ -368,10 +454,26 @@ class SaveWindow(QWidget):
latLonWidget = QWidget()
latLonWidget.setLayout(latLonBox)
# Radio buttons for field type
typeLabel = QLabel('Field type')
typeLabel.setAlignment(Qt.AlignCenter)
self.saveNezButton = QRadioButton("NEZ")
self.saveDifButton = QRadioButton("DIF")
self.saveDifButton.setChecked(True)
typeBox = QHBoxLayout()
typeBox.addWidget(self.saveNezButton)
typeBox.addWidget(self.saveDifButton)
typeBox.setAlignment(Qt.AlignCenter)
typeWidget = QWidget()
typeWidget.setLayout(typeBox)
# Put into widget
vbox = QVBoxLayout()
vbox.addWidget(latLonLabel)
vbox.addWidget(latLonWidget)
vbox.addWidget(typeLabel)
vbox.addWidget(typeWidget)
vbox.setAlignment(Qt.AlignTop)
q = QWidget()
......@@ -379,6 +481,7 @@ class SaveWindow(QWidget):
return q
def epochSelector(self):
''' The argument widget for coefficient output '''
epochLabel = QLabel('Epoch [yrs.]')
epochLabel.setAlignment(Qt.AlignCenter)
......@@ -415,6 +518,8 @@ class QHLine(QFrame):
class QRangeEdit(QLineEdit):
''' A line edit that checks for input in a given range. If the input is
outside, a default value will be inserted. '''
def __init__(self, init, _min, _max, default=0):
super().__init__(init)
self.min = _min
......@@ -437,9 +542,10 @@ def main():
app.setStyleSheet("QLabel{font-size: 16pt;}"
"QComboBox{font-size: 16pt;}"
"QPushButton{font-size: 16pt;}"
"QRadioButton{font-size: 16pt; height: 100px}"
"QLineEdit{font-size: 16pt;}")
_ = MainWindow(argument_parser())
_ = MainWindow()
sys.exit(app.exec_())
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment