source: trunk/exports/G2export_csv.py @ 3136

Last change on this file since 3136 was 3136, checked in by vondreele, 6 years ago

make GSAS-II python 3.6 compliant & preserve python 2.7 use;changes:
do from future import division, print_function for all GSAS-II py sources
all menu items revised to be py 2.7/3.6 compliant
all wx.OPEN --> wx.FD_OPEN in file dialogs
all integer divides (typically for image pixel math) made explicit with ; ambiguous ones made floats as appropriate
all print "stuff" --> print (stuff)
all print >> pFile,'stuff' --> pFile.writeCIFtemplate('stuff')
all read file opens made explicit 'r' or 'rb'
all cPickle imports made for py2.7 or 3.6 as cPickle or _pickle; test for '2' platform.version_tuple[0] for py 2.7
define cPickleload to select load(fp) or load(fp,encoding='latin-1') for loading gpx files; provides cross compatibility between py 2.7/3.6 gpx files
make dict.keys() as explicit list(dict.keys()) as needed (NB: possible source of remaining py3.6 bugs)
make zip(a,b) as explicit list(zip(a,b)) as needed (NB: possible source of remaining py3.6 bugs)
select unichr/chr according test for '2' platform.version_tuple[0] for py 2.7 (G2pwdGUI * G2plot) for special characters
select wg.EVT_GRID_CELL_CHANGE (classic) or wg.EVT_GRID_CELL_CHANGED (phoenix) in grid Bind
maxint --> maxsize; used in random number stuff
raise Exception,"stuff" --> raise Exception("stuff")
wx 'classic' sizer.DeleteWindows?() or 'phoenix' sizer.Clear(True)
wx 'classic' SetToolTipString?(text) or 'phoenix' SetToolTip?(wx.ToolTip?(text)); define SetToolTipString?(self,text) to handle the choice in plots
status.SetFields? --> status.SetStatusText?
'classic' AddSimpleTool? or 'phoenix' self.AddTool? for plot toolbar; Bind different as well
define GetItemPydata? as it doesn't exist in wx 'phoenix'
allow python versions 2.7 & 3.6 to run GSAS-II
Bind override commented out - no logging capability (NB: remove all logging code?)
all import ContentsValidator? open filename & test if valid then close; filepointer removed from Reader
binary importers (mostly images) test for 'byte' type & convert as needed to satisfy py 3.6 str/byte rules

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 18.3 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3########### SVN repository information ###################
4# $Date: 2017-10-23 16:39:16 +0000 (Mon, 23 Oct 2017) $
5# $Author: vondreele $
6# $Revision: 3136 $
7# $URL: trunk/exports/G2export_csv.py $
8# $Id: G2export_csv.py 3136 2017-10-23 16:39:16Z vondreele $
9########### SVN repository information ###################
10'''
11*Module G2export_csv: Spreadsheet export*
12-------------------------------------------
13
14Code to create .csv (comma-separated variable) files for
15GSAS-II data export to a spreadsheet program, etc.
16
17'''
18from __future__ import division, print_function
19import os.path
20import numpy as np
21import GSASIIpath
22GSASIIpath.SetVersionNumber("$Revision: 3136 $")
23import GSASIIIO as G2IO
24import GSASIIpy3 as G2py3
25import GSASIIobj as G2obj
26import GSASIImath as G2mth
27import GSASIIpwd as G2pwd
28
29def WriteList(obj,headerItems):
30    '''Write a CSV header
31
32    :param object obj: Exporter object
33    :param list headerItems: items to write as a header
34    '''
35    line = ''
36    for lbl in headerItems:
37        if line: line += ','
38        line += '"'+lbl+'"'
39    obj.Write(line)
40
41class ExportPhaseCSV(G2IO.ExportBaseclass):
42    '''Used to create a csv file for a phase
43
44    :param wx.Frame G2frame: reference to main GSAS-II frame
45    '''
46    def __init__(self,G2frame):
47        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
48            G2frame=G2frame,
49            formatName = 'CSV file',
50            extension='.csv',
51            longFormatName = 'Export phase as comma-separated (csv) file'
52            )
53        self.exporttype = ['phase']
54        self.multiple = True # allow multiple phases to be selected
55
56    def Writer(self,hist,phasenam,mode='w'):
57        self.OpenFile(mode=mode)
58        # test for aniso atoms
59        aniso = False
60        AtomsList = self.GetAtoms(phasenam)
61        for lbl,typ,mult,xyz,td in AtomsList:
62            if len(td) != 1:
63                aniso = True
64                break
65        if mode == 'w':
66            lbllist = ['hist','phase','a','b','c','alpha','beta','gamma','volume']
67            lbllist += ["atm label","elem","mult","x","y","z","frac","Uiso"]
68            if aniso: lbllist += ['U11','U22','U33','U12','U13','U23']
69            WriteList(self,lbllist)
70           
71        cellList,cellSig = self.GetCell(phasenam)
72        line = '"' + str(hist)+ '","' + str(phasenam) + '"'
73        for defsig,val in zip(
74            3*[-0.00001] + 3*[-0.001] + [-0.01], # sets sig. figs.
75            cellList
76            ):
77            txt = G2mth.ValEsd(val,defsig)
78            if line: line += ','
79            line += txt
80        self.Write(line)
81
82        # get atoms and print separated by commas
83        AtomsList = self.GetAtoms(phasenam)
84        for lbl,typ,mult,xyz,td in AtomsList:
85            line = ",,,,,,,,,"
86            line += '"' + lbl + '","' + typ + '",' + str(mult) + ','
87            for val,sig in xyz:
88                line += G2mth.ValEsd(val,-abs(sig))
89                line += ","
90            if len(td) == 1:
91                line += G2mth.ValEsd(td[0][0],-abs(td[0][1]))
92            else:
93                line += ","
94                for val,sig in td:
95                    line += G2mth.ValEsd(val,-abs(sig))
96                    line += ","
97            self.Write(line)
98
99        if mode == 'w':
100            print('Phase '+phasenam+' written to file '+self.fullpath)
101        self.CloseFile()
102   
103    def Exporter(self,event=None):
104        '''Export a phase as a csv file
105        '''
106        # the export process starts here
107        self.InitExport(event)
108        # load all of the tree into a set of dicts
109        self.loadTree()
110        # create a dict with refined values and their uncertainties
111        self.loadParmDict()
112        if self.ExportSelect(): return # set export parameters; get file name
113        self.OpenFile()
114        # if more than one phase is selected, put them into a single file
115        for phasenam in self.phasenam:
116            phasedict = self.Phases[phasenam] # pointer to current phase info           
117            i = self.Phases[phasenam]['pId']
118            self.Write('"'+"Phase "+str(phasenam)+" from "+str(self.G2frame.GSASprojectfile)+'"')
119            self.Write('\n"Space group:","'+str(phasedict['General']['SGData']['SpGrp'].strip())+'"')
120            # get cell parameters & print them
121            cellList,cellSig = self.GetCell(phasenam)
122            WriteList(self,['a','b','c','alpha','beta','gamma','volume'])
123
124            line = ''
125            for defsig,val in zip(
126                3*[-0.00001] + 3*[-0.001] + [-0.01], # sign values to use when no sigma
127                cellList
128                ):
129                txt = G2mth.ValEsd(val,defsig)
130                if line: line += ','
131                line += txt
132            self.Write(line)
133               
134            # get atoms and print separated by commas
135            AtomsList = self.GetAtoms(phasenam)
136            # check for aniso atoms
137            aniso = False
138            for lbl,typ,mult,xyz,td in AtomsList:
139                if len(td) != 1: aniso = True               
140            lbllist = ["label","elem","mult","x","y","z","frac","Uiso"]
141            if aniso: lbllist += ['U11','U22','U33','U12','U13','U23']
142            WriteList(self,lbllist)
143               
144            for lbl,typ,mult,xyz,td in AtomsList:
145                line = '"' + lbl + '","' + typ + '",' + str(mult) + ','
146                for val,sig in xyz:
147                    line += G2mth.ValEsd(val,-abs(sig))
148                    line += ","
149                if len(td) == 1:
150                    line += G2mth.ValEsd(td[0][0],-abs(td[0][1]))
151                else:
152                    line += ","
153                    for val,sig in td:
154                        line += G2mth.ValEsd(val,-abs(sig))
155                        line += ","
156                self.Write(line)
157            print('Phase '+phasenam+' written to file '+self.fullpath)
158        self.CloseFile()
159
160class ExportPowderCSV(G2IO.ExportBaseclass):
161    '''Used to create a csv file for a powder data set
162
163    :param wx.Frame G2frame: reference to main GSAS-II frame
164    '''
165    def __init__(self,G2frame):
166        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
167            G2frame=G2frame,
168            formatName = 'CSV file',
169            extension='.csv',
170            longFormatName = 'Export powder data as comma-separated (csv) file'
171            )
172        self.exporttype = ['powder']
173        #self.multiple = False # only allow one histogram to be selected
174        self.multiple = True
175
176    def Writer(self,TreeName,filename=None):
177        #print filename
178        self.OpenFile(filename)
179        histblk = self.Histograms[TreeName]
180        WriteList(self,("x","y_obs","weight","y_calc","y_bkg"))
181        digitList = 2*((13,3),) + ((13,5),) + 2*((13,3),)
182        for vallist in zip(histblk['Data'][0],
183                       histblk['Data'][1],
184                       histblk['Data'][2],
185                       histblk['Data'][3],
186                       histblk['Data'][4],
187                       #histblk['Data'][5],
188                       ):
189            line = ""
190            for val,digits in zip(vallist,digitList):
191                if line: line += ','
192                line += G2py3.FormatValue(val,digits)
193            self.Write(line)
194        self.CloseFile()
195       
196    def Exporter(self,event=None):
197        '''Export a set of powder data as a csv file
198        '''
199        # the export process starts here
200        self.InitExport(event)
201        # load all of the tree into a set of dicts
202        self.loadTree()
203        if self.ExportSelect( # set export parameters
204            AskFile='single' # get a file name/directory to save in
205            ): return
206        filenamelist = []
207        for hist in self.histnam:
208            # multiple files: create a unique name from the histogram
209            fileroot = G2obj.MakeUniqueLabel(self.MakePWDRfilename(hist),filenamelist)
210            # create an instrument parameter file
211            self.filename = os.path.join(self.dirname,fileroot + self.extension)
212            self.Writer(hist)
213            print('Histogram '+hist+' written to file '+self.fullpath)
214
215class ExportMultiPowderCSV(G2IO.ExportBaseclass):
216    '''Used to create a csv file for a stack of powder data sets suitable for display
217    purposes only; no y-calc or weights are exported only x & y-obs
218    :param wx.Frame G2frame: reference to main GSAS-II frame
219    '''
220    def __init__(self,G2frame):
221        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
222            G2frame=G2frame,
223            formatName = 'stacked CSV file',
224            extension='.csv',
225            longFormatName = 'Export powder data sets as a (csv) file - x,y-o1,y-o2,... only'
226            )
227        self.exporttype = ['powder']
228        #self.multiple = False # only allow one histogram to be selected
229        self.multiple = True
230
231    def Exporter(self,event=None):
232        '''Export a set of powder data as a csv file
233        '''
234        # the export process starts here
235        self.InitExport(event)
236        # load all of the tree into a set of dicts
237        self.loadTree()
238        if self.ExportSelect( # set export parameters
239            AskFile='single' # get a file name/directory to save in
240            ): return
241        filenamelist = []
242        csvData = []
243        headList = ["x",]
244        digitList = []
245        fileroot = G2obj.MakeUniqueLabel(self.MakePWDRfilename(self.histnam[0]),filenamelist)
246        # create a file
247        self.filename = os.path.join(self.dirname,fileroot + self.extension)
248        for ihst,hist in enumerate(self.histnam):
249            histblk = self.Histograms[hist]
250            headList.append('y_obs_'+str(ihst))
251            if not ihst:
252                digitList = [(13,3),]
253                csvData.append(histblk['Data'][0])
254            digitList += [(13,3),]
255            csvData.append(histblk['Data'][1])
256            print('Histogram '+hist+' written to file '+self.fullpath)
257        self.OpenFile()
258        WriteList(self,headList)
259        for vallist in np.array(csvData).T:
260            line = ""
261            for val,digits in zip(vallist,digitList):
262                if line: line += ','
263                line += G2py3.FormatValue(val,digits)
264            self.Write(line)
265        self.CloseFile()
266
267class ExportPowderReflCSV(G2IO.ExportBaseclass):
268    '''Used to create a csv file of reflections from a powder data set
269
270    :param wx.Frame G2frame: reference to main GSAS-II frame
271    '''
272    def __init__(self,G2frame):
273        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
274            G2frame=G2frame,
275            formatName = 'reflection list as CSV',
276            extension='.csv',
277            longFormatName = 'Export powder reflection list as a comma-separated (csv) file'
278            )
279        self.exporttype = ['powder']
280        self.multiple = False # only allow one histogram to be selected
281
282    def Exporter(self,event=None):
283        '''Export a set of powder reflections as a csv file
284        '''
285        self.InitExport(event)
286        # load all of the tree into a set of dicts
287        self.loadTree()
288        if self.ExportSelect(): return  # set export parameters, get file name
289        self.OpenFile()
290        hist = self.histnam[0] # there should only be one histogram, in any case take the 1st
291        histblk = self.Histograms[hist]
292        self.Write('"Histogram"')
293        self.Write('"'+hist+'"')
294        self.Write('')
295        # table of phases
296        self.Write('"Phase name","phase #"')
297        for i,phasenam in enumerate(sorted(histblk['Reflection Lists'])):
298            self.Write('"'+str(phasenam)+'",'+str(i))
299        self.Write('')
300        # note addition of a phase # flag at end (i)
301        for i,phasenam in enumerate(sorted(histblk['Reflection Lists'])):
302            phasDict = histblk['Reflection Lists'][phasenam]
303            tname = {'T':'TOF','C':'2-theta'}[phasDict['Type'][2]]
304            if phasDict.get('Super',False):
305                WriteList(self,("h","k","l","m",tname,"F_obs","F_calc","phase","mult","sig","gam","FWHM","Prfo","phase #"))
306                if 'T' in phasDict['Type']:
307                    fmt = "{:.0f},{:.0f},{:.0f},{:.0f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:.3f},{:.3f},{:.3f},{:.4f},{:d}"
308                else:
309                    fmt = "{:.0f},{:.0f},{:.0f},{:.0f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:.5f},{:.5f},{:.5f},{:.4f},{:d}"
310                refList = phasDict['RefList']
311                for refItem in refList:
312                    if 'T' in phasDict['Type']:
313                        h,k,l,m,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr,x,x,x,Prfo = refItem[:17]
314                        FWHM = G2pwd.getgamFW(gam,sig)
315                        self.Write(fmt.format(h,k,l,m,pos,Fobs,Fcalc,phase,mult,sig,gam,FWHM,i))
316                    else:        #convert to deg       
317                        h,k,l,m,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr,Prfo = refItem[:14]
318                        s = np.sqrt(max(sig,0.0001))/100.   #var -> sig in deg
319                        g = gam/100.    #-> deg
320                        FWHM = G2pwd.getgamFW(g,s)
321                        self.Write(fmt.format(h,k,l,m,pos,Fobs,Fcalc,phase,mult,s,g,FWHM,i))
322            else:
323                WriteList(self,("h","k","l",tname,"F_obs","F_calc","phase","mult","sig","gam","FWHM","Prfo","phase #"))
324                if 'T' in phasDict['Type']:
325                    fmt = "{:.0f},{:.0f},{:.0f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:.3f},{:.3f},{:.3f},{:.4f},{:d}"
326                else:
327                    fmt = "{:.0f},{:.0f},{:.0f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:.5f},{:.5f},{:.5f},{:.4f},{:d}"
328                refList = phasDict['RefList']
329                for refItem in refList:
330                    if 'T' in phasDict['Type']:
331                        h,k,l,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr,x,x,x,Prfo = refItem[:16]
332                        FWHM = G2pwd.getgamFW(gam,sig)
333                        self.Write(fmt.format(h,k,l,pos,Fobs,Fcalc,phase,mult,sig,gam,FWHM,Prfo,i))
334                    else:        #convert to deg       
335                        h,k,l,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr,Prfo = refItem[:13]
336                        g = gam/100.
337                        s = np.sqrt(max(sig,0.0001))/100.
338                        FWHM = G2pwd.getgamFW(g,s)
339                        self.Write(fmt.format(h,k,l,pos,Fobs,Fcalc,phase,mult,s,g,FWHM,Prfo,i))
340        self.CloseFile()
341        print(hist+'reflections written to file '+self.fullpath)
342
343class ExportSingleCSV(G2IO.ExportBaseclass):
344    '''Used to create a csv file with single crystal reflection data
345
346    :param wx.Frame G2frame: reference to main GSAS-II frame
347    '''
348    def __init__(self,G2frame):
349        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
350            G2frame=G2frame,
351            formatName = 'CSV file',
352            extension='.csv',
353            longFormatName = 'Export reflection list as a comma-separated (csv) file'
354            )
355        self.exporttype = ['single']
356        self.multiple = False # only allow one histogram to be selected
357
358    def Exporter(self,event=None):
359        '''Export a set of single crystal data as a csv file
360        '''
361        # the export process starts here
362        self.InitExport(event)
363        # load all of the tree into a set of dicts
364        self.loadTree()
365        if self.ExportSelect(): return  # set export parameters, get file name
366        self.OpenFile()
367        hist = self.histnam[0] # there should only be one histogram, in any case take the 1st
368        histblk = self.Histograms[hist]
369        for i,phasenam in enumerate(sorted(histblk['Reflection Lists'])):
370            phasDict = histblk['Reflection Lists'][phasenam]
371            tname = {'T':'TOF','C':'2-theta'}[phasDict['Type'][2]]
372            if phasDict.get('Super',False):
373                WriteList(self,("h","k","l","m",tname,"F_obs","F_calc","phase","mult","phase #"))
374                fmt = "{:.0f},{:.0f},{:.0f},{:.0f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:d}"
375                refList = phasDict['RefList']
376                for refItem in refList:
377                    h,k,l,m,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr = refItem[:13]
378                    self.Write(fmt.format(h,k,l,m,pos,Fobs,Fcalc,phase,mult,i))               
379            else:
380                WriteList(self,("h","k","l",tname,"F_obs","F_calc","phase","mult","phase #"))
381                fmt = "{:.0f},{:.0f},{:.0f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:d}"
382                refList = phasDict['RefList']
383                for refItem in refList:
384                    h,k,l,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr = refItem[:12]
385                    self.Write(fmt.format(h,k,l,pos,Fobs,Fcalc,phase,mult,i))
386        self.CloseFile()
387        print(hist+' written to file '+self.fullname)                       
388
389class ExportStrainCSV(G2IO.ExportBaseclass):
390    '''Used to create a csv file with single crystal reflection data
391
392    :param wx.Frame G2frame: reference to main GSAS-II frame
393    '''
394    def __init__(self,G2frame):
395        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
396            G2frame=G2frame,
397            formatName = 'Strain CSV file',
398            extension='.csv',
399            longFormatName = 'Export strain results as a comma-separated (csv) file'
400            )
401        self.exporttype = ['image']
402        self.multiple = False # only allow one histogram to be selected
403
404    def Exporter(self,event=None):
405        '''Export a set of single crystal data as a csv file
406        '''
407        # the export process starts here
408        self.InitExport(event)
409        # load all of the tree into a set of dicts
410        self.loadTree()
411        if self.ExportSelect(): return  # set export parameters, get file name
412        self.OpenFile()
413        hist = self.histnam[0] # there should only be one histogram, in any case take the 1st
414        histblk = self.Histograms[hist]
415        StrSta = histblk['Stress/Strain']
416        WriteList(self,("Dset","Dcalc","e11","sig(e11)","e12","sig(e12)","e22","sig(e22)"))
417        fmt = 2*"{:.5f},"+6*"{:.0f},"
418        fmt1 = "{:.5f}"
419        fmt2 = "{:.2f},{:.5f},{:.5f}"
420        for item in StrSta['d-zero']:
421            Emat = item['Emat']
422            Esig = item['Esig']
423            self.Write(fmt.format(item['Dset'],item['Dcalc'],Emat[0],Esig[0],Emat[1],Esig[1],Emat[2],Esig[2]))
424        for item in StrSta['d-zero']:
425            WriteList(self,("Azm","dobs","dcalc","Dset="+fmt1.format(item['Dset'])))
426            ring = np.vstack((item['ImtaObs'],item['ImtaCalc']))
427            for dat in ring.T:
428                self.Write(fmt2.format(dat[1],dat[0],dat[2]))           
429        self.CloseFile()
430        print(hist+' written to file '+self.fullpath)
Note: See TracBrowser for help on using the repository browser.