Commit 01fe5162 authored by eric pellegrini's avatar eric pellegrini

Renamed IJob.configurators class attribute to IJob.settings to avoid

conflicts
Refactored many GUI related module to make the main app restartable
parent 47d176d4
......@@ -5,11 +5,11 @@ from MDANSE.Framework.Configurators.IConfigurator import ConfiguratorError
class ConfigurationPanel(wx.Panel):
def __init__(self, parent, configuration):
def __init__(self, parent, configurable):
wx.Panel.__init__(self, parent, wx.ID_ANY)
self._configuration = configuration
self._configurable = configurable
self._widgets = {}
......@@ -19,13 +19,13 @@ class ConfigurationPanel(wx.Panel):
self.panelSizer = wx.BoxSizer(wx.VERTICAL)
for cfg in self._configuration.configurators.values():
for cfgName, cfg in self._configurable.settings.items():
widgetClass = REGISTRY["configurator_widget"][cfg.widget]
widgetClass = REGISTRY["widget"][cfg[0]]
self._widgets[cfg.name] = widgetClass(self, cfg.name, self._configuration)
self._widgets[cfgName] = widgetClass(self, cfgName, self._configurable)
self.panelSizer.Add(self._widgets[cfg.name], 0, wx.ALL|wx.EXPAND, 5)
self.panelSizer.Add(self._widgets[cfgName], 0, wx.ALL|wx.EXPAND, 5)
self.SetSizer(self.panelSizer)
......
import wx
import wx.lib.agw.pygauge as pygauge
from nMOLDYN.Core.Status import StatusHandler
from nMOLDYN.GUI.Resources.Icons import ICONS, scaled_bitmap
class ProgressBar(wx.Panel,StatusHandler):
def __init__(self, *args, **kwargs):
wx.Panel.__init__(self,*args, **kwargs)
StatusHandler.__init__(self)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self._progress = pygauge.PyGauge(self, wx.ID_ANY)
self._stop = wx.BitmapButton(self, wx.ID_ANY, scaled_bitmap(ICONS["stop"], 24, 24))
sizer.Add(self._progress,1,wx.ALL|wx.EXPAND,5)
sizer.Add(self._stop,0,wx.ALL|wx.EXPAND,5)
self.SetSizer(sizer)
self.Layout()
self.Bind(wx.EVT_BUTTON,self.on_stop,self._stop)
def finish_status(self,message):
status = message
if status != self._status:
return
self._progress.SetBarColor(wx.BLUE)
self._progress.Refresh()
self._stop.Disable()
def on_stop(self,event):
d = wx.MessageDialog(None, 'This will stop the current task. Do you really want to stop it ?', 'Question', wx.YES_NO|wx.YES_DEFAULT|wx.ICON_WARNING)
if d.ShowModal() == wx.ID_NO:
return
self._stop.Disable()
self._status.stop()
def start_status(self, message):
status = message
if status != self._status:
return
self._stop.Enable()
self._progress.SetValue(self._status.currentStep)
self._progress.SetRange(self._status.nSteps)
self._progress.SetBarColor(wx.GREEN)
def stop_status(self, message):
status = message
if status != self._status:
return
self._progress.SetBarColor(wx.RED)
self._progress.Refresh()
def update_status(self,message):
status = message
if status != self._status:
return
self._progress.SetValue(self._status.currentStep)
self._progress.Refresh()
......@@ -38,9 +38,9 @@ from MDANSE.Framework.Handlers.IHandler import IHandler
from MDANSE.Logging.Formatters import Formatter
class ConsoleHandler(IHandler, logging.Handler):
"""Sets up a GUI handler for the nMOLDYN logger.
"""Sets up a GUI handler for the MDANSE logger.
Emits the logging message to the nMOLDYN GUI console.
Emits the logging message to the MDANSE GUI console.
@note: inherits from logging.Handler class that sets a generic handler.
"""
......
......@@ -27,7 +27,7 @@
'''
Created on Apr 14, 2015
@author: pellegrini
@author: Eric C. pellegrini
'''
import wx
......
......@@ -27,7 +27,7 @@
'''
Created on Apr 14, 2015
@author: pellegrini
@author: Eric C. Pellegrini
'''
import collections
......@@ -40,10 +40,10 @@ from MDANSE import LOGGER, REGISTRY, UD_STORE
from MDANSE.Core.Error import Error
from MDANSE.Externals.pubsub import pub
from MDANSE.Framework.AtomSelectionParser import AtomSelectionParser, AtomSelectionParserError
from MDANSE.MolecularDynamics.Trajectory import sorted_atoms
from MDANSE.App.GUI.Framework.Plugins.Plugin import ComponentPlugin
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
from MDANSE.App.GUI.ComboWidgets.UserDefinitionsPanel import UserDefinitionsPanel
from MDANSE.MolecularDynamics.Trajectory import sorted_atoms
class AtomSelectionPluginError(Error):
pass
......@@ -486,3 +486,4 @@ class AtomSelectionPlugin(ComponentPlugin):
self._parent.show_selected_atoms(self._selection)
print REGISTRY['plugin']
......@@ -27,15 +27,16 @@
'''
Created on Apr 14, 2015
@author: pellegrini
@author: Eric C. Pellegrini
'''
import os
import wx
from nMOLDYN import ELEMENTS, LOGGER, REGISTRY, USER_DEFINITIONS
from nMOLDYN.Externals.pubsub import pub as Publisher
from nMOLDYN.Framework.Plugins.AtomSelectionPlugin import AtomSelectionPlugin
from MDANSE import ELEMENTS, LOGGER, REGISTRY
from MDANSE.Externals.pubsub import pub as Publisher
from MDANSE.App.GUI.Framework.Plugins.AtomSelectionPlugin import AtomSelectionPlugin
class AtomTransmutationPlugin(AtomSelectionPlugin):
......@@ -85,8 +86,8 @@ class AtomTransmutationPlugin(AtomSelectionPlugin):
expression=self._expression,
indexes=self._selection,
element=element)
USER_DEFINITIONS[name] = ud
USER_DEFINITIONS.save()
UD_STORE[name] = ud
UD_STORE.save()
Publisher.sendMessage("new_transmutation", message = (path, name))
\ No newline at end of file
......@@ -37,7 +37,7 @@ import wx.aui as wxaui
from MDANSE import LOGGER, REGISTRY, UD_STORE
from MDANSE.Externals.pubsub import pub
from MDANSE.App.GUI.Framework.Plugins.Plugin import ComponentPlugin
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
from MDANSE.App.GUI.ComboWidgets.UserDefinitionsPanel import UserDefinitionsPanel
from MDANSE.MolecularDynamics.Trajectory import find_atoms_in_molecule, get_chemical_objects_dict
......
......@@ -37,7 +37,7 @@ import wx.aui as wxaui
from MDANSE import LOGGER, REGISTRY, UD_STORE
from MDANSE.Externals.pubsub import pub
from MDANSE.App.GUI.Framework.Plugins.Plugin import ComponentPlugin
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
from MDANSE.App.GUI.ComboWidgets.UserDefinitionsPanel import UserDefinitionsPanel
from MDANSE.MolecularDynamics.Trajectory import find_atoms_in_molecule, get_chemical_objects_dict
......
......@@ -33,7 +33,7 @@ Created on Apr 14, 2015
import wx
import wx.aui as aui
from MDANSE.App.GUI.Framework.Plugins.Plugin import ComponentPlugin
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
class DataInfoPlugin(ComponentPlugin):
......
......@@ -39,7 +39,7 @@ import numpy
from Scientific.IO.NetCDF import NetCDFFile
from MDANSE.App.GUI.Framework.Plugins.Plugin import ComponentPlugin
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
from MDANSE.Core.Error import Error
class DensitySuperpositionError(Error):
......
......@@ -30,7 +30,7 @@ Created on Apr 14, 2015
@author: pellegrini
'''
from MDANSE.App.GUI.Framework.Plugins.Plugin import DataPlugin
from MDANSE.App.GUI.Framework.Plugins.DataPlugin import DataPlugin
class EmptyDataPlugin(DataPlugin):
......
......@@ -27,7 +27,7 @@
'''
Created on Apr 14, 2015
@author: pellegrini
@author: Eric C. ellegrini
'''
import os
......@@ -41,7 +41,9 @@ import wx.aui as aui
from MDANSE import PLATFORM,REGISTRY
from MDANSE.Externals.pubsub import pub
from MDANSE.App.GUI.Framework.Plugins.Plugin import ComponentPlugin
from MDANSE.App.GUI.ComboWidgets.ConfigurationPanel import ConfigurationPanel
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
class JobPlugin(ComponentPlugin):
......@@ -51,17 +53,14 @@ class JobPlugin(ComponentPlugin):
ComponentPlugin.__init__(self, parent, size=wx.Size(800,400), **kwargs)
def build_panel(self):
self._main = wx.ScrolledWindow(self, wx.ID_ANY, size=self.GetSize())
self._main.SetScrollbars(pixelsPerUnitX= 20, pixelsPerUnitY=20, noUnitsX=500, noUnitsY=500)
mainSizer = wx.BoxSizer(wx.VERTICAL)
from nMOLDYN.GUI.Widgets.ConfigurationPanel import ConfigurationPanel
self._parametersPanel = ConfigurationPanel(self._main, self._job.configuration)
self._parametersPanel = ConfigurationPanel(self._main, self._job)
sb = wx.StaticBox(self._main, wx.ID_ANY)
sbSizer = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
......@@ -93,7 +92,6 @@ class JobPlugin(ComponentPlugin):
self.Bind(wx.EVT_BUTTON, self.on_save, saveButton)
self.Bind(wx.EVT_BUTTON, self.on_run, runButton)
def on_help(self, event):
from nMOLDYN.GUI.Widgets.JobHelpFrame import JobHelpFrame
......
......@@ -43,10 +43,10 @@ from MMTK.Trajectory import Trajectory
from MDANSE import ELEMENTS, LOGGER
from MDANSE.Core.Error import Error
from MDANSE.Extensions import fast_calculation
from MDANSE.Externals.pubsub import pub as Publisher
from MDANSE.Externals.pubsub import pub
from MDANSE.MolecularDynamics.Trajectory import sorted_atoms
from MDANSE.App.GUI.Framework.Plugins.Plugin import ComponentPlugin
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
# The colour for a selected atom (R,G,B,Alpha).
RGB_COLOURS = {}
......@@ -145,12 +145,11 @@ class SelectionBox(vtk.vtkBoxWidget):
self.viewer.pick_atoms(selection)
class MolecularViewerPanel(ComponentPlugin):
'''
This class sets up a molecular viewer using vtk functionnalities.
'''
type = "molecular_viewer"
label = "Molecular Viewer"
......@@ -166,7 +165,6 @@ class MolecularViewerPanel(ComponentPlugin):
ComponentPlugin.__init__(self, parent, *args, **kwargs)
def build_panel(self):
self._iren = MyRenderWindowInteractor(self, wx.ID_ANY, size=self.GetSize())
......@@ -196,7 +194,7 @@ class MolecularViewerPanel(ComponentPlugin):
self._iren.AddObserver("CharEvent", self.on_keyboard_input)
self._iren.AddObserver("LeftButtonPressEvent", self.emulate_focus)
Publisher.subscribe(self.check_switch_consistancy, ('Switch'))
pub.subscribe(self.check_switch_consistancy, ('Switch'))
self._iren.Bind(wx.EVT_CONTEXT_MENU, self.on_show_popup_menu)
......@@ -222,7 +220,6 @@ class MolecularViewerPanel(ComponentPlugin):
self.SetFocusIgnoringChildren()
def del_surface(self):
del self._surface
self._surface = None
......@@ -240,15 +237,13 @@ class MolecularViewerPanel(ComponentPlugin):
def emulate_focus(self, obj, event):
self.SetFocusIgnoringChildren()
def close(self):
self.clear_universe()
Publisher.unsubscribe(self.check_switch_consistancy, "Switch")
pub.unsubscribe(self.check_switch_consistancy, "Switch")
def set_trajectory(self, trajectory, selection=None, frame=0):
if not isinstance(trajectory,Trajectory):
......@@ -287,7 +282,7 @@ class MolecularViewerPanel(ComponentPlugin):
self._trajectoryLoaded = True
Publisher.sendMessage(('Load trajectory'), message = self)
pub.sendMessage(('Load trajectory'), message = self)
def color_string_to_RGB(self, s):
......@@ -318,7 +313,6 @@ class MolecularViewerPanel(ComponentPlugin):
return colours, lut
def enable_picking(self):
self.__pickerObserverId = self._iren.AddObserver("LeftButtonPressEvent", self.on_pick)
......@@ -333,7 +327,6 @@ class MolecularViewerPanel(ComponentPlugin):
self._iren.RemoveObserver(self.__pickerObserverId)
self.__pickerObserverId = None
def on_show_popup_menu(self, event):
popupMenu = wx.Menu()
......@@ -387,7 +380,6 @@ class MolecularViewerPanel(ComponentPlugin):
def animation_loop(self):
return self._animationLoop
@property
def surface(self):
return self._surface
......@@ -400,17 +392,14 @@ class MolecularViewerPanel(ComponentPlugin):
def current_frame(self):
return self._currentFrame
@property
def iren(self):
return self._iren
@property
def max_laps(self):
return self._maxLaps
@property
def n_frames(self):
return self._nFrames
......@@ -419,24 +408,20 @@ class MolecularViewerPanel(ComponentPlugin):
def n_atoms(self):
return self._nAtoms
@property
def selection_box(self):
return self.__selectionBox
@property
def timer_interval(self):
return self._timerInterval
@property
def trajectory(self):
return self._trajectory
@property
def trajectory_loaded(self):
......@@ -447,7 +432,6 @@ class MolecularViewerPanel(ComponentPlugin):
return self.__pickedAtoms
def change_frame_rate(self, laps):
if not self._trajectoryLoaded:
......@@ -457,7 +441,6 @@ class MolecularViewerPanel(ComponentPlugin):
if self._animationLoop:
self._iren.CreateRepeatingTimer(self._timerInterval)
def create_timer(self):
self._iren.Initialize()
......@@ -466,7 +449,6 @@ class MolecularViewerPanel(ComponentPlugin):
return timerId
def set_frame(self, frame):
if not self._trajectoryLoaded:
......@@ -477,28 +459,22 @@ class MolecularViewerPanel(ComponentPlugin):
self._timerCounter = frame
self.set_configuration(frame)
def on_clear_labels(self, event=None):
pass
def on_clear_selection(self, event=None):
pass
def on_export(self, event=None):
pass
def on_hide_labels(self, event=None):
pass
def on_select_all(self, event=None):
pass
def on_show_all_atoms(self, event=None):
pass
......@@ -506,19 +482,15 @@ class MolecularViewerPanel(ComponentPlugin):
def on_show_labels(self, event=None):
pass
def on_show_unselected_atoms(self, event=None):
pass
def on_show_selected_atoms(self, event=None):
pass
def on_undo_exclude(self, event=None):
pass
def on_undo_include(self, event=None):
pass
......@@ -556,7 +528,6 @@ class MolecularViewerPanel(ComponentPlugin):
elif key == " ":
self.start_stop_animation()
def on_timer(self, obj=None, event=None):
if self._iren._timer.IsRunning():
......@@ -565,8 +536,7 @@ class MolecularViewerPanel(ComponentPlugin):
self.set_configuration(self._timerCounter)
self._timerCounter += 1
Publisher.sendMessage(("On timer"), message = self)
pub.sendMessage(("On timer"), message = self)
def set_rendering_mode(self, mode):
if not self._trajectoryLoaded:
......@@ -576,7 +546,6 @@ class MolecularViewerPanel(ComponentPlugin):
self._rendmod=mode
self.set_configuration(self._currentFrame)
def goto_first_frame(self):
if not self._trajectoryLoaded:
......@@ -586,8 +555,7 @@ class MolecularViewerPanel(ComponentPlugin):
self._timerCounter = 0
self.set_configuration(0)
def goto_last_frame(self):
if not self._trajectoryLoaded:
......@@ -597,19 +565,16 @@ class MolecularViewerPanel(ComponentPlugin):
last = self._nFrames-1
self._timerCounter = last
self.set_configuration(last)
def show_hide_selection_box(self):
if self._trajectoryLoaded:
self.__selectionBox.on_off()
def set_timer_interval(self, timerInterval):
self._timerInterval = timerInterval
def on_pick(self, obj, evt=None):
if not self._trajectoryLoaded:
......@@ -647,14 +612,12 @@ class MolecularViewerPanel(ComponentPlugin):
self.__pickedAtoms.symmetric_difference_update(atomsList)
Publisher.sendMessage(('select atoms'), message = list(self.__pickedAtoms))
pub.sendMessage(('select atoms'), message = list(self.__pickedAtoms))
def show_selected_atoms(self, atomsList):
self.show_selection(atomsList)
def clear_selection(self):
if not self._trajectoryLoaded:
......@@ -669,7 +632,6 @@ class MolecularViewerPanel(ComponentPlugin):
self._iren.Render()
def show_selection(self, selection):
if not self._trajectoryLoaded:
......@@ -696,13 +658,11 @@ class MolecularViewerPanel(ComponentPlugin):
self._iren.TimerEventResetsTimerOn()
self._animationLoop = True
def stop_animation(self, event=None):
if self._trajectoryLoaded:
self._iren.TimerEventResetsTimerOff()
self._animationLoop = False
def start_stop_animation(self, event=None, check=True):
if not self._trajectoryLoaded:
......@@ -716,9 +676,9 @@ class MolecularViewerPanel(ComponentPlugin):
else:
self.stop_animation()
if check:
Publisher.sendMessage(('Switch'), message = self)
pub.sendMessage(('Switch'), message = self)
Publisher.sendMessage(('Animation'), message = self)
pub.sendMessage(('Animation'), message = self)
def check_switch_consistancy(self, message):
......@@ -753,12 +713,10 @@ class MolecularViewerPanel(ComponentPlugin):
return radius, color, int(idx)
def this_atom_is_selected(self,pid):
_, _, pid = self.get_atom_props(pid)
return self.atomsColours[pid]==RGB_COLOURS["selection"][0]
def pick_atom(self,pid):
if self.this_atom_is_selected(pid):
self.unpick_atom(pid)
......@@ -980,8 +938,7 @@ class MolecularViewerPanel(ComponentPlugin):
# rendering
self._iren.Render()
def set_configuration(self, frame):
'''
Sets a new configuration.
......@@ -1049,7 +1006,6 @@ def ndarray_to_vtkcellarray(array):
return bonds
def get_trajectory_filename():
filters = 'NC file (*.nc)|*.nc|All files (*.*)|*.*'
......
import numpy as np
#MDANSE : Molecular Dynamics Analysis for Neutron Scattering Experiments
#------------------------------------------------------------------------------------------
#Copyright (C)
#2015- Eric C. Pellegrini Institut Laue-Langevin
#BP 156
#6, rue Jules Horowitz
#38042 Grenoble Cedex 9
#France
#pellegrini[at]ill.fr
#goret[at]ill.fr
#aoun[at]ill.fr
#
#This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU Lesser General Public
#License as published by the Free Software Foundation; either
#version 2.1 of the License, or (at your option) any later version.
#
#This library is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#Lesser General Public License for more details.
#
#You should have received a copy of the GNU Lesser General Public
#License along with this library; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
'''
Created on Apr 15, 2015
@author: Gael Goret