Ignore:
Timestamp:
Sep 27, 2013 6:50:08 PM (10 years ago)
Author:
toby
Message:

nearing end of CIF export

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/exports/G2cif.py

    r1067 r1068  
    1313'''
    1414
    15 # TODO: set def names for phase/hist save & load, bond pub flags,...
     15# TODO: set bond pub flags?
    1616
    1717import datetime as dt
     
    2121import cPickle
    2222import copy
     23import re
    2324import wx
    2425import wx.lib.scrolledpanel as wxscroll
     
    222223
    223224class EditCIFtemplate(wx.Dialog):
    224     '''Create a dialog for editing a CIF template
     225    '''Create a dialog for editing a CIF template. The edited information is
     226    placed in cifblk. If the CIF is saved as a file, the name of that file
     227    is saved as ``self.newfile``.
    225228   
    226229    :param wx.Frame parent: parent frame or None
     
    239242      Note that the values for each looped CIF item, such as _a,
    240243      are contained in a list, for example as cifblk["_a"]
     244     
     245    :param str defaultname: specifies the default file name to be used for
     246      saving the CIF.
    241247    '''
    242     def __init__(self,parent,cifblk,loopstructure):
     248    def __init__(self,parent,cifblk,loopstructure,defaultname):
    243249        OKbuttons = []
    244250        self.cifblk = cifblk
    245251        self.loopstructure = loopstructure
    246252        self.newfile = None
     253        self.defaultname = defaultname       
    247254        global CIFdic  # once this is loaded, keep it around
    248255        if CIFdic is None:
     
    254261        savebtn = wx.Button(self, wx.ID_CLOSE, "Save as template")
    255262        OKbuttons.append(savebtn)
    256         savebtn.Bind(wx.EVT_BUTTON,self._onClose)
     263        savebtn.Bind(wx.EVT_BUTTON,self._onSave)
    257264        OKbtn = wx.Button(self, wx.ID_OK, "Use")
    258265        OKbtn.SetDefault()
     
    277284        '''Display the dialog
    278285       
    279         :returns: True, unless Cancel has been pressed.
     286        :returns: True unless Cancel has been pressed.
    280287        '''
    281288        return (self.ShowModal() == wx.ID_OK)
    282     def _onClose(self,event):
     289    def _onSave(self,event):
    283290        'Save CIF entries in a template file'
    284291        dlg = wx.FileDialog(
    285292            self, message="Save as CIF template",
    286293            defaultDir=os.getcwd(),
    287             defaultFile="",
     294            defaultFile=self.defaultname,
    288295            wildcard="CIF (*.cif)|*.cif",
    289296            style=wx.SAVE | wx.CHANGE_DIR
     
    321328
    322329    :param dict cifdic: optional CIF dictionary definitions
     330    :param list OKbuttons: A list of wx.Button objects that should
     331      be disabled when information in the CIF is invalid
    323332    :param (other): optional keyword parameters for wx.ScrolledPanel
    324333    '''
     
    493502                    return ent
    494503        rw1 = rw.ResizeWidget(self)
    495         #print item
    496         #print dct[item]
    497504        ent = G2gd.ValidatedTxtCtrl(
    498505            rw1,dct,item,size=(100, 20),
     
    505512class CIFtemplateSelect(wx.BoxSizer):
    506513    '''Create a set of buttons to show, select and edit a CIF template
    507 
     514   
     515    :param frame: wx.Frame object of parent
     516    :param panel: wx.Panel object where widgets should be placed
    508517    :param str tmplate: one of 'publ', 'phase', or 'instrument' to determine
    509518      the type of template
     519    :param dict G2dict: GSAS-II dict where CIF should be placed. The key
     520      "CIF_template" will be used to store either a list or a string.
     521      If a list, it will contain a dict and a list defining loops. If
     522      an str, it will contain a file name.   
     523    :param function repaint: reference to a routine to be called to repaint
     524      the frame after a change has been made
     525    :param str title: A line of text to show at the top of the window
     526    :param str defaultname: specifies the default file name to be used for
     527      saving the CIF.
    510528    '''
    511     def __init__(self,frame,panel,tmplate,G2dict, repaint, title):
     529    def __init__(self,frame,panel,tmplate,G2dict, repaint, title, defaultname=''):
    512530        wx.BoxSizer.__init__(self,wx.VERTICAL)
    513531        self.cifdefs = frame
    514532        self.dict = G2dict
    515533        self.repaint = repaint
    516         self.fil = 'template_'+tmplate+'.cif'
     534        templateDefName = 'template_'+tmplate+'.cif'
    517535        self.CIF = G2dict.get("CIF_template")
     536        if defaultname:
     537            self.defaultname = defaultname.encode('ascii','replace').strip().replace(' ','_')
     538            self.defaultname = re.sub(r'[^a-zA-Z0-9_-]','',self.defaultname)
     539            self.defaultname = tmplate + "_" + self.defaultname + ".cif"
     540        else:
     541            self.defaultname = ''
     542           
    518543        txt = wx.StaticText(panel,wx.ID_ANY,title)
    519544        self.Add(txt,0,wx.ALIGN_CENTER)
     
    526551
    527552        if not self.CIF: # empty or None
    528             for pth in sys.path:
    529                 if os.path.exists(os.path.join(pth,self.fil)):
    530                     self.CIF = os.path.join(pth,self.fil)
    531                     CIFtxt = "Template: "+self.fil
     553            for pth in [os.getcwd()]+sys.path:
     554                fil = os.path.join(pth,self.defaultname)
     555                if os.path.exists(fil) and self.defaultname:
     556                    self.CIF = fil
     557                    CIFtxt = "Template: "+self.defaultname
    532558                    break
    533559            else:
    534                 print CIF+' not found in path!'
    535                 self.CIF = None
    536                 CIFtxt = "none! (No template found)"
     560                for pth in sys.path:
     561                    fil = os.path.join(pth,templateDefName)
     562                    if os.path.exists(fil):
     563                        self.CIF = fil
     564                        CIFtxt = "Template: "+templateDefName
     565                        break
     566                else:
     567                    print(self.CIF+' not found in path!')
     568                    self.CIF = None
     569                    CIFtxt = "none! (No template found)"
    537570        elif type(self.CIF) is not list and type(self.CIF) is not tuple:
    538571            if not os.path.exists(self.CIF):
     
    551584        # show str, button to select file; button to edit (if CIF defined)
    552585        but = wx.Button(panel,wx.ID_ANY,"Select Template File")
    553         but.Bind(wx.EVT_BUTTON,self.onGetTemplateFile)
     586        but.Bind(wx.EVT_BUTTON,self._onGetTemplateFile)
    554587        hbox =  wx.BoxSizer(wx.HORIZONTAL)
    555588        hbox.Add(but,0,0,2)
    556589        but = wx.Button(panel,wx.ID_ANY,"Edit Template")
    557         but.Bind(wx.EVT_BUTTON,self.onEditTemplateContents)
     590        but.Bind(wx.EVT_BUTTON,self._onEditTemplateContents)
    558591        hbox.Add(but,0,0,2)
    559592        #self.Add(hbox,0,wx.ALIGN_CENTER)
    560593        self.Add(hbox)
    561     def onGetTemplateFile(self,event):
     594    def _onGetTemplateFile(self,event):
    562595        dlg = wx.FileDialog(
    563             self.cifdefs, message="Save as CIF template",
     596            self.cifdefs, message="Read CIF template file",
    564597            defaultDir=os.getcwd(),
    565             defaultFile="",
     598            defaultFile=self.defaultname,
    566599            wildcard="CIF (*.cif)|*.cif",
    567600            style=wx.OPEN | wx.CHANGE_DIR
    568601            )
    569         if dlg.ShowModal() == wx.ID_OK:
    570             self.dict["CIF_template"] = dlg.GetPath()
    571             dlg.Destroy()           
     602        ret = dlg.ShowModal()
     603        fil = dlg.GetPath()
     604        dlg.Destroy()
     605        if ret == wx.ID_OK:
     606            import CifFile as cif # PyCifRW from James Hester
     607            try:
     608                cf = cif.ReadCif(fil)
     609                if len(cf.keys()) == 0: raise Exception,"No CIF data_ blocks found"
     610                if len(cf.keys()) != 1:
     611                    print('\nWarning: CIF has more than one block, '+fil)
     612                self.dict["CIF_template"] = fil
     613            except Exception as err:
     614                print('\nError reading CIF: '+fil)
     615                dlg = wx.MessageDialog(self.cifdefs,
     616                                   'Error reading CIF '+fil,
     617                                   'Error in CIF file',
     618                                   wx.OK)
     619                dlg.ShowModal()
     620                dlg.Destroy()
     621                print(err.message)
     622                return
    572623            self.repaint() #EditCIFDefaults()
    573         else:
    574             dlg.Destroy()
    575 
    576     def onEditTemplateContents(self,event):
     624
     625    def _onEditTemplateContents(self,event):
    577626        import CifFile as cif # PyCifRW from James Hester
    578627        if type(self.CIF) is list or  type(self.CIF) is tuple:
     
    580629        else:
    581630            dblk,loopstructure = CIF2dict(cif.ReadCif(self.CIF))
    582         dlg = EditCIFtemplate(self.cifdefs,dblk,loopstructure)
     631        dlg = EditCIFtemplate(self.cifdefs,dblk,loopstructure,self.defaultname)
    583632        val = dlg.Post()
    584633        if val:
    585634            if dlg.newfile: # results saved in file
    586635                self.dict["CIF_template"] = dlg.newfile
    587                 print 'saved'
    588636            else:
    589637                self.dict["CIF_template"] = [dlg.cifblk,dlg.loopstructure]
    590                 print 'edited'
    591638            self.repaint() #EditCIFDefaults() # note that this does a dlg.Destroy()
    592639        else:
    593             print 'cancelled'
    594640            dlg.Destroy()       
    595641
     
    599645
    600646class ExportCIF(G2IO.ExportBaseclass):
     647    '''Used to create a CIF of an entire project
     648    '''
    601649    def __init__(self,G2frame):
    602650        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
     
    700748            #WriteCIFitem('_refine_ls_matrix_type','userblocks')
    701749
     750        def GetCIF(G2dict,tmplate,defaultname=''):
     751            CIFobj = G2dict.get("CIF_template")
     752            if defaultname:
     753                defaultname = defaultname.encode('ascii','replace').strip().replace(' ','_')
     754                defaultname = re.sub(r'[^a-zA-Z0-9_-]','',defaultname)
     755                defaultname = tmplate + "_" + defaultname + ".cif"
     756            else:
     757                defaultname = ''
     758            templateDefName = 'template_'+tmplate+'.cif'
     759            if not CIFobj: # copying a template
     760                for pth in [os.getcwd()]+sys.path:
     761                    fil = os.path.join(pth,defaultname)
     762                    if os.path.exists(fil) and defaultname: break
     763                else:
     764                    for pth in sys.path:
     765                        fil = os.path.join(pth,templateDefName)
     766                        if os.path.exists(fil): break
     767                    else:
     768                        print(CIFobj+' not found in path!')
     769                        return
     770                fp = open(fil,'r')
     771                txt = fp.read()
     772                fp.close()
     773            elif type(CIFobj) is not list and type(CIFobj) is not tuple:
     774                if not os.path.exists(CIFobj):
     775                    print("Error: template file has disappeared:"+CIFobj)
     776                    return
     777                fp = open(CIFobj,'r')
     778                txt = fp.read()
     779                fp.close()
     780            else:
     781                txt = dict2CIF(CIFobj[0],CIFobj[1]).WriteOut()
     782            # remove the PyCifRW header, if present
     783            #if txt.find('PyCifRW') > -1 and txt.find('data_') > -1:
     784            txt = "# GSAS-II edited template follows "+txt[txt.index("data_")+5:]
     785            #txt = txt.replace('data_','#')
     786            print '***** Template ********'
     787            print txt
     788            WriteCIFitem(txt)
     789
    702790        def WritePubTemplate():
    703             '''TODO: insert the publication template ``template_publ.cif`` or some modified
    704             version for this project. Store this in the GPX file?
     791            '''insert the publication template ``template_publ.cif`` or a modified
     792            version
    705793            '''
    706             print getCallerDocString()
    707 
    708         def WritePhaseTemplate():
    709             '''TODO: insert the phase template ``template_phase.cif`` or some modified
     794            GetCIF(self.OverallParms['Controls'],'publ')
     795
     796        def WritePhaseTemplate(phasenam):
     797            '''insert the phase template ``template_phase.cif`` or a modified
    710798            version for this project
    711799            '''
    712             print getCallerDocString()
    713 
    714         def WritePowderTemplate():
     800            GetCIF(self.Phases[phasenam]['General'],'phase',phasenam)
     801
     802        def WritePowderTemplate(hist):
    715803            '''TODO: insert the phase template ``template_instrument.cif`` or some modified
    716804            version for this project
    717805            '''
    718             print getCallerDocString()
    719 
    720         def WriteSnglXtalTemplate():
     806            histblk = self.Histograms[hist]["Sample Parameters"]
     807            GetCIF(histblk,'powder',histblk['InstrName'])
     808
     809        def WriteSnglXtalTemplate(hist):
    721810            '''TODO: insert the single-crystal histogram template
    722811            for this project
    723812            '''
    724             print getCallerDocString()
     813            histblk = self.Histograms[hist]["Instrument Parameters"][0]
     814            GetCIF(histblk,'single',histblk['InstrName'])
    725815
    726816        def FormatSH(phasenam):
     
    11351225                mult = at[cmult]
    11361226                if not massDict.get(at[ct]):
    1137                     print 'No mass found for atom type '+at[ct]
    1138                     print 'Will not compute cell contents for phase '+phasenam
     1227                    print('Error: No mass found for atom type '+at[ct])
     1228                    print('Will not compute cell contents for phase '+phasenam)
    11391229                    return
    11401230                cellmass += massDict[at[ct]]*mult*fval
     
    12461336                AtomLabels,DistArray,AngArray = G2stMn.RetDistAngle(DisAglCtls,DisAglData)
    12471337            except KeyError:        # inside DistAngle for missing atom types in DisAglCtls
    1248                 print '**** ERROR - try again but do "Reset" to fill in missing atom types ****'
     1338                print('**** ERROR - try again but do "Reset" to fill in missing atom types ****')
    12491339                   
    12501340            # loop over interatomic distances for this phase
     
    13521442                        blockid = datablockidDict.get(hist)
    13531443                        if not blockid:
    1354                             print "Internal error: no block for data. Phase "+str(
    1355                                 phasenam)+" histogram "+str(hist)
     1444                            print("Internal error: no block for data. Phase "+str(
     1445                                phasenam)+" histogram "+str(hist))
    13561446                            histlist = []
    13571447                            break
     
    15551645                for ref in histblk['Reflection Lists'][phasenam]:
    15561646                    if DEBUG:
    1557                         print 'DEBUG: skip reflection list'
     1647                        print('DEBUG: skipping reflection list')
    15581648                        break
    15591649                    if hklmin is None:
     
    16311721
    16321722            if DEBUG:
    1633                 print 'DEBUG: skip profile list'
     1723                print('DEBUG: skipping profile list')
    16341724            else:   
    16351725                for x,yobs,yw,ycalc,ybkg in zip(histblk['Data'][0],
     
    17551845            self.cifdefs.SetTitle('Edit CIF settings')
    17561846            vbox = wx.BoxSizer(wx.VERTICAL)
     1847            but = wx.Button(self.cifdefs, wx.ID_ANY,'Edit CIF Author')
     1848            but.Bind(wx.EVT_BUTTON,EditAuthor)
     1849            vbox.Add(but,0,wx.ALIGN_CENTER,3)
     1850            but = wx.Button(self.cifdefs, wx.ID_ANY,'Edit Instrument Name(s)')
     1851            but.Bind(wx.EVT_BUTTON,EditInstNames)
     1852            vbox.Add(but,0,wx.ALIGN_CENTER,3)
    17571853            cpnl = wxscroll.ScrolledPanel(self.cifdefs,size=(300,300))
    17581854            cbox = wx.BoxSizer(wx.VERTICAL)
    1759             but = wx.Button(cpnl, wx.ID_ANY,'Edit CIF Author')
    1760             but.Bind(wx.EVT_BUTTON,EditAuthor)
    1761             cbox.Add(but,0,wx.ALIGN_CENTER,3)
    1762             but = wx.Button(cpnl, wx.ID_ANY,'Edit Instrument Name(s)')
    1763             but.Bind(wx.EVT_BUTTON,EditInstNames)
    1764             cbox.Add(but,0,wx.ALIGN_CENTER,3)
    17651855            G2gd.HorizontalLine(cbox,cpnl)         
    17661856            cbox.Add(
     
    17791869                                      cpnl,'phase',phasedict['General'],
    17801870                                      EditCIFDefaults,
    1781                                       title),
     1871                                      title,
     1872                                      phasenam),
    17821873                    0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL)
    17831874                cpnl.SetSizer(cbox)
     
    17971888                                      cpnl,'powder',histblk["Sample Parameters"],
    17981889                                      EditCIFDefaults,
    1799                                       title),
     1890                                      title,
     1891                                      histblk["Sample Parameters"]['InstrName']),
    18001892                    0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL)
    18011893                cpnl.SetSizer(cbox)
     
    18091901                                      cpnl,'single',histblk["Instrument Parameters"][0],
    18101902                                      EditCIFDefaults,
    1811                                       title),
     1903                                      title,
     1904                                      histblk["Instrument Parameters"][0]['InstrName']),
    18121905                    0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL)
    18131906                cpnl.SetSizer(cbox)
     
    19902083                WritePubTemplate()
    19912084                WriteOverall()
    1992                 WritePhaseTemplate()
     2085                WritePhaseTemplate(phasenam)
    19932086            # report the phase info
    19942087            WritePhaseInfo(phasenam)
     
    20072100                    FormatInstProfile(histblk["Instrument Parameters"],histblk['hId'])
    20082101                    +'\n'+FormatPhaseProfile(phasenam))
    2009                 WritePowderTemplate()
     2102                WritePowderTemplate(hist)
    20102103                WritePowderData(hist)
    20112104            elif hist.startswith("HKLF") and not self.quickmode:
    2012                 WriteSnglXtalTemplate()
     2105                WriteSnglXtalTemplate(hist)
    20132106                WriteSingleXtalData(hist)
    20142107        else:
     
    20732166                i = self.Phases[phasenam]['pId']
    20742167                WriteCIFitem('\ndata_'+self.CIFname+"_phase_"+str(i))
    2075                 print "debug, processing ",phasenam
    20762168                WriteCIFitem('# Information for phase '+str(i))
    20772169                WriteCIFitem('_pd_block_id',datablockidDict[phasenam])
    20782170                # report the phase
    2079                 WritePhaseTemplate()
     2171                WritePhaseTemplate(phasenam)
    20802172                WritePhaseInfo(phasenam)
    20812173                # preferred orientation
     
    21062198                    WriteCIFitem('# Information for histogram '+str(i)+': '+hist)
    21072199                    WriteCIFitem('_pd_block_id',datablockidDict[hist])
    2108                     WritePowderTemplate()
     2200                    WritePowderTemplate(hist)
    21092201                    WritePowderData(hist)
    21102202            for i in sorted(self.xtalDict.keys()):
     
    21162208                    WriteCIFitem('# Information for histogram '+str(i)+': '+hist)
    21172209                    WriteCIFitem('_pd_block_id',datablockidDict[hist])
    2118                     WriteSnglXtalTemplate()
     2210                    WriteSnglXtalTemplate(hist)
    21192211                    WriteSingleXtalData(hist)
    21202212
Note: See TracChangeset for help on using the changeset viewer.