Changeset 1067


Ignore:
Timestamp:
Sep 26, 2013 3:55:49 PM (8 years ago)
Author:
toby
Message:

CIF updates

Location:
trunk
Files:
8 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIgrid.py

    r1059 r1067  
    339339            self.Refresh()
    340340
    341     def ShowStringValidity(self,previousInvalid=None):
     341    def ShowStringValidity(self,previousInvalid=True):
    342342        '''Check if input is valid. Anytime the input is
    343343        invalid, call self.OKcontrol (if defined) because it is fast.
  • trunk/exports/G2cif.py

    r1057 r1067  
    1313'''
    1414
    15 # TODO: need a mechanism for editing of instrument names, bond pub flags, templates,...
     15# TODO: set def names for phase/hist save & load, bond pub flags,...
    1616
    1717import datetime as dt
     
    1919import sys
    2020import numpy as np
     21import cPickle
     22import copy
    2123import wx
     24import wx.lib.scrolledpanel as wxscroll
     25import wx.lib.resizewidget as rw
    2226import GSASIIpath
    2327GSASIIpath.SetVersionNumber("$Revision: 1006 $")
     
    4145DEBUG = False    #True to skip printing of reflection/powder profile lists
    4246
     47CIFdic = None
     48
    4349def getCallerDocString(): # for development
    4450    "Return the calling function's doc string"
     
    4955    else:
    5056        return '?'
     57
     58#===============================================================================
     59# misc CIF utilities
     60#===============================================================================
     61def PickleCIFdict(fil):
     62    '''Loads a CIF dictionary, cherry picks out the items needed
     63    by local code and sticks them into a python dict and writes
     64    that dict out as a cPickle file for later reuse.
     65    If the write fails a warning message is printed,
     66    but no exception occurs.
     67
     68    :param str fil: file name of CIF dictionary, will usually end
     69      in .dic
     70    :returns: the dict with the definitions 
     71    '''
     72    import CifFile as cif # PyCifRW from James Hester
     73    cifdic = {}
     74    dictobj = cif.CifDic(fil)
     75    if DEBUG: print('loaded '+str(fil))
     76    for item in dictobj.keys():
     77        cifdic[item] = {}
     78        for j in (
     79            '_definition','_type',
     80            '_enumeration',
     81            '_enumeration_detail',
     82            '_enumeration_range'):
     83            if dictobj[item].get(j):
     84                cifdic[item][j] = dictobj[item][j]
     85    try:
     86        fil = os.path.splitext(fil)[0]+'.cpickle'
     87        fp = open(fil,'w')
     88        cPickle.dump(cifdic,fp)
     89        fp.close()
     90        if DEBUG: print('wrote '+str(fil))
     91    except:
     92        print ('Unable to write '+str(fil))
     93    return cifdic
     94
     95def LoadCIFdic():
     96    '''Create a composite core+powder CIF lookup dict containing
     97    information about all items in the CIF dictionaries, loading
     98    pickled files if possible. The routine looks for files
     99    named cif_core.cpickle and cif_pd.cpickle in every
     100    directory in the path and if they are not found, files
     101    cif_core.dic and/or cif_pd.dic are read.
     102
     103    :returns: the dict with the definitions 
     104    '''
     105    cifdic = {}
     106    for ftyp in "cif_core","cif_pd":
     107        for loc in sys.path:
     108            fil = os.path.join(loc,ftyp+".cpickle")
     109            if not os.path.exists(fil): continue
     110            fp = open(fil,'r')
     111            try:
     112                cifdic.update(cPickle.load(fp))
     113                if DEBUG: print('reloaded '+str(fil))
     114                break
     115            finally:
     116                fp.close()
     117        else:
     118            for loc in sys.path:
     119                fil = os.path.join(loc,ftyp+".dic")
     120                if not os.path.exists(fil): continue
     121                #try:
     122                if True:
     123                    cifdic.update(PickleCIFdict(fil))
     124                    break
     125                #except:
     126                #    pass
     127            else:
     128                print('Could not load '+ftyp+' dictionary')
     129    return cifdic
     130
     131class CIFdefHelp(wx.Button):
     132    '''Create a help button that displays help information on
     133    the current data item
     134
     135    :param parent: the panel which will be the parent of the button
     136    :param str msg: the help text to be displayed
     137    :param wx.Dialog helpwin: Frame for CIF editing dialog
     138    :param wx.TextCtrl helptxt: TextCtrl where help text is placed
     139    '''
     140    def __init__(self,parent,msg,helpwin,helptxt):
     141        wx.Button.__init__(self,parent,wx.ID_HELP)
     142        self.Bind(wx.EVT_BUTTON,self._onPress)
     143        self.msg=msg
     144        self.parent = parent
     145        #self.helpwin = self.parent.helpwin
     146        self.helpwin = helpwin
     147        self.helptxt = helptxt
     148    def _onPress(self,event):
     149        'Respond to a button press by displaying the requested text'
     150        try:
     151            #helptxt = self.helptxt
     152            ow,oh = self.helptxt.GetSize()
     153            self.helptxt.SetLabel(self.msg)
     154            w,h = self.helptxt.GetSize()
     155            if h > oh:
     156                self.helpwin.GetSizer().Fit(self.helpwin)
     157        except: # error posting help, ignore
     158            return
     159
     160def CIF2dict(cf):
     161    '''copy the contents of a CIF out from a PyCifRW block object
     162    into a dict
     163
     164    :returns: cifblk, loopstructure where cifblk is a dict with
     165      CIF items and loopstructure is a list of lists that defines
     166      which items are in which loops.
     167    '''
     168    blk = cf.keys()[0] # assume templates are a single CIF block, use the 1st
     169    loopstructure = cf[blk].loopnames()[:] # copy over the list of loop contents
     170    dblk = {}
     171    for item in cf[blk].keys(): # make a copy of all the items in the block
     172        dblk[item] = cf[blk][item]
     173    return dblk,loopstructure
     174
     175def dict2CIF(dblk,loopstructure,blockname='Template'):
     176    '''Create a PyCifRW CIF object containing a single CIF
     177    block object from a dict and loop structure list.
     178
     179    :param dblk: a dict containing values for each CIF item
     180    :param list loopstructure: a list of lists containing the contents of
     181      each loop, as an example::
     182
     183         [ ["_a","_b"], ["_c"], ["_d_1","_d_2","_d_3"]]
     184
     185      this describes a CIF with this type of structure::
     186
     187        loop_ _a _b <a1> <b1> <a2> ...
     188        loop_ _c <c1> <c2>...
     189        loop _d_1 _d_2 _d_3 ...
     190
     191      Note that the values for each looped CIF item, such as _a,
     192      are contained in a list, for example as cifblk["_a"]
     193
     194    :param str blockname: an optional name for the CIF block.
     195      Defaults to 'Template'
     196
     197    :returns: the newly created PyCifRW CIF object
     198    '''
     199
     200    import CifFile as cif # PyCifRW from James Hester
     201    # compile a 'list' of items in loops
     202    loopnames = set()
     203    for i in loopstructure:
     204        loopnames |= set(i)
     205    # create a new block
     206    newblk = cif.CifBlock()
     207    # add the looped items
     208    for keys in loopstructure:
     209        vals = []
     210        for key in keys:
     211            vals.append(dblk[key])
     212        newblk.AddCifItem(([keys],[vals]))
     213    # add the non-looped items
     214    for item in dblk:
     215        if item in loopnames: continue
     216        newblk[item] = dblk[item]
     217    # create a CIF and add the block
     218    newcf = cif.CifFile()
     219    newcf[blockname] = newblk   
     220    return newcf
     221
     222
     223class EditCIFtemplate(wx.Dialog):
     224    '''Create a dialog for editing a CIF template
     225   
     226    :param wx.Frame parent: parent frame or None
     227    :param cifblk: dict or PyCifRW block containing values for each CIF item
     228    :param list loopstructure: a list of lists containing the contents of
     229      each loop, as an example::
     230
     231         [ ["_a","_b"], ["_c"], ["_d_1","_d_2","_d_3"]]
     232
     233      this describes a CIF with this type of structure::
     234
     235        loop_ _a _b <a1> <b1> <a2> ...
     236        loop_ _c <c1> <c2>...
     237        loop _d_1 _d_2 _d_3 ...
     238
     239      Note that the values for each looped CIF item, such as _a,
     240      are contained in a list, for example as cifblk["_a"]
     241    '''
     242    def __init__(self,parent,cifblk,loopstructure):
     243        OKbuttons = []
     244        self.cifblk = cifblk
     245        self.loopstructure = loopstructure
     246        self.newfile = None
     247        global CIFdic  # once this is loaded, keep it around
     248        if CIFdic is None:
     249            CIFdic = LoadCIFdic()
     250        wx.Dialog.__init__(self,parent,style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
     251
     252        # define widgets that will be needed during panel creation
     253        self.helptxt = wx.StaticText(self,wx.ID_ANY,"")
     254        savebtn = wx.Button(self, wx.ID_CLOSE, "Save as template")
     255        OKbuttons.append(savebtn)
     256        savebtn.Bind(wx.EVT_BUTTON,self._onClose)
     257        OKbtn = wx.Button(self, wx.ID_OK, "Use")
     258        OKbtn.SetDefault()
     259        OKbuttons.append(OKbtn)
     260
     261        self.SetTitle('Edit items in CIF template')
     262        vbox = wx.BoxSizer(wx.VERTICAL)
     263        cpnl = EditCIFpanel(self,cifblk,loopstructure,CIFdic,OKbuttons,size=(300,300))
     264        vbox.Add(cpnl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 0)
     265        G2gd.HorizontalLine(vbox,self)
     266        vbox.Add(self.helptxt, 0, wx.EXPAND|wx.ALL, 5)
     267        G2gd.HorizontalLine(vbox,self)
     268        btnsizer = wx.BoxSizer(wx.HORIZONTAL)
     269        btn = wx.Button(self, wx.ID_CANCEL)
     270        btnsizer.Add(btn,0,wx.ALIGN_CENTER|wx.ALL)
     271        btnsizer.Add(savebtn,0,wx.ALIGN_CENTER|wx.ALL)
     272        btnsizer.Add(OKbtn,0,wx.ALIGN_CENTER|wx.ALL)
     273        vbox.Add(btnsizer, 0, wx.ALIGN_CENTER|wx.ALL, 5)
     274        self.SetSizer(vbox)
     275        vbox.Fit(self)
     276    def Post(self):
     277        '''Display the dialog
     278       
     279        :returns: True, unless Cancel has been pressed.
     280        '''
     281        return (self.ShowModal() == wx.ID_OK)
     282    def _onClose(self,event):
     283        'Save CIF entries in a template file'
     284        dlg = wx.FileDialog(
     285            self, message="Save as CIF template",
     286            defaultDir=os.getcwd(),
     287            defaultFile="",
     288            wildcard="CIF (*.cif)|*.cif",
     289            style=wx.SAVE | wx.CHANGE_DIR
     290            )
     291        val = (dlg.ShowModal() == wx.ID_OK)
     292        fil = dlg.GetPath()
     293        dlg.Destroy()
     294        if val: # ignore a Cancel button
     295            fil = os.path.splitext(fil)[0]+'.cif' # force extension
     296            fp = open(fil,'w')
     297            newcf = dict2CIF(self.cifblk,self.loopstructure)
     298            fp.write(newcf.WriteOut())
     299            fp.close()
     300            self.newfile = fil
     301            self.EndModal(wx.ID_OK)
     302
     303class EditCIFpanel(wxscroll.ScrolledPanel):
     304    '''Creates a scrolled panel for editing CIF template items
     305
     306    :param wx.Frame parent: parent frame where panel will be placed
     307    :param cifblk: dict or PyCifRW block containing values for each CIF item
     308    :param list loopstructure: a list of lists containing the contents of
     309      each loop, as an example::
     310
     311         [ ["_a","_b"], ["_c"], ["_d_1","_d_2","_d_3"]]
     312
     313      this describes a CIF with this type of structure::
     314
     315        loop_ _a _b <a1> <b1> <a2> ...
     316        loop_ _c <c1> <c2>...
     317        loop _d_1 _d_2 _d_3 ...
     318
     319      Note that the values for each looped CIF item, such as _a,
     320      are contained in a list, for example as cifblk["_a"]
     321
     322    :param dict cifdic: optional CIF dictionary definitions
     323    :param (other): optional keyword parameters for wx.ScrolledPanel
     324    '''
     325    def __init__(self, parent, cifblk, loopstructure, cifdic={}, OKbuttons=[], **kw):
     326        self.parent = parent
     327        wxscroll.ScrolledPanel.__init__(self, parent, wx.ID_ANY, **kw)
     328        self.vbox = None
     329        self.AddDict = None
     330        self.cifdic = cifdic
     331        self.cifblk = cifblk
     332        self.loops = loopstructure
     333        self.parent = parent
     334        self.LayoutCalled = False
     335        self.parentOKbuttons = OKbuttons
     336        self.ValidatedControlsList = []
     337        self._fill()
     338    def _fill(self):
     339        'Fill the scrolled panel with widgets for each CIF item'
     340        wx.BeginBusyCursor()
     341        self.AddDict = {}
     342        self.ValidatedControlsList = []
     343        # delete any only contents
     344        if self.vbox:
     345            self.vbox.DeleteWindows()
     346            self.vbox = None
     347            self.Update()
     348        vbox = wx.BoxSizer(wx.VERTICAL)
     349        self.vbox = vbox
     350        # compile a 'list' of items in loops
     351        loopnames = set()
     352        for i in self.loops:
     353            loopnames |= set(i)
     354        # post the looped CIF items
     355        for lnum,lp in enumerate(self.loops):
     356            hbox = wx.BoxSizer(wx.HORIZONTAL)
     357            hbox.Add(wx.StaticText(self,wx.ID_ANY,'Loop '+str(lnum+1)))
     358            vbox.Add(hbox)
     359            but = wx.Button(self,wx.ID_ANY,"Add row")
     360            self.AddDict[but]=lnum
     361           
     362            hbox.Add(but)           
     363            but.Bind(wx.EVT_BUTTON,self.OnAddRow)
     364            fbox = wx.GridBagSizer(0, 0)
     365            vbox.Add(fbox)
     366            rows = 0
     367            for i,item in enumerate(lp):
     368                txt = wx.StaticText(self,wx.ID_ANY,item+"  ")
     369                fbox.Add(txt,(0,i+1))
     370                if self.cifdic.get(item):
     371                    df = self.cifdic[item].get('_definition')
     372                    if df:
     373                        txt.SetToolTipString(G2IO.trim(df))
     374                        but = CIFdefHelp(self,
     375                                         "Definition for "+item+":\n\n"+G2IO.trim(df),
     376                                         self.parent,
     377                                         self.parent.helptxt)
     378                        fbox.Add(but,(1,i+1),flag=wx.ALIGN_CENTER)
     379                for j,val in enumerate(self.cifblk[item]):
     380                    ent = self.CIFEntryWidget(self.cifblk[item],j,item)
     381                    fbox.Add(ent,(j+2,i+1),flag=wx.EXPAND|wx.ALL)
     382                rows = max(rows,len(self.cifblk[item]))
     383            for i in range(rows):
     384                txt = wx.StaticText(self,wx.ID_ANY,str(i+1))
     385                fbox.Add(txt,(i+2,0))
     386            line = wx.StaticLine(self,wx.ID_ANY, size=(-1,3), style=wx.LI_HORIZONTAL)
     387            vbox.Add(line, 0, wx.EXPAND|wx.ALIGN_CENTER|wx.ALL, 10)
     388               
     389        # post the non-looped CIF items
     390        for item in sorted(self.cifblk.keys()):
     391            if item not in loopnames:
     392                hbox = wx.BoxSizer(wx.HORIZONTAL)
     393                vbox.Add(hbox)
     394                txt = wx.StaticText(self,wx.ID_ANY,item)
     395                hbox.Add(txt)
     396                if self.cifdic.get(item):
     397                    df = self.cifdic[item].get('_definition')
     398                    if df:
     399                        txt.SetToolTipString(G2IO.trim(df))
     400                        but = CIFdefHelp(self,
     401                                         "Definition for "+item+":\n\n"+G2IO.trim(df),
     402                                         self.parent,
     403                                         self.parent.helptxt)
     404                        hbox.Add(but,0,wx.ALL,2)
     405                ent = self.CIFEntryWidget(self.cifblk,item,item)
     406                hbox.Add(ent)
     407        self.SetSizer(vbox)
     408        #vbox.Fit(self.parent)
     409        self.SetAutoLayout(1)
     410        self.SetupScrolling()
     411        self.Bind(rw.EVT_RW_LAYOUT_NEEDED, self.OnLayoutNeeded)
     412        self.Layout()
     413        wx.EndBusyCursor()
     414    def OnLayoutNeeded(self,event):
     415        '''Called when an update of the panel layout is needed. Calls
     416        self.DoLayout after the current operations are complete using
     417        CallAfter. This is called only once, according to flag
     418        self.LayoutCalled, which is cleared in self.DoLayout.
     419        '''
     420        if self.LayoutCalled: return # call already queued
     421        wx.CallAfter(self.DoLayout) # queue a call
     422        self.LayoutCalled = True
     423    def DoLayout(self):
     424        '''Update the Layout and scroll bars for the Panel. Clears
     425        self.LayoutCalled so that next change to panel can
     426        request a new update
     427        '''
     428        wx.BeginBusyCursor()
     429        self.Layout()
     430        self.SetupScrolling()
     431        wx.EndBusyCursor()
     432        self.LayoutCalled = False
     433    def OnAddRow(self,event):
     434        'add a row to a loop'
     435        lnum = self.AddDict.get(event.GetEventObject())
     436        if lnum is None: return
     437        for item in self.loops[lnum]:
     438            self.cifblk[item].append('?')
     439        self._fill()
     440
     441    def ControlOKButton(self,setvalue):
     442        '''Enable or Disable the OK button(s) for the dialog. Note that this is
     443        passed into the ValidatedTxtCtrl for use by validators.
     444
     445        :param bool setvalue: if True, all entries in the dialog are
     446          checked for validity. The first invalid control triggers
     447          disabling of buttons.
     448          If False then the OK button(s) are disabled with no checking
     449          of the invalid flag for each control.
     450        '''
     451        if setvalue: # turn button on, do only if all controls show as valid
     452            for ctrl in self.ValidatedControlsList:
     453                if ctrl.invalid:
     454                    for btn in self.parentOKbuttons:
     455                        btn.Disable()
     456                    return
     457            else:
     458                for btn in self.parentOKbuttons:
     459                    btn.Enable()
     460        else:
     461            for btn in self.parentOKbuttons:
     462                btn.Disable()
     463       
     464    def CIFEntryWidget(self,dct,item,dataname):
     465        '''Create an entry widget for a CIF item. Use a validated entry for numb values
     466        where int is required when limits are integers and floats otherwise.
     467        At present this does not allow entry of the special CIF values of "." and "?" for
     468        numerical values and highlights them as invalid.
     469        Use a selection widget when there are specific enumerated values for a string.       
     470        '''
     471        if self.cifdic.get(dataname):
     472            if self.cifdic[dataname].get('_enumeration'):
     473                values = ['?']+self.cifdic[dataname]['_enumeration']
     474                choices = ['undefined']
     475                for i in self.cifdic[dataname].get('_enumeration_detail',values):
     476                    choices.append(G2IO.trim(i))
     477                ent = G2gd.EnumSelector(self, dct, item, choices, values, size=(200, -1))
     478                return ent
     479            if self.cifdic[dataname].get('_type') == 'numb':
     480                mn = None
     481                mx = None
     482                hint = int
     483                if self.cifdic[dataname].get('_enumeration_range'):
     484                    rng = self.cifdic[dataname]['_enumeration_range'].split(':')
     485                    if '.' in rng[0] or '.' in rng[1]: hint = float
     486                    if rng[0]: mn = hint(rng[0])
     487                    if rng[1]: mx = hint(rng[1])
     488                    ent = G2gd.ValidatedTxtCtrl(
     489                        self,dct,item,typeHint=hint,min=mn,max=mx,
     490                        CIFinput=True,
     491                        OKcontrol=self.ControlOKButton)
     492                    self.ValidatedControlsList.append(ent)
     493                    return ent
     494        rw1 = rw.ResizeWidget(self)
     495        #print item
     496        #print dct[item]
     497        ent = G2gd.ValidatedTxtCtrl(
     498            rw1,dct,item,size=(100, 20),
     499            style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER,
     500            CIFinput=True,
     501            OKcontrol=self.ControlOKButton)
     502        self.ValidatedControlsList.append(ent)
     503        return rw1
     504
     505class CIFtemplateSelect(wx.BoxSizer):
     506    '''Create a set of buttons to show, select and edit a CIF template
     507
     508    :param str tmplate: one of 'publ', 'phase', or 'instrument' to determine
     509      the type of template
     510    '''
     511    def __init__(self,frame,panel,tmplate,G2dict, repaint, title):
     512        wx.BoxSizer.__init__(self,wx.VERTICAL)
     513        self.cifdefs = frame
     514        self.dict = G2dict
     515        self.repaint = repaint
     516        self.fil = 'template_'+tmplate+'.cif'
     517        self.CIF = G2dict.get("CIF_template")
     518        txt = wx.StaticText(panel,wx.ID_ANY,title)
     519        self.Add(txt,0,wx.ALIGN_CENTER)
     520        # change font on title
     521        txtfnt = txt.GetFont()
     522        txtfnt.SetWeight(wx.BOLD)
     523        txtfnt.SetPointSize(2+txtfnt.GetPointSize())
     524        txt.SetFont(txtfnt)
     525        self.Add((-1,3))
     526
     527        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
     532                    break
     533            else:
     534                print CIF+' not found in path!'
     535                self.CIF = None
     536                CIFtxt = "none! (No template found)"
     537        elif type(self.CIF) is not list and type(self.CIF) is not tuple:
     538            if not os.path.exists(self.CIF):
     539                print("Error: template file has disappeared:"+self.CIF)
     540                self.CIF = None
     541                CIFtxt = "none! (file not found)"
     542            else:
     543                if len(self.CIF) < 40:
     544                    CIFtxt = "File: "+self.CIF
     545                else:
     546                    CIFtxt = "File: ..."+self.CIF[-40:]
     547        else:
     548            CIFtxt = "Template is customized"
     549        # show template source
     550        self.Add(wx.StaticText(panel,wx.ID_ANY,CIFtxt))
     551        # show str, button to select file; button to edit (if CIF defined)
     552        but = wx.Button(panel,wx.ID_ANY,"Select Template File")
     553        but.Bind(wx.EVT_BUTTON,self.onGetTemplateFile)
     554        hbox =  wx.BoxSizer(wx.HORIZONTAL)
     555        hbox.Add(but,0,0,2)
     556        but = wx.Button(panel,wx.ID_ANY,"Edit Template")
     557        but.Bind(wx.EVT_BUTTON,self.onEditTemplateContents)
     558        hbox.Add(but,0,0,2)
     559        #self.Add(hbox,0,wx.ALIGN_CENTER)
     560        self.Add(hbox)
     561    def onGetTemplateFile(self,event):
     562        dlg = wx.FileDialog(
     563            self.cifdefs, message="Save as CIF template",
     564            defaultDir=os.getcwd(),
     565            defaultFile="",
     566            wildcard="CIF (*.cif)|*.cif",
     567            style=wx.OPEN | wx.CHANGE_DIR
     568            )
     569        if dlg.ShowModal() == wx.ID_OK:
     570            self.dict["CIF_template"] = dlg.GetPath()
     571            dlg.Destroy()           
     572            self.repaint() #EditCIFDefaults()
     573        else:
     574            dlg.Destroy()
     575
     576    def onEditTemplateContents(self,event):
     577        import CifFile as cif # PyCifRW from James Hester
     578        if type(self.CIF) is list or  type(self.CIF) is tuple:
     579            dblk,loopstructure = copy.deepcopy(self.CIF) # don't modify original
     580        else:
     581            dblk,loopstructure = CIF2dict(cif.ReadCif(self.CIF))
     582        dlg = EditCIFtemplate(self.cifdefs,dblk,loopstructure)
     583        val = dlg.Post()
     584        if val:
     585            if dlg.newfile: # results saved in file
     586                self.dict["CIF_template"] = dlg.newfile
     587                print 'saved'
     588            else:
     589                self.dict["CIF_template"] = [dlg.cifblk,dlg.loopstructure]
     590                print 'edited'
     591            self.repaint() #EditCIFDefaults() # note that this does a dlg.Destroy()
     592        else:
     593            print 'cancelled'
     594            dlg.Destroy()       
     595
     596#===============================================================================
     597# end of misc CIF utilities
     598#===============================================================================
    51599
    52600class ExportCIF(G2IO.ExportBaseclass):
     
    67615        '''
    68616   
    69         # ===== define functions for export method =======================================
     617# ===== define functions for export method =======================================
    70618        def openCIF(filnam):
    71619            if DEBUG:
     
    11661714                pass
    11671715            return True
    1168         def EditInstNames(event=None,msg=''):
     1716        def EditInstNames(event=None):
    11691717            'Provide a dialog for editing instrument names'
    11701718            dictlist = []
     
    11901738                postlbl=lbllist,
    11911739                title='Instrument names',
    1192                 header="Edit instrument names. Note that a non-blank\nname is required for all histograms"+msg)
    1193         def EditCIFDefaults(parent):
     1740                header="Edit instrument names. Note that a non-blank\nname is required for all histograms",
     1741                CopyButton=True)
     1742           
     1743        def EditRanges(event):
     1744            but = event.GetEventObject()
     1745            phasedict = but.phasedict
     1746            dlg = G2gd.DisAglDialog(self.G2frame,{},phasedict['General'])
     1747            if dlg.ShowModal() == wx.ID_OK:
     1748                phasedict['General']['DisAglCtls'] = dlg.GetData()
     1749            dlg.Destroy()
     1750           
     1751        def EditCIFDefaults():
     1752            'Fills the CIF Defaults window'
    11941753            import wx.lib.scrolledpanel as wxscroll
    1195             cfrm = wx.Dialog(parent,style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
    1196             cfrm.SetTitle('child')
     1754            self.cifdefs.DestroyChildren()
     1755            self.cifdefs.SetTitle('Edit CIF settings')
    11971756            vbox = wx.BoxSizer(wx.VERTICAL)
    1198             cpnl = wxscroll.ScrolledPanel(cfrm,size=(300,300))
     1757            cpnl = wxscroll.ScrolledPanel(self.cifdefs,size=(300,300))
    11991758            cbox = wx.BoxSizer(wx.VERTICAL)
    12001759            but = wx.Button(cpnl, wx.ID_ANY,'Edit CIF Author')
     
    12041763            but.Bind(wx.EVT_BUTTON,EditInstNames)
    12051764            cbox.Add(but,0,wx.ALIGN_CENTER,3)
    1206 
    1207             cpnl.SetSizer(cbox)
     1765            G2gd.HorizontalLine(cbox,cpnl)         
     1766            cbox.Add(
     1767                CIFtemplateSelect(self.cifdefs,
     1768                                  cpnl,'publ',self.OverallParms['Controls'],
     1769                                  EditCIFDefaults,
     1770                                  "Publication (overall) template",
     1771                                  ),
     1772                0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL)
     1773            for phasenam in sorted(self.Phases.keys()):
     1774                G2gd.HorizontalLine(cbox,cpnl)         
     1775                title = 'Phase '+phasenam
     1776                phasedict = self.Phases[phasenam] # pointer to current phase info           
     1777                cbox.Add(
     1778                    CIFtemplateSelect(self.cifdefs,
     1779                                      cpnl,'phase',phasedict['General'],
     1780                                      EditCIFDefaults,
     1781                                      title),
     1782                    0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL)
     1783                cpnl.SetSizer(cbox)
     1784                but = wx.Button(cpnl, wx.ID_ANY,'Edit distance/angle ranges')
     1785                #cbox.Add(but,0,wx.ALIGN_CENTER,3)
     1786                cbox.Add((-1,2))
     1787                cbox.Add(but,0,wx.ALIGN_LEFT,0)
     1788                but.phasedict = self.Phases[phasenam]  # set a pointer to current phase info     
     1789                but.Bind(wx.EVT_BUTTON,EditRanges)     # phase bond/angle ranges
     1790            for i in sorted(self.powderDict.keys()):
     1791                G2gd.HorizontalLine(cbox,cpnl)         
     1792                hist = self.powderDict[i]
     1793                histblk = self.Histograms[hist]
     1794                title = 'Powder dataset '+hist[5:]
     1795                cbox.Add(
     1796                    CIFtemplateSelect(self.cifdefs,
     1797                                      cpnl,'powder',histblk["Sample Parameters"],
     1798                                      EditCIFDefaults,
     1799                                      title),
     1800                    0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL)
     1801                cpnl.SetSizer(cbox)
     1802            for i in sorted(self.xtalDict.keys()):
     1803                G2gd.HorizontalLine(cbox,cpnl)         
     1804                hist = self.xtalDict[i]
     1805                histblk = self.Histograms[hist]
     1806                title = 'Single Xtal dataset '+hist[5:]
     1807                cbox.Add(
     1808                    CIFtemplateSelect(self.cifdefs,
     1809                                      cpnl,'single',histblk["Instrument Parameters"][0],
     1810                                      EditCIFDefaults,
     1811                                      title),
     1812                    0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL)
     1813                cpnl.SetSizer(cbox)
     1814
    12081815            cpnl.SetAutoLayout(1)
    12091816            cpnl.SetupScrolling()
    1210             #cpnl.Bind(rw.EVT_RW_LAYOUT_NEEDED, self.OnLayoutNeeded)
     1817            #cpnl.Bind(rw.EVT_RW_LAYOUT_NEEDED, self.OnLayoutNeeded) # needed if sizes change
    12111818            cpnl.Layout()
    12121819
    12131820            vbox.Add(cpnl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 0)
    12141821            btnsizer = wx.StdDialogButtonSizer()
    1215             btn = wx.Button(cfrm, wx.ID_OK, "Create CIF")
     1822            btn = wx.Button(self.cifdefs, wx.ID_OK, "Create CIF")
    12161823            btn.SetDefault()
    12171824            btnsizer.AddButton(btn)
    1218             btn = wx.Button(cfrm, wx.ID_CANCEL)
     1825            btn = wx.Button(self.cifdefs, wx.ID_CANCEL)
    12191826            btnsizer.AddButton(btn)
    12201827            btnsizer.Realize()
    12211828            vbox.Add(btnsizer, 0, wx.ALIGN_CENTER|wx.ALL, 5)
    1222             cfrm.SetSizer(vbox)
    1223             vbox.Fit(cfrm)
    1224             if cfrm.ShowModal() == wx.ID_OK:
    1225                 val = True
    1226             else:
    1227                 val = False
    1228             cfrm.Destroy()
    1229             return val           
    1230 
    1231         # ===== end of functions for export method =======================================
    1232         #=================================================================================
     1829            self.cifdefs.SetSizer(vbox)
     1830            vbox.Fit(self.cifdefs)
     1831            self.cifdefs.Layout()
     1832
     1833# ===== end of functions for export method =======================================
     1834#=================================================================================
    12331835
    12341836        # the export process starts here
     
    13311933                    "File/Copy option to duplicate the name"
    13321934                    )
    1333                 if not EditInstNames(msg=msg): return
     1935                if not EditInstNames(): return
    13341936        # check for a distance-angle range search range for each phase
    13351937        if not self.quickmode:
    13361938            for phasenam in sorted(self.Phases.keys()):
    1337                 i = self.Phases[phasenam]['pId']
     1939                #i = self.Phases[phasenam]['pId']
    13381940                phasedict = self.Phases[phasenam] # pointer to current phase info           
    1339                 generalData = phasedict['General']
    1340                 if 'DisAglCtls' not in generalData:
    1341                     dlg = G2gd.DisAglDialog(self.G2frame,{},generalData)
     1941                if 'DisAglCtls' not in phasedict['General']:
     1942                    dlg = G2gd.DisAglDialog(self.G2frame,{},phasedict['General'])
    13421943                    if dlg.ShowModal() == wx.ID_OK:
    1343                         generalData['DisAglCtls'] = dlg.GetData()
     1944                        phasedict['General']['DisAglCtls'] = dlg.GetData()
    13441945                    else:
    13451946                        dlg.Destroy()
     
    13641965        if not fil: return
    13651966        if not self.quickmode: # give the user a chance to edit all defaults
    1366             if not EditCIFDefaults(self.G2frame): return
     1967            self.cifdefs = wx.Dialog(
     1968                self.G2frame,style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
     1969            EditCIFDefaults()
     1970            val = self.cifdefs.ShowModal()
     1971            self.cifdefs.Destroy()
     1972            if val != wx.ID_OK:
     1973                return
    13671974        #======================================================================
    13681975        # Start writing the CIF - single block
Note: See TracChangeset for help on using the changeset viewer.