AtomsListWidget.py 6.69 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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#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 Jun 30, 2015

:author: Eric C. Pellegrini
'''

import os

import wx

from MDANSE import LOGGER
from MDANSE.App.GUI.Framework.Widgets.UserDefinitionWidget import UserDefinitionsDialog, UserDefinitionWidget
from MDANSE.MolecularDynamics.Trajectory import find_atoms_in_molecule, get_chemical_objects_dict

class AtomsListDialog(UserDefinitionsDialog):

    def __init__(self, parent, trajectory, nAtoms):
        
        self._parent = parent

        self._trajectory = trajectory
    
        self._nAtoms = nAtoms
        
        self._selectedAtoms = []
eric pellegrini's avatar
eric pellegrini committed
52
53
        
        self._selection = []
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
                
        target = os.path.basename(self._trajectory.filename)
        
        section = "%d_atoms_list" % self._nAtoms

        UserDefinitionsDialog.__init__(self, parent, target, section, wx.ID_ANY, title="%d Atoms selection dialog" % nAtoms,style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.MINIMIZE_BOX|wx.MAXIMIZE_BOX)
                        
    def build_dialog(self):

        panel = wx.ScrolledWindow(self, wx.ID_ANY, size=self.GetSize())
        panel.SetScrollbars(20,20,50,50)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        
        sb = wx.StaticBox(panel, wx.ID_ANY, label = "Atom selection")
        sbSizer = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
        
        gbSizer = wx.GridBagSizer(5,5)
        
        label1 = wx.StaticText(panel, wx.ID_ANY, label="Molecules")
        label2 = wx.StaticText(panel, wx.ID_ANY, label="Atoms")

        gbSizer.Add(label1, (0,0), flag=wx.EXPAND)
        gbSizer.Add(label2, (0,1), flag=wx.EXPAND)
    
        self._molecules = wx.ListBox(panel, wx.ID_ANY, style = wx.LB_SINGLE|wx.LB_NEEDED_SB)
        self._molecularContents = get_chemical_objects_dict(self._trajectory.universe)
        self._molecules.SetItems(sorted(self._molecularContents.keys()))        

        self._atoms = wx.ListBox(panel, wx.ID_ANY, style = wx.LB_MULTIPLE|wx.LB_NEEDED_SB)
        
        gbSizer.Add(self._molecules, (1,0), flag=wx.EXPAND)
        gbSizer.Add(self._atoms    , (1,1), flag=wx.EXPAND)
        
        gbSizer.AddGrowableRow(1)
        gbSizer.AddGrowableCol(0)
        gbSizer.AddGrowableCol(1)
        
        sbSizer.Add(gbSizer, 1, wx.EXPAND|wx.ALL, 5)

        setButton  = wx.Button(panel, wx.ID_ANY, label="Set")
        self._resultsTextCtrl  = wx.TextCtrl(panel, wx.ID_ANY, style=wx.TE_READONLY|wx.TE_MULTILINE)

        sizer.Add(sbSizer,1,wx.EXPAND|wx.ALL,5)
        sizer.Add(setButton,0,wx.EXPAND|wx.ALL,5)
        sizer.Add(self._resultsTextCtrl,1,wx.EXPAND|wx.ALL,5)

        panel.SetSizer(sizer)

        self._mainSizer.Add(panel, 1, wx.EXPAND|wx.ALL, 5)
                
        self.Bind(wx.EVT_BUTTON, self.on_set_user_definition, setButton)
        self.Bind(wx.EVT_LISTBOX, self.on_select_molecule, self._molecules)
        self.Bind(wx.EVT_LISTBOX, self.on_select_atom, self._atoms)

    def set_user_definition(self):

eric pellegrini's avatar
eric pellegrini committed
111
        self._selection = []
112
113
114
115
116
117
118
119

        if len(self._selectedAtoms) != self._nAtoms:
            LOGGER('You must select %d atoms.' % self._nAtoms,'error',['dialog'])
            return

        molecule = str(self._molecules.GetStringSelection())
        atoms = tuple(str(self._atoms.GetString(idx)) for idx in self._selectedAtoms)

eric pellegrini's avatar
eric pellegrini committed
120
        self._selection = find_atoms_in_molecule(self._trajectory.universe,molecule, atoms, True)
121
122
123
124
125
126
                        
    def on_set_user_definition(self,event=None):

        self._resultsTextCtrl.Clear()
        
        self.set_user_definition()
eric pellegrini's avatar
eric pellegrini committed
127
        if not self._selection:
128
129
            return
            
eric pellegrini's avatar
eric pellegrini committed
130
131
        self._resultsTextCtrl.AppendText('Number of selected %d-tuplets: %d\n' % (self._nAtoms,len(self._selection)))
        for idxs in self._selection:
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
            line = "   ;   ".join(["Atom %d : %s" % (i,v) for i,v in enumerate(idxs)])
            self._resultsTextCtrl.AppendText(line)
            self._resultsTextCtrl.AppendText('\n')
        
    def on_select_atom(self, event):
        
        selection = self._atoms.GetSelections()
                
        if len(selection) > self._nAtoms:
            self._atoms.DeselectAll()
            for idx in self._selectedAtoms:
                self._atoms.SetSelection(idx,True)
        else:
            self._selectedAtoms = selection
                            
    def on_select_molecule(self, event):
        
        atomsList = self._molecularContents[event.GetString()][0].atomList()
        atomNames = sorted(set([at.name for at in atomsList]))
        
        self._atoms.SetItems(atomNames)
            
    def validate(self):

eric pellegrini's avatar
eric pellegrini committed
156
        if not self._selection:
157
158
            return None
                        
eric pellegrini's avatar
eric pellegrini committed
159
        return {'selection' : self._selection}
160
161
162
163
164
165
166
167
168

class AtomListWidget(UserDefinitionWidget):
        
    type = "atoms_list"
    
    def initialize(self):
        
        UserDefinitionWidget.initialize(self)
        
169
        self.type = "%d_atoms_list" % self._configurator.nAtoms
170
171
172
        
    def on_new_user_definition(self,event):
        
173
        atomsListDlg = AtomsListDialog(self,self._trajectory,self.configuration[self._name].nAtoms)
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
        
        atomsListDlg.ShowModal()
            
        atomsListDlg.Destroy()
        
if __name__ == "__main__":
    
    from MMTK.Trajectory import Trajectory
    
    t = Trajectory(None,"../../../../../Data/Trajectories/MMTK/waterbox_in_periodic_universe.nc","r")
    
    app = wx.App(False)
                
    p = AtomsListDialog(None,t,2)
                
    p.ShowModal()
    
    p.Destroy()
    
    app.MainLoop()