AtomTransmutationConfigurator.py 5.96 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#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 30, 2015

30
:author: Eric C. Pellegrini
31
32
'''

33
from MDANSE import ELEMENTS
34
from MDANSE.Framework.UserDefinitionStore import UD_STORE
35
from MDANSE.Framework.Configurators.IConfigurator import IConfigurator, ConfiguratorError
36
from MDANSE.Framework.AtomSelectionParser import AtomSelectionParser
37
38
39
        
class AtomTransmutationConfigurator(IConfigurator):
    """
40
41
    This configurator allows to define a set of atoms to be transmutated to a given chemical
    element.
42
43
44
45
46
47
    
    For some analysis it can be necessary to change the nature of the chemical element of a given
    part of the system to have results closer to experience. A good example is to change some 
    hydrogen atoms to deuterium in order to fit with experiments where deuteration experiments have 
    been performed for improving the contrast and having a better access to the dynamic of a specific part
    of the molecular system.
48
            
49
    :note: this configurator depends on 'trajectory' and 'atom_selection' configurators to be configured
50
    """
51
    
52
    type = 'atom_transmutation'
53
54
    
    _default = None
55
56
                                
    def configure(self, configuration, value):
57
        '''
58
        Configure an input value. 
59
60
        
        The value can be:
61
        
62
63
64
65
66
        #. ``None``: no transmutation is performed
        #. (str,str)-dict: for each (str,str) pair, a transmutation will be performed by parsing \
        the 1st element as an atom selection string and transmutating the corresponding atom \
        selection to the target chemical element stored in the 2nd element
        #. str: the transmutation will be performed by reading the corresponding user definition
67
68
        
        :param configuration: the current configuration
69
        :type configuration: MDANSE.Framework.Configurable.Configurable
70
71
72
        :param value: the input value
        :type value: None or (str,str)-dict or str 
        '''
73
74
75

        self["value"] = value  
        
76
        # if the input value is None, do not perform any transmutation
77
78
79
80
81
82
83
84
85
        if value is None:
            return

        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']]
                                                                
86
        parser = AtomSelectionParser(trajConfig["instance"].universe)
87
88
89
90
91
92
93
94
95
96

        for expression,element in value:
                  
            # Otherwise, it must be a string that will be found as a user-definition keys
            if not isinstance(expression,basestring):
                raise ConfiguratorError("Wrong format for atom transmutation configurator.",self)
                
            if UD_STORE.has_definition(trajConfig["basename"],"atom_transmutation",expression):                
                ud = UD_STORE.get_definition(trajConfig["basename"],"atom_selection",expression)
                self.transmutate(configuration, ud["indexes"], element)
eric pellegrini's avatar
eric pellegrini committed
97
            else:
98
99
                indexes = parser.parse(expression)
                self.transmutate(configuration, indexes, element)                    
100
101

    def transmutate(self, configuration, selection, element):
102
103
104
105
        '''
        Transmutates a set of atoms to a given element 
        
        :param configuration: the current configuration
106
        :type configuration: MDANSE.Framework.Configurable.Configurable
107
108
        :param selection: the indexes of the atoms to be transmutated
        :type selection: list of int
109
        :param element: the symbol of the element to which the selected atoms should be transmutated
110
111
        :type element: str
        '''
112
113
114
115
116
        
        if element not in ELEMENTS:
            raise ConfiguratorError("the element %r is not registered in the database" % element, self)
                
        for idx in selection:
117
118
119
120
121
            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                
eric pellegrini's avatar
test    
eric pellegrini committed
122
        configuration[self._dependencies['atom_selection']].set_contents()
123
124

    def get_information(self):
125
        '''
126
        Returns some informations the atoms selected for being transmutated.
127
        
128
        :return: the information about the atoms selected for being transmutated.
129
130
        :rtype: str
        '''
131
132
133

        if not self.has_key("value"):
            return "Not configured yet"
134
                
135
136
137
138
        if self["value"] is None:
            return "No atoms selected for deuteration"
        
        return "Number of selected atoms for deuteration:%d\n" % self["atom_selection"]["n_selected_atoms"]