diff --git a/Makefile b/Makefile
index d0dfe5f..65ceda1 100644
--- a/Makefile
+++ b/Makefile
@@ -37,6 +37,11 @@ light: VENV_PATH = ./_venv
light: venv
@$(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:
# Check if virtualenv python version > 3.3.0
diff --git a/src/msspec/iodata.py b/src/msspec/iodata.py
index 27369d9..c60ccc3 100644
--- a/src/msspec/iodata.py
+++ b/src/msspec/iodata.py
@@ -17,7 +17,7 @@
# along with this msspec. If not, see .
#
# 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
@@ -79,19 +79,26 @@ import ase.io
from ase.io.extxyz import read_xyz, write_xyz
import h5py
import numpy as np
-import wx.grid
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_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 terminaltables import AsciiTable
import msspec
-from msspec.msspecgui.msspec.gui.clusterviewer import ClusterViewer
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):
# 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.
"""
- app = wx.App(False)
- app.SetAppName('MsSpec Data Viewer')
- frame = _DataWindow(self)
- frame.Show(True)
- app.MainLoop()
+ if has_gui:
+ app = wx.App(False)
+ app.SetAppName('MsSpec Data Viewer')
+ frame = _DataWindow(self)
+ 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):
@@ -895,7 +908,8 @@ class _DataSetView(object):
axes.set_yticks(R_ticks)
axes.set_yticklabels(theta_ticks)
- figure.colorbar(im)
+ cbar = figure.colorbar(im)
+ #im.set_clim(0, 0.0275)
elif proj == 'polar':
values[0] = np.radians(values[0])
@@ -918,6 +932,7 @@ class _DataSetView(object):
axes.set_ylabel(opts['ylabel'])
axes.set_xlim(*opts['xlim'])
axes.set_ylim(*opts['ylim'])
+ #axes.set_axis_off()
#axes.set_pickradius(5)
if label:
axes.legend()
@@ -1008,425 +1023,426 @@ class _DataSetView(object):
s += '\tconditions : %s\n' % str(self._selection_conditions)
return s
-class _GridWindow(wx.Frame):
- def __init__(self, dset, parent=None):
- title = 'Data: ' + dset.title
- wx.Frame.__init__(self, parent, title=title, size=(640, 480))
- self.create_grid(dset)
+if has_gui:
+ class _GridWindow(wx.Frame):
+ def __init__(self, dset, parent=None):
+ title = 'Data: ' + dset.title
+ wx.Frame.__init__(self, parent, title=title, size=(640, 480))
+ self.create_grid(dset)
- def create_grid(self, dset):
- grid = wx.grid.Grid(self, -1)
- grid.CreateGrid(len(dset), len(dset.columns()))
- for ic, c in enumerate(dset.columns()):
- grid.SetColLabelValue(ic, c)
- for iv, v in enumerate(dset[c]):
- grid.SetCellValue(iv, ic, str(v))
+ def create_grid(self, dset):
+ grid = wx.grid.Grid(self, -1)
+ grid.CreateGrid(len(dset), len(dset.columns()))
+ for ic, c in enumerate(dset.columns()):
+ grid.SetColLabelValue(ic, c)
+ for iv, v in enumerate(dset[c]):
+ grid.SetCellValue(iv, ic, str(v))
-class _ParametersWindow(wx.Frame):
- def __init__(self, dset, parent=None):
- title = 'Parameters: ' + dset.title
- wx.Frame.__init__(self, parent, title=title, size=(400, 480))
- self.create_tree(dset)
+ class _ParametersWindow(wx.Frame):
+ def __init__(self, dset, parent=None):
+ title = 'Parameters: ' + dset.title
+ wx.Frame.__init__(self, parent, title=title, size=(400, 480))
+ self.create_tree(dset)
- def create_tree(self, dset):
- datatree = {}
- for p in dset.parameters():
- is_hidden = p.get('hidden', "False")
- if is_hidden == "True":
- continue
- group = datatree.get(p['group'], [])
- #strval = str(p['value'] * p['unit'] if p['unit'] else p['value'])
- #group.append("{:s} = {:s}".format(p['name'], strval))
- group.append("{} = {} {}".format(p['name'], p['value'], p['unit']))
- datatree[p['group']] = group
+ def create_tree(self, dset):
+ datatree = {}
+ for p in dset.parameters():
+ is_hidden = p.get('hidden', "False")
+ if is_hidden == "True":
+ continue
+ group = datatree.get(p['group'], [])
+ #strval = str(p['value'] * p['unit'] if p['unit'] else p['value'])
+ #group.append("{:s} = {:s}".format(p['name'], strval))
+ group.append("{} = {} {}".format(p['name'], p['value'], p['unit']))
+ datatree[p['group']] = group
- tree = wx.TreeCtrl(self, -1)
- root = tree.AddRoot('Parameters')
+ tree = wx.TreeCtrl(self, -1)
+ root = tree.AddRoot('Parameters')
- for key in list(datatree.keys()):
- item0 = tree.AppendItem(root, key)
- for item in datatree[key]:
- tree.AppendItem(item0, item)
- tree.ExpandAll()
- tree.SelectItem(root)
+ for key in list(datatree.keys()):
+ item0 = tree.AppendItem(root, key)
+ for item in datatree[key]:
+ tree.AppendItem(item0, item)
+ tree.ExpandAll()
+ tree.SelectItem(root)
-class _DataWindow(wx.Frame):
- def __init__(self, data):
- assert isinstance(data, (Data, DataSet))
+ class _DataWindow(wx.Frame):
+ def __init__(self, data):
+ assert isinstance(data, (Data, DataSet))
- if isinstance(data, DataSet):
- dset = data
- data = Data()
- data.first = dset
- self.data = data
- self._filename = None
- self._current_dset = None
+ if isinstance(data, DataSet):
+ dset = data
+ data = Data()
+ data.first = dset
+ self.data = data
+ self._filename = 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
- self.create_menu()
+ # Populate the menu bar
+ self.create_menu()
- # Create the status bar
- statusbar = wx.StatusBar(self, -1)
- statusbar.SetFieldsCount(3)
- statusbar.SetStatusWidths([-2, -1, -1])
- self.SetStatusBar(statusbar)
+ # Create the status bar
+ statusbar = wx.StatusBar(self, -1)
+ statusbar.SetFieldsCount(3)
+ statusbar.SetStatusWidths([-2, -1, -1])
+ self.SetStatusBar(statusbar)
- # Add the notebook to hold all graphs
- self.notebooks = {}
- sizer = wx.BoxSizer(wx.VERTICAL)
- #sizer.Add(self.notebook)
- self.SetSizer(sizer)
+ # Add the notebook to hold all graphs
+ self.notebooks = {}
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ #sizer.Add(self.notebook)
+ 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()
- dlg.Destroy()
- self.update_title()
- def on_save(self, event):
- if self._filename:
+ 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():
- self.data.save(self._filename)
- else:
- self.on_saveas(event)
-
- 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)
-
- 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 = 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()
- 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
- dlg.Destroy()
- self.update_title()
+ self.data = Data.load(path)
+ self.create_notebooks()
+ 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)
+ def on_save(self, event):
+ if self._filename:
+ if self.data.is_dirty():
+ self.data.save(self._filename)
else:
- if proj in ('ortho', 'stereo'):
- 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)
+ self.on_saveas(event)
- 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':
- values[0] = np.radians(values[0])
- axes.plot(*values, label=label, picker=5,
- marker=opts['marker'])
+ 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()
+ 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:
- if scale == 'semilogx':
- pltcmd = axes.semilogx
- elif scale == 'semilogy':
- pltcmd = axes.semilogy
- elif scale == 'log':
- pltcmd = axes.loglog
+ if proj in ('ortho', 'stereo'):
+ 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)
+
+ elif proj == 'polar':
+ values[0] = np.radians(values[0])
+ axes.plot(*values, label=label, picker=5,
+ marker=opts['marker'])
else:
- pltcmd = axes.plot
- pltcmd(*values, label=label, picker=5,
- marker=opts['marker'])
- axes.grid(opts['grid'])
- 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'])
+ if scale == 'semilogx':
+ pltcmd = axes.semilogx
+ elif scale == 'semilogy':
+ pltcmd = axes.semilogy
+ elif scale == 'log':
+ pltcmd = axes.loglog
+ else:
+ pltcmd = axes.plot
+ pltcmd(*values, label=label, picker=5,
+ marker=opts['marker'])
+ axes.grid(opts['grid'])
+ 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
- figure.canvas.mpl_connect('motion_notify_event', self.on_mpl_motion)
- figure.canvas.mpl_connect('pick_event', self.on_mpl_pick)
+ # 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)
+ nb.AddPage(p, view.title)
- def update_statusbar(self):
- sb = self.GetStatusBar()
- menu_id = self.GetMenuBar().FindMenu('Datasets')
- menu = self.GetMenuBar().GetMenu(menu_id)
- for item in menu.GetMenuItems():
- if item.IsChecked():
- sb.SetStatusText("%s" % item.GetItemLabelText(), 1)
- break
+ def update_statusbar(self):
+ sb = self.GetStatusBar()
+ menu_id = self.GetMenuBar().FindMenu('Datasets')
+ menu = self.GetMenuBar().GetMenu(menu_id)
+ for item in menu.GetMenuItems():
+ if item.IsChecked():
+ sb.SetStatusText("%s" % item.GetItemLabelText(), 1)
+ break
- def update_title(self):
- title = "MsSpec Data Viewer"
- if self.data.title:
- title += ": " + self.data.title
- if self._filename:
- title += " [" + os.path.basename(self._filename) + "]"
- self.SetTitle(title)
+ def update_title(self):
+ title = "MsSpec Data Viewer"
+ if self.data.title:
+ title += ": " + self.data.title
+ if self._filename:
+ title += " [" + os.path.basename(self._filename) + "]"
+ self.SetTitle(title)
- def on_mpl_motion(self, event):
- sb = self.GetStatusBar()
- try:
- txt = "[{:.3f}, {:.3f}]".format(event.xdata, event.ydata)
- sb.SetStatusText(txt, 2)
- except Exception:
- pass
+ def on_mpl_motion(self, event):
+ sb = self.GetStatusBar()
+ try:
+ txt = "[{:.3f}, {:.3f}]".format(event.xdata, event.ydata)
+ sb.SetStatusText(txt, 2)
+ except Exception:
+ pass
- def on_mpl_pick(self, event):
- print(event.artist)
+ def on_mpl_pick(self, event):
+ print(event.artist)
- def on_page_changed(self, event):
- self.update_statusbar()
+ def on_page_changed(self, event):
+ self.update_statusbar()
diff --git a/src/options.mk b/src/options.mk
index 5e08919..6c30220 100644
--- a/src/options.mk
+++ b/src/options.mk
@@ -3,7 +3,7 @@ PYMAJ = 3
PYMIN = 5
FC = gfortran
-F2PY = f2py3 --f77exec=$(FC) --f90exec=$(FC)
+F2PY = f2py --f77exec=$(FC) --f90exec=$(FC)
NO_VENV = 0
DEBUG = 0