Changeset 2449 for trunk/exports/G2export_CIF.py
- Timestamp:
- Aug 24, 2016 9:20:07 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/exports/G2export_CIF.py
r2433 r2449 16 16 publication. In addition, there are three subclasses of :class:`ExportCIF`: 17 17 :class:`ExportProjectCIF`, 18 :class:`ExportPhaseCIF` and :class:`ExportDataCIF` that 19 export a project, single phase or data set. Note that ``self.mode`` determines 20 what is written: 21 22 * `self.mode="simple"` creates a simple CIF with only coordinates 23 or data, while 24 25 * `self.mode="full"` creates a complete CIF of project. 26 18 :class:`ExportPhaseCIF` and :class:`ExportDataCIF` where extra parameters 19 for the _Exporter() determine if a project, single phase or data set are written. 27 20 ''' 28 21 … … 57 50 '''Base class for CIF exports 58 51 ''' 59 def __init__(self,G2frame): 60 super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__ 61 G2frame=G2frame, 62 formatName = 'Full CIF', 63 extension='.cif', 64 longFormatName = 'Export project as CIF' 65 ) 52 def __init__(self,G2frame,formatName,extension,longFormatName=None,): 53 G2IO.ExportBaseclass.__init__(self,G2frame,formatName,extension,longFormatName=None) 66 54 self.exporttype = [] 67 55 self.author = '' 68 self. mode = ''56 self.CIFname = '' 69 57 70 58 def _Exporter(self,event=None,phaseOnly=None,histOnly=None): 71 '''Basic code to export a CIF. Export can be full or simple (as set by self.mode). 72 "simple" skips data, distances & angles, etc. and can only include 73 a single phase while "full" is intended for for publication submission. 59 '''Basic code to export a CIF. Export can be full or simple, as set by 60 phaseOnly and histOnly which skips distances & angles, etc. 74 61 ''' 75 62 … … 1289 1276 return False # cancel was pressed 1290 1277 self.author = dlg.GetValue() 1278 self.shortauthorname = self.author.replace(',','').replace(' ','')[:20] 1291 1279 dlg.Destroy() 1292 1280 try: … … 1295 1283 pass 1296 1284 return True 1285 1297 1286 def EditInstNames(event=None): 1298 1287 'Provide a dialog for editing instrument names' … … 1597 1586 dlg.ShowModal() 1598 1587 1599 #***** end of functions for export method ======================================= 1588 #================================================================================= 1589 #===== end of function definitions for _Exporter ================================= 1600 1590 #================================================================================= 1601 1591 # make sure required information is present 1602 1592 self.CIFdate = dt.datetime.strftime(dt.datetime.now(),"%Y-%m-%dT%H:%M") 1603 self.CIFname = self.CIFname.replace(' ','')1604 if not self.CIFname: # none defined & needed, save as GPX to get one1605 self.G2frame.OnFileSaveas(None)1593 if not self.CIFname: # Get a name for the CIF. If not defined, use the GPX name (save if that is needed). 1594 if not self.G2frame.GSASprojectfile: 1595 self.G2frame.OnFileSaveas(None) 1606 1596 if not self.G2frame.GSASprojectfile: return 1607 1597 self.CIFname = os.path.splitext( … … 1614 1604 except KeyError: 1615 1605 pass 1616 while not (self.author or self.quickmode):1617 if not EditAuthor(): return1618 self.shortauthorname = self.author.replace(',','').replace(' ','')[:20]1619 1620 1606 if phaseOnly: 1607 print('Writing CIF output to file '+str(self.filename)) 1608 self.OpenFile() 1621 1609 oneblock = True 1622 1610 self.quickmode = True … … 1628 1616 # report the phase info 1629 1617 WritePhaseInfo(phaseOnly) 1618 self.CloseFile() 1630 1619 return 1631 elif histOnly and len(self.Phases) == 1: 1620 elif histOnly: 1621 print('Writing CIF output to file '+str(self.filename)) 1622 self.OpenFile() 1632 1623 hist = histOnly 1633 1624 histname = histOnly.replace(' ','') 1634 1625 oneblock = True 1635 self.quickmode = False1626 self.quickmode = True 1636 1627 self.ifHKLF = False 1637 1628 self.ifPWDR = True 1638 1629 self.Write(' ') 1639 1630 self.Write(70*'#') 1640 phasenam = self.Phases.keys()[0]1631 #phasenam = self.Phases.keys()[0] 1641 1632 WriteCIFitem('data_'+self.CIFname) 1642 1633 #print 'phasenam',phasenam 1643 1634 #phaseblk = self.Phases[phasenam] # pointer to current phase info 1644 instnam = instnam.replace(' ','')1645 WriteCIFitem('_pd_block_id',1646 str(self.CIFdate) + "|" + str(self.CIFname) + "|" +1647 str(self.shortauthorname) + "|" + instnam + '|' + histname)1635 #instnam = instnam.replace(' ','') 1636 #WriteCIFitem('_pd_block_id', 1637 # str(self.CIFdate) + "|" + str(self.CIFname) + "|" + 1638 # str(self.shortauthorname) + "|" + instnam + '|' + histname) 1648 1639 #WriteAudit() 1649 1640 #writeCIFtemplate(self.OverallParms['Controls'],'publ') # overall (publication) template … … 1651 1642 #writeCIFtemplate(self.Phases[phasenam]['General'],'phase',phasenam) # write phase template 1652 1643 # report the phase info 1653 WritePhaseInfo(phasenam,hist)1644 #WritePhaseInfo(phasenam,hist) 1654 1645 # preferred orientation 1655 1646 #SH = FormatSH(phasenam) … … 1668 1659 #writeCIFtemplate(histblk,'powder',histblk['InstrName']) # write powder template 1669 1660 WritePowderData(hist) 1661 self.CloseFile() 1670 1662 return 1671 elif histOnly: 1672 hist = histOnly 1673 histname = '|' + histOnly.replace(' ','') 1674 self.ifHKLF = False 1675 if hist.startswith("PWDR"): 1676 self.ifPWDR = True 1677 if not self.Histograms[hist]["Sample Parameters"].get('InstrName'): 1678 self.Histograms[hist]["Sample Parameters"]['InstrName'] = 'Unknown' 1679 else: 1680 print("error: not Powder") 1681 return 1682 oneblock = False 1683 self.quickmode = False 1684 #=== multiblock: multiple phases and/or histograms ==================== 1685 self.Write(70*'#') 1686 #WriteCIFitem('\ndata_'+self.CIFname+'_publ') 1687 #WriteAudit() 1688 #WriteCIFitem('_pd_block_id', 1689 # str(self.CIFdate) + "|" + str(self.CIFname) + "|" + 1690 # str(self.shortauthorname) + histname + "|Overall") 1691 #writeCIFtemplate(self.OverallParms['Controls'],'publ') #insert the publication template 1692 # ``template_publ.cif`` or a modified version 1693 # overall info 1694 WriteCIFitem('data_'+str(self.CIFname)+ histname +'_overall') 1695 #WriteOverall() # this does not give right value 1696 #============================================================ 1697 WriteCIFitem('# POINTERS TO PHASE AND HISTOGRAM BLOCKS') 1698 datablockidDict = {} # save block names here -- N.B. check for conflicts between phase & hist names (unlikely!) 1699 # loop over phase blocks 1700 loopprefix = '' 1701 WriteCIFitem('loop_ _pd_phase_block_id') 1702 1703 for phasenam in sorted(self.Phases.keys()): 1704 i = self.Phases[phasenam]['pId'] 1705 datablockidDict[phasenam] = (str(self.CIFdate) + "|" + str(self.CIFname) + "|" + 1706 'phase_'+ str(i) + '|' + str(self.shortauthorname) + histname) 1707 WriteCIFitem(loopprefix,datablockidDict[phasenam]) 1708 # data block 1709 loopprefix = '_pd_block_diffractogram_id' 1710 histblk = self.Histograms[hist] 1711 instnam = histblk["Sample Parameters"]['InstrName'] 1712 instnam = instnam.replace(' ','') 1713 j = histblk['hId'] 1714 datablockidDict[hist] = (str(self.CIFdate) + "|" + str(self.CIFname) + "|" + 1715 str(self.shortauthorname) + "|" + 1716 instnam + "_hist_"+str(j)) 1717 WriteCIFitem(loopprefix,datablockidDict[hist]) 1718 #============================================================ 1719 # loop over phases, exporting them 1720 phasebyhistDict = {} # create a cross-reference to phases by histogram 1721 for j,phasenam in enumerate(sorted(self.Phases.keys())): 1722 i = self.Phases[phasenam]['pId'] 1723 WriteCIFitem('\ndata_'+self.CIFname+"_phase_"+str(i)) 1724 WriteCIFitem('# Information for phase '+str(i)) 1725 WriteCIFitem('_pd_block_id',datablockidDict[phasenam]) 1726 # report the phase 1727 #writeCIFtemplate(self.Phases[phasenam]['General'],'phase',phasenam) # write phase template 1728 WritePhaseInfo(phasenam,hist) 1729 # preferred orientation 1730 #SH = FormatSH(phasenam) 1731 #MD = FormatHAPpo(phasenam) 1732 #if SH and MD: 1733 # WriteCIFitem('_pd_proc_ls_pref_orient_corr', SH + '\n' + MD) 1734 #elif SH or MD: 1735 # WriteCIFitem('_pd_proc_ls_pref_orient_corr', SH + MD) 1736 #else: 1737 # WriteCIFitem('_pd_proc_ls_pref_orient_corr', 'none') 1738 # report sample profile terms 1739 #PP = FormatPhaseProfile(phasenam) 1740 #if PP: WriteCIFitem('_pd_proc_ls_profile_function',PP) 1741 1742 #============================================================ 1743 # export selected histogram 1744 histblk = self.Histograms[hist] 1745 WriteCIFitem('\ndata_'+self.CIFname+"_pwd_"+str(i)) 1746 #instnam = histblk["Sample Parameters"]['InstrName'] 1747 # report instrumental profile terms 1748 WriteCIFitem('_pd_proc_ls_profile_function', 1749 FormatInstProfile(histblk["Instrument Parameters"],histblk['hId'])) 1750 WriteCIFitem('# Information for histogram '+str(i)+': '+hist) 1751 WriteCIFitem('_pd_block_id',datablockidDict[hist]) 1752 histprm = self.Histograms[hist]["Sample Parameters"] 1753 #writeCIFtemplate(histprm,'powder',histprm['InstrName']) # powder template 1754 WritePowderData(hist) 1755 return 1756 1663 #=============================================================================== 1757 1664 # the normal export process starts here 1665 #=============================================================================== 1758 1666 # get the project file name 1759 1667 self.CIFname = os.path.splitext( … … 1765 1673 # create a dict with refined values and their uncertainties 1766 1674 self.loadParmDict() 1767 if self.mode=='simple': 1768 if self.ExportSelect('ask'): return 1769 else: 1770 if self.ExportSelect('default'): return 1675 if self.ExportSelect('ask'): return 1676 #if self.ExportSelect('default'): return 1771 1677 # Someday: get restraint & constraint info 1772 1678 #restraintDict = self.OverallParms.get('Restraints',{}) … … 1782 1688 'Project does not contain any data or phases. Are they interconnected?') 1783 1689 return 1690 if not self.author: 1691 if not EditAuthor(): return 1784 1692 # test for quick CIF mode or no data 1785 1693 self.quickmode = False 1786 1694 phasenam = None # include all phases 1787 if self.mode == "simple" and self.currentExportType == 'phase':1788 if len(self.Phases) == 0: # this check is probably not needed1789 self.G2frame.ErrorDialog(1790 'No phase present',1791 'Cannot create a coordinates CIF with no phases')1792 return1793 self.quickmode = True1794 oneblock = True1795 if len(self.Phases) > 1: # quick mode: get selected phase1796 phasenam = self.phasenam[0]1797 elif self.mode == "simple": # powder/single xtal data export1798 self.quickmode = True1799 oneblock = True1800 1695 # Project export: will this require a multiblock CIF? 1801 elif len(self.Phases) > 1:1696 if len(self.Phases) > 1: 1802 1697 oneblock = False 1803 1698 elif len(self.powderDict) + len(self.xtalDict) > 1: … … 1809 1704 self.ifPWDR = False 1810 1705 self.ifHKLF = False 1811 if not self.quickmode: 1812 invalid = 0 1813 key3 = 'InstrName' 1814 for hist in self.Histograms: 1815 if hist.startswith("PWDR"): 1816 self.ifPWDR = True 1817 key2 = "Sample Parameters" 1818 d = self.Histograms[hist][key2] 1819 elif hist.startswith("HKLF"): 1820 self.ifHKLF = True 1821 key2 = "Instrument Parameters" 1822 d = self.Histograms[hist][key2][0] 1823 instrname = d.get(key3) 1824 if instrname is None: 1825 d[key3] = '' 1826 invalid += 1 1827 elif instrname.strip() == '': 1828 invalid += 1 1829 if invalid: 1830 msg = "" 1831 if invalid > 3: msg = ( 1832 "\n\nNote: it may be faster to set the name for\n" 1833 "one histogram for each instrument and use the\n" 1834 "File/Copy option to duplicate the name" 1835 ) 1836 if not EditInstNames(): return 1837 if not self.quickmode: 1838 # check for a distance-angle range search range for each phase 1839 for phasenam in sorted(self.Phases.keys()): 1840 #i = self.Phases[phasenam]['pId'] 1841 phasedict = self.Phases[phasenam] # pointer to current phase info 1842 if 'DisAglCtls' not in phasedict['General']: 1843 dlg = G2gd.DisAglDialog( 1844 self.G2frame, 1845 {}, 1846 phasedict['General']) 1847 if dlg.ShowModal() == wx.ID_OK: 1848 phasedict['General']['DisAglCtls'] = dlg.GetData() 1849 else: 1850 dlg.Destroy() 1851 return 1706 invalid = 0 1707 key3 = 'InstrName' 1708 for hist in self.Histograms: 1709 if hist.startswith("PWDR"): 1710 self.ifPWDR = True 1711 key2 = "Sample Parameters" 1712 d = self.Histograms[hist][key2] 1713 elif hist.startswith("HKLF"): 1714 self.ifHKLF = True 1715 key2 = "Instrument Parameters" 1716 d = self.Histograms[hist][key2][0] 1717 instrname = d.get(key3) 1718 if instrname is None: 1719 d[key3] = '' 1720 invalid += 1 1721 elif instrname.strip() == '': 1722 invalid += 1 1723 if invalid: 1724 msg = "" 1725 if invalid > 3: msg = ( 1726 "\n\nNote: it may be faster to set the name for\n" 1727 "one histogram for each instrument and use the\n" 1728 "File/Copy option to duplicate the name" 1729 ) 1730 if not EditInstNames(): return 1731 1732 # check for a distance-angle range search range for each phase 1733 for phasenam in sorted(self.Phases.keys()): 1734 #i = self.Phases[phasenam]['pId'] 1735 phasedict = self.Phases[phasenam] # pointer to current phase info 1736 if 'DisAglCtls' not in phasedict['General']: 1737 dlg = G2gd.DisAglDialog( 1738 self.G2frame, 1739 {}, 1740 phasedict['General']) 1741 if dlg.ShowModal() == wx.ID_OK: 1742 phasedict['General']['DisAglCtls'] = dlg.GetData() 1743 else: 1852 1744 dlg.Destroy() 1853 if not self.quickmode: 1854 # check if temperature values & pressure are defaulted 1855 default = 0 1856 for hist in self.Histograms: 1857 if hist.startswith("PWDR"): 1858 key2 = "Sample Parameters" 1859 T = self.Histograms[hist][key2].get('Temperature') 1860 if not T: 1861 default += 1 1862 elif T == 300: 1863 default += 1 1864 P = self.Histograms[hist][key2].get('Pressure') 1865 if not P: 1866 default += 1 1867 elif P == 1: 1868 default += 1 1869 if default > 0: 1870 dlg = wx.MessageDialog( 1871 self.G2frame, 1872 'Temperature/Pressure values appear to be defaulted for some powder histograms (See Sample Parameters for each PWDR tree entry). Do you want to use those values?', 1873 'Check T and P values', 1874 wx.OK|wx.CANCEL) 1875 ret = dlg.ShowModal() 1745 return 1876 1746 dlg.Destroy() 1877 if ret != wx.ID_OK: return 1878 if oneblock and not self.quickmode: 1747 1748 # check if temperature values & pressure are defaulted 1749 default = 0 1750 for hist in self.Histograms: 1751 if hist.startswith("PWDR"): 1752 key2 = "Sample Parameters" 1753 T = self.Histograms[hist][key2].get('Temperature') 1754 if not T: 1755 default += 1 1756 elif T == 300: 1757 default += 1 1758 P = self.Histograms[hist][key2].get('Pressure') 1759 if not P: 1760 default += 1 1761 elif P == 1: 1762 default += 1 1763 if default > 0: 1764 dlg = wx.MessageDialog( 1765 self.G2frame, 1766 'Temperature/Pressure values appear to be defaulted for some powder histograms (See Sample Parameters for each PWDR tree entry). Do you want to use those values?', 1767 'Check T and P values', 1768 wx.OK|wx.CANCEL) 1769 ret = dlg.ShowModal() 1770 dlg.Destroy() 1771 if ret != wx.ID_OK: return 1772 if oneblock: 1879 1773 # select a dataset to use (there should only be one set in one block, 1880 1774 # but take whatever comes 1st) … … 1887 1781 instnam = histblk["Instrument Parameters"][0]['InstrName'] 1888 1782 break # ignore all but 1st data histogram 1889 if not self.quickmode:# give the user a chance to edit all defaults1890 1891 1892 1893 1894 1895 1896 1897 1898 1783 # give the user a chance to edit all defaults 1784 self.cifdefs = wx.Dialog( 1785 self.G2frame, 1786 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) 1787 EditCIFDefaults() 1788 self.cifdefs.CenterOnParent() 1789 val = self.cifdefs.ShowModal() 1790 self.cifdefs.Destroy() 1791 if val != wx.ID_OK: 1792 return 1899 1793 #====================================================================== 1900 1794 # Start writing the CIF - single block … … 1913 1807 else: 1914 1808 print "should not happen" 1915 elif self.quickmode:1916 #====Phase only CIF ====================================================1917 WriteCIFitem('data_'+self.CIFname)1918 if phasenam is None: # if not already selected, select the first phase (should be one)1919 phasenam = self.Phases.keys()[0]1920 #print 'phasenam',phasenam1921 #phaseblk = self.Phases[phasenam] # pointer to current phase info1922 # report the phase info1923 WritePhaseInfo(phasenam)1924 1809 elif oneblock: 1925 1810 #====Single block, data & phase CIF =================================== … … 2105 1990 ''' 2106 1991 def __init__(self,G2frame): 2107 G2IO.ExportBaseclass.__init__(self,1992 ExportCIF.__init__(self, 2108 1993 G2frame=G2frame, 2109 1994 formatName = 'Full CIF', … … 2112 1997 ) 2113 1998 self.exporttype = ['project'] 2114 1999 2115 2000 def Exporter(self,event=None): 2116 self._Exporter( self,event=event)2001 self._Exporter(event=event) 2117 2002 2118 2003 def Writer(self,hist,mode='w'): … … 2130 2015 class ExportPhaseCIF(ExportCIF): 2131 2016 '''Used to create a simple CIF with one phase. Uses exact same code as 2132 :class:`ExportCIF` except that ` self.mode` is set to "simple" in `self.InitExport`.2017 :class:`ExportCIF` except that `phaseOnly` is set for the Exporter 2133 2018 Shows up in menu as Quick CIF. 2134 2019 … … 2136 2021 ''' 2137 2022 def __init__(self,G2frame): 2138 G2IO.ExportBaseclass.__init__(self,2023 ExportCIF.__init__(self, 2139 2024 G2frame=G2frame, 2140 2025 formatName = 'Quick CIF', … … 2145 2030 # CIF-specific items 2146 2031 self.author = '' 2147 self.mode = 'simple'2148 2032 2149 2033 def Exporter(self,event=None): 2150 self._Exporter(self,event=event) 2034 # get a phase and file name 2035 # the export process starts here 2036 self.InitExport(event) 2037 # load all of the tree into a set of dicts 2038 self.loadTree() 2039 # create a dict with refined values and their uncertainties 2040 self.loadParmDict() 2041 self.multiple = False 2042 self.currentExportType = 'phase' 2043 if self.ExportSelect('ask'): return 2044 self._Exporter(event=event,phaseOnly=self.phasenam[0]) 2151 2045 2152 2046 def Writer(self,hist,phasenam,mode='w'): … … 2160 2054 self.CloseFile() 2161 2055 2162 class Export DataCIF(ExportCIF):2056 class ExportPwdrCIF(ExportCIF): 2163 2057 '''Used to create a simple CIF containing diffraction data only. Uses exact same code as 2164 :class:`ExportCIF` except that ` self.mode` is set to "simple" and `self.currentExportType`2165 is set to "single" or "powder" in `self.InitExport`. Shows up in menus as Data-onlyCIF.2058 :class:`ExportCIF` except that `histOnly` is set for the Exporter 2059 Shows up in menu as Quick CIF. 2166 2060 2167 2061 :param wx.Frame G2frame: reference to main GSAS-II frame 2168 2062 ''' 2169 2063 def __init__(self,G2frame): 2170 G2IO.ExportBaseclass.__init__(self,2064 ExportCIF.__init__(self, 2171 2065 G2frame=G2frame, 2172 2066 formatName = 'Data-only CIF', … … 2174 2068 longFormatName = 'Export data as CIF' 2175 2069 ) 2176 self.exporttype = [' single','powder']2070 self.exporttype = ['powder'] 2177 2071 # CIF-specific items 2178 2072 self.author = '' 2179 self.mode = 'simple'2180 2073 2181 2074 def Exporter(self,event=None): 2182 self._Exporter(self,event=event) 2183 2075 self.InitExport(event) 2076 # load all of the tree into a set of dicts 2077 self.currentExportType = None 2078 self.loadTree() 2079 self.currentExportType = 'powder' 2080 # create a dict with refined values and their uncertainties 2081 self.loadParmDict() 2082 self.multiple = False 2083 if self.ExportSelect( # set export parameters 2084 AskFile='ask' # get a file name/directory to save in 2085 ): return 2086 self._Exporter(event=event,histOnly=self.histnam[0]) 2087 2088 class ExportHKLCIF(ExportCIF): 2089 '''Used to create a simple CIF containing diffraction data only. Uses exact same code as 2090 :class:`ExportCIF` except that `histOnly` is set for the Exporter 2091 Shows up in menu as Quick CIF. 2092 2093 :param wx.Frame G2frame: reference to main GSAS-II frame 2094 ''' 2095 def __init__(self,G2frame): 2096 ExportCIF.__init__(self, 2097 G2frame=G2frame, 2098 formatName = 'Data-only CIF', 2099 extension='.cif', 2100 longFormatName = 'Export data as CIF' 2101 ) 2102 self.exporttype = ['single'] 2103 # CIF-specific items 2104 self.author = '' 2105 2106 def Exporter(self,event=None): 2107 self.InitExport(event) 2108 # load all of the tree into a set of dicts 2109 self.currentExportType = None 2110 self.loadTree() 2111 self.currentExportType = 'single' 2112 # create a dict with refined values and their uncertainties 2113 self.loadParmDict() 2114 self.multiple = False 2115 if self.ExportSelect( # set export parameters 2116 AskFile='ask' # get a file name/directory to save in 2117 ): return 2118 self._Exporter(event=event,histOnly=self.histnam[0]) 2119 2184 2120 #=============================================================================== 2185 2121 # misc CIF utilities
Note: See TracChangeset
for help on using the changeset viewer.