source: trunk/GSASIIexprGUI.py @ 1322

Last change on this file since 1322 was 1322, checked in by toby, 9 years ago

rework pseudovars and parametric fitting; remove step size for derivatives from expression objects

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Author Revision URL Id
File size: 24.6 KB
Line 
1# -*- coding: utf-8 -*-
2#GSASIIexprGUI - Expression Definition and Evaluation
3########### SVN repository information ###################
4# $Date: 2014-05-05 03:30:16 +0000 (Mon, 05 May 2014) $
5# $Author: toby $
6# $Revision: 1322 $
7# $URL: trunk/GSASIIexprGUI.py $
8# $Id: GSASIIexprGUI.py 1322 2014-05-05 03:30:16Z toby $
9########### SVN repository information ###################
10'''
11*GSASIIexprGUI: Expression Handling*
12-------------------------------------
13
14This module defines a class for defining an expression in terms of values
15in a parameter dictionary via a wx.Dialog. The dialog creates a :class:`GSASII.ExpressionObj`
16which is used to evaluate the expression against a supplied parameter dictionary.
17
18The expression is parsed to find variables used in the expression and then
19the user is asked to assign parameters from the dictionary to each variable.
20
21'''
22# TODO: improve variable browser (search, add parameter descriptions)
23
24import re
25import sys
26import wx
27import wx.lib.scrolledpanel as wxscroll
28import numpy as np
29import GSASIIgrid as G2gd
30import GSASIIpy3 as G2py3
31import GSASIIobj as G2obj
32
33#==========================================================================
34class ExpressionDialog(wx.Dialog):
35    '''A wx.Dialog that allows a user to input an arbitrary expression
36    to be evaluated and possibly minimized.
37
38    To do this, the user assigns a new (free) or existing
39    GSAS-II parameter to each parameter label used in the expression.
40    The free parameters can optionally be designated to be refined.
41    For example, is an expression is used such as::
42
43    'A*np.exp(-B/C)'
44
45    then A, B and C can each be assigned as Free parameter with a user-selected
46    value or to any existing GSAS-II variable in the parameter dictionary.
47    As the expression is entered it is checked for validity.
48
49    After the :class:`ExpressionDialog` object is created, use :meth:`Show` to
50    run it and obtain a :class:`GSASIIobj.ExpressionObj` object with the user
51    input.
52
53    :param wx.Frame parent: The parent of the Dialog. Can be None,
54      but better is to provide the name of the Frame where the dialog
55      is called.
56    :param dict parmDict: a dict with defined parameters and their values. Each value
57      may be a list with parameter values and a refine flag or may just contain
58      the parameter value (non-float/int values in dict are ignored)
59    :param str exprObj: a :class:`GSASIIobj.ExpressionObj` object with an expression and
60      label assignments or None (default)
61    :param str wintitle: String placed on title bar of dialog;
62      defaults to "Expression Editor"
63    :param str header: String placed at top of dialog to tell the user
64      what they will do here; default is "Enter restraint expression here"
65    :param bool fit: determines if the expression will be used in fitting (default=True).
66      If set to False, and refinement flags are not shown
67      and Free parameters are not offered as an assignment option.
68    :param str VarLabel: an optional variable label to include before the expression
69      input. Ignored if None (default)
70    :param list depVarDict: a dict of choices for the dependent variable to be
71      fitted to the expression and their values. Ignored if None (default).
72    '''
73    def __init__(self, parent, parmDict, exprObj=None,
74                 header='Enter restraint expression here',
75                 wintitle='Expression Editor',
76                 fit=True,VarLabel=None,depVarDict=None):
77        self.fit = fit
78        self.depVarDict = depVarDict
79        self.parmDict = {}
80        '''A copy of the G2 parameter dict (parmDict) except only numerical
81        values are included and only the value (not the vary flag, if present)
82        is included.
83        '''
84        self.exprVarLst = []
85        '''A list containing the variables utilized in the current expression.
86        Placed into a :class:`GSASIIobj.ExpressionObj` object when the dialog is closed
87        with "OK", saving any changes.
88        '''
89        self.varSelect = {}
90        '''A dict that shows the variable type for each label
91        found in the expression.
92
93        * If the value is None or is not defined, the value is not assigned.
94        * If the value is 0, then the varible is "free" -- a new refineable
95          parameter.
96        * Values above 1 determine what variables will be shown
97          when the option is selected.
98        '''
99        self.varName = {}
100        'Name assigned to each variable'
101        self.varValue = {}
102        'Value for a variable (Free parameters only)'
103        self.varRefflag = {}
104        'Refinement flag for a variable (Free parameters only)'
105        self.expr = ''
106        'Expression as a text string'
107        self.depVar = [None,None]
108        'index # and name for dependent variable selection when depVarDict is specified'
109       
110        # process dictionary of values and create an index
111        for key in parmDict:
112            try: # deal with values that are in lists
113                val = parmDict[key][0]
114            except (TypeError,IndexError):
115                val = parmDict[key]
116            if isinstance(val, basestring): continue
117            try:
118                self.parmDict[key] = float(val)
119            except:
120                pass
121        prex = re.compile('[0-9]+::.*')
122        hrex = re.compile(':[0-9]+:.*')
123        self.parmLists = {}
124        for i in (1,2,3,4):
125            self.parmLists[i] = []
126        for i in sorted(self.parmDict.keys()):
127            if i.startswith("::") or i.find(':') == -1: # globals
128                self.parmLists[4].append(i)
129            elif prex.match(i):
130                self.parmLists[1].append(i)
131            elif hrex.match(i):
132                self.parmLists[3].append(i)
133            else:
134                self.parmLists[2].append(i)
135        if self.fit:
136            for i in (1,2,3,4):
137                wildList = G2obj.GenWildCard(self.parmLists[i])
138                self.parmLists[i] += wildList
139                self.parmLists[i].sort()
140
141        self.timer = wx.Timer()
142        self.timer.Bind(wx.EVT_TIMER,self.OnValidate)
143
144        style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER
145        wx.Dialog.__init__(self, parent, wx.ID_ANY, wintitle, style=style)
146        self.mainsizer = wx.BoxSizer(wx.VERTICAL)
147        label = wx.StaticText(self,  wx.ID_ANY, header)
148        self.mainsizer.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
149
150        self.exsizer = wx.BoxSizer(wx.HORIZONTAL)
151        if VarLabel:
152            label = wx.StaticText(self,  wx.ID_ANY, VarLabel + ' = ')
153            self.exsizer.Add(label, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 0)
154        elif depVarDict:
155            choice = G2gd.G2ChoiceButton(
156                self,
157                sorted(depVarDict.keys()),
158                self.depVar,0,
159                self.depVar,1,
160                self.RestartTimer)
161            self.exsizer.Add(choice, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 0)
162            label = wx.StaticText(self,  wx.ID_ANY, ' = ')
163            self.exsizer.Add(label, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 0)
164
165        self.exCtrl = wx.TextCtrl(self,  wx.ID_ANY, size=(150,-1),style=wx.TE_PROCESS_ENTER)
166        self.exCtrl.Bind(wx.EVT_CHAR, self.OnChar)
167        self.exCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnValidate)
168        self.exsizer.Add(self.exCtrl, 1, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 0)
169        #self.mainsizer.Add(self.exCtrl, 0, wx.ALL|wx.EXPAND, 5)
170        self.mainsizer.Add(self.exsizer, 0, wx.ALL|wx.EXPAND, 5)
171        self.mainsizer.Add((-1,5),0,wx.EXPAND,1)
172
173        evalSizer = wx.BoxSizer(wx.HORIZONTAL)
174        self.mainsizer.Add(evalSizer,0,wx.ALL|wx.EXPAND,0)
175        btn = wx.Button(self, wx.ID_ANY,"Validate")
176        btn.Bind(wx.EVT_BUTTON,self.OnValidate)
177        evalSizer.Add(btn,0,wx.LEFT|wx.RIGHT,5)
178        self.result = wx.StaticText(self,  wx.ID_ANY, '')
179        evalSizer.Add(self.result, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
180
181        self.varSizer = wx.BoxSizer(wx.HORIZONTAL)
182        self.mainsizer.Add(self.varSizer,1,wx.ALL|wx.EXPAND,1)
183        self.mainsizer.Add((-1,5),0,wx.EXPAND,1)
184
185        btnsizer = wx.StdDialogButtonSizer()
186        self.OKbtn = wx.Button(self, wx.ID_OK)
187        self.OKbtn.SetDefault()
188        self.OKbtn.Disable()
189        btnsizer.AddButton(self.OKbtn)
190        btn = wx.Button(self, wx.ID_CANCEL)
191        btnsizer.AddButton(btn)
192        btnsizer.Realize()
193        self.mainsizer.Add(btnsizer, 0, wx.ALIGN_CENTER|wx.ALL|wx.EXPAND, 5)
194        self.SetSizer(self.mainsizer)
195        self.CenterOnParent()
196        if exprObj:
197            self.expr = exprObj.EditExpression(
198                self.exprVarLst,
199                self.varSelect,
200                self.varName,
201                self.varValue,
202                self.varRefflag,
203                )
204            # set the initial value for the dependent value
205            if self.depVarDict:
206                var = exprObj.GetDepVar()
207                if var in self.depVarDict:
208                    indx = sorted(self.depVarDict.keys()).index(var)
209                    choice.SetSelection(indx)
210                    self.depVar = [indx,var]
211                   
212        self.exCtrl.SetValue(self.expr)
213        self.OnValidate(None)
214        self.SetMinSize((620,300)) # seems like a good size
215        #self.errbox.SetAutoLayout(1)
216        #self.errbox.SetupScrolling()
217        #self.varbox.SetAutoLayout(1)
218        #self.varbox.SetupScrolling()
219        #self.mainsizer.Fit(self)
220
221    def Show(self,mode=True):
222        '''Call to use the dialog after it is created.
223
224        :returns: None (On Cancel) or a new :class:`~GSASIIobj.ExpressionObj`
225        '''
226        self.Layout()
227        self.mainsizer.Fit(self)
228        if self.ShowModal() == wx.ID_OK:
229            # store the edit results in the object and return it
230            exprObj = G2obj.ExpressionObj()
231            exprObj.LoadExpression(
232                self.expr,
233                self.exprVarLst,
234                self.varSelect,
235                self.varName,
236                self.varValue,
237                self.varRefflag,
238                )
239            if self.depVarDict:
240                exprObj.SetDepVar(self.depVar[1])
241            return exprObj
242        else:
243            return None
244       
245    def setEvalResult(self,msg):
246        'Show a string in the expression result area'
247        self.result.SetLabel(msg)
248
249    def RestartTimer(self):
250        '''Cancels any running timer and starts a new one.
251        The timer causes a check of syntax after 2 seconds unless there is further input.
252        Disables the OK button until a validity check is complete.
253        '''
254        if self.timer.IsRunning():
255            self.timer.Stop()
256        self.timer.Start(2000,oneShot=True)
257       
258    def OnChar(self,event):
259        '''Called as each character is entered. Cancels any running timer
260        and starts a new one. The timer causes a check of syntax after 2 seconds
261        without input.
262        Disables the OK button until a validity check is complete.
263        '''
264        self.RestartTimer()
265        self.OKbtn.Disable()
266        event.Skip()
267        return
268   
269    def CheckVars(self):
270        '''Check that appropriate variables are defined for each
271        symbol used in :data:`self.expr`
272
273        :returns: a text error message or None if all needed input is present       
274        '''
275        invalid = 0
276        for v in self.exprVarLst:
277            if self.varSelect.get(v) is None:
278                invalid += 1
279        if invalid==1:
280            return '(a variable is not assigned)'
281        elif invalid:
282            return '('+str(invalid)+' variables are not assigned)'
283        msg = ''
284        for v in self.exprVarLst:
285            varname = self.varName.get(v)
286            if not varname:
287                invalid += 1
288                if msg: msg += "; "
289                msg += 'No variable for '+str(v)
290            elif self.varSelect.get(v) > 0:
291               if '*' in varname:
292                   l = G2obj.LookupWildCard(varname,self.parmDict.keys())
293                   if len(l) == 0:
294                       invalid += 1
295                       if msg: msg += "; "
296                       msg += 'No variables match '+str(varname)
297               elif varname not in self.parmDict.keys():
298                   invalid += 1
299                   if msg: msg += "; "
300                   msg += 'No variables match '+str(varname)
301            else:
302                # value assignment: this check is likely unneeded
303                val = self.varValue.get(v)
304                try:
305                    float(val)
306                except ValueError,TypeError:
307                    invalid += 1
308                    if msg: msg += "; "
309                    if val is None:
310                        msg += 'No value for '+str(v)
311                    else:
312                        msg += 'Value '+str(val)+' invalid for '+str(v)
313        if invalid:
314            return '('+msg+')'       
315        return
316
317    def ShowVars(self):
318        # create widgets to associate vars with labels and/or show messages
319        self.varSizer.Clear(True)
320        self.errbox = wxscroll.ScrolledPanel(self,style=wx.HSCROLL)
321        self.errbox.SetMinSize((100,130))
322        self.varSizer.Add(self.errbox,0,wx.ALL|wx.EXPAND,1)
323        self.varbox = wxscroll.ScrolledPanel(self,style=wx.HSCROLL)
324        self.varSizer.Add(self.varbox,1,wx.ALL|wx.EXPAND,1)
325        Siz = wx.BoxSizer(wx.VERTICAL)
326        Siz.Add(
327            wx.StaticText(self.varbox,wx.ID_ANY,
328                          'Assign variables to labels'),
329            0,wx.EXPAND|wx.ALIGN_CENTER,0)
330        GridSiz = wx.FlexGridSizer(len(self.exprVarLst)+1,5,2,2)
331        GridSiz.Add(
332            wx.StaticText(self.varbox,wx.ID_ANY,'label',style=wx.CENTER),
333            0,wx.ALIGN_CENTER)
334        lbls = ('varib. type\nselection','variable\nname','value')
335        self.choices = ['Free','Phase','Hist./Phase','Hist.','Global']
336        if self.fit:
337            lbls += ('refine\nflag',)
338        else:
339            lbls += ('',)
340            self.choices[0] = ''
341        for i in (1,2,3,4): # remove empty menus from choice list
342            if not len(self.parmLists[i]): self.choices[i] = ''
343
344        for lbl in lbls:
345            w = wx.StaticText(self.varbox,wx.ID_ANY,lbl,style=wx.CENTER)
346            w.SetMinSize((80,-1))
347            GridSiz.Add(w,0,wx.ALIGN_CENTER)
348
349        # show input for each var in expression.
350        for v in self.exprVarLst:
351            # label
352            GridSiz.Add(wx.StaticText(self.varbox,wx.ID_ANY,v),0,wx.ALIGN_CENTER,0)
353            # assignment type
354            self.ch = wx.Choice(
355                self.varbox, wx.ID_ANY,
356                choices = self.choices)
357            GridSiz.Add(self.ch,0,wx.ALIGN_LEFT,0)
358            self.ch.SetSelection(self.varSelect.get(v,wx.NOT_FOUND))
359            self.ch.label = v
360            self.ch.Bind(wx.EVT_CHOICE,self.OnChoice)
361
362            # var name/var assignment
363            if self.varSelect.get(v) is None:
364                GridSiz.Add((-1,-1),0,wx.ALIGN_LEFT|wx.EXPAND,0)
365            elif self.varSelect.get(v) == 0:
366                wid = G2gd.ValidatedTxtCtrl(self.varbox,self.varName,v,
367                                            #OnLeave=self.OnTxtLeave,
368                                            size=(50,-1))
369                GridSiz.Add(wid,0,wx.ALIGN_LEFT|wx.EXPAND,0)
370            else:
371                wid = wx.StaticText(self.varbox,wx.ID_ANY,self.varName[v])
372                GridSiz.Add(wid,0,wx.ALIGN_LEFT,0)
373
374            # value
375            if self.varSelect.get(v) is None:
376                GridSiz.Add((-1,-1),0,wx.ALIGN_RIGHT|wx.EXPAND,0)
377            elif self.varSelect.get(v) == 0:
378                wid = G2gd.ValidatedTxtCtrl(self.varbox,self.varValue,v,
379                                            #OnLeave=self.OnTxtLeave,
380                                            size=(75,-1))
381                GridSiz.Add(wid,0,wx.ALIGN_LEFT|wx.EXPAND,0)
382                wid.Bind(wx.EVT_CHAR,self.OnChar)
383            else:
384                var = self.varName[v]
385                if '*' in var:
386                    #[self.parmDict[v] for v in LookupWildCard(var,self.parmDict.keys())]
387                    #print self.varValue[v]
388                    vs = G2obj.LookupWildCard(var,self.parmDict.keys())
389                    s = '('+str(len(vs))+' values)'
390                elif var in self.parmDict:
391                    val = self.parmDict[var]
392                    s = G2py3.FormatSigFigs(val).rstrip('0')
393                else:
394                    s = '?'
395                wid = wx.StaticText(self.varbox,wx.ID_ANY,s)
396                GridSiz.Add(wid,0,wx.ALIGN_LEFT,0)
397
398            # show a refine flag for Free Vars only
399            if self.varSelect.get(v) == 0 and self.fit:
400                self.varRefflag[v] = self.varRefflag.get(v,True)
401                wid = G2gd.G2CheckBox(self.varbox,'',self.varRefflag,v)
402                GridSiz.Add(wid,0,wx.ALIGN_LEFT|wx.EXPAND,0)
403            else:
404                wid = (-1,-1)
405                GridSiz.Add(wid,0,wx.ALIGN_LEFT|wx.EXPAND,0)
406
407        Siz.Add(GridSiz)
408        self.varbox.SetSizer(Siz,True)
409        xwid,yhgt = Siz.Fit(self.varbox)
410        self.varbox.SetMinSize((xwid,130))
411        self.varbox.SetAutoLayout(1)
412        self.varbox.SetupScrolling()
413        self.varbox.Refresh()
414        self.Layout()
415        return
416
417    def GetDepVar(self):
418        '''Returns the name of the dependent variable, when depVarDict is used.
419        '''
420        return self.depVar[1]
421       
422    def OnChoice(self,event):
423        '''Respond to a selection of a variable type for a label in
424        an expression
425        '''
426        v = event.GetEventObject().label
427        sel = event.GetEventObject().GetSelection()
428        if self.choices[sel] == '':
429            if v in self.varSelect: del self.varSelect[v]
430            sel = event.GetEventObject().GetSelection()
431            self.OnValidate(None)
432            return
433        self.varSelect[v] = sel
434        if sel == 0:
435            self.varName[v] = str(v)
436            self.varValue[v] = self.varValue.get(v,0.0)
437        else:
438            var = self.SelectG2var(sel,v)
439            if not var:
440                del self.varSelect[v]
441                sel = event.GetEventObject().GetSelection()
442                self.OnValidate(None)
443                return
444            self.varName[v] = var
445        self.OnValidate(None)
446
447    def SelectG2var(self,sel,var):
448        '''Offer a selection of a GSAS-II variable.
449
450        :param int sel: Determines the type of variable to be selected.
451          where 1 is used for Phase variables, and 2 for Histogram/Phase vars,
452          3 for Histogram vars and 4 for Global vars.
453        :returns: a variable name or None (if Cancel is pressed)
454        '''
455        if not self.parmLists[sel]:
456            return None
457        #varListlbl = ["("+i+") "+G2obj.fmtVarDescr(i) for i in self.parmLists[sel]]
458        #varListlbl = self.parmLists[sel]
459        l2 = l1 = 1
460        for i in self.parmLists[sel]:
461            l1 = max(l1,len(i))
462            loc,desc = G2obj.VarDescr(i)
463            l2 = max(l2,len(loc))
464        fmt = u"{:"+str(l1)+"s} {:"+str(l2)+"s} {:s}"
465        varListlbl = [fmt.format(i,*G2obj.VarDescr(i)) for i in self.parmLists[sel]]
466
467        dlg = G2gd.G2SingleChoiceDialog(
468            self,'Select GSAS-II variable for '+str(var)+':',
469            'Select variable',
470            varListlbl,monoFont=True)
471        dlg.SetSize((625,250))
472        dlg.CenterOnParent()
473        var = None
474        if dlg.ShowModal() == wx.ID_OK:
475            i = dlg.GetSelection()
476            var = self.parmLists[sel][i]
477        dlg.Destroy()
478        return var
479
480    def showError(self,msg1,msg2='',msg3=''):
481        '''Show an error message of 1 to 3 sections. The second
482        section is shown in an equally-spaced font.
483       
484        :param str msg1: msg1 is shown in a the standard font
485        :param str msg2: msg2 is shown in a equally-spaced (wx.MODERN) font
486        :param str msg3: msg3 is shown in a the standard font
487        '''
488        self.OKbtn.Disable()
489        self.varSizer.Clear(True)
490        self.errbox = wxscroll.ScrolledPanel(self,style=wx.HSCROLL)
491        self.errbox.SetMinSize((200,130))
492        self.varSizer.Add(self.errbox,1,wx.ALL|wx.EXPAND,1)
493        Siz = wx.BoxSizer(wx.VERTICAL)
494        errMsg1 = wx.StaticText(self.errbox, wx.ID_ANY,"")
495        Siz.Add(errMsg1, 0, wx.ALIGN_LEFT|wx.LEFT|wx.EXPAND, 5)
496        errMsg2 = wx.StaticText(self.errbox, wx.ID_ANY,"\n\n")
497        font1 = wx.Font(errMsg2.GetFont().GetPointSize(),
498                        wx.MODERN, wx.NORMAL, wx.NORMAL, False)
499        errMsg2.SetFont(font1)
500        Siz.Add(errMsg2, 0, wx.ALIGN_LEFT|wx.LEFT|wx.EXPAND, 5)
501        errMsg3 = wx.StaticText(self.errbox, wx.ID_ANY,"")
502        Siz.Add(errMsg3, 0, wx.ALIGN_LEFT|wx.LEFT|wx.EXPAND, 5)
503        self.errbox.SetSizer(Siz,True)
504        Siz.Fit(self.errbox)
505        errMsg1.SetLabel(msg1)
506        errMsg2.SetLabel("  "+msg2)
507        errMsg2.Wrap(-1)
508        errMsg3.SetLabel(msg3)
509        self.Layout()
510
511    def OnValidate(self,event):
512        '''Respond to a press of the Validate button or when a variable
513        is associated with a label (in :meth:`OnChoice`)
514        '''
515        self.setEvalResult('(expression cannot be evaluated)')
516        self.timer.Stop()
517        self.expr = self.exCtrl.GetValue().strip()
518        self.varSizer.Clear(True)
519        if not self.expr: 
520            self.showError(
521                "Invalid Expression:","",
522                "(an expression must be entered)")
523            return
524        exprObj = G2obj.ExpressionObj()
525        ret = exprObj.ParseExpression(self.expr)
526        if not ret:
527            self.showError(*exprObj.lastError)
528            return
529        self.exprVarLst,pkgdict = ret
530        self.ShowVars() # show widgets to set vars
531        msg = self.CheckVars() 
532        if msg:
533            self.setEvalResult(msg)
534            return
535        exprObj.LoadExpression(
536            self.expr,
537            self.exprVarLst,
538            self.varSelect,
539            self.varName,
540            self.varValue,
541            self.varRefflag,
542            )
543        try:
544            calcobj = G2obj.ExpressionCalcObj(exprObj)
545            calcobj.SetupCalc(self.parmDict)
546            val = calcobj.EvalExpression()
547        except Exception as msg:
548            self.setEvalResult("Error in evaluation: "+str(msg))
549            return
550        if not np.isfinite(val):
551            self.setEvalResult("Expression value is infinite or out-of-bounds")
552            return
553        s = G2py3.FormatSigFigs(val).rstrip('0')
554        depVal = ""
555        if self.depVarDict:
556            if not self.depVar[1]:
557                self.setEvalResult("A dependent variable must be selected.")
558                return
559            depVal = '; Variable "' + self.depVar[1] + '" = ' + str(
560                self.depVarDict.get(self.depVar[1],'?')
561                )
562        self.setEvalResult("Expression evaluates to: "+str(s)+depVal)
563        self.OKbtn.Enable()
564       
565if __name__ == "__main__":
566    app = wx.PySimpleApp() # create the App
567    frm = wx.Frame(None)
568    frm.Show()
569    PSvarDict = {'::a':1.0,'::b':1.1,'0::c':1.2}
570    #PSvars = PSvarDict.keys()
571    indepvarDict = {'Temperature':1.0,'Pressure':1.1,'Phase of Moon':1.2,'1:1:HAP':1.3}
572    dlg = ExpressionDialog(frm,indepvarDict,
573                           header="Edit the PseudoVar expression",
574                           fit=False,
575                           depVarDict=PSvarDict,
576                           #VarLabel="New PseudoVar",                           
577                           )
578    print dlg.GetDepVar()
579    newobj = dlg.Show(True)
580    print dlg.GetDepVar()
581    dlg = ExpressionDialog(frm,PSvarDict,
582                           header="Edit the PseudoVar expression",
583                           fit=True)
584    newobj = dlg.Show(True)
585    print dlg.GetDepVar()
586    import sys
587    #sys.exit()
588
589    #app.MainLoop()
590
591
592    import cPickle
593    def showEQ(calcobj):
594        print
595        print calcobj.eObj.expression
596        for v in sorted(calcobj.eObj.freeVars.keys()+calcobj.eObj.assgnVars.keys()):
597            print "  ",v,'=',calcobj.exprDict[v]
598        print calcobj.EvalExpression()
599    print "starting test"
600    obj = G2obj.ExpressionObj()
601    obj.expression = "A*np.exp(B)"
602    obj.assgnVars =  {'B': '0::Afrac:*'}
603    obj.freeVars =  {'A': [u'A', 0.5, True]}
604    obj.CheckVars()
605    parmDict2 = {'0::Afrac:0':1.0, '0::Afrac:1': 1.0}
606    calcobj = G2obj.ExpressionCalcObj(obj)
607    calcobj.SetupCalc(parmDict2)
608    showEQ(calcobj)
609    fp = open('/tmp/obj.pickle','w')
610    cPickle.dump(obj,fp)
611    fp.close()
612   
613    obj.expression = "A*np.exp(-2/B)"
614    obj.assgnVars =  {'A': '0::Afrac:0', 'B': '0::Afrac:1'}
615    obj.freeVars =  {}
616    parmDict1 = {'0::Afrac:0':1.0, '0::Afrac:1': -2.0}
617    calcobj = G2obj.ExpressionCalcObj(obj)
618    calcobj.SetupCalc(parmDict1)
619    showEQ(calcobj)
620
621    fp = open('/tmp/obj.pickle','r')
622    obj = cPickle.load(fp)
623    fp.close()
624    parmDict2 = {'0::Afrac:0':0.0, '0::Afrac:1': 1.0}
625    calcobj = G2obj.ExpressionCalcObj(obj)
626    calcobj.SetupCalc(parmDict2)
627    showEQ(calcobj)
628
629    parmDict2 = {'0::Afrac:0':1.0, '0::Afrac:1': 1.0}
630    calcobj = G2obj.ExpressionCalcObj(obj)
631    calcobj.SetupCalc(parmDict2)
632    showEQ(calcobj)
633   
Note: See TracBrowser for help on using the repository browser.