1 import wx
2 import traceback
3 import numpy
4
5 from park.parkAui.common.auiPanel import AuiPanel
6 from park.parkAui.common.parkEvent import EVT_PARK_PARAMETER, \
7 wxEVT_PARK_PARAMETER, ParkParameterEvent
8 from reflectometry.model1d.model.bspline import BSpline, spline, slope, Slope
9
10 SELECTED_COLOR = wx.Color(0, 255, 0)
11 WARNING_COLOR = wx.Color(255, 0, 0)
12
13
14 RoughFactor = numpy.sqrt( numpy.log(256.0) )
15 ReflFactor = 1.0e-6
16
17
18 DEFAULT_PANEL_SIZE = (400, 300)
19 DEFAULT_GRID_SIZE = (400, 300)
20 ROW_LABEL_DEFAULT_SIZE = 30
21
22
23 ANGSTROM_SYMBOL = u'\u212B'
24 DEGREE_SYMBOL = u'\u00B0'
25 SET_OPT_COLOR = True
26
27
28 COL_LABELS = ('Model\n Name',
29 'Layer\n #',
30 'Layer Name',
31 'Thickness ' + ANGSTROM_SYMBOL +'\nDepth',
32 'Roughness ' + ANGSTROM_SYMBOL +'\nRO',
33 'Number density ' + '\nRho',
34 'Absorption 1/' + ANGSTROM_SYMBOL +'\nMu',
35 'Mag. density ' + '\nPhi',
36 'Mag. theta ' + DEGREE_SYMBOL +'\nTheta'
37 )
38
39 COL_LABELS2 = ('Model\n Name',
40 'Layer\n #',
41 'Layer Name',
42 'Thickness ' + ANGSTROM_SYMBOL +'\nDepth',
43 'Roughness ' + ANGSTROM_SYMBOL +'\nRO',
44 'Number density ' + '\nRho (10^6)',
45 'Absorption 1/' + ANGSTROM_SYMBOL +'\nMu (10^6)',
46 'Mag. density ' + '\nPhi(10^6)',
47 'Mag. theta ' + DEGREE_SYMBOL +'\nTheta'
48 )
49
50
51
52 [
53 wxID_Switch_Fmt,
54 wxID_Ro2Staj_Fmt,
55 wxID_R2Staj_Fmt,
56 wxID_Tab_CUSTOM,
57 wxID_Align_Left,
58 wxID_Align_Right,
59 wxID_Align_Center,
60 ] = [ wx.NewId() for item in range(7) ]
61
62
63
64
65
66
68 """ Panel to view the constrains and optimized variables only. """
75 AuiPanel.__init__(self, parent, id, pos=pos, size=size )
76 self.grid = ConstrainViewerGrid(self, id=id, pos=pos, size=size)
77 self.editMode = True
78 self.parent = parent
79
80 self._CellAlignMode = 'center'
81
82 self.sizer = wx.BoxSizer(wx.VERTICAL)
83 self.sizer.Add(self.grid, 1, wx.LEFT|wx.TOP|wx.GROW|wx.EXPAND)
84 self.SetSizer(self.sizer)
85
86 self._createMenu()
87 self._createAlignMenu()
88
89
90 self.Binds()
91
92
103
104
106 """ On touch the right mouse """
107 self.PopupMenu(self.editMenu)
108
109
110
112
113
114 (currAlign, dummy) = self.grid.GetCellAlignment(0, evt.GetCol())
115 if currAlign == wx.ALIGN_LEFT:
116 self.alignMenu.Check(wxID_Align_Left, True)
117 elif currAlign == wx.ALIGN_RIGHT:
118 self.alignMenu.Check(wxID_Align_Right, True)
119 elif currAlign == wx.ALIGN_CENTER:
120 self.alignMenu.Check(wxID_Align_Center, True)
121 else:
122 pass
123
124 self.PopupMenu(self.alignMenu)
125
126 if self._CellAlignMode=='left':
127 self.grid.SetCellsAlignmentByCol(evt.GetCol(), wx.ALIGN_LEFT)
128
129 if self._CellAlignMode=='right':
130 self.grid.SetCellsAlignmentByCol(evt.GetCol(), wx.ALIGN_RIGHT)
131
132 if self._CellAlignMode=='center':
133 self.grid.SetCellsAlignmentByCol(evt.GetCol(), wx.ALIGN_CENTER)
134
135 self.grid.ForceRefresh()
136
137 evt.Skip()
138
139
141 self.parent.showDefaultConstrain(choice=True)
142
143
146
147
150
151
153 """ popup menus """
154 menu = wx.Menu(title=u'Parameters Manager')
155 menu.Append( help='',
156 id=wxID_Switch_Fmt,
157 kind=wx.ITEM_NORMAL,
158 text=u'&Switch RARK Show Format...' )
159
160 menu.AppendSeparator()
161 menu.Append( help='',
162 id=wxID_Ro2Staj_Fmt,
163 kind=wx.ITEM_CHECK,
164 text=u'&Rough(PARK Notation)...' )
165 menu.Check(wxID_Ro2Staj_Fmt, False)
166
167 menu.Append( help='',
168 id=wxID_R2Staj_Fmt,
169 kind=wx.ITEM_CHECK,
170 text=u'&R * 10^6...' )
171 menu.Check(wxID_R2Staj_Fmt, True)
172
173 self.editMenu = menu
174
175
176
177 self.editMenu.Enable(wxID_R2Staj_Fmt, True)
178 self.editMenu.Enable(wxID_Ro2Staj_Fmt, True)
179
180
182 """ popup menus """
183 menu = wx.Menu(title=u'Align Manager')
184 menu.Append(help='', id=wxID_Align_Left, kind=wx.ITEM_RADIO,
185 text=u'A&lign Left')
186 menu.Append(help='', id=wxID_Align_Right, kind=wx.ITEM_RADIO,
187 text=u'A&lign Right')
188 menu.Append(help='', id=wxID_Align_Center, kind=wx.ITEM_RADIO,
189 text=u'A&lign Center')
190 self.alignMenu = menu
191
192
193 self.alignMenu.Check(wxID_Align_Center, True)
194
195
196 self.Bind(wx.EVT_MENU, self.OnAlignment, id=wxID_Align_Left)
197 self.Bind(wx.EVT_MENU, self.OnAlignment, id=wxID_Align_Right)
198 self.Bind(wx.EVT_MENU, self.OnAlignment, id=wxID_Align_Center)
199
200
202
203
204 if evt.GetId() == wxID_Align_Left: self._CellAlignMode = 'left'
205 elif evt.GetId() == wxID_Align_Right: self._CellAlignMode = 'right'
206 elif evt.GetId() == wxID_Align_Center: self._CellAlignMode = 'center'
207 else:
208 pass
209
210
212 """ Update all the views"""
213 self.xor = xor
214 xor.updateVariables()
215 self.grid.SetMultiplexor(xor, modelname)
216 self.UpdateViewer()
217
218
221
222
225
226
228 """ Update multiplexor for the fitting. """
229 self.UpdateViewer()
230
231
233 """ refresh multiplexor for the fitting. """
234 self.xor = xor
235 xor.updateVariables()
236 self.grid.RefreshMultiplexor(xor, modelname)
237 self.UpdateViewer()
238
239
240 - def Enable(self, enable=True):
241 """ Enable the panel."""
242 self.grid.Enable(enable)
243
244
246 """ Update the viewer due to the updating of the model. """
247 self.grid.UpdateViewer()
248
249
251 """ Update the viewer due to the updating of the model. """
252 self.grid.UpdateModelViewer()
253
254
258
259
263
264
266 """ Update the viewer when parameter value is updated. """
267 self.grid.RefreshViewer()
268
269
272
273
275 """ Set to editable mode or not. """
276 self.grid.SetEditMode(True)
277
278
280 """ Get grid table for save """
281 return self.grid.getFmtTable()
282
283
284
285
286
287
288
289
290
291
293 """ The grid to show the constrains and variables"""
300 wx.grid.Grid.__init__(self,parent, id)
301 self.xor = None
302 self.editMode = True
303
304
305 self.table = CustomConstrainTable()
306 self._init_Table()
307
308
309 self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnCellChanged)
310 self.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnCellLeftClick)
311
312
314 self.editMode = True
315 self.table.SetEditMode(editMode)
316
317 self.ForceRefresh()
318
319
322
323
325 """ Initialize the grid table. """
326
327 self.SetTable(self.table)
328
329 self.table.SetEditMode( self.IsEditMode() )
330 self.SetRowLabelSize(0)
331 self.SetDefaultCellAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
332
333
334
335
336
337 attr = wx.grid.GridCellAttr()
338 attr.SetReadOnly(True)
339 self.SetColAttr(0, attr)
340 self.SetColAttr(1, attr)
341 self.SetColAttr(2, attr)
342
343
344 self.SetGridCursor(0,3)
345
346
348 """ Initialize the grid table and adjust everthing automatically."""
349 self._Init_GridTable()
350
351 self.AutoSize()
352
353
355 """ Initialize the grid table and
356 resfresh column and Rows sizes automatically.
357 """
358 self._Init_GridTable()
359
360 self.AutoSizeColumns(True)
361 self.AutoSizeRows(True)
362
363
365 for model in self.xor.getXmlModels():
366 if modelName == model.name:
367 return model
368 return None
369
370
375
376
378 """ Update all the views"""
379 self.xor = xor
380
381 self.table.SetMultiplexor(xor, modelname)
382
383 self._init_Table_Refresh()
384
385
386 if self.table.nrows >1:
387 self.SetCellSize( 0, 0, self.table.nrows, 1)
388
389
390 self.setColor4OptVar()
391
392
394 """ Update all the views"""
395 self.xor = xor
396
397 self.table.SetMultiplexor(xor, modelname)
398
399 self._init_Table()
400
401
402 self.setColor4OptVar()
403
404
406 _vars = self.xor.getXmlVariables().getVariables()
407
408 count = 0
409 for i in xrange( len(_vars) ):
410 if _vars[i].target.split('_')[0].strip() == pname:
411 count+=1
412
413 _varsList = []
414 for i in xrange( count ):
415 vname = pname + '_%d'%i
416 for i in xrange( len(_vars) ):
417 if _vars[i].target == vname:
418 _varsList.append( _vars[i] )
419 break
420
421 svals = "["
422 for i in xrange( len(_varsList) ):
423 svals+=str(_varsList[i].v0)
424 if i < len(_varsList)-1:
425 svals+=','
426 svals += "]"
427
428 return svals
429
430
432 """ Event handle to update the viewer when the parameter of the
433 model is updated.
434 """
435 if names is None or len(names) < 3:
436 self.UpdateViewer()
437 else:
438 name2 = names[2].split('_')[0].strip()
439 name = '%s.%s.%s'%(names[0], names[1], name2)
440 (row, col) = self.table.findRowColByName( name )
441
442 self.MakeCellVisible(row, col)
443 self.SelectBlock(row, col, row, col)
444
445 if len(names[2].split('_'))==1:
446 self.SetCellValue(row, col, str(value))
447 else:
448 svals = self.getValuesByPName( name)
449 self.SetCellValue(row, col, svals)
450
451
453 """ Event handle to show the parameter of the model """
454 if names is None or len(names) < 3:
455 self.UpdateViewer()
456 else:
457 name2 = names[2].split('_')[0].strip()
458 name = '%s.%s.%s' %(names[0],names[1],name2)
459 (row, col) = self.table.findRowColByName( name )
460
461 self.MakeCellVisible(row, col)
462 self.SelectBlock(row, col, row, col)
463
464
466 """ set up color for all optimized variable in grid table """
467 bg = self.GetDefaultCellBackgroundColour()
468 _vars = self.table.GetXmlVariables().getVariables()
469
470 for var in _vars:
471 if not var.target.startswith(self.table.modelName):
472 continue
473
474 (row, col) = self.table.findRowCol(var)
475 self.SetCellBackgroundColour(row, col, bg)
476
477 if var.isOptimized():
478 if row==-1 or col == -1:
479 continue
480 self.SetCellBackgroundColour(row, col, SELECTED_COLOR)
481
482
489
490
492 """ Event handle to update the viewer when the model is updated. """
493
494 modelname = self.table.getModelName()
495
496
497 self.table.SetMultiplexor(self.xor, modelname)
498
499 self._init_Table_Refresh()
500
501
502 if self.table.nrows >1:
503 self.SetCellSize( 0, 0, self.table.nrows, 1)
504
505
506 self.setColor4OptVar()
507
508
514
515
519
520
524
525
528
529
531 """ We can do some thing useful here """
532 row = event.GetRow()
533 col = event.GetCol()
534 event.Skip()
535
536
538 try:
539 lenValue = len(value)
540 return True
541 except:
542 return False
543
544
546 """ Event handler when the cell value is changed. """
547 if True:
548 row = event.GetRow()
549 col = event.GetCol()
550 self._freshViewer( row, col )
551
552
553 value = self.GetCellValue( row, col )
554 valueIsSpline = self.IsSpline( eval(value) )
555
556
557 _vars = self.xor.getXmlVariables().getVariables()
558 pname = self.table.GetVarByRowCol( row, col )
559 if valueIsSpline:
560 _varsList = []
561 _pnameList = []
562 for i in xrange( len( eval(value) ) ):
563 vname = pname + '_%d'%i
564 _pnameList.append( vname )
565 for i in xrange( len(_vars) ):
566 if _vars[i].target == vname:
567 _varsList.append( _vars[i] )
568 break
569 else:
570 for i in xrange( len(_vars) ):
571 if _vars[i].target == pname:
572 currVar = _vars[i]
573 break
574
575
576 if self.table.roughFmt and col == 3 and not valueIsSpline:
577 value /= RoughFactor
578
579 if not self.table.ReflFmt and col != 3 and col != 2 and \
580 not valueIsSpline:
581 value /= ReflFactor
582
583
584 if not valueIsSpline:
585 names = pname.split('.')
586 currVar.v0 = value
587 currVar.value = value
588 self._fireEvent(names, value)
589
590 else:
591 for i in xrange( len(_varsList) ):
592 _val = eval(value)[i]
593 if _varsList[i].v0 == _val:
594 pass
595
596 else:
597 _varsList[i].v0 = _val
598 _varsList[i].value = _val
599 names = _pnameList[i].split('.')
600 self._fireEvent(names, _val)
601
602
603 event.Skip()
604
605
607 """ Fire the ParkParameter event. """
608 evt = ParkParameterEvent(wxEVT_PARK_PARAMETER,
609 self.GetId(),
610 self.xor,
611 names,
612 value,
613 self.GetModel(names[0])
614 )
615 self.GetEventHandler().ProcessEvent(evt)
616
617
620
621
623 for i in xrange( self.table.GetNumberRows() ):
624 self.SetCellAlignment( i, col, alignment, wx.ALIGN_CENTER )
625
626
627
628
629
630
631
632
633
634
636 """
637 Table to show the parameter constrains only
638 """
640 """ Constructor. """
641 wx.grid.PyGridTableBase.__init__(self)
642 self.roughFmt = False
643 self.ReflFmt = True
644 self.xor = None
645 self.editMode = False
646 self.modelName = None
647 self.magnetic=True
648 self.setEmptyLists()
649 self.ncols = len(COL_LABELS)
650 self.nrows = 0
651
652
654 self._layerNames=[]
655 self._depths=[]
656 self._roughs=[]
657 self._rhos=[]
658 self._mus=[]
659 self._phis=[]
660 self._thetas=[]
661
662
664 vList = name.split('.')
665 layerName = vList[1].strip()
666 VarName = vList[2].strip()
667 return ( layerName, VarName )
668
669
671 if VarName == 'depth': col = 3
672 elif VarName == 'rough': col = 4
673 elif VarName == 'rho': col = 5
674 elif VarName == 'mu': col = 6
675 elif VarName == 'phi': col = 7
676 elif VarName == 'theta': col = 8
677 else:
678 col = -1
679
680 return col
681
682
684 row = -1
685 for i in xrange( len(self._layerNames) ):
686 if layerName==self._layerNames[i]:
687 row=i; break
688
689 return row
690
691
699
700
708
709
710
712 if col == 3: return 'depth'
713 elif col == 4: return 'rough'
714 elif col == 5: return 'rho'
715 elif col == 6: return 'mu'
716 elif col == 7: return 'phi'
717 elif col == 8: return 'theta'
718 else: return None
719
720
722 if row < 0 or row >= len(self._layerNames):
723 return None
724 else:
725 return self._layerNames[row]
726
727
729 layerName = self.getLayerNameByRow(row)
730 VarName = self.getVarNameByCol( col)
731 modelName = self.getModelName()
732 if layerName == None or VarName == None or modelName == None:
733 return None
734
735 _Var = '%s.%s.%s' %( modelName, layerName, VarName )
736
737 return _Var
738
739
742
743
746
747
750
751
754
755
757 """ The table is not editable. """
758 self.editMode = False
759
760
762 """ Return True if it is in the edit mode. """
763 return False
764
765
767 return self.modelName
768
769
771 ret=[]
772 ret.append( self._layerNames )
773 ret.append( self._depths )
774 ret.append( self._roughs )
775 ret.append( self._rhos )
776 ret.append( self._mus )
777 if self.magnetic:
778 ret.append( self._phis )
779 ret.append( self._thetas )
780 return ret
781
782
783
785 """
786 In varaiable List, we have some hidden parameters.
787 """
788 try:
789 pm=self.xor.getLocalModels()[self.modelName].getXmlParameters()[0]
790 self._depths.append( pm.depth )
791 self._roughs.append( pm.rough )
792 self._phis.append( pm.phi )
793 self._thetas.append( pm.theta )
794 except:
795 pass
796
797
799 vList = var.target.split('.')
800 _ModelName = vList[0].strip()
801 layerName = vList[1].strip()
802 VarName = vList[2].strip()
803 return ( _ModelName, layerName, VarName )
804
805
807 if len(self._roughs) < 1 :
808 return
809 self._roughs.pop( len(self._roughs) -1 )
810 self._roughs.insert( 0, 0.0)
811
812
814 """
815 In varaiable List, we have some hidden parameters.
816 """
817 pms=self.xor.getLocalModels()[self.modelName].getXmlParameters()
818 for i in xrange( len(pms) ):
819 if pms[i].name == layerName:
820 CurrPm = pms[i]
821 sname = getattr(CurrPm, varName)
822
823 if self._rhos.count(sname)>0:
824 return None
825 else:
826 return sname
827
828
830 if VarName == 'rho': self._rhos.append( val )
831 elif VarName == 'mu': self._mus.append( val )
832 elif VarName == 'phi': self._phis.append( val )
833 elif VarName == 'theta': self._thetas.append( val )
834 else:
835 pass
836
837
839 """ Set the multiplexor. The constrain and variable
840 are defined in multiplexor.
841 """
842 self.xor = xor
843 self.xor.updateVariables()
844
845 self.modelName = modelName
846
847
848 self.setEmptyLists()
849
850
851 self.setHideParameters()
852
853 try:
854 oldLayerName = ""
855 for var in self.xor.getXmlVariables().getVariables():
856
857 ( _ModelName, layerName, VarName ) = self.getNames4Var( var )
858 if _ModelName == self.modelName:
859 if layerName != oldLayerName:
860 self._layerNames.append( layerName )
861 oldLayerName = layerName
862
863 if VarName == 'depth': self._depths.append( var.v0 )
864 elif VarName == 'rough': self._roughs.append( var.v0 )
865 elif VarName == 'rho': self._rhos.append( var.v0 )
866 elif VarName == 'mu': self._mus.append( var.v0 )
867 elif VarName == 'phi': self._phis.append( var.v0 )
868 elif VarName == 'theta': self._thetas.append( var.v0 )
869 else:
870 _varName = VarName.split('_')[0].strip()
871 _val = self.getSplineParameters(layerName, _varName)
872 if _val != None:
873 self.appendSpine2DataLists(_val, _varName)
874
875
876 self._adjustRough()
877
878 if len(self._phis) >= 1: self.magnetic = True
879 else: self.magnetic = False
880 except:
881 pass
882
883
884 if self.magnetic: self.ncols = len(COL_LABELS)
885 else: self.ncols = len(COL_LABELS)-2
886
887 self.nrows = len(self._layerNames)
888
889
891 """ Return the multiplexor for the fitting. """
892 return self.xor
893
894
896 """ Return the XmlVariables for the fitting. """
897 return self.xor.getXmlVariables()
898
899
901 """ Return number of rows in the table."""
902 return self.nrows
903
904
906 """ Return number of columns in the table"""
907 return self.ncols
908
909
918
919
921 """
922 Decompose a parameter.
923
924 In this code. It only works for spline obj
925 """
926 try: return eval(p)
927 except: return p
928
929
943
944
946 """ Return the value for the cell (row, col)"""
947
948 if col == 0:
949
950 if row==0: return self.modelName
951 else: return ''
952
953 if col == 1:
954 if row==0: return 'V'
955 else: return row
956
957 elif col == 2:
958 try: return self._layerNames[row]
959 except: return ''
960
961 elif col == 3:
962 try: return "%.6f"%(self._depths[row])
963 except: return ''
964
965 elif col == 4: return self.toRoughFormat( self._roughs[row] )
966
967 elif col == 5: return self.toReflFormat( self._rhos[row] )
968
969 elif col == 6: return self.toReflFormat( self._mus[row] )
970
971 elif col == 7: return self.toReflFormat( self._phis[row] )
972
973 elif col == 8:
974 try: return "%.4f"%(self._thetas[row])
975 except: return ''
976
977 else:
978 return ''
979
980
982 try:
983 lenValue = len(value)
984 return True
985 except:
986 lenValue = 1
987 return False
988
989
991 """ Return the value for the cell (row, col)"""
992
993
994 _var = self.GetVarByRowCol( row, col )
995 if _var == None:
996 return
997
998 valueIsSpline = self.IsSpline( eval(value) )
999
1000
1001 _vars = self.xor.getXmlVariables().getVariables()
1002 if valueIsSpline:
1003 _varsList=[]
1004 for i in xrange( len( eval(value) ) ):
1005 vname = _var + '_%d'%i
1006 for i in xrange( len(_vars) ):
1007 if _vars[i].target == vname:
1008 _varsList.append( _vars[i] )
1009 break
1010 else:
1011 for i in xrange( len(_vars) ):
1012 if _vars[i].target == _var:
1013 currVar = _vars[i]
1014 break
1015
1016
1017 if valueIsSpline:
1018 _val = BSpline( eval(value) )
1019 else:
1020 _val = float(value)
1021
1022
1023 if self.roughFmt and col == 3 and col != 2 and not valueIsSpline:
1024 _val /= RoughFactor
1025 if not self.ReflFmt and col != 3 and col != 2 and not valueIsSpline:
1026 _val /= ReflFactor
1027
1028
1029 if not valueIsSpline:
1030 currVar.v0 = _val
1031 currVar.value = _val
1032 else:
1033 for i in xrange( len(_varsList) ):
1034 val_i = eval(value)[i]
1035 _varsList[i].v0 = val_i
1036 _varsList[i].value = val_i
1037
1038
1039
1040 if col == 0 or col ==1 or col ==2:
1041 pass
1042
1043 elif col == 3: self._depths[row] = _val
1044
1045 elif col == 4: self._roughs[row] = _val
1046
1047 elif col == 5: self._rhos[row] = _val
1048
1049 elif col == 6: self._mus[row] = _val
1050
1051 elif col == 7: self._phis[row] = _val
1052
1053 elif col == 8: self._thetas[row] = _val
1054
1055 else:
1056 pass
1057
1058
1059
1061 """ Return the column label string. """
1062 try:
1063 if self.ReflFmt: return COL_LABELS2[col]
1064 else: return COL_LABELS[col]
1065 except:
1066 return ''
1067
1068
1070 """ Return the row label string. """
1071 try:
1072 return super(ConstrainViewerTable, self).GetRowLabelValue(row)
1073 except:
1074 return ''
1075