Unverified Commit 6f50bc0c authored by jdha's avatar jdha Committed by GitHub
Browse files

Merge pull request #1 from jdha/PyNEMO3

Py nemo3
parents b1ee0b2f a666111c
PyNEMO Description
===================
\ No newline at end of file
...@@ -6,13 +6,13 @@ Created on 21 Jan 2015 ...@@ -6,13 +6,13 @@ Created on 21 Jan 2015
# pylint: disable=E1103 # pylint: disable=E1103
# pylint: disable=no-name-in-module # pylint: disable=no-name-in-module
# pylint: disable=E1002 # pylint: disable=E1002
from PyQt4 import QtGui from PyQt5 import QtGui, QtWidgets
from .nemo_bdy_namelist_edit import NameListEditor from .nemo_bdy_namelist_edit import NameListEditor
from .nemo_bdy_mask_gui import MatplotlibWidget from .nemo_bdy_mask_gui import MatplotlibWidget
from PyQt4.QtGui import QSizePolicy from PyQt5.QtWidgets import QSizePolicy
from PyQt4.Qt import Qt from PyQt5.Qt import Qt
class InputWindow(QtGui.QDialog): class InputWindow(QtWidgets.QDialog):
''' '''
Input Window for editing pyNEMO settings Input Window for editing pyNEMO settings
''' '''
...@@ -43,15 +43,15 @@ class InputWindow(QtGui.QDialog): ...@@ -43,15 +43,15 @@ class InputWindow(QtGui.QDialog):
self.mpl_widget.set_mask_settings(float(setup.settings['mask_max_depth']), float(setup.settings['mask_shelfbreak_dist'])) self.mpl_widget.set_mask_settings(float(setup.settings['mask_max_depth']), float(setup.settings['mask_shelfbreak_dist']))
splitter = QtGui.QSplitter(Qt.Horizontal) splitter = QtWidgets.QSplitter(Qt.Horizontal)
splitter.addWidget(self.nl_editor) splitter.addWidget(self.nl_editor)
splitter.addWidget(self.mpl_widget) splitter.addWidget(self.mpl_widget)
hbox = QtGui.QHBoxLayout() hbox = QtWidgets.QHBoxLayout()
hbox.addWidget(splitter) hbox.addWidget(splitter)
self.setLayout(hbox) self.setLayout(hbox)
#set the Dialog title #set the Dialog title
self.setWindowTitle("PyNEMO Settings Editor") self.setWindowTitle("PyNEMO Settings Editor")
QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Cleanlooks')) QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create('Cleanlooks'))
#show the window #show the window
self.show() self.show()
...@@ -12,8 +12,8 @@ import logging ...@@ -12,8 +12,8 @@ import logging
from scipy import ndimage from scipy import ndimage
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from pynemo.utils import gcoms_break_depth from pynemo.utils import gcoms_break_depth
from PyQt4.QtGui import QMessageBox from PyQt5.QtWidgets import QMessageBox
from PyQt4 import QtCore from PyQt5 import QtCore
class Mask(object): class Mask(object):
"""This is a Mask holder. which reads from a netCDF bathymetry file and """This is a Mask holder. which reads from a netCDF bathymetry file and
...@@ -199,7 +199,7 @@ class Mask(object): ...@@ -199,7 +199,7 @@ class Mask(object):
mask_data[index] = self.data[index] mask_data[index] = self.data[index]
#connected components #connected components
label_mask, num_labels = ndimage.label(mask_data) label_mask, num_labels = ndimage.label(mask_data)
mean_values = ndimage.sum(np.ones(self.data.shape),label_mask,range(1, num_labels+1)) mean_values = ndimage.sum(np.ones(self.data.shape),label_mask,list(range(1, num_labels+1)))
max_area_mask = None max_area_mask = None
if mean_values.size != 0: if mean_values.size != 0:
max_area_index = np.argmax(mean_values)+1 max_area_index = np.argmax(mean_values)+1
...@@ -228,7 +228,7 @@ class Mask(object): ...@@ -228,7 +228,7 @@ class Mask(object):
label_mask, num_labels = ndimage.label(mask_data) label_mask, num_labels = ndimage.label(mask_data)
if num_labels == 0: #if mask is empty/clear if num_labels == 0: #if mask is empty/clear
return return
mean_values = ndimage.sum(np.ones(self.data.shape),label_mask,range(1, num_labels+1)) mean_values = ndimage.sum(np.ones(self.data.shape),label_mask,list(range(1, num_labels+1)))
max_area_mask = None max_area_mask = None
if mean_values.size != 0: if mean_values.size != 0:
max_area_index = np.argmax(mean_values)+1 max_area_index = np.argmax(mean_values)+1
......
...@@ -10,15 +10,15 @@ from mpl_toolkits.basemap import Basemap, cm ...@@ -10,15 +10,15 @@ from mpl_toolkits.basemap import Basemap, cm
import numpy as np import numpy as np
from .selection_editor import PolygonEditor, BoxEditor from .selection_editor import PolygonEditor, BoxEditor
import os.path import os.path
from PyQt4.QtCore import pyqtSignal, pyqtSlot, Qt from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
from nemo_bdy_mask import Mask from .nemo_bdy_mask import Mask
import logging import logging
from PyQt4.QtGui import QSizePolicy from PyQt5.QtWidgets import QSizePolicy
from matplotlib.colors import Normalize from matplotlib.colors import Normalize
mask_alpha = 0.3 mask_alpha = 0.3
from PyQt4 import QtGui from PyQt5 import QtGui, QtWidgets
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib.figure import Figure from matplotlib.figure import Figure
from matplotlib.path import Path from matplotlib.path import Path
...@@ -26,7 +26,7 @@ from matplotlib.transforms import Bbox ...@@ -26,7 +26,7 @@ from matplotlib.transforms import Bbox
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
# pylint: disable=E1002 # pylint: disable=E1002
class MatplotlibWidget(QtGui.QWidget): class MatplotlibWidget(QtWidgets.QWidget):
"""This class is a QWidget for pyNEMO mask plot""" """This class is a QWidget for pyNEMO mask plot"""
min_depth = 200.0 min_depth = 200.0
shelfbreak_dist = 200.0 shelfbreak_dist = 200.0
...@@ -34,7 +34,7 @@ class MatplotlibWidget(QtGui.QWidget): ...@@ -34,7 +34,7 @@ class MatplotlibWidget(QtGui.QWidget):
def __init__(self, parent=None, mask=None, min_depth = 200.0, shelfbreak_dist = 200.0,*args, **kwargs): def __init__(self, parent=None, mask=None, min_depth = 200.0, shelfbreak_dist = 200.0,*args, **kwargs):
""" Initialises the mask, matplot and the navigation toolbar """ """ Initialises the mask, matplot and the navigation toolbar """
super(MatplotlibWidget, self).__init__(parent) super(MatplotlibWidget, self).__init__(parent)
#QtGui.QWidget.__init__(self, parent) #QtWidgets.QWidget.__init__(self, parent)
self.figure = Figure(*args, **kwargs) self.figure = Figure(*args, **kwargs)
self.canvas = FigureCanvas(self.figure) self.canvas = FigureCanvas(self.figure)
self.mask = mask self.mask = mask
...@@ -51,7 +51,7 @@ class MatplotlibWidget(QtGui.QWidget): ...@@ -51,7 +51,7 @@ class MatplotlibWidget(QtGui.QWidget):
self.toolbar.drawing_tool.connect(self.drawing_tool_callback) self.toolbar.drawing_tool.connect(self.drawing_tool_callback)
self.axes = self.figure.add_subplot(111) self.axes = self.figure.add_subplot(111)
self.cbar = None self.cbar = None
layout = QtGui.QVBoxLayout() layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.toolbar) layout.addWidget(self.toolbar)
layout.addWidget(self.canvas) layout.addWidget(self.canvas)
self.setLayout(layout) self.setLayout(layout)
...@@ -126,7 +126,7 @@ class MatplotlibWidget(QtGui.QWidget): ...@@ -126,7 +126,7 @@ class MatplotlibWidget(QtGui.QWidget):
x = np.arange(0, self.mask.lon.shape[0]) x = np.arange(0, self.mask.lon.shape[0])
y = np.arange(0, self.mask.lon.shape[1]) y = np.arange(0, self.mask.lon.shape[1])
x_vals, y_vals = np.meshgrid(y, x) x_vals, y_vals = np.meshgrid(y, x)
grid = zip(x_vals.ravel(), y_vals.ravel()) grid = list(zip(x_vals.ravel(), y_vals.ravel()))
self._drawing_tool.polygon.set_linewidth(1.0) self._drawing_tool.polygon.set_linewidth(1.0)
p_path = Path(self._drawing_tool.polygon.xy) p_path = Path(self._drawing_tool.polygon.xy)
...@@ -146,7 +146,7 @@ class MatplotlibWidget(QtGui.QWidget): ...@@ -146,7 +146,7 @@ class MatplotlibWidget(QtGui.QWidget):
x = np.arange(0, self.mask.lon.shape[0]) x = np.arange(0, self.mask.lon.shape[0])
y = np.arange(0, self.mask.lon.shape[1]) y = np.arange(0, self.mask.lon.shape[1])
x_vals, y_vals = np.meshgrid(y, x) x_vals, y_vals = np.meshgrid(y, x)
grid = zip(x_vals.ravel(), y_vals.ravel()) #check for the index grid = list(zip(x_vals.ravel(), y_vals.ravel())) #check for the index
self._drawing_tool.polygon.set_linewidth(1.0) self._drawing_tool.polygon.set_linewidth(1.0)
p_path = Path(self._drawing_tool.polygon.xy) p_path = Path(self._drawing_tool.polygon.xy)
......
...@@ -10,10 +10,10 @@ from mpl_toolkits.basemap import Basemap, cm ...@@ -10,10 +10,10 @@ from mpl_toolkits.basemap import Basemap, cm
import numpy as np import numpy as np
from .selection_editor import PolygonEditor, BoxEditor from .selection_editor import PolygonEditor, BoxEditor
import os.path import os.path
from PyQt4.QtCore import pyqtSignal, pyqtSlot, Qt from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
from nemo_bdy_mask import Mask from nemo_bdy_mask import Mask
import logging import logging
from PyQt4.QtGui import QSizePolicy from PyQt5.QtGui import QSizePolicy
mask_alpha = 0.3 mask_alpha = 0.3
......
...@@ -6,13 +6,14 @@ Editor for namelist.bdy file ...@@ -6,13 +6,14 @@ Editor for namelist.bdy file
# pylint: disable=E1103 # pylint: disable=E1103
# pylint: disable=no-name-in-module # pylint: disable=no-name-in-module
# pylint: disable=E1002 # pylint: disable=E1002
from PyQt4 import QtGui, QtCore from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt4.QtCore import pyqtSignal, Qt, QRect, QPoint from PyQt5.QtCore import pyqtSignal, Qt, QRect, QPoint
import ast import ast
from PyQt4.QtGui import QMessageBox, QRegion, QIcon, QToolTip, QCursor from PyQt5.QtGui import QRegion, QIcon, QCursor
from PyQt5.QtWidgets import QMessageBox, QToolTip
class NameListEditor(QtGui.QWidget): class NameListEditor(QtWidgets.QWidget):
''' '''
This class creates a gui for the Namelist file options This class creates a gui for the Namelist file options
''' '''
...@@ -34,25 +35,25 @@ class NameListEditor(QtGui.QWidget): ...@@ -34,25 +35,25 @@ class NameListEditor(QtGui.QWidget):
''' '''
Initialises the UI components of the GUI Initialises the UI components of the GUI
''' '''
client = QtGui.QWidget(self) client = QtWidgets.QWidget(self)
# Create the Layout to Grid # Create the Layout to Grid
grid = QtGui.QGridLayout() grid = QtWidgets.QGridLayout()
# Loop through the settings and create widgets for each setting # Loop through the settings and create widgets for each setting
index = 0 index = 0
for setting in self.settings: for setting in self.settings:
# initialises setting Widget # initialises setting Widget
label = QtGui.QLabel(setting) label = QtWidgets.QLabel(setting)
qlabel = QtGui.QPushButton("") qlabel = QtWidgets.QPushButton("")
qlabel.setIcon(self.style().standardIcon(QtGui.QStyle.SP_MessageBoxQuestion)) qlabel.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_MessageBoxQuestion))
if type(self.settings[setting]).__name__ in ['str', 'float', 'double', if type(self.settings[setting]).__name__ in ['str', 'float', 'double',
'int', 'time', 'dict']: 'int', 'time', 'dict']:
text = QtGui.QLineEdit(self) text = QtWidgets.QLineEdit(self)
text.setText(str(self.settings[setting])) text.setText(str(self.settings[setting]))
text.textChanged.connect(lambda value=setting,\ text.textChanged.connect(lambda value=setting,\
var_name=setting: self.label_changed(value, var_name)) var_name=setting: self.label_changed(value, var_name))
if self.bool_settings.has_key(setting): if setting in self.bool_settings:
chkbox = QtGui.QCheckBox(self) chkbox = QtWidgets.QCheckBox(self)
chkbox.setChecked(self.bool_settings[setting]) chkbox.setChecked(self.bool_settings[setting])
chkbox.stateChanged.connect(lambda value=setting,\ chkbox.stateChanged.connect(lambda value=setting,\
var_name=setting:\ var_name=setting:\
...@@ -60,7 +61,7 @@ class NameListEditor(QtGui.QWidget): ...@@ -60,7 +61,7 @@ class NameListEditor(QtGui.QWidget):
grid.addWidget(chkbox, index, 0) grid.addWidget(chkbox, index, 0)
elif type(self.settings[setting]).__name__ == 'bool': elif type(self.settings[setting]).__name__ == 'bool':
text = QtGui.QComboBox(self) text = QtWidgets.QComboBox(self)
text.insertItem(0, 'True') text.insertItem(0, 'True')
text.insertItem(1, 'False') text.insertItem(1, 'False')
if self.settings[setting]: if self.settings[setting]:
...@@ -83,22 +84,22 @@ class NameListEditor(QtGui.QWidget): ...@@ -83,22 +84,22 @@ class NameListEditor(QtGui.QWidget):
client.setLayout(grid) client.setLayout(grid)
#scrollbars #scrollbars
scroll_area = QtGui.QScrollArea(self) scroll_area = QtWidgets.QScrollArea(self)
#scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) #scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll_area.setWidget(client) scroll_area.setWidget(client)
#save cancel buttons #save cancel buttons
btn_widget = QtGui.QWidget(self) btn_widget = QtWidgets.QWidget(self)
hbox_layout = QtGui.QHBoxLayout(self) hbox_layout = QtWidgets.QHBoxLayout(self)
btn_save = QtGui.QPushButton('Save') btn_save = QtWidgets.QPushButton('Save')
btn_save.clicked.connect(self._btn_save_callback) btn_save.clicked.connect(self._btn_save_callback)
self.btn_cancel = QtGui.QPushButton('Close') self.btn_cancel = QtWidgets.QPushButton('Close')
self.btn_cancel.clicked.connect(self._btn_cancel_callback) self.btn_cancel.clicked.connect(self._btn_cancel_callback)
hbox_layout.addWidget(btn_save) hbox_layout.addWidget(btn_save)
hbox_layout.addWidget(self.btn_cancel) hbox_layout.addWidget(self.btn_cancel)
btn_widget.setLayout(hbox_layout) btn_widget.setLayout(hbox_layout)
box_layout = QtGui.QVBoxLayout(self) box_layout = QtWidgets.QVBoxLayout(self)
box_layout.addWidget(scroll_area) box_layout.addWidget(scroll_area)
box_layout.addWidget(btn_widget) box_layout.addWidget(btn_widget)
btn_widget.setMaximumWidth(400) btn_widget.setMaximumWidth(400)
...@@ -109,7 +110,7 @@ class NameListEditor(QtGui.QWidget): ...@@ -109,7 +110,7 @@ class NameListEditor(QtGui.QWidget):
def label_changed(self, value, name): def label_changed(self, value, name):
""" callback when the text is changed in the text box""" """ callback when the text is changed in the text box"""
self.new_settings[name] = unicode(value).encode('utf_8') self.new_settings[name] = str(value).encode('utf_8')
def combo_index_changed(self, value, name): def combo_index_changed(self, value, name):
""" callback when the True/False drop down for the settings which has boolean value """ callback when the True/False drop down for the settings which has boolean value
...@@ -153,7 +154,7 @@ class NameListEditor(QtGui.QWidget): ...@@ -153,7 +154,7 @@ class NameListEditor(QtGui.QWidget):
try: try:
self.mask_settings_update.emit(float(self.settings['mask_max_depth']), float(self.settings['mask_shelfbreak_dist'])) self.mask_settings_update.emit(float(self.settings['mask_max_depth']), float(self.settings['mask_shelfbreak_dist']))
except KeyError: except KeyError:
print 'Set the mask setting mask_max_depth and mask_shelfbreak_dist' print('Set the mask setting mask_max_depth and mask_shelfbreak_dist')
if self.bool_settings['mask_file']: if self.bool_settings['mask_file']:
self.bathymetry_update.emit(self.settings['bathy'],self.settings['mask_file']) self.bathymetry_update.emit(self.settings['bathy'],self.settings['mask_file'])
......
...@@ -6,13 +6,13 @@ Created on 6 Aug 2015 ...@@ -6,13 +6,13 @@ Created on 6 Aug 2015
import logging import logging
import os import os
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from PyQt4 import QtGui from PyQt5 import QtGui, QtWidgets
from PyQt4 import QtCore from PyQt5 import QtCore
from PyQt4.QtCore import pyqtSlot from PyQt5.QtCore import pyqtSlot
import nemo_ncml_tab_widget from . import nemo_ncml_tab_widget
from thredds_crawler.crawl import Crawl from thredds_crawler.crawl import Crawl
class Ncml_generator(QtGui.QDialog): class Ncml_generator(QtWidgets.QDialog):
''' '''
Gui editor to capture user input for the purpose of generating NCML representation of pynemo source datasets. Gui editor to capture user input for the purpose of generating NCML representation of pynemo source datasets.
''' '''
...@@ -30,35 +30,35 @@ class Ncml_generator(QtGui.QDialog): ...@@ -30,35 +30,35 @@ class Ncml_generator(QtGui.QDialog):
self.baseFile = os.path.join(testpath,'base.ncml') self.baseFile = os.path.join(testpath,'base.ncml')
else: else:
self.baseFile = basefile self.baseFile = basefile
print 'ncml baseFile : ', str(self.baseFile) print('ncml baseFile : ', str(self.baseFile))
self.filename = None # store the output file pointer self.filename = None # store the output file pointer
self.initUI() self.initUI()
def initUI(self): def initUI(self):
QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 11)) QtWidgets.QToolTip.setFont(QtGui.QFont('SansSerif', 11))
''' '''
vbox is the top container vbox is the top container
''' '''
#the #the
vbox = QtGui.QVBoxLayout(self) vbox = QtWidgets.QVBoxLayout(self)
vbox.setSpacing(10) vbox.setSpacing(10)
vbox.setContentsMargins(10, 10, 5, 5) vbox.setContentsMargins(10, 10, 5, 5)
''' '''
top panel for output file top panel for output file
''' '''
top_outfile_label = QtGui.QLabel(unicode('Output filename').encode('utf-8')) top_outfile_label = QtWidgets.QLabel('Output filename')
self.top_outfile_name = QtGui.QLineEdit() #location is pre-defined self.top_outfile_name = QtWidgets.QLineEdit() #location is pre-defined
self.top_outfile_name.setToolTip(unicode('Define output file').encode('utf-8')) self.top_outfile_name.setToolTip('Define output file')
self.top_outfile_name.returnPressed.connect(self.get_fname_input) self.top_outfile_name.returnPressed.connect(self.get_fname_input)
top_outfile_button = QtGui.QPushButton(unicode('Select file').encode('utf-8')) top_outfile_button = QtWidgets.QPushButton('Select file')
top_outfile_button.clicked.connect(self.get_fname) top_outfile_button.clicked.connect(self.get_fname)
top_grpBox = QtGui.QGroupBox(unicode('Define output file').encode('utf-8'), None) top_grpBox = QtWidgets.QGroupBox('Define output file', None)
top_grid = QtGui.QGridLayout(top_grpBox) top_grid = QtWidgets.QGridLayout(top_grpBox)
top_grid.setVerticalSpacing(5) top_grid.setVerticalSpacing(5)
top_grid.setHorizontalSpacing(10) top_grid.setHorizontalSpacing(10)
top_grid.addWidget(top_outfile_label, 1, 0) top_grid.addWidget(top_outfile_label, 1, 0)
...@@ -68,23 +68,23 @@ class Ncml_generator(QtGui.QDialog): ...@@ -68,23 +68,23 @@ class Ncml_generator(QtGui.QDialog):
''' '''
middle panel for tab folder middle panel for tab folder
''' '''
self.tabWidget = QtGui.QTabWidget() self.tabWidget = QtWidgets.QTabWidget()
self.tracer_tab = nemo_ncml_tab_widget.Ncml_tab(unicode("Tracer").encode('utf-8')) self.tracer_tab = nemo_ncml_tab_widget.Ncml_tab("Tracer")
self.tracer_tab.setEnabled(False) self.tracer_tab.setEnabled(False)
self.dynamic_tab = nemo_ncml_tab_widget.Ncml_tab(unicode("Dynamics").encode('utf-8')) self.dynamic_tab = nemo_ncml_tab_widget.Ncml_tab("Dynamics")
self.dynamic_tab.setEnabled(False) self.dynamic_tab.setEnabled(False)
self.ice_tab = nemo_ncml_tab_widget.Ncml_tab(unicode("Ice").encode('utf-8')) self.ice_tab = nemo_ncml_tab_widget.Ncml_tab("Ice")
self.ice_tab.setEnabled(False) self.ice_tab.setEnabled(False)
self.ecosys_tab = nemo_ncml_tab_widget.Ncml_tab(unicode("Ecosystem").encode('utf-8')) self.ecosys_tab = nemo_ncml_tab_widget.Ncml_tab("Ecosystem")
self.ecosys_tab.setEnabled(False) self.ecosys_tab.setEnabled(False)
self.grid_tab = nemo_ncml_tab_widget.Ncml_tab(unicode("Grid").encode('utf-8')) self.grid_tab = nemo_ncml_tab_widget.Ncml_tab("Grid")
self.grid_tab.setEnabled(False) self.grid_tab.setEnabled(False)
self.tabWidget.addTab(self.tracer_tab, unicode("Tracer").encode('utf-8')) self.tabWidget.addTab(self.tracer_tab, "Tracer")
self.tabWidget.addTab(self.dynamic_tab, unicode("Dynamics").encode('utf-8')) self.tabWidget.addTab(self.dynamic_tab, "Dynamics")
self.tabWidget.addTab(self.ice_tab, unicode("Ice").encode('utf-8')) self.tabWidget.addTab(self.ice_tab, "Ice")
self.tabWidget.addTab(self.ecosys_tab, unicode("Ecosystem").encode('utf-8')) # should be disabled self.tabWidget.addTab(self.ecosys_tab, "Ecosystem") # should be disabled
self.tabWidget.addTab(self.grid_tab, unicode("Grid").encode('utf-8')) # should be disabled self.tabWidget.addTab(self.grid_tab, "Grid") # should be disabled
self.tabWidget.setMovable(False) self.tabWidget.setMovable(False)
# if self.tabWidget.widget(self.tabWidget.currentIndex()).isEnabled() is True: # if self.tabWidget.widget(self.tabWidget.currentIndex()).isEnabled() is True:
...@@ -93,13 +93,13 @@ class Ncml_generator(QtGui.QDialog): ...@@ -93,13 +93,13 @@ class Ncml_generator(QtGui.QDialog):
''' '''
button bar button bar
''' '''
go_btn = QtGui.QPushButton(unicode('Generate').encode('utf-8')) go_btn = QtWidgets.QPushButton('Generate')
go_btn.setToolTip(unicode('Add all variable definitions before generating NcML file.').encode('utf-8')) go_btn.setToolTip('Add all variable definitions before generating NcML file.')
cancel_btn = QtGui.QPushButton(unicode('Cancel').encode('utf-8')) cancel_btn = QtWidgets.QPushButton('Cancel')
enable_btn = QtGui.QPushButton(unicode('Enable Tab').encode('utf-8')) enable_btn = QtWidgets.QPushButton('Enable Tab')
#layout button bar #layout button bar
btn_hBox = QtGui.QHBoxLayout(None) btn_hBox = QtWidgets.QHBoxLayout(None)
btn_hBox.setMargin(5) btn_hBox.setContentsMargins(5, 5, 5, 5)
btn_hBox.setSpacing(10) btn_hBox.setSpacing(10)
btn_hBox.setAlignment(QtCore.Qt.AlignRight) btn_hBox.setAlignment(QtCore.Qt.AlignRight)
btn_hBox.addWidget(enable_btn) btn_hBox.addWidget(enable_btn)
...@@ -120,7 +120,7 @@ class Ncml_generator(QtGui.QDialog): ...@@ -120,7 +120,7 @@ class Ncml_generator(QtGui.QDialog):
#self.setLayout(grp_box) #self.setLayout(grp_box)
self.setWindowIcon(QtGui.QIcon('/Users/jdha/anaconda/lib/python2.7/site-packages/pynemo-0.2-py2.7.egg/pynemo/gui/nemo_icon.png')) #doesn't work self.setWindowIcon(QtGui.QIcon('/Users/jdha/anaconda/lib/python2.7/site-packages/pynemo-0.2-py2.7.egg/pynemo/gui/nemo_icon.png')) #doesn't work
self.setWindowTitle(unicode("PyNEMO NcML Generator").encode('utf-8')) self.setWindowTitle("PyNEMO NcML Generator")
self.resize(650,300) self.resize(650,300)
#has to change the default focus to stop the output file QTextedit to trigger the widget in focus when enter is pressed. Not sure why this happens??? #has to change the default focus to stop the output file QTextedit to trigger the widget in focus when enter is pressed. Not sure why this happens???
...@@ -137,7 +137,7 @@ class Ncml_generator(QtGui.QDialog): ...@@ -137,7 +137,7 @@ class Ncml_generator(QtGui.QDialog):
# When you call getOpenFileName, a file picker dialog is created # When you call getOpenFileName, a file picker dialog is created
# and if the user selects a file, it's path is returned, and if not # and if the user selects a file, it's path is returned, and if not
# (ie, the user cancels the operation) None is returned # (ie, the user cancels the operation) None is returned
fname = QtGui.QFileDialog.getSaveFileName(self, 'Select output file', '', selectedFilter='*.ncml') fname = QtWidgets.QFileDialog.getSaveFileName(self, 'Select output file', '', selectedFilter='*.ncml')
if fname: if fname:
self.filename = fname #returns a QString self.filename = fname #returns a QString
self.top_outfile_name.setText(str(fname)) self.top_outfile_name.setText(str(fname))
...@@ -155,9 +155,9 @@ class Ncml_generator(QtGui.QDialog): ...@@ -155,9 +155,9 @@ class Ncml_generator(QtGui.QDialog):
@pyqtSlot() @pyqtSlot()
def enable_btn_update(self, enable_btn): def enable_btn_update(self, enable_btn):
if self.tabWidget.widget(self.tabWidget.currentIndex()).isEnabled() is True: if self.tabWidget.widget(self.tabWidget.currentIndex()).isEnabled() is True:
enable_btn.setText(unicode('Disable Tab').encode('utf-8')) enable_btn.setText('Disable Tab')
else: else:
enable_btn.setText(unicode('Enable Tab').encode('utf-8')) enable_btn.setText('Enable Tab')
''' '''
call back to handle the generate button pressed call back to handle the generate button pressed
''' '''
...@@ -167,10 +167,10 @@ class Ncml_generator(QtGui.QDialog): ...@@ -167,10 +167,10 @@ class Ncml_generator(QtGui.QDialog):
#validate output file #validate output file
if self.tabWidget.widget(self.tabWidget.currentIndex()).isEnabled() is True: if self.tabWidget.widget(self.tabWidget.currentIndex()).isEnabled() is True:
self.tabWidget.widget(self.tabWidget.currentIndex()).setEnabled(False) self.tabWidget.widget(self.tabWidget.currentIndex()).setEnabled(False)
enable_btn.setText(unicode('Enable Tab').encode('utf-8')) enable_btn.setText('Enable Tab')
else: else:
self.tabWidget.widget(self.tabWidget.currentIndex()).setEnabled(True) self.tabWidget.widget(self.tabWidget.currentIndex()).setEnabled(True)
enable_btn.setText(unicode('Disable Tab').encode('utf-8')) enable_btn.setText('Disable Tab')
''' '''
call back to handle the generate button pressed call back to handle the generate button pressed
...@@ -180,14 +180,14 @@ class Ncml_generator(QtGui.QDialog): ...@@ -180,14 +180,14 @@ class Ncml_generator(QtGui.QDialog):
#validate output file #validate output file
if self.filename is None or self.filename == "": if self.filename is None or self.filename == "":
if self.top_outfile_name.text() is None or self.top_outfile_name.text() == "": if self.top_outfile_name.text() is None or self.top_outfile_name.text() == "":
QtGui.QMessageBox.critical(self, unicode('Something is wrong').encode('utf-8'), unicode('No output file specified!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.critical(self, 'Something is wrong', 'No output file specified!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
return return
else: else:
self.filename = self.top_outfile_name.text() self.filename = self.top_outfile_name.text()
if(os.path.exists(os.path.dirname(str(self.filename)))) == False: if(os.path.exists(os.path.dirname(str(self.filename)))) == False:
#if os.path.dirname(os.path.dirname(os.path.exists(os.path.normpath(str(self.filename))))) == False: #if os.path.dirname(os.path.dirname(os.path.exists(os.path.normpath(str(self.filename))))) == False:
QtGui.QMessageBox.critical(self, unicode('Something is wrong').encode('utf-8'), unicode('Invalid output directory! Cannot generate file!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.critical(self, 'Something is wrong', 'Invalid output directory! Cannot generate file!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
#print 'invalid target directory! Cannot generate.' #print 'invalid target directory! Cannot generate.'
return return
...@@ -201,7 +201,7 @@ class Ncml_generator(QtGui.QDialog): ...@@ -201,7 +201,7 @@ class Ncml_generator(QtGui.QDialog):
self.tracer_tab.vosaline.src != "" : self.tracer_tab.vosaline.src != "" :
tabsList.extend([self.tracer_tab.votemper, self.tracer_tab.vosaline]) tabsList.extend([self.tracer_tab.votemper, self.tracer_tab.vosaline])
else: else:
QtGui.QMessageBox.information(self, unicode('Something is wrong').encode('utf-8'), unicode('Not all the variables under the tracer tab have been defined!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'Something is wrong', 'Not all the variables under the tracer tab have been defined!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
if self.ice_tab.isEnabled() is True: if self.ice_tab.isEnabled() is True:
...@@ -210,7 +210,7 @@ class Ncml_generator(QtGui.QDialog): ...@@ -210,7 +210,7 @@ class Ncml_generator(QtGui.QDialog):
self.ice_tab.isnowthi.src != "" : self.ice_tab.isnowthi.src != "" :
tabsList.extend([self.ice_tab.iicethic, self.ice_tab.ileadfra, self.ice_tab.isnowthi]) tabsList.extend([self.ice_tab.iicethic, self.ice_tab.ileadfra, self.ice_tab.isnowthi])
else: else:
QtGui.QMessageBox.information(self, unicode('Something is wrong').encode('utf-8'), unicode('Not all the variables under the ice tab have been defined!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'Something is wrong', 'Not all the variables under the ice tab have been defined!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
if self.dynamic_tab.isEnabled() is True: if self.dynamic_tab.isEnabled() is True:
if self.dynamic_tab.vozocrtx.src != "" and \ if self.dynamic_tab.vozocrtx.src != "" and \
...@@ -218,7 +218,7 @@ class Ncml_generator(QtGui.QDialog): ...@@ -218,7 +218,7 @@ class Ncml_generator(QtGui.QDialog):
self.dynamic_tab.sossheig.src != "" : self.dynamic_tab.sossheig.src != "" :
tabsList.extend([self.dynamic_tab.vozocrtx, self.dynamic_tab.vomecrty, self.dynamic_tab.sossheig]) tabsList.extend([self.dynamic_tab.vozocrtx, self.dynamic_tab.vomecrty, self.dynamic_tab.sossheig])
else: else:
QtGui.QMessageBox.information(self, unicode('Something is wrong').encode('utf-8'), unicode('Not all the variables under the dynamics tab have been defined!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'Something is wrong', 'Not all the variables under the dynamics tab have been defined!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
if self.grid_tab.isEnabled() is True: if self.grid_tab.isEnabled() is True:
if self.grid_tab.gdept.src != "" and \ if self.grid_tab.gdept.src != "" and \
...@@ -229,14 +229,14 @@ class Ncml_generator(QtGui.QDialog): ...@@ -229,14 +229,14 @@ class Ncml_generator(QtGui.QDialog):
self.grid_tab.e3v.src != "" : self.grid_tab.e3v.src != "" :
tabsList.extend([self.grid_tab.gdept, self.grid_tab.gdepw, self.grid_tab.mbathy, self.grid_tab.e3t, self.grid_tab.e3u, self.grid_tab.e3v]) tabsList.extend([self.grid_tab.gdept, self.grid_tab.gdepw, self.grid_tab.mbathy, self.grid_tab.e3t, self.grid_tab.e3u, self.grid_tab.e3v])
else: else:
QtGui.QMessageBox.information(self, unicode('Something is wrong').encode('utf-8'), unicode('Not all the variables under the grid tab have been defined!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'Something is wrong', 'Not all the variables under the grid tab have been defined!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
try: try:
self.generateNcML(tabsList) #go ahead and do it self.generateNcML(tabsList) #go ahead and do it
except: except:
raise raise
QtGui.QMessageBox.information(self, unicode('Success.').encode('utf-8'), unicode('NcML file generated.').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'Success.', 'NcML file generated.', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
''' '''
Function to generates the NcML text and write it to the user defined output file Function to generates the NcML text and write it to the user defined output file
...@@ -248,68 +248,68 @@ class Ncml_generator(QtGui.QDialog): ...@@ -248,68 +248,68 @@ class Ncml_generator(QtGui.QDialog):
self.root = self.tree.getroot() self.root = self.tree.getroot()
#create a netcdf element for each tab variable #create a netcdf element for each tab variable
for tab in tabsList: for tab in tabsList:
netcdfE = ET.Element(ns+unicode('netcdf').encode('utf-8')) #src directory is converted to the correct format when added/ netcdfE = ET.Element(ns+'netcdf') #src directory is converted to the correct format when added/
if str(tab.src).startswith("http:") or str(tab.src).startswith("https:"): if str(tab.src).startswith("http:") or str(tab.src).startswith("https:"):
#Its url so use thredds crawler to get the urls #Its url so use thredds crawler to get the urls
urls = self.url_trawler(tab.src,str(tab.regex)) urls = self.url_trawler(tab.src,str(tab.regex))
aggE = ET.Element(ns+unicode('aggregation').encode('utf-8'), name=unicode(str(tab.name)).encode('utf-8'), type=unicode('joinExisting').encode('utf-8'), dimName=unicode('time_counter').encode('utf-8')) #tab.name already encoded aggE = ET.Element(ns+'aggregation', name=str(tab.name), type='joinExisting', dimName='time_counter') #tab.name already encoded
for nc_url in urls: for nc_url in urls:
tcNetcdf = ET.Element(ns+unicode('netcdf').encode('utf-8'), location=unicode(str(nc_url)).encode('utf-8')) tcNetcdf = ET.Element(ns+'netcdf', location=str(nc_url))
aggE.append(tcNetcdf) aggE.append(tcNetcdf)
netcdfE.append(aggE) netcdfE.append(aggE)
else: else:
scanE = ET.Element(ns+unicode('scan').encode('utf-8'), location=unicode(str(tab.src)).encode('utf-8'), regExp=unicode(str(tab.regex)).encode('utf-8')) scanE = ET.Element(ns+'scan', location=str(tab.src), regExp=str(tab.regex))
if tab.subdirs == True: if tab.subdirs == True:
scanE.set(unicode('subdirs').encode('utf-8'), unicode('true').encode('utf-8')) scanE.set('subdirs', 'true')
aggE = ET.Element(ns+unicode('aggregation').encode('utf-8'), name=unicode(str(tab.name)).encode('utf-8'), type=unicode('joinExisting').encode('utf-8'), dimName=unicode('time_counter').encode('utf-8')) #tab.name already encoded aggE = ET.Element(ns+'aggregation', name=str(tab.name), type='joinExisting', dimName='time_counter') #tab.name already encoded
aggE.append(scanE) aggE.append(scanE)
netcdfE.append(aggE) netcdfE.append(aggE)
self.root[0].append(netcdfE) #add the new netcdf element to the top aggregation self.root[0].append(netcdfE) #add the new netcdf element to the top aggregation
#deal with variable name change TODO put this into a loop? #deal with variable name change TODO put this into a loop?
if tab.old_name is not None and tab.old_name != "": if tab.old_name is not None and tab.old_name != "":
vname = unicode('variable').encode('utf-8') vname = 'variable'
#v is None #v is None
if tab.name == unicode('temperature').encode('utf-8') and tab.old_name != unicode('votemper').encode('utf-8'): if tab.name == 'temperature' and tab.old_name != 'votemper':
v = ET.Element(ns+vname, name='votemper', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='votemper', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('salinity').encode('utf-8') and tab.old_name != unicode('vosaline').encode('utf-8'): elif tab.name == 'salinity' and tab.old_name != 'vosaline':
v = ET.Element(ns+vname, name='vosaline', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='vosaline', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('ice_thickness').encode('utf-8') and tab.old_name != unicode('iicethic').encode('utf-8'): elif tab.name == 'ice_thickness' and tab.old_name != 'iicethic':
v = ET.Element(ns+vname, name='iicethic', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='iicethic', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('leads_fraction').encode('utf-8') and tab.old_name != unicode('ileadfra').encode('utf-8'): elif tab.name == 'leads_fraction' and tab.old_name != 'ileadfra':
v = ET.Element(ns+vname, name='ileadfra', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='ileadfra', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('snow_thickness').encode('utf-8') and tab.old_name != unicode('isnowthi').encode('utf-8'): elif tab.name == 'snow_thickness' and tab.old_name != 'isnowthi':
v = ET.Element(ns+vname, name='isnowthi', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='isnowthi', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('zonal_velocity').encode('utf-8') and tab.old_name != unicode('vozocrtx').encode('utf-8'): elif tab.name == 'zonal_velocity' and tab.old_name != 'vozocrtx':
v = ET.Element(ns+vname, name='vozocrtx', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='vozocrtx', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('meridian_velocity').encode('utf-8') and tab.old_name != unicode('vomecrty').encode('utf-8'): elif tab.name == 'meridian_velocity' and tab.old_name != 'vomecrty':
v = ET.Element(ns+vname, name='vomecrty', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='vomecrty', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('sea_surface_height').encode('utf-8') and tab.old_name != unicode('sossheig').encode('utf-8'): elif tab.name == 'sea_surface_height' and tab.old_name != 'sossheig':
v = ET.Element(ns+vname, name='sossheig', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='sossheig', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('depth_at_t_points').encode('utf-8') and tab.old_name != unicode('gdept').encode('utf-8'): elif tab.name == 'depth_at_t_points' and tab.old_name != 'gdept':
v = ET.Element(ns+vname, name='gdept', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='gdept', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('depth_at_w_points').encode('utf-8') and tab.old_name != unicode('gdepw').encode('utf-8'): elif tab.name == 'depth_at_w_points' and tab.old_name != 'gdepw':
v = ET.Element(ns+vname, name='gdepw', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='gdepw', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('number_of_wet_levels').encode('utf-8') and tab.old_name != unicode('mbathy').encode('utf-8'): elif tab.name == 'number_of_wet_levels' and tab.old_name != 'mbathy':
v = ET.Element(ns+vname, name='mbathy', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='mbathy', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('vertical_scale_factors_at_t_points').encode('utf-8') and tab.old_name != unicode('e3t').encode('utf-8'): elif tab.name == 'vertical_scale_factors_at_t_points' and tab.old_name != 'e3t':
v = ET.Element(ns+vname, name='e3t', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='e3t', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('vertical_scale_factors_at_u_points').encode('utf-8') and tab.old_name != unicode('e3u').encode('utf-8'): elif tab.name == 'vertical_scale_factors_at_u_points' and tab.old_name != 'e3u':
v = ET.Element(ns+vname, name='e3u', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='e3u', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
elif tab.name == unicode('vertical_scale_factors_at_v_points').encode('utf-8') and tab.old_name != unicode('e3v').encode('utf-8'): elif tab.name == 'vertical_scale_factors_at_v_points' and tab.old_name != 'e3v':
v = ET.Element(ns+vname, name='e3v', orgName = str(tab.old_name)) v = ET.Element(ns+vname, name='e3v', orgName = str(tab.old_name))
self.root.append(v) self.root.append(v)
...@@ -317,7 +317,8 @@ class Ncml_generator(QtGui.QDialog): ...@@ -317,7 +317,8 @@ class Ncml_generator(QtGui.QDialog):
try: try:
self.indent(self.root, 0) #24Aug15 format the xml for pretty printing self.indent(self.root, 0) #24Aug15 format the xml for pretty printing
self.tree.write(self.filename, encoding='utf-8') self.tree.write(self.filename, encoding='utf-8')
except IOError as (errno, strerror): except IOError as xxx_todo_changeme:
(errno, strerror) = xxx_todo_changeme.args
self.logger.error("I/O error({0}): {1}".format(errno, strerror)) self.logger.error("I/O error({0}): {1}".format(errno, strerror))
except: except:
self.logger.error('Error generating ncml file') self.logger.error('Error generating ncml file')
...@@ -331,9 +332,9 @@ class Ncml_generator(QtGui.QDialog): ...@@ -331,9 +332,9 @@ class Ncml_generator(QtGui.QDialog):
parser = ET.XMLParser(encoding="utf-8") parser = ET.XMLParser(encoding="utf-8")
tree = ET.parse(self.baseFile, parser=parser) tree = ET.parse(self.baseFile, parser=parser)
return tree return tree
except ET.ParseError, v: except ET.ParseError as v:
row, column = v.position row, column = v.position
print "error on row", row, "column", column, ":", v print("error on row", row, "column", column, ":", v)
''' '''
Function to format xml. Based on code provided by http://effbot.org/zone/element-lib Function to format xml. Based on code provided by http://effbot.org/zone/element-lib
......
...@@ -5,11 +5,11 @@ Created on 2 Jul 2015 ...@@ -5,11 +5,11 @@ Created on 2 Jul 2015
''' '''
import logging import logging
import os import os
from PyQt4 import QtGui from PyQt5 import QtGui, QtWidgets
from PyQt4 import QtCore from PyQt5 import QtCore
from PyQt4.QtCore import pyqtSlot from PyQt5.QtCore import pyqtSlot
class Ncml_tab(QtGui.QWidget): class Ncml_tab(QtWidgets.QWidget):
''' '''
tab contents to define child aggregation tab contents to define child aggregation
''' '''
...@@ -28,49 +28,49 @@ class Ncml_tab(QtGui.QWidget): ...@@ -28,49 +28,49 @@ class Ncml_tab(QtGui.QWidget):
def initUI(self): def initUI(self):
QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 11)) QtWidgets.QToolTip.setFont(QtGui.QFont('SansSerif', 11))
self.varStackedWidget = QtGui.QStackedWidget() self.varStackedWidget = QtWidgets.QStackedWidget()
#variable chooser combobox #variable chooser combobox
combo_vars = [] combo_vars = []
if(self.var == unicode("Tracer").encode('utf-8')): if(self.var == "Tracer"):
combo_vars = [unicode('temperature').encode('utf-8'),unicode('salinity').encode('utf-8')] #votemper, vosaline combo_vars = ['temperature','salinity'] #votemper, vosaline
self.votemper = ncml_variable(unicode('temperature').encode('utf-8'),'votemper') self.votemper = ncml_variable('temperature','votemper')
self.vosaline = ncml_variable(unicode('salinity').encode('utf-8'),'vosaline') self.vosaline = ncml_variable('salinity','vosaline')
self.varStackedWidget.addWidget(self._addStackWidget("votemper")) self.varStackedWidget.addWidget(self._addStackWidget("votemper"))
self.varStackedWidget.addWidget(self._addStackWidget("vosaline")) self.varStackedWidget.addWidget(self._addStackWidget("vosaline"))
#debug #debug
# print 'Tracer has ' + str(self.varStackedWidget.count()) # print 'Tracer has ' + str(self.varStackedWidget.count())
elif(self.var == unicode("Ice").encode('utf-8')): elif(self.var == "Ice"):
combo_vars = [unicode('ice thickness').encode('utf-8'),unicode('leads fraction').encode('utf-8'),unicode('snow thickness').encode('utf-8')] #'iicethic,ileadfra,isnowthi combo_vars = ['ice thickness','leads fraction','snow thickness'] #'iicethic,ileadfra,isnowthi
self.iicethic = ncml_variable(unicode('ice_thickness').encode('utf-8'),'iicethic') self.iicethic = ncml_variable('ice_thickness','iicethic')
self.ileadfra = ncml_variable(unicode('leads_fraction').encode('utf-8'),'ileadfra') self.ileadfra = ncml_variable('leads_fraction','ileadfra')
self.isnowthi = ncml_variable(unicode('snow_thickness').encode('utf-8'),'isnowthi') self.isnowthi = ncml_variable('snow_thickness','isnowthi')
self.varStackedWidget.addWidget(self._addStackWidget("iicethic")) self.varStackedWidget.addWidget(self._addStackWidget("iicethic"))
self.varStackedWidget.addWidget(self._addStackWidget("ileadfra")) self.varStackedWidget.addWidget(self._addStackWidget("ileadfra"))
self.varStackedWidget.addWidget(self._addStackWidget("isnowthi")) self.varStackedWidget.addWidget(self._addStackWidget("isnowthi"))
# print 'Ice has ' + str(self.varStackedWidget.count()) # print 'Ice has ' + str(self.varStackedWidget.count())
elif(self.var == unicode("Dynamics").encode('utf-8')): elif(self.var == "Dynamics"):
combo_vars = [unicode('zonal velocity').encode('utf-8'), unicode('meridian velocity').encode('utf-8'), unicode('sea surface height').encode('utf-8')] #vozocrtx, vomecrty, sossheig combo_vars = ['zonal velocity', 'meridian velocity', 'sea surface height'] #vozocrtx, vomecrty, sossheig
self.vozocrtx = ncml_variable(unicode('zonal_velocity').encode('utf-8'),'vozocrtx') self.vozocrtx = ncml_variable('zonal_velocity','vozocrtx')
self.vomecrty = ncml_variable(unicode('meridian_velocity').encode('utf-8'),'vomecrty') self.vomecrty = ncml_variable('meridian_velocity','vomecrty')
self.sossheig = ncml_variable(unicode('sea_surface_height').encode('utf-8'),'sossheig') self.sossheig = ncml_variable('sea_surface_height','sossheig')
self.varStackedWidget.addWidget(self._addStackWidget("vozocrtx")) self.varStackedWidget.addWidget(self._addStackWidget("vozocrtx"))
self.varStackedWidget.addWidget(self._addStackWidget("vomecrty")) self.varStackedWidget.addWidget(self._addStackWidget("vomecrty"))
self.varStackedWidget.addWidget(self._addStackWidget("sossheig")) self.varStackedWidget.addWidget(self._addStackWidget("sossheig"))
# print 'Dynamics has ' + str(self.varStackedWidget.count()) # print 'Dynamics has ' + str(self.varStackedWidget.count())
elif(self.var == unicode("Grid").encode('utf-8')): elif(self.var == "Grid"):
combo_vars = [unicode('depth at T points').encode('utf-8'), combo_vars = ['depth at T points',
unicode('depth at W points').encode('utf-8'), 'depth at W points',
unicode('number of wet levels').encode('utf-8'), 'number of wet levels',
unicode('vertical scale factor at T points').encode('utf-8'), 'vertical scale factor at T points',
unicode('vertical scale factor at U points').encode('utf-8'), 'vertical scale factor at U points',
unicode('vertical scale factor at V points').encode('utf-8')] #gdept,gdepw,mbathy 'vertical scale factor at V points'] #gdept,gdepw,mbathy
self.gdept = ncml_variable(unicode('depth_at_t_points').encode('utf-8'),'gdept') self.gdept = ncml_variable('depth_at_t_points','gdept')
self.gdepw = ncml_variable(unicode('depth_at_w_points').encode('utf-8'),'gdepw') self.gdepw = ncml_variable('depth_at_w_points','gdepw')
self.mbathy = ncml_variable(unicode('number_of_wet_levels').encode('utf-8'),'mbathy') self.mbathy = ncml_variable('number_of_wet_levels','mbathy')
self.e3t = ncml_variable(unicode('vertical_scale_factors_at_t_points').encode('utf-8'),'e3t') self.e3t = ncml_variable('vertical_scale_factors_at_t_points','e3t')
self.e3u = ncml_variable(unicode('vertical_scale_factors_at_u_points').encode('utf-8'),'e3u') self.e3u = ncml_variable('vertical_scale_factors_at_u_points','e3u')
self.e3v = ncml_variable(unicode('vertical_scale_factors_at_v_points').encode('utf-8'),'e3v') self.e3v = ncml_variable('vertical_scale_factors_at_v_points','e3v')
self.varStackedWidget.addWidget(self._addStackWidget("gdept")) self.varStackedWidget.addWidget(self._addStackWidget("gdept"))
self.varStackedWidget.addWidget(self._addStackWidget("gdepw")) self.varStackedWidget.addWidget(self._addStackWidget("gdepw"))
self.varStackedWidget.addWidget(self._addStackWidget("mbathy")) self.varStackedWidget.addWidget(self._addStackWidget("mbathy"))
...@@ -82,7 +82,7 @@ class Ncml_tab(QtGui.QWidget): ...@@ -82,7 +82,7 @@ class Ncml_tab(QtGui.QWidget):
vars = ['nitrate','silicate'] #nitrate, silicate vars = ['nitrate','silicate'] #nitrate, silicate
self.varStackedWidget.setCurrentIndex(0) #we rely on the stacked tab index to be the same as the combo box self.varStackedWidget.setCurrentIndex(0) #we rely on the stacked tab index to be the same as the combo box
#combo box #combo box
self.var_combo = QtGui.QComboBox() self.var_combo = QtWidgets.QComboBox()
self.var_combo.addItems(combo_vars) self.var_combo.addItems(combo_vars)
self.var_combo.setEditable(False) self.var_combo.setEditable(False)
self.var_combo.setCurrentIndex(0) self.var_combo.setCurrentIndex(0)
...@@ -90,20 +90,20 @@ class Ncml_tab(QtGui.QWidget): ...@@ -90,20 +90,20 @@ class Ncml_tab(QtGui.QWidget):
self.var_combo.currentIndexChanged.connect(lambda var_name = self.var : self.src_combo_changed(var_name)) self.var_combo.currentIndexChanged.connect(lambda var_name = self.var : self.src_combo_changed(var_name))
self.var_combo.currentIndexChanged.connect(self.setWidgetStack) self.var_combo.currentIndexChanged.connect(self.setWidgetStack)
#label #label
var_label = QtGui.QLabel(unicode('Variable').encode('utf-8')) var_label = QtWidgets.QLabel('Variable')
#set layout #set layout
stacked_hBox = QtGui.QHBoxLayout() stacked_hBox = QtWidgets.QHBoxLayout()
stacked_hBox.setMargin(5) stacked_hBox.setContentsMargins(5, 5, 5, 5)
stacked_hBox.setSpacing(50) # spacing between items stacked_hBox.setSpacing(50) # spacing between items
stacked_hBox.setAlignment(QtCore.Qt.AlignLeft) stacked_hBox.setAlignment(QtCore.Qt.AlignLeft)
stacked_hBox.addWidget(var_label) stacked_hBox.addWidget(var_label)
stacked_hBox.addWidget(self.var_combo) stacked_hBox.addWidget(self.var_combo)
# #
vBoxLayout = QtGui.QVBoxLayout() vBoxLayout = QtWidgets.QVBoxLayout()
vBoxLayout.addLayout(stacked_hBox) vBoxLayout.addLayout(stacked_hBox)
vBoxLayout.addWidget(self.varStackedWidget) vBoxLayout.addWidget(self.varStackedWidget)
# #
grp_box = QtGui.QGroupBox(None) grp_box = QtWidgets.QGroupBox(None)
grp_box.setLayout(vBoxLayout) grp_box.setLayout(vBoxLayout)
''' '''
...@@ -115,24 +115,24 @@ class Ncml_tab(QtGui.QWidget): ...@@ -115,24 +115,24 @@ class Ncml_tab(QtGui.QWidget):
button bar button bar
''' '''
# reset button # reset button
reset_btn = QtGui.QPushButton(unicode('Reset').encode('utf-8')) reset_btn = QtWidgets.QPushButton('Reset')
reset_btn.setToolTip(unicode('Reset fields to previously saved values').encode('utf-8')) reset_btn.setToolTip('Reset fields to previously saved values')
add_btn = QtGui.QPushButton(unicode('Add').encode('utf-8')) add_btn = QtWidgets.QPushButton('Add')
add_btn.setDefault(True) add_btn.setDefault(True)
add_btn.setToolTip(unicode('Add the current definition to the NcML').encode('utf-8')) add_btn.setToolTip('Add the current definition to the NcML')
#connect up with events #connect up with events
reset_btn.clicked.connect(self.reset_tab) reset_btn.clicked.connect(self.reset_tab)
add_btn.clicked.connect(self.add_tab) add_btn.clicked.connect(self.add_tab)
btn_hBox = QtGui.QHBoxLayout(None) btn_hBox = QtWidgets.QHBoxLayout(None)
btn_hBox.setMargin(5) btn_hBox.setContentsMargins(5, 5, 5, 5)
btn_hBox.setSpacing(10) btn_hBox.setSpacing(10)
btn_hBox.setAlignment(QtCore.Qt.AlignCenter) btn_hBox.setAlignment(QtCore.Qt.AlignCenter)
btn_hBox.addWidget(reset_btn) btn_hBox.addWidget(reset_btn)
btn_hBox.addWidget(add_btn) btn_hBox.addWidget(add_btn)
#build the contents #build the contents
vbox = QtGui.QVBoxLayout(self) vbox = QtWidgets.QVBoxLayout(self)
vbox.setSpacing(10) vbox.setSpacing(10)
vbox.setContentsMargins(10, 10, 5, 5) vbox.setContentsMargins(10, 10, 5, 5)
vbox.addWidget(grp_box) vbox.addWidget(grp_box)
...@@ -141,30 +141,30 @@ class Ncml_tab(QtGui.QWidget): ...@@ -141,30 +141,30 @@ class Ncml_tab(QtGui.QWidget):
create the stacked widget for each nemo variable create the stacked widget for each nemo variable
''' '''
def _addStackWidget(self, old_name=""): def _addStackWidget(self, old_name=""):
self.varWidget = QtGui.QWidget() self.varWidget = QtWidgets.QWidget()
#self.varWidget.setObjectName(objName) #self.varWidget.setObjectName(objName)
varLayout = QtGui.QGridLayout() varLayout = QtWidgets.QGridLayout()
varLayout.setSpacing(20) varLayout.setSpacing(20)
#labels #labels
src_label = QtGui.QLabel(unicode('Source directory*').encode('utf-8')) src_label = QtWidgets.QLabel('Source directory*')
cbox_label = QtGui.QLabel(unicode('Includes subdirs').encode('utf-8')) cbox_label = QtWidgets.QLabel('Includes subdirs')
regex_label = QtGui.QLabel(unicode('Regular expression').encode('utf-8')) regex_label = QtWidgets.QLabel('Regular expression')
old_name_label = QtGui.QLabel(unicode('Existing variable name*').encode('utf-8')) old_name_label = QtWidgets.QLabel('Existing variable name*')
#input textboxs #input textboxs
self.varWidget.src_tedit = QtGui.QLineEdit() # input widgets need to be attached to the stacked widget itself self.varWidget.src_tedit = QtWidgets.QLineEdit() # input widgets need to be attached to the stacked widget itself
self.varWidget.src_tedit.setToolTip(unicode('either remote OPeNDAP server or local file absolute path').encode('utf-8')) self.varWidget.src_tedit.setToolTip('either remote OPeNDAP server or local file absolute path')
self.varWidget.src_tedit.returnPressed.connect(self.src_tedit_edited) self.varWidget.src_tedit.returnPressed.connect(self.src_tedit_edited)
self.varWidget.cbox = QtGui.QCheckBox() self.varWidget.cbox = QtWidgets.QCheckBox()
self.varWidget.cbox.setCheckable(True) self.varWidget.cbox.setCheckable(True)
self.varWidget.cbox.setChecked(False) self.varWidget.cbox.setChecked(False)
self.varWidget.cbox.setToolTip(unicode('includes subdirectories').encode('utf-8')) self.varWidget.cbox.setToolTip('includes subdirectories')
self.varWidget.regex_tedit = QtGui.QLineEdit() self.varWidget.regex_tedit = QtWidgets.QLineEdit()
self.varWidget.regex_tedit.setToolTip(unicode('see http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/ncml/AnnotatedSchema4.html#regexp').encode('utf-8')) self.varWidget.regex_tedit.setToolTip('see http://www.unidata.ucar.edu/software/thredds/current/netcdf-java/ncml/AnnotatedSchema4.html#regexp')
self.varWidget.old_name_tedit = QtGui.QLineEdit() self.varWidget.old_name_tedit = QtWidgets.QLineEdit()
self.varWidget.old_name_tedit.setToolTip(unicode('variable name in data file').encode('utf-8')) self.varWidget.old_name_tedit.setToolTip('variable name in data file')
self.varWidget.old_name_tedit.setText(old_name) self.varWidget.old_name_tedit.setText(old_name)
varLayout.addWidget(src_label, 1, 0, 1, 1) varLayout.addWidget(src_label, 1, 0, 1, 1)
...@@ -201,10 +201,10 @@ class Ncml_tab(QtGui.QWidget): ...@@ -201,10 +201,10 @@ class Ncml_tab(QtGui.QWidget):
#validate the input now #validate the input now
if not str(src_tedit_input).startswith('http'): if not str(src_tedit_input).startswith('http'):
if not os.path.isabs(src_tedit_input): #assumes local file if not os.path.isabs(src_tedit_input): #assumes local file
QtGui.QMessageBox.critical(self, unicode('Something is wrong').encode('utf-8'), unicode('source directory must be an absolute path!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.critical(self, 'Something is wrong', 'source directory must be an absolute path!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
self.varStackedWidget.currentWidget().src_tedit.clear() self.varStackedWidget.currentWidget().src_tedit.clear()
if not os.path.exists(src_tedit_input) : if not os.path.exists(src_tedit_input) :
QtGui.QMessageBox.critical(self, unicode('Something is wrong').encode('utf-8'), unicode('source directory does not exist!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.critical(self, 'Something is wrong', 'source directory does not exist!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
self.varStackedWidget.currentWidget().src_tedit.clear() self.varStackedWidget.currentWidget().src_tedit.clear()
''' '''
reset button pushed callback. The widgets are reset to default values reset button pushed callback. The widgets are reset to default values
...@@ -213,34 +213,34 @@ class Ncml_tab(QtGui.QWidget): ...@@ -213,34 +213,34 @@ class Ncml_tab(QtGui.QWidget):
def reset_tab(self): def reset_tab(self):
#current screen value is not saved until the add button is pressed #current screen value is not saved until the add button is pressed
#reset only reset the screen values, not the cached values #reset only reset the screen values, not the cached values
if self.var_combo.currentText() == unicode("temperature").encode('utf-8'): if self.var_combo.currentText() == "temperature":
# print 'reset button is pushed, temperature ....' # print 'reset button is pushed, temperature ....'
self.resetValues(self.votemper) self.resetValues(self.votemper)
elif self.var_combo.currentText() == unicode("salinity").encode('utf-8'): elif self.var_combo.currentText() == "salinity":
self.resetValues(self.vosaline) self.resetValues(self.vosaline)
elif self.var_combo.currentText() == unicode("ice thickness").encode('utf-8'): elif self.var_combo.currentText() == "ice thickness":
self.resetValues(self.iicethic) self.resetValues(self.iicethic)
elif self.var_combo.currentText() == unicode("leads fraction").encode('utf-8'): elif self.var_combo.currentText() == "leads fraction":
self.resetValues(self.ileadfra) self.resetValues(self.ileadfra)
elif self.var_combo.currentText() == unicode("snow thickness").encode('utf-8'): elif self.var_combo.currentText() == "snow thickness":
self.resetValues(self.isnowthi) self.resetValues(self.isnowthi)
elif self.var_combo.currentText() == unicode("zonal velocity").encode('utf-8'): elif self.var_combo.currentText() == "zonal velocity":
self.resetValues(self.vozocrtx) self.resetValues(self.vozocrtx)
elif self.var_combo.currentText() == unicode("meridian velocity").encode('utf-8'): elif self.var_combo.currentText() == "meridian velocity":
self.resetValues(self.vomecrty) self.resetValues(self.vomecrty)
elif self.var_combo.currentText() == unicode("sea surface height").encode('utf-8'): elif self.var_combo.currentText() == "sea surface height":
self.resetValues(self.sossheig) self.resetValues(self.sossheig)
elif self.var_combo.currentText() == unicode("depth at T points").encode('utf-8'): elif self.var_combo.currentText() == "depth at T points":
self.resetValues(self.gdept) self.resetValues(self.gdept)
elif self.var_combo.currentText() == unicode("depth at W points").encode('utf-8'): elif self.var_combo.currentText() == "depth at W points":
self.resetValues(self.gdepw) self.resetValues(self.gdepw)
elif self.var_combo.currentText() == unicode("number of wet levels").encode('utf-8'): elif self.var_combo.currentText() == "number of wet levels":
self.resetValues(self.mbathy) self.resetValues(self.mbathy)
elif self.var_combo.currentText() == unicode("vertical scale factor at T points").encode('utf-8'): elif self.var_combo.currentText() == "vertical scale factor at T points":
self.resetValues(self.e3t) self.resetValues(self.e3t)
elif self.var_combo.currentText() == unicode("vertical scale factor at U points").encode('utf-8'): elif self.var_combo.currentText() == "vertical scale factor at U points":
self.resetValues(self.e3u) self.resetValues(self.e3u)
elif self.var_combo.currentText() == unicode("vertical scale factor at V points").encode('utf-8'): elif self.var_combo.currentText() == "vertical scale factor at V points":
self.resetValues(self.e3v) self.resetValues(self.e3v)
''' '''
...@@ -270,7 +270,7 @@ class Ncml_tab(QtGui.QWidget): ...@@ -270,7 +270,7 @@ class Ncml_tab(QtGui.QWidget):
#first validate the src tab is not null #first validate the src tab is not null
if(self.varStackedWidget.currentWidget().src_tedit.text() is None or self.varStackedWidget.currentWidget().src_tedit.text() == '' or if(self.varStackedWidget.currentWidget().src_tedit.text() is None or self.varStackedWidget.currentWidget().src_tedit.text() == '' or
self.varStackedWidget.currentWidget().old_name_tedit.text() is None or self.varStackedWidget.currentWidget().old_name_tedit.text() == ''): self.varStackedWidget.currentWidget().old_name_tedit.text() is None or self.varStackedWidget.currentWidget().old_name_tedit.text() == ''):
QtGui.QMessageBox.critical(self, unicode('Something is wrong').encode('utf-8'), unicode('source directory and existing variable name cannot be blank!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.critical(self, 'Something is wrong', 'source directory and existing variable name cannot be blank!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
''' '''
if not str(target).startsWith(unicode('http').encode('utf-8')): if not str(target).startsWith(unicode('http').encode('utf-8')):
...@@ -283,10 +283,10 @@ class Ncml_tab(QtGui.QWidget): ...@@ -283,10 +283,10 @@ class Ncml_tab(QtGui.QWidget):
# be in the same directory. # be in the same directory.
if(self.var == unicode("Tracer").encode('utf-8')): if(self.var == "Tracer"):
if (self.var_combo.currentText() == unicode("temperature").encode('utf-8')): if (self.var_combo.currentText() == "temperature"):
if(self._sameValues(self.votemper)): if(self._sameValues(self.votemper)):
QtGui.QMessageBox.information(self, 'For information', 'No changes have been made!', QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.votemper.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.votemper.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.votemper.old_name = self.varStackedWidget.currentWidget().old_name_tedit.text() self.votemper.old_name = self.varStackedWidget.currentWidget().old_name_tedit.text()
...@@ -297,7 +297,7 @@ class Ncml_tab(QtGui.QWidget): ...@@ -297,7 +297,7 @@ class Ncml_tab(QtGui.QWidget):
self.votemper.regex = '' #blank it over self.votemper.regex = '' #blank it over
else: # can only be salinity else: # can only be salinity
if(self._sameValues(self.vosaline)): if(self._sameValues(self.vosaline)):
QtGui.QMessageBox.information(self, 'For information', 'No changes have been made!', QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.vosaline.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.vosaline.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.vosaline.old_name = self.varStackedWidget.currentWidget().old_name_tedit.text() self.vosaline.old_name = self.varStackedWidget.currentWidget().old_name_tedit.text()
...@@ -312,10 +312,10 @@ class Ncml_tab(QtGui.QWidget): ...@@ -312,10 +312,10 @@ class Ncml_tab(QtGui.QWidget):
if self.vosaline.src == '': if self.vosaline.src == '':
self.vosaline.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.vosaline.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.varStackedWidget.widget(1).src_tedit.setText(self.varStackedWidget.currentWidget().src_tedit.text()) self.varStackedWidget.widget(1).src_tedit.setText(self.varStackedWidget.currentWidget().src_tedit.text())
elif(self.var == unicode('Ice').encode('utf-8')): #iicethic,ileadfra,isnowthi elif(self.var == 'Ice'): #iicethic,ileadfra,isnowthi
if (self.var_combo.currentText() == unicode("ice thickness").encode('utf-8')): if (self.var_combo.currentText() == "ice thickness"):
if(self._sameValues(self.iicethic)): if(self._sameValues(self.iicethic)):
QtGui.QMessageBox.information(self, 'For information', 'No changes have been made!', QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.iicethic.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.iicethic.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.iicethic.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.iicethic.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -324,9 +324,9 @@ class Ncml_tab(QtGui.QWidget): ...@@ -324,9 +324,9 @@ class Ncml_tab(QtGui.QWidget):
self.iicethic.regex = self.varStackedWidget.currentWidget().regex_tedit.text() self.iicethic.regex = self.varStackedWidget.currentWidget().regex_tedit.text()
else: else:
self.iicethic.regex = '' self.iicethic.regex = ''
elif(self.var_combo.currentText() == unicode("leads fraction").encode('utf-8')): elif(self.var_combo.currentText() == "leads fraction"):
if(self._sameValues(self.ileadfra)): if(self._sameValues(self.ileadfra)):
QtGui.QMessageBox.information(self, unicode('For information').encode('utf-8'), unicode('No changes have been made!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.ileadfra.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.ileadfra.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.ileadfra.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.ileadfra.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -337,7 +337,7 @@ class Ncml_tab(QtGui.QWidget): ...@@ -337,7 +337,7 @@ class Ncml_tab(QtGui.QWidget):
self.ileadfra.regex = '' self.ileadfra.regex = ''
else: else:
if(self._sameValues(self.isnowthi)): #snow thickness if(self._sameValues(self.isnowthi)): #snow thickness
QtGui.QMessageBox.information(self, unicode('For information').encode('utf-8'), unicode('No changes have been made!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.isnowthi.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.isnowthi.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.isnowthi.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.isnowthi.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -355,10 +355,10 @@ class Ncml_tab(QtGui.QWidget): ...@@ -355,10 +355,10 @@ class Ncml_tab(QtGui.QWidget):
if self.isnowthi.src == '': if self.isnowthi.src == '':
self.isnowthi.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.isnowthi.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.varStackedWidget.widget(2).src_tedit.setText(self.varStackedWidget.currentWidget().src_tedit.text()) self.varStackedWidget.widget(2).src_tedit.setText(self.varStackedWidget.currentWidget().src_tedit.text())
elif(self.var == unicode("Dynamics").encode('utf-8')): elif(self.var == "Dynamics"):
if (self.var_combo.currentText() == unicode("zonal velocity").encode('utf-8')): if (self.var_combo.currentText() == "zonal velocity"):
if(self._sameValues(self.vozocrtx)): if(self._sameValues(self.vozocrtx)):
QtGui.QMessageBox.information(self, unicode('For information').encode('utf-8'), unicode('No changes have been made!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.vozocrtx.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.vozocrtx.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.vozocrtx.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.vozocrtx.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -367,9 +367,9 @@ class Ncml_tab(QtGui.QWidget): ...@@ -367,9 +367,9 @@ class Ncml_tab(QtGui.QWidget):
self.vozocrtx.regex = self.varStackedWidget.currentWidget().regex_tedit.text() self.vozocrtx.regex = self.varStackedWidget.currentWidget().regex_tedit.text()
else: else:
self.vozocrtx.regex = '' self.vozocrtx.regex = ''
elif(self.var_combo.currentText() == unicode('meridian velocity').encode('utf-8')): elif(self.var_combo.currentText() == 'meridian velocity'):
if(self._sameValues(self.vomecrty)): if(self._sameValues(self.vomecrty)):
QtGui.QMessageBox.information(self, 'For information', 'No changes have been made!', QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.vomecrty.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.vomecrty.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.vomecrty.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.vomecrty.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -378,9 +378,9 @@ class Ncml_tab(QtGui.QWidget): ...@@ -378,9 +378,9 @@ class Ncml_tab(QtGui.QWidget):
self.vomecrty.regex = self.varStackedWidget.currentWidget().regex_tedit.text() self.vomecrty.regex = self.varStackedWidget.currentWidget().regex_tedit.text()
else: else:
self.vomecrty.regex = '' self.vomecrty.regex = ''
elif(self.var_combo.currentText() == unicode('sea surface height').encode('utf-8')): elif(self.var_combo.currentText() == 'sea surface height'):
if(self._sameValues(self.sossheig)): #sea surface height if(self._sameValues(self.sossheig)): #sea surface height
QtGui.QMessageBox.information(self, unicode('For information').encode('utf-8'), unicode('No changes have been made!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.sossheig.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.sossheig.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.sossheig.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.sossheig.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -398,10 +398,10 @@ class Ncml_tab(QtGui.QWidget): ...@@ -398,10 +398,10 @@ class Ncml_tab(QtGui.QWidget):
if self.sossheig.src == '': if self.sossheig.src == '':
self.sossheig.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.sossheig.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.varStackedWidget.widget(2).src_tedit.setText(self.varStackedWidget.currentWidget().src_tedit.text()) self.varStackedWidget.widget(2).src_tedit.setText(self.varStackedWidget.currentWidget().src_tedit.text())
elif(self.var == unicode("Grid").encode('utf-8')): elif(self.var == "Grid"):
if (self.var_combo.currentText() == unicode("depth at T points").encode('utf-8')): if (self.var_combo.currentText() == "depth at T points"):
if(self._sameValues(self.gdept)): if(self._sameValues(self.gdept)):
QtGui.QMessageBox.information(self, unicode('For information').encode('utf-8'), unicode('No changes have been made!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.gdept.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.gdept.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.gdept.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.gdept.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -410,9 +410,9 @@ class Ncml_tab(QtGui.QWidget): ...@@ -410,9 +410,9 @@ class Ncml_tab(QtGui.QWidget):
self.gdept.regex = self.varStackedWidget.currentWidget().regex_tedit.text() self.gdept.regex = self.varStackedWidget.currentWidget().regex_tedit.text()
else: else:
self.gdept.regex = '' self.gdept.regex = ''
elif(self.var_combo.currentText() == unicode('depth at W points').encode('utf-8')): elif(self.var_combo.currentText() == 'depth at W points'):
if(self._sameValues(self.gdepw)): if(self._sameValues(self.gdepw)):
QtGui.QMessageBox.information(self, 'For information', 'No changes have been made!', QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.gdepw.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.gdepw.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.gdepw.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.gdepw.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -421,9 +421,9 @@ class Ncml_tab(QtGui.QWidget): ...@@ -421,9 +421,9 @@ class Ncml_tab(QtGui.QWidget):
self.gdepw.regex = self.varStackedWidget.currentWidget().regex_tedit.text() self.gdepw.regex = self.varStackedWidget.currentWidget().regex_tedit.text()
else: else:
self.gdepw.regex = '' self.gdepw.regex = ''
elif(self.var_combo.currentText() == unicode('number of wet levels').encode('utf-8')): elif(self.var_combo.currentText() == 'number of wet levels'):
if(self._sameValues(self.mbathy)): #sea surface height if(self._sameValues(self.mbathy)): #sea surface height
QtGui.QMessageBox.information(self, unicode('For information').encode('utf-8'), unicode('No changes have been made!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.mbathy.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.mbathy.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.mbathy.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.mbathy.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -432,9 +432,9 @@ class Ncml_tab(QtGui.QWidget): ...@@ -432,9 +432,9 @@ class Ncml_tab(QtGui.QWidget):
self.mbathy.regex = self.varStackedWidget.currentWidget().regex_tedit.text() self.mbathy.regex = self.varStackedWidget.currentWidget().regex_tedit.text()
else: else:
self.mbathy.regex = '' self.mbathy.regex = ''
elif(self.var_combo.currentText() == unicode('vertical scale factor at T points').encode('utf-8')): elif(self.var_combo.currentText() == 'vertical scale factor at T points'):
if(self._sameValues(self.e3t)): #sea surface height if(self._sameValues(self.e3t)): #sea surface height
QtGui.QMessageBox.information(self, unicode('For information').encode('utf-8'), unicode('No changes have been made!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.e3t.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.e3t.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.e3t.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.e3t.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -443,9 +443,9 @@ class Ncml_tab(QtGui.QWidget): ...@@ -443,9 +443,9 @@ class Ncml_tab(QtGui.QWidget):
self.e3t.regex = self.varStackedWidget.currentWidget().regex_tedit.text() self.e3t.regex = self.varStackedWidget.currentWidget().regex_tedit.text()
else: else:
self.e3t.regex = '' self.e3t.regex = ''
elif(self.var_combo.currentText() == unicode('vertical scale factor at U points').encode('utf-8')): elif(self.var_combo.currentText() == 'vertical scale factor at U points'):
if(self._sameValues(self.e3u)): #sea surface height if(self._sameValues(self.e3u)): #sea surface height
QtGui.QMessageBox.information(self, unicode('For information').encode('utf-8'), unicode('No changes have been made!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.e3u.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.e3u.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.e3u.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.e3u.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -454,9 +454,9 @@ class Ncml_tab(QtGui.QWidget): ...@@ -454,9 +454,9 @@ class Ncml_tab(QtGui.QWidget):
self.e3u.regex = self.varStackedWidget.currentWidget().regex_tedit.text() self.e3u.regex = self.varStackedWidget.currentWidget().regex_tedit.text()
else: else:
self.e3u.regex = '' self.e3u.regex = ''
elif(self.var_combo.currentText() == unicode('vertical scale factor at V points').encode('utf-8')): elif(self.var_combo.currentText() == 'vertical scale factor at V points'):
if(self._sameValues(self.e3v)): #sea surface height if(self._sameValues(self.e3v)): #sea surface height
QtGui.QMessageBox.information(self, unicode('For information').encode('utf-8'), unicode('No changes have been made!').encode('utf-8'), QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) QtWidgets.QMessageBox.information(self, 'For information', 'No changes have been made!', QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
else: else:
self.e3v.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text()) self.e3v.src = self._convertSrc(self.varStackedWidget.currentWidget().src_tedit.text())
self.e3v.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked() self.e3v.subdirs = self.varStackedWidget.currentWidget().cbox.isChecked()
...@@ -497,10 +497,10 @@ class Ncml_tab(QtGui.QWidget): ...@@ -497,10 +497,10 @@ class Ncml_tab(QtGui.QWidget):
elif fpath.startswith('file:/'): elif fpath.startswith('file:/'):
temp = os.path.normpath(fpath[6:]) temp = os.path.normpath(fpath[6:])
# print 'normal path : ', temp # print 'normal path : ', temp
target = unicode('file:/' + str(os.path.abspath(temp)).replace("\\", "/")).encode('utf-8') target = str('file:/' + str(os.path.abspath(temp)).replace("\\", "/")).encode('utf-8')
else: #should be local file but not prefixed by file:/ we still check for absolute path else: #should be local file but not prefixed by file:/ we still check for absolute path
# print 'normal path : ', os.path.normpath(fpath) # print 'normal path : ', os.path.normpath(fpath)
target = unicode('file:/' + str(os.path.abspath(fpath)).replace("\\", "/")).encode('utf-8') target = str('file:/' + str(os.path.abspath(fpath)).replace("\\", "/")).encode('utf-8')
# if not str(target).endswith('/'): # if not str(target).endswith('/'):
# target = target + '/' # target = target + '/'
......
...@@ -9,7 +9,7 @@ import numpy as np ...@@ -9,7 +9,7 @@ import numpy as np
from matplotlib.lines import Line2D from matplotlib.lines import Line2D
from matplotlib.patches import Polygon from matplotlib.patches import Polygon
from matplotlib.artist import Artist from matplotlib.artist import Artist
from matplotlib.mlab import dist_point_to_segment from pynemo.utils.nemo_bdy_lib import dist_point_to_segment
from matplotlib.widgets import RectangleSelector from matplotlib.widgets import RectangleSelector
...@@ -58,12 +58,12 @@ class PolygonEditor(object): ...@@ -58,12 +58,12 @@ class PolygonEditor(object):
self.reset_line() self.reset_line()
self.reset_polygon() self.reset_polygon()
elif self.xy_values.shape[0] <= 2: # point or line for 1 or 2 points elif self.xy_values.shape[0] <= 2: # point or line for 1 or 2 points
xval, yval = zip(*self.xy_values) xval, yval = list(zip(*self.xy_values))
if self.line == None: if self.line == None:
self.line = Line2D(xval, yval, marker='o', markerfacecolor='r', animated=True) self.line = Line2D(xval, yval, marker='o', markerfacecolor='r', animated=True)
self.axis.add_line(self.line) self.axis.add_line(self.line)
else: else:
self.line.set_data(zip(*self.xy_values)) self.line.set_data(list(zip(*self.xy_values)))
self.reset_polygon() self.reset_polygon()
else: # more than 2 points if polygon is not created then creates one and draws else: # more than 2 points if polygon is not created then creates one and draws
if self.polygon == None: if self.polygon == None:
...@@ -72,7 +72,7 @@ class PolygonEditor(object): ...@@ -72,7 +72,7 @@ class PolygonEditor(object):
self.axis.add_patch(self.polygon) self.axis.add_patch(self.polygon)
else: else:
self.polygon.xy = self.xy_values self.polygon.xy = self.xy_values
self.line.set_data(zip(*self.xy_values)) self.line.set_data(list(zip(*self.xy_values)))
self.draw_callback(None) self.draw_callback(None)
self.canvas.draw() self.canvas.draw()
......
...@@ -38,12 +38,12 @@ import numpy as np ...@@ -38,12 +38,12 @@ import numpy as np
import scipy.spatial as sp import scipy.spatial as sp
from calendar import monthrange, isleap from calendar import monthrange, isleap
from scipy.interpolate import interp1d from scipy.interpolate import interp1d
from netcdftime import datetime, utime from cftime import datetime, utime
from pynemo import nemo_bdy_ncgen as ncgen from pynemo import nemo_bdy_ncgen as ncgen
from pynemo import nemo_bdy_ncpop as ncpop from pynemo import nemo_bdy_ncpop as ncpop
# Local Imports # Local Imports
import nemo_bdy_grid_angle as ga from . import nemo_bdy_grid_angle as ga
from pynemo.reader.factory import GetFile from pynemo.reader.factory import GetFile
from pynemo.utils.nemo_bdy_lib import rot_rep, sub2ind from pynemo.utils.nemo_bdy_lib import rot_rep, sub2ind
...@@ -233,12 +233,12 @@ class Extract: ...@@ -233,12 +233,12 @@ class Extract:
# Ann Query substitute # Ann Query substitute
source_tree = None source_tree = None
try: try:
source_tree = sp.cKDTree(zip(SC.lon.ravel(order='F'), source_tree = sp.cKDTree(list(zip(SC.lon.ravel(order='F'),
SC.lat.ravel(order='F')), balanced_tree=False,compact_nodes=False) SC.lat.ravel(order='F'))), balanced_tree=False,compact_nodes=False)
except TypeError: #added this fix to make it compatible with scipy 0.16.0 except TypeError: #added this fix to make it compatible with scipy 0.16.0
source_tree = sp.cKDTree(zip(SC.lon.ravel(order='F'), source_tree = sp.cKDTree(list(zip(SC.lon.ravel(order='F'),
SC.lat.ravel(order='F'))) SC.lat.ravel(order='F'))))
dst_pts = zip(dst_lon[:].ravel(order='F'), dst_lat[:].ravel(order='F')) dst_pts = list(zip(dst_lon[:].ravel(order='F'), dst_lat[:].ravel(order='F')))
nn_dist, nn_id = source_tree.query(dst_pts, k=1) nn_dist, nn_id = source_tree.query(dst_pts, k=1)
# Find surrounding points # Find surrounding points
...@@ -280,8 +280,8 @@ class Extract: ...@@ -280,8 +280,8 @@ class Extract:
ind[p, :] = ind[p, dist_ind[p, :]] ind[p, :] = ind[p, dist_ind[p, :]]
if self.key_vec: if self.key_vec:
self.gcos = self.gcos.flatten(1)[ind].reshape(ind.shape, order='F') self.gcos = self.gcos.flatten('F')[ind].reshape(ind.shape, order='F')
self.gsin = self.gsin.flatten(1)[ind].reshape(ind.shape, order='F') self.gsin = self.gsin.flatten('F')[ind].reshape(ind.shape, order='F')
sc_ind = {} sc_ind = {}
sc_ind['ind'] = ind sc_ind['ind'] = ind
...@@ -301,14 +301,14 @@ class Extract: ...@@ -301,14 +301,14 @@ class Extract:
tmp_lat[r_id] = -9999 tmp_lat[r_id] = -9999
source_tree = None source_tree = None
try: try:
source_tree = sp.cKDTree(zip(tmp_lon.ravel(order='F'), source_tree = sp.cKDTree(list(zip(tmp_lon.ravel(order='F'),
tmp_lat.ravel(order='F')), balanced_tree=False,compact_nodes=False) tmp_lat.ravel(order='F'))), balanced_tree=False,compact_nodes=False)
except TypeError: #fix for scipy 0.16.0 except TypeError: #fix for scipy 0.16.0
source_tree = sp.cKDTree(zip(tmp_lon.ravel(order='F'), source_tree = sp.cKDTree(list(zip(tmp_lon.ravel(order='F'),
tmp_lat.ravel(order='F'))) tmp_lat.ravel(order='F'))))
dst_pts = zip(dst_lon[rr_id].ravel(order='F'), dst_pts = list(zip(dst_lon[rr_id].ravel(order='F'),
dst_lat[rr_id].ravel(order='F')) dst_lat[rr_id].ravel(order='F')))
junk, an_id = source_tree.query(dst_pts, k=3, junk, an_id = source_tree.query(dst_pts, k=3,
distance_upper_bound=fr) distance_upper_bound=fr)
id_121[rr_id, :] = an_id id_121[rr_id, :] = an_id
...@@ -347,11 +347,11 @@ class Extract: ...@@ -347,11 +347,11 @@ class Extract:
z_ind = np.zeros((num_bdy * dst_len_z, 2), dtype=np.int64) z_ind = np.zeros((num_bdy * dst_len_z, 2), dtype=np.int64)
source_tree = None source_tree = None
try: try:
source_tree = sp.cKDTree(zip(sc_z.ravel(order='F')), balanced_tree=False,compact_nodes=False) source_tree = sp.cKDTree(list(zip(sc_z.ravel(order='F'))), balanced_tree=False,compact_nodes=False)
except TypeError: #fix for scipy 0.16.0 except TypeError: #fix for scipy 0.16.0
source_tree = sp.cKDTree(zip(sc_z.ravel(order='F'))) source_tree = sp.cKDTree(list(zip(sc_z.ravel(order='F'))))
junk, nn_id = source_tree.query(zip(dst_dep_rv), k=1) junk, nn_id = source_tree.query(list(zip(dst_dep_rv)), k=1)
# WORKAROUND: the tree query returns out of range val when # WORKAROUND: the tree query returns out of range val when
# dst_dep point is NaN, causing ref problems later. # dst_dep point is NaN, causing ref problems later.
...@@ -453,7 +453,7 @@ class Extract: ...@@ -453,7 +453,7 @@ class Extract:
# Get first and last date within range, init to cover entire range # Get first and last date within range, init to cover entire range
first_date = 0 first_date = 0
last_date = len(sc_time.time_counter) - 1 last_date = len(sc_time.time_counter) - 1
rev_seq = range(len(sc_time.time_counter)) rev_seq = list(range(len(sc_time.time_counter)))
rev_seq.reverse() rev_seq.reverse()
for date in rev_seq: for date in rev_seq:
if src_date_seconds[date] < dst_start: if src_date_seconds[date] < dst_start:
...@@ -571,11 +571,11 @@ class Extract: ...@@ -571,11 +571,11 @@ class Extract:
for dep in range(sc_z_len): for dep in range(sc_z_len):
tmp_arr = [None, None] tmp_arr = [None, None]
# Consider squeezing # Consider squeezing
tmp_arr[0] = sc_array[0][0,dep,:,:].flatten(1) #[:,:,dep] tmp_arr[0] = sc_array[0][0,dep,:,:].flatten('F') #[:,:,dep]
if not self.key_vec: if not self.key_vec:
sc_bdy[vn, dep, :, :] = self._flat_ref(tmp_arr[0], ind) sc_bdy[vn, dep, :, :] = self._flat_ref(tmp_arr[0], ind)
else: else:
tmp_arr[1] = sc_array[1][0,dep,:,:].flatten(1) #[:,:,dep] tmp_arr[1] = sc_array[1][0,dep,:,:].flatten('F') #[:,:,dep]
# Include in the collapse the rotation from the # Include in the collapse the rotation from the
# grid to real zonal direction, ie ij -> e # grid to real zonal direction, ie ij -> e
sc_bdy[vn, dep, :] = (tmp_arr[0][ind[:]] * self.gcos - sc_bdy[vn, dep, :] = (tmp_arr[0][ind[:]] * self.gcos -
...@@ -669,11 +669,11 @@ class Extract: ...@@ -669,11 +669,11 @@ class Extract:
# Apply 1-2-1 filter along bdy pts using NN ind self.id_121 # Apply 1-2-1 filter along bdy pts using NN ind self.id_121
if self.first: if self.first:
tmp_valid = np.invert(np.isnan( tmp_valid = np.invert(np.isnan(
dst_bdy.flatten(1)[self.id_121])) dst_bdy.flatten('F')[self.id_121]))
# Finished first run operations # Finished first run operations
self.first = False self.first = False
dst_bdy = (np.nansum(dst_bdy.flatten(1)[self.id_121] * dst_bdy = (np.nansum(dst_bdy.flatten('F')[self.id_121] *
self.tmp_filt, 2) / np.sum(self.tmp_filt * self.tmp_filt, 2) / np.sum(self.tmp_filt *
tmp_valid, 2)) tmp_valid, 2))
# Set land pts to zero # Set land pts to zero
...@@ -688,7 +688,7 @@ class Extract: ...@@ -688,7 +688,7 @@ class Extract:
# If we have depth dimension # If we have depth dimension
if not self.isslab: if not self.isslab:
# If all else fails fill down using deepest pt # If all else fails fill down using deepest pt
dst_bdy = dst_bdy.flatten(1) dst_bdy = dst_bdy.flatten('F')
dst_bdy += ((dst_bdy == 0) * dst_bdy += ((dst_bdy == 0) *
dst_bdy[data_ind].repeat(sc_z_len)) dst_bdy[data_ind].repeat(sc_z_len))
# Weighted averaged on new vertical grid # Weighted averaged on new vertical grid
...@@ -732,7 +732,7 @@ class Extract: ...@@ -732,7 +732,7 @@ class Extract:
alpha -- input array alpha -- input array
beta -- index array beta -- index array
""" """
return alpha.flatten(1)[beta.flatten(1)].reshape( return alpha.flatten('F')[beta.flatten('F')].reshape(
beta.shape, order='F') beta.shape, order='F')
# Convert numeric date from source to dest # Convert numeric date from source to dest
...@@ -752,7 +752,7 @@ class Extract: ...@@ -752,7 +752,7 @@ class Extract:
""" """
vals = {'gregorian': 365. + isleap(year), 'noleap': vals = {'gregorian': 365. + isleap(year), 'noleap':
365., '360_day': 360.} 365., '360_day': 360.}
if source not in vals.keys(): if source not in list(vals.keys()):
raise ValueError('Unknown source calendar type: %s' %source) raise ValueError('Unknown source calendar type: %s' %source)
# Get month length # Get month length
if dest == '360_day': if dest == '360_day':
......
...@@ -13,7 +13,7 @@ import numpy as np ...@@ -13,7 +13,7 @@ import numpy as np
import logging import logging
#Local Imports #Local Imports
from utils.nemo_bdy_lib import sub2ind from .utils.nemo_bdy_lib import sub2ind
class Boundary: class Boundary:
# Bearings for overlays # Bearings for overlays
...@@ -102,8 +102,8 @@ class Boundary: ...@@ -102,8 +102,8 @@ class Boundary:
bdy_i = np.transpose(bdy_i, (1, 2, 0)) bdy_i = np.transpose(bdy_i, (1, 2, 0))
bdy_i = np.reshape(bdy_i, bdy_i = np.reshape(bdy_i,
(bdy_i.shape[0],bdy_i.shape[1]*bdy_i.shape[2])) (bdy_i.shape[0],bdy_i.shape[1]*bdy_i.shape[2]))
bdy_r = bdy_r.flatten(1) bdy_r = bdy_r.flatten('F')
## Remove duplicate and open sea points ## ## Remove duplicate and open sea points ##
bdy_i, bdy_r = self._remove_duplicate_points(bdy_i, bdy_r) bdy_i, bdy_r = self._remove_duplicate_points(bdy_i, bdy_r)
...@@ -210,11 +210,11 @@ class Boundary: ...@@ -210,11 +210,11 @@ class Boundary:
t -- input 2D array t -- input 2D array
""" """
sh = np.shape(t) sh = np.shape(t)
if (len(sh)> 2) or (sh[0] ==0) or (sh[1] == 0): if (len(sh)> 2) or (sh[0] ==0) or (sh[1] == 0):
print 'Warning: Shape of expected 2D array:', sh print('Warning: Shape of expected 2D array:', sh)
tlist = t.tolist() tlist = t.tolist()
sortt = [] sortt = []
indx = zip(*sorted([(val, i) for i,val in enumerate(tlist)]))[1] indx = list(zip(*sorted([(val, i) for i,val in enumerate(tlist)])))[1]
indx = np.array(indx) indx = np.array(indx)
for i in indx: for i in indx:
sortt.append(tlist[i]) sortt.append(tlist[i])
...@@ -224,7 +224,7 @@ class Boundary: ...@@ -224,7 +224,7 @@ class Boundary:
indx[i] = -1 indx[i] = -1
# all the rows are identical, set the first as the unique row # all the rows are identical, set the first as the unique row
if sortt[0] == sortt[-1]: if sortt[0] == sortt[-1]:
indx[0] = 0 indx[0] = 0
return indx[indx != -1] return indx[indx != -1]
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
# cd_type: define the nature of pt2d grid points # cd_type: define the nature of pt2d grid points
import numpy as np import numpy as np
from reader.factory import GetFile from .reader.factory import GetFile
import logging import logging
# pylint: disable=E1101 # pylint: disable=E1101
......
...@@ -23,13 +23,13 @@ def write_data_to_file(filename, variable_name, data): ...@@ -23,13 +23,13 @@ def write_data_to_file(filename, variable_name, data):
if variable_name in three_dim_variables: if variable_name in three_dim_variables:
if len(count) == 3: if len(count) == 3:
count += (1L, ) count += (1, )
ncid.variables[variable_name][:, :, :, :] = np.reshape(data, count)[:, :, :, :] ncid.variables[variable_name][:, :, :, :] = np.reshape(data, count)[:, :, :, :]
elif variable_name in two_dim_variables: elif variable_name in two_dim_variables:
if len(count) == 2: if len(count) == 2:
count += (1L, ) count += (1, )
elif len(count) == 1: elif len(count) == 1:
count += (1L, 1L, ) count += (1, 1, )
ncid.variables[variable_name][:, :, :] = np.reshape(data, count)[:, :, :] ncid.variables[variable_name][:, :, :] = np.reshape(data, count)[:, :, :]
elif variable_name == 'time_counter': elif variable_name == 'time_counter':
ncid.variables[variable_name][:] = data[:] ncid.variables[variable_name][:] = data[:]
......
...@@ -204,11 +204,11 @@ def _get_val(vars_dictionary, bool_vars_dictionary, line): ...@@ -204,11 +204,11 @@ def _get_val(vars_dictionary, bool_vars_dictionary, line):
if name_prefix == 'ln': if name_prefix == 'ln':
if value.find('true') is not -1: if value.find('true') is not -1:
if vars_dictionary.has_key(name) != True: if (name in vars_dictionary) != True:
vars_dictionary[name] = True vars_dictionary[name] = True
bool_vars_dictionary[name] = True bool_vars_dictionary[name] = True
elif value.find('false') is not -1: elif value.find('false') is not -1:
if vars_dictionary.has_key(name) != True: if (name in vars_dictionary) != True:
vars_dictionary[name] = False vars_dictionary[name] = False
bool_vars_dictionary[name] = False bool_vars_dictionary[name] = False
else: else:
......
...@@ -29,7 +29,7 @@ class SourceTime: ...@@ -29,7 +29,7 @@ class SourceTime:
dir_list.sort() dir_list.sort()
return filter(None, dir_list) return [_f for _f in dir_list if _f]
# Returns list of dicts of date/time info # Returns list of dicts of date/time info
# I assume there is only one date per file # I assume there is only one date per file
......
...@@ -14,12 +14,12 @@ Initialise with bdy t, u and v grid attributes (Grid.bdy_i) ...@@ -14,12 +14,12 @@ Initialise with bdy t, u and v grid attributes (Grid.bdy_i)
and settings dictionary and settings dictionary
""" """
from reader.factory import GetFile from .reader.factory import GetFile
import numpy as np import numpy as np
import logging import logging
from utils.nemo_bdy_lib import sub2ind from .utils.nemo_bdy_lib import sub2ind
from utils.e3_to_depth import e3_to_depth from .utils.e3_to_depth import e3_to_depth
# pylint: disable=E1101 # pylint: disable=E1101
# Query name # Query name
class Depth: class Depth:
...@@ -52,6 +52,7 @@ class Depth: ...@@ -52,6 +52,7 @@ class Depth:
# Check inputs # Check inputs
# FIX ME? Errors for wrong obj arg len. probably better to work around # FIX ME? Errors for wrong obj arg len. probably better to work around
print(settings)
if settings['sco']: if settings['sco']:
# hc = ... FIX ME?? # hc = ... FIX ME??
# Depth of water column at t-point # Depth of water column at t-point
...@@ -68,7 +69,7 @@ class Depth: ...@@ -68,7 +69,7 @@ class Depth:
v_ind = sub2ind(mbathy.shape, bdy_v[:,0], bdy_v[:,1]) v_ind = sub2ind(mbathy.shape, bdy_v[:,0], bdy_v[:,1])
v_ind2 = sub2ind(mbathy.shape, bdy_v[:,0], bdy_v[:,1] + 1) v_ind2 = sub2ind(mbathy.shape, bdy_v[:,0], bdy_v[:,1] + 1)
[tmp_zt, tmp_zw] = e3_to_depth(np.squeeze(nc['e3t'][:,:,:,:]), np.squeeze(nc['e3w'][:,:,:,:]), nz) [tmp_zt, tmp_zw] = e3_to_depth(np.squeeze(nc['e3t'][:,:,:,:]), np.squeeze(nc['e3w'][:,:,:,:]), nz)
# This is very slow # This is very slow
self.logger.debug( 'starting nc reads loop' ) self.logger.debug( 'starting nc reads loop' )
for k in range(nz): for k in range(nz):
...@@ -95,12 +96,12 @@ class Depth: ...@@ -95,12 +96,12 @@ class Depth:
# Set u and v grid point depths # Set u and v grid point depths
zshapes = {} zshapes = {}
for p in self.zpoints.keys(): for p in list(self.zpoints.keys()):
zshapes[p] = self.zpoints[p].shape zshapes[p] = self.zpoints[p].shape
wshapes = [] wshapes = []
wshapes.append(wrk1.shape) wshapes.append(wrk1.shape)
wshapes.append(wrk2.shape) wshapes.append(wrk2.shape)
wrk1, wrk2 = wrk1.flatten(1), wrk2.flatten(1) wrk1, wrk2 = wrk1.flatten('F'), wrk2.flatten('F')
self.zpoints['t'][k,:] = wrk1[t_ind] self.zpoints['t'][k,:] = wrk1[t_ind]
self.zpoints['wt'][k,:] = wrk2[t_ind] self.zpoints['wt'][k,:] = wrk2[t_ind]
...@@ -111,7 +112,7 @@ class Depth: ...@@ -111,7 +112,7 @@ class Depth:
self.zpoints['v'][k,:] = 0.5 * (wrk1[v_ind] + wrk1[v_ind2]) self.zpoints['v'][k,:] = 0.5 * (wrk1[v_ind] + wrk1[v_ind2])
self.zpoints['wv'][k,:] = 0.5 * (wrk2[v_ind] + wrk2[v_ind2]) self.zpoints['wv'][k,:] = 0.5 * (wrk2[v_ind] + wrk2[v_ind2])
for p in self.zpoints.keys(): for p in list(self.zpoints.keys()):
self.zpoints[p] = self.zpoints[p].reshape(zshapes[p]) self.zpoints[p] = self.zpoints[p].reshape(zshapes[p])
self.logger.debug( 'Done loop, zpoints: %s ', self.zpoints['t'].shape) self.logger.debug( 'Done loop, zpoints: %s ', self.zpoints['t'].shape)
......
#
# The loop from nemo_bdy_extr_tm3
#
#
#
from calendar import monthrange
from datetime import datetime
from netCDF4 import Dataset, netcdftime
class Enter:
def __init__(self, settings, sc_time, dir_list, dst_cal_type, year, month):
var_nam = ['votemper', 'vosaline']
sc_fields = source_fields
#self.setup = settings # dict
# define src/dst cals
sf, ed = cal_trans(sc_time, dst_cal_type, year, month)
# W
DstCal = utime('seconds since %d-1-1' %year, dst_cal_type)
dst_start = DstCal.date2num(datetime(year, month, 1))
dst_end = DstCal.date2num(datetime(year, month, ed, 23, 59, 59))
self.S_cal = utime(sc_time[0]['units'], sc_time[0]['calendar'])
self.D_cal = utime('seconds since %d-1-1' %settings['year_000'],
settings['dst_calendar'])
for date in sc_time:
date['date_num'] = DstCal.date2num(date['date']) * sf
# Get first and last date within range
first_date, last_date = None, None
rev_seq = range(len_sc_time)
rev_seq.reverse()
# Multiple values.. might be broken..
for date in rev_seq:
if sc_time[date]['date_num'] < dst_start:
first_date = date #number..
break
for date in range(len_sc_time):
if sc_time[date]['date_num'] > dst_end:
last_date = date
break
for date in range(first_date, last_date + 1):
nc = Dataset(sc_time[date], 'r')
if key_vec:
pass
#nc_2 = Dataset
# FIX ME
# We shouldnt have to worry about counters
sc_bdy = np.zeros(nvar, sc_z_len, source_ind['ind'].shape[0],
source_ind['ind'].shape[1])
ind_vec = {}
# distinctive variable name since it gets lost in the huge loop
for shoggoth in range(nvar):
varid = nc.variables[var_nam[shoggoth]]
i, ii = source_ind['imin'], source_ind['imax']
j, jj = source_ind['jmin'], source_ind['jmax']
sc_arrays = []
col_sc_arrays = []
if key_vec:
varid_2 = nc_2.variables[var_nam[shoggoth + 1]]
if not isslab and not key_vec:
# NOTE: 0 v 1 indexing may problemate
sc_arrays.append(varid[i-1:ii, j-1:jj, :sc_z_len, :1])
elif key_vec:
sc_arrays.append(varid[i-2:ii, j-1:jj, :sc_z_len, :1])
sc_arrays.append(varid_2[i-1:ii, j-2:jj, :sc_z_len, :1])
for x in 0,1:
# tidy up src array - replace missing val
for y in 'mv', 'fv':
if not np.isnan(sc_fields[y][x]):
ind_vec[y] = sc_arrays[x] == sc_fields[y][x]
sc_arrays[x][ind_vec[y]] = 0
else:
sc_arrays[x][np.isnan(scarr)] = 0
# Adjust for scaling or offsets
if not np.isnan(sc_fields['sf'][x]):
sc_arrays[x] *= sc_fields['sf'][x]
if not np.isnan(sc_fields['os'][x]):
sc_arrays[x] += sc_fields['os'][x]
# Colocate velocity points on T grid prior to rotation
axis = [1, None]
col = 0.5 * (sc_arrays[x][:-axis[0],:-axis[1],:] +
sc_arrays[x][axis[0]:,axis[1]:,:])
col[col == 0] = np.NaN
col_sc_arrays.append(col)
axis.reverse()
# This is a slab
else:
sc_arrays.append(varid[i-1:ii, j-1:jj, :1])
#query var names
if msk and first and shoggoth==0:
pass
# Open another magic file and do stuff
nc3 = Dataset(source_mask, 'r')
varid_3 = nc3.variables['tmaskutil']
msk_array = varid_3[i-1:ii, j-1:jj, :1]
if msk: #must be true for msk array ??...
sc_arrays[0][msk_array == 0] = np.NaN
# Finished reading Source data
#for depth_val in range(sc_z_len):
# tmp_arrays = []
# if not key_vec:
# tmp_arrays.append(sc_arrays[0][:,:depth_val]
def _fv_mv_to_zero(self, scarr, indvec, sc_fields, pos):
for x in 'mv', 'fv':
if not np.isnan(sc_fields[x][pos]):
ind_vec[x] = scarr == sc_fields[x][pos]
scarr[ind_vec[x]] = 0
else:
scarr[np.isnan(scarr)] = 0
return scarr, indvec
# Convert numeric date from source to dest
def convert_date(self, date):
val = self.S_cal.num2date(date)
return self.D_cal.date2num(val)
def cal_trans(self, source, dest, year, month):
vals = {'gregorian': [monthrange(year, month)[1], 31], 'noleap':
[365., 31],'360_day': [360., 30]}
if source not in vals.keys():
raise ValueError('Unknown calendar type: %s' %source)
sf = val[source][0] / val[dest][0]
return sf, vals[dest][1]
...@@ -28,7 +28,7 @@ class Coord: ...@@ -28,7 +28,7 @@ class Coord:
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
self.logger.debug( fname ) self.logger.debug( fname )
if not fname: if not fname:
print 'need some error handling in here or is this redundant?' # TODO print('need some error handling in here or is this redundant?') # TODO
# Enter define mode # Enter define mode
self.ncid = Dataset(fname, 'w', clobber=True, format='NETCDF4') self.ncid = Dataset(fname, 'w', clobber=True, format='NETCDF4')
......
...@@ -34,7 +34,7 @@ $Last commit on:$ ...@@ -34,7 +34,7 @@ $Last commit on:$
import time import time
import logging import logging
import numpy as np import numpy as np
from PyQt4.QtGui import QMessageBox from PyQt5.QtWidgets import QMessageBox
#Local imports #Local imports
from pynemo import pynemo_settings_editor from pynemo import pynemo_settings_editor
...@@ -244,13 +244,13 @@ def process_bdy(setup_filepath=0, mask_gui=False): ...@@ -244,13 +244,13 @@ def process_bdy(setup_filepath=0, mask_gui=False):
'values in input bdy file') 'values in input bdy file')
return return
yrs = range(yr_000, yr_end+1) yrs = list(range(yr_000, yr_end+1))
if yr_end - yr_000 >= 1: if yr_end - yr_000 >= 1:
if range(mn_000, mn_end+1) < 12: if list(range(mn_000, mn_end+1)) < 12:
logger.info('Warning: All months will be extracted as the number '+ logger.info('Warning: All months will be extracted as the number '+
'of years is greater than 1') 'of years is greater than 1')
mns = range(1,13) mns = list(range(1,13))
else: else:
mn_000 = settings['month_000'] mn_000 = settings['month_000']
mn_end = settings['month_end'] mn_end = settings['month_end']
...@@ -258,7 +258,7 @@ def process_bdy(setup_filepath=0, mask_gui=False): ...@@ -258,7 +258,7 @@ def process_bdy(setup_filepath=0, mask_gui=False):
logging.error('Please check the nn_month_000 and nn_month_end '+ logging.error('Please check the nn_month_000 and nn_month_end '+
'values in input bdy file') 'values in input bdy file')
return return
mns = range(mn_000, mn_end+1) mns = list(range(mn_000, mn_end+1))
# Enter the loop for each year and month extraction # Enter the loop for each year and month extraction
...@@ -311,7 +311,7 @@ def process_bdy(setup_filepath=0, mask_gui=False): ...@@ -311,7 +311,7 @@ def process_bdy(setup_filepath=0, mask_gui=False):
# Initialise the mapping indices for each grid # Initialise the mapping indices for each grid
for key, val in emap.items(): for key, val in list(emap.items()):
extract_obj[key] = extract.Extract(Setup.settings, extract_obj[key] = extract.Extract(Setup.settings,
SourceCoord, DstCoord, SourceCoord, DstCoord,
...@@ -324,7 +324,7 @@ def process_bdy(setup_filepath=0, mask_gui=False): ...@@ -324,7 +324,7 @@ def process_bdy(setup_filepath=0, mask_gui=False):
for year in yrs: for year in yrs:
for month in mns: for month in mns:
for key, val in emap.items(): for key, val in list(emap.items()):
# Extract the data for a given month and year # Extract the data for a given month and year
...@@ -379,7 +379,7 @@ def write_tidal_data(setup_var, dst_coord_var, grid, tide_cons, cons): ...@@ -379,7 +379,7 @@ def write_tidal_data(setup_var, dst_coord_var, grid, tide_cons, cons):
const_name = setup_var.settings['clname'][tide_con] const_name = setup_var.settings['clname'][tide_con]
const_name = const_name.replace("'", "").upper() const_name = const_name.replace("'", "").upper()
for key,val in tmap.items(): for key,val in list(tmap.items()):
fout_tide = setup_var.settings['dst_dir']+ \ fout_tide = setup_var.settings['dst_dir']+ \
setup_var.settings['fn']+ \ setup_var.settings['fn']+ \
......
...@@ -5,7 +5,7 @@ Entry for the project ...@@ -5,7 +5,7 @@ Entry for the project
''' '''
import sys, getopt import sys, getopt
import profile from . import profile
import logging import logging
import cProfile import cProfile
...@@ -21,14 +21,14 @@ def main(): ...@@ -21,14 +21,14 @@ def main():
try: try:
opts, dummy_args = getopt.getopt(sys.argv[1:], "hs:g", ["help","setup=","mask_gui"]) opts, dummy_args = getopt.getopt(sys.argv[1:], "hs:g", ["help","setup=","mask_gui"])
except getopt.GetoptError: except getopt.GetoptError:
print "usage: pynemo -g -s <namelist.bdy> " print("usage: pynemo -g -s <namelist.bdy> ")
sys.exit(2) sys.exit(2)
for opt, arg in opts: for opt, arg in opts:
if opt == "-h": if opt == "-h":
print "usage: pynemo [-g] -s <namelist.bdy> " print("usage: pynemo [-g] -s <namelist.bdy> ")
print " -g (optional) will open settings editor before extracting the data" print(" -g (optional) will open settings editor before extracting the data")
print " -s <bdy filename> file to use" print(" -s <bdy filename> file to use")
sys.exit() sys.exit()
elif opt in ("-s", "--setup"): elif opt in ("-s", "--setup"):
setup_file = arg setup_file = arg
...@@ -36,7 +36,7 @@ def main(): ...@@ -36,7 +36,7 @@ def main():
mask_gui = True mask_gui = True
if setup_file == "": if setup_file == "":
print "usage: pynemo [-g] -s <namelist.bdy> " print("usage: pynemo [-g] -s <namelist.bdy> ")
sys.exit(2) sys.exit(2)
#Logger #Logger
...@@ -44,7 +44,7 @@ def main(): ...@@ -44,7 +44,7 @@ def main():
t0 = time.time() t0 = time.time()
cProfile.runctx("f(x, y)",{'f': profile.process_bdy, 'x': setup_file, 'y': mask_gui}, {}, 'pynemo_stats') cProfile.runctx("f(x, y)",{'f': profile.process_bdy, 'x': setup_file, 'y': mask_gui}, {}, 'pynemo_stats')
t1 = time.time() t1 = time.time()
print "Execution Time: %s" % (t1-t0) print("Execution Time: %s" % (t1-t0))
if __name__ == "__main__": if __name__ == "__main__":
main() main()
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