Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Scientific Software
MDANSE
Commits
69289a79
Commit
69289a79
authored
Jul 24, 2015
by
eric pellegrini
Browse files
Implemented a template job builder
Removed unused module The user macros definition is now ok
parent
7adb267c
Changes
8
Hide whitespace changes
Inline
Side-by-side
MDANSE/Core/ClassRegistry.py
View file @
69289a79
...
...
@@ -145,47 +145,32 @@ class ClassRegistry(abc.ABCMeta):
if
not
cls
.
_registry
.
has_key
(
interface
):
return
"The interface "
+
interface
+
" is not registered"
# Dictionnay whose keys are the package names and values and list of (job name, job path) stored in the corresponding package.
packages
=
{}
words
=
[
"Name"
,
"Class"
,
"File"
]
contents
=
[]
contents
.
append
(
"="
*
130
)
contents
.
append
(
"{1:{0}s} {2:50s} {3}"
)
contents
.
append
(
"="
*
130
)
maxlength
=
-
1
# Loop over the registry items.
for
k
,
v
in
cls
.
_registry
[
interface
].
items
():
for
i
,
(
k
,
v
)
in
enumerate
(
sorted
(
cls
.
_registry
[
interface
].
items
()
))
:
# Get the module corresponding to the job class.
mod
=
inspect
.
getmodule
(
v
)
# The package hosting the module.
modPackage
=
mod
.
__package__
# The module file.
modFilename
=
mod
.
__file__
# If no package could be found, guess a name using the directory name of the module file.
if
modPackage
is
None
:
modPackage
=
os
.
path
.
split
(
os
.
path
.
dirname
(
modFilename
))[
1
]
modPackage
=
modPackage
.
split
(
"."
)[
-
1
]
# Update the packages dictionary.
if
packages
.
has_key
(
modPackage
):
packages
[
modPackage
].
append
([
k
,
v
.
__name__
])
else
:
packages
[
modPackage
]
=
[[
k
,
v
.
__name__
]]
contents
=
[]
# Print the contents of the packages dictionary.
contents
.
append
(
"="
*
130
)
contents
.
append
(
"%-50s %-40s %-s"
%
(
"Package"
,
"Name"
,
"Class"
))
contents
.
append
(
"="
*
130
)
for
k
,
v
in
sorted
(
packages
.
items
()):
for
vv
in
sorted
(
v
):
contents
.
append
(
"%-50s %-40s %-s"
%
(
k
,
vv
[
0
],
vv
[
1
]))
contents
.
append
(
'-'
*
130
)
words
.
extend
([
k
,
v
.
__name__
,
mod
.
__file__
])
contents
.
append
(
"{%d:{0}s} {%d:50} {%d}"
%
(
3
*
i
+
4
,
3
*
i
+
5
,
3
*
i
+
6
))
maxlength
=
max
(
len
(
k
),
maxlength
)
contents
.
append
(
'-'
*
130
)
contents
=
"
\n
"
.
join
(
contents
)
return
contents
contents
=
"
\n
"
.
join
(
contents
)
return
contents
.
format
(
maxlength
,
*
words
)
@
classmethod
def
get_interfaces
(
cls
):
...
...
MDANSE/Core/Preferences.py
View file @
69289a79
...
...
@@ -204,6 +204,12 @@ class InputDirectory(PreferencesItem):
raise
PreferencesError
(
'Error when setting input directory %r'
%
value
)
self
.
_value
=
value
def
get_value
(
self
):
PLATFORM
.
create_directory
(
self
.
_value
)
return
self
.
_value
class
Preferences
(
object
):
'''
...
...
MDANSE/Framework/Jobs/IJob.py
View file @
69289a79
...
...
@@ -461,3 +461,89 @@ class IJob(Configurable):
def
info
(
self
):
return
self
.
_info
@
classmethod
def
save_template
(
cls
,
shortname
,
longname
=
None
):
if
longname
is
None
:
longname
=
shortname
if
REGISTRY
[
'job'
].
has_key
(
shortname
):
raise
IOError
(
"A job with %r name is already stored in the registry"
%
shortname
)
from
MDANSE
import
PREFERENCES
macrosDir
=
PREFERENCES
.
get_preferences_item
(
"macros_directory"
).
get_value
()
templateFile
=
os
.
path
.
join
(
macrosDir
,
"%s.py"
%
longname
)
f
=
open
(
templateFile
,
'w'
)
f
.
write
(
'''import collections
from MDANSE.Framework.Jobs.IJob import IJob
class %s(IJob):
"""
You should enter the description of your job here ...
"""
type = %r
# You should enter the label under which your job will be referenced from the gui.
label = %r
# You should enter the category under which your job will be references.
category = ('My jobs',)
ancestor = "mmtk_trajectory"
# You should enter the configuration of your job here
# Here a basic example of a job that will use a MMTK trajectory, a frame selection and an output file in NetCDF and ASCII file formats
settings = collections.OrderedDict()
settings['trajectory']=('mmtk_trajectory',{})
settings['frames']=('frames', {"dependencies":{'trajectory':'trajectory'}})
settings['output_files']=('output_files', {"formats":["netcdf","ascii"]})
def initialize(self):
"""
Initialize the input parameters and analysis self variables
"""
# Compulsory. You must enter the number of steps of your job.
# Here for example the number of selected frames
self.numberOfSteps = self.configuration['frames']['number']
# Create an output data for the selected frames.
self._outputData.add("times", "line", self.configuration['frames']['time'], units='ps')
def run_step(self, index):
"""
Runs a single step of the job.
"""
return index, None
def combine(self, index, x):
"""
Synchronize the output of each individual run_step output.
"""
def finalize(self):
"""
Finalizes the job (e.g. averaging the total term, output files creations ...).
"""
# The output data are written
self._outputData.write(self.configuration['output_files']['root'], self.configuration['output_files']['formats'], self._info)
# The trajectory is closed
self.configuration['trajectory']['instance'].close()
'''
%
(
longname
,
shortname
,
longname
))
f
.
close
()
return
templateFile
\ No newline at end of file
MDANSE/Framework/Plugins/__init__.py
View file @
69289a79
import
glob
import
os
from
MDANSE
import
REGISTRY
from
MDANSE.Framework.Plugins.DataPlugin
import
DataPlugin
from
MDANSE.Framework.Plugins.JobPlugin
import
JobPlugin
for
job
in
REGISTRY
[
"job"
].
values
():
if
not
hasattr
(
job
,
"type"
):
continue
attrs
=
{
"type"
:
job
.
type
,
"ancestor"
:
getattr
(
job
,
"ancestor"
,
""
),
"category"
:
(
'Analysis'
,)
+
getattr
(
job
,
"category"
,
(
"Miscellaneous"
,)),
"label"
:
getattr
(
job
,
"label"
,
job
.
__name__
)}
kls
=
type
(
"%sPlugin"
%
job
.
__name__
,
(
JobPlugin
,),
attrs
)
for
data
in
REGISTRY
[
"input_data"
].
values
():
if
not
hasattr
(
data
,
"type"
):
continue
attrs
=
{
"type"
:
data
.
type
,
"label"
:
" "
.
join
(
""
.
split
(
"_"
)).
capitalize
(),
"ancestor"
:
""
}
kls
=
type
(
"%sPlugin"
%
data
.
__name__
,
(
DataPlugin
,),
attrs
)
\ No newline at end of file
MDANSE/Framework/__init__.py
View file @
69289a79
import
os
from
MDANSE
import
REGISTRY
from
MDANSE
import
PLATFORM
,
PREFERENCES
,
REGISTRY
directories
=
sorted
([
x
[
0
]
for
x
in
os
.
walk
(
os
.
path
.
dirname
(
__file__
))][
1
:])
macrosDir
=
PREFERENCES
.
get_preferences_item
(
'macros_directory'
).
get_value
()
directories
.
insert
(
0
,
macrosDir
)
directories
.
extend
(
sorted
([
x
[
0
]
for
x
in
os
.
walk
(
macrosDir
)][
1
:]))
for
d
in
directories
:
REGISTRY
.
update_registry
(
d
)
MDANSE/GUI/ComboWidgets/ComboWidgets.py
deleted
100644 → 0
View file @
7adb267c
import
collections
import
os
import
wx.combo
import
wx.lib.filebrowsebutton
as
wxfile
class
CheckboxComboPopup
(
wx
.
combo
.
ComboPopup
):
def
__init__
(
self
,
items
,
maxNumberOfItems
=
None
):
wx
.
combo
.
ComboPopup
.
__init__
(
self
)
self
.
_items
=
items
self
.
_maxNumberOfItems
=
maxNumberOfItems
@
property
def
items
(
self
):
return
self
.
_items
@
property
def
checklistbox
(
self
):
return
self
.
_checklistbox
def
Create
(
self
,
parent
):
self
.
_checklistbox
=
wx
.
CheckListBox
(
parent
,
-
1
,
choices
=
self
.
_items
)
self
.
_checklistbox
.
Bind
(
wx
.
EVT_CHECKLISTBOX
,
self
.
on_check_item
)
if
not
self
.
_checklistbox
.
IsEmpty
():
self
.
_checklistbox
.
Check
(
0
)
return
True
def
GetControl
(
self
):
return
self
.
_checklistbox
def
GetAdjustedSize
(
self
,
minWidth
,
prefHeight
,
maxHeight
):
return
self
.
_checklistbox
.
GetSize
()
def
GetStringValue
(
self
):
return
self
.
_checklistbox
.
GetCheckedStrings
()
def
on_check_item
(
self
,
event
):
if
self
.
_maxNumberOfItems
is
None
:
return
nCheckedItems
=
len
(
self
.
_checklistbox
.
GetChecked
())
if
nCheckedItems
>
self
.
_maxNumberOfItems
:
self
.
_checklistbox
.
Check
(
event
.
GetInt
(),
False
)
class
ComboPanel
(
wx
.
Panel
):
def
__init__
(
self
,
parent
,
*
args
,
**
kwargs
):
wx
.
Panel
.
__init__
(
self
,
parent
,
*
args
,
**
kwargs
)
class
ComboCheckableMenu
(
ComboPanel
):
def
__init__
(
self
,
parent
,
choices
,
exclusive
=
False
,
labelText
=
""
,
menuText
=
""
,
*
args
,
**
kwargs
):
ComboPanel
.
__init__
(
self
,
parent
,
*
args
,
**
kwargs
)
self
.
_choices
=
collections
.
OrderedDict
().
fromkeys
(
choices
,
False
)
self
.
_exclusive
=
exclusive
self
.
_labelText
=
labelText
self
.
_menuText
=
menuText
self
.
build_panel
()
self
.
build_layout
()
def
build_panel
(
self
):
self
.
_button
=
self
.
create_menubutton
()
def
build_layout
(
self
):
sizer
=
wx
.
BoxSizer
(
wx
.
HORIZONTAL
)
sizer
.
Add
(
self
.
_button
,
1
,
flag
=
wx
.
EXPAND
)
self
.
SetSizer
(
sizer
)
def
create_menubutton
(
self
):
button
=
wx
.
Button
(
self
,
wx
.
ID_ANY
,
label
=
self
.
_menuText
)
button
.
Bind
(
wx
.
EVT_BUTTON
,
self
.
on_display_menu
)
return
button
def
get_value
(
self
):
selection
=
[
label
for
label
,
state
in
self
.
_choices
.
items
()
if
state
]
return
selection
def
on_check_menuitem
(
self
,
event
):
for
item
in
event
.
GetEventObject
().
GetMenuItems
():
self
.
_choices
[
item
.
GetLabel
()]
=
item
.
IsChecked
()
if
self
.
_exclusive
:
item
=
event
.
GetEventObject
().
FindItemById
(
event
.
GetId
())
self
.
_button
.
SetLabel
(
item
.
GetLabel
())
def
on_display_menu
(
self
,
event
):
menu
=
wx
.
Menu
()
for
label
,
state
in
self
.
_choices
.
items
():
if
self
.
_exclusive
:
item
=
menu
.
AppendRadioItem
(
wx
.
ID_ANY
,
label
)
else
:
item
=
menu
.
AppendCheckItem
(
wx
.
ID_ANY
,
label
)
item
.
Check
(
state
)
x
,
y
=
self
.
_button
.
GetPosition
()
w
,
h
=
self
.
_button
.
GetSize
()
self
.
Bind
(
wx
.
EVT_MENU
,
self
.
on_check_menuitem
)
self
.
_button
.
PopupMenu
(
menu
,
(
x
+
w
/
2
,
y
+
h
/
2
))
class
ComboCheckbox
(
ComboPanel
):
def
__init__
(
self
,
parent
,
parameters
=
None
,
sizerParameters
=
None
,
checked
=
False
,
*
args
,
**
kwargs
):
ComboPanel
.
__init__
(
self
,
parent
,
*
args
,
**
kwargs
)
self
.
_parameters
=
parameters
self
.
_checked
=
checked
if
sizerParameters
is
None
:
sizerParameters
=
{
"hgap"
:
5
,
"vgap"
:
5
}
self
.
_sizerParameters
=
sizerParameters
self
.
build_panel
()
self
.
build_layout
()
self
.
on_toggle_checkbox_state
()
def
build_panel
(
self
):
check
=
self
.
_parameters
.
setdefault
(
"check"
,{})
cParams
=
check
.
setdefault
(
"w_parameters"
,{})
self
.
_checkbox
=
wx
.
CheckBox
(
self
,
**
cParams
)
self
.
_widget
=
self
.
_parameters
.
setdefault
(
"widget"
,
None
)
if
self
.
_widget
is
not
None
:
widget
,
wParams
=
self
.
_widget
wParams
.
setdefault
(
"w_parameters"
,{})
self
.
_widget
=
widget
(
self
,
**
wParams
[
"w_parameters"
])
self
.
_checkbox
.
SetValue
(
self
.
_checked
)
self
.
_checkbox
.
Bind
(
wx
.
EVT_CHECKBOX
,
self
.
on_toggle_checkbox_state
)
def
build_layout
(
self
):
sizer
=
wx
.
GridBagSizer
(
**
self
.
_sizerParameters
)
sParams
=
self
.
_parameters
[
"check"
].
setdefault
(
"s_parameters"
,{})
sizer
.
Add
(
self
.
_checkbox
,
**
sParams
)
if
self
.
_widget
is
not
None
:
sParams
=
self
.
_parameters
[
"widget"
][
1
].
setdefault
(
"s_parameters"
,{})
sizer
.
Add
(
self
.
_widget
,
**
sParams
)
self
.
SetSizer
(
sizer
)
def
get_value
(
self
):
checked
=
self
.
_checkbox
.
GetValue
()
if
checked
:
try
:
value
=
self
.
_widget
.
get_value
()
except
AttributeError
:
try
:
value
=
self
.
_widget
.
GetValue
()
except
AttributeError
:
value
=
None
else
:
value
=
None
return
(
checked
,
value
)
def
on_toggle_checkbox_state
(
self
,
event
=
None
):
checked
=
self
.
_checkbox
.
GetValue
()
try
:
self
.
_widget
.
Enable
(
checked
)
except
:
pass
class
ComboOutputFile
(
ComboPanel
):
def
__init__
(
self
,
parent
,
formats
,
sizerParameters
=
None
,
*
args
,
**
kwargs
):
ComboPanel
.
__init__
(
self
,
parent
,
*
args
,
**
kwargs
)
self
.
_formats
=
formats
if
sizerParameters
is
None
:
sizerParameters
=
{
"hgap"
:
5
,
"vgap"
:
5
}
self
.
_sizerParameters
=
sizerParameters
self
.
build_panel
()
self
.
build_layout
()
@
property
def
directory
(
self
):
return
self
.
_directory
@
property
def
basename
(
self
):
return
self
.
_basename
def
build_panel
(
self
):
self
.
_directory
=
wxfile
.
DirBrowseButton
(
self
,
labelText
=
"Directory"
,
startDirectory
=
os
.
getcwd
(),
newDirectory
=
True
)
self
.
_directory
.
label
.
SetWindowStyle
(
wx
.
ALIGN_LEFT
)
self
.
_basenameLabel
=
wx
.
StaticText
(
self
,
label
=
"Basename"
,
style
=
wx
.
ALIGN_LEFT
)
self
.
_basename
=
wx
.
TextCtrl
(
self
,
value
=
""
)
self
.
_formats
=
ComboCheckableMenu
(
self
,
self
.
_formats
,
labelText
=
"File formats"
,
menuText
=
"Formats"
)
def
build_layout
(
self
):
sizer
=
wx
.
GridBagSizer
(
**
self
.
_sizerParameters
)
sizer
.
Add
(
self
.
_directory
,
pos
=
(
0
,
0
),
span
=
(
1
,
3
),
flag
=
wx
.
ALIGN_CENTER_VERTICAL
|
wx
.
EXPAND
)
sizer
.
Add
(
self
.
_basenameLabel
,
pos
=
(
1
,
0
),
flag
=
wx
.
ALIGN_CENTER_VERTICAL
)
sizer
.
Add
(
self
.
_basename
,
pos
=
(
1
,
1
),
flag
=
wx
.
EXPAND
)
sizer
.
Add
(
self
.
_formats
,
pos
=
(
1
,
2
),
flag
=
wx
.
EXPAND
)
sizer
.
AddGrowableCol
(
1
)
self
.
SetSizer
(
sizer
)
def
get_value
(
self
):
directory
=
self
.
_directory
.
GetValue
()
basename
=
self
.
_basename
.
GetValue
().
strip
()
if
not
basename
:
raise
ValueError
(
"No basename for the output file provided."
)
formats
=
self
.
_formats
.
get_value
()
if
not
formats
:
raise
ValueError
(
"No output formats selected."
)
return
(
directory
,
basename
,
formats
)
class
ComboRadioButtons
(
ComboPanel
):
def
__init__
(
self
,
parent
,
parameters
,
sizerParameters
=
None
,
selected
=
0
,
*
args
,
**
kwargs
):
ComboPanel
.
__init__
(
self
,
parent
,
*
args
,
**
kwargs
)
self
.
_parameters
=
parameters
if
sizerParameters
is
None
:
sizerParameters
=
{
"hgap"
:
5
,
"vgap"
:
5
}
self
.
_sizerParameters
=
sizerParameters
self
.
_selected
=
selected
self
.
_radios
=
[]
self
.
_widgets
=
[]
self
.
build_panel
()
self
.
build_layout
()
def
add_radiobutton
(
self
,
parameters
):
radio
=
parameters
.
setdefault
(
"radio"
,{})
rParams
=
radio
.
setdefault
(
"w_parameters"
,{})
self
.
_radios
.
append
(
wx
.
RadioButton
(
self
,
**
rParams
))
widget
=
parameters
.
setdefault
(
"widget"
,
None
)
if
widget
is
not
None
:
widget
,
wParams
=
widget
wParams
.
setdefault
(
"w_parameters"
,{})
widget
=
widget
(
self
,
**
wParams
[
"w_parameters"
])
self
.
_widgets
.
append
(
widget
)
self
.
_radios
[
-
1
].
Bind
(
wx
.
EVT_RADIOBUTTON
,
self
.
on_select_radiobutton
)
def
build_panel
(
self
):
for
params
in
self
.
_parameters
:
self
.
add_radiobutton
(
params
)
self
.
_radios
[
0
].
SetWindowStyle
(
wx
.
RB_GROUP
)
self
.
_radios
[
self
.
_selected
].
SetValue
(
True
)
self
.
select_radiobutton
(
self
.
_selected
)
def
build_layout
(
self
):
sizer
=
wx
.
GridBagSizer
(
**
self
.
_sizerParameters
)
for
p
,
r
,
w
in
zip
(
self
.
_parameters
,
self
.
_radios
,
self
.
_widgets
):
sParam
=
p
[
"radio"
].
setdefault
(
"s_parameters"
,{})
sizer
.
Add
(
r
,
**
sParam
)
if
w
is
not
None
:
sParam
=
p
[
"widget"
][
1
].
setdefault
(
"s_parameters"
,{})
sizer
.
Add
(
w
,
**
sParam
)
self
.
SetSizer
(
sizer
)
def
get_selected_radiobutton
(
self
):
idx
=
[
i
for
i
,
r
in
enumerate
(
self
.
_radios
)
if
r
.
GetValue
()][
0
]
return
idx
def
get_value
(
self
):
label
=
str
(
self
.
_radios
[
self
.
_selected
].
GetLabel
())
try
:
value
=
self
.
_widgets
[
self
.
_selected
].
get_value
()
except
AttributeError
:
try
:
value
=
self
.
_widgets
[
self
.
_selected
].
GetValue
()
except
AttributeError
:
value
=
None
return
(
label
,
value
)
def
on_select_radiobutton
(
self
,
event
=
None
):
self
.
_selected
=
self
.
_radios
.
index
(
event
.
GetEventObject
())
self
.
select_radiobutton
(
self
.
_selected
)
def
select_radiobutton
(
self
,
idx
):
for
i
,
w
in
enumerate
(
self
.
_widgets
):
try
:
w
.
Enable
(
i
==
idx
)
except
:
pass
class
ComboRange
(
ComboPanel
):
def
__init__
(
self
,
parent
,
typ
=
int
,
*
args
,
**
kwargs
):
ComboPanel
.
__init__
(
self
,
parent
,
*
args
,
**
kwargs
)