source: trunk/GSASIIddataGUI.py

Last change on this file was 5307, checked in by vondreele, 3 months ago

add micro-ED support. New electron scattering tables, new histogram type ('SEC'), etc., etc.
Fix sign of ZERO for RMCProfile MakeInst? fxn.
Add calc of Rvalues to Error Analysis for PWDR & HKLF histograms; results are printed om console.
Add a stub for Cluster analysis in Controls GUI

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 74.5 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASII - phase data display routines
3########### SVN repository information ###################
4# $Date: 2022-07-07 17:02:04 +0000 (Thu, 07 Jul 2022) $
5# $Author: vondreele $
6# $Revision: 5307 $
7# $URL: trunk/GSASIIddataGUI.py $
8# $Id: GSASIIddataGUI.py 5307 2022-07-07 17:02:04Z vondreele $
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: 5307 $")
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        ifkeV = 'E' in UseList[G2frame.hist].get('Type','')           
83        plotSizer = wx.BoxSizer(wx.VERTICAL)
84        if ifkeV:
85            choice = ['None','Mustrain','Size']
86        else:
87            choice = ['None','Mustrain','Size','Preferred orientation','St. proj. Inv. pole figure','Eq. area Inv. pole figure']
88        plotSel = wx.RadioBox(DData,wx.ID_ANY,'Select plot type:',choices=choice,
89            majorDimension=1,style=wx.RA_SPECIFY_COLS)
90        plotSel.SetStringSelection(generalData['Data plot type'])
91        plotSel.Bind(wx.EVT_RADIOBOX,OnPlotSel)   
92        plotSizer.Add(plotSel)
93        if generalData['Data plot type'] == 'Preferred orientation':
94            POhklSizer = wx.BoxSizer(wx.HORIZONTAL)
95            POhklSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Plot preferred orientation for H K L: '),0,WACV)
96            h,k,l = generalData['POhkl']
97            poAxis = wx.TextCtrl(DData,wx.ID_ANY,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
98            poAxis.Bind(wx.EVT_TEXT_ENTER,OnPOhkl)
99            poAxis.Bind(wx.EVT_KILL_FOCUS,OnPOhkl)
100            POhklSizer.Add(poAxis,0,WACV)
101            plotSizer.Add(POhklSizer)
102        elif generalData['Data plot type'] in ['Mustrain','Size']:
103            projSizer = wx.BoxSizer(wx.HORIZONTAL)
104            projSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Show projections for: '),0,WACV)
105            proj = ['','x','y','z','xy','xz','yz','xyz']
106            projType = wx.ComboBox(DData,wx.ID_ANY,value=generalData['3Dproj'],choices=proj,
107                style=wx.CB_READONLY|wx.CB_DROPDOWN)
108            projType.Bind(wx.EVT_COMBOBOX, OnProj)
109            projSizer.Add(projType,0,WACV)
110            plotSizer.Add(projSizer)           
111        return plotSizer
112       
113    def ScaleSizer():
114       
115        def OnScaleRef(event):
116            Obj = event.GetEventObject()
117            UseList[G2frame.hist]['Scale'][1] = Obj.GetValue()
118        def onChangeFraction(invalid,value,tc):
119            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
120           
121        scaleSizer = wx.BoxSizer(wx.HORIZONTAL)
122        if 'PWDR' in G2frame.hist:
123            scaleRef = wx.CheckBox(DData,wx.ID_ANY,label=' Phase fraction: ')
124        elif 'HKLF' in G2frame.hist:
125            scaleRef = wx.CheckBox(DData,wx.ID_ANY,label=' Scale factor: ')               
126        scaleRef.SetValue(UseList[G2frame.hist]['Scale'][1])
127        scaleRef.Bind(wx.EVT_CHECKBOX, OnScaleRef)
128        scaleSizer.Add(scaleRef,0,WACV|wx.LEFT,5)
129        scaleVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Scale'],0,
130            xmin=0.,nDig=(10,4,'g'),typeHint=float,OnLeave=onChangeFraction)
131        scaleSizer.Add(scaleVal,0,WACV)
132        if 'PWDR' in G2frame.hist and generalData['Type'] != 'magnetic':
133            wtSum = G2pwd.PhaseWtSum(G2frame,G2frame.hist)
134            if wtSum and UseList[G2frame.hist]['Use']:
135                weightFr = UseList[G2frame.hist]['Scale'][0]*generalData['Mass']/wtSum
136                scaleSizer.Add(wx.StaticText(DData,label=' Wt. fraction: %.3f'%(weightFr)),0,WACV)
137        return scaleSizer
138       
139    def OnLGmixRef(event):
140        Obj = event.GetEventObject()
141        hist,name = Indx[Obj.GetId()]
142        UseList[G2frame.hist][name][2][2] = Obj.GetValue()
143       
144    def OnSizeType(event):
145        Obj = event.GetEventObject()
146        UseList[G2frame.hist]['Size'][0] = Obj.GetValue()
147        G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
148        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
149       
150    def OnSizeRef(event):
151        Obj = event.GetEventObject()
152        hist,pid = Indx[Obj.GetId()]
153        if UseList[G2frame.hist]['Size'][0] == 'ellipsoidal':
154            UseList[G2frame.hist]['Size'][5][pid] = Obj.GetValue()               
155        else:
156            UseList[G2frame.hist]['Size'][2][pid] = Obj.GetValue()
157       
158    def OnStrainType(event):
159        Obj = event.GetEventObject()
160        UseList[G2frame.hist]['Mustrain'][0] = Obj.GetValue()
161        G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
162        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
163       
164    def OnStrainRef(event):
165        Obj = event.GetEventObject()
166        hist,pid = Indx[Obj.GetId()]
167        if UseList[G2frame.hist]['Mustrain'][0] == 'generalized':
168            UseList[G2frame.hist]['Mustrain'][5][pid] = Obj.GetValue()
169        else:
170            UseList[G2frame.hist]['Mustrain'][2][pid] = Obj.GetValue()
171       
172    def OnStrainAxis(event):
173        event.Skip()
174        Obj = event.GetEventObject()
175        Saxis = Obj.GetValue().split()
176        try:
177            hkl = [int(Saxis[i]) for i in range(3)]
178        except (ValueError,IndexError):
179            hkl = UseList[G2frame.hist]['Mustrain'][3]
180        if not np.any(np.array(hkl)):
181            hkl = UseList[G2frame.hist]['Mustrain'][3]
182        UseList[G2frame.hist]['Mustrain'][3] = hkl
183        h,k,l = hkl
184        Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
185        wx.CallAfter(G2plt.PlotSizeStrainPO,G2frame,data,hist)
186       
187    def OnResetStrain(event):
188        Obj = event.GetEventObject()
189        item,name = Indx[Obj.GetId()]
190        if name == 'isotropic':
191            UseList[item]['Mustrain'][1][0] = 1000.0
192        elif name == 'uniaxial':
193            UseList[item]['Mustrain'][1][0] = 1000.0
194            UseList[item]['Mustrain'][1][1] = 1000.0
195        elif name == 'generalized':
196            muiso = 1000.
197            cell = generalData['Cell'][1:7]
198            vals = G2spc.Muiso2Shkl(muiso,SGData,cell)
199            UseList[item]['Mustrain'][4] = vals
200        G2plt.PlotSizeStrainPO(G2frame,data,item)
201        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
202           
203    def OnPOAxis(event):
204        event.Skip()
205        Obj = event.GetEventObject()
206        Saxis = Obj.GetValue().split()
207        try:
208            hkl = [int(Saxis[i]) for i in range(3)]
209        except (ValueError,IndexError):
210            hkl = UseList[G2frame.hist]['Pref.Ori.'][3]
211        if not np.any(np.array(hkl)):
212            hkl = UseList[G2frame.hist]['Pref.Ori.'][3]
213        UseList[G2frame.hist]['Pref.Ori.'][3] = hkl
214        h,k,l = hkl
215        Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
216       
217    def OnPOOrder(event):
218        Obj = event.GetEventObject()
219        Order = int(Obj.GetValue())
220        UseList[G2frame.hist]['Pref.Ori.'][4] = Order
221        UseList[G2frame.hist]['Pref.Ori.'][5] = SetPOCoef(Order,G2frame.hist)
222        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
223
224    def OnPOType(event):
225        Obj = event.GetEventObject()
226        if 'March' in Obj.GetValue():
227            UseList[G2frame.hist]['Pref.Ori.'][0] = 'MD'
228        else:
229            UseList[G2frame.hist]['Pref.Ori.'][0] = 'SH'
230        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
231
232    def OnPORef(event):
233        Obj = event.GetEventObject()
234        UseList[G2frame.hist]['Pref.Ori.'][2] = Obj.GetValue()
235
236    def OnAddFixed(event):
237        fixedVars = UseList[G2frame.hist].get('FixedSeqVars',[])
238        SeqId = G2gd.GetGPXtreeItemId(G2frame, G2frame.root, 'Sequential results')
239        seqData = G2frame.GPXtree.GetItemPyData(SeqId)
240        if G2frame.hist not in seqData:
241            print('Strange: '+G2frame.hist+' not found')
242            return
243        parmDict = seqData[G2frame.hist].get('parmDict',[])
244        # narrow down to items w/o a histogram & having float values
245        phaseKeys = [i for i in parmDict if ':' in i and i.split(':')[1] == '']
246        phaseKeys = [i for i in phaseKeys if type(parmDict[i]) not in (int,str,bool)]
247        if len(phaseKeys) == 0: return
248        selected = []
249        for i,key in enumerate(phaseKeys):
250            if key in fixedVars: selected.append(i)
251        dlg = G2G.G2MultiChoiceDialog(G2frame, 'Choose phase vars to fix for this histogram only', 
252            'Choose items to edit', phaseKeys,selected=selected)
253        if dlg.ShowModal() == wx.ID_OK:
254            sel = dlg.GetSelections()
255            dlg.Destroy()
256        else:
257            dlg.Destroy()
258            return
259        UseList[G2frame.hist]['FixedSeqVars'] = [phaseKeys[i] for i in sel]
260        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
261
262    def SetPOCoef(Order,hist):
263        cofNames = G2lat.GenSHCoeff(SGData['SGLaue'],'0',Order,False)     #cylindrical & no M
264        newPOCoef = dict(zip(cofNames,np.zeros(len(cofNames))))
265        POCoeff = UseList[G2frame.hist]['Pref.Ori.'][5]
266        for cofName in POCoeff:
267            if cofName in  cofNames:
268                newPOCoef[cofName] = POCoeff[cofName]
269        return newPOCoef
270       
271    def checkAxis(axis):
272        if not np.any(np.array(axis)):
273            return False
274        return axis
275       
276    def OnNewValue(invalid,value,tc):
277        G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
278           
279    def OnNewValueReDraw(invalid,value,tc):
280        G2plt.PlotSizeStrainPO(G2frame,data,G2frame.hist)
281        wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
282           
283    def TopSizer(name,choices,parm,OnType):
284        topSizer = wx.BoxSizer(wx.HORIZONTAL)
285        topSizer.Add(wx.StaticText(DData,wx.ID_ANY,name),0,WACV)
286        sizeType = wx.ComboBox(DData,wx.ID_ANY,value=UseList[G2frame.hist][parm][0],choices=choices,
287            style=wx.CB_READONLY|wx.CB_DROPDOWN)
288        sizeType.Bind(wx.EVT_COMBOBOX, OnType)
289        topSizer.Add(sizeType,0,WACV|wx.BOTTOM,5)
290        return topSizer
291       
292    def LGmixSizer(name,Limits,OnRef):
293        lgmixSizer = wx.BoxSizer(wx.HORIZONTAL)
294        lgmixRef = wx.CheckBox(DData,wx.ID_ANY,label='LGmix')
295        lgmixRef.thisown = False
296        lgmixRef.SetValue(UseList[G2frame.hist][name][2][2])
297        Indx[lgmixRef.GetId()] = [G2frame.hist,name]
298        lgmixRef.Bind(wx.EVT_CHECKBOX, OnRef)
299        lgmixSizer.Add(lgmixRef,0,WACV|wx.LEFT,5)
300        lgmixVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist][name][1],2,
301            nDig=(10,3),xmin=Limits[0],xmax=Limits[1])
302        lgmixSizer.Add(lgmixVal,0,WACV|wx.LEFT,5)
303        return lgmixSizer
304                   
305    def ResetSizer(name,OnReset):
306        resetSizer = wx.BoxSizer(wx.HORIZONTAL)
307        reset = wx.Button(DData,wx.ID_ANY,label='Reset?')
308        reset.thisown = False
309        Indx[reset.GetId()] = [G2frame.hist,name]
310        reset.Bind(wx.EVT_BUTTON,OnReset)
311        resetSizer.Add(reset,0,WACV)
312        return resetSizer
313       
314    def IsoSizer(name,parm,fmt,Limits,OnRef):
315        isoSizer = wx.BoxSizer(wx.HORIZONTAL)
316        sizeRef = wx.CheckBox(DData,wx.ID_ANY,label=name)
317        sizeRef.thisown = False
318        sizeRef.SetValue(UseList[G2frame.hist][parm][2][0])
319        Indx[sizeRef.GetId()] = [G2frame.hist,0]
320        sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
321        isoSizer.Add(sizeRef,0,WACV|wx.LEFT,5)
322        sizeVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist][parm][1],0,
323            nDig=fmt,xmin=Limits[0],xmax=Limits[1],OnLeave=OnNewValue)
324        isoSizer.Add(sizeVal,0,WACV)
325        return isoSizer
326       
327    def UniSizer(parm,OnAxis):
328        uniSizer = wx.BoxSizer(wx.HORIZONTAL)
329        uniSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Unique axis, H K L: '),0,WACV)
330        h,k,l = UseList[G2frame.hist][parm][3]
331        Axis = wx.TextCtrl(DData,wx.ID_ANY,'%3d %3d %3d'%(h,k,l),style=wx.TE_PROCESS_ENTER)
332        Axis.Bind(wx.EVT_TEXT_ENTER,OnAxis)
333        Axis.Bind(wx.EVT_KILL_FOCUS,OnAxis)
334        uniSizer.Add(Axis,0,WACV|wx.LEFT,5)
335        return uniSizer
336       
337    def UniDataSizer(parmName,parm,fmt,Limits,OnRef):
338        dataSizer = wx.BoxSizer(wx.HORIZONTAL)
339        parms = zip([' Equatorial '+parmName,' Axial '+parmName],
340            UseList[G2frame.hist][parm][2],range(2))
341        for Pa,ref,Id in parms:
342            sizeRef = wx.CheckBox(DData,wx.ID_ANY,label=Pa)
343            sizeRef.thisown = False
344            sizeRef.SetValue(ref)
345            Indx[sizeRef.GetId()] = [G2frame.hist,Id]
346            sizeRef.Bind(wx.EVT_CHECKBOX, OnRef)
347            dataSizer.Add(sizeRef,0,WACV|wx.LEFT,5)
348            sizeVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist][parm][1],
349                Id,fmt,xmin=Limits[0],xmax=Limits[1],OnLeave=OnNewValue)
350            dataSizer.Add(sizeVal,0,WACV)
351        return dataSizer
352
353    def EllSizeDataSizer():
354        parms = zip(['S11','S22','S33','S12','S13','S23'],UseList[G2frame.hist]['Size'][4],
355            UseList[G2frame.hist]['Size'][5],range(6))
356        dataSizer = wx.BoxSizer(wx.VERTICAL)
357        matrixSizer = wx.FlexGridSizer(0,6,5,5)
358        Sij = []
359        for Pa,val,ref,Id in parms:
360            sizeRef = wx.CheckBox(DData,wx.ID_ANY,label=Pa)
361            sizeRef.thisown = False
362            sizeRef.SetValue(ref)
363            Indx[sizeRef.GetId()] = [G2frame.hist,Id]
364            sizeRef.Bind(wx.EVT_CHECKBOX, OnSizeRef)
365            matrixSizer.Add(sizeRef,0,WACV)
366            if Id < 3:
367                sizeVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Size'][4],
368                    Id,nDig=(10,3),xmin=0.,xmax=4.,OnLeave=OnNewValueReDraw)
369            else:
370                sizeVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Size'][4],
371                    Id,nDig=(10,3),OnLeave=OnNewValueReDraw)
372            # Create Sij matrix
373            Sij += [val]
374            matrixSizer.Add(sizeVal,0,WACV)
375        dataSizer.Add(matrixSizer, 0)
376        Esize,Rsize = nl.eigh(G2lat.U6toUij(np.asarray(Sij)))
377        lengths = Esize
378        G,g = G2lat.cell2Gmat(data['General']['Cell'][1:7])       #recip & real metric tensors
379        GA,GB = G2lat.Gmat2AB(G)    #Orthogonalization matricies
380        hkls = [x/(sum(x**2)**0.5) for x in np.dot(Rsize, GA)]
381        Ids = np.argsort(lengths)
382        dataSizer.Add(wx.StaticText(DData,label=' Principal ellipsoid components:'),0)
383        compSizer = wx.FlexGridSizer(3,3,5,5)
384        Axes = [' Short Axis:',' Middle Axis:',' Long Axis:']
385        for Id in Ids:
386            compSizer.Add(wx.StaticText(DData,label=Axes[Id]),0,WACV)
387            compSizer.Add(wx.StaticText(DData,label='(%.3f, %.3f, %.3f) '%(hkls[Id][0], hkls[Id][1], hkls[Id][2])),0,WACV)
388            compSizer.Add(wx.StaticText(DData,label='Length: %.3f'%lengths[Id]),0,WACV)
389        dataSizer.Add(compSizer)
390        return dataSizer
391       
392    def GenStrainDataSizer():
393        Snames = G2spc.MustrainNames(SGData)
394        numb = len(Snames)
395        onumb = len(UseList[G2frame.hist]['Mustrain'][4])
396        while onumb < numb:
397            UseList[G2frame.hist]['Mustrain'][4].append(0.0)
398            UseList[G2frame.hist]['Mustrain'][5].append(False)
399            onumb += 1
400        muMean = G2spc.MuShklMean(SGData,Amat,UseList[G2frame.hist]['Mustrain'][4][:numb])
401        parms = zip(Snames,UseList[G2frame.hist]['Mustrain'][5],range(numb))
402        mainSizer = wx.BoxSizer(wx.VERTICAL)
403        dataSizer = wx.FlexGridSizer(0,6,5,5)
404        for Pa,ref,Id in parms:
405            strainRef = wx.CheckBox(DData,wx.ID_ANY,label=Pa)
406            strainRef.thisown = False
407            strainRef.SetValue(ref)
408            Indx[strainRef.GetId()] = [G2frame.hist,Id]
409            strainRef.Bind(wx.EVT_CHECKBOX, OnStrainRef)
410            dataSizer.Add(strainRef,0,WACV)
411            strainVal = G2G.ValidatedTxtCtrl(DData,UseList[G2frame.hist]['Mustrain'][4],
412                Id,nDig=(10,2),OnLeave=OnNewValueReDraw)
413            dataSizer.Add(strainVal,0,WACV)
414        mainSizer.Add(dataSizer)
415        mainSizer.Add(wx.StaticText(DData,label=' Mean mustrain %.1f'%muMean)
416                          ,0,wx.ALIGN_CENTER_HORIZONTAL)
417        return mainSizer
418
419    def HstrainSizer():
420       
421        def OnHstrainRef(event):
422            Obj = event.GetEventObject()
423            hist,pid = Indx[Obj.GetId()]
424            UseList[G2frame.hist]['HStrain'][1][pid] = Obj.GetValue()
425           
426        hSizer = wx.BoxSizer(wx.VERTICAL)
427        hstrainSizer = wx.FlexGridSizer(0,6,5,5)
428        Hsnames = G2spc.HStrainNames(SGData)
429        parms = zip(Hsnames,UseList[G2frame.hist]['HStrain'][1],range(len(Hsnames)))
430        allzero = True
431        for Pa,ref,Id in parms:
432            hstrainRef = wx.CheckBox(DData,wx.ID_ANY,label=Pa)
433            hstrainRef.thisown = False
434            hstrainRef.SetValue(ref)
435            Indx[hstrainRef.GetId()] = [G2frame.hist,Id]
436            hstrainRef.Bind(wx.EVT_CHECKBOX, OnHstrainRef)
437            hstrainSizer.Add(hstrainRef,0,WACV|wx.LEFT,5)
438            hstrainVal = G2G.ValidatedTxtCtrl(DData,
439                UseList[G2frame.hist]['HStrain'][0],Id,nDig=(10,3,'g'),OnLeave=OnNewValueReDraw)
440            if abs(UseList[G2frame.hist]['HStrain'][0][Id]) > 1e-8:
441                allzero = False
442            hstrainSizer.Add(hstrainVal,0,WACV)
443        hSizer.Add(hstrainSizer,0)
444        if not allzero:   # show Dij shifted unit cell
445            DijVals = UseList[G2frame.hist]['HStrain'][0][:]
446            A = G2lat.cell2A(data['General']['Cell'][1:7])
447            # apply the Dij values to the reciprocal cell
448            newA =  G2lat.AplusDij(A,DijVals,SGData)
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,6),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            if not UseList[G2frame.hist]['LeBail']:
845                Controls['newLeBail'] = True
846            else:
847                Controls['newLeBail'] = False
848            UseList[G2frame.hist]['LeBail'] = not UseList[G2frame.hist]['LeBail']
849            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
850           
851        def OnResetSize(event):
852            Obj = event.GetEventObject()
853            item,name = Indx[Obj.GetId()]
854            if name == 'isotropic':
855                UseList[item]['Size'][1][0] = 1.0
856            elif name == 'uniaxial':
857                UseList[item]['Size'][1][0] = 1.0
858                UseList[item]['Size'][1][1] = 1.0
859            elif name == 'ellipsoidal':
860                for i in range(3):
861                    UseList[item]['Size'][4][i] = 1.0
862                    UseList[item]['Size'][4][i+3] = 0.0
863            G2plt.PlotSizeStrainPO(G2frame,data,item)
864            wx.CallLater(100,RepaintHistogramInfo,DData.GetScrollPos(wx.VERTICAL))
865           
866        def OnSizeAxis(event):           
867            event.Skip()
868            Obj = event.GetEventObject()
869            Saxis = Obj.GetValue().split()
870            try:
871                hkl = [int(Saxis[i]) for i in range(3)]
872            except (ValueError,IndexError):
873                hkl = UseList[G2frame.hist]['Size'][3]
874            if not np.any(np.array(hkl)):
875                hkl = UseList[G2frame.hist]['Size'][3]
876            UseList[G2frame.hist]['Size'][3] = hkl
877            h,k,l = hkl
878            Obj.SetValue('%3d %3d %3d'%(h,k,l)) 
879           
880        def OnFixVals(event):
881            Obj = event.GetEventObject()
882            UseList[G2frame.hist]['Fix FXU'] = Obj.GetValue()
883
884        if G2frame.hist not in UseList:               
885            G2frame.ErrorDialog('Missing data error',
886                    G2frame.hist+' not in GSAS-II data tree')
887            return
888#patch
889        if 'Use' not in UseList[G2frame.hist]:
890            UseList[G2frame.hist]['Use'] = True
891        if 'LeBail' not in UseList[G2frame.hist]:
892            UseList[G2frame.hist]['LeBail'] = False
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        ifkeV = 'E' in UseList[G2frame.hist].get('Type','')           
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 ifkeV:
924            G2G.HorizontalLine(bottomSizer,DData)
925            bottomSizer.Add(wx.StaticText(DData,label=' NB: No structure or sample broadening refinement possible from energy dispersive data'))
926        G2G.HorizontalLine(bottomSizer,DData)
927        if G2frame.testSeqRefineMode() and not UseList[G2frame.hist]['LeBail']:
928            bottomSizer.Add(wx.StaticText(DData,label='     Sequential Refinement Options'))
929            parmChoice = [' ','X','XU','U','F','FX','FXU','FU']
930            if generalData['Type'] == 'magnetic':
931                parmChoice += ['M','MX','MXU','MU','MF','MFX','MFXU','MFU']
932            fixBox = wx.BoxSizer(wx.HORIZONTAL)
933            fixBox.Add(wx.StaticText(DData,label='     Fix these var types: '),0,WACV)
934            fixVals = wx.ComboBox(DData,value=UseList[G2frame.hist]['Fix FXU'],choices=parmChoice,
935                style=wx.CB_DROPDOWN)
936            fixVals.Bind(wx.EVT_COMBOBOX,OnFixVals)
937            fixBox.Add(fixVals,0,WACV)
938            fixBox.Add(wx.StaticText(DData,label=' in phase '+generalData['Name']+' for this histogram'),0,WACV)
939            bottomSizer.Add(fixBox)
940            SeqId = G2gd.GetGPXtreeItemId(G2frame, G2frame.root, 'Sequential results')
941            if SeqId:
942                fixBox = wx.BoxSizer(wx.HORIZONTAL)
943                fixBox.Add(wx.StaticText(DData,label='     Specific phase variables to fix for this histogram: '),0,WACV)
944                addFixed = wx.Button(DData,wx.ID_ANY,label='Select Vars')
945                fixBox.Add(addFixed,0,WACV)
946                addFixed.Bind(wx.EVT_BUTTON,OnAddFixed)
947                fixedVars = UseList[G2frame.hist].get('FixedSeqVars',[])
948                if len(fixedVars): 
949                    fixBox.Add(wx.StaticText(DData,label=' (currently {} fixed)'.format(len(fixedVars))),0,WACV)
950                bottomSizer.Add(fixBox)
951       
952        if not UseList[G2frame.hist]['LeBail'] or 'HKLF' in G2frame.hist[:4]:
953            bottomSizer.Add(ScaleSizer(),0,wx.BOTTOM,5)
954           
955        if G2frame.hist[:4] == 'PWDR':
956            if not ifkeV:
957                if UseList[G2frame.hist]['Size'][0] == 'isotropic':
958                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
959                    isoSizer.Add(TopSizer(' Domain size model: ',['isotropic','uniaxial','ellipsoidal'],
960                        'Size',OnSizeType),0,WACV)
961                    isoSizer.Add(LGmixSizer('Size',[0.,1.],OnLGmixRef))
962                    isoSizer.Add(ResetSizer('isotropic',OnResetSize),0,WACV)
963                    bottomSizer.Add(isoSizer)
964                    bottomSizer.Add(IsoSizer(u'size(\xb5m): ','Size',(10,4),[0.,10.],OnSizeRef),0,wx.BOTTOM,5)
965                elif UseList[G2frame.hist]['Size'][0] == 'uniaxial':
966                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
967                    uniSizer.Add(TopSizer(' Domain size model: ',['isotropic','uniaxial','ellipsoidal'],
968                        'Size',OnSizeType),0,WACV)
969                    uniSizer.Add(LGmixSizer('Size',[0.,1.],OnLGmixRef))
970                    uniSizer.Add(ResetSizer('uniaxial',OnResetSize),0,WACV)
971                    bottomSizer.Add(UniSizer('Size',OnSizeAxis),0)
972                    bottomSizer.Add(uniSizer)
973                    bottomSizer.Add(UniDataSizer(u'size(\xb5m): ','Size',(10,3),[0.,10.],OnSizeRef),0,wx.BOTTOM,5)
974                elif UseList[G2frame.hist]['Size'][0] == 'ellipsoidal':
975                    ellSizer = wx.BoxSizer(wx.HORIZONTAL)
976                    ellSizer.Add(TopSizer(' Domain size model: ',['isotropic','uniaxial','ellipsoidal'],
977                        'Size',OnSizeType),0,WACV)
978                    ellSizer.Add(LGmixSizer('Size',[0.,1.],OnLGmixRef))
979                    ellSizer.Add(ResetSizer('ellipsoidal',OnResetSize),0,WACV)
980                    bottomSizer.Add(ellSizer)
981                    bottomSizer.Add(EllSizeDataSizer(),0,wx.BOTTOM,5)
982               
983                if UseList[G2frame.hist]['Mustrain'][0] == 'isotropic':
984                    isoSizer = wx.BoxSizer(wx.HORIZONTAL)
985                    isoSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
986                        'Mustrain',OnStrainType),0,WACV)
987                    isoSizer.Add(LGmixSizer('Mustrain',[0.,1.],OnLGmixRef))
988                    isoSizer.Add(ResetSizer('isotropic',OnResetStrain),0,WACV)
989                    bottomSizer.Add(isoSizer)
990                    bottomSizer.Add(IsoSizer(' microstrain: ','Mustrain',(10,1),[0.,1.e5],OnStrainRef),0,wx.BOTTOM,5)
991                elif UseList[G2frame.hist]['Mustrain'][0] == 'uniaxial':
992                    uniSizer = wx.BoxSizer(wx.HORIZONTAL)
993                    uniSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
994                        'Mustrain',OnStrainType),0,WACV)
995                    uniSizer.Add(LGmixSizer('Mustrain',[0.,1.],OnLGmixRef))
996                    uniSizer.Add(ResetSizer('uniaxial',OnResetStrain),0,WACV)
997                    bottomSizer.Add(uniSizer)
998                    bottomSizer.Add(UniSizer('Mustrain',OnStrainAxis),0)
999                    bottomSizer.Add(UniDataSizer('mustrain: ','Mustrain',(10,1),[0.,1.e5],OnStrainRef),0,wx.BOTTOM,5)
1000                elif UseList[G2frame.hist]['Mustrain'][0] == 'generalized':
1001                    genSizer = wx.BoxSizer(wx.HORIZONTAL)
1002                    genSizer.Add(TopSizer(' Mustrain model: ',['isotropic','uniaxial','generalized',],
1003                        'Mustrain',OnStrainType),0,WACV)
1004                    genSizer.Add(LGmixSizer('Mustrain',[0.,1.],OnLGmixRef))
1005                    genSizer.Add(ResetSizer('generalized',OnResetStrain),0,WACV)
1006                    bottomSizer.Add(genSizer)
1007                    bottomSizer.Add(GenStrainDataSizer(),0,wx.BOTTOM,5)
1008               
1009            bottomSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Hydrostatic/elastic strain:'))
1010            bottomSizer.Add(HstrainSizer())
1011            bottomSizer.Add(DispSizer())
1012               
1013            if not UseList[G2frame.hist]['LeBail'] and not ifkeV:
1014                poSizer = wx.BoxSizer(wx.VERTICAL)
1015                POData = UseList[G2frame.hist]['Pref.Ori.']
1016# patch - add penalty items
1017                if len(POData) < 7:
1018                    POData.append(['',])
1019                    POData.append(0.1)
1020                if not POData[6]:
1021                    POData[6] = ['',]
1022# end patch
1023                poSizer.Add(PoTopSizer(POData))
1024                if POData[0] == 'MD':
1025                    poSizer.Add(MDDataSizer(POData))
1026                else:           #'SH'
1027                    if POData[4]:       #SH order > 0
1028                        textJ = G2lat.textureIndex(POData[5])
1029                        poSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Spherical harmonic coefficients: '+'Texture index: %.3f'%(textJ))
1030                            ,0,wx.TOP|wx.BOTTOM,5)
1031                        poSizer.Add(SHDataSizer(POData))  #,0,wx.TOP|wx.BOTTOM,5)
1032                        poSizer.Add(SHPenalty(POData))  #,0,wx.TOP|wx.BOTTOM,5)
1033                       
1034                bottomSizer.Add(poSizer)    #,0,wx.TOP|wx.BOTTOM,5)
1035                bottomSizer.Add(ExtSizer('PWDR'),0,wx.TOP|wx.BOTTOM,5)
1036                if generalData['Type'] != 'magnetic': 
1037                    bottomSizer.Add(BabSizer(),0,wx.BOTTOM,5)
1038        elif G2frame.hist[:4] == 'HKLF':
1039            bottomSizer.Add(ExtSizer('HKLF'))  #,0,wx.BOTTOM,5)
1040            bottomSizer.Add(BabSizer())  #,0,wx.BOTTOM,5)
1041            if not SGData['SGInv'] and len(UseList[G2frame.hist]['Twins']) < 2:
1042                bottomSizer.Add(FlackSizer())  #,0,wx.BOTTOM,5)
1043            bottomSizer.Add(twinSizer())  #,0,wx.BOTTOM,5)
1044        return bottomSizer,offMsg
1045
1046    ######################################################################
1047    #### Beginning of UpdateDData execution here
1048    ######################################################################
1049    Controls = G2frame.GPXtree.GetItemPyData(G2gd.GetGPXtreeItemId(G2frame,G2frame.GPXtree.root, 'Controls'))
1050    G2frame.SetStatusText('',1)
1051    keyList = G2frame.GetHistogramNames(['PWDR','HKLF'])
1052    UseList = data['Histograms']
1053    # look for histgrams that are no longer in the project (can happen when histogram deleted from tree)
1054    broken = [i for i in UseList if i not in keyList]
1055    if broken:
1056        msg = 'Removing histogram(s) referenced in this phase that are no longer in project:\n\n'
1057        for i,j in enumerate(broken): 
1058            if i > 0: msg += ', '
1059            msg += j
1060            del data['Histograms'][j]
1061        G2G.G2MessageBox(G2frame,msg,'Dereferencing Removed histograms')
1062    if UseList:
1063        G2frame.dataWindow.DataMenu.Enable(G2G.wxID_DATADELETE,True)
1064        for item in G2frame.Refine: item.Enable(True)
1065    else:
1066        G2frame.dataWindow.DataMenu.Enable(G2G.wxID_DATADELETE,False)
1067        for item in G2frame.Refine: item.Enable(False)
1068    # make a list of histograms (any type) used in this phase, ordered as in tree
1069    G2frame.dataWindow.HistsInPhase = [name for name in keyList if name in UseList]
1070    generalData = data['General']
1071    cell = generalData['Cell'][1:]
1072    Amat,Bmat = G2lat.cell2AB(cell[:6])
1073    PhaseName = generalData['Name']       
1074    SGData = generalData['SGData']
1075    if len(G2frame.dataWindow.HistsInPhase) == 0: # no associated histograms, nothing to display here
1076        G2frame.hist = ''
1077    elif hist and hist in G2frame.dataWindow.HistsInPhase: # something was input as a selection as an argument
1078        G2frame.hist = hist
1079    elif (not G2frame.hist) or (G2frame.hist not in G2frame.dataWindow.HistsInPhase): # no or bad selection but have data, take the first
1080        G2frame.hist = G2frame.dataWindow.HistsInPhase[0]
1081    Indx = {}
1082   
1083    if DData.GetSizer():
1084        try:
1085            if hasattr(DData,'select'): 
1086                DData.select.Unbind(wx.EVT_LISTBOX)  # remove binding to avoid event on Linux
1087        except:
1088            pass
1089        DData.GetSizer().Clear(True)
1090    mainSizer = wx.BoxSizer(wx.VERTICAL)
1091    topSizer = wx.BoxSizer(wx.HORIZONTAL)
1092    topSizer.Add(wx.StaticText(DData,wx.ID_ANY,' Histogram data for Phase '+PhaseName+':'),0,wx.LEFT,5)
1093    # add help button to bring up help web page - at right sede of window
1094    topSizer.Add((-1,-1),1,wx.EXPAND)
1095    topSizer.Add(G2G.HelpButton(DData,helpIndex=G2frame.dataWindow.helpKey))
1096    mainSizer.Add(topSizer,0,wx.EXPAND)
1097    LeBailMsg = None
1098    if G2frame.hist:
1099        ifkeV = 'E' in UseList[G2frame.hist].get('Type','')           
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]) and not ifkeV:
1108            topSizer.Add(PlotSizer())
1109        mainSizer.Add(topSizer)       
1110        G2frame.bottomSizer,LeBailMsg = 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    if LeBailMsg:
1123        G2G.G2MessageBox(G2frame,LeBailMsg,title='LeBail refinement changes')
1124
1125def MakeHistPhaseWin(G2frame):
1126    '''Display Phase/Data info from Hist/Phase tree item (not used with Phase/Data tab)
1127    '''
1128    TabSelectionIdDict = {}
1129    def OnSelectPage(event):
1130        'Called when an item is selected from the Select page menu'
1131        tabname = TabSelectionIdDict.get(event.GetId()) # lookup phase
1132        if not tabname:
1133            print ('Warning: menu item not in dict! id= %d'%event.GetId())
1134            return
1135        # find the tab matching the phase
1136        for i,page in enumerate(phaseList):
1137            if tabname == phaseList[i]:
1138                HAPBook.SetSelection(i)
1139                wx.CallAfter(FillDDataWindow,i) # may result in a double paint on some OSs
1140                return
1141        else:
1142            print ("Warning: tab "+tabname+" was not found")
1143           
1144    def OnPageChanged(event):
1145        'respond to a notebook tab'
1146        page = event.GetSelection()
1147        wx.CallAfter(FillDDataWindow,page)
1148
1149    def getDDataWindow():
1150        'Get the current scrollwindow for selected phase'
1151        return DData[HAPBook.GetSelection()]
1152   
1153    def getDDataPhaseinfo():
1154        'Get the data tree entry for the currently selected phase'
1155        page = HAPBook.GetSelection()
1156        return G2frame.GPXtree.GetItemPyData(phaseIds[page])
1157       
1158    def FillDDataWindow(page):
1159        'display the DData info'
1160        G2frame.HistPhaseLastSel = phaseList[page]
1161        data = G2frame.GPXtree.GetItemPyData(phaseIds[page])
1162        G2plt.PlotSizeStrainPO(G2frame,data,hist='',Start=True)           
1163        UpdateDData(G2frame,DData[page],data)
1164       
1165    #### G2frame.dataWindow.DataMenu/"Edit Phase" menu routines (note similar routines in GSASIIphsGUI.py)
1166    def OnHklfAdd(event):
1167        data = getDDataPhaseinfo()
1168        keyList = data['Histograms'].keys()
1169        TextList = []
1170        if not G2frame.GPXtree.GetCount():
1171            return
1172       
1173        item, cookie = G2frame.GPXtree.GetFirstChild(G2frame.root)
1174        while item:
1175            name = G2frame.GPXtree.GetItemText(item)
1176            if name not in keyList and 'HKLF' in name:
1177                TextList.append(name)
1178            item, cookie = G2frame.GPXtree.GetNextChild(G2frame.root, cookie)                       
1179            if not TextList: 
1180                G2G.G2MessageBox(G2frame,'No reflections')
1181                return
1182        dlg = G2G.G2MultiChoiceDialog(G2frame, 'Select reflection sets to use',
1183            'Use data',TextList)
1184        try:
1185            if dlg.ShowModal() == wx.ID_OK:
1186                result = dlg.GetSelections()
1187            else:
1188                return
1189        finally:
1190            dlg.Destroy()
1191
1192        # get the histograms used in other phases
1193        phaseRIdList,usedHistograms = G2frame.GetPhaseInfofromTree()
1194        usedHKLFhists = [] # used single-crystal histograms
1195        for p in usedHistograms:
1196            for h in usedHistograms[p]:
1197                if h.startswith('HKLF ') and h not in usedHKLFhists:
1198                    usedHKLFhists.append(h)
1199        # check that selected single crystal histograms are not already in use!
1200        for i in result:
1201            used = [TextList[i] for i in result if TextList[i] in usedHKLFhists]
1202            if used:
1203                msg = 'The following single crystal histogram(s) are already in use'
1204                for i in used:
1205                    msg += '\n  '+str(i)
1206                msg += '\nAre you sure you want to add them to this phase? '
1207                msg += 'Associating a single crystal dataset to >1 histogram is usually an error, '
1208                msg += 'so No is suggested here.'
1209                if G2frame.ErrorDialog('Likely error',msg,G2frame,wtype=wx.YES_NO) != wx.ID_YES: return
1210
1211        wx.BeginBusyCursor()
1212        for i in result:
1213            histoName = TextList[i]
1214            Id = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,histoName)
1215            refDict,reflData = G2frame.GPXtree.GetItemPyData(Id)
1216            data['Histograms'][histoName] = {'Histogram':histoName,'Show':False,'Scale':[1.0,True],
1217                'Babinet':{'BabA':[0.0,False],'BabU':[0.0,False]},
1218                'Extinction':['Lorentzian','None',
1219                {'Tbar':0.1,'Cos2TM':0.955,'Eg':[1.e-7,False],'Es':[1.e-7,False],'Ep':[1.e-7,False]},],
1220                'Flack':[0.0,False],'Twins':[[np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False,0]],]}                       
1221            if 'TwMax' in reflData:     #nonmerohedral twins present
1222                data['Histograms'][histoName]['Twins'] = []
1223                for iT in range(reflData['TwMax'][0]+1):
1224                    if iT in reflData['TwMax'][1]:
1225                        data['Histograms'][histoName]['Twins'].append([False,0.0])
1226                    else:
1227                        data['Histograms'][histoName]['Twins'].append([np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False,reflData['TwMax'][0]]])
1228            else:   #no nonmerohedral twins
1229                data['Histograms'][histoName]['Twins'] = [[np.array([[1,0,0],[0,1,0],[0,0,1]]),[1.0,False,0]],]
1230            UpdateHKLFdata(histoName)
1231        wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1232        wx.EndBusyCursor()
1233       
1234    def OnDataUse(event):
1235        data = getDDataPhaseinfo()
1236#        hist = G2frame.hist
1237        if data['Histograms']:
1238            dlg = G2G.G2MultiChoiceDialog(G2frame, 'Use histograms', 
1239                'Use which histograms?',G2frame.dataWindow.HistsInPhase)
1240            try:
1241                if dlg.ShowModal() == wx.ID_OK:
1242                    sel = dlg.GetSelections()
1243                    for Id,item in enumerate(G2frame.dataWindow.HistsInPhase):
1244                        if Id in sel:
1245                            data['Histograms'][item]['Use'] = True
1246                        else:
1247                            data['Histograms'][item]['Use'] = False                       
1248            finally:
1249                dlg.Destroy()
1250        wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1251
1252    def UpdateHKLFdata(histoName):
1253        data = getDDataPhaseinfo()
1254        generalData = data['General']
1255        Id = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,histoName)
1256        refDict,reflData = G2frame.GPXtree.GetItemPyData(Id)
1257        SGData = generalData['SGData']
1258        Cell = generalData['Cell'][1:7]
1259        G,g = G2lat.cell2Gmat(Cell)
1260        for iref,ref in enumerate(reflData['RefList']):
1261            H = list(ref[:3])
1262            ref[4] = np.sqrt(1./G2lat.calc_rDsq2(H,G))
1263            iabsnt,ref[3],Uniq,phi = G2spc.GenHKLf(H,SGData)
1264       
1265    def OnDataCopy(event):
1266        data = getDDataPhaseinfo()
1267        hist = G2frame.hist
1268        keyList = G2frame.dataWindow.HistsInPhase[:]
1269        if hist in keyList: keyList.remove(hist)
1270        if not keyList:
1271            G2G.G2MessageBox(G2frame,'No histograms to copy to')
1272            return
1273        sourceDict = copy.deepcopy(data['Histograms'][hist])
1274        if 'HKLF' in sourceDict['Histogram']:
1275            copyNames = ['Extinction','Babinet','Flack','Twins']
1276        else:  #PWDR 
1277            copyNames = ['Pref.Ori.','Size','Mustrain','HStrain','Extinction','Babinet','LeBail','Layer Disp']
1278        copyNames += ['Scale','Fix FXU','FixedSeqVars']
1279        copyDict = {}
1280        for name in copyNames:
1281            if name not in sourceDict: continue
1282            copyDict[name] = copy.deepcopy(sourceDict[name])        #force copy
1283        dlg = G2G.G2MultiChoiceDialog(G2frame,u'Copy phase/histogram parameters\nfrom '+hist[5:][:35],
1284                'Copy phase/hist parameters', keyList)
1285        try:
1286            if dlg.ShowModal() == wx.ID_OK:
1287                for sel in dlg.GetSelections():
1288                    data['Histograms'][keyList[sel]].update(copy.deepcopy(copyDict))
1289        finally:
1290            dlg.Destroy()
1291       
1292    def OnDataCopyFlags(event):
1293        data = getDDataPhaseinfo()
1294        hist = G2frame.hist
1295        sourceDict = copy.deepcopy(data['Histograms'][hist])
1296        copyDict = {}
1297        if 'HKLF' in sourceDict['Histogram']:
1298            copyNames = ['Extinction','Babinet','Flack','Twins']
1299        else:  #PWDR 
1300            copyNames = ['Pref.Ori.','Size','Mustrain','HStrain','Extinction','Babinet','Layer Disp']
1301        copyNames += ['Scale','Fix FXU','FixedSeqVars']
1302        babNames = ['BabA','BabU']
1303        for name in copyNames:
1304            if name not in sourceDict: continue
1305            if name in ['Scale','Extinction','HStrain','Flack','Twins','Layer Disp']:
1306                if name == 'Extinction' and 'HKLF' in sourceDict['Histogram']:
1307                    copyDict[name] = {name:[sourceDict[name][:2]]}
1308                    for item in ['Eg','Es','Ep']:
1309                        copyDict[name][item] = sourceDict[name][2][item][1]
1310                elif name == 'Twins':
1311                    copyDict[name] = sourceDict[name][0][1][1]
1312                else:
1313                    copyDict[name] = sourceDict[name][1]
1314            elif name in ['Size','Mustrain']:
1315                copyDict[name] = [sourceDict[name][0],sourceDict[name][2],sourceDict[name][5]]
1316            elif name == 'Pref.Ori.':
1317                copyDict[name] = [sourceDict[name][0],sourceDict[name][2]]
1318                if sourceDict[name][0] == 'SH':
1319                    SHterms = sourceDict[name][5]
1320                    SHflags = {}
1321                    for item in SHterms:
1322                        SHflags[item] = SHterms[item]
1323                    copyDict[name].append(SHflags)
1324            elif name == 'Babinet':
1325                copyDict[name] = {}
1326                for bab in babNames:
1327                    copyDict[name][bab] = sourceDict[name][bab][1]
1328            elif name in ['Fix FXU','FixedSeqVars']:
1329                copyDict[name] = copy.deepcopy(sourceDict[name])                   
1330        keyList = G2frame.dataWindow.HistsInPhase[:]
1331        if hist in keyList: keyList.remove(hist)
1332        if not keyList:
1333            G2G.G2MessageBox(G2frame,'No histograms to copy to')
1334            return
1335        dlg = G2G.G2MultiChoiceDialog(G2frame,u'Copy phase/histogram flags\nfrom '+hist[5:][:35],
1336                'Copy phase/hist flags', keyList)
1337        try:
1338            if dlg.ShowModal() == wx.ID_OK:
1339                for sel in dlg.GetSelections():
1340                    item = keyList[sel]
1341                    for name in copyNames:
1342                        if name not in sourceDict: continue
1343                        if name in ['Scale','Extinction','HStrain','Flack','Twins','Layer Disp']:
1344                            if name == 'Extinction' and 'HKLF' in sourceDict['Histogram']:
1345                                data['Histograms'][item][name][:2] = copy.deepcopy(sourceDict[name][:2])
1346                                for itm in ['Eg','Es','Ep']:
1347                                    data['Histograms'][item][name][2][itm][1] = copy.deepcopy(copyDict[name][itm])
1348                            elif name == 'Twins':
1349                                data['Histograms'][item]['Twins'][0][1][1] = copy.deepcopy(copyDict['Twins'])
1350                            else:
1351                                try:
1352                                    data['Histograms'][item][name][1] = copy.deepcopy(copyDict[name])
1353                                except KeyError:
1354                                    continue
1355                        elif name in ['Size','Mustrain']:
1356                            data['Histograms'][item][name][0] = copy.deepcopy(copyDict[name][0])
1357                            data['Histograms'][item][name][2] = copy.deepcopy(copyDict[name][1])
1358                            data['Histograms'][item][name][5] = copy.deepcopy(copyDict[name][2])
1359                        elif name == 'Pref.Ori.':
1360                            data['Histograms'][item][name][0] = copy.deepcopy(copyDict[name][0])
1361                            data['Histograms'][item][name][2] = copy.deepcopy(copyDict[name][1])
1362                            if sourceDict[name][0] == 'SH':
1363                               SHflags = copy.deepcopy(copyDict[name][2])
1364                               SHterms = copy.deepcopy(sourceDict[name][5])
1365                               data['Histograms'][item][name][6] = copy.deepcopy(sourceDict[name][6])
1366                               data['Histograms'][item][name][7] = copy.deepcopy(sourceDict[name][7])
1367                        elif name == 'Babinet':
1368                            for bab in babNames:
1369                                data['Histograms'][item][name][bab][1] = copy.deepcopy(copyDict[name][bab])
1370                        elif name in ['Fix FXU','FixedSeqVars']:
1371                            data['Histograms'][item][name] = copy.deepcopy(sourceDict[name])                     
1372        finally:
1373            dlg.Destroy()
1374       
1375    def OnSelDataCopy(event):
1376        data = getDDataPhaseinfo()
1377        hist = G2frame.hist
1378        sourceDict = data['Histograms'][hist]
1379        keyList = G2frame.dataWindow.HistsInPhase[:]
1380        if hist in keyList: keyList.remove(hist)
1381        if not keyList:
1382            G2G.G2MessageBox(G2frame,'No histograms to copy to')
1383            return
1384        if 'HKLF' in sourceDict['Histogram']:
1385            copyNames = ['Extinction','Babinet','Flack','Twins']
1386        else:  #PWDR 
1387            copyNames = ['Pref.Ori.','Size','Mustrain','HStrain','Extinction','Babinet','LeBail','Layer Disp']
1388        copyNames += ['Scale','Fix FXU','FixedSeqVars']           
1389        dlg = G2G.G2MultiChoiceDialog(G2frame,'Select which parameters to copy',
1390            'Select phase data parameters', copyNames)
1391        selectedItems = []
1392        try:
1393            if dlg.ShowModal() == wx.ID_OK:
1394                selectedItems = [copyNames[i] for i in dlg.GetSelections()]
1395        finally:
1396            dlg.Destroy()
1397        if not selectedItems: return # nothing to copy
1398        copyDict = {}
1399        for parm in selectedItems:
1400            if parm not in sourceDict: continue
1401            copyDict[parm] = copy.deepcopy(sourceDict[parm])
1402        dlg = G2G.G2MultiChoiceDialog(G2frame,u'Copy selected phase/histogram parameters\nfrom '+hist[5:][:35],
1403            'Copy selected phase/hist parameters', keyList)
1404        try:
1405            if dlg.ShowModal() == wx.ID_OK:
1406                for sel in dlg.GetSelections():
1407                    data['Histograms'][keyList[sel]].update(copy.deepcopy(copyDict))
1408        finally:
1409            dlg.Destroy()           
1410       
1411    def OnPwdrAdd(event):
1412        data = getDDataPhaseinfo()
1413        generalData = data['General']
1414        SGData = generalData['SGData']
1415        newList = []
1416        NShkl = len(G2spc.MustrainNames(SGData))
1417        NDij = len(G2spc.HStrainNames(SGData))
1418        keyList = data['Histograms'].keys()
1419        TextList = []
1420        if G2frame.GPXtree.GetCount():
1421            item, cookie = G2frame.GPXtree.GetFirstChild(G2frame.root)
1422            while item:
1423                name = G2frame.GPXtree.GetItemText(item)
1424                if name not in keyList and 'PWDR' in name:
1425                    TextList.append(name)
1426                item, cookie = G2frame.GPXtree.GetNextChild(G2frame.root, cookie)
1427            if not TextList: 
1428                G2G.G2MessageBox(G2frame,'No histograms')
1429                return
1430            dlg = G2G.G2MultiChoiceDialog(G2frame, 'Select powder histograms to use',
1431                'Use data',TextList)
1432            try:
1433                if dlg.ShowModal() == wx.ID_OK:
1434                    result = dlg.GetSelections()
1435                    for i in result: newList.append(TextList[i])
1436                    if 'All PWDR' in newList:
1437                        newList = TextList[1:]
1438                    for histoName in newList:
1439                        Id = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,histoName)
1440                        data['Histograms'][histoName] = {'Histogram':histoName,'Show':False,'LeBail':False,
1441                            'Scale':[1.0,False],'Pref.Ori.':['MD',1.0,False,[0,0,1],0,{},['',],0.1],
1442                            'Size':['isotropic',[1.,1.,1.],[False,False,False],[0,0,1],
1443                                [1.,1.,1.,0.,0.,0.],6*[False,]],
1444                            'Mustrain':['isotropic',[1000.0,1000.0,1.0],[False,False,False],[0,0,1],
1445                                NShkl*[0.01,],NShkl*[False,]],
1446                            'HStrain':[NDij*[0.0,],NDij*[False,]],
1447                            'Layer Disp':[0.0,False],                         
1448                            'Extinction':[0.0,False],'Babinet':{'BabA':[0.0,False],'BabU':[0.0,False]},'Fix FXU':' ','FixedSeqVars':[]}
1449                        refList = G2frame.GPXtree.GetItemPyData(G2gd.GetGPXtreeItemId(G2frame,Id,'Reflection Lists'))
1450                        refList[generalData['Name']] = {}                       
1451                    wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1452            finally:
1453                dlg.Destroy()
1454               
1455    def OnDataDelete(event):
1456        data = getDDataPhaseinfo()
1457        if G2frame.dataWindow.HistsInPhase:
1458            DelList = []
1459            extraOpts= {'label_0':'Remove from all phases','value_0':False}
1460            h,pd = G2frame.GetUsedHistogramsAndPhasesfromTree()
1461            if len(pd) > 1:
1462                opts = extraOpts
1463            else:
1464                opts = {}
1465            dlg = G2G.G2MultiChoiceDialog(G2frame, 
1466                'Select histogram(s) to remove   \nfrom this phase:',
1467                'Remove histograms', G2frame.dataWindow.HistsInPhase,
1468                extraOpts=opts)
1469            try:
1470                if dlg.ShowModal() == wx.ID_OK:
1471                    DelList = [G2frame.dataWindow.HistsInPhase[i] for i in dlg.GetSelections()]
1472            finally:
1473                dlg.Destroy()
1474            if extraOpts['value_0']:
1475                for p in pd: 
1476                    for i in DelList:
1477                        if i in pd[p]['Histograms']: del pd[p]['Histograms'][i]
1478            else:
1479                for i in DelList:
1480                    del data['Histograms'][i]
1481            wx.CallLater(100,UpdateDData,G2frame,getDDataWindow(),data)
1482           
1483    def OnDataApplyStrain(event):
1484        data = getDDataPhaseinfo()
1485        SGData = data['General']['SGData']       
1486        DijVals = data['Histograms'][G2frame.hist]['HStrain'][0][:]
1487        # apply the Dij values to the reciprocal cell
1488        newA = []
1489        Dijdict = dict(zip(G2spc.HStrainNames(SGData),DijVals))
1490        for Aij,lbl in zip(G2lat.cell2A(data['General']['Cell'][1:7]),
1491                            ['D11','D22','D33','D12','D13','D23']):
1492            newA.append(Aij + Dijdict.get(lbl,0.0))
1493        # convert back to direct cell
1494        data['General']['Cell'][1:7] = G2lat.A2cell(newA)
1495        data['General']['Cell'][7] = G2lat.calc_V(newA)
1496        # subtract the selected histograms Dij values from all for this phase
1497        for hist in data['Histograms']:
1498            for i,val in enumerate(DijVals):
1499                data['Histograms'][hist]['HStrain'][0][i] -= val
1500        # for hist in sorted(data['Histograms']): # list effective lattice constants applying Dij values
1501        #     DijVals = data['Histograms'][hist]['HStrain'][0]
1502        #     newA = []
1503        #     Dijdict = dict(zip(G2spc.HStrainNames(SGData),DijVals))
1504        #     for Aij,lbl in zip(G2lat.cell2A(data['General']['Cell'][1:7]),
1505        #                     ['D11','D22','D33','D12','D13','D23']):
1506        #         newA.append(Aij + Dijdict.get(lbl,0.0))
1507        #     print(hist, G2lat.A2cell(newA)[:3], G2lat.calc_V(newA))
1508        wx.CallAfter(UpdateDData,G2frame,getDDataWindow(),data)
1509       
1510    #### start of MakeHistPhaseWin
1511    G2frame.dataWindow.ClearData()
1512    HAPBook = G2G.GSNoteBook(parent=G2frame.dataWindow)
1513    G2frame.dataWindow.GetSizer().Add(HAPBook,1,wx.ALL|wx.EXPAND,1)
1514    phaseList = []
1515    phaseIds = []
1516    DData = []
1517    sub = G2gd.GetGPXtreeItemId(G2frame,G2frame.root,'Phases')
1518    item, cookie = G2frame.GPXtree.GetFirstChild(sub)
1519    while item: # loop over phases
1520        phaseName = G2frame.GPXtree.GetItemText(item)
1521        phaseIds.append(item)
1522        phaseList.append(phaseName)
1523        item, cookie = G2frame.GPXtree.GetNextChild(sub, cookie)
1524        HAPtab = wx.ScrolledWindow(HAPBook)
1525        HAPBook.AddPage(HAPtab,phaseName)
1526        DData.append(HAPtab)
1527    HAPBook.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, OnPageChanged)
1528    # set up "Select tab" menu contents
1529    G2gd.SetDataMenuBar(G2frame,G2frame.dataWindow.DataMenu)
1530    mid = G2frame.dataWindow.DataMenu.FindMenu('Select tab')
1531    menu = G2frame.dataWindow.DataMenu.GetMenu(mid)
1532    items = menu.GetMenuItems()
1533    for item in items:
1534         menu.Remove(item)
1535    if len(phaseList) == 0: return
1536    for i,page in enumerate(phaseList):
1537        Id = wx.NewId()
1538        if menu.FindItem(page) >= 0: continue # is tab already in menu?
1539        menu.Append(Id,page,'')
1540        TabSelectionIdDict[Id] = page
1541        G2frame.Bind(wx.EVT_MENU, OnSelectPage, id=Id)
1542    # define commands in G2frame.dataWindow.DataMenu/"Edit Phase" menu
1543    G2frame.Bind(wx.EVT_MENU, OnDataUse, id=G2G.wxID_DATAUSE)
1544    G2frame.Bind(wx.EVT_MENU, OnDataCopy, id=G2G.wxID_DATACOPY)
1545    G2frame.Bind(wx.EVT_MENU, OnDataCopyFlags, id=G2G.wxID_DATACOPYFLAGS)
1546    G2frame.Bind(wx.EVT_MENU, OnSelDataCopy, id=G2G.wxID_DATASELCOPY)
1547    G2frame.Bind(wx.EVT_MENU, OnPwdrAdd, id=G2G.wxID_PWDRADD)
1548    G2frame.Bind(wx.EVT_MENU, OnHklfAdd, id=G2G.wxID_HKLFADD)
1549    G2frame.Bind(wx.EVT_MENU, OnDataDelete, id=G2G.wxID_DATADELETE)
1550    G2frame.Bind(wx.EVT_MENU, OnDataApplyStrain, id=G2G.wxID_DATADIJ)
1551    # display the last-selected phase or the 1st
1552    try:
1553        G2frame.HistPhaseLastSel
1554    except:
1555        G2frame.HistPhaseLastSel = phaseList[0]
1556    if G2frame.HistPhaseLastSel in phaseList:
1557        page = phaseList.index(G2frame.HistPhaseLastSel)
1558    else:
1559        page = 0
1560    HAPBook.SetSelection(page)
1561    wx.CallAfter(FillDDataWindow,page)
Note: See TracBrowser for help on using the repository browser.