1 import wx
2 import wx.aui
3 import traceback
4 import numpy
5
6 from reflModelBuilder import ReflModelBuilder
7
8 USEMATPLOT=False
9 if USEMATPLOT:
10 from matDatasetPanel import MatDatasetPanel as ReflDatasetPanel
11 from matFittingResidual import MatFittingResidual as ReflFittingResidual
12 else:
13 from reflDatasetPanel import ReflDatasetPanel
14 from reflFittingResidual import ReflFittingResidual
15
16 import park
17 from park.parkAui.common.auiPanel import AuiPanel
18 from park.parkAui.common.parkEvent import ParkDatasetEvent, wxEVT_PARK_DATASET,\
19 DATASET_UPDATE, EVT_PARK_DATASET, \
20 EVT_PARK_MODEL, EVT_PARK_PARAMETER, \
21 ParkModelEvent, ParkParameterEvent
22
23 from reflectometry.model1d.model.calcRefl import convolve, reflectivity, \
24 magnetic_reflectivity
25
26 REFL_DATASET_TITLE = 'data set'
27 REFL_MODEL_TITLE = 'model builder'
28
29 DefaultPaneInfo = lambda : \
30 wx.aui.AuiPaneInfo().CloseButton(False).PinButton(True).MaximizeButton(
31 True).MinimizeButton(True).CaptionVisible(True).CloseButton(True)
32
33 BUILDER_TITLE = 'Refl Model Builder'
34 BUILDER_NAME = 'Builder'
35 DATASET_TITLE = 'Dataset Viewer'
36 DATASET_NAME = 'Dataset'
37 RESIDUAL_TITLE = 'Refl Fitting Residual'
38 RESIDUAL_NAME = 'Residual'
39 PARAMETER_TITLE = 'Parameter Table'
40 PARAMETER_NAME = 'Parameter'
41
42
43 -class ReflModelPage(AuiPanel):
44 """ The page for model notebook. """
45 - def __init__(self,
46 parent,
47 id=-1,
48 pos=wx.DefaultPosition,
49 size=(800,400)
50 ):
51 super(ReflModelPage, self).__init__(parent, id, pos=pos, size=size)
52
53 self.parent = parent
54 self.datasetPanel = ReflDatasetPanel(self )
55 self.builderPanel = ReflModelBuilder(self)
56 self.residualPanel = ReflFittingResidual(self)
57
58 self._mgr = wx.aui.AuiManager(self)
59
60 self._mgr.AddPane(self.datasetPanel, DefaultPaneInfo().Left(
61 ).Caption( REFL_DATASET_TITLE
62 ).Name(DATASET_NAME))
63
64 self._mgr.AddPane(self.builderPanel, DefaultPaneInfo().Center(
65 ).Caption( BUILDER_TITLE ).Name(BUILDER_NAME))
66
67 if self.residualPanel is not None:
68 self._mgr.AddPane(self.residualPanel, DefaultPaneInfo().Left(
69 ).Caption(RESIDUAL_TITLE).Name(RESIDUAL_NAME))
70 self._mgr.GetPane(RESIDUAL_NAME).Show(False)
71
72 self._mgr.Update()
73
74 self.settings={}
75
76 self.StorePerspective()
77
78 self.defaultPerspective = self.settings
79
80 self._mgr.Bind(wx.aui.EVT_AUI_PANE_BUTTON, self.OnAuiButtonPressed)
81
82 self.model = None
83 self.SetEditMode(True)
84
85 self.builderPanel.Bind(EVT_PARK_MODEL, self.OnModelUpdated)
86 self.builderPanel.Bind(EVT_PARK_PARAMETER,self.OnModelParameterUpdated)
87 self.datasetPanel.Bind(EVT_PARK_DATASET, self.OnDatasetUpdated)
88
89
92
93
95 self.settings['perspectives'] = self._mgr.SavePerspective()
96 self.datasetPanel.SetPerspective(self.settings['perspectives'])
97 self.builderPanel.SetPerspective(self.settings['perspectives'])
98 if self.residualPanel is not None:
99 self.residualPanel.SetPerspective(self.settings['perspectives'])
100
101
103 """ The button on aui panel is pressed. """
104 if event.GetButton() == wx.aui.AUI_BUTTON_CLOSE:
105 event.GetPane().Show(False)
106 self.GetAuiManager().Update()
107 self.StorePerspective()
108 elif event.GetButton() == wx.aui.AUI_BUTTON_PIN:
109 self.StorePerspective()
110 event.Skip()
111 else:
112 event.Skip()
113
114
115 - def refreshModel(self, model):
116 """ refresh the model. """
117 self.model = model
118 self.builderPanel.refreshModel(model)
119 self.datasetPanel.SetModel(model)
120 if self.residualPanel is not None:
121 self.residualPanel.SetModel(model)
122
123
124 - def SetModel(self, model):
125 """ Set the model. """
126
127 self.model = model
128 self.builderPanel.SetModel(model)
129 self.datasetPanel.SetModel(model)
130
131 if self.residualPanel is not None:
132 self.residualPanel.SetModel(model)
133
134
135 - def GetModel(self):
136 """ Return the model"""
137 return self.model
138
139
140 - def UpdateViewer(self):
141 """ Update the whole model Page """
142 self.builderPanel.UpdateViewer()
143 self.datasetPanel.UpdateViewer()
144 if self.residualPanel is not None:
145 self.residualPanel.UpdateViewer()
146
147
148 - def UpdateParameterViewer(self, paramName, value):
149 """ Update the whole model Page """
150 self.builderPanel.UpdateParameterViewer(paramName, value)
151 self._updateModelOnModel()
152
153
155 """ Update when the dataset is updated """
156 model = self.GetModel()
157 dataset = self.datasetPanel.GetDataset()
158
159 if model is None or dataset is None:
160 return
161
162 try:
163 model.setXmlDataset(dataset)
164 model.updateXmlTheoryData()
165 model.getXmlTheoryData().chisq = self._calcChisq( dataset, model)
166
167 self.datasetPanel.UpdateViewer()
168
169 if self.residualPanel is not None and \
170 self.IsModelResidualShown():
171 self.residualPanel.UpdateModelView()
172
173 except:
174 pass
175
176
178 """ Update the whole model Page """
179 model = self.GetModel()
180 dataset = self.datasetPanel.GetDataset()
181
182 if model is None or dataset is None:
183 return
184
185
186 dataset.setImbedSrc()
187 model.updateXmlTheoryData()
188 model.getXmlTheoryData().chisq = self._calcChisq( dataset, model)
189
190
191 self.datasetPanel.UpdateViewer()
192
193
194 if self.residualPanel is not None and \
195 self.IsModelResidualShown():
196 self.residualPanel.UpdateViewer()
197
198
200 """ Update the whole model Page """
201 model = self.GetModel()
202 dataset = self.datasetPanel.GetDataset()
203
204 if model is None or dataset is None:
205 return
206
207
208 dataset.setImbedSrc()
209 dataset.removeChild('profile')
210 model.updateXmlTheoryData()
211 model.getXmlTheoryData().chisq = self._calcChisq( dataset, model)
212
213
214
215 self.datasetPanel.UpdateViewer()
216
217
218 if self.residualPanel is not None and \
219 self.IsModelResidualShown():
220 self.residualPanel.UpdateViewer()
221
222
224 """ Update the whole model Page """
225
226 model = self.GetModel()
227 dataset = self.datasetPanel.GetDataset()
228
229 if model is None or dataset is None:
230 return
231
232 model.updateXmlTheoryData()
233 model.getXmlTheoryData().chisq = self._calcChisq( dataset, model)
234
235 self.datasetPanel.UpdateViewer()
236
237
238 if self.residualPanel is not None and \
239 self.IsModelResidualShown():
240 self.residualPanel.UpdateViewer()
241
242
243
245 """ Update the whole model Page """
246 model = self.GetModel()
247 dataset = self.datasetPanel.GetDataset()
248
249 if model is None or dataset is None:
250 return
251
252
253 dataset.setImbedSrc()
254 model.updateXmlTheoryData()
255 model.getXmlTheoryData().chisq = self._calcChisq( dataset, model)
256
257
258 self.datasetPanel.RefreshViewer()
259
260
261 if self.residualPanel is not None and \
262 self.IsModelResidualShown():
263 self.residualPanel.UpdateViewer()
264
265
266 - def OnModelUpdated(self, event):
267 """ Update the whole model Page """
268 if event.IsUpdateModelMeta():
269 self._updateModelOnModelMeta()
270
271 elif event.IsClearModel():
272 self._clearModelOnModel()
273
274 else:
275 self._updateModelOnModel()
276
277 event.Skip()
278
279
281 if event.IsShowParameter():
282 pass
283 else:
284
285 self._refreshModelOnModel()
286
287
288 event.Skip()
289
290
291 - def OnDatasetUpdated(self, event):
292 self._updateModelOnDataset()
293 event.Skip()
294
295
296 - def CloseAuiManager(self):
297 """ Uninitalize the AuiManager."""
298 self._mgr.UnInit()
299
300
301 - def Enable(self, enable=True):
302 self.builderPanel.Enable(enable)
303 self.datasetPanel.Enable(enable)
304 if self.residualPanel is not None:
305 self.residualPanel.Enable(enable)
306
307
308 - def SetEditMode(self, editMode):
309 self.datasetPanel.SetEditMode(editMode)
310 self.builderPanel.SetEditMode(editMode)
311 self.residualPanel.SetEditMode(editMode)
312
313
314 - def GetOwnerManager(self):
315 return self._mgr
316
317 - def GetAuiManager(self):
318 return self.GetOwnerManager()
319
320
321 - def ShowModelDataset(self, show=True):
322 """ Show / hide the dataset panel. """
323 self.GetAuiManager().GetPane(DATASET_NAME).Show(show)
324 self.GetAuiManager().Update()
325
326
328 """ return True if the dataset panel is shown. """
329 return self.GetAuiManager().GetPane(DATASET_NAME).IsShown()
330
331
332 - def ShowModelBuilder(self, show=True):
333 """ Show / hide the model builder panel. """
334 self.GetAuiManager().GetPane(BUILDER_NAME).Show(show)
335 self.GetAuiManager().Update()
336
337
339 """ Retur True if the model builder panel is shown. """
340 return self.GetAuiManager().GetPane(BUILDER_NAME).IsShown()
341
342
343 - def ShowModelResidual(self, show=True):
344 """ Show / hide the data residual panel. """
345 if self.residualPanel is not None:
346
347 self.GetAuiManager().GetPane(RESIDUAL_NAME).Show(show)
348 self.GetAuiManager().Update()
349
350
352 """ Return True if the data residual panel is shown. """
353 if self.residualPanel is not None:
354 return self.GetAuiManager().GetPane(RESIDUAL_NAME).IsShown()
355 else:
356 return False
357
358
359 - def ShowModelParameter(self, show=True):
360 """ Show / hide the parameter panel. """
361 if self.parameterPanel is not None:
362 self.GetAuiManager().GetPane(PARAMETER_NAME).Show(show)
363 self.GetAuiManager().Update()
364
365
367 """ return True if the parameter panel is shown. """
368 if self.parameterPanel is not None:
369 return self.GetAuiManager().GetPane(PARAMETER_NAME).IsShown()
370 else:
371 return False
372
373
374 - def getEnds_Rhos(self):
375 try:
376 return self.builderPanel.getEnds_Rhos()
377 except:
378 return None
379
380
381 - def fresnel(self, Q, sigma=0.):
382 fb = self.getEnds_Rhos()
383 if fb != None:
384 front_val, back_val = fb
385 return reflectivity(Q,
386 [0.,0.],
387 [front_val, back_val],
388 mu=[0.,0.],
389 wavelength=1
390 )
391
392
393 - def _calcChisq(self, dataset, model):
394 """
395 Calculate chisq from current dataset and model.
396
397 We do this here in order to avoid repeated calculation
398 """
399 try:
400 calcR = model.getXmlTheoryData().getXmlDataArray()
401 except:
402 calcR = None
403 try:
404 data =dataset.getXmlData()[0].getXmlReductionData(
405 ).getDataArrayList()
406 except:
407 data =None
408
409 if calcR == None: return None
410 if data == None: return None
411 if calcR[0].getData() == None: return
412
413 if len( data )/4 == 1:
414
415 try:
416 R = data[2].getData()
417 dR = data[3].getData()
418 except:
419 R = data[2]
420 dR = data[3]
421
422 if dR == None or len(dR)==0:
423 dy = R - calcR[0].getData()
424 else:
425 R0 = numpy.ones(len(dR))*1.0e-10
426 dR = numpy.choose( dR<1.0e-10, (dR,R0) )
427 dy = (R - calcR[0].getData())/dR
428
429 if len(R) >=1: return numpy.dot(dy,dy)/len(R)
430 else: return numpy.dot(dy,dy)
431
432 else:
433 try:
434 R = [ data[2 ].getData(), data[6 ].getData(),
435 data[10].getData(), data[14].getData() ]
436 dR = [ data[3 ].getData(), data[7 ].getData(),
437 data[11].getData(), data[15].getData() ]
438 except:
439 R = [data[2], data[6], data[10], data[14]]
440 dR = [data[3], data[7], data[11], data[15]]
441
442 _sum = 0.0
443 for i in xrange(4):
444 if dR[i] == None:
445 dy = (R[i] - calcR[i].getData())
446 else:
447 R0 = numpy.ones(len(dR[i]))*1.0e-10
448 dRi = numpy.choose( dR[i]<1.0e-10, (dR[i],R0) )
449 dy = (R[i] - calcR[i].getData()) /dRi
450
451 _sum += numpy.sum(dy*dy)
452
453 return _sum/ ( len(R[0]) + len(R[1]) + len(R[2]) + len(R[3]) )
454