Changeset 1080


Ignore:
Timestamp:
Oct 3, 2013 9:29:47 PM (8 years ago)
Author:
toby
Message:

revise export menu; add multiple selection to G2gd.ItemSelector?

Location:
trunk
Files:
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/G2cif.py

    r1077 r1080  
    11#!/usr/bin/env python
    22# -*- coding: utf-8 -*-
    3 #G2cif
    43########### SVN repository information ###################
    54# $Date$
     
    5150        super(self.__class__,self).__init__( # fancy way to say <parentclass>.__init__
    5251            G2frame=G2frame,
    53             formatName = 'full CIF',
     52            formatName = 'Full CIF',
    5453            extension='.cif',
    5554            longFormatName = 'Export project as CIF'
    5655            )
     56        self.exporttype = ['project']
    5757        self.author = ''
    5858        self.mode = 'full'
    59         self.exporttype = 'project'
    60 
    61     def export(self):
     59
     60    def Exporter(self,event=None):
    6261        '''Export a CIF. Export can be full or simple (as set by self.mode).
    6362        "simple" skips data, distances & angles, etc. and can only include
    6463        a single phase while "full" is intended for for publication submission.
    6564        '''
    66    
    67 # ===== define functions for export method =======================================
     65
     66#***** define functions for export method =======================================
    6867        def openCIF(filnam):
    6968            'opens the output file'
     
    12591258            self.cifdefs.SetTitle('Edit CIF settings')
    12601259            vbox = wx.BoxSizer(wx.VERTICAL)
     1260            vbox.Add(wx.StaticText(self.cifdefs, wx.ID_ANY,'Creating file '+str(self.filename)))
    12611261            but = wx.Button(self.cifdefs, wx.ID_ANY,'Edit CIF Author')
    12621262            but.Bind(wx.EVT_BUTTON,EditAuthor)
     
    12871287                    0,wx.EXPAND|wx.ALIGN_LEFT|wx.ALL)
    12881288                cpnl.SetSizer(cbox)
    1289                 but = wx.Button(cpnl, wx.ID_ANY,'Edit distance/angle ranges')
    1290                 #cbox.Add(but,0,wx.ALIGN_CENTER,3)
     1289                if phasedict['General']['Type'] == 'nuclear': 
     1290                    but = wx.Button(cpnl, wx.ID_ANY,'Edit distance/angle ranges')
     1291                    cbox.Add(but,0,wx.ALIGN_LEFT,0)
     1292                    cbox.Add((-1,2))
     1293                    but.phasedict = self.Phases[phasenam]  # set a pointer to current phase info
     1294                    but.Bind(wx.EVT_BUTTON,EditRanges)     # phase bond/angle ranges
     1295                    but = wx.Button(cpnl, wx.ID_ANY,'Set distance/angle publication flags')
     1296                    but.phase = phasenam  # set a pointer to current phase info     
     1297                    but.Bind(wx.EVT_BUTTON,SelectDisAglFlags)     # phase bond/angle ranges
     1298                    cbox.Add(but,0,wx.ALIGN_LEFT,0)
    12911299                cbox.Add((-1,2))
    1292                 cbox.Add(but,0,wx.ALIGN_LEFT,0)
    1293                 but.phasedict = self.Phases[phasenam]  # set a pointer to current phase info     
    1294                 but.Bind(wx.EVT_BUTTON,EditRanges)     # phase bond/angle ranges
    1295                 but = wx.Button(cpnl, wx.ID_ANY,'Set distance/angle publication flags')
    1296                 but.phase = phasenam  # set a pointer to current phase info     
    1297                 but.Bind(wx.EVT_BUTTON,SelectDisAglFlags)     # phase bond/angle ranges
    1298                 cbox.Add((-1,2))
    1299                 cbox.Add(but,0,wx.ALIGN_LEFT,0)
    13001300            for i in sorted(self.powderDict.keys()):
    13011301                G2gd.HorizontalLine(cbox,cpnl)         
     
    15081508            dlg.ShowModal()
    15091509           
    1510 # ===== end of functions for export method =======================================
     1510#***** end of functions for export method =======================================
    15111511#=================================================================================
    15121512
     
    15161516        # create a dict with refined values and their uncertainties
    15171517        self.loadParmDict()
     1518        if self.SetupExport(event,
     1519                            AskFile=(self.mode=='simple')
     1520                            ): return # set export parameters
    15181521
    15191522        # Someday: get restraint & constraint info
     
    15251528
    15261529        self.CIFdate = dt.datetime.strftime(dt.datetime.now(),"%Y-%m-%dT%H:%M")
    1527         # index powder and single crystal histograms
    1528         self.powderDict = {}
    1529         self.xtalDict = {}
    1530         for hist in self.Histograms:
    1531             i = self.Histograms[hist]['hId']
    1532             if hist.startswith("PWDR"):
    1533                 self.powderDict[i] = hist
    1534             elif hist.startswith("HKLF"):
    1535                 self.xtalDict[i] = hist
    15361530        # is there anything to export?
    15371531        if len(self.Phases) == len(self.powderDict) == len(self.xtalDict) == 0:
    15381532           self.G2frame.ErrorDialog(
    15391533               'Empty project',
    1540                'Project does not contain interconnected data & phase(s)')
     1534               'Project does not contain any data or phases. Are they interconnected?')
    15411535           return
    15421536        # get the project file name
     
    16361630                    instnam = histblk["Instrument Parameters"][0]['InstrName']
    16371631                    break # ignore all but 1st data histogram
    1638         if self.quickmode:
    1639             fil = self.askSaveFile()
    1640         else:
    1641             fil = self.defSaveFile()
    1642         if not fil: return
    16431632        if not self.quickmode: # give the user a chance to edit all defaults
    16441633            self.cifdefs = wx.Dialog(
     
    16541643        # Start writing the CIF - single block
    16551644        #======================================================================
    1656         print('Writing CIF output to file '+fil+"...")
    1657         openCIF(fil)
    1658         if oneblock:
     1645        print('Writing CIF output to file '+str(self.filename)+"...")
     1646        openCIF(self.filename)
     1647        if self.currentExportType == 'single' or self.currentExportType == 'powder':
     1648            hist = self.histnam
     1649            print hist
     1650            self.CIFname = self.histnam[5:40].replace(' ','')
     1651            print 'hist',self.CIFname
     1652            WriteCIFitem('data_'+self.CIFname)
     1653            if hist.startswith("PWDR"):
     1654                WritePowderData(hist)
     1655            elif hist.startswith("HKLF"):
     1656                WriteSingleXtalData(hist)
     1657            else:
     1658                print "should not happen"
     1659        elif oneblock:
    16591660            WriteCIFitem('data_'+self.CIFname)
    16601661            if phasenam is None: # if not already selected, select the first phase (should be one)
     
    17451746                    instnam = histblk["Sample Parameters"]['InstrName']
    17461747                    instnam = instnam.replace(' ','')
    1747                     i = histblk['hId']
     1748                    j = histblk['hId']
    17481749                    datablockidDict[hist] = (str(self.CIFdate) + "|" + str(self.CIFname) + "|" +
    17491750                                             str(self.shortauthorname) + "|" +
    1750                                              instnam + "_hist_"+str(i))
     1751                                             instnam + "_hist_"+str(j))
    17511752                    WriteCIFitem(loopprefix,datablockidDict[hist])
    17521753                for i in sorted(self.xtalDict.keys()):
     
    18331834        # end of CIF export
    18341835
    1835 class ExportSimpleCIF(ExportCIF):
     1836class ExportPhaseCIF(ExportCIF):
    18361837    '''Used to create a simple CIF of at most one phase. Uses exact same code as
    1837     :class:`ExportCIF` except that `self.mode` is set to simple.
     1838    :class:`ExportCIF` except that `self.mode` is set to "simple". Shows up in menu as
     1839    Quick CIF
    18381840
    18391841    :param wx.Frame G2frame: reference to main GSAS-II frame
     
    18421844        G2IO.ExportBaseclass.__init__(self,
    18431845            G2frame=G2frame,
    1844             formatName = 'full CIF',
     1846            formatName = 'Quick CIF',
    18451847            extension='.cif',
    1846             longFormatName = 'Export project as CIF'
     1848            longFormatName = 'Export one phase in CIF'
    18471849            )
     1850        self.exporttype = ['phase']
     1851        # CIF-specific items
    18481852        self.author = ''
    18491853        self.mode = 'simple'
    1850         self.exporttype = 'phase'
     1854
     1855class ExportDataCIF(ExportCIF):
     1856    '''Used to create a simple CIF containing diffraction data only. Uses exact same code as
     1857    :class:`ExportCIF` except that `self.mode` is set to "simple" and `self.currentExportType`
     1858    is set to "single" or "powder" in `self.SetupExport`. Shows up in menus as Data-only CIF.
     1859
     1860    :param wx.Frame G2frame: reference to main GSAS-II frame
     1861    '''
     1862    def __init__(self,G2frame):
     1863        G2IO.ExportBaseclass.__init__(self,
     1864            G2frame=G2frame,
     1865            formatName = 'Data-only CIF',
     1866            extension='.cif',
     1867            longFormatName = 'Export data as CIF'
     1868            )
     1869        self.exporttype = ['single','powder']
     1870        # CIF-specific items
     1871        self.author = ''
     1872        self.mode = 'simple'
    18511873
    18521874#===============================================================================
  • trunk/GSASII.py

    r1077 r1080  
    10121012
    10131013    def _init_Exports(self,menu):
    1014         '''This is a place holder for when exports are handled in a manner similar to imports
    1015         '''
    1016 #        submenu = wx.Menu()
    1017 #        item = menu.AppendMenu(
    1018 #            wx.ID_ANY, 'entire project',
    1019 #            submenu, help='Export entire project')
    1020 
    1021         # for now hard-code CIF testing here
    1022         item = menu.Append(
    1023             wx.ID_ANY,
    1024             help='full CIF file includes powder/reflection data',
    1025             kind=wx.ITEM_NORMAL,
    1026             text='full CIF file')
    1027         self.Bind(wx.EVT_MENU, self.OnTestCIF, id=item.GetId())
    1028         item = menu.Append(
    1029             wx.ID_ANY,
    1030             help='quick CIF file with no data, no distance/angle table',
    1031             kind=wx.ITEM_NORMAL,
    1032             text='quick CIF file')
    1033         self.Bind(wx.EVT_MENU, self.OnTestCIF, id=item.GetId())
    1034 
    1035     def OnTestCIF(self,event):
    1036         # hard-code CIF testing here
    1037        
    1038         # get the menu command on Windows and Linux
    1039         menu = self.ExportMenu.FindItemById(event.GetId())
    1040         mode = 'full'
    1041         if menu:
    1042             if 'quick' in menu.GetLabel():
    1043                 mode = 'simple'
    1044         else: # this works on the Mac
    1045             try:
    1046                 if 'quick' in event.EventObject.GetLabelText(event.Id):
    1047                     mode = 'simple'
    1048             except:
     1014        '''Find exporter routines and add them into menus
     1015        '''
     1016        # set up the top-level menus
     1017        projectmenu = wx.Menu()
     1018        item = menu.AppendMenu(
     1019            wx.ID_ANY, 'Entire project as',
     1020            projectmenu, help='Export entire project')
     1021
     1022        phasemenu = wx.Menu()
     1023        item = menu.AppendMenu(
     1024            wx.ID_ANY, 'Phase as',
     1025            phasemenu, help='Export phase or sometimes phases')
     1026
     1027        powdermenu = wx.Menu()
     1028        item = menu.AppendMenu(
     1029            wx.ID_ANY, 'Powder data as',
     1030            powdermenu, help='Export powder diffraction histogram(s)')
     1031
     1032        singlemenu = wx.Menu()
     1033        item = menu.AppendMenu(
     1034            wx.ID_ANY, 'Single crystal data as',
     1035            singlemenu, help='Export single crystal histogram(s)')
     1036
     1037        # find all the exporter files
     1038        pathlist = sys.path
     1039        filelist = []
     1040        for path in pathlist:
     1041            for filename in glob.iglob(os.path.join(
     1042                path,
     1043                "G2export*.py")):
     1044                filelist.append(filename)   
     1045        filelist = sorted(list(set(filelist))) # remove duplicates
     1046        exporterlist = []
     1047        # go through the routines and import them, saving objects that
     1048        # have export routines (method Exporter)
     1049        for filename in filelist:
     1050            path,rootname = os.path.split(filename)
     1051            pkg = os.path.splitext(rootname)[0]
     1052            try:
     1053                fp = None
     1054                fp, fppath,desc = imp.find_module(pkg,[path,])
     1055                pkg = imp.load_module(pkg,fp,fppath,desc)
     1056                for clss in inspect.getmembers(pkg): # find classes defined in package
     1057                    if clss[0].startswith('_'): continue
     1058                    if inspect.isclass(clss[1]):
     1059                        # check if we have the required methods
     1060                        for m in 'Exporter','loadParmDict':
     1061                            if not hasattr(clss[1],m): break
     1062                            if not callable(getattr(clss[1],m)): break
     1063                        else:
     1064                            exporter = clss[1](self) # create an export instance
     1065                            exporterlist.append(exporter)
     1066            except AttributeError:
     1067                print 'Import_'+errprefix+': Attribute Error'+str(filename)
    10491068                pass
    1050         #path2GSAS2 = os.path.join(
    1051         #    os.path.dirname(os.path.realpath(__file__)), # location of this file
    1052         #    'exports')
    1053         #if path2GSAS2 not in sys.path: sys.path.append(path2GSAS2)
    1054         #reload(G2IO)
    1055         import G2cif
    1056         reload(G2cif)
    1057         exp = G2cif.ExportCIF(self)
    1058         sexp = G2cif.ExportSimpleCIF(self)
    1059         if mode == 'full':
    1060             exp.export()
    1061         else:
    1062             sexp.export()
    1063 
     1069            except ImportError:
     1070                print 'Import_'+errprefix+': Error importing file'+str(filename)
     1071                pass
     1072            if fp: fp.close()
     1073        # Add submenu item(s) for each Exporter by its self-declared type (can be more than one)
     1074        for obj in exporterlist:
     1075            #print 'exporter',obj
     1076            for typ in obj.exporttype:
     1077                if typ == "project":
     1078                    submenu = projectmenu
     1079                elif typ == "phase":
     1080                    submenu = phasemenu
     1081                elif typ == "powder":
     1082                    submenu = powdermenu
     1083                elif typ == "single":
     1084                    submenu = singlemenu
     1085                else:
     1086                    print("Error, unknown type in "+str(obj))
     1087                    break
     1088                item = submenu.Append(
     1089                    wx.ID_ANY,
     1090                    help=obj.longFormatName,
     1091                    kind=wx.ITEM_NORMAL,
     1092                    text=obj.formatName)
     1093                self.Bind(wx.EVT_MENU, obj.Exporter, id=item.GetId())
     1094                self.ExportLookup[item.GetId()] = typ # lookup table for submenu item
     1095           
    10641096    def _Add_ExportMenuItems(self,parent):
    10651097        item = parent.Append(
     
    11861218       
    11871219    def __init__(self, parent):
     1220        self.ExportLookup = {}
    11881221        self._init_ctrls(parent)
    11891222        self.Image = wx.Image(
  • trunk/GSASIIIO.py

    r1074 r1080  
    15791579        self.Phases = {}
    15801580        self.Histograms = {}
    1581 
     1581        self.powderDict = {}
     1582        self.xtalDict = {}
     1583        # updated in SetupExport, when used
     1584        self.currentExportType = None # type of export that has been requested
     1585        self.phasenam = None # name of selected phase or a list of phases
     1586        self.histnam = None # name of selected histogram or a list of histograms
     1587        self.filename = None # name of file to be written
     1588       
     1589        # items that should be defined in a subclass of this class
     1590        self.exporttype = []  # defines the type(s) of exports that the class can handle.
     1591        # The following types are defined: 'project', "phase", "powder", "single"
     1592        self.multiple = False # set as True if the class can export multiple phase or histograms
     1593        # ignored for "project" exports
     1594
     1595    def SetupExport(self,event,AskFile=True):
     1596        '''Determines the type of menu that called the Exporter. Selects histograms
     1597        or phases when needed.
     1598
     1599        :param bool AskFile: if AskFile is True (default)
     1600        '''
     1601        if event:
     1602            self.currentExportType = self.G2frame.ExportLookup.get(event.Id)
     1603        if AskFile:
     1604            self.filename = self.askSaveFile()
     1605        else:
     1606            self.filename = self.defaultSaveFile()
     1607        if not self.filename: return True
     1608       
     1609        if self.currentExportType == 'phase':
     1610            if len(self.Phases) == 0:
     1611                self.G2frame.ErrorDialog(
     1612                    'Empty project',
     1613                    'Project does not contain any data or phases or they are not interconnected.')
     1614                return True
     1615            elif self.multiple:
     1616                if len(self.Phases) == 1:
     1617                    self.phasenam = self.Phases.keys()
     1618                else:
     1619                    choices = sorted(self.Phases.keys())
     1620                    phasenum = G2gd.ItemSelector(choices,self.G2frame,multiple=True)
     1621                    if phasenum is None: return True
     1622                    self.phasenam = [choices[i] for i in phasenum]
     1623            else:
     1624                if len(self.Phases) == 1:
     1625                    self.phasenam = self.Phases.keys()[0]
     1626                else:
     1627                    choices = sorted(self.Phases.keys())
     1628                    phasenum = G2gd.ItemSelector(choices,self.G2frame)
     1629                    if phasenum is None: return True
     1630                    self.phasenam = choices[phasenum]
     1631        elif self.currentExportType == 'single':
     1632            if len(self.xtalDict) == 0:
     1633                self.G2frame.ErrorDialog(
     1634                    'Empty project',
     1635                    'Project does not contain any single crystal data or data is not connected to a phase.')
     1636                return True
     1637            elif self.multiple:
     1638                if len(self.xtalDict) == 1:
     1639                    self.histnam = self.xtalDict.values()
     1640                else:
     1641                    choices = sorted(self.xtalDict.values())
     1642                    hnum = G2gd.ItemSelector(choices,self.G2frame,multiple=True)
     1643                    if hnum is None: return True
     1644                    self.histnam = [choices[i] for i in hnum]
     1645            else:
     1646                if len(self.xtalDict) == 1:
     1647                    self.histnam = self.xtalDict.values()[0]
     1648                else:
     1649                    choices = sorted(self.xtalDict.values())
     1650                    hnum = G2gd.ItemSelector(choices,self.G2frame)
     1651                    if hnum is None: return True
     1652                    self.histnam = choices[hnum]
     1653        elif self.currentExportType == 'powder':
     1654            if len(self.powderDict) == 0:
     1655                self.G2frame.ErrorDialog(
     1656                    'Empty project',
     1657                    'Project does not contain any powder data or data is not connected to a phase.')
     1658                return True
     1659            elif self.multiple:
     1660                if len(self.powderDict) == 1:
     1661                    self.histnam = self.powderDict.values()
     1662                else:
     1663                    choices = sorted(self.powderDict.values())
     1664                    hnum = G2gd.ItemSelector(choices,self.G2frame,multiple=True)
     1665                    if hnum is None: return True
     1666                    self.histnam = [choices[i] for i in hnum]
     1667            else:
     1668                if len(self.powderDict) == 1:
     1669                    self.histnam = self.powderDict.values()[0]
     1670                else:
     1671                    choices = sorted(self.powderDict.values())
     1672                    hnum = G2gd.ItemSelector(choices,self.G2frame)
     1673                    if hnum is None: return True
     1674                    self.histnam = choices[hnum]
     1675            print 'selected histograms = ',self.histnam
     1676            print 'selected histograms = ',self.histnam
     1677            return True
    15821678    def loadParmDict(self):
    15831679        '''Load the GSAS-II refinable parameters from the tree into a dict (self.parmDict). Update
     
    16561752    def loadTree(self):
    16571753        '''Load the contents of the data tree into a set of dicts
    1658         (self.OverallParms, self.Phases and self.Histogram)
     1754        (self.OverallParms, self.Phases and self.Histogram as well as self.powderDict
     1755        & self.xtalDict)
    16591756       
    16601757        * The childrenless data tree items are overall parameters/controls for the
     
    16741771                self.OverallParms[name] = self.G2frame.PatternTree.GetItemPyData(item)
    16751772            item, cookie = self.G2frame.PatternTree.GetNextChild(self.G2frame.root, cookie)
     1773        # index powder and single crystal histograms
     1774        self.powderDict = {}
     1775        self.xtalDict = {}
     1776        for hist in self.Histograms:
     1777            i = self.Histograms[hist]['hId']
     1778            if hist.startswith("PWDR"):
     1779                self.powderDict[i] = hist
     1780            elif hist.startswith("HKLF"):
     1781                self.xtalDict[i] = hist
    16761782
    16771783    def dumpTree(self,mode='type'):
     
    16941800                print '      ',key2,Show(self.Histograms[key1][key2])
    16951801
    1696     def defSaveFile(self):
     1802    def defaultSaveFile(self):
    16971803        return os.path.abspath(
    16981804            os.path.splitext(self.G2frame.GSASprojectfile
  • trunk/GSASIIgrid.py

    r1077 r1080  
    12771277                 title='Select an item',
    12781278                 size=None, header='Item Selector',
    1279                  useCancel=True):
     1279                 useCancel=True,multiple=False):
    12801280        ''' Provide a wx dialog to select a single item from list of choices
    12811281
     
    12861286        :param str header: Title to place on window frame (default 'Item Selector')
    12871287        :param bool useCancel: If True (default) both the OK and Cancel buttons are offered
    1288 
    1289         :returns: the selection index or None
     1288        :param bool multiple: If True then multiple items can be selected (default False)
     1289
     1290        :returns: the selection index or None or a selection list if multiple is true
    12901291        '''
    1291         if useCancel:
    1292             dlg = wx.SingleChoiceDialog(
    1293                 ParentFrame,title, header, ChoiceList)
     1292        if multiple:
     1293            if useCancel:
     1294                dlg = wx.MultiChoiceDialog(
     1295                    ParentFrame,title, header, ChoiceList)
     1296            else:
     1297                dlg = wx.MultiChoiceDialog(
     1298                    ParentFrame,title, header, ChoiceList,
     1299                    style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.OK|wx.CENTRE)
     1300            pass
    12941301        else:
    1295             dlg = wx.SingleChoiceDialog(
    1296                 ParentFrame,title, header,ChoiceList,
    1297                 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.OK|wx.CENTRE)
     1302            if useCancel:
     1303                dlg = wx.SingleChoiceDialog(
     1304                    ParentFrame,title, header, ChoiceList)
     1305            else:
     1306                dlg = wx.SingleChoiceDialog(
     1307                    ParentFrame,title, header,ChoiceList,
     1308                    style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.OK|wx.CENTRE)
    12981309        if size: dlg.SetSize(size)
    12991310        if dlg.ShowModal() == wx.ID_OK:
    1300             sel = dlg.GetSelection()
    1301             return sel
     1311            if multiple:
     1312                return dlg.GetSelections()
     1313            else:
     1314                return dlg.GetSelection()
    13021315        else:
    13031316            return None
Note: See TracChangeset for help on using the changeset viewer.