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
ccb98160
Commit
ccb98160
authored
Oct 06, 2015
by
eric pellegrini
Browse files
Modified the configure method by removing the configuration argument.
This one is now set at __init__
parent
2d9a92a9
Changes
33
Hide whitespace changes
Inline
Side-by-side
MDANSE/Framework/Configurators/AtomSelectionConfigurator.py
View file @
ccb98160
...
...
@@ -33,8 +33,8 @@ Created on Mar 30, 2015
import
collections
import
operator
import
numpy
from
MDANSE
import
ELEMENTS
from
MDANSE.Framework.UserDefinitionStore
import
UD_STORE
from
MDANSE.Framework.Configurators.IConfigurator
import
IConfigurator
,
ConfiguratorError
from
MDANSE.Framework.AtomSelectionParser
import
AtomSelectionParser
...
...
@@ -52,28 +52,38 @@ class AtomSelectionConfigurator(IConfigurator):
This configurator allows the selection of a specific set of atoms on which the analysis will be performed.
Without any selection, all the atoms stored into the trajectory file will be selected.
After the call to :py:meth:`~MDANSE.Framework.Configurators.AtomSelectionConfigurator.AtomSelectionConfigurator.configure` method
the following keys will be available for this configurator
#. value: the input value used to configure this configurator
#. indexes: the sorted (in increasing order) MMTK indexes of the selected atoms
#. n_selected_atoms: the number of selected atoms
#. elements: a nested-list of the chemical symbols of the selected atoms. The size of the nested list depends on the
grouping_level selected via :py:class:`~MDANSE.Framework.Configurators.GroupingLevelConfigurator.GroupingLevelConfigurator`
configurator.
:note: this configurator depends on 'trajectory' and 'grouping_level' configurators to be configured
:note: this configurator depends on :py:class:`~MDANSE.Framework.Configurators.MMTKTrajectoryConfigurator.MMTKTrajectoryConfigurator`
and :py:class:`~MDANSE.Framework.Configurators.GroupingLevelConfigurator.GroupingLevelConfigurator` configurators to be configured
'''
type
=
'atom_selection'
_default
=
"all"
def
configure
(
self
,
configuration
,
value
):
def
configure
(
self
,
value
):
'''
Configure an input value.
The value must be a string that can be either an atom selection string or a valid user
definition.
:param configuration: the current configuration
:type configuration: a MDANSE.Framework.Configurable.Configurable object
:param value: the input value
:type value: str
'''
trajConfig
=
configura
tion
[
self
.
_dependencies
[
'trajectory'
]]
trajConfig
=
self
.
_
configura
ble
[
self
.
_dependencies
[
'trajectory'
]]
if
value
is
None
:
value
=
[
'all'
]
...
...
@@ -86,97 +96,51 @@ class AtomSelectionConfigurator(IConfigurator):
self
[
"value"
]
=
value
self
[
"
indexes
"
]
=
[]
indexes
=
set
()
for
v
in
value
:
if
UD_STORE
.
has_definition
(
trajConfig
[
"basename"
],
"atom_selection"
,
v
):
ud
=
UD_STORE
.
get_definition
(
trajConfig
[
"basename"
],
"atom_selection"
,
v
)
self
[
"
indexes
"
].
extend
(
ud
[
"indexes"
])
indexes
.
update
(
ud
[
"indexes"
])
else
:
parser
=
AtomSelectionParser
(
trajConfig
[
"instance"
].
universe
)
self
[
"indexes"
].
extend
(
parser
.
parse
(
v
))
indexes
.
update
(
parser
.
parse
(
v
))
indexes
=
sorted
(
list
(
indexes
))
self
[
"indexes"
].
sort
()
self
[
"n_selected_atoms"
]
=
len
(
self
[
"indexes"
])
atoms
=
sorted
(
trajConfig
[
"universe"
].
atomList
(),
key
=
operator
.
attrgetter
(
'index'
))
selectedAtoms
=
[
atoms
[
idx
]
for
idx
in
self
[
"indexes"
]]
self
[
"elements"
]
=
[[
at
.
symbol
]
for
at
in
selectedAtoms
]
if
self
.
_dependencies
.
has_key
(
"grouping_level"
):
self
.
group
(
selectedAtoms
,
configuration
[
self
.
_dependencies
[
'grouping_level'
]][
'value'
])
else
:
self
.
group
(
selectedAtoms
)
self
.
set_contents
()
@
staticmethod
def
find_parent
(
atom
,
level
):
'''
Retrieve recursively the parent of a given MMTK atom at a given level.
For example, a level of 1 will return the direct parent of the atom.
:note: this is a static method
:param atom: the atom for which the parent is searched for
:type atom: MMTK.Atom object
:param level: the level of the parent
:type level: int
'''
for
_
in
range
(
level
):
atom
=
atom
.
parent
return
atom
selectedAtoms
=
[
atoms
[
idx
]
for
idx
in
indexes
]
self
[
"selection_length"
]
=
len
(
indexes
)
self
[
'elements'
]
=
[[
at
.
symbol
]
for
at
in
selectedAtoms
]
self
[
'indexes'
]
=
[[
idx
]
for
idx
in
indexes
]
self
[
'names'
]
=
[
at
.
symbol
for
at
in
selectedAtoms
]
self
[
'unique_names'
]
=
sorted
(
set
(
self
[
'names'
]))
self
[
'masses'
]
=
[[
ELEMENTS
[
n
,
'atomic_weight'
]]
for
n
in
self
[
'names'
]]
def
get_natoms
(
self
):
nAtomsPerElement
=
{}
for
v
in
self
[
"names"
]:
if
nAtomsPerElement
.
has_key
(
v
):
nAtomsPerElement
[
v
]
+=
1
else
:
nAtomsPerElement
[
v
]
=
1
return
nAtomsPerElement
def
group
(
self
,
atoms
,
level
=
"atom"
):
'''
Group the selected atoms according to a given granularity and update
the configurator with the grouping results.
:param atoms: the atoms for
:type atoms: list of MMTK.Atom
:param level: the level of granularity at which the atoms should be grouped
:type level: str
'''
groups
=
collections
.
OrderedDict
()
for
at
in
atoms
:
lvl
=
LEVELS
[
level
][
at
.
topLevelChemicalObject
().
__class__
.
__name__
.
lower
()]
parent
=
self
.
find_parent
(
at
,
lvl
)
groups
.
setdefault
(
parent
,[]).
append
(
at
.
index
)
self
[
"groups"
]
=
groups
.
values
()
self
[
"n_groups"
]
=
len
(
self
[
"groups"
])
if
level
!=
"atom"
:
self
[
"elements"
]
=
[[
"dummy"
]]
*
self
[
"n_groups"
]
self
[
"level"
]
=
level
def
get_indexes
(
self
):
indexesPerElement
=
{}
for
i
,
v
in
enumerate
(
self
[
"names"
]):
if
indexesPerElement
.
has_key
(
v
):
indexesPerElement
[
v
].
extend
(
self
[
'indexes'
][
i
])
else
:
indexesPerElement
[
v
]
=
self
[
'indexes'
][
i
]
self
.
set_contents
()
def
set_contents
(
self
):
'''
Sets the contents of the atom selection.
'''
self
[
"contents"
]
=
collections
.
OrderedDict
()
self
[
'index_to_symbol'
]
=
collections
.
OrderedDict
()
for
i
,
group
in
enumerate
(
self
[
"elements"
]):
for
j
,
el
in
enumerate
(
group
):
self
[
"contents"
].
setdefault
(
el
,[]).
append
(
self
[
"groups"
][
i
][
j
])
self
[
'index_to_symbol'
][
self
[
"groups"
][
i
][
j
]]
=
el
for
k
,
v
in
self
[
"contents"
].
items
():
self
[
"contents"
][
k
]
=
numpy
.
array
(
v
,
dtype
=
numpy
.
int32
)
return
indexesPerElement
self
[
"n_atoms_per_element"
]
=
dict
([(
k
,
len
(
v
))
for
k
,
v
in
self
[
"contents"
].
items
()])
self
[
'n_selected_elements'
]
=
len
(
self
[
"contents"
])
def
get_information
(
self
):
'''
Returns some informations the atom selection.
...
...
@@ -190,8 +154,6 @@ class AtomSelectionConfigurator(IConfigurator):
info
=
[]
info
.
append
(
"Number of selected atoms:%d"
%
self
[
"n_selected_atoms"
])
info
.
append
(
"Level of selection:%s"
%
self
[
"level"
])
info
.
append
(
"Number of selected groups:%d"
%
self
[
"n_groups"
])
info
.
append
(
"Selected elements:%s"
%
self
[
"contents"
].
keys
())
return
"
\n
"
.
join
(
info
)
\ No newline at end of file
MDANSE/Framework/Configurators/AtomTransmutationConfigurator.py
View file @
ccb98160
...
...
@@ -53,7 +53,7 @@ class AtomTransmutationConfigurator(IConfigurator):
_default
=
None
def
configure
(
self
,
configuration
,
value
):
def
configure
(
self
,
value
):
'''
Configure an input value.
...
...
@@ -65,14 +65,12 @@ class AtomTransmutationConfigurator(IConfigurator):
selection to the target chemical element stored in the 2nd element
#. str: the transmutation will be performed by reading the corresponding user definition
:param configuration: the current configuration
:type configuration: MDANSE.Framework.Configurable.Configurable
:param value: the input value
:type value: None or (str,str)-dict or str
'''
self
[
"value"
]
=
value
self
[
"value"
]
=
value
# if the input value is None, do not perform any transmutation
if
value
is
None
:
return
...
...
@@ -80,13 +78,11 @@ class AtomTransmutationConfigurator(IConfigurator):
if
not
isinstance
(
value
,(
list
,
tuple
)):
raise
ConfiguratorError
(
"Invalid input value."
)
self
[
"atom_selection"
]
=
configuration
[
self
.
_dependencies
[
'atom_selection'
]]
if
self
[
"atom_selection"
][
"level"
]
!=
"atom"
:
raise
ConfiguratorError
(
"the atom transmutation can only be set with a grouping level set to %r"
%
'atom'
,
self
)
trajConfig
=
configuration
[
self
.
_dependencies
[
'trajectory'
]]
trajConfig
=
self
.
_configurable
[
self
.
_dependencies
[
'trajectory'
]]
parser
=
AtomSelectionParser
(
trajConfig
[
"instance"
].
universe
)
parser
=
AtomSelectionParser
(
trajConfig
[
"instance"
].
universe
)
self
.
_nTransmutatedAtoms
=
0
for
expression
,
element
in
value
:
...
...
@@ -96,17 +92,18 @@ class AtomTransmutationConfigurator(IConfigurator):
if
UD_STORE
.
has_definition
(
trajConfig
[
"basename"
],
"atom_selection"
,
expression
):
ud
=
UD_STORE
.
get_definition
(
trajConfig
[
"basename"
],
"atom_selection"
,
expression
)
self
.
transmutate
(
configuration
,
ud
[
"indexes"
]
,
element
)
indexes
=
ud
[
"indexes"
]
else
:
indexes
=
parser
.
parse
(
expression
)
self
.
transmutate
(
configuration
,
indexes
,
element
)
def
transmutate
(
self
,
configuration
,
selection
,
element
):
self
.
transmutate
(
indexes
,
element
)
self
.
_nTransmutatedAtoms
+=
len
(
indexes
)
def
transmutate
(
self
,
selection
,
element
):
'''
Transmutates a set of atoms to a given element
:param configuration: the current configuration
:type configuration: MDANSE.Framework.Configurable.Configurable
:param selection: the indexes of the atoms to be transmutated
:type selection: list of int
:param element: the symbol of the element to which the selected atoms should be transmutated
...
...
@@ -115,15 +112,15 @@ class AtomTransmutationConfigurator(IConfigurator):
if
element
not
in
ELEMENTS
:
raise
ConfiguratorError
(
"the element %r is not registered in the database"
%
element
,
self
)
atomSelConfigurator
=
self
.
_configurable
[
self
.
_dependencies
[
'atom_selection'
]]
for
idx
in
selection
:
pos
=
self
[
"atom_selection"
][
"groups"
].
index
([
idx
])
self
[
"atom_selection"
][
"elements"
][
pos
]
=
[
element
]
# Update the current configuration according to the changes triggered by
# atom transumutation
configuration
[
self
.
_dependencies
[
'atom_selection'
]].
set_contents
()
atomSelConfigurator
[
"names"
][
idx
]
=
element
atomSelConfigurator
[
"elements"
][
idx
]
=
[
element
]
atomSelConfigurator
[
'unique_names'
]
=
sorted
(
set
(
atomSelConfigurator
[
'names'
]))
def
get_information
(
self
):
'''
Returns some informations the atoms selected for being transmutated.
...
...
@@ -136,6 +133,6 @@ class AtomTransmutationConfigurator(IConfigurator):
return
"Not configured yet"
if
self
[
"value"
]
is
None
:
return
"No atoms selected for
deuter
ation"
return
"No atoms selected for
transmut
ation"
return
"Number of selected atoms for deuteration:%d
\n
"
%
self
[
"atom_selection"
][
"n_selected_atoms"
]
\ No newline at end of file
return
"Number of transmutated atoms:%d
\n
"
%
self
.
_nTransmutatedAtoms
\ No newline at end of file
MDANSE/Framework/Configurators/AtomsListConfigurator.py
View file @
ccb98160
...
...
@@ -47,7 +47,7 @@ class AtomsListConfigurator(IConfigurator):
_default
=
None
def
__init__
(
self
,
name
,
nAtoms
=
2
,
**
kwargs
):
def
__init__
(
self
,
configurable
,
name
,
nAtoms
=
2
,
**
kwargs
):
'''
Initializes the configurator.
...
...
@@ -57,7 +57,7 @@ class AtomsListConfigurator(IConfigurator):
:type nAtoms: int
'''
IConfigurator
.
__init__
(
self
,
name
,
**
kwargs
)
IConfigurator
.
__init__
(
self
,
configurable
,
name
,
**
kwargs
)
self
.
_nAtoms
=
nAtoms
...
...
@@ -66,20 +66,18 @@ class AtomsListConfigurator(IConfigurator):
return
self
.
_nAtoms
def
configure
(
self
,
configuration
,
value
):
def
configure
(
self
,
value
):
'''
Configure an input value.
The value must be a string that can be either an atom selection string or a valid user
definition.
:param configuration: the current configuration
:type configuration: a MDANSE.Framework.Configurable.Configurable object
:param value: the input value
:type value: str
'''
trajConfig
=
configura
tion
[
self
.
_dependencies
[
'trajectory'
]]
trajConfig
=
self
.
_
configura
ble
[
self
.
_dependencies
[
'trajectory'
]]
if
UD_STORE
.
has_definition
(
trajConfig
[
"basename"
],
"%d_atoms_list"
%
self
.
_nAtoms
,
value
):
molecule
,
atoms
=
UD_STORE
.
get_definition
(
trajConfig
[
"basename"
],
"%d_atoms_list"
%
self
.
_nAtoms
,
value
)
...
...
MDANSE/Framework/Configurators/AxisSelectionConfigurator.py
View file @
ccb98160
...
...
@@ -47,7 +47,7 @@ class AxisSelection(IConfigurator):
_default
=
None
def
configure
(
self
,
configuration
,
value
):
def
configure
(
self
,
value
):
'''
Configure an input value.
...
...
@@ -64,7 +64,7 @@ class AxisSelection(IConfigurator):
:type value: tuple or str
'''
trajConfig
=
configura
tion
[
self
.
_dependencies
[
'trajectory'
]]
trajConfig
=
self
.
_
configura
ble
[
self
.
_dependencies
[
'trajectory'
]]
if
UD_STORE
.
has_definition
(
trajConfig
[
"basename"
],
"axis_selection"
,
value
):
ud
=
UD_STORE
.
get_definition
(
trajConfig
[
"basename"
],
"axis_selection"
,
value
)
...
...
MDANSE/Framework/Configurators/BasisSelectionConfigurator.py
View file @
ccb98160
...
...
@@ -47,7 +47,7 @@ class BasisSelection(IConfigurator):
_default
=
None
def
configure
(
self
,
configuration
,
value
):
def
configure
(
self
,
value
):
'''
Configure an input value.
...
...
@@ -58,15 +58,13 @@ class BasisSelection(IConfigurator):
keys are the names of three atoms of the molecule that will be used to define respectively the origin, the X and Y axis of the basis
#. str: the axis selection will be performed by reading the corresponding user definition.
:param configuration: the current configuration
:type configuration: MDANSE.Framework.Configurable.Configurable
:param value: the input value
:type value: tuple or str
:note: this configurator depends on 'trajectory' configurator to be configured
'''
trajConfig
=
configura
tion
[
self
.
_dependencies
[
'trajectory'
]]
trajConfig
=
self
.
_
configura
ble
[
self
.
_dependencies
[
'trajectory'
]]
if
UD_STORE
.
has_definition
(
trajConfig
[
"basename"
],
"basis_selection"
,
value
):
ud
=
UD_STORE
.
get_definition
(
trajConfig
[
"basename"
],
"basis_selection"
,
value
)
...
...
MDANSE/Framework/Configurators/BooleanConfigurator.py
View file @
ccb98160
...
...
@@ -47,7 +47,7 @@ class BooleanConfigurator(IConfigurator):
_shortCuts
=
{
True
:
True
,
"true"
:
True
,
"yes"
:
True
,
"y"
:
True
,
"1"
:
True
,
1
:
True
,
False
:
False
,
"false"
:
False
,
"no"
:
False
,
"n"
:
False
,
"0"
:
False
,
0
:
False
}
def
configure
(
self
,
configuration
,
value
):
def
configure
(
self
,
value
):
'''
Configure an input value.
...
...
MDANSE/Framework/Configurators/ComplexNumberConfigurator.py
View file @
ccb98160
...
...
@@ -42,7 +42,7 @@ class ComplexNumberConfigurator(IConfigurator):
_default
=
0
def
__init__
(
self
,
name
,
mini
=
None
,
maxi
=
None
,
choices
=
None
,
**
kwargs
):
def
__init__
(
self
,
configurable
,
name
,
mini
=
None
,
maxi
=
None
,
choices
=
None
,
**
kwargs
):
'''
Initializes the configurator.
...
...
@@ -57,7 +57,7 @@ class ComplexNumberConfigurator(IConfigurator):
'''
# The base class constructor.
IConfigurator
.
__init__
(
self
,
name
,
**
kwargs
)
IConfigurator
.
__init__
(
self
,
configurable
,
name
,
**
kwargs
)
self
.
_mini
=
float
(
mini
)
if
mini
is
not
None
else
None
...
...
@@ -65,12 +65,10 @@ class ComplexNumberConfigurator(IConfigurator):
self
.
_choices
=
choices
if
choices
is
not
None
else
[]
def
configure
(
self
,
configuration
,
value
):
def
configure
(
self
,
value
):
'''
Configure an input value.
:param configuration: the current configuration.
:type configuration: a MDANSE.Framework.Configurable.Configurable object
:param value: the input complex number.
:type value: complex
'''
...
...
MDANSE/Framework/Configurators/FloatConfigurator.py
View file @
ccb98160
...
...
@@ -41,7 +41,7 @@ class FloatConfigurator(IConfigurator):
_default
=
0
def
__init__
(
self
,
name
,
mini
=
None
,
maxi
=
None
,
choices
=
None
,
**
kwargs
):
def
__init__
(
self
,
configurable
,
name
,
mini
=
None
,
maxi
=
None
,
choices
=
None
,
**
kwargs
):
'''
Initializes the configurator.
...
...
@@ -56,7 +56,7 @@ class FloatConfigurator(IConfigurator):
'''
# The base class constructor.
IConfigurator
.
__init__
(
self
,
name
,
**
kwargs
)
IConfigurator
.
__init__
(
self
,
configurable
,
name
,
**
kwargs
)
self
.
_mini
=
float
(
mini
)
if
mini
is
not
None
else
None
...
...
@@ -64,12 +64,10 @@ class FloatConfigurator(IConfigurator):
self
.
_choices
=
choices
if
choices
is
not
None
else
[]
def
configure
(
self
,
configuration
,
value
):
def
configure
(
self
,
value
):
'''
Configure an input value.
:param configuration: the current configuration
:type configuration: a MDANSE.Framework.Configurable.Configurable object
:param value: the input value
:type value: float
'''
...
...
MDANSE/Framework/Configurators/FramesConfigurator.py
View file @
ccb98160
...
...
@@ -48,7 +48,7 @@ class FramesConfigurator(RangeConfigurator):
type
=
'frames'
def
__init__
(
self
,
name
,
**
kwargs
):
def
__init__
(
self
,
configurable
,
name
,
**
kwargs
):
'''
Initializes the configurator.
...
...
@@ -56,34 +56,30 @@ class FramesConfigurator(RangeConfigurator):
:type name: str
'''
RangeConfigurator
.
__init__
(
self
,
name
,
sort
=
True
,
**
kwargs
)
RangeConfigurator
.
__init__
(
self
,
configurable
,
name
,
sort
=
True
,
**
kwargs
)
def
configure
(
self
,
configuration
,
value
):
def
configure
(
self
,
value
):
'''
Configure the frames range that will be used to perform an analysis.
:param configuration: the current configuration
:type configuration: a MDANSE.Framework.Configurable.Configurable object
:param value: the input value
:type value: 3-tuple, 'all' or None
'''
trajConfig
=
configura
tion
[
self
.
_dependencies
[
'trajectory'
]]
trajConfig
=
self
.
_
configura
ble
[
self
.
_dependencies
[
'trajectory'
]]
if
value
in
[
"all"
,
None
]:
value
=
(
0
,
trajConfig
[
'length'
],
1
)
self
.
_mini
=
-
1
self
.
_mini
=
0
self
.
_maxi
=
trajConfig
[
'length'
]
RangeConfigurator
.
configure
(
self
,
configuration
,
value
)
RangeConfigurator
.
configure
(
self
,
value
)
self
[
"n_frames"
]
=
self
[
"number"
]
self
[
'time'
]
=
trajConfig
[
'md_time_step'
]
*
self
[
'value'
]
self
[
'relative_time'
]
=
self
[
'time'
]
-
self
[
'time'
][
0
]
# case of single frame selected
try
:
self
[
'time_step'
]
=
self
[
'time'
][
1
]
-
self
[
'time'
][
0
]
...
...
MDANSE/Framework/Configurators/GroupingLevelConfigurator.py
View file @
ccb98160
...
...
@@ -31,6 +31,7 @@ Created on Mar 30, 2015
'''
import
collections
import
operator
from
MDANSE.Framework.Configurators.SingleChoiceConfigurator
import
SingleChoiceConfigurator
...
...
@@ -61,7 +62,7 @@ class GroupingLevelConfigurator(SingleChoiceConfigurator):
_default
=
"atom"
def
__init__
(
self
,
name
,
choices
=
None
,
**
kwargs
):
def
__init__
(
self
,
configurable
,
name
,
choices
=
None
,
**
kwargs
):
'''
Initializes the configurator.
...
...
@@ -76,7 +77,79 @@ class GroupingLevelConfigurator(SingleChoiceConfigurator):
else
:
choices
=
list
(
set
(
LEVELS
.
keys
()).
intersection
(
choices
))
SingleChoiceConfigurator
.
__init__
(
self
,
name
,
choices
=
choices
,
**
kwargs
)
SingleChoiceConfigurator
.
__init__
(
self
,
configurable
,
name
,
choices
=
choices
,
**
kwargs
)
def
configure
(
self
,
value
):
'''
:param value: the level of granularity at which the atoms should be grouped
:type value: str
'''
if
value
is
None
:
value
=
"atom"
value
=
str
(
value
)
SingleChoiceConfigurator
.
configure
(
self
,
value
)
if
value
==
"atom"
:
return
trajConfig
=
self
.
_configurable
[
self
.
_dependencies
[
'trajectory'
]]
atomSelectionConfig
=
self
.
_configurable
[
self
.
_dependencies
[
'atom_selection'
]]
allAtoms
=
sorted
(
trajConfig
[
"universe"
].
atomList
(),
key
=
operator
.
attrgetter
(
'index'
))
groups
=
collections
.
OrderedDict
()
for
i
in
range
(
atomSelectionConfig
[
"selection_length"
]):
idx
=
atomSelectionConfig
[
"indexes"
][
i
][
0
]
el
=
atomSelectionConfig
[
"elements"
][
i
][
0
]
mass
=
atomSelectionConfig
[
"masses"
][
i
][
0
]
at
=
allAtoms
[
idx
]
lvl
=
LEVELS
[
value
][
at
.
topLevelChemicalObject
().
__class__
.
__name__
.
lower
()]
parent
=
self
.
find_parent
(
at
,
lvl
)
d
=
groups
.
setdefault
(
parent
,{})
d
.
setdefault
(
"indexes"
,[]).
append
(
idx
)
d
.
setdefault
(
"elements"
,[]).
append
(
el
)
d
.
setdefault
(
"masses"
,[]).
append
(
mass
)
indexes
=
[]
elements
=
[]
masses
=
[]
names
=
[]
for
i
,
v
in
enumerate
(
groups
.
values
()):
names
.
append
(
"group_%d"
%
i
)
elements
.
append
(
v
[
'elements'
])
indexes
.
append
(
v
[
'indexes'
])
masses
.
append
(
v
[
'masses'
])
atomSelectionConfig
[
"indexes"
]
=
indexes
atomSelectionConfig
[
"elements"
]
=
elements
atomSelectionConfig
[
"masses"
]
=
masses
atomSelectionConfig
[
"names"
]
=
names
atomSelectionConfig
[
"selection_length"
]
=
len
(
names
)
atomSelectionConfig
[
'unique_names'
]
=
sorted
(
set
(
atomSelectionConfig
[
'names'
]))
self
[
"level"
]
=
value
@
staticmethod
def
find_parent
(
atom
,
level
):
'''
Retrieve recursively the parent of a given MMTK atom at a given level.
For example, a level of 1 will return the direct parent of the atom.
:note: this is a static method
:param atom: the atom for which the parent is searched for