Package diffpy :: Package pdfgui :: Package gui :: Module datasetconfigurepanel
[hide private]
[frames] | no frames]

Source Code for Module diffpy.pdfgui.gui.datasetconfigurepanel

  1  #!/usr/bin/env python 
  2  # -*- coding: UTF-8 -*- 
  3  ############################################################################## 
  4  # 
  5  # PDFgui            by DANSE Diffraction group 
  6  #                   Simon J. L. Billinge 
  7  #                   (c) 2006 trustees of the Michigan State University. 
  8  #                   All rights reserved. 
  9  # 
 10  # File coded by:    Chris Farrow 
 11  # 
 12  # See AUTHORS.txt for a list of people who contributed. 
 13  # See LICENSE.txt for license information. 
 14  # 
 15  ############################################################################## 
 16   
 17  # generated by wxGlade 0.4 on Wed Feb 22 21:02:37 2006 
 18   
 19  import wx 
 20  from diffpy.pdfgui.gui.wxExtensions.validators import TextValidator, FLOAT_ONLY 
 21  from diffpy.pdfgui.gui.pdfpanel import PDFPanel 
 22  from diffpy.pdfgui.gui.tooltips import datasetconfigurepanel as toolTips 
 23  from diffpy.pdfgui.gui.wxExtensions.textctrlutils import textCtrlAsGridCell 
 24   
25 -class DataSetConfigurePanel(wx.Panel, PDFPanel):
26 - def __init__(self, *args, **kwds):
27 PDFPanel.__init__(self) 28 self.toolTips = toolTips 29 # begin wxGlade: DataSetConfigurePanel.__init__ 30 kwds["style"] = wx.TAB_TRAVERSAL 31 wx.Panel.__init__(self, *args, **kwds) 32 self.sizer_panelname_staticbox = wx.StaticBox(self, -1, "") 33 self.panelNameLabel = wx.StaticText(self, -1, "Data Set Configuration") 34 self.radioBoxStype = wx.RadioBox(self, -1, "Scatterer Type", choices=["Neutron", "X-ray"], majorDimension=2, style=wx.RA_SPECIFY_COLS) 35 self.radioBoxSampling = wx.RadioBox(self, -1, "Data Sampling", choices=["Data", "Nyquist", "Custom"], majorDimension=3, style=wx.RA_SPECIFY_COLS) 36 self.labelDataRange = wx.StaticText(self, -1, "Data Range") 37 self.textCtrlDataFrom = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY) 38 self.labelDataTo = wx.StaticText(self, -1, "to") 39 self.textCtrlDataTo = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY) 40 self.labelDataStep = wx.StaticText(self, -1, "spacing") 41 self.textCtrlDataStep = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY) 42 self.labelFitRange = wx.StaticText(self, -1, "Fit Range", style=wx.ALIGN_RIGHT) 43 self.textCtrlFitFrom = wx.TextCtrl(self, -1, "1.0") 44 self.labelFitTo = wx.StaticText(self, -1, "to", style=wx.ALIGN_RIGHT) 45 self.textCtrlFitTo = wx.TextCtrl(self, -1, "10.0") 46 self.labelFitStep = wx.StaticText(self, -1, "spacing") 47 self.textCtrlFitStep = wx.TextCtrl(self, -1, "0") 48 self.labelScaleFactor = wx.StaticText(self, -1, "Scale Factor", style=wx.ALIGN_RIGHT) 49 self.textCtrlScaleFactor = wx.TextCtrl(self, -1, "1.0") 50 self.labelQmax = wx.StaticText(self, -1, "Qmax", style=wx.ALIGN_RIGHT) 51 self.textCtrlQmax = wx.TextCtrl(self, -1, "25.0") 52 self.blank1_copy = wx.StaticText(self, -1, "") 53 self.blank1_copy_4 = wx.StaticText(self, -1, "") 54 self.labelQdamp = wx.StaticText(self, -1, "Qdamp", style=wx.ALIGN_RIGHT) 55 self.textCtrlQdamp = wx.TextCtrl(self, -1, "0.0") 56 self.labelQbroad = wx.StaticText(self, -1, "Qbroad", style=wx.ALIGN_RIGHT) 57 self.textCtrlQbroad = wx.TextCtrl(self, -1, "0.0") 58 self.blank1_copy_1 = wx.StaticText(self, -1, "") 59 self.blank1_copy_5 = wx.StaticText(self, -1, "") 60 self.labelTemperature = wx.StaticText(self, -1, "Temperature", style=wx.ALIGN_RIGHT) 61 self.textCtrlTemperature = wx.TextCtrl(self, -1, "300.0") 62 self.labelDoping = wx.StaticText(self, -1, "Doping", style=wx.ALIGN_RIGHT) 63 self.textCtrlDoping = wx.TextCtrl(self, -1, "1.0") 64 self.blank1_copy_3 = wx.StaticText(self, -1, "") 65 self.blank1_copy_7 = wx.StaticText(self, -1, "") 66 67 self.__set_properties() 68 self.__do_layout() 69 70 self.Bind(wx.EVT_RADIOBOX, self.onStype, self.radioBoxStype) 71 self.Bind(wx.EVT_RADIOBOX, self.onSampling, self.radioBoxSampling) 72 # end wxGlade 73 self.__customProperties()
74
75 - def __set_properties(self):
76 # begin wxGlade: DataSetConfigurePanel.__set_properties 77 self.panelNameLabel.SetFont(wx.Font(18, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) 78 self.radioBoxStype.SetMinSize((330, 43)) 79 self.radioBoxStype.SetSelection(0) 80 self.radioBoxSampling.SetMinSize((232, 44)) 81 self.radioBoxSampling.SetSelection(0) 82 self.textCtrlDataFrom.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRAYTEXT)) 83 self.textCtrlDataTo.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRAYTEXT)) 84 self.textCtrlDataStep.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRAYTEXT))
85 # end wxGlade 86
87 - def __do_layout(self):
88 # begin wxGlade: DataSetConfigurePanel.__do_layout 89 sizer_1 = wx.BoxSizer(wx.HORIZONTAL) 90 outerSizer = wx.BoxSizer(wx.VERTICAL) 91 grid_sizer_1 = wx.FlexGridSizer(8, 6, 5, 10) 92 sizer_panelname = wx.StaticBoxSizer(self.sizer_panelname_staticbox, wx.HORIZONTAL) 93 sizer_panelname.Add(self.panelNameLabel, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) 94 outerSizer.Add(sizer_panelname, 0, wx.LEFT|wx.RIGHT|wx.EXPAND, 5) 95 outerSizer.Add((450, 5), 0, 0, 0) 96 outerSizer.Add(self.radioBoxStype, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) 97 outerSizer.Add(self.radioBoxSampling, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) 98 grid_sizer_1.Add(self.labelDataRange, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) 99 grid_sizer_1.Add(self.textCtrlDataFrom, 0, 0, 0) 100 grid_sizer_1.Add(self.labelDataTo, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 20) 101 grid_sizer_1.Add(self.textCtrlDataTo, 0, 0, 0) 102 grid_sizer_1.Add(self.labelDataStep, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 20) 103 grid_sizer_1.Add(self.textCtrlDataStep, 0, 0, 0) 104 grid_sizer_1.Add(self.labelFitRange, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) 105 grid_sizer_1.Add(self.textCtrlFitFrom, 0, wx.ALIGN_CENTER_VERTICAL, 0) 106 grid_sizer_1.Add(self.labelFitTo, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 20) 107 grid_sizer_1.Add(self.textCtrlFitTo, 0, wx.ALIGN_CENTER_VERTICAL, 0) 108 grid_sizer_1.Add(self.labelFitStep, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 20) 109 grid_sizer_1.Add(self.textCtrlFitStep, 0, wx.ALIGN_CENTER_VERTICAL, 0) 110 grid_sizer_1.Add(self.labelScaleFactor, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) 111 grid_sizer_1.Add(self.textCtrlScaleFactor, 0, wx.ALIGN_CENTER_VERTICAL, 0) 112 grid_sizer_1.Add(self.labelQmax, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 20) 113 grid_sizer_1.Add(self.textCtrlQmax, 0, wx.ALIGN_CENTER_VERTICAL, 0) 114 grid_sizer_1.Add(self.blank1_copy, 0, 0, 0) 115 grid_sizer_1.Add(self.blank1_copy_4, 0, 0, 0) 116 grid_sizer_1.Add(self.labelQdamp, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) 117 grid_sizer_1.Add(self.textCtrlQdamp, 0, wx.ALIGN_CENTER_VERTICAL, 0) 118 grid_sizer_1.Add(self.labelQbroad, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 20) 119 grid_sizer_1.Add(self.textCtrlQbroad, 0, wx.ALIGN_CENTER_VERTICAL, 0) 120 grid_sizer_1.Add(self.blank1_copy_1, 0, 0, 0) 121 grid_sizer_1.Add(self.blank1_copy_5, 0, 0, 0) 122 grid_sizer_1.Add(self.labelTemperature, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) 123 grid_sizer_1.Add(self.textCtrlTemperature, 0, wx.ALIGN_CENTER_VERTICAL, 0) 124 grid_sizer_1.Add(self.labelDoping, 0, wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 20) 125 grid_sizer_1.Add(self.textCtrlDoping, 0, wx.ALIGN_CENTER_VERTICAL, 0) 126 grid_sizer_1.Add(self.blank1_copy_3, 0, 0, 0) 127 grid_sizer_1.Add(self.blank1_copy_7, 0, 0, 0) 128 outerSizer.Add(grid_sizer_1, 0, wx.ALL|wx.EXPAND, 5) 129 sizer_1.Add(outerSizer, 1, wx.EXPAND, 0) 130 self.SetSizer(sizer_1) 131 sizer_1.Fit(self)
132 # end wxGlade 133 134 # USER CONFIGURATION CODE ################################################# 135
136 - def __customProperties(self):
137 # Set some reasonable defaults 138 self.configuration = None 139 self.constraints = {} 140 self.stypeMap = {0: 'N', 1: 'X'} 141 self.metaNames = ['doping', 'temperature'] 142 self.constrainables = ['dscale', 'qdamp', 'qbroad'] 143 self.sampList = ["data", "Nyquist", "custom"] 144 self._focusedText = None 145 146 # Note that the rstep and fitrstep attributes are special cases, so they 147 # are handled separately. Qmax is also handled with these. 148 self.ctrlMap = {'fitrmin' : 'textCtrlFitFrom', 149 'fitrmax' : 'textCtrlFitTo', 150 'rmin' : 'textCtrlDataFrom', 151 'rmax' : 'textCtrlDataTo', 152 'dscale' : 'textCtrlScaleFactor', 153 'qdamp' : 'textCtrlQdamp', 154 'qbroad' : 'textCtrlQbroad', 155 'temperature' : 'textCtrlTemperature', 156 'doping' : 'textCtrlDoping', 157 } 158 159 # Give each textCtrl a name that can be referenced and setup the 160 # validator 161 for (key, value) in self.ctrlMap.items(): 162 textCtrl = getattr(self, value) 163 textCtrl.SetName(key) 164 textCtrl.SetValidator(TextValidator(FLOAT_ONLY)) 165 self.textCtrlFitStep.SetValidator(TextValidator(FLOAT_ONLY)) 166 167 # Setup the event code. 168 for ctrlName in self.ctrlMap.values(): 169 textCtrl = getattr(self, ctrlName) 170 textCtrl.Bind(wx.EVT_SET_FOCUS, self.onSetFocus) 171 textCtrl.Bind(wx.EVT_KILL_FOCUS, self.onLoseFocus) 172 textCtrl.Bind(wx.EVT_KEY_DOWN, self.onTextCtrlKey) 173 174 self.textCtrlFitStep.Bind(wx.EVT_KILL_FOCUS, self.onSampling) 175 self.textCtrlQmax.Bind(wx.EVT_KILL_FOCUS, self.onSampling) 176 self.textCtrlFitStep.Bind(wx.EVT_KEY_DOWN, self.onTextCtrlKey) 177 self.textCtrlQmax.Bind(wx.EVT_KEY_DOWN, self.onTextCtrlKey) 178 179 # For blocked text controls. 180 self.message = "This variable is constrained. Edit the associated parameter." 181 return
182 183 # Create the onTextCtrlKey event handler from textCtrlAsGridCell from 184 # wxExtensions.textctrlutils 185 onTextCtrlKey = textCtrlAsGridCell 186
187 - def setConfigurationData(self):
188 """Set the values in the configuration panel. 189 190 The values come from the configuration member dictionary. 191 stype -- 'N' or 'X' 192 dscale -- float 193 qmax -- float 194 qdamp -- float 195 rmin -- float 196 rmax -- float 197 fitrmin -- float 198 fitrmax -- float 199 temperature -- float 200 doping -- float 201 """ 202 if not self.configuration: return 203 204 stype = self.configuration.stype 205 206 if stype == 'N': 207 self.radioBoxStype.SetSelection(0) 208 elif stype == 'X': 209 self.radioBoxStype.SetSelection(1) 210 else: 211 self.configuration.stype = 'N' 212 self.radioBoxStype.SetSelection(0) 213 214 # iterate over all configurable items 215 for (key, value) in self.ctrlMap.items(): 216 textCtrl = getattr(self, value) 217 218 if key in self.metaNames: 219 value = self.configuration.metadata.get(key) 220 else: 221 value = getattr(self.configuration, key) 222 223 if value is not None: 224 textCtrl.SetValue(str(value)) 225 else: 226 textCtrl.SetValue('0.0') 227 228 # Set qmax 229 val = self.configuration.qmax 230 self.textCtrlQmax.SetValue(str(val)) 231 232 # Set the data step 233 val = self.configuration.getObsSampling() 234 self.textCtrlDataStep.SetValue(str(val)) 235 236 # Set up the sampling type and fit step type 237 st = self.configuration.getFitSamplingType() 238 si = self.sampList.index(st) 239 self.radioBoxSampling.SetSelection(si) 240 val = self.configuration.fitrstep 241 self.textCtrlFitStep.SetValue(str(val)) 242 243 # Make sure the sampling info is consistent 244 self.onSampling(None) 245 return
246
248 """Set 'read-only' boxes that correspond to constrained parameters.""" 249 if not self.configuration: return 250 251 self.setToolTips(toolTips) 252 253 for key in self.constrainables: 254 value = self.ctrlMap[key] 255 textCtrl = getattr(self, value) 256 if key in self.constraints: 257 textCtrl.SetEditable(False) 258 textCtrl.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRAYTEXT)) 259 textCtrl.SetToolTipString(self.constraints[key].formula) 260 else: 261 textCtrl.SetEditable(True) 262 textCtrl.SetBackgroundColour(wx.NullColour) 263 264 return
265
266 - def __coerseText(self, value):
267 """Turn the text representation of a float into a float.""" 268 if not value: 269 value = '0' 270 if value[-1].lower() in ('-', 'e'): 271 value += '0' 272 return float(value)
273
274 - def __adjustFitRange(self, name, value):
275 """Check the fit range values. 276 277 The fit range values are set to their defaults (the data range) when the 278 fit range is nonsensical. 279 """ 280 if name == 'fitrmin': 281 if value < self.configuration.rmin or\ 282 value >= self.configuration.fitrmax: 283 value = self.configuration.rmin 284 self.textCtrlFitFrom.SetValue(str(value)) 285 elif name == 'fitrmax': 286 if value < self.configuration.fitrmin or\ 287 value >= self.configuration.rmax: 288 value = self.configuration.rmax 289 self.textCtrlFitTo.SetValue(str(value)) 290 return value
291 292 # EVENT CODE ############################################################# 293
294 - def onStype(self, event): # wxGlade: DataSetConfigurePanel.<event_handler>
295 """Record the user's selection for stype.""" 296 value = event.GetInt() 297 self.configuration.stype = self.stypeMap[value] 298 self.mainFrame.needsSave() 299 return
300
301 - def onSampling(self, event): # wxGlade: DataSetConfigurePanel.<event_handler>
302 """Record how the data is to be sampled during the fit. 303 304 This does not use the event argument, so feel free to call this method 305 programmatically. 306 """ 307 si = self.radioBoxSampling.GetSelection() 308 oldsampling = self.configuration.getFitSamplingType() 309 sampling = self.sampList[si] 310 oldstep = self.configuration.fitrstep 311 # Get the value of the custom sampling and enable/disable status 312 if sampling == "custom": # "custom" 313 step = self.__coerseText(self.textCtrlFitStep.GetValue()) 314 self.textCtrlFitStep.SetEditable(True) 315 self.textCtrlFitStep.SetBackgroundColour(wx.NullColour) 316 else: 317 step = None 318 self.textCtrlFitStep.SetEditable(False) 319 self.textCtrlFitStep.SetBackgroundColour( 320 wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRAYTEXT)) 321 322 # Set the value of qmax 323 val = self.__coerseText(self.textCtrlQmax.GetValue()) 324 oldqmax = self.configuration.qmax 325 if oldqmax != val: 326 self.configuration.qmax = val 327 self.mainFrame.needsSave() 328 329 # Set the configured value 330 if oldsampling != sampling or (sampling == "custom" and oldstep != 331 step): 332 self.configuration.setFitSamplingType(sampling, step) 333 self.mainFrame.needsSave() 334 # Update the text control 335 self.textCtrlFitStep.SetValue(str(self.configuration.fitrstep)) 336 337 return 338
339 - def onSetFocus(self, event):
340 """Saves a TextCtrl value, to be used later.""" 341 self._focusedText = event.GetEventObject().GetValue() 342 return
343
344 - def onLoseFocus(self, event):
345 """Record the user's selection for the text ctrl data.""" 346 if not self.configuration: return 347 textCtrl = event.GetEventObject() 348 value = textCtrl.GetValue() 349 value = self.__coerseText(value) 350 name = textCtrl.GetName() 351 # Check the fit range 352 value = self.__adjustFitRange(name, value) 353 if name in self.metaNames: 354 temp = self.configuration.metadata.get(name) 355 if temp != value: 356 self.configuration.metadata[name] = value 357 self.mainFrame.needsSave() 358 else: 359 temp = getattr(self.configuration, name) 360 if temp != value: 361 setattr(self.configuration, name, value) 362 self.mainFrame.needsSave() 363 return
364 365 # Methods overloaded from PDFPanel 366
367 - def refresh(self):
368 """Refresh the panel.""" 369 self.setConfigurationData() 370 self.restrictConstrainedParameters() 371 return
372 373 374 # end of class DataSetConfigurePanel 375 376 377 __id__ = "$Id: datasetconfigurepanel.py 2981 2009-04-02 02:13:58Z farrowch $" 378