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
|