source: trunk/GSASIIddataGUI.py @ 5068

Last change on this file since 5068 was 5043, checked in by vondreele, 4 years ago

Add ISODISTORT menu option to RMC menu; active only for PDFfit (under construction)
More additions for PDFfit
fix split --> rsplit in G2phase_CIF importer

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