File: uncertaintyMiniFrame.py

package info (click to toggle)
model-builder 0.4.1-5
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 1,056 kB
  • ctags: 621
  • sloc: python: 3,917; fortran: 690; makefile: 18; sh: 11
file content (336 lines) | stat: -rw-r--r-- 15,812 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# -*- coding:iso8859-1 -*- 
#-----------------------------------------------------------------------------
# Name:        uncertaintyMiniFrame.py
# Purpose:     Panel to specify parameters for the uncertainty analysis
#
# Author:      <Flvio Codeo Coelho>
#
# Created:     2003/02/04
# RCS-ID:      $Id: uncertaintyMiniFrame.py,v 1.3 2004/01/13 10:51:43 fccoelho Exp $
# Copyright:   (c) 2003 Flvio Codeo Coelho <fccoelho@uerj.br>
# Licence:     This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#-----------------------------------------------------------------------------
#Boa:MiniFrame:uncertaintyMiniFrame
import wxversion
wxversion.select('2.8')
import wx
import wx.gizmos
from Numeric import *
from string import *
from Bayes import Melding as meld
import os

def create(parent):
    return uncertaintyMiniFrame(parent)

[wxID_UNCERTAINTYMINIFRAME, wxID_UNCERTAINTYMINIFRAMEDONEBUTTON, 
 wxID_UNCERTAINTYMINIFRAMELIKLIST, wxID_UNCERTAINTYMINIFRAMEPRIORLIST, 
 wxID_UNCERTAINTYMINIFRAMESELALL, wxID_UNCERTAINTYMINIFRAMESPINCTRL1, 
 wxID_UNCERTAINTYMINIFRAMESTATICTEXT1, wxID_UNCERTAINTYMINIFRAMESTATICTEXT2, 
 wxID_UNCERTAINTYMINIFRAMESTATICTEXT3, wxID_UNCERTAINTYMINIFRAMESTATICTEXT4, 
 wxID_UNCERTAINTYMINIFRAMESTATICTEXT5, wxID_UNCERTAINTYMINIFRAMESTATUSPANEL, 
 wxID_UNCERTAINTYMINIFRAMEVARLIST, 
] = [wx.NewId() for _init_ctrls in range(13)]

class uncertaintyMiniFrame(wx.MiniFrame):
    def _init_ctrls(self, prnt):
        # generated method, don't edit
        wx.MiniFrame.__init__(self, id=wxID_UNCERTAINTYMINIFRAME,
              name='uncertaintyMiniFrame', parent=prnt, pos=wx.Point(181, 159),
              size=wx.Size(683, 445), style=wx.DEFAULT_FRAME_STYLE,
              title='Bayesian Melding Uncertainty Analysis')
        self.SetClientSize(wx.Size(683, 445))
        self.SetAutoLayout(True)
        self.SetToolTipString('Melding parameters')
        self.Bind(wx.EVT_CLOSE, self.OnUncertaintyMiniFrameClose)

        self.staticText1 = wx.StaticText(id=wxID_UNCERTAINTYMINIFRAMESTATICTEXT1,
              label='Choose state variable(s) to be analyzed:',
              name='staticText1', parent=self, pos=wx.Point(24, 16),
              size=wx.Size(226, 16), style=0)

        self.staticText2 = wx.StaticText(id=wxID_UNCERTAINTYMINIFRAMESTATICTEXT2,
              label='Variables:', name='staticText2', parent=self,
              pos=wx.Point(24, 40), size=wx.Size(56, 16), style=0)

        self.varList = wx.CheckListBox(choices=['Y[0]', 'Y[1]'],
              id=wxID_UNCERTAINTYMINIFRAMEVARLIST, name='varList', parent=self,
              pos=wx.Point(24, 56), size=wx.Size(104, 40), style=wx.VSCROLL,
              validator=wx.DefaultValidator)
        self.varList.SetToolTipString('The checked variables will be retained in memory for analysis.')
        self.varList.SetThemeEnabled(True)
        self.varList.Bind(wx.EVT_CHECKLISTBOX, self.OnVarListChecklistbox,
              id=wxID_UNCERTAINTYMINIFRAMEVARLIST)
        self.varList.Bind(wx.EVT_LISTBOX, self.OnVarListListbox,
              id=wxID_UNCERTAINTYMINIFRAMEVARLIST)

        self.staticText4 = wx.StaticText(id=wxID_UNCERTAINTYMINIFRAMESTATICTEXT4,
              label='Number of runs (k):', name='staticText4', parent=self,
              pos=wx.Point(300, 16), size=wx.Size(106, 16), style=0)

        self.spinCtrl1 = wx.SpinCtrl(id=wxID_UNCERTAINTYMINIFRAMESPINCTRL1,
              initial=5, max=100000, min=2, name='spinCtrl1', parent=self,
              pos=wx.Point(416, 16), size=wx.Size(95, 22),
              style=wx.SP_ARROW_KEYS)
        self.spinCtrl1.SetToolTipString('Number of times model should be run.')
        self.spinCtrl1.SetRange(2, 100000)
        self.spinCtrl1.SetThemeEnabled(True)

        self.Donebutton = wx.Button(id=wxID_UNCERTAINTYMINIFRAMEDONEBUTTON,
              label='Done', name='Donebutton', parent=self, pos=wx.Point(576,
              400), size=wx.Size(80, 32), style=0)
        self.Donebutton.SetToolTipString('Hit here when done')
        self.Donebutton.SetThemeEnabled(True)
        self.Donebutton.Bind(wx.EVT_BUTTON, self.OnDonebuttonButton,
              id=wxID_UNCERTAINTYMINIFRAMEDONEBUTTON)

        self.priorList = wx.TextCtrl(id=wxID_UNCERTAINTYMINIFRAMEPRIORLIST,
              name='priorList', parent=self, pos=wx.Point(176, 56),
              size=wx.Size(224, 144), style=wx.VSCROLL | wx.TE_MULTILINE,
              value='uniform (0,2)')

        self.likList = wx.TextCtrl(id=wxID_UNCERTAINTYMINIFRAMELIKLIST,
              name='likList', parent=self, pos=wx.Point(176, 242),
              size=wx.Size(224, 144), style=wx.VSCROLL | wx.TE_MULTILINE,
              value='normal (1,1)')
        self.likList.SetToolTipString('List of likelihood functions for each state variable')

        self.staticText3 = wx.StaticText(id=wxID_UNCERTAINTYMINIFRAMESTATICTEXT3,
              label='Prior distributions:', name='staticText3', parent=self,
              pos=wx.Point(184, 40), size=wx.Size(99, 16), style=0)

        self.staticText5 = wx.StaticText(id=wxID_UNCERTAINTYMINIFRAMESTATICTEXT5,
              label='Likelihood functions:', name='staticText5', parent=self,
              pos=wx.Point(184, 224), size=wx.Size(114, 16), style=0)

        self.statusPanel = wx.TextCtrl(id=wxID_UNCERTAINTYMINIFRAMESTATUSPANEL,
              name='Statuspanel', parent=self, pos=wx.Point(424, 56),
              size=wx.Size(216, 328),
              style=wx.HSCROLL | wx.VSCROLL | wx.TE_MULTILINE,
              value='Status Report:')

        self.selAll = wx.Button(id=wxID_UNCERTAINTYMINIFRAMESELALL,
              label='Select All', name='selAll', parent=self, pos=wx.Point(24,
              112), size=wx.Size(88, 32), style=0)
        self.selAll.SetThemeEnabled(True)
        self.selAll.SetToolTipString('Press this button to select all variables in the above list.')
        self.selAll.Bind(wx.EVT_BUTTON, self.OnSelAllButton,
              id=wxID_UNCERTAINTYMINIFRAMESELALL)

    def __init__(self, parent):
        self._init_ctrls(parent)
        self.uncertainPars = None
        self.dataloaded = 0

    def createVarList(self, items):
        """
        Re-creates varList checkListBox from items received from the main frame
        """
        self.varList = wx.CheckListBox(choices=items,
            id=wxID_UNCERTAINTYMINIFRAMEVARLIST, name='varList', parent=self,
            pos= wx.Point(24, 56), size= wx.Size(142, 54), style=0,
            validator=wx.DefaultValidator)
        self.varList.SetToolTipString('the checked variables will have to be assigned prior distribution on the right, and likelihoods if available.\n'+'Total items: '+str(self.varList.GetCount()))

    def updatePriorList(self, n):
        """
        Updates the box of prior distributions with a list of uniform priors
        based on the number of state variables elected.
        """
        value = 'uniform(0,10)\n'*(n-1)
        value = value+'uniform(0,10)'
        self.priorList.SetValue(value)


    def saveSpecs(self):
        """
        Saves the specs of the last analysis ran.
        """
        fname = os.path.split(self.fileName)[1]
        fname = fname[:-4]+'_unc.spec'
        checkedvars = [self.varList.IsChecked(i) for i in range(self.varList.GetCount())]
        pr = self.priorList.GetValue()
        lk = self.likList.GetValue()
        nr = self.spinCtrl1.GetValue()
        uncSpecs = {'vars':checkedvars, 'priors':pr, 'liks':lk,'nruns':nr}
        f = open(fname,'w')
        pickle.dump(uncSpecs,f)
        f.close()

    def loadSpecs(self, fname):
        """
        Load specs from last uncertainty analysis ran from file fname.
        """
        f = open(fname,'r')
        uncSpecs = pickle.load(f)
        f.close()
        for i in range(len(uncSpecs['vars'])):
            if uncSpecs['vars'][i] == 1:
                self.varList.Check(i)

        self.priorList.SetValue(uncSpecs['priors'])
        self.likList.SetValue(uncSpecs['liks'])
        self.spinCtrl1.SetValue(uncSpecs['nruns'])

    def OnDonebuttonButton(self, event):
        """
        When clicked this button checks the information about the Bayesian melding analysis, saves it and open a dialog box for specification of a data file
        (containing the data to calculate the likelihoods).
        returns a dictionary (uncertainPars) with the data entered.
        """
        self.saveSpecs()


# TODO: Introduce more checks to avoid stupid errors!!!
#---check if the number of checked variables is the same as the number of priors available---------------------------------------------------------------
        self.statusPanel.AppendText('\nChecking selected variables...\n')
        nvars = self.varList.GetCount() # Get the totalnumber of variables in varlist
        sel = [self.varList.IsChecked(i) for i in range(nvars)] # returns a list with ones for selected variables and zeros for not selected.
        if 1 not in sel: # if no variable has been selected, warn the user
            dlg = wx.MessageDialog(self, 'Select at least one variable from the list.',
              'Caption', wx.OK | wx.ICON_INFORMATION)
            try:
                dlg.ShowModal()
            finally:
                dlg.Destroy()
        self.statusPanel.AppendText('Done!\n\n')

#---Check if the number of priors entered corresponds to the number of variable selected----------------------------------------------------------------------------
        self.statusPanel.AppendText('Checking number of prior distributions...\n')
        npriors = int(self.priorList.GetNumberOfLines()) # Number of priors available
        while strip(self.priorList.GetLineText(npriors-1)) == '': # avoid getting empty lines at the end of the eq. box
            npriors = npriors-1
            if npriors == 1:
                break

        s = sum(array(sel))
        if s != npriors:
            dlg = wx.MessageDialog(self, 'The number of priors specified must be the same as the number of variables selected.',
              'Mismatched  number of variables and priors', wx.OK | wx.ICON_INFORMATION)
            try:
                dlg.ShowModal()
            finally:
                dlg.Destroy()
        self.statusPanel.AppendText('Done!\n\n')

        self.statusPanel.AppendText('Checking Number of likelihoods...\n')
        nlhoods = int(self.likList.GetNumberOfLines()) # Number of Likelihoods available
        while strip(self.likList.GetLineText(nlhoods-1)) == '': # avoid getting empty lines at the end of the eq. box
            nlhoods = nlhoods-1
            if nlhoods <= 1:
                break
        self.statusPanel.AppendText('Done!\n\n')
        if not self.likList.GetLineText(0) =='': #read datafile
            self.statusPanel.AppendText('Reading data from file...\n')
            dlg = wx.FileDialog(self, "Open data file", ".", "", "*.txt", wx.OPEN)
            try:
                if dlg.ShowModal() == wx.ID_OK:
                    filename = dlg.GetPath()
                    f = open(filename)
                    data = f.readlines()
                    f.close()
                    self.dataloaded = 1
                    self.statusPanel.AppendText('Done!\n\n')
            finally:
                dlg.Destroy()

            if len(data) != nlhoods: #check data size
                dlg = wx.MessageDialog(self, 'Number of datasets (lines) on the chosen file do not correspond to the number of likelihoods specified. Please open the correct file.',
                  'Wrong data file size!', wx.OK | wx.ICON_INFORMATION)
                try:
                    dlg.ShowModal()
                finally:
                    dlg.Destroy()


            else:
                datafloat=[None]
                for i in range(len(data)):
                    try:
                        data[i] = data[i][0:data[i].find("\\")] #remove newline characters
                    finally:
                        data[i] = data[i].split(' ') # Split strings into lists
                        datafloat[i] = [float(j) for j in data[i]] #Turns the list elements into   floats
                data = datafloat


#---initializing lists and dictionaries to receive form data----------------------------------------------------------------------------
        priors = []
        lhoods = []
        dist = []
        params = []
        distl = []
        paramsl = []
        k = self.spinCtrl1.GetValue() #number of runs
        for i in range(npriors):
            st = strip(self.priorList.GetLineText(i)) #get prior defining strings
            dist.append(strip(st[:find(st,'(')])) #parse distribution name
            params.append(eval(st[find(st,'('):])) # parse parameters string and eval it to a tuple
        priors = (dist,params) #name of the dist and parameters
        print dist[i]
#---generating priors----------------------------------------------------------------------------
        self.statusPanel.AppendText('generating priors...\n')
        priords = [meld.genprior(dist[i],params[i],k) for i in range(npriors)] #list of arrays
        self.statusPanel.AppendText('done!\n\n')
#-------------------------------------------------------------------------------
#---check if there are likelihoods available----------------------------------------------------------------------------
        if not self.likList.GetLineText(0) == '':
            for j in range(nlhoods):
                stl = strip(self.likList.GetLineText(j))#get likelihood defining strings
                distl.append(strip(stl[:find(stl,'(')]))#parse distribution name
                paramsl.append(eval(stl[find(stl,'('):]))# parse parameters string and eval it to a tuple
            lhoods = (distl,paramsl) #name of the dist and parameters

#---calculating likelihoods----------------------------------------------------------------------------
            self.statuspanel.AppendText('calculating likelihoods...\n')
            lik = []
            for l in range (nlhoods):
                dat = data[l]
                lik.append(meld.Likeli(dat, distl[l],paramsl[l])) #calculates likelihoods f
        else:
            lik=[]



        self.statusPanel.AppendText('done!\n\n')
        self.uncertainPars = (priors, priords, lhoods, lik)
        self.statusPanel.AppendText('press the start button on the main panel.\n')
        self.Donebutton.Disable()

    def OnSelAllButton(self, event):
        """
        When this button is clicked, it checks all items on the list.
        """
        n = self.varList.GetCount()
        for i in range(n):
            self.varList.Check(i)
        sel = sum(array([self.varList.IsChecked(i) for i in range(n)]))
        self.updatePriorList(sel)

    def OnVarListChecklistbox(self, event):
        """
        Every time an item is checked in the variable list box,
        it calls for an update of prior list box.
        """
        n = self.varList.GetCount()
        sel = sum(array([self.varList.IsChecked(i) for i in range(n)]))
        self.updatePriorList(sel)

    def OnUncertaintyMiniFrameClose(self, event):
        event.Skip()

    def OnVarListListbox(self, event):
        event.Skip()