source: trunk/exports/G2export_csv.py @ 3024

Last change on this file since 3024 was 2819, checked in by vondreele, 5 years ago

fix printing of nonascii characters (e.g. "umlaut-o") in file names, etc. in exporters

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