source: trunk/exports/G2export_csv.py @ 3260

Last change on this file since 3260 was 3230, checked in by toby, 4 years ago

change stacked CSV header

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 18.5 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3########### SVN repository information ###################
4# $Date: 2018-01-17 15:13:07 +0000 (Wed, 17 Jan 2018) $
5# $Author: toby $
6# $Revision: 3230 $
7# $URL: trunk/exports/G2export_csv.py $
8# $Id: G2export_csv.py 3230 2018-01-17 15:13:07Z 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'''
18from __future__ import division, print_function
19import os.path
20import numpy as np
21import GSASIIpath
22GSASIIpath.SetVersionNumber("$Revision: 3230 $")
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            if len(self.histnam) == 1:
209                name = self.filename
210            else:    # multiple files: create a unique name from the histogram
211                name = self.MakePWDRfilename(hist)
212            fileroot = os.path.splitext(G2obj.MakeUniqueLabel(name,filenamelist))[0]
213            # create the file
214            self.filename = os.path.join(self.dirname,fileroot + self.extension)
215            self.Writer(hist)
216            print('Histogram '+hist+' written to file '+self.fullpath)
217
218class ExportMultiPowderCSV(G2IO.ExportBaseclass):
219    '''Used to create a csv file for a stack of powder data sets suitable for display
220    purposes only; no y-calc or weights are exported only x & y-obs
221    :param wx.Frame G2frame: reference to main GSAS-II frame
222    '''
223    def __init__(self,G2frame):
224        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
225            G2frame=G2frame,
226            formatName = 'stacked CSV file',
227            extension='.csv',
228            longFormatName = 'Export powder data sets as a (csv) file - x,y-o1,y-o2,... only'
229            )
230        self.exporttype = ['powder']
231        #self.multiple = False # only allow one histogram to be selected
232        self.multiple = True
233
234    def Exporter(self,event=None):
235        '''Export a set of powder data as a single csv file
236        '''
237        # the export process starts here
238        self.InitExport(event)
239        # load all of the tree into a set of dicts
240        self.loadTree()
241        if self.ExportSelect( # set export parameters
242            AskFile='ask' # only one file is ever written
243            ): return
244        csvData = []
245        headList = ["x",]
246        digitList = []
247        self.filename = os.path.join(self.dirname,os.path.splitext(self.filename)[0]
248                                     + self.extension)
249        for ihst,hist in enumerate(self.histnam):
250            histblk = self.Histograms[hist]
251            headList.append('y_obs_'+G2obj.StripUnicode(hist[5:].replace(' ','_')))
252            if not ihst:
253                digitList = [(13,3),]
254                csvData.append(histblk['Data'][0])
255            digitList += [(13,3),]
256            csvData.append(histblk['Data'][1])
257            print('Histogram '+hist+' added to file...')
258        self.OpenFile()
259        WriteList(self,headList)
260        for vallist in np.array(csvData).T:
261            line = ""
262            for val,digits in zip(vallist,digitList):
263                if line: line += ','
264                line += G2py3.FormatValue(val,digits)
265            self.Write(line)
266        self.CloseFile()
267        print('...file '+self.fullpath+' written')
268
269class ExportPowderReflCSV(G2IO.ExportBaseclass):
270    '''Used to create a csv file of reflections from a powder data set
271
272    :param wx.Frame G2frame: reference to main GSAS-II frame
273    '''
274    def __init__(self,G2frame):
275        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
276            G2frame=G2frame,
277            formatName = 'reflection list as CSV',
278            extension='.csv',
279            longFormatName = 'Export powder reflection list as a comma-separated (csv) file'
280            )
281        self.exporttype = ['powder']
282        self.multiple = False # only allow one histogram to be selected
283
284    def Exporter(self,event=None):
285        '''Export a set of powder reflections as a csv file
286        '''
287        self.InitExport(event)
288        # load all of the tree into a set of dicts
289        self.loadTree()
290        if self.ExportSelect(): return  # set export parameters, get file name
291        self.OpenFile()
292        hist = self.histnam[0] # there should only be one histogram, in any case take the 1st
293        histblk = self.Histograms[hist]
294        self.Write('"Histogram"')
295        self.Write('"'+hist+'"')
296        self.Write('')
297        # table of phases
298        self.Write('"Phase name","phase #"')
299        for i,phasenam in enumerate(sorted(histblk['Reflection Lists'])):
300            self.Write('"'+str(phasenam)+'",'+str(i))
301        self.Write('')
302        # note addition of a phase # flag at end (i)
303        for i,phasenam in enumerate(sorted(histblk['Reflection Lists'])):
304            phasDict = histblk['Reflection Lists'][phasenam]
305            tname = {'T':'TOF','C':'2-theta'}[phasDict['Type'][2]]
306            if phasDict.get('Super',False):
307                WriteList(self,("h","k","l","m","d-sp",tname,"F_obs","F_calc","phase","mult","sig","gam","FWHM","Prfo","phase #"))
308                if 'T' in phasDict['Type']:
309                    fmt = "{:.0f},{:.0f},{:.0f},{:.0f},{:.5f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:.3f},{:.3f},{:.3f},{:.4f},{:d}"
310                else:
311                    fmt = "{:.0f},{:.0f},{:.0f},{:.0f},{:.5f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:.5f},{:.5f},{:.5f},{:.4f},{:d}"
312                refList = phasDict['RefList']
313                for refItem in refList:
314                    if 'T' in phasDict['Type']:
315                        h,k,l,m,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr,x,x,x,Prfo = refItem[:17]
316                        FWHM = G2pwd.getgamFW(gam,sig)
317                        self.Write(fmt.format(h,k,l,m,dsp,pos,Fobs,Fcalc,phase,mult,sig,gam,FWHM,i))
318                    else:        #convert to deg       
319                        h,k,l,m,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr,Prfo = refItem[:14]
320                        s = np.sqrt(max(sig,0.0001))/100.   #var -> sig in deg
321                        g = gam/100.    #-> deg
322                        FWHM = G2pwd.getgamFW(g,s)
323                        self.Write(fmt.format(h,k,l,m,dsp,pos,Fobs,Fcalc,phase,mult,s,g,FWHM,i))
324            else:
325                WriteList(self,("h","k","l","d-sp",tname,"F_obs","F_calc","phase","mult","sig","gam","FWHM","Prfo","phase #"))
326                if 'T' in phasDict['Type']:
327                    fmt = "{:.0f},{:.0f},{:.0f},{:.5f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:.3f},{:.3f},{:.3f},{:.4f},{:d}"
328                else:
329                    fmt = "{:.0f},{:.0f},{:.0f},{:.5f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:.5f},{:.5f},{:.5f},{:.4f},{:d}"
330                refList = phasDict['RefList']
331                for refItem in refList:
332                    if 'T' in phasDict['Type']:
333                        h,k,l,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr,x,x,x,Prfo = refItem[:16]
334                        FWHM = G2pwd.getgamFW(gam,sig)
335                        self.Write(fmt.format(h,k,l,dsp,pos,Fobs,Fcalc,phase,mult,sig,gam,FWHM,Prfo,i))
336                    else:        #convert to deg       
337                        h,k,l,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr,Prfo = refItem[:13]
338                        g = gam/100.
339                        s = np.sqrt(max(sig,0.0001))/100.
340                        FWHM = G2pwd.getgamFW(g,s)
341                        self.Write(fmt.format(h,k,l,dsp,pos,Fobs,Fcalc,phase,mult,s,g,FWHM,Prfo,i))
342        self.CloseFile()
343        print(hist+' reflections written to file '+self.fullpath)
344
345class ExportSingleCSV(G2IO.ExportBaseclass):
346    '''Used to create a csv file with single crystal reflection data
347
348    :param wx.Frame G2frame: reference to main GSAS-II frame
349    '''
350    def __init__(self,G2frame):
351        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
352            G2frame=G2frame,
353            formatName = 'CSV file',
354            extension='.csv',
355            longFormatName = 'Export reflection list as a comma-separated (csv) file'
356            )
357        self.exporttype = ['single']
358        self.multiple = False # only allow one histogram to be selected
359
360    def Exporter(self,event=None):
361        '''Export a set of single crystal data as a csv file
362        '''
363        # the export process starts here
364        self.InitExport(event)
365        # load all of the tree into a set of dicts
366        self.loadTree()
367        if self.ExportSelect(): return  # set export parameters, get file name
368        self.OpenFile()
369        hist = self.histnam[0] # there should only be one histogram, in any case take the 1st
370        histblk = self.Histograms[hist]
371        for i,phasenam in enumerate(sorted(histblk['Reflection Lists'])):
372            phasDict = histblk['Reflection Lists'][phasenam]
373            tname = {'T':'TOF','C':'2-theta'}[phasDict['Type'][2]]
374            if phasDict.get('Super',False):
375                WriteList(self,("h","k","l","m",'d-sp',tname,"F_obs","F_calc","phase","mult","phase #"))
376                fmt = "{:.0f},{:.0f},{:.0f},{:.0f},{:.5f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:d}"
377                refList = phasDict['RefList']
378                for refItem in refList:
379                    h,k,l,m,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr = refItem[:13]
380                    self.Write(fmt.format(h,k,l,m,dsp,pos,Fobs,Fcalc,phase,mult,i))               
381            else:
382                WriteList(self,("h","k","l",'d-sp',tname,"F_obs","F_calc","phase","mult","phase #"))
383                fmt = "{:.0f},{:.0f},{:.0f},{:.5f},{:.3f},{:.3f},{:.3f},{:.2f},{:.0f},{:d}"
384                refList = phasDict['RefList']
385                for refItem in refList:
386                    h,k,l,mult,dsp,pos,sig,gam,Fobs,Fcalc,phase,Icorr = refItem[:12]
387                    self.Write(fmt.format(h,k,l,dsp,pos,Fobs,Fcalc,phase,mult,i))
388        self.CloseFile()
389        print(hist+' written to file '+self.fullname)                       
390
391class ExportStrainCSV(G2IO.ExportBaseclass):
392    '''Used to create a csv file with single crystal reflection data
393
394    :param wx.Frame G2frame: reference to main GSAS-II frame
395    '''
396    def __init__(self,G2frame):
397        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
398            G2frame=G2frame,
399            formatName = 'Strain CSV file',
400            extension='.csv',
401            longFormatName = 'Export strain results as a comma-separated (csv) file'
402            )
403        self.exporttype = ['image']
404        self.multiple = False # only allow one histogram to be selected
405
406    def Exporter(self,event=None):
407        '''Export a set of single crystal data as a csv file
408        '''
409        # the export process starts here
410        self.InitExport(event)
411        # load all of the tree into a set of dicts
412        self.loadTree()
413        if self.ExportSelect(): return  # set export parameters, get file name
414        self.OpenFile()
415        hist = self.histnam[0] # there should only be one histogram, in any case take the 1st
416        histblk = self.Histograms[hist]
417        StrSta = histblk['Stress/Strain']
418        WriteList(self,("Dset","Dcalc","e11","sig(e11)","e12","sig(e12)","e22","sig(e22)"))
419        fmt = 2*"{:.5f},"+6*"{:.0f},"
420        fmt1 = "{:.5f}"
421        fmt2 = "{:.2f},{:.5f},{:.5f}"
422        for item in StrSta['d-zero']:
423            Emat = item['Emat']
424            Esig = item['Esig']
425            self.Write(fmt.format(item['Dset'],item['Dcalc'],Emat[0],Esig[0],Emat[1],Esig[1],Emat[2],Esig[2]))
426        for item in StrSta['d-zero']:
427            WriteList(self,("Azm","dobs","dcalc","Dset="+fmt1.format(item['Dset'])))
428            ring = np.vstack((item['ImtaObs'],item['ImtaCalc']))
429            for dat in ring.T:
430                self.Write(fmt2.format(dat[1],dat[0],dat[2]))           
431        self.CloseFile()
432        print(hist+' written to file '+self.fullpath)
Note: See TracBrowser for help on using the repository browser.