source: trunk/GSASIIddataGUI.py @ 4968

Last change on this file since 4968 was 4968, checked in by toby, 4 months ago

finish hist/phase tree entry; create new help file for it(incomplete)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 73.4 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASII - phase data display routines
3########### SVN repository information ###################
4# $Date: 2021-06-21 22:58:24 +0000 (Mon, 21 Jun 2021) $
5# $Author: toby $
6# $Revision: 4968 $
7# $URL: trunk/GSASIIddataGUI.py $
8# $Id: GSASIIddataGUI.py 4968 2021-06-21 22:58:24Z toby $
9########### SVN repository information ###################
10'''
11*GSASIIddataGUI: Phase Diffraction Data GUI*
12--------------------------------------------
13
14Module to create the GUI for display of diffraction data * phase
15information that is shown in the data display window
16(when a phase is selected.)
17
18'''
19from __future__ import division, print_function
20import copy
21import wx
22import numpy as np
23import numpy.linalg as nl
24import GSASIIpath
25GSASIIpath.SetVersionNumber("$Revision: 4968 $")
26import GSASIIlattice as G2lat
27import GSASIIspc as G2spc
28import GSASIIplot as G2plt
29import GSASIIpwd as G2pwd
30import GSASIIphsGUI as G2phG
31import GSASIIctrlGUI as G2G
32import GSASIIpy3 as G2py3
33import GSASIIdataGUI as G2gd
34
35WACV = wx.ALIGN_CENTER_VERTICAL
36VERY_LIGHT_GREY = wx.Colour(235,235,235)
37WHITE = wx.Colour(255,255,255)
38BLACK = wx.Colour(0,0,0)
39mapDefault = {'MapType':'','RefList':'','GridStep':0.25,'Show bonds':True,
40                'rho':[],'rhoMax':0.,'mapSize':10.0,'cutOff':50.,'Flip':False}
41
42def UpdateDData(G2frame,DData,data,hist='',Scroll=0):
43    '''Display the Diffraction Data associated with a phase
44    (items where there is a value for each histogram and phase)
45    Used in the Phase/Data tab or the Hist/Phase tree entry
46
47    :param wx.frame G2frame: the main GSAS-II frame object
48    :param wx.ScrolledWindow DData: notebook page to be used for the display
49    :param dict data: all the information on the phase in a dictionary
50    :param str hist: histogram name
51    :param int Scroll: previous scroll position
52
53    '''
54    def PlotSizer():
55
56        def OnPlotSel(event):
57            Obj = event.GetEventObject()
58            generalData['Data plot type'] = Obj.GetStringSelection()
59            G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
60            wx.CallLater(100,UpdateDData,G2frame,DData,data,G2frame.hist)
61           
62        def OnPOhkl(event):
63            event.Skip()
64            Obj = event.GetEventObject()
65            Saxis = Obj.GetValue().split()
66            try:
67                hkl = [int(Saxis[i]) for i in range(3)]
68            except (ValueError,IndexError):
69                hkl = generalData['POhkl']
70            if not np.any(np.array(hkl)):
71                hkl = generalData['POhkl']
72            generalData['POhkl'] = hkl
73            h,k,l = hkl
74            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
75            G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
76           
77        def OnProj(event):
78            Obj = event.GetEventObject()
79            generalData['3Dproj'] = Obj.GetValue()
80            G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
81       
82        plotSizer = wx.BoxSizer(wx.VERTICAL)
83        choice = ['None','Mustrain','Size','Preferred orientation','St. proj. Inv. pole figure','Eq. area Inv. pole figure']
84        plotSel = wx.RadioBox(DData,wx.ID_ANY,'Select plot type:',choices=choice,
85            majorDimension=1,style=wx.RA_SPECIFY_COLS)
86        plotSel.SetStringSelection(generalData['Data plot type'])
87        plotSel.Bind(wx.EVT_RADIOBOX,OnPlotSel)   
88        plotSizer.Add(plotSel)
89        if generalData['Data plot type'] == 'Preferred orientation':
90            POhklSizer = wx.BoxSizer(wx.HORIZONTAL)
91            POhklSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Plot preferred orientation for H K L: '),0,WACV)
92            h,k,l = generalData['POhkl']
93            poAxis = wx.TextCtrl(DData,wx.ID_ANY,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
94            poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOhkl)
95            poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOhkl)
96            POhklSizer.Add(poAxis,0,WACV)
97            plotSizer.Add(POhklSizer)
98        elif generalData['Data plot type'] in ['Mustrain','Size']:
99            projSizer = wx.BoxSizer(wx.HORIZONTAL)
100            projSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Show projections for: '),0,WACV)
101            proj = ['','x','y','z','xy','xz','yz','xyz']
102            projType = wx.ComboBox(DData,wx.ID_ANY,value=generalData['3Dproj'],choices=proj,
103                style=wx.CB_READONLY|wx.CB_DROPDOWN)
104            projType.Bind(wx.EVT_COMBOBOX, OnProj)
105            projSizer.Add(projType,0,WACV)
106            plotSizer.Add(projSizer)           
107        return plotSizer
108       
109    def ScaleSizer():
110       
111        def OnScaleRef(event):
112            Obj = event.GetEventObject()
113            UseList[G2frame.hist]['Scale'][1] = Obj.GetValue()
114        def onChangeFraction(invalid,value,tc):
115            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
116           
117        scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
118        if 'PWDR' in G2frame.hist:
119            scaleRef = wx.CheckBox(DData,wx.ID_ANY,label=' Phase fraction: ')
120        elif 'HKLF' in G2frame.hist:
121            scaleRef = wx.CheckBox(DData,wx.ID_ANY,label=' Scale factor: ')               
122        scaleRef.SetValue(UseList[G2frame.hist]['Scale'][1])
123        scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
124        scaleSizer.Add(scaleRef,0,WACV|wx.LEFT,5)
125        scaleVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Scale'],0,
126            xmin=0.,nDig=(10,4,'g'),typeHint=float,OnLeave=onChangeFraction)
127        scaleSizer.Add(scaleVal,0,WACV)
128        if 'PWDR' in G2frame.hist and generalData['Type'] != 'magnetic':
129            wtSum = G2pwd.PhaseWtSum(G2frame,G2frame.hist)
130            if wtSum and UseList[G2frame.hist]['Use']:
131                weightFr = UseList[G2frame.hist]['Scale'][0]*generalData['Mass']/wtSum
132                scaleSizer.Add(wx.StaticText(DData,label=' Wt. fraction: %.3f'%(weightFr)),0,WACV)
133        return scaleSizer
134       
135    def OnLGmixRef(event):
136        Obj = event.GetEventObject()
137        hist,name = Indx[Obj.GetId()]
138        UseList[G2frame.hist][name][2][2] = Obj.GetValue()
139       
140    def OnSizeType(event):
141        Obj = event.GetEventObject()
142        UseList[G2frame.hist]['Size'][0] = Obj.GetValue()
143        G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
144        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
145       
146    def OnSizeRef(event):
147        Obj = event.GetEventObject()
148        hist,pid = Indx[Obj.GetId()]
149        if UseList[G2frame.hist]['Size'][0] == 'ellipsoidal':
150            UseList[G2frame.hist]['Size'][5][pid] = Obj.GetValue()               
151        else:
152            UseList[G2frame.hist]['Size'][2][pid] = Obj.GetValue()
153       
154    def OnStrainType(event):
155        Obj = event.GetEventObject()
156        UseList[G2frame.hist]['Mustrain'][0] = Obj.GetValue()
157        G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
158        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
159       
160    def OnStrainRef(event):
161        Obj = event.GetEventObject()
162        hist,pid = Indx[Obj.GetId()]
163        if UseList[G2frame.hist]['Mustrain'][0] == 'generalized':
164            UseList[G2frame.hist]['Mustrain'][5][pid] = Obj.GetValue()
165        else:
166            UseList[G2frame.hist]['Mustrain'][2][pid] = Obj.GetValue()
167       
168    def OnStrainAxis(event):
169        event.Skip()
170        Obj = event.GetEventObject()
171        Saxis = Obj.GetValue().split()
172        try:
173            hkl = [int(Saxis[i]) for i in range(3)]
174        except (ValueError,IndexError):
175            hkl = UseList[G2frame.hist]['Mustrain'][3]
176        if not np.any(np.array(hkl)):
177            hkl = UseList[G2frame.hist]['Mustrain'][3]
178        UseList[G2frame.hist]['Mustrain'][3] = hkl
179        h,k,l = hkl
180        Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
181        wx.CallAfter(G2plt.PlotSizeStrainPO,G2frame,data,hist)
182       
183    def OnResetStrain(event):
184        Obj = event.GetEventObject()
185        item,name = Indx[Obj.GetId()]
186        if name == 'isotropic':
187            UseList[item]['Mustrain'][1][0] = 1000.0
188        elif name == 'uniaxial':
189            UseList[item]['Mustrain'][1][0] = 1000.0
190            UseList[item]['Mustrain'][1][1] = 1000.0
191        elif name == 'generalized':
192            muiso = 1000.
193            cell = generalData['Cell'][1:7]
194            vals = G2spc.Muiso2Shkl(muiso,SGData,cell)
195            UseList[item]['Mustrain'][4] = vals
196        G2plt.PlotSizeStrainPO(G2frame,data,item)
197        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
198           
199    def OnPOAxis(event):
200        event.Skip()
201        Obj = event.GetEventObject()
202        Saxis = Obj.GetValue().split()
203        try:
204            hkl = [int(Saxis[i]) for i in range(3)]
205        except (ValueError,IndexError):
206            hkl = UseList[G2frame.hist]['Pref.Ori.'][3]
207        if not np.any(np.array(hkl)):
208            hkl = UseList[G2frame.hist]['Pref.Ori.'][3]
209        UseList[G2frame.hist]['Pref.Ori.'][3] = hkl
210        h,k,l = hkl
211        Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
212       
213    def OnPOOrder(event):
214        Obj = event.GetEventObject()
215        Order = int(Obj.GetValue())
216        UseList[G2frame.hist]['Pref.Ori.'][4] = Order
217        UseList[G2frame.hist]['Pref.Ori.'][5] = SetPOCoef(Order,G2frame.hist)
218        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
219
220    def OnPOType(event):
221        Obj = event.GetEventObject()
222        if 'March' in Obj.GetValue():
223            UseList[G2frame.hist]['Pref.Ori.'][0] = 'MD'
224        else:
225            UseList[G2frame.hist]['Pref.Ori.'][0] = 'SH'
226        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
227
228    def OnPORef(event):
229        Obj = event.GetEventObject()
230        UseList[G2frame.hist]['Pref.Ori.'][2] = Obj.GetValue()
231
232    def OnAddFixed(event):
233        fixedVars = UseList[G2frame.hist].get('FixedSeqVars',[])
234        SeqId = G2gd.GetGPXtreeItemId(G2frame, G2frame.root, 'Sequential results')
235        seqData = G2frame.GPXtree.GetItemPyData(SeqId)
236        if G2frame.hist not in seqData:
237            print('Strange: '+G2frame.hist+' not found')
238            return
239        parmDict = seqData[G2frame.hist].get('parmDict',[])
240        # narrow down to items w/o a histogram & having float values
241        phaseKeys = [i for i in parmDict if ':' in i and i.split(':')[1] == '']
242        phaseKeys = [i for i in phaseKeys if type(parmDict[i]) not in (int,str,bool)]
243        if len(phaseKeys) == 0: return
244        selected = []
245        for i,key in enumerate(phaseKeys):
246            if key in fixedVars: selected.append(i)
247        dlg = G2G.G2MultiChoiceDialog(G2frame, 'Choose phase vars to fix for this histogram only', 
248                                      'Choose items to edit', phaseKeys,selected=selected)
249        if dlg.ShowModal() == wx.ID_OK:
250            sel = dlg.GetSelections()
251            dlg.Destroy()
252        else:
253            dlg.Destroy()
254            return
255        UseList[G2frame.hist]['FixedSeqVars'] = [phaseKeys[i] for i in sel]
256        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
257
258    def SetPOCoef(Order,hist):
259        cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],'0',Order,False)     #cylindrical & no M
260        newPOCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
261        POCoeff = UseList[G2frame.hist]['Pref.Ori.'][5]
262        for cofName in POCoeff:
263            if cofName in  cofNames:
264                newPOCoef[cofName] = POCoeff[cofName]
265        return newPOCoef
266       
267    def checkAxis(axis):
268        if not np.any(np.array(axis)):
269            return False
270        return axis
271       
272    def OnNewValue(invalid,value,tc):
273        G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
274           
275    def OnNewValueReDraw(invalid,value,tc):
276        G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
277        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
278           
279    def TopSizer(name,choices,parm,OnType):
280        topSizer = wx.BoxSizer(wx.HORIZONTAL)
281        topSizer.Add(wx.StaticText(DData,wx.ID_ANY,name),0,WACV)
282        sizeType = wx.ComboBox(DData,wx.ID_ANY,value=UseList[G2frame.hist][parm][0],choices=choices,
283            style=wx.CB_READONLY|wx.CB_DROPDOWN)
284        sizeType.Bind(wx.EVT_COMBOBOX, OnType)
285        topSizer.Add(sizeType,0,WACV|wx.BOTTOM,5)
286        return topSizer
287       
288    def LGmixSizer(name,Limits,OnRef):
289        lgmixSizer = wx.BoxSizer(wx.HORIZONTAL)
290        lgmixRef = wx.CheckBox(DData,wx.ID_ANY,label='LGmix')
291        lgmixRef.thisown = False
292        lgmixRef.SetValue(UseList[G2frame.hist][name][2][2])
293        Indx[lgmixRef.GetId()] = [G2frame.hist,name]
294        lgmixRef.Bind(wx.EVT_CHECKBOX, OnRef)
295        lgmixSizer.Add(lgmixRef,0,WACV|wx.LEFT,5)
296        lgmixVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist][name][1],2,
297            nDig=(10,3),xmin=Limits[0],xmax=Limits[1])
298        lgmixSizer.Add(lgmixVal,0,WACV|wx.LEFT,5)
299        return lgmixSizer
300                   
301    def ResetSizer(name,OnReset):
302        resetSizer = wx.BoxSizer(wx.HORIZONTAL)
303        reset = wx.Button(DData,wx.ID_ANY,label='Reset?')
304        reset.thisown = False
305        Indx[reset.GetId()] = [G2frame.hist,name]
306        reset.Bind(wx.EVT_BUTTON,OnReset)
307        resetSizer.Add(reset,0,WACV)
308        return resetSizer
309       
310    def IsoSizer(name,parm,fmt,Limits,OnRef):
311        isoSizer = wx.BoxSizer(wx.HORIZONTAL)
312        sizeRef = wx.CheckBox(DData,wx.ID_ANY,label=name)
313        sizeRef.thisown = False
314        sizeRef.SetValue(UseList[G2frame.hist][parm][2][0])
315        Indx[sizeRef.GetId()] = [G2frame.hist,0]
316        sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
317        isoSizer.Add(sizeRef,0,WACV|wx.LEFT,5)
318        sizeVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist][parm][1],0,
319            nDig=fmt,xmin=Limits[0],xmax=Limits[1],OnLeave=OnNewValue)
320        isoSizer.Add(sizeVal,0,WACV)
321        return isoSizer
322       
323    def UniSizer(parm,OnAxis):
324        uniSizer = wx.BoxSizer(wx.HORIZONTAL)
325        uniSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Unique axis, H K L: '),0,WACV)
326        h,k,l = UseList[G2frame.hist][parm][3]
327        Axis = wx.TextCtrl(DData,wx.ID_ANY,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
328        Axis.Bind(wx.EVT_TEXT_ENTER,OnAxis)
329        Axis.Bind(wx.EVT_KILL_FOCUS,OnAxis)
330        uniSizer.Add(Axis,0,WACV|wx.LEFT,5)
331        return uniSizer
332       
333    def UniDataSizer(parmName,parm,fmt,Limits,OnRef):
334        dataSizer = wx.BoxSizer(wx.HORIZONTAL)
335        parms = zip([' Equatorial '+parmName,' Axial '+parmName],
336            UseList[G2frame.hist][parm][2],range(2))
337        for Pa,ref,Id in parms:
338            sizeRef = wx.CheckBox(DData,wx.ID_ANY,label=Pa)
339            sizeRef.thisown = False
340            sizeRef.SetValue(ref)
341            Indx[sizeRef.GetId()] = [G2frame.hist,Id]
342            sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
343            dataSizer.Add(sizeRef,0,WACV|wx.LEFT,5)
344            sizeVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist][parm][1],
345                Id,fmt,xmin=Limits[0],xmax=Limits[1],OnLeave=OnNewValue)
346            dataSizer.Add(sizeVal,0,WACV)
347        return dataSizer
348
349    def EllSizeDataSizer():
350        parms = zip(['S11','S22','S33','S12','S13','S23'],UseList[G2frame.hist]['Size'][4],
351            UseList[G2frame.hist]['Size'][5],range(6))
352        dataSizer = wx.BoxSizer(wx.VERTICAL)
353        matrixSizer = wx.FlexGridSizer(0,6,5,5)
354        Sij = []
355        for Pa,val,ref,Id in parms:
356            sizeRef = wx.CheckBox(DData,wx.ID_ANY,label=Pa)
357            sizeRef.thisown = False
358            sizeRef.SetValue(ref)
359            Indx[sizeRef.GetId()] = [G2frame.hist,Id]
360            sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
361            matrixSizer.Add(sizeRef,0,WACV)
362            if Id < 3:
363                sizeVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Size'][4],
364                    Id,nDig=(10,3),xmin=0.,xmax=4.,OnLeave=OnNewValueReDraw)
365            else:
366                sizeVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Size'][4],
367                    Id,nDig=(10,3),OnLeave=OnNewValueReDraw)
368            # Create Sij matrix
369            Sij += [val]
370            matrixSizer.Add(sizeVal,0,WACV)
371        dataSizer.Add(matrixSizer, 0)
372        Esize,Rsize = nl.eigh(G2lat.U6toUij(np.asarray(Sij)))
373        lengths = Esize
374        G,g = G2lat.cell2Gmat(data['General']['Cell'][1:7])       #recip & real metric tensors
375        GA,GB = G2lat.Gmat2AB(G)    #Orthogonalization matricies
376        hkls = [x/(sum(x**2)**0.5) for x in np.dot(Rsize, GA)]
377        Ids = np.argsort(lengths)
378        dataSizer.Add(wx.StaticText(DData,label=' Principal ellipsoid components:'),0)
379        compSizer = wx.FlexGridSizer(3,3,5,5)
380        Axes = [' Short Axis:',' Middle Axis:',' Long Axis:']
381        for Id in Ids:
382            compSizer.Add(wx.StaticText(DData,label=Axes[Id]),0,WACV)
383            compSizer.Add(wx.StaticText(DData,label='(%.3f, %.3f, %.3f) '%(hkls[Id][0], hkls[Id][1], hkls[Id][2])),0,WACV)
384            compSizer.Add(wx.StaticText(DData,label='Length: %.3f'%lengths[Id]),0,WACV)
385        dataSizer.Add(compSizer)
386        return dataSizer
387       
388    def GenStrainDataSizer():
389        Snames = G2spc.MustrainNames(SGData)
390        numb = len(Snames)
391        onumb = len(UseList[G2frame.hist]['Mustrain'][4])
392        while onumb < numb:
393            UseList[G2frame.hist]['Mustrain'][4].append(0.0)
394            UseList[G2frame.hist]['Mustrain'][5].append(False)
395            onumb += 1
396        muMean = G2spc.MuShklMean(SGData,Amat,UseList[G2frame.hist]['Mustrain'][4][:numb])
397        parms = zip(Snames,UseList[G2frame.hist]['Mustrain'][5],range(numb))
398        mainSizer = wx.BoxSizer(wx.VERTICAL)
399        dataSizer = wx.FlexGridSizer(0,6,5,5)
400        for Pa,ref,Id in parms:
401            strainRef = wx.CheckBox(DData,wx.ID_ANY,label=Pa)
402            strainRef.thisown = False
403            strainRef.SetValue(ref)
404            Indx[strainRef.GetId()] = [G2frame.hist,Id]
405            strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
406            dataSizer.Add(strainRef,0,WACV)
407            strainVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Mustrain'][4],
408                Id,nDig=(10,2),OnLeave=OnNewValueReDraw)
409            dataSizer.Add(strainVal,0,WACV)
410        mainSizer.Add(dataSizer)
411        mainSizer.Add(wx.StaticText(DData,label=' Mean mustrain %.1f'%muMean)
412                          ,0,wx.ALIGN_CENTER_HORIZONTAL)
413        return mainSizer
414
415    def HstrainSizer():
416       
417        def OnHstrainRef(event):
418            Obj = event.GetEventObject()
419            hist,pid = Indx[Obj.GetId()]
420            UseList[G2frame.hist]['HStrain'][1][pid] = Obj.GetValue()
421           
422        hSizer = wx.BoxSizer(wx.VERTICAL)
423        hstrainSizer = wx.FlexGridSizer(0,6,5,5)
424        Hsnames = G2spc.HStrainNames(SGData)
425        parms = zip(Hsnames,UseList[G2frame.hist]['HStrain'][1],range(len(Hsnames)))
426        allzero = True
427        for Pa,ref,Id in parms:
428            hstrainRef = wx.CheckBox(DData,wx.ID_ANY,label=Pa)
429            hstrainRef.thisown = False
430            hstrainRef.SetValue(ref)
431            Indx[hstrainRef.GetId()] = [G2frame.hist,Id]
432            hstrainRef.Bind(wx.EVT_CHECKBOX, OnHstrainRef)
433            hstrainSizer.Add(hstrainRef,0,WACV|wx.LEFT,5)
434            hstrainVal = G2G.ValidatedTxtCtrl(DData,
435                        UseList[G2frame.hist]['HStrain'][0],Id,nDig=(10,3,'g'),
436                        OnLeave=OnNewValueReDraw)
437            if abs(UseList[G2frame.hist]['HStrain'][0][Id]) > 1e-8:
438                allzero = False
439            hstrainSizer.Add(hstrainVal,0,WACV)
440        hSizer.Add(hstrainSizer,0)
441        if not allzero:   # show Dij shifted unit cell
442            DijVals = UseList[G2frame.hist]['HStrain'][0][:]
443            # apply the Dij values to the reciprocal cell
444            newA = []
445            Dijdict = dict(zip(G2spc.HStrainNames(SGData),DijVals))
446            for Aij,lbl in zip(G2lat.cell2A(data['General']['Cell'][1:7]),
447                            ['D11','D22','D33','D12','D13','D23']):
448                newA.append(Aij + Dijdict.get(lbl,0.0))
449            cell = G2lat.A2cell(newA)   # convert back to direct cell
450            laue = generalData['SGData']['SGLaue']
451            if laue == '2/m':
452                laue += generalData['SGData']['SGUniq']
453            for cellGUI in G2py3.cellGUIlist:
454                if laue in cellGUI[0]:
455                    useGUI = cellGUI
456                    break
457            else:
458                return hSizer
459            cellstr = ''
460            for txt,fmt,ifEdit,Id in zip(*useGUI[2:]):
461                if cellstr: cellstr += ", "
462                cellstr += txt+fmt.format(cell[Id])
463            cellstr += ', Vol = {:.3f}'.format(G2lat.calc_V(newA))
464            hSizer.Add(wx.StaticText(DData,wx.ID_ANY,'     '+cellstr),0)
465        return hSizer
466       
467    def PoTopSizer(POData):
468        poSizer = wx.FlexGridSizer(0,6,5,5)
469        choice = ['March-Dollase','Spherical harmonics']
470        POtype = choice[['MD','SH'].index(POData[0])]
471        poSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Preferred orientation model '),0,WACV)
472        POType = wx.ComboBox(DData,wx.ID_ANY,value=POtype,choices=choice,
473            style=wx.CB_READONLY|wx.CB_DROPDOWN)
474        POType.Bind(wx.EVT_COMBOBOX, OnPOType)
475        poSizer.Add(POType)
476        if POData[0] == 'SH':
477            poSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Harmonic order: '),0,WACV)
478            poOrder = wx.ComboBox(DData,wx.ID_ANY,value=str(POData[4]),choices=[str(2*i) for i in range(18)],
479                style=wx.CB_READONLY|wx.CB_DROPDOWN)
480            poOrder.Bind(wx.EVT_COMBOBOX,OnPOOrder)
481            poSizer.Add(poOrder,0,WACV)
482            poRef = wx.CheckBox(DData,wx.ID_ANY,label=' Refine? ')
483            poRef.SetValue(POData[2])
484            poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
485            poSizer.Add(poRef,0,WACV)
486        return poSizer
487       
488    def MDDataSizer(POData):
489        poSizer = wx.BoxSizer(wx.HORIZONTAL)
490        poRef = wx.CheckBox(DData,wx.ID_ANY,label=' March-Dollase ratio: ')
491        poRef.SetValue(POData[2])
492        poRef.Bind(wx.EVT_CHECKBOX,OnPORef)
493        poSizer.Add(poRef,0,WACV|wx.LEFT,5)
494        poVal = G2G.ValidatedTxtCtrl(DData,POData,1,nDig=(10,3),typeHint=float,xmin=0.)
495        poSizer.Add(poVal,0,WACV)
496        poSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Unique axis, H K L: '),0,WACV)
497        h,k,l =POData[3]
498        poAxis = wx.TextCtrl(DData,wx.ID_ANY,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
499        poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOAxis)
500        poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOAxis)
501        poSizer.Add(poAxis,0,WACV)
502        return poSizer
503       
504    def SHDataSizer(POData):
505       
506        ODFSizer = wx.FlexGridSizer(0,8,2,2)
507        ODFkeys = list(POData[5].keys())
508        ODFkeys.sort()
509        for odf in ODFkeys:
510            ODFSizer.Add(wx.StaticText(DData,wx.ID_ANY,odf),0,WACV)
511            ODFval = G2G.ValidatedTxtCtrl(DData,POData[5],odf,nDig=(8,3),typeHint=float,OnLeave=OnNewValue)
512            ODFSizer.Add(ODFval,0,WACV|wx.LEFT,5)
513        return ODFSizer
514       
515    def SHPenalty(POData):
516       
517        def OnHKLList(event):
518            dlg = G2G.G2MultiChoiceDialog(G2frame, 'Select penalty hkls',
519                'Penalty hkls',hkls,filterBox=False)
520            try:
521                if dlg.ShowModal() == wx.ID_OK:
522                    POData[6] = [hkls[i] for i in dlg.GetSelections()]
523                    if not POData[6]:
524                        POData[6] = ['',]
525                else:
526                    return
527            finally:
528                dlg.Destroy()
529            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
530           
531        A = G2lat.cell2A(generalData['Cell'][1:7])
532        hkls = G2lat.GenPfHKLs(10,SGData,A)   
533        shPenalty = wx.BoxSizer(wx.HORIZONTAL)
534        shPenalty.Add(wx.StaticText(DData,wx.ID_ANY,' Negative MRD penalty list: '),0,WACV)
535        shPenalty.Add(wx.ComboBox(DData,value=POData[6][0],choices=POData[6],
536            style=wx.CB_DROPDOWN),0,WACV|wx.LEFT,5)
537        hklList = wx.Button(DData,label='Select penalty hkls')
538        hklList.Bind(wx.EVT_BUTTON,OnHKLList)
539        shPenalty.Add(hklList,0,WACV)
540        shPenalty.Add(wx.StaticText(DData,wx.ID_ANY,' Zero MRD tolerance: '),0,WACV)
541        shToler = G2G.ValidatedTxtCtrl(DData,POData,7,nDig=(10,2),typeHint=float)
542        shPenalty.Add(shToler,0,WACV)
543        return shPenalty   
544       
545    def ExtSizer(Type):
546       
547        def OnSCExtType(event):
548            Obj = event.GetEventObject()
549            item = Indx[Obj.GetId()]
550            UseList[item[0]]['Extinction'][item[1]] = Obj.GetValue()
551            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
552               
553        def OnEref(event):
554            Obj = event.GetEventObject()
555            item = Indx[Obj.GetId()]
556            UseList[item[0]]['Extinction'][2][item[1]][1] = Obj.GetValue()
557   
558        def OnExtRef(event):
559            Obj = event.GetEventObject()
560            UseList[G2frame.hist]['Extinction'][1] = Obj.GetValue()
561           
562        if Type == 'HKLF':
563            extSizer = wx.BoxSizer(wx.VERTICAL)
564            typeSizer = wx.BoxSizer(wx.HORIZONTAL)           
565            typeSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Extinction type: '),0,WACV)
566            Choices = ['None','Primary','Secondary Type I','Secondary Type II',]    # remove 'Secondary Type I & II'
567            typeTxt = wx.ComboBox(DData,wx.ID_ANY,choices=Choices,value=UseList[G2frame.hist]['Extinction'][1],
568                style=wx.CB_READONLY|wx.CB_DROPDOWN)
569            Indx[typeTxt.GetId()] = [G2frame.hist,1]
570            typeTxt.Bind(wx.EVT_COMBOBOX,OnSCExtType)
571            typeSizer.Add(typeTxt)
572            typeSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Approx: '),0,WACV)
573            Choices=['Lorentzian','Gaussian']
574            approxTxT = wx.ComboBox(DData,wx.ID_ANY,choices=Choices,value=UseList[G2frame.hist]['Extinction'][0],
575                style=wx.CB_READONLY|wx.CB_DROPDOWN)
576            Indx[approxTxT.GetId()] = [G2frame.hist,0]
577            approxTxT.Bind(wx.EVT_COMBOBOX,OnSCExtType)
578            typeSizer.Add(approxTxT)
579            if UseList[G2frame.hist]['Extinction'][1] == 'None':
580                extSizer.Add(typeSizer,0)
581            else:
582                extSizer.Add(typeSizer,0,wx.BOTTOM,5)       
583                if 'Tbar' in UseList[G2frame.hist]['Extinction'][2]:       #skipped for TOF   
584                    valSizer =wx.BoxSizer(wx.HORIZONTAL)
585                    valSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Tbar(mm):'),0,WACV)
586                    tbarVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Extinction'][2],'Tbar',
587                        xmin=0.,nDig=(10,3),typeHint=float)
588                    valSizer.Add(tbarVal,0,WACV)
589                    valSizer.Add(wx.StaticText(DData,wx.ID_ANY,' cos(2ThM):'),0,WACV)
590                    cos2tm = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Extinction'][2],'Cos2TM',
591                        xmin=0.,xmax=1.,nDig=(10,3),typeHint=float)
592                    valSizer.Add(cos2tm,0,WACV)
593                    extSizer.Add(valSizer,0)
594                val2Sizer =wx.BoxSizer(wx.HORIZONTAL)
595                if 'Primary' in UseList[G2frame.hist]['Extinction'][1]:
596                    Ekey = ['Ep',]
597                elif 'Secondary Type II' == UseList[G2frame.hist]['Extinction'][1]:
598                    Ekey = ['Es',]
599                elif 'Secondary Type I' == UseList[G2frame.hist]['Extinction'][1]:
600                    Ekey = ['Eg',]
601                else:
602                    Ekey = ['Eg','Es']
603                for ekey in Ekey:
604                    Eref = wx.CheckBox(DData,wx.ID_ANY,label=ekey+' : ')
605                    Eref.SetValue(UseList[G2frame.hist]['Extinction'][2][ekey][1])
606                    Indx[Eref.GetId()] = [G2frame.hist,ekey]
607                    Eref.Bind(wx.EVT_CHECKBOX, OnEref)
608                    val2Sizer.Add(Eref,0,WACV|wx.LEFT,5)
609                    Eval = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Extinction'][2][ekey],0,
610                        xmin=0.,nDig=(10,3,'g'),typeHint=float)
611                    val2Sizer.Add(Eval,0,WACV)
612                extSizer.Add(val2Sizer,0)
613        else:   #PWDR
614            extSizer = wx.BoxSizer(wx.HORIZONTAL)
615            extRef = wx.CheckBox(DData,wx.ID_ANY,label=' Extinction: ')
616            extRef.SetValue(UseList[G2frame.hist]['Extinction'][1])
617            extRef.Bind(wx.EVT_CHECKBOX, OnExtRef)
618            extSizer.Add(extRef,0,WACV|wx.LEFT,5)
619            extVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Extinction'],0,
620                xmin=0.,nDig=(10,2),typeHint=float)
621            extSizer.Add(extVal,0,WACV)
622
623        return extSizer
624       
625    def BabSizer():
626       
627        def OnBabRef(event):
628            Obj = event.GetEventObject()
629            item,bab = Indx[Obj.GetId()]
630            UseList[item]['Babinet']['Bab'+bab][1] = Obj.GetValue()
631       
632        babSizer = wx.BoxSizer(wx.HORIZONTAL)
633        for bab in ['A','U']:
634            babRef = wx.CheckBox(DData,wx.ID_ANY,label=' Babinet '+bab+': ')
635            babRef.SetValue(UseList[G2frame.hist]['Babinet']['Bab'+bab][1])
636            Indx[babRef.GetId()] = [G2frame.hist,bab]
637            babRef.Bind(wx.EVT_CHECKBOX, OnBabRef)
638            babSizer.Add(babRef,0,WACV|wx.LEFT,5)
639            babVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Babinet']['Bab'+bab],0,
640                nDig=(10,3),xmin=0.,typeHint=float)
641            babSizer.Add(babVal,0,WACV)
642        return babSizer
643       
644    def FlackSizer():
645       
646        def OnFlackRef(event):
647            Obj = event.GetEventObject()
648            UseList[G2frame.hist]['Flack'][1] = Obj.GetValue()
649               
650        flackSizer = wx.BoxSizer(wx.HORIZONTAL)
651        flackRef = wx.CheckBox(DData,wx.ID_ANY,label=' Flack parameter: ')
652        flackRef.SetValue(UseList[G2frame.hist]['Flack'][1])
653        flackRef.Bind(wx.EVT_CHECKBOX, OnFlackRef)
654        flackSizer.Add(flackRef,0,WACV|wx.LEFT,5)
655        flackVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Flack'],0,nDig=(10,3),typeHint=float)
656        flackSizer.Add(flackVal,0,WACV)
657        return flackSizer
658       
659    def DispSizer():
660       
661        def OnDispRef(event):
662            Obj = event.GetEventObject()
663            UseList[G2frame.hist]['Layer Disp'][1] = Obj.GetValue()
664               
665        dispSizer = wx.BoxSizer(wx.HORIZONTAL)
666        dispRef = wx.CheckBox(DData,wx.ID_ANY,label=u' Layer displacement (\xb5m): ')
667        dispRef.SetValue(UseList[G2frame.hist]['Layer Disp'][1])
668        dispRef.Bind(wx.EVT_CHECKBOX, OnDispRef)
669        dispSizer.Add(dispRef,0,WACV|wx.LEFT,5)
670        dispSizer.Add(G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Layer Disp'],0,nDig=(10,2),typeHint=float),0,WACV)
671        return dispSizer
672       
673    def twinSizer():
674       
675        def OnAddTwin(event):
676            twinMat = np.array([[-1,0,0],[0,-1,0],[0,0,-1]])    #inversion by default
677            twinVal = 0.0
678            UseList[G2frame.hist]['Twins'].append([twinMat,twinVal])
679            nNonM = UseList[G2frame.hist]['Twins'][0][1][2]
680            for i in range(nNonM):
681                UseList[G2frame.hist]['Twins'].append([False,0.0])
682            addtwin.SetValue(False)
683            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
684           
685        def OnMat(event):
686            event.Skip()
687            Obj = event.GetEventObject()
688            it,im = Indx[Obj.GetId()]
689            newMat = Obj.GetValue().split()
690            try:
691                uvw = [int(newMat[i]) for i in range(3)]
692            except ValueError:
693                uvw = UseList[G2frame.hist]['Twins'][it][0][im]
694            UseList[G2frame.hist]['Twins'][it][0][im] = uvw
695            Obj.SetValue('%3d %3d %3d'%(uvw[0],uvw[1],uvw[2]))
696           
697        def OnTwinVal(invalid,value,tc):
698            it = Indx[tc.GetId()]
699            sumTw = 0.
700            for it,twin in enumerate(UseList[G2frame.hist]['Twins']):
701                if it:
702                    sumTw += twin[1]
703            UseList[G2frame.hist]['Twins'][0][1][0] = 1.-sumTw
704            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
705           
706        def OnTwinRef(event):
707            Obj = event.GetEventObject()
708            UseList[G2frame.hist]['Twins'][0][1][1] = Obj.GetValue()
709           
710        def OnTwinInv(event):
711            Obj = event.GetEventObject()
712            it = Indx[Obj.GetId()]
713            UseList[G2frame.hist]['Twins'][it][0] = Obj.GetValue()
714                       
715        def OnTwinDel(event):
716            Obj = event.GetEventObject()
717            it = Indx[Obj.GetId()]
718            nNonM = UseList[G2frame.hist]['Twins'][0][1][2]
719            for i in range(nNonM):
720                del UseList[G2frame.hist]['Twins'][1+i+it]
721            del UseList[G2frame.hist]['Twins'][it]
722            sumTw = 0.
723            for it,twin in enumerate(UseList[G2frame.hist]['Twins']):
724                if it:
725                    sumTw += twin[1]
726            UseList[G2frame.hist]['Twins'][0][1][0] = 1.-sumTw
727            if len(UseList[G2frame.hist]['Twins']) == 1:
728                UseList[G2frame.hist]['Twins'][0][1][1] = False
729            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))           
730           
731        nTwin = len(UseList[G2frame.hist]['Twins'])
732        twinsizer = wx.BoxSizer(wx.VERTICAL)
733        topsizer = wx.BoxSizer(wx.HORIZONTAL)         
734        topsizer.Add(wx.StaticText(DData,wx.ID_ANY,' Merohedral twins: '),0,WACV)
735        #temporary - add twin not allowed if nonmerohedral twins present
736#        if nTwin == 1 or 'bool' not in str(type(UseList[G2frame.hist]['Twins'][1][0])):
737        addtwin = wx.CheckBox(DData,wx.ID_ANY,label=' Add Twin Law')
738        addtwin.Bind(wx.EVT_CHECKBOX, OnAddTwin)
739        topsizer.Add(addtwin,0,WACV|wx.LEFT,5)
740        twinsizer.Add(topsizer)
741        Indx = {}
742        if nTwin > 1:
743            for it,Twin in enumerate(UseList[G2frame.hist]['Twins']):
744                twinMat,twinVal = Twin
745                matSizer = wx.BoxSizer(wx.HORIZONTAL)
746                if it:
747                    Style = wx.TE_PROCESS_ENTER
748                    TwVal = Twin[1]
749                else:
750                    Style = wx.TE_READONLY
751                    TwVal = Twin[1][0]
752                if 'bool' not in str(type(Twin[0])):
753                    matSizer.Add(wx.StaticText(DData,-1,' Twin Law: '),0,WACV|wx.LEFT,5)
754                    for im,Mat in enumerate(twinMat):
755                        mat = wx.TextCtrl(DData,wx.ID_ANY,'%3d %3d %3d'%(Mat[0],Mat[1],Mat[2]),
756                            style=Style)
757                        if it:
758                            Indx[mat.GetId()] = [it,im]
759                            mat.Bind(wx.EVT_TEXT_ENTER,OnMat)
760                            mat.Bind(wx.EVT_KILL_FOCUS,OnMat)
761                        else:
762                            mat.SetBackgroundColour(VERY_LIGHT_GREY)
763                        matSizer.Add(mat,0,WACV|wx.LEFT,5)
764                else:
765                    matSizer.Add(wx.StaticText(DData,-1,' Nonmerohedral twin component %d: '%(it)),0,WACV|wx.LEFT,5)
766                    if not SGData['SGInv']:
767                        twinv = wx.CheckBox(DData,wx.ID_ANY,label=' Use enantiomorph?')
768                        twinv.SetValue(Twin[0])
769                        Indx[twinv.GetId()] = it
770                        twinv.Bind(wx.EVT_CHECKBOX, OnTwinInv)
771                        matSizer.Add(twinv,0,WACV)
772                twinsizer.Add(matSizer,0,wx.LEFT,5)
773                valSizer = wx.BoxSizer(wx.HORIZONTAL)
774                valSizer.Add(wx.StaticText(DData,-1,label=' Twin element fraction:'),0,WACV)
775                if it:
776                    twinval = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Twins'][it],1,nDig=(10,3),
777                        xmin=0.,xmax=1.,typeHint=float,OnLeave=OnTwinVal)
778                    Indx[twinval.GetId()] = it
779                else:
780                    twinval = wx.TextCtrl(DData,-1,'%.3f'%(TwVal),style=Style)
781                    twinval.SetBackgroundColour(VERY_LIGHT_GREY)
782                valSizer.Add(twinval,0,WACV)
783                if it and 'bool' not in str(type(Twin[0])):
784                    twindel = wx.CheckBox(DData,wx.ID_ANY,label=' Delete?')
785                    Indx[twindel.GetId()] = it
786                    twindel.Bind(wx.EVT_CHECKBOX, OnTwinDel)
787                    valSizer.Add(twindel,0,WACV)
788                elif not it:
789                    twinref = wx.CheckBox(DData,wx.ID_ANY,label=' Refine?')
790                    twinref.SetValue(Twin[1][1])
791                    twinref.Bind(wx.EVT_CHECKBOX, OnTwinRef)
792                    valSizer.Add(twinref,0,WACV)
793                twinsizer.Add(valSizer,0,wx.LEFT,5)
794        return twinsizer
795       
796    def OnSelect(event):
797        G2frame.hist = G2frame.dataWindow.HistsInPhase[DData.select.GetSelection()]
798        oldFocus = wx.Window.FindFocus()
799        G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
800        wx.CallLater(100,RepaintHistogramInfo)
801        if oldFocus: wx.CallAfter(oldFocus.SetFocus)
802       
803    def RepaintHistogramInfo(Scroll=0):
804        if 'phoenix' in wx.version():
805            G2frame.bottomSizer.Clear(True)
806            # deal with case where this is called after another tree item has been selected
807            try:
808                DData.Shown
809            except RuntimeError:
810                if GSASIIpath.GetConfigValue('debug'):
811                    print('DBG: DData window deleted. Ignoring RepaintHistogramInfo, forcing redraw')
812                # Repaint called while DData window deleted, force redraw of entire window
813                import GSASIIdataGUI
814                G2frame.PickIdText = ''
815                wx.CallLater(100,GSASIIdataGUI.SelectDataTreeItem,G2frame,G2frame.GPXtree.Selection)
816                return
817        else:
818            # deal with case where this is called after another tree item has been selected
819            if DData.__class__ is  not wx._windows.ScrolledWindow:
820                # fix bug where this is called after the Window is deleted
821                return
822            G2frame.bottomSizer.DeleteWindows()
823        Indx.clear()
824        G2frame.bottomSizer = ShowHistogramInfo()
825        mainSizer.Add(G2frame.bottomSizer)
826        mainSizer.Layout()
827        G2frame.dataWindow.Refresh()
828        DData.SetVirtualSize(mainSizer.GetMinSize())
829        DData.Scroll(0,Scroll)
830        G2frame.dataWindow.SendSizeEvent()
831       
832    def ShowHistogramInfo():
833        '''This creates a sizer with all the information pulled out from the Phase/data dict
834        '''
835       
836        def OnUseData(event):
837            Obj = event.GetEventObject()
838            UseList[G2frame.hist]['Use'] = Obj.GetValue()
839            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
840
841        def OnLeBail(event):
842            Obj = event.GetEventObject()
843            if not UseList[G2frame.hist]['LeBail']:
844                UseList[G2frame.hist]['newLeBail'] = True
845                Obj.SetLabel('Do new Le Bail extraction?')
846            UseList[G2frame.hist]['LeBail'] = not UseList[G2frame.hist]['LeBail']
847        def OnResetSize(event):
848            Obj = event.GetEventObject()
849            item,name = Indx[Obj.GetId()]
850            if name == 'isotropic':
851                UseList[item]['Size'][1][0] = 1.0
852            elif name == 'uniaxial':
853                UseList[item]['Size'][1][0] = 1.0
854                UseList[item]['Size'][1][1] = 1.0
855            elif name == 'ellipsoidal':
856                for i in range(3):
857                    UseList[item]['Size'][4][i] = 1.0
858                    UseList[item]['Size'][4][i+3] = 0.0
859            G2plt.PlotSizeStrainPO(G2frame,data,item)
860            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
861           
862        def OnSizeAxis(event):           
863            event.Skip()
864            Obj = event.GetEventObject()
865            Saxis = Obj.GetValue().split()
866            try:
867                hkl = [int(Saxis[i]) for i in range(3)]
868            except (ValueError,IndexError):
869                hkl = UseList[G2frame.hist]['Size'][3]
870            if not np.any(np.array(hkl)):
871                hkl = UseList[G2frame.hist]['Size'][3]
872            UseList[G2frame.hist]['Size'][3] = hkl
873            h,k,l = hkl
874            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
875           
876        def OnFixVals(event):
877            Obj = event.GetEventObject()
878            UseList[G2frame.hist]['Fix FXU'] = Obj.GetValue()
879
880        if G2frame.hist not in UseList:               
881            G2frame.ErrorDialog('Missing data error',
882                    G2frame.hist+' not in GSAS-II data tree')
883            return
884#patch
885        if 'Use' not in UseList[G2frame.hist]:
886            UseList[G2frame.hist]['Use'] = True
887        if 'LeBail' not in UseList[G2frame.hist]:
888            UseList[G2frame.hist]['LeBail'] = False
889        if 'newLeBail' not in UseList[G2frame.hist]:
890            UseList[G2frame.hist]['newLeBail'] = True
891        if 'Babinet' not in UseList[G2frame.hist]:
892            UseList[G2frame.hist]['Babinet'] = {'BabA':[0.0,False],'BabU':[0.0,False]}
893        if 'Fix FXU' not in UseList[G2frame.hist]:
894            UseList[G2frame.hist]['Fix FXU'] = ' '
895        if 'FixedSeqVars' not in UseList[G2frame.hist]:
896            UseList[G2frame.hist]['FixedSeqVars'] = []
897        if 'Flack' not in UseList[G2frame.hist]:
898            UseList[G2frame.hist]['Flack'] = [0.0,False]
899        if 'Twins' not in UseList[G2frame.hist]:
900            UseList[G2frame.hist]['Twins'] = [[np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False]],]
901        if 'Layer Disp' not in UseList[G2frame.hist]:
902            UseList[G2frame.hist]['Layer Disp'] = [0.0,False]
903#end patch
904        bottomSizer = wx.BoxSizer(wx.VERTICAL)
905        useBox = wx.BoxSizer(wx.HORIZONTAL)
906        useData = wx.CheckBox(DData,wx.ID_ANY,label='Use Histogram: '+G2frame.hist+' ?')
907        useData.Bind(wx.EVT_CHECKBOX, OnUseData)
908        useData.SetValue(UseList[G2frame.hist]['Use'])
909        useBox.Add(useData,0,WACV)
910        if not generalData['doPawley'] and 'PWDR' in G2frame.hist[:4]:
911            lbLabel = 'Redo Le Bail extraction?   '
912            if UseList[G2frame.hist]['newLeBail']:
913                lbLabel = 'Do new Le Bail extraction?'
914            lebail = wx.CheckBox(DData,wx.ID_ANY,label=lbLabel)
915            lebail.Bind(wx.EVT_CHECKBOX, OnLeBail)
916            lebail.SetValue(UseList[G2frame.hist]['LeBail'])
917            useBox.Add(lebail,0,WACV)
918            if UseList[G2frame.hist]['LeBail']:
919                G2frame.SetStatusText('To reset Le Bail, cycle Le Bail check box.',1)
920        bottomSizer.Add(useBox,0,wx.TOP|wx.BOTTOM|wx.LEFT,5)
921        if G2frame.testSeqRefineMode():
922            bottomSizer.Add(wx.StaticText(DData,label='     Sequential Refinemment Options'))
923            parmChoice = [' ','X','XU','U','F','FX','FXU','FU']
924            if generalData['Type'] == 'magnetic':
925                parmChoice += ['M','MX','MXU','MU','MF','MFX','MFXU','MFU']
926            fixBox = wx.BoxSizer(wx.HORIZONTAL)
927            fixBox.Add(wx.StaticText(DData,label='     Fix these var types: '),0,WACV)
928            fixVals = wx.ComboBox(DData,value=UseList[G2frame.hist]['Fix FXU'],choices=parmChoice,
929                style=wx.CB_DROPDOWN)
930            fixVals.Bind(wx.EVT_COMBOBOX,OnFixVals)
931            fixBox.Add(fixVals,0,WACV)
932            fixBox.Add(wx.StaticText(DData,label=' in phase '+generalData['Name']+' for this histogram'),0,WACV)
933            bottomSizer.Add(fixBox)
934            SeqId = G2gd.GetGPXtreeItemId(G2frame, G2frame.root, 'Sequential results')
935            if SeqId:
936                fixBox = wx.BoxSizer(wx.HORIZONTAL)
937                fixBox.Add(wx.StaticText(DData,label='     Specific phase variables to fix for this histogram: '),0,WACV)
938                addFixed = wx.Button(DData,wx.ID_ANY,label='Select Vars')
939                fixBox.Add(addFixed,0,WACV)
940                addFixed.Bind(wx.EVT_BUTTON,OnAddFixed)
941                fixedVars = UseList[G2frame.hist].get('FixedSeqVars',[])
942                if len(fixedVars): 
943                    fixBox.Add(wx.StaticText(DData,label=' (currently {} fixed)'.format(len(fixedVars))),0,WACV)
944            bottomSizer.Add(fixBox)
945       
946        bottomSizer.Add(ScaleSizer(),0,wx.BOTTOM,5)
947           
948        if G2frame.hist[:4] == 'PWDR':
949            if UseList[G2frame.hist]['Size'][0] == 'isotropic':
950                isoSizer = wx.BoxSizer(wx.HORIZONTAL)
951                isoSizer.Add(TopSizer(' Domain size model: ',['isotropic','uniaxial','ellipsoidal'],
952                    'Size',OnSizeType),0,WACV)
953                isoSizer.Add(LGmixSizer('Size',[0.,1.],OnLGmixRef))
954                isoSizer.Add(ResetSizer('isotropic',OnResetSize),0,WACV)
955                bottomSizer.Add(isoSizer)
956                bottomSizer.Add(IsoSizer(u'size(\xb5m): ','Size',(10,4),[0.,4.],OnSizeRef),0,wx.BOTTOM,5)
957            elif UseList[G2frame.hist]['Size'][0] == 'uniaxial':
958                uniSizer = wx.BoxSizer(wx.HORIZONTAL)
959                uniSizer.Add(TopSizer(' Domain size model: ',['isotropic','uniaxial','ellipsoidal'],
960                    'Size',OnSizeType),0,WACV)
961                uniSizer.Add(LGmixSizer('Size',[0.,1.],OnLGmixRef))
962                uniSizer.Add(ResetSizer('uniaxial',OnResetSize),0,WACV)
963                bottomSizer.Add(UniSizer('Size',OnSizeAxis),0)
964                bottomSizer.Add(uniSizer)
965                bottomSizer.Add(UniDataSizer(u'size(\xb5m): ','Size',(10,3),[0.,4.],OnSizeRef),0,wx.BOTTOM,5)
966            elif UseList[G2frame.hist]['Size'][0] == 'ellipsoidal':
967                ellSizer = wx.BoxSizer(wx.HORIZONTAL)
968                ellSizer.Add(TopSizer(' Domain size model: ',['isotropic','uniaxial','ellipsoidal'],
969                    'Size',OnSizeType),0,WACV)
970                ellSizer.Add(LGmixSizer('Size',[0.,1.],OnLGmixRef))
971                ellSizer.Add(ResetSizer('ellipsoidal',OnResetSize),0,WACV)
972                bottomSizer.Add(ellSizer)
973                bottomSizer.Add(EllSizeDataSizer(),0,wx.BOTTOM,5)
974           
975            if UseList[G2frame.hist]['Mustrain'][0] == 'isotropic':
976                isoSizer = wx.BoxSizer(wx.HORIZONTAL)
977                isoSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
978                    'Mustrain',OnStrainType),0,WACV)
979                isoSizer.Add(LGmixSizer('Mustrain',[0.,1.],OnLGmixRef))
980                isoSizer.Add(ResetSizer('isotropic',OnResetStrain),0,WACV)
981                bottomSizer.Add(isoSizer)
982                bottomSizer.Add(IsoSizer(' microstrain: ','Mustrain',(10,1),[0.,1.e5],OnStrainRef),0,wx.BOTTOM,5)
983            elif UseList[G2frame.hist]['Mustrain'][0] == 'uniaxial':
984                uniSizer = wx.BoxSizer(wx.HORIZONTAL)
985                uniSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
986                    'Mustrain',OnStrainType),0,WACV)
987                uniSizer.Add(LGmixSizer('Mustrain',[0.,1.],OnLGmixRef))
988                uniSizer.Add(ResetSizer('uniaxial',OnResetStrain),0,WACV)
989                bottomSizer.Add(uniSizer)
990                bottomSizer.Add(UniSizer('Mustrain',OnStrainAxis),0)
991                bottomSizer.Add(UniDataSizer('mustrain: ','Mustrain',(10,1),[0.,1.e5],OnStrainRef),0,wx.BOTTOM,5)
992            elif UseList[G2frame.hist]['Mustrain'][0] == 'generalized':
993                genSizer = wx.BoxSizer(wx.HORIZONTAL)
994                genSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
995                    'Mustrain',OnStrainType),0,WACV)
996                genSizer.Add(LGmixSizer('Mustrain',[0.,1.],OnLGmixRef))
997                genSizer.Add(ResetSizer('generalized',OnResetStrain),0,WACV)
998                bottomSizer.Add(genSizer)
999                bottomSizer.Add(GenStrainDataSizer(),0,wx.BOTTOM,5)
1000           
1001            bottomSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Hydrostatic/elastic strain:'))
1002            bottomSizer.Add(HstrainSizer())
1003            bottomSizer.Add(DispSizer())
1004               
1005            poSizer = wx.BoxSizer(wx.VERTICAL)
1006            POData = UseList[G2frame.hist]['Pref.Ori.']
1007# patch - add penalty items
1008            if len(POData) < 7:
1009                POData.append(['',])
1010                POData.append(0.1)
1011            if not POData[6]:
1012                POData[6] = ['',]
1013# end patch
1014            poSizer.Add(PoTopSizer(POData))
1015            if POData[0] == 'MD':
1016                poSizer.Add(MDDataSizer(POData))
1017            else:           #'SH'
1018                if POData[4]:       #SH order > 0
1019                    textJ = G2lat.textureIndex(POData[5])
1020                    poSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Spherical harmonic coefficients: '+'Texture index: %.3f'%(textJ))
1021                        ,0,wx.TOP|wx.BOTTOM,5)
1022                    poSizer.Add(SHDataSizer(POData),0,wx.TOP|wx.BOTTOM,5)
1023                    poSizer.Add(SHPenalty(POData),0,wx.TOP|wx.BOTTOM,5)
1024                   
1025            bottomSizer.Add(poSizer,0,wx.TOP|wx.BOTTOM,5)
1026            bottomSizer.Add(ExtSizer('PWDR'),0,wx.TOP|wx.BOTTOM,5)
1027            if generalData['Type'] != 'magnetic': 
1028                bottomSizer.Add(BabSizer(),0,wx.BOTTOM,5)
1029        elif G2frame.hist[:4] == 'HKLF':
1030            bottomSizer.Add(ExtSizer('HKLF'),0,wx.BOTTOM,5)
1031            bottomSizer.Add(BabSizer(),0,wx.BOTTOM,5)
1032            if not SGData['SGInv'] and len(UseList[G2frame.hist]['Twins']) < 2:
1033                bottomSizer.Add(FlackSizer(),0,wx.BOTTOM,5)
1034            bottomSizer.Add(twinSizer(),0,wx.BOTTOM,5)
1035        return bottomSizer
1036
1037    ######################################################################
1038    #### Beginning of UpdateDData execution here
1039    ######################################################################
1040    G2frame.SetStatusText('',1)
1041    keyList = G2frame.GetHistogramNames(['PWDR','HKLF'])
1042    UseList = data['Histograms']
1043    # look for histgrams that are no longer in the project (should not happen!)
1044    broken = [i for i in UseList if i not in keyList]
1045    if broken:
1046        msg = 'Removing histogram(s) referenced in this phase that are no longer in project:\n\n'
1047        for i,j in enumerate(broken): 
1048            if i > 0: msg += ', '
1049            msg += j
1050            del data['Histograms'][j]
1051        G2G.G2MessageBox(G2frame,msg,'Removing bad histograms')
1052    if UseList:
1053        G2frame.dataWindow.DataMenu.Enable(G2G.wxID_DATADELETE,True)
1054        for item in G2frame.Refine: item.Enable(True)
1055    else:
1056        G2frame.dataWindow.DataMenu.Enable(G2G.wxID_DATADELETE,False)
1057        for item in G2frame.Refine: item.Enable(False)
1058    # make a list of histograms (any type) used in this phase, ordered as in tree
1059    G2frame.dataWindow.HistsInPhase = [name for name in keyList if name in UseList]
1060    generalData = data['General']
1061    cell = generalData['Cell'][1:]
1062    Amat,Bmat = G2lat.cell2AB(cell[:6])
1063    PhaseName = generalData['Name']       
1064    SGData = generalData['SGData']
1065    if len(G2frame.dataWindow.HistsInPhase) == 0: # no associated histograms, nothing to display here
1066        G2frame.hist = ''
1067    elif hist and hist in G2frame.dataWindow.HistsInPhase: # something was input as a selection as an argument
1068        G2frame.hist = hist
1069    elif (not G2frame.hist) or (G2frame.hist not in G2frame.dataWindow.HistsInPhase): # no or bad selection but have data, take the first
1070        G2frame.hist = G2frame.dataWindow.HistsInPhase[0]
1071    Indx = {}
1072   
1073    if DData.GetSizer():
1074        try:
1075            if hasattr(DData,'select'): 
1076                DData.select.Unbind(wx.EVT_LISTBOX)  # remove binding to avoid event on Linux
1077        except:
1078            pass
1079        DData.GetSizer().Clear(True)
1080    mainSizer = wx.BoxSizer(wx.VERTICAL)
1081    topSizer = wx.BoxSizer(wx.HORIZONTAL)
1082    topSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Histogram data for Phase '+PhaseName+':'),0,wx.LEFT,5)
1083    # add help button to bring up help web page - at right sede of window
1084    topSizer.Add((-1,-1),1,wx.EXPAND)
1085    topSizer.Add(G2G.HelpButton(DData,helpIndex=G2frame.dataWindow.helpKey))
1086    mainSizer.Add(topSizer,0,wx.EXPAND)
1087    if G2frame.hist:
1088        topSizer = wx.FlexGridSizer(1,2,5,5)
1089        DData.select = wx.ListBox(DData,choices=G2frame.dataWindow.HistsInPhase,
1090                            style=wx.LB_SINGLE,size=(-1,160))
1091        DData.select.SetSelection(G2frame.dataWindow.HistsInPhase.index(G2frame.hist))
1092        DData.select.SetFirstItem(G2frame.dataWindow.HistsInPhase.index(G2frame.hist))
1093        DData.select.Bind(wx.EVT_LISTBOX,OnSelect)
1094        topSizer.Add(DData.select,0,WACV|wx.LEFT,5)
1095        if any(['PWDR' in item for item in keyList]):
1096            topSizer.Add(PlotSizer())
1097        mainSizer.Add(topSizer)       
1098        G2frame.bottomSizer = ShowHistogramInfo()
1099        mainSizer.Add(G2frame.bottomSizer)
1100    elif not keyList:
1101        mainSizer.Add(wx.StaticText(DData,wx.ID_ANY,
1102            '  (This project has no data; use Import to read it)'),0,wx.TOP,10)
1103    elif not UseList in G2frame.dataWindow.HistsInPhase:
1104        mainSizer.Add(wx.StaticText(DData,wx.ID_ANY,
1105            '  (This phase has no associated data; use appropriate Edit/Add... menu item)'),0,wx.TOP,10)
1106    else:
1107        mainSizer.Add(wx.StaticText(DData,wx.ID_ANY,'  (Strange, how did we get here?)'),0,wx.TOP,10)
1108       
1109    G2phG.SetPhaseWindow(DData,mainSizer,Scroll=Scroll)
1110
1111def MakeHistPhaseWin(G2frame):
1112    '''Display Phase/Data info from Hist/Phase tree item (not used with Phase/Data tab)
1113    '''
1114    TabSelectionIdDict = {}
1115    def OnSelectPage(event):
1116        'Called when an item is selected from the Select page menu'
1117        tabname = TabSelectionIdDict.get(event.GetId()) # lookup phase
1118        if not tabname:
1119            print ('Warning: menu item not in dict! id= %d'%event.GetId())
1120            return
1121        # find the tab matching the phase
1122        for i,page in enumerate(phaseList):
1123            if tabname == phaseList[i]:
1124                HAPBook.SetSelection(i)
1125                wx.CallAfter(FillDDataWindow,i) # may result in a double paint on some OSs
1126                return
1127        else:
1128            print ("Warning: tab "+tabname+" was not found")
1129           
1130    def OnPageChanged(event):
1131        'respond to a notebook tab'
1132        page = event.GetSelection()
1133        wx.CallAfter(FillDDataWindow,page)
1134
1135    def getDDataWindow():
1136        'Get the current scrollwindow for selected phase'
1137        return DData[HAPBook.GetSelection()]
1138   
1139    def getDDataPhaseinfo():
1140        'Get the data tree entry for the currently selected phase'
1141        page = HAPBook.GetSelection()
1142        return G2frame.GPXtree.GetItemPyData(phaseIds[page])
1143       
1144    def FillDDataWindow(page):
1145        'display the DData info'
1146        G2frame.HistPhaseLastSel = phaseList[page]
1147        data = G2frame.GPXtree.GetItemPyData(phaseIds[page])
1148        G2plt.PlotSizeStrainPO(G2frame,data,hist='',Start=True)           
1149        UpdateDData(G2frame,DData[page],data)
1150       
1151    #### G2frame.dataWindow.DataMenu/"Edit Phase" menu routines (note similar routines in GSASIIphsGUI.py)
1152    def OnHklfAdd(event):
1153        data = getDDataPhaseinfo()
1154        keyList = data['Histograms'].keys()
1155        TextList = []
1156        if not G2frame.GPXtree.GetCount():
1157            return
1158       
1159        item, cookie = G2frame.GPXtree.GetFirstChild(G2frame.root)
1160        while item:
1161            name = G2frame.GPXtree.GetItemText(item)
1162            if name not in keyList and 'HKLF' in name:
1163                TextList.append(name)
1164            item, cookie = G2frame.GPXtree.GetNextChild(G2frame.root, cookie)                       
1165            if not TextList: 
1166                G2G.G2MessageBox(G2frame,'No reflections')
1167                return
1168        dlg = G2G.G2MultiChoiceDialog(G2frame, 'Select reflection sets to use',
1169            'Use data',TextList)
1170        try:
1171            if dlg.ShowModal() == wx.ID_OK:
1172                result = dlg.GetSelections()
1173            else:
1174                return
1175        finally:
1176            dlg.Destroy()
1177
1178        # get the histograms used in other phases
1179        phaseRIdList,usedHistograms = G2frame.GetPhaseInfofromTree()
1180        usedHKLFhists = [] # used single-crystal histograms
1181        for p in usedHistograms:
1182            for h in usedHistograms[p]:
1183                if h.startswith('HKLF ') and h not in usedHKLFhists:
1184                    usedHKLFhists.append(h)
1185        # check that selected single crystal histograms are not already in use!
1186        for i in result:
1187            used = [TextList[i] for i in result if TextList[i] in usedHKLFhists]
1188            if used:
1189                msg = 'The following single crystal histogram(s) are already in use'
1190                for i in used:
1191                    msg += '\n  '+str(i)
1192                msg += '\nAre you sure you want to add them to this phase? '
1193                msg += 'Associating a single crystal dataset to >1 histogram is usually an error, '
1194                msg += 'so No is suggested here.'
1195                if G2frame.ErrorDialog('Likely error',msg,G2frame,wtype=wx.YES_NO) != wx.ID_YES: return
1196
1197        wx.BeginBusyCursor()
1198        for i in result:
1199            histoName = TextList[i]
1200            Id = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,histoName)
1201            refDict,reflData = G2frame.GPXtree.GetItemPyData(Id)
1202            data['Histograms'][histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
1203                'Babinet':{'BabA':[0.0,False],'BabU':[0.0,False]},
1204                'Extinction':['Lorentzian','None',
1205                {'Tbar':0.1,'Cos2TM':0.955,'Eg':[1.e-7,False],'Es':[1.e-7,False],'Ep':[1.e-7,False]},],
1206                'Flack':[0.0,False],'Twins':[[np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False,0]],]}                       
1207            if 'TwMax' in reflData:     #nonmerohedral twins present
1208                data['Histograms'][histoName]['Twins'] = []
1209                for iT in range(reflData['TwMax'][0]+1):
1210                    if iT in reflData['TwMax'][1]:
1211                        data['Histograms'][histoName]['Twins'].append([False,0.0])
1212                    else:
1213                        data['Histograms'][histoName]['Twins'].append([np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False,reflData['TwMax'][0]]])
1214            else:   #no nonmerohedral twins
1215                data['Histograms'][histoName]['Twins'] = [[np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False,0]],]
1216            UpdateHKLFdata(histoName)
1217        wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1218        wx.EndBusyCursor()
1219       
1220    def OnDataUse(event):
1221        data = getDDataPhaseinfo()
1222#        hist = G2frame.hist
1223        if data['Histograms']:
1224            dlg = G2G.G2MultiChoiceDialog(G2frame, 'Use histograms', 
1225                'Use which histograms?',G2frame.dataWindow.HistsInPhase)
1226            try:
1227                if dlg.ShowModal() == wx.ID_OK:
1228                    sel = dlg.GetSelections()
1229                    for Id,item in enumerate(G2frame.dataWindow.HistsInPhase):
1230                        if Id in sel:
1231                            data['Histograms'][item]['Use'] = True
1232                        else:
1233                            data['Histograms'][item]['Use'] = False                       
1234            finally:
1235                dlg.Destroy()
1236        wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1237
1238    def UpdateHKLFdata(histoName):
1239        data = getDDataPhaseinfo()
1240        generalData = data['General']
1241        Id = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,histoName)
1242        refDict,reflData = G2frame.GPXtree.GetItemPyData(Id)
1243        SGData = generalData['SGData']
1244        Cell = generalData['Cell'][1:7]
1245        G,g = G2lat.cell2Gmat(Cell)
1246        for iref,ref in enumerate(reflData['RefList']):
1247            H = list(ref[:3])
1248            ref[4] = np.sqrt(1./G2lat.calc_rDsq2(H,G))
1249            iabsnt,ref[3],Uniq,phi = G2spc.GenHKLf(H,SGData)
1250       
1251    def OnDataCopy(event):
1252        data = getDDataPhaseinfo()
1253        hist = G2frame.hist
1254        keyList = G2frame.dataWindow.HistsInPhase[:]
1255        if hist in keyList: keyList.remove(hist)
1256        if not keyList:
1257            G2G.G2MessageBox(G2frame,'No histograms to copy to')
1258            return
1259        sourceDict = copy.deepcopy(data['Histograms'][hist])
1260        if 'HKLF' in sourceDict['Histogram']:
1261            copyNames = ['Extinction','Babinet','Flack','Twins']
1262        else:  #PWDR 
1263            copyNames = ['Pref.Ori.','Size','Mustrain','HStrain','Extinction','Babinet','LeBail','newLeBail','Layer Disp']
1264        copyNames += ['Scale','Fix FXU','FixedSeqVars']
1265        copyDict = {}
1266        for name in copyNames:
1267            if name not in sourceDict: continue
1268            copyDict[name] = copy.deepcopy(sourceDict[name])        #force copy
1269        dlg = G2G.G2MultiChoiceDialog(G2frame,u'Copy phase/histogram parameters\nfrom '+hist[5:][:35],
1270                'Copy phase/hist parameters', keyList)
1271        try:
1272            if dlg.ShowModal() == wx.ID_OK:
1273                for sel in dlg.GetSelections():
1274                    data['Histograms'][keyList[sel]].update(copy.deepcopy(copyDict))
1275        finally:
1276            dlg.Destroy()
1277       
1278    def OnDataCopyFlags(event):
1279        data = getDDataPhaseinfo()
1280        hist = G2frame.hist
1281        sourceDict = copy.deepcopy(data['Histograms'][hist])
1282        copyDict = {}
1283        if 'HKLF' in sourceDict['Histogram']:
1284            copyNames = ['Extinction','Babinet','Flack','Twins']
1285        else:  #PWDR 
1286            copyNames = ['Pref.Ori.','Size','Mustrain','HStrain','Extinction','Babinet','Layer Disp']
1287        copyNames += ['Scale','Fix FXU','FixedSeqVars']
1288        babNames = ['BabA','BabU']
1289        for name in copyNames:
1290            if name not in sourceDict: continue
1291            if name in ['Scale','Extinction','HStrain','Flack','Twins','Layer Disp']:
1292                if name == 'Extinction' and 'HKLF' in sourceDict['Histogram']:
1293                    copyDict[name] = {name:[sourceDict[name][:2]]}
1294                    for item in ['Eg','Es','Ep']:
1295                        copyDict[name][item] = sourceDict[name][2][item][1]
1296                elif name == 'Twins':
1297                    copyDict[name] = sourceDict[name][0][1][1]
1298                else:
1299                    copyDict[name] = sourceDict[name][1]
1300            elif name in ['Size','Mustrain']:
1301                copyDict[name] = [sourceDict[name][0],sourceDict[name][2],sourceDict[name][5]]
1302            elif name == 'Pref.Ori.':
1303                copyDict[name] = [sourceDict[name][0],sourceDict[name][2]]
1304                if sourceDict[name][0] == 'SH':
1305                    SHterms = sourceDict[name][5]
1306                    SHflags = {}
1307                    for item in SHterms:
1308                        SHflags[item] = SHterms[item]
1309                    copyDict[name].append(SHflags)
1310            elif name == 'Babinet':
1311                copyDict[name] = {}
1312                for bab in babNames:
1313                    copyDict[name][bab] = sourceDict[name][bab][1]
1314            elif name == 'Fix FXU' or name == 'FixedSeqVars':
1315                copyDict[name] = copy.deepcopy(sourceDict[name])                   
1316        keyList = G2frame.dataWindow.HistsInPhase[:]
1317        if hist in keyList: keyList.remove(hist)
1318        if not keyList:
1319            G2G.G2MessageBox(G2frame,'No histograms to copy to')
1320            return
1321        dlg = G2G.G2MultiChoiceDialog(G2frame,u'Copy phase/histogram flags\nfrom '+hist[5:][:35],
1322                'Copy phase/hist flags', keyList)
1323        try:
1324            if dlg.ShowModal() == wx.ID_OK:
1325                for sel in dlg.GetSelections():
1326                    item = keyList[sel]
1327                    for name in copyNames:
1328                        if name not in sourceDict: continue
1329                        if name in ['Scale','Extinction','HStrain','Flack','Twins','Layer Disp']:
1330                            if name == 'Extinction' and 'HKLF' in sourceDict['Histogram']:
1331                                data['Histograms'][item][name][:2] = copy.deepcopy(sourceDict[name][:2])
1332                                for itm in ['Eg','Es','Ep']:
1333                                    data['Histograms'][item][name][2][itm][1] = copy.deepcopy(copyDict[name][itm])
1334                            elif name == 'Twins':
1335                                data['Histograms'][item]['Twins'][0][1][1] = copy.deepcopy(copyDict['Twins'])
1336                            else:
1337                                try:
1338                                    data['Histograms'][item][name][1] = copy.deepcopy(copyDict[name])
1339                                except KeyError:
1340                                    continue
1341                        elif name in ['Size','Mustrain']:
1342                            data['Histograms'][item][name][0] = copy.deepcopy(copyDict[name][0])
1343                            data['Histograms'][item][name][2] = copy.deepcopy(copyDict[name][1])
1344                            data['Histograms'][item][name][5] = copy.deepcopy(copyDict[name][2])
1345                        elif name == 'Pref.Ori.':
1346                            data['Histograms'][item][name][0] = copy.deepcopy(copyDict[name][0])
1347                            data['Histograms'][item][name][2] = copy.deepcopy(copyDict[name][1])
1348                            if sourceDict[name][0] == 'SH':
1349                               SHflags = copy.deepcopy(copyDict[name][2])
1350                               SHterms = copy.deepcopy(sourceDict[name][5])
1351                               data['Histograms'][item][name][6] = copy.deepcopy(sourceDict[name][6])
1352                               data['Histograms'][item][name][7] = copy.deepcopy(sourceDict[name][7])
1353                        elif name == 'Babinet':
1354                            for bab in babNames:
1355                                data['Histograms'][item][name][bab][1] = copy.deepcopy(copyDict[name][bab])
1356                        elif name == 'Fix FXU' or name == 'FixedSeqVars':
1357                            data['Histograms'][item][name] = copy.deepcopy(sourceDict[name])                     
1358        finally:
1359            dlg.Destroy()
1360       
1361    def OnSelDataCopy(event):
1362        data = getDDataPhaseinfo()
1363        hist = G2frame.hist
1364        sourceDict = data['Histograms'][hist]
1365        keyList = G2frame.dataWindow.HistsInPhase[:]
1366        if hist in keyList: keyList.remove(hist)
1367        if not keyList:
1368            G2G.G2MessageBox(G2frame,'No histograms to copy to')
1369            return
1370        if 'HKLF' in sourceDict['Histogram']:
1371            copyNames = ['Extinction','Babinet','Flack','Twins']
1372        else:  #PWDR 
1373            copyNames = ['Pref.Ori.','Size','Mustrain','HStrain','Extinction','Babinet','LeBail','newLeBail','Layer Disp']
1374        copyNames += ['Scale','Fix FXU','FixedSeqVars']           
1375        dlg = G2G.G2MultiChoiceDialog(G2frame,'Select which parameters to copy',
1376            'Select phase data parameters', copyNames)
1377        selectedItems = []
1378        try:
1379            if dlg.ShowModal() == wx.ID_OK:
1380                selectedItems = [copyNames[i] for i in dlg.GetSelections()]
1381        finally:
1382            dlg.Destroy()
1383        if not selectedItems: return # nothing to copy
1384        copyDict = {}
1385        for parm in selectedItems:
1386            if parm not in sourceDict: continue
1387            copyDict[parm] = copy.deepcopy(sourceDict[parm])
1388        dlg = G2G.G2MultiChoiceDialog(G2frame,u'Copy selected phase/histogram parameters\nfrom '+hist[5:][:35],
1389            'Copy selected phase/hist parameters', keyList)
1390        try:
1391            if dlg.ShowModal() == wx.ID_OK:
1392                for sel in dlg.GetSelections():
1393                    data['Histograms'][keyList[sel]].update(copy.deepcopy(copyDict))
1394        finally:
1395            dlg.Destroy()           
1396       
1397    def OnPwdrAdd(event):
1398        data = getDDataPhaseinfo()
1399        generalData = data['General']
1400        SGData = generalData['SGData']
1401        newList = []
1402        NShkl = len(G2spc.MustrainNames(SGData))
1403        NDij = len(G2spc.HStrainNames(SGData))
1404        keyList = data['Histograms'].keys()
1405        TextList = []
1406        if G2frame.GPXtree.GetCount():
1407            item, cookie = G2frame.GPXtree.GetFirstChild(G2frame.root)
1408            while item:
1409                name = G2frame.GPXtree.GetItemText(item)
1410                if name not in keyList and 'PWDR' in name:
1411                    TextList.append(name)
1412                item, cookie = G2frame.GPXtree.GetNextChild(G2frame.root, cookie)
1413            if not TextList: 
1414                G2G.G2MessageBox(G2frame,'No histograms')
1415                return
1416            dlg = G2G.G2MultiChoiceDialog(G2frame, 'Select powder histograms to use',
1417                'Use data',TextList)
1418            try:
1419                if dlg.ShowModal() == wx.ID_OK:
1420                    result = dlg.GetSelections()
1421                    for i in result: newList.append(TextList[i])
1422                    if 'All PWDR' in newList:
1423                        newList = TextList[1:]
1424                    for histoName in newList:
1425                        Id = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,histoName)
1426                        data['Histograms'][histoName] = {'Histogram':histoName,'Show':False,'LeBail':False,'newLeBail':True,
1427                            'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{},['',],0.1],
1428                            'Size':['isotropic',[1.,1.,1.],[False,False,False],[0,0,1],
1429                                [1.,1.,1.,0.,0.,0.],6*[False,]],
1430                            'Mustrain':['isotropic',[1000.0,1000.0,1.0],[False,False,False],[0,0,1],
1431                                NShkl*[0.01,],NShkl*[False,]],
1432                            'HStrain':[NDij*[0.0,],NDij*[False,]],
1433                            'Layer Disp':[0.0,False],                         
1434                            'Extinction':[0.0,False],'Babinet':{'BabA':[0.0,False],'BabU':[0.0,False]},'Fix FXU':' ','FixedSeqVars':[]}
1435                        refList = G2frame.GPXtree.GetItemPyData(G2gd.GetGPXtreeItemId(G2frame,Id,'Reflection Lists'))
1436                        refList[generalData['Name']] = {}                       
1437                    wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1438            finally:
1439                dlg.Destroy()
1440               
1441    def OnDataDelete(event):
1442        data = getDDataPhaseinfo()
1443        if G2frame.dataWindow.HistsInPhase:
1444            DelList = []
1445            extraOpts= {'label_0':'Remove from all phases','value_0':False}
1446            h,pd = G2frame.GetUsedHistogramsAndPhasesfromTree()
1447            if len(pd) > 1:
1448                opts = extraOpts
1449            else:
1450                opts = {}
1451            dlg = G2G.G2MultiChoiceDialog(G2frame, 
1452                'Select histogram(s) to remove   \nfrom this phase:',
1453                'Remove histograms', G2frame.dataWindow.HistsInPhase,
1454                extraOpts=opts)
1455            try:
1456                if dlg.ShowModal() == wx.ID_OK:
1457                    DelList = [G2frame.dataWindow.HistsInPhase[i] for i in dlg.GetSelections()]
1458            finally:
1459                dlg.Destroy()
1460            if extraOpts['value_0']:
1461                for p in pd: 
1462                    for i in DelList:
1463                        if i in pd[p]['Histograms']: del pd[p]['Histograms'][i]
1464            else:
1465                for i in DelList:
1466                    del data['Histograms'][i]
1467            wx.CallLater(100,UpdateDData,G2frame,getDDataWindow(),data)
1468           
1469    def OnDataApplyStrain(event):
1470        data = getDDataPhaseinfo()
1471        SGData = data['General']['SGData']       
1472        DijVals = data['Histograms'][G2frame.hist]['HStrain'][0][:]
1473        # apply the Dij values to the reciprocal cell
1474        newA = []
1475        Dijdict = dict(zip(G2spc.HStrainNames(SGData),DijVals))
1476        for Aij,lbl in zip(G2lat.cell2A(data['General']['Cell'][1:7]),
1477                            ['D11','D22','D33','D12','D13','D23']):
1478            newA.append(Aij + Dijdict.get(lbl,0.0))
1479        # convert back to direct cell
1480        data['General']['Cell'][1:7] = G2lat.A2cell(newA)
1481        data['General']['Cell'][7] = G2lat.calc_V(newA)
1482        # subtract the selected histograms Dij values from all for this phase
1483        for hist in data['Histograms']:
1484            for i,val in enumerate(DijVals):
1485                data['Histograms'][hist]['HStrain'][0][i] -= val
1486        # for hist in sorted(data['Histograms']): # list effective lattice constants applying Dij values
1487        #     DijVals = data['Histograms'][hist]['HStrain'][0]
1488        #     newA = []
1489        #     Dijdict = dict(zip(G2spc.HStrainNames(SGData),DijVals))
1490        #     for Aij,lbl in zip(G2lat.cell2A(data['General']['Cell'][1:7]),
1491        #                     ['D11','D22','D33','D12','D13','D23']):
1492        #         newA.append(Aij + Dijdict.get(lbl,0.0))
1493        #     print(hist, G2lat.A2cell(newA)[:3], G2lat.calc_V(newA))
1494        wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1495       
1496    #### start of MakeHistPhaseWin
1497    G2frame.dataWindow.ClearData()
1498    HAPBook = G2G.GSNoteBook(parent=G2frame.dataWindow)
1499    G2frame.dataWindow.GetSizer().Add(HAPBook,1,wx.ALL|wx.EXPAND,1)
1500    phaseList = []
1501    phaseIds = []
1502    DData = []
1503    sub = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,'Phases')
1504    item, cookie = G2frame.GPXtree.GetFirstChild(sub)
1505    while item: # loop over phases
1506        phaseName = G2frame.GPXtree.GetItemText(item)
1507        phaseIds.append(item)
1508        phaseList.append(phaseName)
1509        item, cookie = G2frame.GPXtree.GetNextChild(sub, cookie)
1510        HAPtab = wx.ScrolledWindow(HAPBook)
1511        HAPBook.AddPage(HAPtab,phaseName)
1512        DData.append(HAPtab)
1513    HAPBook.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, OnPageChanged)
1514    # set up "Select tab" menu contents
1515    G2gd.SetDataMenuBar(G2frame,G2frame.dataWindow.DataMenu)
1516    mid = G2frame.dataWindow.DataMenu.FindMenu('Select tab')
1517    menu = G2frame.dataWindow.DataMenu.GetMenu(mid)
1518    items = menu.GetMenuItems()
1519    for item in items:
1520         menu.Remove(item)
1521    if len(phaseList) == 0: return
1522    for i,page in enumerate(phaseList):
1523        Id = wx.NewId()
1524        if menu.FindItem(page) >= 0: continue # is tab already in menu?
1525        menu.Append(Id,page,'')
1526        TabSelectionIdDict[Id] = page
1527        G2frame.Bind(wx.EVT_MENU, OnSelectPage, id=Id)
1528    # define commands in G2frame.dataWindow.DataMenu/"Edit Phase" menu
1529    G2frame.Bind(wx.EVT_MENU, OnDataUse, id=G2G.wxID_DATAUSE)
1530    G2frame.Bind(wx.EVT_MENU, OnDataCopy, id=G2G.wxID_DATACOPY)
1531    G2frame.Bind(wx.EVT_MENU, OnDataCopyFlags, id=G2G.wxID_DATACOPYFLAGS)
1532    G2frame.Bind(wx.EVT_MENU, OnSelDataCopy, id=G2G.wxID_DATASELCOPY)
1533    G2frame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2G.wxID_PWDRADD)
1534    G2frame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2G.wxID_HKLFADD)
1535    G2frame.Bind(wx.EVT_MENU, OnDataDelete, id=G2G.wxID_DATADELETE)
1536    G2frame.Bind(wx.EVT_MENU, OnDataApplyStrain, id=G2G.wxID_DATADIJ)
1537    # display the last-selected phase or the 1st
1538    try:
1539        G2frame.HistPhaseLastSel
1540    except:
1541        G2frame.HistPhaseLastSel = phaseList[0]
1542    if G2frame.HistPhaseLastSel in phaseList:
1543        page = phaseList.index(G2frame.HistPhaseLastSel)
1544    else:
1545        page = 0
1546    HAPBook.SetSelection(page)
1547    wx.CallAfter(FillDDataWindow,page)
Note: See TracBrowser for help on using the repository browser.