Commit ccb98160 authored by eric pellegrini's avatar eric pellegrini
Browse files

Modified the configure method by removing the configuration argument.

This one is now set at __init__
parent 2d9a92a9
...@@ -33,8 +33,8 @@ Created on Mar 30, 2015 ...@@ -33,8 +33,8 @@ Created on Mar 30, 2015
import collections import collections
import operator import operator
import numpy
from MDANSE import ELEMENTS
from MDANSE.Framework.UserDefinitionStore import UD_STORE from MDANSE.Framework.UserDefinitionStore import UD_STORE
from MDANSE.Framework.Configurators.IConfigurator import IConfigurator, ConfiguratorError from MDANSE.Framework.Configurators.IConfigurator import IConfigurator, ConfiguratorError
from MDANSE.Framework.AtomSelectionParser import AtomSelectionParser from MDANSE.Framework.AtomSelectionParser import AtomSelectionParser
...@@ -52,28 +52,38 @@ class AtomSelectionConfigurator(IConfigurator): ...@@ -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. 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. 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' type = 'atom_selection'
_default = "all" _default = "all"
def configure(self, configuration, value): def configure(self, value):
''' '''
Configure an input value. Configure an input value.
The value must be a string that can be either an atom selection string or a valid user The value must be a string that can be either an atom selection string or a valid user
definition. definition.
:param configuration: the current configuration
:type configuration: a MDANSE.Framework.Configurable.Configurable object
:param value: the input value :param value: the input value
:type value: str :type value: str
''' '''
trajConfig = configuration[self._dependencies['trajectory']] trajConfig = self._configurable[self._dependencies['trajectory']]
if value is None: if value is None:
value = ['all'] value = ['all']
...@@ -86,97 +96,51 @@ class AtomSelectionConfigurator(IConfigurator): ...@@ -86,97 +96,51 @@ class AtomSelectionConfigurator(IConfigurator):
self["value"] = value self["value"] = value
self["indexes"] = [] indexes = set()
for v in value: for v in value:
if UD_STORE.has_definition(trajConfig["basename"],"atom_selection",v): if UD_STORE.has_definition(trajConfig["basename"],"atom_selection",v):
ud = UD_STORE.get_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: else:
parser = AtomSelectionParser(trajConfig["instance"].universe) 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')) atoms = sorted(trajConfig["universe"].atomList(), key = operator.attrgetter('index'))
selectedAtoms = [atoms[idx] for idx in self["indexes"]] selectedAtoms = [atoms[idx] for idx in indexes]
self["elements"] = [[at.symbol] for at in selectedAtoms]
self["selection_length"] = len(indexes)
if self._dependencies.has_key("grouping_level"): self['elements'] = [[at.symbol] for at in selectedAtoms]
self.group(selectedAtoms, configuration[self._dependencies['grouping_level']]['value']) self['indexes'] = [[idx] for idx in indexes]
else: self['names'] = [at.symbol for at in selectedAtoms]
self.group(selectedAtoms) self['unique_names'] = sorted(set(self['names']))
self['masses'] = [[ELEMENTS[n,'atomic_weight']] for n in self['names']]
self.set_contents()
def get_natoms(self):
@staticmethod
def find_parent(atom, level): nAtomsPerElement = {}
''' for v in self["names"]:
Retrieve recursively the parent of a given MMTK atom at a given level. if nAtomsPerElement.has_key(v):
For example, a level of 1 will return the direct parent of the atom. nAtomsPerElement[v] += 1
else:
:note: this is a static method nAtomsPerElement[v] = 1
:param atom: the atom for which the parent is searched for return nAtomsPerElement
:type atom: MMTK.Atom object
:param level: the level of the parent
:type level: int
'''
for _ in range(level):
atom = atom.parent
return atom
def group(self, atoms, level="atom"): def get_indexes(self):
'''
Group the selected atoms according to a given granularity and update indexesPerElement = {}
the configurator with the grouping results. for i,v in enumerate(self["names"]):
if indexesPerElement.has_key(v):
:param atoms: the atoms for indexesPerElement[v].extend(self['indexes'][i])
:type atoms: list of MMTK.Atom else:
:param level: the level of granularity at which the atoms should be grouped indexesPerElement[v] = self['indexes'][i]
: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
self.set_contents() return indexesPerElement
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)
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): def get_information(self):
''' '''
Returns some informations the atom selection. Returns some informations the atom selection.
...@@ -190,8 +154,6 @@ class AtomSelectionConfigurator(IConfigurator): ...@@ -190,8 +154,6 @@ class AtomSelectionConfigurator(IConfigurator):
info = [] info = []
info.append("Number of selected atoms:%d" % self["n_selected_atoms"]) 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()) info.append("Selected elements:%s" % self["contents"].keys())
return "\n".join(info) return "\n".join(info)
\ No newline at end of file
...@@ -53,7 +53,7 @@ class AtomTransmutationConfigurator(IConfigurator): ...@@ -53,7 +53,7 @@ class AtomTransmutationConfigurator(IConfigurator):
_default = None _default = None
def configure(self, configuration, value): def configure(self, value):
''' '''
Configure an input value. Configure an input value.
...@@ -65,14 +65,12 @@ class AtomTransmutationConfigurator(IConfigurator): ...@@ -65,14 +65,12 @@ class AtomTransmutationConfigurator(IConfigurator):
selection to the target chemical element stored in the 2nd element selection to the target chemical element stored in the 2nd element
#. str: the transmutation will be performed by reading the corresponding user definition #. 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 :param value: the input value
:type value: None or (str,str)-dict or str :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 the input value is None, do not perform any transmutation
if value is None: if value is None:
return return
...@@ -80,13 +78,11 @@ class AtomTransmutationConfigurator(IConfigurator): ...@@ -80,13 +78,11 @@ class AtomTransmutationConfigurator(IConfigurator):
if not isinstance(value,(list,tuple)): if not isinstance(value,(list,tuple)):
raise ConfiguratorError("Invalid input value.") raise ConfiguratorError("Invalid input value.")
self["atom_selection"] = configuration[self._dependencies['atom_selection']] trajConfig = self._configurable[self._dependencies['trajectory']]
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']]
parser = AtomSelectionParser(trajConfig["instance"].universe) parser = AtomSelectionParser(trajConfig["instance"].universe)
self._nTransmutatedAtoms = 0
for expression,element in value: for expression,element in value:
...@@ -96,17 +92,18 @@ class AtomTransmutationConfigurator(IConfigurator): ...@@ -96,17 +92,18 @@ class AtomTransmutationConfigurator(IConfigurator):
if UD_STORE.has_definition(trajConfig["basename"],"atom_selection",expression): if UD_STORE.has_definition(trajConfig["basename"],"atom_selection",expression):
ud = UD_STORE.get_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: else:
indexes = parser.parse(expression) indexes = parser.parse(expression)
self.transmutate(configuration, indexes, element)
self.transmutate(indexes, element)
def transmutate(self, configuration, selection, element):
self._nTransmutatedAtoms += len(indexes)
def transmutate(self, selection, element):
''' '''
Transmutates a set of atoms to a given 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 :param selection: the indexes of the atoms to be transmutated
:type selection: list of int :type selection: list of int
:param element: the symbol of the element to which the selected atoms should be transmutated :param element: the symbol of the element to which the selected atoms should be transmutated
...@@ -115,15 +112,15 @@ class AtomTransmutationConfigurator(IConfigurator): ...@@ -115,15 +112,15 @@ class AtomTransmutationConfigurator(IConfigurator):
if element not in ELEMENTS: if element not in ELEMENTS:
raise ConfiguratorError("the element %r is not registered in the database" % element, self) raise ConfiguratorError("the element %r is not registered in the database" % element, self)
atomSelConfigurator = self._configurable[self._dependencies['atom_selection']]
for idx in selection: for idx in selection:
pos = self["atom_selection"]["groups"].index([idx]) atomSelConfigurator["names"][idx] = element
self["atom_selection"]["elements"][pos] = [element] atomSelConfigurator["elements"][idx] = [element]
# Update the current configuration according to the changes triggered by
# atom transumutation
configuration[self._dependencies['atom_selection']].set_contents()
atomSelConfigurator['unique_names'] = sorted(set(atomSelConfigurator['names']))
def get_information(self): def get_information(self):
''' '''
Returns some informations the atoms selected for being transmutated. Returns some informations the atoms selected for being transmutated.
...@@ -136,6 +133,6 @@ class AtomTransmutationConfigurator(IConfigurator): ...@@ -136,6 +133,6 @@ class AtomTransmutationConfigurator(IConfigurator):
return "Not configured yet" return "Not configured yet"
if self["value"] is None: if self["value"] is None:
return "No atoms selected for deuteration" return "No atoms selected for transmutation"
return "Number of selected atoms for deuteration:%d\n" % self["atom_selection"]["n_selected_atoms"] return "Number of transmutated atoms:%d\n" % self._nTransmutatedAtoms
\ No newline at end of file \ No newline at end of file
...@@ -47,7 +47,7 @@ class AtomsListConfigurator(IConfigurator): ...@@ -47,7 +47,7 @@ class AtomsListConfigurator(IConfigurator):
_default = None _default = None
def __init__(self, name, nAtoms=2, **kwargs): def __init__(self, configurable, name, nAtoms=2, **kwargs):
''' '''
Initializes the configurator. Initializes the configurator.
...@@ -57,7 +57,7 @@ class AtomsListConfigurator(IConfigurator): ...@@ -57,7 +57,7 @@ class AtomsListConfigurator(IConfigurator):
:type nAtoms: int :type nAtoms: int
''' '''
IConfigurator.__init__(self, name, **kwargs) IConfigurator.__init__(self, configurable, name, **kwargs)
self._nAtoms = nAtoms self._nAtoms = nAtoms
...@@ -66,20 +66,18 @@ class AtomsListConfigurator(IConfigurator): ...@@ -66,20 +66,18 @@ class AtomsListConfigurator(IConfigurator):
return self._nAtoms return self._nAtoms
def configure(self, configuration, value): def configure(self, value):
''' '''
Configure an input value. Configure an input value.
The value must be a string that can be either an atom selection string or a valid user The value must be a string that can be either an atom selection string or a valid user
definition. definition.
:param configuration: the current configuration
:type configuration: a MDANSE.Framework.Configurable.Configurable object
:param value: the input value :param value: the input value
:type value: str :type value: str
''' '''
trajConfig = configuration[self._dependencies['trajectory']] trajConfig = self._configurable[self._dependencies['trajectory']]
if UD_STORE.has_definition(trajConfig["basename"],"%d_atoms_list" % self._nAtoms,value): 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) molecule,atoms = UD_STORE.get_definition(trajConfig["basename"],"%d_atoms_list" % self._nAtoms,value)
......
...@@ -47,7 +47,7 @@ class AxisSelection(IConfigurator): ...@@ -47,7 +47,7 @@ class AxisSelection(IConfigurator):
_default = None _default = None
def configure(self, configuration, value): def configure(self, value):
''' '''
Configure an input value. Configure an input value.
...@@ -64,7 +64,7 @@ class AxisSelection(IConfigurator): ...@@ -64,7 +64,7 @@ class AxisSelection(IConfigurator):
:type value: tuple or str :type value: tuple or str
''' '''
trajConfig = configuration[self._dependencies['trajectory']] trajConfig = self._configurable[self._dependencies['trajectory']]
if UD_STORE.has_definition(trajConfig["basename"],"axis_selection",value): if UD_STORE.has_definition(trajConfig["basename"],"axis_selection",value):
ud = UD_STORE.get_definition(trajConfig["basename"],"axis_selection",value) ud = UD_STORE.get_definition(trajConfig["basename"],"axis_selection",value)
......
...@@ -47,7 +47,7 @@ class BasisSelection(IConfigurator): ...@@ -47,7 +47,7 @@ class BasisSelection(IConfigurator):
_default = None _default = None
def configure(self, configuration, value): def configure(self, value):
''' '''
Configure an input value. Configure an input value.
...@@ -58,15 +58,13 @@ class BasisSelection(IConfigurator): ...@@ -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 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. #. 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 :param value: the input value
:type value: tuple or str :type value: tuple or str
:note: this configurator depends on 'trajectory' configurator to be configured :note: this configurator depends on 'trajectory' configurator to be configured
''' '''
trajConfig = configuration[self._dependencies['trajectory']] trajConfig = self._configurable[self._dependencies['trajectory']]
if UD_STORE.has_definition(trajConfig["basename"],"basis_selection",value): if UD_STORE.has_definition(trajConfig["basename"],"basis_selection",value):
ud = UD_STORE.get_definition(trajConfig["basename"],"basis_selection",value) ud = UD_STORE.get_definition(trajConfig["basename"],"basis_selection",value)
......
...@@ -47,7 +47,7 @@ class BooleanConfigurator(IConfigurator): ...@@ -47,7 +47,7 @@ class BooleanConfigurator(IConfigurator):
_shortCuts = {True : True, "true" : True , "yes" : True, "y" : True, "1" : True, 1 : True, _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} 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. Configure an input value.
......
...@@ -42,7 +42,7 @@ class ComplexNumberConfigurator(IConfigurator): ...@@ -42,7 +42,7 @@ class ComplexNumberConfigurator(IConfigurator):
_default = 0 _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. Initializes the configurator.
...@@ -57,7 +57,7 @@ class ComplexNumberConfigurator(IConfigurator): ...@@ -57,7 +57,7 @@ class ComplexNumberConfigurator(IConfigurator):
''' '''
# The base class constructor. # 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 self._mini = float(mini) if mini is not None else None
...@@ -65,12 +65,10 @@ class ComplexNumberConfigurator(IConfigurator): ...@@ -65,12 +65,10 @@ class ComplexNumberConfigurator(IConfigurator):
self._choices = choices if choices is not None else [] self._choices = choices if choices is not None else []
def configure(self, configuration, value): def configure(self, value):
''' '''
Configure an input value. Configure an input value.
:param configuration: the current configuration.
:type configuration: a MDANSE.Framework.Configurable.Configurable object
:param value: the input complex number. :param value: the input complex number.
:type value: complex :type value: complex
''' '''
......
...@@ -41,7 +41,7 @@ class FloatConfigurator(IConfigurator): ...@@ -41,7 +41,7 @@ class FloatConfigurator(IConfigurator):
_default = 0 _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. Initializes the configurator.
...@@ -56,7 +56,7 @@ class FloatConfigurator(IConfigurator): ...@@ -56,7 +56,7 @@ class FloatConfigurator(IConfigurator):
''' '''
# The base class constructor. # 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 self._mini = float(mini) if mini is not None else None
...@@ -64,12 +64,10 @@ class FloatConfigurator(IConfigurator): ...@@ -64,12 +64,10 @@ class FloatConfigurator(IConfigurator):