Commit 6f9fe9e5 authored by eric pellegrini's avatar eric pellegrini

Added a dialog for setting a new MMTK entry from the database

The MDANSE database is now append instead of prended to the MMTK
database search path
Removed unused method
parent 9e11a155
Pipeline #419 skipped
......@@ -47,44 +47,6 @@ class ElementsDatabaseError(Error):
'''
pass
def create_mmtk_atom_entry(filename, name=None, symbol=None, mass=1.0, **props):
'''
Creates a new atom in mmtk database.
:param name: the basename of the file in which the atom entry will be stored
:type name: str
:param symbol:
:type symbol: str
:param mass: the mass of the atom
:type mass: float
:return: the absolute path of the file that stores the newly created atom
:rtype: str
'''
# Every entry of the MMTK database is searched in lower case.
filename = filename.lower()
if name is None:
name = filename
if symbol is None:
symbol = filename
filename = os.path.join(PLATFORM.local_mmtk_database_directory(),"Atoms", name)
f = open(filename, 'w')
# This three entries are compulsory for a MMTK.Atom to be valid
f.write('name = "%s"' % name)
f.write('\n\nsymbol = "%s"' % symbol)
f.write('\n\nmass = %s' % mass)
for k,v in props.items():
f.write('\n\n%s = %r' % (k,v))
f.close()
return filename
def indent(elem, level=0):
"""
Produces a pretty indented XML tree.
......@@ -384,14 +346,12 @@ class ElementsDatabase(object):
except:
self._load(ElementsDatabase._DEFAULT_DATABASE)
def add_element(self, ename, createMMTKEntry=False):
def add_element(self, ename):
'''
Add a new element in the elements database.
:param ename: the name of the element to add
:type ename: str
:param save: if True the elements database will be saved
:type save: bool
'''
ename = ename.lower()
......@@ -728,18 +688,5 @@ class ElementsDatabase(object):
'''
self.export("csv",ElementsDatabase._USER_DATABASE)
def rebuild_mmtk_database(self):
'''
Rebuild the whole MMTK Atoms database from the MDANSE elements database.
'''
for name,props in self._data.items():
filename = os.path.join(PLATFORM.local_mmtk_database_directory(),"Atoms", name)
f = open(filename, 'w')
f.write('name = "%s"\n\n' % props["name"])
f.write('symbol = "%s"\n\n' % name)
f.write('mass = %s' % props["atomic_weight"])
f.close()
ELEMENTS = ElementsDatabase()
......@@ -49,6 +49,8 @@ class MMTKTrajectoryInputData(InputFileData):
except IOError as e:
raise InputDataError(str(e))
except ValueError as e:
raise InputDataError(str(e))
self._data = traj
......
......@@ -36,9 +36,136 @@ import wx
import wx.grid as wxgrid
from MDANSE import ELEMENTS
from MDANSE.Core.Error import Error
from MDANSE.Core.Singleton import Singleton
class PropertyDialog(wx.Dialog):
def create_mmtk_atom_entry(entryname, name, symbol, mass, **props):
'''
Creates a new atom in mmtk database.
:param name: the basename of the file in which the atom entry will be stored
:type name: str
:param symbol:
:type symbol: str
:param mass: the mass of the atom
:type mass: float
:return: the absolute path of the file that stores the newly created atom
:rtype: str
'''
# Every entry of the MMTK database is searched in lower case.
entryname = entryname.lower()
filename = os.path.join(PLATFORM.local_mmtk_database_directory(),"Atoms", entryname)
f = open(filename, 'w')
# This three entries are compulsory for a MMTK.Atom to be valid
f.write('name = "%s"' % name)
f.write('\n\nsymbol = "%s"' % symbol)
f.write('\n\nmass = %f' % mass)
for k,v in props.items():
f.write('\n\n%s = %r' % (k,v))
f.close()
return filename
class ElementsDatabaseError(Error):
pass
class NewElementDialog(wx.Dialog):
"""
This class pops up a dialog that prompts the user for registering a new element in the database.
"""
def __init__(self,*args,**kwargs):
"""
The constructor.
"""
# The base class constructor
wx.Dialog.__init__(self,*args,**kwargs)
self.Center()
panel = wx.Panel(self,wx.ID_ANY)
staticLabel0 = wx.StaticText(panel, -1, "Enter element settings")
subPanel = wx.Panel(panel,wx.ID_ANY)
staticLabel1 = wx.StaticText(subPanel, wx.ID_ANY, "Entry name")
self._entry = wx.TextCtrl(subPanel, wx.ID_ANY)
staticLabel2 = wx.StaticText(subPanel, wx.ID_ANY, "Atom name")
self._name = wx.TextCtrl(subPanel, id = wx.ID_ANY)
staticLabel3 = wx.StaticText(subPanel, wx.ID_ANY, "Atom symbol")
self._symbol = wx.TextCtrl(subPanel, wx.ID_ANY)
staticLabel4 = wx.StaticText(subPanel, wx.ID_ANY, "Atom Mass (uma)")
self._mass = wx.TextCtrl(subPanel, id = wx.ID_ANY)
staticLine = wx.StaticLine(self, wx.ID_ANY)
buttonPanel = wx.Panel(self,wx.ID_ANY)
ok = wx.Button(buttonPanel, wx.ID_OK, "OK")
ok.SetDefault()
cancel = wx.Button(buttonPanel, wx.ID_CANCEL, "Cancel")
panelSizer = wx.BoxSizer(wx.VERTICAL)
panelSizer.Add(staticLabel0, 0, wx.ALL|wx.ALIGN_LEFT, 5)
subsizer = wx.GridBagSizer(5,5)
subsizer.AddGrowableCol(1)
subsizer.Add(staticLabel1,pos=(0,0),flag=wx.ALIGN_CENTER_VERTICAL)
subsizer.Add(self._entry ,pos=(0,1),flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
subsizer.Add(staticLabel2,pos=(1,0),flag=wx.ALIGN_CENTER_VERTICAL)
subsizer.Add(self._name,pos=(1,1),flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
subsizer.Add(staticLabel3,pos=(2,0),flag=wx.ALIGN_CENTER_VERTICAL)
subsizer.Add(self._symbol,pos=(2,1),flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
subsizer.Add(staticLabel4,pos=(3,0),flag=wx.ALIGN_CENTER_VERTICAL)
subsizer.Add(self._mass,pos=(3,1),flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
subPanel.SetSizer(subsizer)
panelSizer.Add(subPanel, 0, wx.ALL|wx.EXPAND, 5)
panel.SetSizer(panelSizer)
btnsizer = wx.StdDialogButtonSizer()
btnsizer.AddButton(cancel)
btnsizer.AddButton(ok)
btnsizer.Realize()
buttonPanel.SetSizer(btnsizer)
dlgsizer = wx.BoxSizer(wx.VERTICAL)
dlgsizer.Add(panel, 1, wx.ALL|wx.EXPAND, 5)
dlgsizer.Add(staticLine, 0, wx.ALL|wx.EXPAND, 5)
dlgsizer.Add(buttonPanel, 0, wx.ALL|wx.ALIGN_RIGHT|wx.EXPAND, 5)
# Bind the top sizer to the dialog.
self.SetSizer(dlgsizer)
def GetValue(self, event=None):
"""
Handler called when the user clicks on the OK button of the property dialog.
"""
entry = str(self._entry.GetValue().strip())
if not entry:
raise ElementsDatabaseError("Empty entry name")
name = str(self._name.GetValue().strip())
if not name:
raise ElementsDatabaseError("Empty name")
symbol = str(self._symbol.GetValue().strip())
if not symbol:
raise ElementsDatabaseError("Empty symbol")
try:
mass = float(self._mass.GetValue().strip())
except ValueError:
raise ElementsDatabaseError("Invalid mass value")
return entry,name,symbol,mass
class NewPropertyDialog(wx.Dialog):
"""
This class pops up a dialog that prompts the user for registering a new property in the database.
"""
......@@ -60,7 +187,7 @@ class PropertyDialog(wx.Dialog):
subPanel = wx.Panel(panel,wx.ID_ANY)
staticLabel1 = wx.StaticText(subPanel, wx.ID_ANY, "Name")
self.name = wx.TextCtrl(subPanel, wx.ID_ANY)
staticLabel2 = wx.StaticText(subPanel, wx.ID_ANY, "Default value")
staticLabel2 = wx.StaticText(subPanel, wx.ID_ANY, "Numeric type")
self.propertyType = wx.ComboBox(subPanel, id = wx.ID_ANY, choices=ELEMENTS._TYPES.keys(), style=wx.CB_READONLY)
staticLine = wx.StaticLine(self, wx.ID_ANY)
......@@ -139,9 +266,17 @@ class Database(wxgrid.PyGridTableBase):
self.notify_grid(wxgrid.GRIDTABLE_NOTIFY_COLS_APPENDED, 1)
def add_row(self, ename):
ELEMENTS.add_element(ename)
def add_row(self, entry, name, symbol, mass):
if ELEMENTS.has_element(entry):
return
create_mmtk_atom_entry(entry, name, symbol, mass)
ELEMENTS.add_element(entry)
ELEMENTS[entry,"name"] = name
ELEMENTS[entry,"symbol"] = symbol
ELEMENTS[entry,"atomic_weight"] = mass
self.notify_grid(wxgrid.GRIDTABLE_NOTIFY_ROWS_APPENDED, 1)
......@@ -210,6 +345,8 @@ class ElementsDatabaseEditor(wx.Frame):
self.SetSize((800,400))
self.Bind(wx.EVT_CONTEXT_MENU, self.on_show_popup_menu)
self.Bind(wx.EVT_CLOSE, self.on_close)
def build_menu(self):
......@@ -253,6 +390,15 @@ class ElementsDatabaseEditor(wx.Frame):
self.PopupMenu(menu)
menu.Destroy()
def on_close(self,event):
d = wx.MessageDialog(None, 'This will close the database editor. Continue ?', 'Question', wx.YES_NO|wx.YES_DEFAULT|wx.ICON_WARNING)
if d.ShowModal() == wx.ID_NO:
return
self.Destroy()
def on_edit_cell(self,event):
......@@ -265,26 +411,23 @@ class ElementsDatabaseEditor(wx.Frame):
Handler called when the user add new elements to the database.
"""
d = wx.TextEntryDialog(self,"Enter element id","add element")
d = NewElementDialog(self,title="Add element",size=(400,220))
# If the new element dialog is closed by clicking on OK.
if d.ShowModal() == wx.ID_CANCEL:
return
# Get rid of wxpython unicode string formatting
ename = str(d.GetValue())
if not ename:
return
self._database.add_row(ename)
entry,name,symbol,mass = d.GetValue()
self._database.add_row(entry,name,symbol,mass)
def on_add_property(self, message):
"""
Handler called when the user add a property to the database.
"""
d = PropertyDialog(self,title="Add property",size=(400,160))
d = NewPropertyDialog(self,title="Add property",size=(400,160))
if d.ShowModal() == wx.ID_CANCEL:
return
......
......@@ -190,6 +190,7 @@ class MainFrame(wx.Frame):
elementsDatabaseButton = self._toolbar.AddSimpleTool(wx.ID_ANY, ICONS["element",32,32], 'Launch the elements database editor')
plotButton = self._toolbar.AddSimpleTool(wx.ID_ANY,ICONS["plot",32,32], 'Launch the NetCDF plotter')
udButton = self._toolbar.AddSimpleTool(wx.ID_ANY,ICONS["user",32,32], 'Launch the user definitions editor')
atomButton = self._toolbar.AddSimpleTool(wx.ID_ANY, ICONS["atom",32,32], 'Create an atom database entry')
preferencesButton = self._toolbar.AddSimpleTool(wx.ID_ANY, ICONS["preferences",32,32], 'Launch the preferences editor')
registryButton = self._toolbar.AddSimpleTool(wx.ID_ANY, ICONS["registry",32,32], 'Inspect MDANSE classes framework')
templateButton = self._toolbar.AddSimpleTool(wx.ID_ANY, ICONS["template",32,32], 'Save a template for a new analysis')
......@@ -210,6 +211,7 @@ class MainFrame(wx.Frame):
self.Bind(wx.EVT_MENU, self.on_start_plotter, plotButton)
self.Bind(wx.EVT_MENU, self.on_set_preferences, preferencesButton)
self.Bind(wx.EVT_MENU, self.on_open_user_definitions, udButton)
self.Bind(wx.EVT_MENU, self.on_create_atom_database_entry, atomButton)
self.Bind(wx.EVT_MENU, self.on_open_classes_registry, registryButton)
self.Bind(wx.EVT_MENU, self.on_save_job_template, templateButton)
self.Bind(wx.EVT_MENU, self.on_about, aboutButton)
......@@ -268,6 +270,10 @@ or directly to the MDANSE mailing list:
d.ShowModal()
d.Destroy()
def on_create_atom_database_entry(self,event):
print "coucou"
def on_simple_help(self,event):
path = os.path.join(PLATFORM.doc_path(),'simple_help.txt')
......
......@@ -38,7 +38,7 @@ from MDANSE.Core.DataController import DATA_CONTROLLER
from MDANSE.Core.Platform import PLATFORM
from MDANSE.Core.ClassRegistry import ClassRegistry as REGISTRY
from MDANSE.Data.ElementsDatabase import ELEMENTS, create_mmtk_atom_entry
from MDANSE.Data.ElementsDatabase import ELEMENTS
from MDANSE.Core.Preferences import PREFERENCES
......@@ -48,49 +48,6 @@ import os
# MMTK imports.
from MMTK import Database
from MMTK.Database import path
from MMTK.Utility import checkURL, isURL, joinURL
def databasePath(filename, directory, try_direct = False):
if isURL(filename):
return filename
filename = os.path.expanduser(filename)
if try_direct and os.path.exists(filename):
return os.path.normcase(filename)
entries = None
dirname,basename = os.path.split(filename)
if dirname == '':
for p in path:
if isURL(p):
url = joinURL(p, directory+'/'+basename)
if checkURL(url):
entries = url
break
else:
full_name = os.path.join(os.path.join(p, directory), basename)
if os.path.exists(full_name):
entries = os.path.normcase(full_name)
break
if entries is None:
if directory == "Atoms":
ELEMENTS.add_element(basename)
ELEMENTS.save()
create_mmtk_atom_entry(basename)
return os.path.join(PLATFORM.local_mmtk_database_directory(),"Atoms", basename)
else:
raise IOError("Database entry %s/%s not found" % (directory, filename))
else:
return entries
# Add the path to the MDANSE database to complete the MMTK database.
Database.databasePath = databasePath
Database.path.insert(0,os.path.join(PLATFORM.package_directory(), 'Data'))
Database.path.insert(0,PLATFORM.local_mmtk_database_directory())
# The default databse is still the MMTK one
Database.path.append(os.path.join(PLATFORM.package_directory(), 'Data'))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment