Commit 47d176d4 authored by eric pellegrini's avatar eric pellegrini

Reintroduced and refactored some plugins

parent 7b12be21
......@@ -25,57 +25,47 @@
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
'''
Created on Mar 27, 2015
Created on Apr 14, 2015
@author: pellegrini
'''
import time
import wx
class UserDefinable(dict):
'''
Base class for user definable objects. User definable objects are objects used in MDANSE for
storing information that can be reused later when setting up jobs (e.g. k-vectors defintion,
atom selection ...). A user definable object is a dictionary with a predefined set of keys that
depends on the user definable object. Object serialization is the underlying mechanism used to
save those objets and is done using cPickle module.
'''
def __init__(self, target):
'''
The constructor
'''
class UserDefinitionsPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
self._target = target
wx.Panel.__init__(self, parent, wx.ID_ANY, *args, **kwargs)
self._creationTime = time.ctime()
self._parent = parent
self._definition = {}
@property
def target(self):
sb = wx.StaticBox(self, wx.ID_ANY)
actionsSizer = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
self._cancelButton = wx.Button(self, wx.ID_ANY, label="Cancel")
self._udName = wx.TextCtrl(self, wx.ID_ANY, style = wx.TE_PROCESS_ENTER)
self._saveButton = wx.Button(self, wx.ID_ANY, label="Save")
return self._target
@property
def creationTime(self):
actionsSizer.Add(self._cancelButton, 0, wx.ALL, 5)
actionsSizer.Add(self._udName, 1, wx.ALL|wx.EXPAND, 5)
actionsSizer.Add(self._saveButton, 0, wx.ALL, 5)
return self._creationTime
@property
def definition(self):
self.SetSizer(actionsSizer)
return self._definition
self.Layout()
self.Bind(wx.EVT_BUTTON, self.on_close, self._cancelButton)
self.Bind(wx.EVT_BUTTON, self.on_save, self._saveButton)
def __str__(self):
'''
Return the informal representation of a user definable object
'''
def get_selection_name(self):
if not self._definition:
return "Not yet defined"
return self._udName.GetValue()
def on_close(self, event):
info = ["Created on: %s\n" % self._creationTime] + ["%s:\n%s\n" % (k,v) for k,v in self._definition.iteritems()]
self._parent.Parent.on_close()
def on_save(self, event):
return "".join(info)
\ No newline at end of file
self._parent.Parent.on_save()
\ No newline at end of file
......@@ -25,7 +25,7 @@
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
'''
Created on Apr 10, 2015
Created on Apr 14, 2015
@author: pellegrini
'''
......
......@@ -25,7 +25,7 @@
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
'''
Created on Apr 10, 2015
Created on Apr 14, 2015
@author: pellegrini
'''
......
#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 14, 2015
@author: pellegrini
'''
import wx
import wx.aui as wxaui
from MDANSE.Externals.pubsub import pub as Publisher
from MDANSE.App.GUI.Icons import ICONS
from MDANSE.App.GUI.Framework.Plugins.ComponentPlugin import ComponentPlugin
class AnimationPlugin(ComponentPlugin):
type = "animation"
label = "Animation"
ancestor = "molecular_viewer"
def __init__(self, parent, *args, **kwargs):
ComponentPlugin.__init__(self, parent, size=(-1,50), *args, **kwargs)
def build_panel(self):
panel = wx.Panel(self, wx.ID_ANY, size=self.GetSize())
controlSizer = wx.BoxSizer(wx.HORIZONTAL)
firstButton = wx.BitmapButton(panel, wx.ID_ANY, ICONS["first",32,32])
self.playPause = wx.BitmapButton(panel, wx.ID_ANY, ICONS["play",32,32])
lastButton = wx.BitmapButton(panel, wx.ID_ANY, ICONS["last",32,32])
self.frameSlider = wx.Slider(panel,id=wx.ID_ANY, value=0, minValue=0, maxValue=1, style=wx.SL_HORIZONTAL)
self.frameEntry = wx.TextCtrl(panel,id=wx.ID_ANY,value="0", size=(60,20), style= wx.SL_HORIZONTAL|wx.TE_PROCESS_ENTER)
speedBitmap = wx.StaticBitmap(panel,-1, ICONS["clock",42,42])
self.speedSlider = wx.Slider(panel,id=wx.ID_ANY,value=0,minValue=0,maxValue=1,style=wx.SL_HORIZONTAL)
self.speedSlider.SetRange(0,self._parent.max_laps)
speed = self._parent.max_laps - self._parent.timer_interval
self.speedSlider.SetValue(speed)
self.speedEntry = wx.TextCtrl(panel,id=wx.ID_ANY,value=str(speed), size=(60,20), style= wx.SL_HORIZONTAL|wx.TE_PROCESS_ENTER)
controlSizer.Add(firstButton, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL,5)
controlSizer.Add(self.playPause, 0, wx.ALIGN_CENTER_VERTICAL)
controlSizer.Add(lastButton, 0, wx.ALIGN_CENTER_VERTICAL)
controlSizer.Add((5, -1), 0, wx.ALIGN_RIGHT)
controlSizer.Add(self.frameSlider, 3, wx.ALIGN_CENTER_VERTICAL)
controlSizer.Add(self.frameEntry, 0, wx.ALIGN_CENTER_VERTICAL)
controlSizer.Add((5, -1), 0, wx.ALIGN_RIGHT)
controlSizer.Add(speedBitmap, 0 , wx.ALIGN_CENTER_VERTICAL)
controlSizer.Add((5, -1), 0, wx.ALIGN_RIGHT)
controlSizer.Add(self.speedSlider, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL)
controlSizer.Add(self.speedEntry, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL,5)
panel.SetSizer(controlSizer)
controlSizer.Fit(panel)
panel.Layout()
self._mgr.AddPane(panel, wxaui.AuiPaneInfo().Center().Dock().CaptionVisible(False).CloseButton(False).MinSize(self.GetSize()))
self._mgr.Update()
self.Bind(wx.EVT_SCROLL, self.on_frame_sliding, self.frameSlider)
self.Bind(wx.EVT_TEXT_ENTER, self.on_set_frame, self.frameEntry)
self.Bind(wx.EVT_SLIDER, self.on_change_frame_rate, self.speedSlider)
self.Bind(wx.EVT_TEXT_ENTER, self.on_set_speed, self.speedEntry)
self.Bind(wx.EVT_BUTTON, self.on_start_stop_animation, self.playPause)
self.Bind(wx.EVT_BUTTON, self.on_goto_first_frame, firstButton)
self.Bind(wx.EVT_BUTTON, self.on_goto_last_frame, lastButton)
Publisher.subscribe(self.on_update_animation_icon, ('Animation'))
Publisher.subscribe(self.on_set_up_frame_slider, ('Load trajectory'))
Publisher.subscribe(self.on_timer, ('On timer'))
def plug(self):
self._parent._mgr.GetPane(self).LeftDockable(False).RightDockable(False).Dock().Bottom().CloseButton(True)
self._parent._mgr.Update()
Publisher.sendMessage(('Load trajectory'), message = self.parent)
def on_change_frame_rate(self, event=None):
laps = self.speedSlider.GetValue()
self._parent.change_frame_rate(laps)
self.speedEntry.SetValue(str(self.speedSlider.GetValue()))
def on_frame_sliding(self, event=None):
frame = self.frameSlider.GetValue()
self._parent.set_frame(frame)
frame = self._parent.current_frame
self.frameEntry.SetValue(str(frame))
self.frameSlider.SetValue(frame)
def on_goto_first_frame(self, event=None):
self._parent.goto_first_frame()
self.frameEntry.SetValue(str(0))
self.frameSlider.SetValue(0)
def on_goto_last_frame(self, event=None):
self._parent.goto_last_frame()
self.frameEntry.SetValue(str(self._parent.n_frames-1))
self.frameSlider.SetValue(self._parent.n_frames-1)
def on_set_speed(self, event=None):
self.speedSlider.SetValue(int(self.speedEntry.GetValue()))
self._parent.change_frame_rate()
def on_timer(self, message):
mv = message
if not self.has_parent(mv):
return
frame = mv.current_frame
self.frameEntry.SetValue(str(frame))
self.frameSlider.SetValue(int(frame))
def on_set_frame(self, event=None):
frame = int(self.frameEntry.GetValue())
self._parent.set_configuration(frame)
self.frameSlider.SetValue(frame)
def on_start_stop_animation(self, event=None):
self._parent.start_stop_animation()
def on_update_animation_icon(self, message):
mv = message
if not self.has_parent(mv):
return
if mv.animation_loop:
self.playPause.SetBitmapLabel(ICONS["pause",32,32])
else:
self.playPause.SetBitmapLabel(ICONS["play",32,32])
def on_set_up_frame_slider(self, message):
mv = message
if not self.has_parent(mv):
return
self.frameSlider.SetRange(0,self._parent.n_frames-1)
\ No newline at end of file
This diff is collapsed.
#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 Mar 27, 2015
@author: pellegrini
'''
import time
from MDANSE import REGISTRY
from MDANSE.Core.Error import Error
class UserDefinableError(Error):
pass
class IUserDefinable(dict):
'''
Base class for user definable objects. User definable objects are objects used in MDANSE for
storing information that can be reused later when setting up jobs (e.g. k-vectors defintion,
atom selection ...). A user definable object is a dictionary with a predefined set of keys that
depends on the user definable object. Object serialization is the underlying mechanism used to
save those objets and is done using cPickle module.
'''
# Any user definable object will be registered at MDANSE startup.
__metaclass__ = REGISTRY
# The base class has no type (hence it will not be registered)
type = "user_definable"
# The base class has no predefined set keywords
_keywords = []
def __init__(self, target, **kwargs):
'''
The constructor
'''
self._target = target
self._creationTime = time.ctime()
self._keywords = self._keywords
for k in self._keywords:
try:
self[k] = kwargs[k]
except KeyError:
raise UserDefinableError("Incomplete user definable object: missing %r key" % k)
@property
def target(self):
return self._target
@property
def keywords(self):
return self._keywords
@property
def creationTime(self):
return self._creationTime
def __setitem__(self, item, value):
# It is not possible to set directly a key of a user definable object
if item in self._keywords:
super(IUserDefinable,self).__setitem__(item, value)
def __str__(self):
'''
Return the informal representation of a user definable object
'''
info = ["Created on: %s\n" % self.creationTime] + ["%s:\n%s\n" % (k,self[k]) for k in self._keywords]
return "".join(info)
\ No newline at end of file
#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 14, 2015
@author: 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
class AtomTransmutationPlugin(AtomSelectionPlugin):
type = "atom_transmutation"
label = "Atom transmutation"
ancestor = "molecular_viewer"
def build_panel(self):
AtomSelectionPlugin.build_panel(self)
label = wx.StaticText(self._mainPanel, wx.ID_ANY, style=wx.ALIGN_LEFT, label="Transmute to")
self._elements = wx.Choice(self._mainPanel, wx.ID_ANY, choices=ELEMENTS.elements)
self._elements.SetStringSelection("H[2]")
self._selectionExpressionSizer.Add(label, pos=(1,0), flag=wx.ALIGN_CENTER_VERTICAL)
self._selectionExpressionSizer.Add(self._elements, pos=(1,1), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)
self._mainPanel.Layout()
def on_save(self, event=None):
'''
Event handler: validate the selection.
@param event: the event binder
@type event: wx event
'''
if not self._selection:
LOGGER("The current selection is empty", "warning", ["dialog"])
return
name = self._udPanel.get_selection_name()
if not name:
LOGGER("You must enter a value for the user definition", "error", ["dialog"])
return
path = os.path.basename(self.parent.trajectory.filename)
element = self._elements.GetStringSelection()
ud = REGISTRY['userdefinable']['atom_transmutation'](path,
expression=self._expression,
indexes=self._selection,
element=element)
USER_DEFINITIONS[name] = ud
USER_DEFINITIONS.save()
Publisher.sendMessage("new_transmutation", message = (path, name))
\ No newline at end of file
#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 14, 2015
@author: pellegrini
'''
import os
import wx
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.ComboWidgets.UserDefinitionsPanel import UserDefinitionsPanel
from MDANSE.MolecularDynamics.Trajectory import find_atoms_in_molecule, get_chemical_objects_dict
class AxisSelectionPlugin(ComponentPlugin):
type = "axis_selection"
label = "Axis selection"
ancestor = "molecular_viewer"
def __init__(self, parent, *args, **kwargs):
ComponentPlugin.__init__(self, parent, size=(-1,50), *args, **kwargs)
def build_panel(self):
panel = wx.ScrolledWindow(self, wx.ID_ANY, size=self.GetSize())
panel.SetScrollbars(20,20,50,50)
bSizer = wx.BoxSizer(wx.VERTICAL)
sb = wx.StaticBox(panel, wx.ID_ANY, label = "Axis definition")
sbSizer = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
gbSizer = wx.GridBagSizer(5,5)
label1 = wx.StaticText(panel, wx.ID_ANY, label="Molecules")
label2 = wx.StaticText(panel, wx.ID_ANY, label="Endpoint 1")
label3 = wx.StaticText(panel, wx.ID_ANY, label="Endpoint 2")
gbSizer.Add(label1, (0,0), flag=wx.EXPAND)
gbSizer.Add(label2, (0,1), flag=wx.EXPAND)
gbSizer.Add(label3, (0,2), flag=wx.EXPAND)
self._moleculeNames = wx.ListBox(panel, wx.ID_ANY, style = wx.LB_SINGLE|wx.LB_NEEDED_SB)
self._atomNames1 = wx.ListBox(panel, wx.ID_ANY, style = wx.LB_MULTIPLE|wx.LB_NEEDED_SB)
self._atomNames2 = wx.ListBox(panel, wx.ID_ANY, style = wx.LB_MULTIPLE|wx.LB_NEEDED_SB)
gbSizer.Add(self._moleculeNames, (1,0), flag=wx.EXPAND)
gbSizer.Add(self._atomNames1 , (1,1), flag=wx.EXPAND)
gbSizer.Add(self._atomNames2 , (1,2), flag=wx.EXPAND)
gbSizer.AddGrowableRow(1)
gbSizer.AddGrowableCol(0)
gbSizer.AddGrowableCol(1)
gbSizer.AddGrowableCol(2)
sbSizer.Add(gbSizer, 1, wx.EXPAND|wx.ALL, 5)
bSizer.Add(sbSizer, 1, wx.EXPAND|wx.ALL, 5)
self._udPanel = UserDefinitionsPanel(panel)
bSizer.Add(self._udPanel, 0, wx.EXPAND|wx.ALL, 5)
panel.SetSizer(bSizer)