source: trunk/GSASIIddataGUI.py @ 5003

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

redo LeBail? msg to show up only after screen paint & only show what is changed & now turn off Hist Scale; Save As now in recent menu; scriptable minor docs updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 76.2 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASII - phase data display routines
3########### SVN repository information ###################
4# $Date: 2021-07-28 20:04:06 +0000 (Wed, 28 Jul 2021) $
5# $Author: toby $
6# $Revision: 5003 $
7# $URL: trunk/GSASIIddataGUI.py $
8# $Id: GSASIIddataGUI.py 5003 2021-07-28 20:04:06Z 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: 5003 $")
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,LeBailMsg = 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        if LeBailMsg:
832            G2G.G2MessageBox(G2frame,LeBailMsg,
833                                 title='LeBail refinement changes')
834       
835    def ShowHistogramInfo():
836        '''This creates a sizer with all the information pulled out from the Phase/data dict
837        '''
838       
839        def OnUseData(event):
840            Obj = event.GetEventObject()
841            UseList[G2frame.hist]['Use'] = Obj.GetValue()
842            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
843
844        def OnLeBail(event):
845            Obj = event.GetEventObject()
846            if not UseList[G2frame.hist]['LeBail']:
847                UseList[G2frame.hist]['newLeBail'] = True
848                Obj.SetLabel('Do new Le Bail extraction?')
849            UseList[G2frame.hist]['LeBail'] = not UseList[G2frame.hist]['LeBail']
850            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
851           
852        def OnResetSize(event):
853            Obj = event.GetEventObject()
854            item,name = Indx[Obj.GetId()]
855            if name == 'isotropic':
856                UseList[item]['Size'][1][0] = 1.0
857            elif name == 'uniaxial':
858                UseList[item]['Size'][1][0] = 1.0
859                UseList[item]['Size'][1][1] = 1.0
860            elif name == 'ellipsoidal':
861                for i in range(3):
862                    UseList[item]['Size'][4][i] = 1.0
863                    UseList[item]['Size'][4][i+3] = 0.0
864            G2plt.PlotSizeStrainPO(G2frame,data,item)
865            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
866           
867        def OnSizeAxis(event):           
868            event.Skip()
869            Obj = event.GetEventObject()
870            Saxis = Obj.GetValue().split()
871            try:
872                hkl = [int(Saxis[i]) for i in range(3)]
873            except (ValueError,IndexError):
874                hkl = UseList[G2frame.hist]['Size'][3]
875            if not np.any(np.array(hkl)):
876                hkl = UseList[G2frame.hist]['Size'][3]
877            UseList[G2frame.hist]['Size'][3] = hkl
878            h,k,l = hkl
879            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
880           
881        def OnFixVals(event):
882            Obj = event.GetEventObject()
883            UseList[G2frame.hist]['Fix FXU'] = Obj.GetValue()
884
885        if G2frame.hist not in UseList:               
886            G2frame.ErrorDialog('Missing data error',
887                    G2frame.hist+' not in GSAS-II data tree')
888            return
889#patch
890        if 'Use' not in UseList[G2frame.hist]:
891            UseList[G2frame.hist]['Use'] = True
892        if 'LeBail' not in UseList[G2frame.hist]:
893            UseList[G2frame.hist]['LeBail'] = False
894        if 'newLeBail' not in UseList[G2frame.hist]:
895            UseList[G2frame.hist]['newLeBail'] = True
896        if 'Babinet' not in UseList[G2frame.hist]:
897            UseList[G2frame.hist]['Babinet'] = {'BabA':[0.0,False],'BabU':[0.0,False]}
898        if 'Fix FXU' not in UseList[G2frame.hist]:
899            UseList[G2frame.hist]['Fix FXU'] = ' '
900        if 'FixedSeqVars' not in UseList[G2frame.hist]:
901            UseList[G2frame.hist]['FixedSeqVars'] = []
902        if 'Flack' not in UseList[G2frame.hist]:
903            UseList[G2frame.hist]['Flack'] = [0.0,False]
904        if 'Twins' not in UseList[G2frame.hist]:
905            UseList[G2frame.hist]['Twins'] = [[np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False]],]
906        if 'Layer Disp' not in UseList[G2frame.hist]:
907            UseList[G2frame.hist]['Layer Disp'] = [0.0,False]
908#end patch
909        offMsg = ''
910        bottomSizer = wx.BoxSizer(wx.VERTICAL)
911        useBox = wx.BoxSizer(wx.HORIZONTAL)
912        useData = wx.CheckBox(DData,wx.ID_ANY,label='Use Histogram: '+G2frame.hist+' ?')
913        useData.Bind(wx.EVT_CHECKBOX, OnUseData)
914        useData.SetValue(UseList[G2frame.hist]['Use'])
915        useBox.Add(useData,0,WACV)
916        if not generalData['doPawley'] and 'PWDR' in G2frame.hist[:4]:
917            lbLabel = 'Redo Le Bail extraction?   '
918            if UseList[G2frame.hist]['newLeBail']:
919                lbLabel = 'Do new Le Bail extraction?'
920            lebail = wx.CheckBox(DData,wx.ID_ANY,label=lbLabel)
921            lebail.Bind(wx.EVT_CHECKBOX, OnLeBail)
922            lebail.SetValue(UseList[G2frame.hist]['LeBail'])
923            useBox.Add(lebail,0,WACV)
924            if UseList[G2frame.hist]['LeBail']:
925                G2frame.SetStatusText('To reset Le Bail, cycle Le Bail check box.',1)
926        bottomSizer.Add(useBox,0,wx.TOP|wx.BOTTOM|wx.LEFT,5)
927        if G2frame.testSeqRefineMode() and not UseList[G2frame.hist]['LeBail']:
928            bottomSizer.Add(wx.StaticText(DData,label='     Sequential Refinemment Options'))
929            parmChoice = [' ','X','XU','U','F','FX','FXU','FU']
930            if generalData['Type'] == 'magnetic':
931                parmChoice += ['M','MX','MXU','MU','MF','MFX','MFXU','MFU']
932            fixBox = wx.BoxSizer(wx.HORIZONTAL)
933            fixBox.Add(wx.StaticText(DData,label='     Fix these var types: '),0,WACV)
934            fixVals = wx.ComboBox(DData,value=UseList[G2frame.hist]['Fix FXU'],choices=parmChoice,
935                style=wx.CB_DROPDOWN)
936            fixVals.Bind(wx.EVT_COMBOBOX,OnFixVals)
937            fixBox.Add(fixVals,0,WACV)
938            fixBox.Add(wx.StaticText(DData,label=' in phase '+generalData['Name']+' for this histogram'),0,WACV)
939            bottomSizer.Add(fixBox)
940            SeqId = G2gd.GetGPXtreeItemId(G2frame, G2frame.root, 'Sequential results')
941            if SeqId:
942                fixBox = wx.BoxSizer(wx.HORIZONTAL)
943                fixBox.Add(wx.StaticText(DData,label='     Specific phase variables to fix for this histogram: '),0,WACV)
944                addFixed = wx.Button(DData,wx.ID_ANY,label='Select Vars')
945                fixBox.Add(addFixed,0,WACV)
946                addFixed.Bind(wx.EVT_BUTTON,OnAddFixed)
947                fixedVars = UseList[G2frame.hist].get('FixedSeqVars',[])
948                if len(fixedVars): 
949                    fixBox.Add(wx.StaticText(DData,label=' (currently {} fixed)'.format(len(fixedVars))),0,WACV)
950            bottomSizer.Add(fixBox)
951       
952        if not UseList[G2frame.hist]['LeBail'] or 'HKLF' in G2frame.hist[:4]:
953            bottomSizer.Add(ScaleSizer(),0,wx.BOTTOM,5)
954           
955        if G2frame.hist[:4] == 'PWDR':
956            if UseList[G2frame.hist]['Size'][0] == 'isotropic':
957                isoSizer = wx.BoxSizer(wx.HORIZONTAL)
958                isoSizer.Add(TopSizer(' Domain size model: ',['isotropic','uniaxial','ellipsoidal'],
959                    'Size',OnSizeType),0,WACV)
960                isoSizer.Add(LGmixSizer('Size',[0.,1.],OnLGmixRef))
961                isoSizer.Add(ResetSizer('isotropic',OnResetSize),0,WACV)
962                bottomSizer.Add(isoSizer)
963                bottomSizer.Add(IsoSizer(u'size(\xb5m): ','Size',(10,4),[0.,4.],OnSizeRef),0,wx.BOTTOM,5)
964            elif UseList[G2frame.hist]['Size'][0] == 'uniaxial':
965                uniSizer = wx.BoxSizer(wx.HORIZONTAL)
966                uniSizer.Add(TopSizer(' Domain size model: ',['isotropic','uniaxial','ellipsoidal'],
967                    'Size',OnSizeType),0,WACV)
968                uniSizer.Add(LGmixSizer('Size',[0.,1.],OnLGmixRef))
969                uniSizer.Add(ResetSizer('uniaxial',OnResetSize),0,WACV)
970                bottomSizer.Add(UniSizer('Size',OnSizeAxis),0)
971                bottomSizer.Add(uniSizer)
972                bottomSizer.Add(UniDataSizer(u'size(\xb5m): ','Size',(10,3),[0.,4.],OnSizeRef),0,wx.BOTTOM,5)
973            elif UseList[G2frame.hist]['Size'][0] == 'ellipsoidal':
974                ellSizer = wx.BoxSizer(wx.HORIZONTAL)
975                ellSizer.Add(TopSizer(' Domain size model: ',['isotropic','uniaxial','ellipsoidal'],
976                    'Size',OnSizeType),0,WACV)
977                ellSizer.Add(LGmixSizer('Size',[0.,1.],OnLGmixRef))
978                ellSizer.Add(ResetSizer('ellipsoidal',OnResetSize),0,WACV)
979                bottomSizer.Add(ellSizer)
980                bottomSizer.Add(EllSizeDataSizer(),0,wx.BOTTOM,5)
981           
982            if UseList[G2frame.hist]['Mustrain'][0] == 'isotropic':
983                isoSizer = wx.BoxSizer(wx.HORIZONTAL)
984                isoSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
985                    'Mustrain',OnStrainType),0,WACV)
986                isoSizer.Add(LGmixSizer('Mustrain',[0.,1.],OnLGmixRef))
987                isoSizer.Add(ResetSizer('isotropic',OnResetStrain),0,WACV)
988                bottomSizer.Add(isoSizer)
989                bottomSizer.Add(IsoSizer(' microstrain: ','Mustrain',(10,1),[0.,1.e5],OnStrainRef),0,wx.BOTTOM,5)
990            elif UseList[G2frame.hist]['Mustrain'][0] == 'uniaxial':
991                uniSizer = wx.BoxSizer(wx.HORIZONTAL)
992                uniSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
993                    'Mustrain',OnStrainType),0,WACV)
994                uniSizer.Add(LGmixSizer('Mustrain',[0.,1.],OnLGmixRef))
995                uniSizer.Add(ResetSizer('uniaxial',OnResetStrain),0,WACV)
996                bottomSizer.Add(uniSizer)
997                bottomSizer.Add(UniSizer('Mustrain',OnStrainAxis),0)
998                bottomSizer.Add(UniDataSizer('mustrain: ','Mustrain',(10,1),[0.,1.e5],OnStrainRef),0,wx.BOTTOM,5)
999            elif UseList[G2frame.hist]['Mustrain'][0] == 'generalized':
1000                genSizer = wx.BoxSizer(wx.HORIZONTAL)
1001                genSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
1002                    'Mustrain',OnStrainType),0,WACV)
1003                genSizer.Add(LGmixSizer('Mustrain',[0.,1.],OnLGmixRef))
1004                genSizer.Add(ResetSizer('generalized',OnResetStrain),0,WACV)
1005                bottomSizer.Add(genSizer)
1006                bottomSizer.Add(GenStrainDataSizer(),0,wx.BOTTOM,5)
1007           
1008            bottomSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Hydrostatic/elastic strain:'))
1009            bottomSizer.Add(HstrainSizer())
1010            bottomSizer.Add(DispSizer())
1011               
1012            if not UseList[G2frame.hist]['LeBail']:
1013                poSizer = wx.BoxSizer(wx.VERTICAL)
1014                POData = UseList[G2frame.hist]['Pref.Ori.']
1015# patch - add penalty items
1016                if len(POData) < 7:
1017                    POData.append(['',])
1018                    POData.append(0.1)
1019                if not POData[6]:
1020                    POData[6] = ['',]
1021# end patch
1022                poSizer.Add(PoTopSizer(POData))
1023                if POData[0] == 'MD':
1024                    poSizer.Add(MDDataSizer(POData))
1025                else:           #'SH'
1026                    if POData[4]:       #SH order > 0
1027                        textJ = G2lat.textureIndex(POData[5])
1028                        poSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Spherical harmonic coefficients: '+'Texture index: %.3f'%(textJ))
1029                            ,0,wx.TOP|wx.BOTTOM,5)
1030                        poSizer.Add(SHDataSizer(POData),0,wx.TOP|wx.BOTTOM,5)
1031                        poSizer.Add(SHPenalty(POData),0,wx.TOP|wx.BOTTOM,5)
1032                       
1033                bottomSizer.Add(poSizer,0,wx.TOP|wx.BOTTOM,5)
1034                bottomSizer.Add(ExtSizer('PWDR'),0,wx.TOP|wx.BOTTOM,5)
1035                if generalData['Type'] != 'magnetic': 
1036                    bottomSizer.Add(BabSizer(),0,wx.BOTTOM,5)
1037            else:   #turn off PWDR intensity related paramters for LeBail refinement
1038                if UseList[G2frame.hist]['Scale'][1]:
1039                    offMsg = "Phase fraction"
1040                    UseList[G2frame.hist]['Scale'][1] = False
1041                if UseList[G2frame.hist]['Pref.Ori.'][2]:
1042                    UseList[G2frame.hist]['Pref.Ori.'][2] = False
1043                    if offMsg: offMsg += ', '
1044                    offMsg += 'Preferred orientation'
1045                if UseList[G2frame.hist]['Extinction'][1]:
1046                    UseList[G2frame.hist]['Extinction'][1] = False
1047                    if offMsg: offMsg += ', '
1048                    offMsg += 'Extinction'
1049                flag = False
1050                for item in UseList[G2frame.hist]['Babinet']:
1051                    if UseList[G2frame.hist]['Babinet'][item][1]:
1052                        UseList[G2frame.hist]['Babinet'][item][1] = False
1053                        flag = True
1054                if flag:
1055                    if offMsg: offMsg += ', '
1056                    offMsg += 'Babinet'
1057                # make sure that the at least one phase uses the histogram...
1058                allLeBail = True
1059                hists,phases = G2frame.GetUsedHistogramsAndPhasesfromTree()
1060                for key in phases:
1061                    d = phases[key]
1062                    if G2frame.hist not in d['Histograms']: continue
1063                    if not d['Histograms'][G2frame.hist]['Use']: continue
1064                    if not d['Histograms'][G2frame.hist]['LeBail']:
1065                        #print('Phase',key,'is used as non-LeBail')
1066                        allLeBail = False
1067                        break
1068                # ...or turn off scale
1069                if allLeBail:
1070                    if hists[G2frame.hist]['Sample Parameters']['Scale'][1]:
1071                        hists[G2frame.hist]['Sample Parameters']['Scale'][1] = False
1072                        if offMsg: offMsg += ', '
1073                        offMsg += 'Histogram scale factor'
1074                if offMsg:
1075                    offMsg = "Refinement flags turned for: " + offMsg
1076        elif G2frame.hist[:4] == 'HKLF':
1077            bottomSizer.Add(ExtSizer('HKLF'),0,wx.BOTTOM,5)
1078            bottomSizer.Add(BabSizer(),0,wx.BOTTOM,5)
1079            if not SGData['SGInv'] and len(UseList[G2frame.hist]['Twins']) < 2:
1080                bottomSizer.Add(FlackSizer(),0,wx.BOTTOM,5)
1081            bottomSizer.Add(twinSizer(),0,wx.BOTTOM,5)
1082        return bottomSizer,offMsg
1083
1084    ######################################################################
1085    #### Beginning of UpdateDData execution here
1086    ######################################################################
1087    G2frame.SetStatusText('',1)
1088    keyList = G2frame.GetHistogramNames(['PWDR','HKLF'])
1089    UseList = data['Histograms']
1090    # look for histgrams that are no longer in the project (can happen when histogram deleted from tree)
1091    broken = [i for i in UseList if i not in keyList]
1092    if broken:
1093        msg = 'Removing histogram(s) referenced in this phase that are no longer in project:\n\n'
1094        for i,j in enumerate(broken): 
1095            if i > 0: msg += ', '
1096            msg += j
1097            del data['Histograms'][j]
1098        G2G.G2MessageBox(G2frame,msg,'Dereferencing Removed histograms')
1099    if UseList:
1100        G2frame.dataWindow.DataMenu.Enable(G2G.wxID_DATADELETE,True)
1101        for item in G2frame.Refine: item.Enable(True)
1102    else:
1103        G2frame.dataWindow.DataMenu.Enable(G2G.wxID_DATADELETE,False)
1104        for item in G2frame.Refine: item.Enable(False)
1105    # make a list of histograms (any type) used in this phase, ordered as in tree
1106    G2frame.dataWindow.HistsInPhase = [name for name in keyList if name in UseList]
1107    generalData = data['General']
1108    cell = generalData['Cell'][1:]
1109    Amat,Bmat = G2lat.cell2AB(cell[:6])
1110    PhaseName = generalData['Name']       
1111    SGData = generalData['SGData']
1112    if len(G2frame.dataWindow.HistsInPhase) == 0: # no associated histograms, nothing to display here
1113        G2frame.hist = ''
1114    elif hist and hist in G2frame.dataWindow.HistsInPhase: # something was input as a selection as an argument
1115        G2frame.hist = hist
1116    elif (not G2frame.hist) or (G2frame.hist not in G2frame.dataWindow.HistsInPhase): # no or bad selection but have data, take the first
1117        G2frame.hist = G2frame.dataWindow.HistsInPhase[0]
1118    Indx = {}
1119   
1120    if DData.GetSizer():
1121        try:
1122            if hasattr(DData,'select'): 
1123                DData.select.Unbind(wx.EVT_LISTBOX)  # remove binding to avoid event on Linux
1124        except:
1125            pass
1126        DData.GetSizer().Clear(True)
1127    mainSizer = wx.BoxSizer(wx.VERTICAL)
1128    topSizer = wx.BoxSizer(wx.HORIZONTAL)
1129    topSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Histogram data for Phase '+PhaseName+':'),0,wx.LEFT,5)
1130    # add help button to bring up help web page - at right sede of window
1131    topSizer.Add((-1,-1),1,wx.EXPAND)
1132    topSizer.Add(G2G.HelpButton(DData,helpIndex=G2frame.dataWindow.helpKey))
1133    mainSizer.Add(topSizer,0,wx.EXPAND)
1134    LeBailMsg = None
1135    if G2frame.hist:
1136        topSizer = wx.FlexGridSizer(1,2,5,5)
1137        DData.select = wx.ListBox(DData,choices=G2frame.dataWindow.HistsInPhase,
1138                            style=wx.LB_SINGLE,size=(-1,160))
1139        DData.select.SetSelection(G2frame.dataWindow.HistsInPhase.index(G2frame.hist))
1140        DData.select.SetFirstItem(G2frame.dataWindow.HistsInPhase.index(G2frame.hist))
1141        DData.select.Bind(wx.EVT_LISTBOX,OnSelect)
1142        topSizer.Add(DData.select,0,WACV|wx.LEFT,5)
1143        if any(['PWDR' in item for item in keyList]):
1144            topSizer.Add(PlotSizer())
1145        mainSizer.Add(topSizer)       
1146        G2frame.bottomSizer,LeBailMsg = ShowHistogramInfo()
1147        mainSizer.Add(G2frame.bottomSizer)
1148    elif not keyList:
1149        mainSizer.Add(wx.StaticText(DData,wx.ID_ANY,
1150            '  (This project has no data; use Import to read it)'),0,wx.TOP,10)
1151    elif not UseList in G2frame.dataWindow.HistsInPhase:
1152        mainSizer.Add(wx.StaticText(DData,wx.ID_ANY,
1153            '  (This phase has no associated data; use appropriate Edit/Add... menu item)'),0,wx.TOP,10)
1154    else:
1155        mainSizer.Add(wx.StaticText(DData,wx.ID_ANY,'  (Strange, how did we get here?)'),0,wx.TOP,10)
1156       
1157    G2phG.SetPhaseWindow(DData,mainSizer,Scroll=Scroll)
1158    if LeBailMsg:
1159        G2G.G2MessageBox(G2frame,LeBailMsg,
1160                                 title='LeBail refinement changes')
1161
1162def MakeHistPhaseWin(G2frame):
1163    '''Display Phase/Data info from Hist/Phase tree item (not used with Phase/Data tab)
1164    '''
1165    TabSelectionIdDict = {}
1166    def OnSelectPage(event):
1167        'Called when an item is selected from the Select page menu'
1168        tabname = TabSelectionIdDict.get(event.GetId()) # lookup phase
1169        if not tabname:
1170            print ('Warning: menu item not in dict! id= %d'%event.GetId())
1171            return
1172        # find the tab matching the phase
1173        for i,page in enumerate(phaseList):
1174            if tabname == phaseList[i]:
1175                HAPBook.SetSelection(i)
1176                wx.CallAfter(FillDDataWindow,i) # may result in a double paint on some OSs
1177                return
1178        else:
1179            print ("Warning: tab "+tabname+" was not found")
1180           
1181    def OnPageChanged(event):
1182        'respond to a notebook tab'
1183        page = event.GetSelection()
1184        wx.CallAfter(FillDDataWindow,page)
1185
1186    def getDDataWindow():
1187        'Get the current scrollwindow for selected phase'
1188        return DData[HAPBook.GetSelection()]
1189   
1190    def getDDataPhaseinfo():
1191        'Get the data tree entry for the currently selected phase'
1192        page = HAPBook.GetSelection()
1193        return G2frame.GPXtree.GetItemPyData(phaseIds[page])
1194       
1195    def FillDDataWindow(page):
1196        'display the DData info'
1197        G2frame.HistPhaseLastSel = phaseList[page]
1198        data = G2frame.GPXtree.GetItemPyData(phaseIds[page])
1199        G2plt.PlotSizeStrainPO(G2frame,data,hist='',Start=True)           
1200        UpdateDData(G2frame,DData[page],data)
1201       
1202    #### G2frame.dataWindow.DataMenu/"Edit Phase" menu routines (note similar routines in GSASIIphsGUI.py)
1203    def OnHklfAdd(event):
1204        data = getDDataPhaseinfo()
1205        keyList = data['Histograms'].keys()
1206        TextList = []
1207        if not G2frame.GPXtree.GetCount():
1208            return
1209       
1210        item, cookie = G2frame.GPXtree.GetFirstChild(G2frame.root)
1211        while item:
1212            name = G2frame.GPXtree.GetItemText(item)
1213            if name not in keyList and 'HKLF' in name:
1214                TextList.append(name)
1215            item, cookie = G2frame.GPXtree.GetNextChild(G2frame.root, cookie)                       
1216            if not TextList: 
1217                G2G.G2MessageBox(G2frame,'No reflections')
1218                return
1219        dlg = G2G.G2MultiChoiceDialog(G2frame, 'Select reflection sets to use',
1220            'Use data',TextList)
1221        try:
1222            if dlg.ShowModal() == wx.ID_OK:
1223                result = dlg.GetSelections()
1224            else:
1225                return
1226        finally:
1227            dlg.Destroy()
1228
1229        # get the histograms used in other phases
1230        phaseRIdList,usedHistograms = G2frame.GetPhaseInfofromTree()
1231        usedHKLFhists = [] # used single-crystal histograms
1232        for p in usedHistograms:
1233            for h in usedHistograms[p]:
1234                if h.startswith('HKLF ') and h not in usedHKLFhists:
1235                    usedHKLFhists.append(h)
1236        # check that selected single crystal histograms are not already in use!
1237        for i in result:
1238            used = [TextList[i] for i in result if TextList[i] in usedHKLFhists]
1239            if used:
1240                msg = 'The following single crystal histogram(s) are already in use'
1241                for i in used:
1242                    msg += '\n  '+str(i)
1243                msg += '\nAre you sure you want to add them to this phase? '
1244                msg += 'Associating a single crystal dataset to >1 histogram is usually an error, '
1245                msg += 'so No is suggested here.'
1246                if G2frame.ErrorDialog('Likely error',msg,G2frame,wtype=wx.YES_NO) != wx.ID_YES: return
1247
1248        wx.BeginBusyCursor()
1249        for i in result:
1250            histoName = TextList[i]
1251            Id = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,histoName)
1252            refDict,reflData = G2frame.GPXtree.GetItemPyData(Id)
1253            data['Histograms'][histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
1254                'Babinet':{'BabA':[0.0,False],'BabU':[0.0,False]},
1255                'Extinction':['Lorentzian','None',
1256                {'Tbar':0.1,'Cos2TM':0.955,'Eg':[1.e-7,False],'Es':[1.e-7,False],'Ep':[1.e-7,False]},],
1257                'Flack':[0.0,False],'Twins':[[np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False,0]],]}                       
1258            if 'TwMax' in reflData:     #nonmerohedral twins present
1259                data['Histograms'][histoName]['Twins'] = []
1260                for iT in range(reflData['TwMax'][0]+1):
1261                    if iT in reflData['TwMax'][1]:
1262                        data['Histograms'][histoName]['Twins'].append([False,0.0])
1263                    else:
1264                        data['Histograms'][histoName]['Twins'].append([np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False,reflData['TwMax'][0]]])
1265            else:   #no nonmerohedral twins
1266                data['Histograms'][histoName]['Twins'] = [[np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False,0]],]
1267            UpdateHKLFdata(histoName)
1268        wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1269        wx.EndBusyCursor()
1270       
1271    def OnDataUse(event):
1272        data = getDDataPhaseinfo()
1273#        hist = G2frame.hist
1274        if data['Histograms']:
1275            dlg = G2G.G2MultiChoiceDialog(G2frame, 'Use histograms', 
1276                'Use which histograms?',G2frame.dataWindow.HistsInPhase)
1277            try:
1278                if dlg.ShowModal() == wx.ID_OK:
1279                    sel = dlg.GetSelections()
1280                    for Id,item in enumerate(G2frame.dataWindow.HistsInPhase):
1281                        if Id in sel:
1282                            data['Histograms'][item]['Use'] = True
1283                        else:
1284                            data['Histograms'][item]['Use'] = False                       
1285            finally:
1286                dlg.Destroy()
1287        wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1288
1289    def UpdateHKLFdata(histoName):
1290        data = getDDataPhaseinfo()
1291        generalData = data['General']
1292        Id = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,histoName)
1293        refDict,reflData = G2frame.GPXtree.GetItemPyData(Id)
1294        SGData = generalData['SGData']
1295        Cell = generalData['Cell'][1:7]
1296        G,g = G2lat.cell2Gmat(Cell)
1297        for iref,ref in enumerate(reflData['RefList']):
1298            H = list(ref[:3])
1299            ref[4] = np.sqrt(1./G2lat.calc_rDsq2(H,G))
1300            iabsnt,ref[3],Uniq,phi = G2spc.GenHKLf(H,SGData)
1301       
1302    def OnDataCopy(event):
1303        data = getDDataPhaseinfo()
1304        hist = G2frame.hist
1305        keyList = G2frame.dataWindow.HistsInPhase[:]
1306        if hist in keyList: keyList.remove(hist)
1307        if not keyList:
1308            G2G.G2MessageBox(G2frame,'No histograms to copy to')
1309            return
1310        sourceDict = copy.deepcopy(data['Histograms'][hist])
1311        if 'HKLF' in sourceDict['Histogram']:
1312            copyNames = ['Extinction','Babinet','Flack','Twins']
1313        else:  #PWDR 
1314            copyNames = ['Pref.Ori.','Size','Mustrain','HStrain','Extinction','Babinet','LeBail','newLeBail','Layer Disp']
1315        copyNames += ['Scale','Fix FXU','FixedSeqVars']
1316        copyDict = {}
1317        for name in copyNames:
1318            if name not in sourceDict: continue
1319            copyDict[name] = copy.deepcopy(sourceDict[name])        #force copy
1320        dlg = G2G.G2MultiChoiceDialog(G2frame,u'Copy phase/histogram parameters\nfrom '+hist[5:][:35],
1321                'Copy phase/hist parameters', keyList)
1322        try:
1323            if dlg.ShowModal() == wx.ID_OK:
1324                for sel in dlg.GetSelections():
1325                    data['Histograms'][keyList[sel]].update(copy.deepcopy(copyDict))
1326        finally:
1327            dlg.Destroy()
1328       
1329    def OnDataCopyFlags(event):
1330        data = getDDataPhaseinfo()
1331        hist = G2frame.hist
1332        sourceDict = copy.deepcopy(data['Histograms'][hist])
1333        copyDict = {}
1334        if 'HKLF' in sourceDict['Histogram']:
1335            copyNames = ['Extinction','Babinet','Flack','Twins']
1336        else:  #PWDR 
1337            copyNames = ['Pref.Ori.','Size','Mustrain','HStrain','Extinction','Babinet','Layer Disp']
1338        copyNames += ['Scale','Fix FXU','FixedSeqVars']
1339        babNames = ['BabA','BabU']
1340        for name in copyNames:
1341            if name not in sourceDict: continue
1342            if name in ['Scale','Extinction','HStrain','Flack','Twins','Layer Disp']:
1343                if name == 'Extinction' and 'HKLF' in sourceDict['Histogram']:
1344                    copyDict[name] = {name:[sourceDict[name][:2]]}
1345                    for item in ['Eg','Es','Ep']:
1346                        copyDict[name][item] = sourceDict[name][2][item][1]
1347                elif name == 'Twins':
1348                    copyDict[name] = sourceDict[name][0][1][1]
1349                else:
1350                    copyDict[name] = sourceDict[name][1]
1351            elif name in ['Size','Mustrain']:
1352                copyDict[name] = [sourceDict[name][0],sourceDict[name][2],sourceDict[name][5]]
1353            elif name == 'Pref.Ori.':
1354                copyDict[name] = [sourceDict[name][0],sourceDict[name][2]]
1355                if sourceDict[name][0] == 'SH':
1356                    SHterms = sourceDict[name][5]
1357                    SHflags = {}
1358                    for item in SHterms:
1359                        SHflags[item] = SHterms[item]
1360                    copyDict[name].append(SHflags)
1361            elif name == 'Babinet':
1362                copyDict[name] = {}
1363                for bab in babNames:
1364                    copyDict[name][bab] = sourceDict[name][bab][1]
1365            elif name == 'Fix FXU' or name == 'FixedSeqVars':
1366                copyDict[name] = copy.deepcopy(sourceDict[name])                   
1367        keyList = G2frame.dataWindow.HistsInPhase[:]
1368        if hist in keyList: keyList.remove(hist)
1369        if not keyList:
1370            G2G.G2MessageBox(G2frame,'No histograms to copy to')
1371            return
1372        dlg = G2G.G2MultiChoiceDialog(G2frame,u'Copy phase/histogram flags\nfrom '+hist[5:][:35],
1373                'Copy phase/hist flags', keyList)
1374        try:
1375            if dlg.ShowModal() == wx.ID_OK:
1376                for sel in dlg.GetSelections():
1377                    item = keyList[sel]
1378                    for name in copyNames:
1379                        if name not in sourceDict: continue
1380                        if name in ['Scale','Extinction','HStrain','Flack','Twins','Layer Disp']:
1381                            if name == 'Extinction' and 'HKLF' in sourceDict['Histogram']:
1382                                data['Histograms'][item][name][:2] = copy.deepcopy(sourceDict[name][:2])
1383                                for itm in ['Eg','Es','Ep']:
1384                                    data['Histograms'][item][name][2][itm][1] = copy.deepcopy(copyDict[name][itm])
1385                            elif name == 'Twins':
1386                                data['Histograms'][item]['Twins'][0][1][1] = copy.deepcopy(copyDict['Twins'])
1387                            else:
1388                                try:
1389                                    data['Histograms'][item][name][1] = copy.deepcopy(copyDict[name])
1390                                except KeyError:
1391                                    continue
1392                        elif name in ['Size','Mustrain']:
1393                            data['Histograms'][item][name][0] = copy.deepcopy(copyDict[name][0])
1394                            data['Histograms'][item][name][2] = copy.deepcopy(copyDict[name][1])
1395                            data['Histograms'][item][name][5] = copy.deepcopy(copyDict[name][2])
1396                        elif name == 'Pref.Ori.':
1397                            data['Histograms'][item][name][0] = copy.deepcopy(copyDict[name][0])
1398                            data['Histograms'][item][name][2] = copy.deepcopy(copyDict[name][1])
1399                            if sourceDict[name][0] == 'SH':
1400                               SHflags = copy.deepcopy(copyDict[name][2])
1401                               SHterms = copy.deepcopy(sourceDict[name][5])
1402                               data['Histograms'][item][name][6] = copy.deepcopy(sourceDict[name][6])
1403                               data['Histograms'][item][name][7] = copy.deepcopy(sourceDict[name][7])
1404                        elif name == 'Babinet':
1405                            for bab in babNames:
1406                                data['Histograms'][item][name][bab][1] = copy.deepcopy(copyDict[name][bab])
1407                        elif name == 'Fix FXU' or name == 'FixedSeqVars':
1408                            data['Histograms'][item][name] = copy.deepcopy(sourceDict[name])                     
1409        finally:
1410            dlg.Destroy()
1411       
1412    def OnSelDataCopy(event):
1413        data = getDDataPhaseinfo()
1414        hist = G2frame.hist
1415        sourceDict = data['Histograms'][hist]
1416        keyList = G2frame.dataWindow.HistsInPhase[:]
1417        if hist in keyList: keyList.remove(hist)
1418        if not keyList:
1419            G2G.G2MessageBox(G2frame,'No histograms to copy to')
1420            return
1421        if 'HKLF' in sourceDict['Histogram']:
1422            copyNames = ['Extinction','Babinet','Flack','Twins']
1423        else:  #PWDR 
1424            copyNames = ['Pref.Ori.','Size','Mustrain','HStrain','Extinction','Babinet','LeBail','newLeBail','Layer Disp']
1425        copyNames += ['Scale','Fix FXU','FixedSeqVars']           
1426        dlg = G2G.G2MultiChoiceDialog(G2frame,'Select which parameters to copy',
1427            'Select phase data parameters', copyNames)
1428        selectedItems = []
1429        try:
1430            if dlg.ShowModal() == wx.ID_OK:
1431                selectedItems = [copyNames[i] for i in dlg.GetSelections()]
1432        finally:
1433            dlg.Destroy()
1434        if not selectedItems: return # nothing to copy
1435        copyDict = {}
1436        for parm in selectedItems:
1437            if parm not in sourceDict: continue
1438            copyDict[parm] = copy.deepcopy(sourceDict[parm])
1439        dlg = G2G.G2MultiChoiceDialog(G2frame,u'Copy selected phase/histogram parameters\nfrom '+hist[5:][:35],
1440            'Copy selected phase/hist parameters', keyList)
1441        try:
1442            if dlg.ShowModal() == wx.ID_OK:
1443                for sel in dlg.GetSelections():
1444                    data['Histograms'][keyList[sel]].update(copy.deepcopy(copyDict))
1445        finally:
1446            dlg.Destroy()           
1447       
1448    def OnPwdrAdd(event):
1449        data = getDDataPhaseinfo()
1450        generalData = data['General']
1451        SGData = generalData['SGData']
1452        newList = []
1453        NShkl = len(G2spc.MustrainNames(SGData))
1454        NDij = len(G2spc.HStrainNames(SGData))
1455        keyList = data['Histograms'].keys()
1456        TextList = []
1457        if G2frame.GPXtree.GetCount():
1458            item, cookie = G2frame.GPXtree.GetFirstChild(G2frame.root)
1459            while item:
1460                name = G2frame.GPXtree.GetItemText(item)
1461                if name not in keyList and 'PWDR' in name:
1462                    TextList.append(name)
1463                item, cookie = G2frame.GPXtree.GetNextChild(G2frame.root, cookie)
1464            if not TextList: 
1465                G2G.G2MessageBox(G2frame,'No histograms')
1466                return
1467            dlg = G2G.G2MultiChoiceDialog(G2frame, 'Select powder histograms to use',
1468                'Use data',TextList)
1469            try:
1470                if dlg.ShowModal() == wx.ID_OK:
1471                    result = dlg.GetSelections()
1472                    for i in result: newList.append(TextList[i])
1473                    if 'All PWDR' in newList:
1474                        newList = TextList[1:]
1475                    for histoName in newList:
1476                        Id = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,histoName)
1477                        data['Histograms'][histoName] = {'Histogram':histoName,'Show':False,'LeBail':False,'newLeBail':True,
1478                            'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{},['',],0.1],
1479                            'Size':['isotropic',[1.,1.,1.],[False,False,False],[0,0,1],
1480                                [1.,1.,1.,0.,0.,0.],6*[False,]],
1481                            'Mustrain':['isotropic',[1000.0,1000.0,1.0],[False,False,False],[0,0,1],
1482                                NShkl*[0.01,],NShkl*[False,]],
1483                            'HStrain':[NDij*[0.0,],NDij*[False,]],
1484                            'Layer Disp':[0.0,False],                         
1485                            'Extinction':[0.0,False],'Babinet':{'BabA':[0.0,False],'BabU':[0.0,False]},'Fix FXU':' ','FixedSeqVars':[]}
1486                        refList = G2frame.GPXtree.GetItemPyData(G2gd.GetGPXtreeItemId(G2frame,Id,'Reflection Lists'))
1487                        refList[generalData['Name']] = {}                       
1488                    wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1489            finally:
1490                dlg.Destroy()
1491               
1492    def OnDataDelete(event):
1493        data = getDDataPhaseinfo()
1494        if G2frame.dataWindow.HistsInPhase:
1495            DelList = []
1496            extraOpts= {'label_0':'Remove from all phases','value_0':False}
1497            h,pd = G2frame.GetUsedHistogramsAndPhasesfromTree()
1498            if len(pd) > 1:
1499                opts = extraOpts
1500            else:
1501                opts = {}
1502            dlg = G2G.G2MultiChoiceDialog(G2frame, 
1503                'Select histogram(s) to remove   \nfrom this phase:',
1504                'Remove histograms', G2frame.dataWindow.HistsInPhase,
1505                extraOpts=opts)
1506            try:
1507                if dlg.ShowModal() == wx.ID_OK:
1508                    DelList = [G2frame.dataWindow.HistsInPhase[i] for i in dlg.GetSelections()]
1509            finally:
1510                dlg.Destroy()
1511            if extraOpts['value_0']:
1512                for p in pd: 
1513                    for i in DelList:
1514                        if i in pd[p]['Histograms']: del pd[p]['Histograms'][i]
1515            else:
1516                for i in DelList:
1517                    del data['Histograms'][i]
1518            wx.CallLater(100,UpdateDData,G2frame,getDDataWindow(),data)
1519           
1520    def OnDataApplyStrain(event):
1521        data = getDDataPhaseinfo()
1522        SGData = data['General']['SGData']       
1523        DijVals = data['Histograms'][G2frame.hist]['HStrain'][0][:]
1524        # apply the Dij values to the reciprocal cell
1525        newA = []
1526        Dijdict = dict(zip(G2spc.HStrainNames(SGData),DijVals))
1527        for Aij,lbl in zip(G2lat.cell2A(data['General']['Cell'][1:7]),
1528                            ['D11','D22','D33','D12','D13','D23']):
1529            newA.append(Aij + Dijdict.get(lbl,0.0))
1530        # convert back to direct cell
1531        data['General']['Cell'][1:7] = G2lat.A2cell(newA)
1532        data['General']['Cell'][7] = G2lat.calc_V(newA)
1533        # subtract the selected histograms Dij values from all for this phase
1534        for hist in data['Histograms']:
1535            for i,val in enumerate(DijVals):
1536                data['Histograms'][hist]['HStrain'][0][i] -= val
1537        # for hist in sorted(data['Histograms']): # list effective lattice constants applying Dij values
1538        #     DijVals = data['Histograms'][hist]['HStrain'][0]
1539        #     newA = []
1540        #     Dijdict = dict(zip(G2spc.HStrainNames(SGData),DijVals))
1541        #     for Aij,lbl in zip(G2lat.cell2A(data['General']['Cell'][1:7]),
1542        #                     ['D11','D22','D33','D12','D13','D23']):
1543        #         newA.append(Aij + Dijdict.get(lbl,0.0))
1544        #     print(hist, G2lat.A2cell(newA)[:3], G2lat.calc_V(newA))
1545        wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1546       
1547    #### start of MakeHistPhaseWin
1548    G2frame.dataWindow.ClearData()
1549    HAPBook = G2G.GSNoteBook(parent=G2frame.dataWindow)
1550    G2frame.dataWindow.GetSizer().Add(HAPBook,1,wx.ALL|wx.EXPAND,1)
1551    phaseList = []
1552    phaseIds = []
1553    DData = []
1554    sub = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,'Phases')
1555    item, cookie = G2frame.GPXtree.GetFirstChild(sub)
1556    while item: # loop over phases
1557        phaseName = G2frame.GPXtree.GetItemText(item)
1558        phaseIds.append(item)
1559        phaseList.append(phaseName)
1560        item, cookie = G2frame.GPXtree.GetNextChild(sub, cookie)
1561        HAPtab = wx.ScrolledWindow(HAPBook)
1562        HAPBook.AddPage(HAPtab,phaseName)
1563        DData.append(HAPtab)
1564    HAPBook.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, OnPageChanged)
1565    # set up "Select tab" menu contents
1566    G2gd.SetDataMenuBar(G2frame,G2frame.dataWindow.DataMenu)
1567    mid = G2frame.dataWindow.DataMenu.FindMenu('Select tab')
1568    menu = G2frame.dataWindow.DataMenu.GetMenu(mid)
1569    items = menu.GetMenuItems()
1570    for item in items:
1571         menu.Remove(item)
1572    if len(phaseList) == 0: return
1573    for i,page in enumerate(phaseList):
1574        Id = wx.NewId()
1575        if menu.FindItem(page) >= 0: continue # is tab already in menu?
1576        menu.Append(Id,page,'')
1577        TabSelectionIdDict[Id] = page
1578        G2frame.Bind(wx.EVT_MENU, OnSelectPage, id=Id)
1579    # define commands in G2frame.dataWindow.DataMenu/"Edit Phase" menu
1580    G2frame.Bind(wx.EVT_MENU, OnDataUse, id=G2G.wxID_DATAUSE)
1581    G2frame.Bind(wx.EVT_MENU, OnDataCopy, id=G2G.wxID_DATACOPY)
1582    G2frame.Bind(wx.EVT_MENU, OnDataCopyFlags, id=G2G.wxID_DATACOPYFLAGS)
1583    G2frame.Bind(wx.EVT_MENU, OnSelDataCopy, id=G2G.wxID_DATASELCOPY)
1584    G2frame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2G.wxID_PWDRADD)
1585    G2frame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2G.wxID_HKLFADD)
1586    G2frame.Bind(wx.EVT_MENU, OnDataDelete, id=G2G.wxID_DATADELETE)
1587    G2frame.Bind(wx.EVT_MENU, OnDataApplyStrain, id=G2G.wxID_DATADIJ)
1588    # display the last-selected phase or the 1st
1589    try:
1590        G2frame.HistPhaseLastSel
1591    except:
1592        G2frame.HistPhaseLastSel = phaseList[0]
1593    if G2frame.HistPhaseLastSel in phaseList:
1594        page = phaseList.index(G2frame.HistPhaseLastSel)
1595    else:
1596        page = 0
1597    HAPBook.SetSelection(page)
1598    wx.CallAfter(FillDDataWindow,page)
Note: See TracBrowser for help on using the repository browser.