Provide a "nogui" target in the installation.
It is possible to install msspec without gui, which reduces a lot the number of dependencies. It is still possible to export the results as *.png or to view the cluster with the ase gui.
This commit is contained in:
parent
583eb08924
commit
4aec48b4f6
5
Makefile
5
Makefile
|
@ -37,6 +37,11 @@ light: VENV_PATH = ./_venv
|
||||||
light: venv
|
light: venv
|
||||||
@$(INSIDE_VENV) pip install src/
|
@$(INSIDE_VENV) pip install src/
|
||||||
|
|
||||||
|
nogui: VENV_PATH = ./_venv
|
||||||
|
nogui: venv
|
||||||
|
@$(INSIDE_VENV) pip install --no-cache-dir --upgrade -r src/pip.freeze
|
||||||
|
@$(INSIDE_VENV) pip install -e src/
|
||||||
|
@+$(INSIDE_VENV) $(MAKE) -C src pybinding
|
||||||
|
|
||||||
_attrdict:
|
_attrdict:
|
||||||
# Check if virtualenv python version > 3.3.0
|
# Check if virtualenv python version > 3.3.0
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
# along with this msspec. If not, see <http://www.gnu.org/licenses/>.
|
# along with this msspec. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
# Source file : src/msspec/iodata.py
|
# Source file : src/msspec/iodata.py
|
||||||
# Last modified: Mon, 11 Mar 2024 09:51:47 +0100
|
# Last modified: Tue, 22 Oct 2024 12:39:54 +0200
|
||||||
# Committed by : Sylvain Tricot <sylvain.tricot@univ-rennes.fr>
|
# Committed by : Sylvain Tricot <sylvain.tricot@univ-rennes.fr>
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,19 +79,26 @@ import ase.io
|
||||||
from ase.io.extxyz import read_xyz, write_xyz
|
from ase.io.extxyz import read_xyz, write_xyz
|
||||||
import h5py
|
import h5py
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import wx.grid
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
|
|
||||||
#from matplotlib.backends.backend_wxagg import FigureCanvasWx as FigureCanvas
|
#from matplotlib.backends.backend_wxagg import FigureCanvasWx as FigureCanvas
|
||||||
from matplotlib.backends.backend_agg import FigureCanvasAgg
|
from matplotlib.backends.backend_agg import FigureCanvasAgg
|
||||||
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg
|
#from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvasAgg
|
||||||
from matplotlib.figure import Figure
|
from matplotlib.figure import Figure
|
||||||
from terminaltables import AsciiTable
|
from terminaltables import AsciiTable
|
||||||
|
|
||||||
import msspec
|
import msspec
|
||||||
from msspec.msspecgui.msspec.gui.clusterviewer import ClusterViewer
|
|
||||||
from msspec.misc import LOGGER
|
from msspec.misc import LOGGER
|
||||||
|
|
||||||
|
try:
|
||||||
|
import wx.grid
|
||||||
|
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
|
||||||
|
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg
|
||||||
|
from msspec.msspecgui.msspec.gui.clusterviewer import ClusterViewer
|
||||||
|
has_gui = True
|
||||||
|
except ImportError:
|
||||||
|
LOGGER.warning('No modules for GUI')
|
||||||
|
has_gui = False
|
||||||
|
|
||||||
|
|
||||||
def cols2matrix(x, y, z, nx=88*1+1, ny=360*1+1):
|
def cols2matrix(x, y, z, nx=88*1+1, ny=360*1+1):
|
||||||
# mix the values of existing theta and new theta and return the
|
# mix the values of existing theta and new theta and return the
|
||||||
|
@ -796,11 +803,17 @@ class Data(object):
|
||||||
"""Pops up a grphical window to show all the defined views of the Data object.
|
"""Pops up a grphical window to show all the defined views of the Data object.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
app = wx.App(False)
|
if has_gui:
|
||||||
app.SetAppName('MsSpec Data Viewer')
|
app = wx.App(False)
|
||||||
frame = _DataWindow(self)
|
app.SetAppName('MsSpec Data Viewer')
|
||||||
frame.Show(True)
|
frame = _DataWindow(self)
|
||||||
app.MainLoop()
|
frame.Show(True)
|
||||||
|
app.MainLoop()
|
||||||
|
else:
|
||||||
|
print('**** INFORMATION ****')
|
||||||
|
print('You can not use the Data.view() method since ther is no')
|
||||||
|
print('graphical user interface available in this version of MsSpec.')
|
||||||
|
print("Install WxPython if you need it or use Data.export(...) method instead.")
|
||||||
|
|
||||||
|
|
||||||
class _DataSetView(object):
|
class _DataSetView(object):
|
||||||
|
@ -895,7 +908,8 @@ class _DataSetView(object):
|
||||||
axes.set_yticks(R_ticks)
|
axes.set_yticks(R_ticks)
|
||||||
axes.set_yticklabels(theta_ticks)
|
axes.set_yticklabels(theta_ticks)
|
||||||
|
|
||||||
figure.colorbar(im)
|
cbar = figure.colorbar(im)
|
||||||
|
#im.set_clim(0, 0.0275)
|
||||||
|
|
||||||
elif proj == 'polar':
|
elif proj == 'polar':
|
||||||
values[0] = np.radians(values[0])
|
values[0] = np.radians(values[0])
|
||||||
|
@ -918,6 +932,7 @@ class _DataSetView(object):
|
||||||
axes.set_ylabel(opts['ylabel'])
|
axes.set_ylabel(opts['ylabel'])
|
||||||
axes.set_xlim(*opts['xlim'])
|
axes.set_xlim(*opts['xlim'])
|
||||||
axes.set_ylim(*opts['ylim'])
|
axes.set_ylim(*opts['ylim'])
|
||||||
|
#axes.set_axis_off()
|
||||||
#axes.set_pickradius(5)
|
#axes.set_pickradius(5)
|
||||||
if label:
|
if label:
|
||||||
axes.legend()
|
axes.legend()
|
||||||
|
@ -1008,425 +1023,426 @@ class _DataSetView(object):
|
||||||
s += '\tconditions : %s\n' % str(self._selection_conditions)
|
s += '\tconditions : %s\n' % str(self._selection_conditions)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
class _GridWindow(wx.Frame):
|
if has_gui:
|
||||||
def __init__(self, dset, parent=None):
|
class _GridWindow(wx.Frame):
|
||||||
title = 'Data: ' + dset.title
|
def __init__(self, dset, parent=None):
|
||||||
wx.Frame.__init__(self, parent, title=title, size=(640, 480))
|
title = 'Data: ' + dset.title
|
||||||
self.create_grid(dset)
|
wx.Frame.__init__(self, parent, title=title, size=(640, 480))
|
||||||
|
self.create_grid(dset)
|
||||||
|
|
||||||
def create_grid(self, dset):
|
def create_grid(self, dset):
|
||||||
grid = wx.grid.Grid(self, -1)
|
grid = wx.grid.Grid(self, -1)
|
||||||
grid.CreateGrid(len(dset), len(dset.columns()))
|
grid.CreateGrid(len(dset), len(dset.columns()))
|
||||||
for ic, c in enumerate(dset.columns()):
|
for ic, c in enumerate(dset.columns()):
|
||||||
grid.SetColLabelValue(ic, c)
|
grid.SetColLabelValue(ic, c)
|
||||||
for iv, v in enumerate(dset[c]):
|
for iv, v in enumerate(dset[c]):
|
||||||
grid.SetCellValue(iv, ic, str(v))
|
grid.SetCellValue(iv, ic, str(v))
|
||||||
|
|
||||||
class _ParametersWindow(wx.Frame):
|
class _ParametersWindow(wx.Frame):
|
||||||
def __init__(self, dset, parent=None):
|
def __init__(self, dset, parent=None):
|
||||||
title = 'Parameters: ' + dset.title
|
title = 'Parameters: ' + dset.title
|
||||||
wx.Frame.__init__(self, parent, title=title, size=(400, 480))
|
wx.Frame.__init__(self, parent, title=title, size=(400, 480))
|
||||||
self.create_tree(dset)
|
self.create_tree(dset)
|
||||||
|
|
||||||
def create_tree(self, dset):
|
def create_tree(self, dset):
|
||||||
datatree = {}
|
datatree = {}
|
||||||
for p in dset.parameters():
|
for p in dset.parameters():
|
||||||
is_hidden = p.get('hidden', "False")
|
is_hidden = p.get('hidden', "False")
|
||||||
if is_hidden == "True":
|
if is_hidden == "True":
|
||||||
continue
|
continue
|
||||||
group = datatree.get(p['group'], [])
|
group = datatree.get(p['group'], [])
|
||||||
#strval = str(p['value'] * p['unit'] if p['unit'] else p['value'])
|
#strval = str(p['value'] * p['unit'] if p['unit'] else p['value'])
|
||||||
#group.append("{:s} = {:s}".format(p['name'], strval))
|
#group.append("{:s} = {:s}".format(p['name'], strval))
|
||||||
group.append("{} = {} {}".format(p['name'], p['value'], p['unit']))
|
group.append("{} = {} {}".format(p['name'], p['value'], p['unit']))
|
||||||
datatree[p['group']] = group
|
datatree[p['group']] = group
|
||||||
|
|
||||||
tree = wx.TreeCtrl(self, -1)
|
tree = wx.TreeCtrl(self, -1)
|
||||||
root = tree.AddRoot('Parameters')
|
root = tree.AddRoot('Parameters')
|
||||||
|
|
||||||
for key in list(datatree.keys()):
|
for key in list(datatree.keys()):
|
||||||
item0 = tree.AppendItem(root, key)
|
item0 = tree.AppendItem(root, key)
|
||||||
for item in datatree[key]:
|
for item in datatree[key]:
|
||||||
tree.AppendItem(item0, item)
|
tree.AppendItem(item0, item)
|
||||||
tree.ExpandAll()
|
tree.ExpandAll()
|
||||||
tree.SelectItem(root)
|
tree.SelectItem(root)
|
||||||
|
|
||||||
class _DataWindow(wx.Frame):
|
class _DataWindow(wx.Frame):
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
assert isinstance(data, (Data, DataSet))
|
assert isinstance(data, (Data, DataSet))
|
||||||
|
|
||||||
if isinstance(data, DataSet):
|
if isinstance(data, DataSet):
|
||||||
dset = data
|
dset = data
|
||||||
data = Data()
|
data = Data()
|
||||||
data.first = dset
|
data.first = dset
|
||||||
self.data = data
|
self.data = data
|
||||||
self._filename = None
|
self._filename = None
|
||||||
self._current_dset = None
|
self._current_dset = None
|
||||||
|
|
||||||
wx.Frame.__init__(self, None, title="", size=(640, 480))
|
wx.Frame.__init__(self, None, title="", size=(640, 480))
|
||||||
|
|
||||||
self.Bind(wx.EVT_CLOSE, self.on_close)
|
self.Bind(wx.EVT_CLOSE, self.on_close)
|
||||||
|
|
||||||
# Populate the menu bar
|
# Populate the menu bar
|
||||||
self.create_menu()
|
self.create_menu()
|
||||||
|
|
||||||
# Create the status bar
|
# Create the status bar
|
||||||
statusbar = wx.StatusBar(self, -1)
|
statusbar = wx.StatusBar(self, -1)
|
||||||
statusbar.SetFieldsCount(3)
|
statusbar.SetFieldsCount(3)
|
||||||
statusbar.SetStatusWidths([-2, -1, -1])
|
statusbar.SetStatusWidths([-2, -1, -1])
|
||||||
self.SetStatusBar(statusbar)
|
self.SetStatusBar(statusbar)
|
||||||
|
|
||||||
# Add the notebook to hold all graphs
|
# Add the notebook to hold all graphs
|
||||||
self.notebooks = {}
|
self.notebooks = {}
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
#sizer.Add(self.notebook)
|
#sizer.Add(self.notebook)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.on_page_changed)
|
self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.on_page_changed)
|
||||||
|
|
||||||
self.create_notebooks()
|
|
||||||
|
|
||||||
self.update_title()
|
|
||||||
|
|
||||||
def create_notebooks(self):
|
|
||||||
for key in list(self.notebooks.keys()):
|
|
||||||
nb = self.notebooks.pop(key)
|
|
||||||
nb.Destroy()
|
|
||||||
|
|
||||||
for dset in self.data:
|
|
||||||
nb = wx.Notebook(self, -1)
|
|
||||||
self.notebooks[dset.title] = nb
|
|
||||||
#self.GetSizer().Add(nb, 1, wx.ALL|wx.EXPAND)
|
|
||||||
self.GetSizer().Add(nb, proportion=1, flag=wx.ALL|wx.EXPAND)
|
|
||||||
for view in dset.views():
|
|
||||||
self.create_page(nb, view)
|
|
||||||
|
|
||||||
self.create_menu()
|
|
||||||
|
|
||||||
self.show_dataset(self.data[0].title)
|
|
||||||
|
|
||||||
|
|
||||||
def create_menu(self):
|
|
||||||
menubar = wx.MenuBar()
|
|
||||||
menu1 = wx.Menu()
|
|
||||||
menu1.Append(110, "Open\tCtrl+O")
|
|
||||||
menu1.Append(120, "Save\tCtrl+S")
|
|
||||||
menu1.Append(130, "Save as...")
|
|
||||||
menu1.Append(140, "Export\tCtrl+E")
|
|
||||||
menu1.AppendSeparator()
|
|
||||||
menu1.Append(199, "Close\tCtrl+Q")
|
|
||||||
|
|
||||||
menu2 = wx.Menu()
|
|
||||||
for i, dset in enumerate(self.data):
|
|
||||||
menu_id = 201 + i
|
|
||||||
menu2.AppendRadioItem(menu_id, dset.title)
|
|
||||||
self.Bind(wx.EVT_MENU, self.on_menu_dataset, id=menu_id)
|
|
||||||
|
|
||||||
self.Bind(wx.EVT_MENU, self.on_open, id=110)
|
|
||||||
self.Bind(wx.EVT_MENU, self.on_save, id=120)
|
|
||||||
self.Bind(wx.EVT_MENU, self.on_saveas, id=130)
|
|
||||||
self.Bind(wx.EVT_MENU, self.on_export, id=140)
|
|
||||||
self.Bind(wx.EVT_MENU, self.on_close, id=199)
|
|
||||||
|
|
||||||
|
|
||||||
menu3 = wx.Menu()
|
|
||||||
menu3.Append(301, "Data")
|
|
||||||
menu3.Append(302, "Cluster")
|
|
||||||
menu3.Append(303, "Parameters")
|
|
||||||
|
|
||||||
self.Bind(wx.EVT_MENU, self.on_viewdata, id=301)
|
|
||||||
self.Bind(wx.EVT_MENU, self.on_viewcluster, id=302)
|
|
||||||
self.Bind(wx.EVT_MENU, self.on_viewparameters, id=303)
|
|
||||||
|
|
||||||
menubar.Append(menu1, "&File")
|
|
||||||
menubar.Append(menu2, "&Datasets")
|
|
||||||
menubar.Append(menu3, "&View")
|
|
||||||
self.SetMenuBar(menubar)
|
|
||||||
|
|
||||||
def on_open(self, event):
|
|
||||||
if self.data.is_dirty():
|
|
||||||
mbx = wx.MessageDialog(self, ('Displayed data is unsaved. Do '
|
|
||||||
'you wish to save before opening'
|
|
||||||
'another file ?'),
|
|
||||||
'Warning: Unsaved data',
|
|
||||||
wx.YES_NO | wx.ICON_WARNING)
|
|
||||||
if mbx.ShowModal() == wx.ID_YES:
|
|
||||||
self.on_saveas(wx.Event())
|
|
||||||
mbx.Destroy()
|
|
||||||
|
|
||||||
wildcard = "HDF5 files (*.hdf5)|*.hdf5"
|
|
||||||
dlg = wx.FileDialog(
|
|
||||||
self, message="Open a file...", defaultDir=os.getcwd(),
|
|
||||||
defaultFile="", wildcard=wildcard, style=wx.FD_OPEN
|
|
||||||
)
|
|
||||||
|
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
|
||||||
path = dlg.GetPath()
|
|
||||||
self._filename = path
|
|
||||||
self.data = Data.load(path)
|
|
||||||
self.create_notebooks()
|
self.create_notebooks()
|
||||||
dlg.Destroy()
|
|
||||||
self.update_title()
|
|
||||||
|
|
||||||
def on_save(self, event):
|
self.update_title()
|
||||||
if self._filename:
|
|
||||||
|
def create_notebooks(self):
|
||||||
|
for key in list(self.notebooks.keys()):
|
||||||
|
nb = self.notebooks.pop(key)
|
||||||
|
nb.Destroy()
|
||||||
|
|
||||||
|
for dset in self.data:
|
||||||
|
nb = wx.Notebook(self, -1)
|
||||||
|
self.notebooks[dset.title] = nb
|
||||||
|
#self.GetSizer().Add(nb, 1, wx.ALL|wx.EXPAND)
|
||||||
|
self.GetSizer().Add(nb, proportion=1, flag=wx.ALL|wx.EXPAND)
|
||||||
|
for view in dset.views():
|
||||||
|
self.create_page(nb, view)
|
||||||
|
|
||||||
|
self.create_menu()
|
||||||
|
|
||||||
|
self.show_dataset(self.data[0].title)
|
||||||
|
|
||||||
|
|
||||||
|
def create_menu(self):
|
||||||
|
menubar = wx.MenuBar()
|
||||||
|
menu1 = wx.Menu()
|
||||||
|
menu1.Append(110, "Open\tCtrl+O")
|
||||||
|
menu1.Append(120, "Save\tCtrl+S")
|
||||||
|
menu1.Append(130, "Save as...")
|
||||||
|
menu1.Append(140, "Export\tCtrl+E")
|
||||||
|
menu1.AppendSeparator()
|
||||||
|
menu1.Append(199, "Close\tCtrl+Q")
|
||||||
|
|
||||||
|
menu2 = wx.Menu()
|
||||||
|
for i, dset in enumerate(self.data):
|
||||||
|
menu_id = 201 + i
|
||||||
|
menu2.AppendRadioItem(menu_id, dset.title)
|
||||||
|
self.Bind(wx.EVT_MENU, self.on_menu_dataset, id=menu_id)
|
||||||
|
|
||||||
|
self.Bind(wx.EVT_MENU, self.on_open, id=110)
|
||||||
|
self.Bind(wx.EVT_MENU, self.on_save, id=120)
|
||||||
|
self.Bind(wx.EVT_MENU, self.on_saveas, id=130)
|
||||||
|
self.Bind(wx.EVT_MENU, self.on_export, id=140)
|
||||||
|
self.Bind(wx.EVT_MENU, self.on_close, id=199)
|
||||||
|
|
||||||
|
|
||||||
|
menu3 = wx.Menu()
|
||||||
|
menu3.Append(301, "Data")
|
||||||
|
menu3.Append(302, "Cluster")
|
||||||
|
menu3.Append(303, "Parameters")
|
||||||
|
|
||||||
|
self.Bind(wx.EVT_MENU, self.on_viewdata, id=301)
|
||||||
|
self.Bind(wx.EVT_MENU, self.on_viewcluster, id=302)
|
||||||
|
self.Bind(wx.EVT_MENU, self.on_viewparameters, id=303)
|
||||||
|
|
||||||
|
menubar.Append(menu1, "&File")
|
||||||
|
menubar.Append(menu2, "&Datasets")
|
||||||
|
menubar.Append(menu3, "&View")
|
||||||
|
self.SetMenuBar(menubar)
|
||||||
|
|
||||||
|
def on_open(self, event):
|
||||||
if self.data.is_dirty():
|
if self.data.is_dirty():
|
||||||
self.data.save(self._filename)
|
mbx = wx.MessageDialog(self, ('Displayed data is unsaved. Do '
|
||||||
else:
|
'you wish to save before opening'
|
||||||
self.on_saveas(event)
|
'another file ?'),
|
||||||
|
'Warning: Unsaved data',
|
||||||
def on_saveas(self, event):
|
wx.YES_NO | wx.ICON_WARNING)
|
||||||
overwrite = True
|
if mbx.ShowModal() == wx.ID_YES:
|
||||||
wildcard = "HDF5 files (*.hdf5)|*.hdf5|All files (*.*)|*.*"
|
self.on_saveas(wx.Event())
|
||||||
dlg = wx.FileDialog(
|
|
||||||
self, message="Save file as ...", defaultDir=os.getcwd(),
|
|
||||||
defaultFile='{}.hdf5'.format(self.data.title.replace(' ','_')),
|
|
||||||
wildcard=wildcard, style=wx.FD_SAVE)
|
|
||||||
dlg.SetFilterIndex(0)
|
|
||||||
|
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
|
||||||
path = dlg.GetPath()
|
|
||||||
if os.path.exists(path):
|
|
||||||
mbx = wx.MessageDialog(self, ('This file already exists. '
|
|
||||||
'Do you wish to overwrite it ?'),
|
|
||||||
'Warning: File exists',
|
|
||||||
wx.YES_NO | wx.ICON_WARNING)
|
|
||||||
if mbx.ShowModal() == wx.ID_NO:
|
|
||||||
overwrite = False
|
|
||||||
mbx.Destroy()
|
mbx.Destroy()
|
||||||
if overwrite:
|
|
||||||
self.data.save(path)
|
wildcard = "HDF5 files (*.hdf5)|*.hdf5"
|
||||||
|
dlg = wx.FileDialog(
|
||||||
|
self, message="Open a file...", defaultDir=os.getcwd(),
|
||||||
|
defaultFile="", wildcard=wildcard, style=wx.FD_OPEN
|
||||||
|
)
|
||||||
|
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
path = dlg.GetPath()
|
||||||
self._filename = path
|
self._filename = path
|
||||||
dlg.Destroy()
|
self.data = Data.load(path)
|
||||||
self.update_title()
|
self.create_notebooks()
|
||||||
|
dlg.Destroy()
|
||||||
|
self.update_title()
|
||||||
|
|
||||||
def on_export(self, event):
|
def on_save(self, event):
|
||||||
overwrite = True
|
if self._filename:
|
||||||
dlg = wx.DirDialog(
|
if self.data.is_dirty():
|
||||||
self, message="Export data...", defaultPath=os.getcwd(),
|
self.data.save(self._filename)
|
||||||
style=wx.DD_DEFAULT_STYLE)
|
|
||||||
|
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
|
||||||
path = dlg.GetPath()
|
|
||||||
if os.listdir(path):
|
|
||||||
mbx = wx.MessageDialog(self,
|
|
||||||
('This folder is not empty. '
|
|
||||||
'Exporting tour data here may '
|
|
||||||
'overwrite its content. Do you wish '
|
|
||||||
'to continue ?'),
|
|
||||||
'Warning: Folder is not empty',
|
|
||||||
wx.YES_NO | wx.ICON_WARNING)
|
|
||||||
if mbx.ShowModal() == wx.ID_NO:
|
|
||||||
overwrite = False
|
|
||||||
mbx.Destroy()
|
|
||||||
self.data.export(path, overwrite)
|
|
||||||
dlg.Destroy()
|
|
||||||
|
|
||||||
def on_viewdata(self, event):
|
|
||||||
dset = self.data[self._current_dset]
|
|
||||||
frame = _GridWindow(dset, parent=self)
|
|
||||||
frame.Show()
|
|
||||||
|
|
||||||
def on_viewcluster(self, event):
|
|
||||||
win = wx.Frame(None, size=wx.Size(480, 340))
|
|
||||||
cluster_viewer = ClusterViewer(win, size=wx.Size(480, 340))
|
|
||||||
|
|
||||||
dset = self.data[self._current_dset]
|
|
||||||
#s = StringIO()
|
|
||||||
#s.write(dset.get_parameter(group='Cluster', name='cluster')['value'])
|
|
||||||
#_s = dset.get_parameter(group='Cluster', name='cluster')['value']
|
|
||||||
#print(_s)
|
|
||||||
# rewind to the begining of the string
|
|
||||||
#s.seek(0)
|
|
||||||
#atoms = ase.io.read(s, format='xyz')
|
|
||||||
atoms = dset.get_cluster()
|
|
||||||
cluster_viewer.set_atoms(atoms, rescale=True, center=True)
|
|
||||||
cluster_viewer.rotate_atoms(0., 180.)
|
|
||||||
cluster_viewer.rotate_atoms(-45., -45.)
|
|
||||||
#cluster_viewer.show_emitter(True)
|
|
||||||
win.Show()
|
|
||||||
|
|
||||||
def on_viewparameters(self, event):
|
|
||||||
dset = self.data[self._current_dset]
|
|
||||||
frame = _ParametersWindow(dset, parent=self)
|
|
||||||
frame.Show()
|
|
||||||
|
|
||||||
def on_close(self, event):
|
|
||||||
if self.data.is_dirty():
|
|
||||||
mbx = wx.MessageDialog(self, ('Displayed data is unsaved. Do you '
|
|
||||||
'really want to quit ?'),
|
|
||||||
'Warning: Unsaved data',
|
|
||||||
wx.YES_NO | wx.ICON_WARNING)
|
|
||||||
if mbx.ShowModal() == wx.ID_NO:
|
|
||||||
mbx.Destroy()
|
|
||||||
return
|
|
||||||
self.Destroy()
|
|
||||||
|
|
||||||
|
|
||||||
def on_menu_dataset(self, event):
|
|
||||||
menu_id = event.GetId()
|
|
||||||
dset_name = self.GetMenuBar().FindItemById(menu_id).GetItemLabelText()
|
|
||||||
self.show_dataset(dset_name)
|
|
||||||
|
|
||||||
|
|
||||||
def show_dataset(self, name):
|
|
||||||
for nb in list(self.notebooks.values()):
|
|
||||||
nb.Hide()
|
|
||||||
self.notebooks[name].Show()
|
|
||||||
self.Layout()
|
|
||||||
self.update_statusbar()
|
|
||||||
self._current_dset = name
|
|
||||||
|
|
||||||
def create_page(self, nb, view):
|
|
||||||
# Get the matplotlib figure
|
|
||||||
figure = view.get_figure()
|
|
||||||
|
|
||||||
# Create a panel
|
|
||||||
p = wx.Panel(nb, -1)
|
|
||||||
|
|
||||||
# Create a matplotlib canvas for the figure
|
|
||||||
canvas = FigureCanvas(p, -1, figure)
|
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
|
|
||||||
toolbar = NavigationToolbar2WxAgg(canvas)
|
|
||||||
toolbar.Realize()
|
|
||||||
|
|
||||||
#sizer.Add(toolbar, 0, wx.ALL|wx.EXPAND)
|
|
||||||
sizer.Add(toolbar, proportion=0, flag=wx.ALL|wx.EXPAND)
|
|
||||||
toolbar.update()
|
|
||||||
|
|
||||||
#sizer.Add(canvas, 5, wx.ALL|wx.EXPAND)
|
|
||||||
sizer.Add(canvas, proportion=1, flag=wx.ALL|wx.EXPAND)
|
|
||||||
|
|
||||||
p.SetSizer(sizer)
|
|
||||||
p.Fit()
|
|
||||||
p.Show()
|
|
||||||
|
|
||||||
# MPL events
|
|
||||||
figure.canvas.mpl_connect('motion_notify_event', self.on_mpl_motion)
|
|
||||||
figure.canvas.mpl_connect('pick_event', self.on_mpl_pick)
|
|
||||||
|
|
||||||
nb.AddPage(p, view.title)
|
|
||||||
canvas.draw()
|
|
||||||
|
|
||||||
|
|
||||||
def OLDcreate_page(self, nb, view):
|
|
||||||
opts = view._plotopts
|
|
||||||
p = wx.Panel(nb, -1)
|
|
||||||
|
|
||||||
figure = Figure()
|
|
||||||
|
|
||||||
axes = None
|
|
||||||
proj = opts['projection']
|
|
||||||
scale = opts['scale']
|
|
||||||
if proj == 'rectilinear':
|
|
||||||
axes = figure.add_subplot(111, projection='rectilinear')
|
|
||||||
elif proj in ('polar', 'ortho', 'stereo'):
|
|
||||||
axes = figure.add_subplot(111, projection='polar')
|
|
||||||
|
|
||||||
canvas = FigureCanvas(p, -1, figure)
|
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
|
|
||||||
toolbar = NavigationToolbar2WxAgg(canvas)
|
|
||||||
toolbar.Realize()
|
|
||||||
|
|
||||||
sizer.Add(toolbar, 0, wx.ALL|wx.EXPAND)
|
|
||||||
toolbar.update()
|
|
||||||
|
|
||||||
sizer.Add(canvas, 5, wx.ALL|wx.EXPAND)
|
|
||||||
|
|
||||||
p.SetSizer(sizer)
|
|
||||||
p.Fit()
|
|
||||||
p.Show()
|
|
||||||
|
|
||||||
|
|
||||||
for values, label in zip(view.get_data(), opts['legend']):
|
|
||||||
# if we have only one column to plot, select a bar graph
|
|
||||||
if np.shape(values)[0] == 1:
|
|
||||||
xvalues = list(range(len(values[0])))
|
|
||||||
axes.bar(xvalues, values[0], label=label,
|
|
||||||
picker=5)
|
|
||||||
axes.set_xticks(xvalues)
|
|
||||||
else:
|
else:
|
||||||
if proj in ('ortho', 'stereo'):
|
self.on_saveas(event)
|
||||||
theta, phi, Xsec = cols2matrix(*values)
|
|
||||||
theta_ticks = np.arange(0, 91, 15)
|
|
||||||
if proj == 'ortho':
|
|
||||||
R = np.sin(np.radians(theta))
|
|
||||||
R_ticks = np.sin(np.radians(theta_ticks))
|
|
||||||
elif proj == 'stereo':
|
|
||||||
R = 2 * np.tan(np.radians(theta/2.))
|
|
||||||
R_ticks = 2 * np.tan(np.radians(theta_ticks/2.))
|
|
||||||
#R = np.tan(np.radians(theta/2.))
|
|
||||||
X, Y = np.meshgrid(np.radians(phi), R)
|
|
||||||
im = axes.pcolormesh(X, Y, Xsec)
|
|
||||||
axes.set_yticks(R_ticks)
|
|
||||||
axes.set_yticklabels(theta_ticks)
|
|
||||||
|
|
||||||
figure.colorbar(im)
|
def on_saveas(self, event):
|
||||||
|
overwrite = True
|
||||||
|
wildcard = "HDF5 files (*.hdf5)|*.hdf5|All files (*.*)|*.*"
|
||||||
|
dlg = wx.FileDialog(
|
||||||
|
self, message="Save file as ...", defaultDir=os.getcwd(),
|
||||||
|
defaultFile='{}.hdf5'.format(self.data.title.replace(' ','_')),
|
||||||
|
wildcard=wildcard, style=wx.FD_SAVE)
|
||||||
|
dlg.SetFilterIndex(0)
|
||||||
|
|
||||||
elif proj == 'polar':
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
values[0] = np.radians(values[0])
|
path = dlg.GetPath()
|
||||||
axes.plot(*values, label=label, picker=5,
|
if os.path.exists(path):
|
||||||
marker=opts['marker'])
|
mbx = wx.MessageDialog(self, ('This file already exists. '
|
||||||
|
'Do you wish to overwrite it ?'),
|
||||||
|
'Warning: File exists',
|
||||||
|
wx.YES_NO | wx.ICON_WARNING)
|
||||||
|
if mbx.ShowModal() == wx.ID_NO:
|
||||||
|
overwrite = False
|
||||||
|
mbx.Destroy()
|
||||||
|
if overwrite:
|
||||||
|
self.data.save(path)
|
||||||
|
self._filename = path
|
||||||
|
dlg.Destroy()
|
||||||
|
self.update_title()
|
||||||
|
|
||||||
|
def on_export(self, event):
|
||||||
|
overwrite = True
|
||||||
|
dlg = wx.DirDialog(
|
||||||
|
self, message="Export data...", defaultPath=os.getcwd(),
|
||||||
|
style=wx.DD_DEFAULT_STYLE)
|
||||||
|
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
path = dlg.GetPath()
|
||||||
|
if os.listdir(path):
|
||||||
|
mbx = wx.MessageDialog(self,
|
||||||
|
('This folder is not empty. '
|
||||||
|
'Exporting tour data here may '
|
||||||
|
'overwrite its content. Do you wish '
|
||||||
|
'to continue ?'),
|
||||||
|
'Warning: Folder is not empty',
|
||||||
|
wx.YES_NO | wx.ICON_WARNING)
|
||||||
|
if mbx.ShowModal() == wx.ID_NO:
|
||||||
|
overwrite = False
|
||||||
|
mbx.Destroy()
|
||||||
|
self.data.export(path, overwrite)
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def on_viewdata(self, event):
|
||||||
|
dset = self.data[self._current_dset]
|
||||||
|
frame = _GridWindow(dset, parent=self)
|
||||||
|
frame.Show()
|
||||||
|
|
||||||
|
def on_viewcluster(self, event):
|
||||||
|
win = wx.Frame(None, size=wx.Size(480, 340))
|
||||||
|
cluster_viewer = ClusterViewer(win, size=wx.Size(480, 340))
|
||||||
|
|
||||||
|
dset = self.data[self._current_dset]
|
||||||
|
#s = StringIO()
|
||||||
|
#s.write(dset.get_parameter(group='Cluster', name='cluster')['value'])
|
||||||
|
#_s = dset.get_parameter(group='Cluster', name='cluster')['value']
|
||||||
|
#print(_s)
|
||||||
|
# rewind to the begining of the string
|
||||||
|
#s.seek(0)
|
||||||
|
#atoms = ase.io.read(s, format='xyz')
|
||||||
|
atoms = dset.get_cluster()
|
||||||
|
cluster_viewer.set_atoms(atoms, rescale=True, center=True)
|
||||||
|
cluster_viewer.rotate_atoms(0., 180.)
|
||||||
|
cluster_viewer.rotate_atoms(-45., -45.)
|
||||||
|
#cluster_viewer.show_emitter(True)
|
||||||
|
win.Show()
|
||||||
|
|
||||||
|
def on_viewparameters(self, event):
|
||||||
|
dset = self.data[self._current_dset]
|
||||||
|
frame = _ParametersWindow(dset, parent=self)
|
||||||
|
frame.Show()
|
||||||
|
|
||||||
|
def on_close(self, event):
|
||||||
|
if self.data.is_dirty():
|
||||||
|
mbx = wx.MessageDialog(self, ('Displayed data is unsaved. Do you '
|
||||||
|
'really want to quit ?'),
|
||||||
|
'Warning: Unsaved data',
|
||||||
|
wx.YES_NO | wx.ICON_WARNING)
|
||||||
|
if mbx.ShowModal() == wx.ID_NO:
|
||||||
|
mbx.Destroy()
|
||||||
|
return
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
|
||||||
|
def on_menu_dataset(self, event):
|
||||||
|
menu_id = event.GetId()
|
||||||
|
dset_name = self.GetMenuBar().FindItemById(menu_id).GetItemLabelText()
|
||||||
|
self.show_dataset(dset_name)
|
||||||
|
|
||||||
|
|
||||||
|
def show_dataset(self, name):
|
||||||
|
for nb in list(self.notebooks.values()):
|
||||||
|
nb.Hide()
|
||||||
|
self.notebooks[name].Show()
|
||||||
|
self.Layout()
|
||||||
|
self.update_statusbar()
|
||||||
|
self._current_dset = name
|
||||||
|
|
||||||
|
def create_page(self, nb, view):
|
||||||
|
# Get the matplotlib figure
|
||||||
|
figure = view.get_figure()
|
||||||
|
|
||||||
|
# Create a panel
|
||||||
|
p = wx.Panel(nb, -1)
|
||||||
|
|
||||||
|
# Create a matplotlib canvas for the figure
|
||||||
|
canvas = FigureCanvas(p, -1, figure)
|
||||||
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
|
||||||
|
toolbar = NavigationToolbar2WxAgg(canvas)
|
||||||
|
toolbar.Realize()
|
||||||
|
|
||||||
|
#sizer.Add(toolbar, 0, wx.ALL|wx.EXPAND)
|
||||||
|
sizer.Add(toolbar, proportion=0, flag=wx.ALL|wx.EXPAND)
|
||||||
|
toolbar.update()
|
||||||
|
|
||||||
|
#sizer.Add(canvas, 5, wx.ALL|wx.EXPAND)
|
||||||
|
sizer.Add(canvas, proportion=1, flag=wx.ALL|wx.EXPAND)
|
||||||
|
|
||||||
|
p.SetSizer(sizer)
|
||||||
|
p.Fit()
|
||||||
|
p.Show()
|
||||||
|
|
||||||
|
# MPL events
|
||||||
|
figure.canvas.mpl_connect('motion_notify_event', self.on_mpl_motion)
|
||||||
|
figure.canvas.mpl_connect('pick_event', self.on_mpl_pick)
|
||||||
|
|
||||||
|
nb.AddPage(p, view.title)
|
||||||
|
canvas.draw()
|
||||||
|
|
||||||
|
|
||||||
|
def OLDcreate_page(self, nb, view):
|
||||||
|
opts = view._plotopts
|
||||||
|
p = wx.Panel(nb, -1)
|
||||||
|
|
||||||
|
figure = Figure()
|
||||||
|
|
||||||
|
axes = None
|
||||||
|
proj = opts['projection']
|
||||||
|
scale = opts['scale']
|
||||||
|
if proj == 'rectilinear':
|
||||||
|
axes = figure.add_subplot(111, projection='rectilinear')
|
||||||
|
elif proj in ('polar', 'ortho', 'stereo'):
|
||||||
|
axes = figure.add_subplot(111, projection='polar')
|
||||||
|
|
||||||
|
canvas = FigureCanvas(p, -1, figure)
|
||||||
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
|
||||||
|
toolbar = NavigationToolbar2WxAgg(canvas)
|
||||||
|
toolbar.Realize()
|
||||||
|
|
||||||
|
sizer.Add(toolbar, 0, wx.ALL|wx.EXPAND)
|
||||||
|
toolbar.update()
|
||||||
|
|
||||||
|
sizer.Add(canvas, 5, wx.ALL|wx.EXPAND)
|
||||||
|
|
||||||
|
p.SetSizer(sizer)
|
||||||
|
p.Fit()
|
||||||
|
p.Show()
|
||||||
|
|
||||||
|
|
||||||
|
for values, label in zip(view.get_data(), opts['legend']):
|
||||||
|
# if we have only one column to plot, select a bar graph
|
||||||
|
if np.shape(values)[0] == 1:
|
||||||
|
xvalues = list(range(len(values[0])))
|
||||||
|
axes.bar(xvalues, values[0], label=label,
|
||||||
|
picker=5)
|
||||||
|
axes.set_xticks(xvalues)
|
||||||
else:
|
else:
|
||||||
if scale == 'semilogx':
|
if proj in ('ortho', 'stereo'):
|
||||||
pltcmd = axes.semilogx
|
theta, phi, Xsec = cols2matrix(*values)
|
||||||
elif scale == 'semilogy':
|
theta_ticks = np.arange(0, 91, 15)
|
||||||
pltcmd = axes.semilogy
|
if proj == 'ortho':
|
||||||
elif scale == 'log':
|
R = np.sin(np.radians(theta))
|
||||||
pltcmd = axes.loglog
|
R_ticks = np.sin(np.radians(theta_ticks))
|
||||||
|
elif proj == 'stereo':
|
||||||
|
R = 2 * np.tan(np.radians(theta/2.))
|
||||||
|
R_ticks = 2 * np.tan(np.radians(theta_ticks/2.))
|
||||||
|
#R = np.tan(np.radians(theta/2.))
|
||||||
|
X, Y = np.meshgrid(np.radians(phi), R)
|
||||||
|
im = axes.pcolormesh(X, Y, Xsec)
|
||||||
|
axes.set_yticks(R_ticks)
|
||||||
|
axes.set_yticklabels(theta_ticks)
|
||||||
|
|
||||||
|
figure.colorbar(im)
|
||||||
|
|
||||||
|
elif proj == 'polar':
|
||||||
|
values[0] = np.radians(values[0])
|
||||||
|
axes.plot(*values, label=label, picker=5,
|
||||||
|
marker=opts['marker'])
|
||||||
else:
|
else:
|
||||||
pltcmd = axes.plot
|
if scale == 'semilogx':
|
||||||
pltcmd(*values, label=label, picker=5,
|
pltcmd = axes.semilogx
|
||||||
marker=opts['marker'])
|
elif scale == 'semilogy':
|
||||||
axes.grid(opts['grid'])
|
pltcmd = axes.semilogy
|
||||||
axes.set_title(opts['title'])
|
elif scale == 'log':
|
||||||
axes.set_xlabel(opts['xlabel'])
|
pltcmd = axes.loglog
|
||||||
axes.set_ylabel(opts['ylabel'])
|
else:
|
||||||
axes.set_xlim(*opts['xlim'])
|
pltcmd = axes.plot
|
||||||
axes.set_ylim(*opts['ylim'])
|
pltcmd(*values, label=label, picker=5,
|
||||||
if label:
|
marker=opts['marker'])
|
||||||
axes.legend()
|
axes.grid(opts['grid'])
|
||||||
axes.autoscale(enable=opts['autoscale'])
|
axes.set_title(opts['title'])
|
||||||
|
axes.set_xlabel(opts['xlabel'])
|
||||||
|
axes.set_ylabel(opts['ylabel'])
|
||||||
|
axes.set_xlim(*opts['xlim'])
|
||||||
|
axes.set_ylim(*opts['ylim'])
|
||||||
|
if label:
|
||||||
|
axes.legend()
|
||||||
|
axes.autoscale(enable=opts['autoscale'])
|
||||||
|
|
||||||
|
|
||||||
# MPL events
|
# MPL events
|
||||||
figure.canvas.mpl_connect('motion_notify_event', self.on_mpl_motion)
|
figure.canvas.mpl_connect('motion_notify_event', self.on_mpl_motion)
|
||||||
figure.canvas.mpl_connect('pick_event', self.on_mpl_pick)
|
figure.canvas.mpl_connect('pick_event', self.on_mpl_pick)
|
||||||
|
|
||||||
nb.AddPage(p, view.title)
|
nb.AddPage(p, view.title)
|
||||||
|
|
||||||
|
|
||||||
def update_statusbar(self):
|
def update_statusbar(self):
|
||||||
sb = self.GetStatusBar()
|
sb = self.GetStatusBar()
|
||||||
menu_id = self.GetMenuBar().FindMenu('Datasets')
|
menu_id = self.GetMenuBar().FindMenu('Datasets')
|
||||||
menu = self.GetMenuBar().GetMenu(menu_id)
|
menu = self.GetMenuBar().GetMenu(menu_id)
|
||||||
for item in menu.GetMenuItems():
|
for item in menu.GetMenuItems():
|
||||||
if item.IsChecked():
|
if item.IsChecked():
|
||||||
sb.SetStatusText("%s" % item.GetItemLabelText(), 1)
|
sb.SetStatusText("%s" % item.GetItemLabelText(), 1)
|
||||||
break
|
break
|
||||||
|
|
||||||
def update_title(self):
|
def update_title(self):
|
||||||
title = "MsSpec Data Viewer"
|
title = "MsSpec Data Viewer"
|
||||||
if self.data.title:
|
if self.data.title:
|
||||||
title += ": " + self.data.title
|
title += ": " + self.data.title
|
||||||
if self._filename:
|
if self._filename:
|
||||||
title += " [" + os.path.basename(self._filename) + "]"
|
title += " [" + os.path.basename(self._filename) + "]"
|
||||||
self.SetTitle(title)
|
self.SetTitle(title)
|
||||||
|
|
||||||
def on_mpl_motion(self, event):
|
def on_mpl_motion(self, event):
|
||||||
sb = self.GetStatusBar()
|
sb = self.GetStatusBar()
|
||||||
try:
|
try:
|
||||||
txt = "[{:.3f}, {:.3f}]".format(event.xdata, event.ydata)
|
txt = "[{:.3f}, {:.3f}]".format(event.xdata, event.ydata)
|
||||||
sb.SetStatusText(txt, 2)
|
sb.SetStatusText(txt, 2)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_mpl_pick(self, event):
|
def on_mpl_pick(self, event):
|
||||||
print(event.artist)
|
print(event.artist)
|
||||||
|
|
||||||
def on_page_changed(self, event):
|
def on_page_changed(self, event):
|
||||||
self.update_statusbar()
|
self.update_statusbar()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ PYMAJ = 3
|
||||||
PYMIN = 5
|
PYMIN = 5
|
||||||
|
|
||||||
FC = gfortran
|
FC = gfortran
|
||||||
F2PY = f2py3 --f77exec=$(FC) --f90exec=$(FC)
|
F2PY = f2py --f77exec=$(FC) --f90exec=$(FC)
|
||||||
|
|
||||||
NO_VENV = 0
|
NO_VENV = 0
|
||||||
DEBUG = 0
|
DEBUG = 0
|
||||||
|
|
Loading…
Reference in New Issue