source: trunk/GSASIIddataGUI.py @ 4987

Last change on this file since 4987 was 4972, checked in by vondreele, 4 years ago

hide intensity related variables & set their refinement flags to False for LeBail? selection. Message shows .

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