AtomTransmutationConfigurator.py 5.58 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, 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
69
70
        
        :param value: the input value
        :type value: None or (str,str)-dict or str 
        '''
71

72
73
        self["value"] = value
                        
74
        # if the input value is None, do not perform any transmutation
75
76
        if value is None:
            return
77
78
79
        
        if not isinstance(value,(list,tuple)):
            raise ConfiguratorError("Invalid input value.")
80

81
        trajConfig = self._configurable[self._dependencies['trajectory']]
82
                                                                
83
84
85
        parser = AtomSelectionParser(trajConfig["instance"].universe)        

        self._nTransmutatedAtoms = 0
86
87
88
89
90
91
92

        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)
                
93
            if UD_STORE.has_definition(trajConfig["basename"],"atom_selection",expression):                
94
                ud = UD_STORE.get_definition(trajConfig["basename"],"atom_selection",expression)
95
                indexes = ud["indexes"]
eric pellegrini's avatar
eric pellegrini committed
96
            else:
97
                indexes = parser.parse(expression)
98
99
100
101
102
103
                
            self.transmutate(indexes, element)
            
            self._nTransmutatedAtoms += len(indexes)
                
    def transmutate(self, selection, element):
104
105
106
107
108
        '''
        Transmutates a set of atoms to a given element 
        
        :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
        
        if element not in ELEMENTS:
            raise ConfiguratorError("the element %r is not registered in the database" % element, self)
115
116

        atomSelConfigurator = self._configurable[self._dependencies['atom_selection']]
117
118
                
        for idx in selection:
119
120
            atomSelConfigurator["names"][idx] = element
            atomSelConfigurator["elements"][idx] = [element]
121

122
123
        atomSelConfigurator['unique_names'] = sorted(set(atomSelConfigurator['names']))
            
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
        if self["value"] is None:
136
            return "No atoms selected for transmutation"
137
        
138
        return "Number of transmutated atoms:%d\n" % self._nTransmutatedAtoms