File: gse_ctr.py

package info (click to toggle)
genx 3.8.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 39,152 kB
  • sloc: python: 79,013; makefile: 153; sh: 92; xml: 7
file content (228 lines) | stat: -rw-r--r-- 9,830 bytes parent folder | download | duplicates (2)
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
52
53
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
''' <h1>gsecars ctr data loader </h1>
Loads the data from whitespace seperated column formatted ascii data files.
It is intended for surface x-ray diffraction data where the data sets consists
of rod scans along the l-direction (perpendicular to the surface). The plugin
sorts each rod with equal h and k values into one data sets. The l-direction 
is also sorted. <p>
The default columns are the following:<br>
1st column h values; 2nd column k values; 3rd values l values;
4th column Intensites; 5th column The standard deviation of the intensities;
6th column L of first Bragg peak, 7th column L spacing of Bragg peaks
 The other settings are just as in the default data loader.<p>

The h,k values is stored as extra data in data.extra_data dictonary as
h and k. 
'''

import numpy as np
import wx
from wx.lib.masked import NumCtrl

from genx.plugins.data_loader_framework import Template
from genx.plugins.utils import ShowErrorDialog, ShowWarningDialog, ShowInfoDialog

class Plugin(Template):
    def __init__(self, parent):
        Template.__init__(self, parent)
        self.h_col = 0
        self.k_col = 1
        self.l_col = 2
        self.I_col = 3
        self.eI_col =4
        self.LB_col = 5
        self.dL_col = 6
        self.comment = '#'
        self.skip_rows = 0
        self.delimiter = None
    
    def LoadData(self, data_item_number, filename):
        '''LoadData(self, data_item_number, filename) --> none
        
        Loads the data from filename into the data_item_number.
        '''
        try:
            load_array = np.loadtxt(filename, delimiter = self.delimiter, 
                comments = self.comment, skiprows = self.skip_rows)
        except Exception as e:
            ShowWarningDialog(self.parent, 'Could not load the file: ' +\
                    filename + ' \nPlease check the format.\n\n numpy.loadtxt'\
                    + ' gave the following error:\n'  +  str(e))
        else:
            # For the freak case of only one data point
            if len(load_array.shape) < 2:
                load_array = np.array([load_array])
            # Check so we have enough columns
            if load_array.shape[1]-1 < max(self.h_col, self.k_col,\
                     self.l_col, self.I_col, self.eI_col, self.LB_col, self.dL_col):
                ShowWarningDialog(self.parent, 'The data file does not contain'\
                        + 'enough number of columns. It has ' + str(load_array.shape[1])\
                        + ' columns. Rember that the column index start at zero!')
                # Okay now we have showed a dialog lets bail out ...
                return
            # The data is set by the default Template.__init__ function, neat hu
            # Note that the loaded data goes into *_raw so that they are not
            # changed by the transforms
            
            # Create an record array so we can sort the data properly
            data = np.rec.fromarrays([\
                     load_array[:,self.h_col].round().astype(type(1)),\
                     load_array[:,self.k_col].round().astype(type(1)),\
                     load_array[:,self.l_col], load_array[:,self.I_col],\
                     load_array[:,self.eI_col],\
                     load_array[:,self.LB_col], load_array[:,self.dL_col]\
                    ],\
                     names = 'h, k, l, I, eI, LB, dL')
            # Sort the data
            data.sort(order = ('h','k','l'))
            i = 0
            while i < len(data):
                # Find all the data for each rod
                tmp = data.compress(np.bitwise_and(data['h'] == data[i]['h'],\
                                    data['k'] == data[i]['k']))
                self.data.add_new('(%i, %i)'%(tmp['h'][0], tmp['k'][0]))
                self.data[-1].x_raw = tmp['l']
                self.data[-1].y_raw =tmp['I']
                self.data[-1].error_raw = tmp['eI']
                # Run the commands on the data - this also sets the x,y, error memebers
                # of that data item.
                self.data[-1].run_command()
                self.data[-1].set_extra_data('h', tmp['h'], 'h')
                self.data[-1].set_extra_data('k', tmp['k'], 'k')
                self.data[-1].set_extra_data('LB', tmp['LB'], 'LB')
                self.data[-1].set_extra_data('dL', tmp['dL'], 'dL')
                # Increase the index
                i += len(tmp)
            
            # Update the data list
            self.UpdateDataList()
            # Send an update that new data has been loaded
            self.SendUpdateDataEvent()
            
        
    def SettingsDialog(self):
        '''SettingsDialog(self) --> None
        
        This function should - if necessary implement a dialog box
        that allows the user set import settings for example.
        '''
        col_values = {'I': self.I_col,'h': self.h_col,'k': self.k_col,\
                        'l': self.l_col, 'I error': self.eI_col,\
                        'LB': self.LB_col,'dL': self.dL_col,}
        misc_values = {'Comment': str(self.comment), 'Skip rows': self.skip_rows,\
                'Delimiter': str(self.delimiter)}
        dlg = SettingsDialog(self.parent, col_values, misc_values)
        if dlg.ShowModal() == wx.ID_OK:
            col_values = dlg.GetColumnValues()
            misc_values = dlg.GetMiscValues()
            self.h_col = col_values['h']
            self.k_col = col_values['k']
            self.l_col = col_values['l']
            self.I_col = col_values['I']
            self.eI_col = col_values['I error']
            self.LB_col = col_values['LB']
            self.dL_col = col_values['dL']
            self.comment = misc_values['Comment']
            self.skip_rows = misc_values['Skip rows']
            self.delimiter = misc_values['Delimiter']
            self.SetStatusText('Changed import settings')
        else:
            self.SetStatusText('No change to import settings')
        dlg.Destroy()
        
        
class SettingsDialog(wx.Dialog):
    
    def __init__(self, parent, col_values, misc_values):
        wx.Dialog.__init__(self, parent, -1, 'Data loader settings')
        
        box_sizer = wx.BoxSizer(wx.HORIZONTAL)
        
        # Make the box for putting in the columns
        col_box = wx.StaticBox(self, -1, "Columns" )
        col_box_sizer = wx.StaticBoxSizer(col_box, wx.VERTICAL )
        
        
        #col_values = {'y': 1,'x': 0,'y error': 1}
        col_grid = wx.GridBagSizer(len(col_values), 2)
        self.col_controls = col_values.copy()
        keys = col_values.keys()
        keys.sort()
        for i, name in enumerate(keys):
            text = wx.StaticText(self, -1, name+': ')
            control = wx.SpinCtrl(self)
            control.SetRange(0,100)
            control.SetValue(col_values[name])
            col_grid.Add(text, (i,0),\
                    flag = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL,\
                    border = 5)
            col_grid.Add(control, (i,1),\
                    flag = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL,\
                    border = 5)
            self.col_controls[name] = control
        
        col_box_sizer.Add(col_grid, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
        box_sizer.Add(col_box_sizer, 0, wx.ALIGN_CENTRE|wx.ALL|wx.EXPAND, 5)
        
        col_box = wx.StaticBox(self, -1, "Misc" )
        col_box_sizer = wx.StaticBoxSizer(col_box, wx.VERTICAL )
        
        # Lets add another box for comments and rows to skip
        #misc_values = {'Comment': '#', 'Skip rows': 0,'Delimiter': 'None'}
        col_grid = wx.GridBagSizer(len(misc_values), 2)
        self.misc_controls = misc_values.copy()
        keys = misc_values.keys()
        keys.sort()
        for i, name in enumerate(keys):
            text = wx.StaticText(self, -1, name+': ')
            if type(misc_values[name]) == type(1):
                control = wx.SpinCtrl(self)
                control.SetRange(0,100)
                control.SetValue(misc_values[name])
            else:
                control = wx.TextCtrl(self, value = misc_values[name],\
                        style = wx.EXPAND)
            col_grid.Add(text, (i,0),\
                    flag = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL,\
                    border = 5)
            col_grid.Add(control, (i,1),\
                    flag = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL,\
                    border = 5)
            self.misc_controls[name] = control
        
        col_box_sizer.Add(col_grid, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
        box_sizer.Add(col_box_sizer, 0, wx.ALIGN_CENTRE|wx.ALL|wx.EXPAND, 5)
        
        button_sizer = wx.StdDialogButtonSizer()
        okay_button = wx.Button(self, wx.ID_OK)
        okay_button.SetDefault()
        button_sizer.AddButton(okay_button)
        button_sizer.AddButton(wx.Button(self, wx.ID_CANCEL))
        button_sizer.Realize()
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(box_sizer, 1, wx.GROW, 20)
        line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
        sizer.Add(line, 0, wx.GROW, 30)
        
        sizer.Add(button_sizer,0,\
                flag = wx.ALIGN_RIGHT, border = 20)
        self.SetSizer(sizer)
        
        sizer.Fit(self)
        self.Layout()
        
    def GetColumnValues(self):
        values = {}
        for key in self.col_controls:
            values[key] = self.col_controls[key].GetValue()
        return values
    
    def GetMiscValues(self):
        values = {}
        for key in self.misc_controls:
            val = self.misc_controls[key].GetValue()
            if (type(val) == type(u'') or type(val) == type('')):
                if val.lower() == 'none':
                    val = None
            values[key] = val
        return values