예제 #1
0
class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.padx = 3
        self.pady = 3
        self.grid()
        self.results = []
        self.playlists = []
        self.vids = []
        self.__createWidgets()

    def __createWidgets(self):
        self.__searchFields()
        self.__resultArea()
        self.__buttons()
        self.__markdownArea()
        self.bind('<Return>', self.search_button)

    def __buttons(self):
        self.resultSelect = Button(text='OK', state=DISABLED)
        self.resultSelect.grid(row=5, column=4, sticky=E,
                               padx=self.padx, pady=self.pady)
        self.status = Label(text="", bd=1, relief=SUNKEN, anchor=W)
        self.status.grid(row=9, column=0, columnspan=10, sticky=N + E + S + W)
        self.__vidButtons()
        self.__rmVidButtons()
        self.resultSelect.grid_forget()

    def __searchFields(self):
        Label(text="User", anchor=E).grid(row=0, column=0,
                                          padx=self.padx, pady=self.pady,
                                          sticky=W)
        self.user_entry = Entry()
        self.user_entry.grid(row=0, column=1, padx=self.padx, pady=self.pady,
                             sticky=W)
        Label(text="Search terms").grid(row=0, column=3,
                                        padx=self.padx, pady=self.pady,
                                        sticky=W)
        self.search_terms = Entry()
        self.search_terms.grid(row=0, column=4,
                               padx=self.padx, pady=self.pady,
                               sticky=W)
        Label(text="playlist id").grid(row=1, column=3,
                                       padx=self.padx, pady=self.pady,
                                       sticky=W)
        self.playlist_id = Entry()
        self.playlist_id.grid(row=1, column=4, padx=self.padx, pady=self.pady,
                              sticky=W)
        self.search_button = Button(text="Search", command=self.__search)
        self.search_button.grid(row=2, column=4,
                                padx=self.padx, pady=self.pady, sticky=E)

    def __resultArea(self):
        self.result_label = Label(text="Results")
        self.result_label.grid(row=2, column=0,
                               padx=self.padx, pady=self.pady,
                               sticky=W)
        self.resultshowbut = Button(text="View", command=self.__showResults)
        self.resultshowbut.grid(row=2, column=1, sticky=W)
        self.yScroll = Scrollbar(orient=VERTICAL)
        self.xScroll = Scrollbar(orient=HORIZONTAL)
        self.listbox = Listbox(xscrollcommand=self.xScroll.set,
                                yscrollcommand=self.yScroll.set,
                                selectmode=SINGLE)
        self.xScroll.config(command=self.listbox.xview)
        self.yScroll.config(command=self.listbox.yview)

    def __showResults(self):
        self.resultshowbut.config(text="Hide", command=self.__hideResults)
        self.yScroll.grid(row=3, column=5, sticky=N + S)
        self.xScroll.grid(row=4, column=0, sticky=E + W, columnspan=5)
        self.listbox.grid(row=3, column=0, sticky=N + S + E + W, columnspan=5)
        self.markdownarea.config(height=10)

    def __hideResults(self):
        self.resultshowbut.config(text="View", command=self.__showResults)
        self.yScroll.grid_forget()
        self.xScroll.grid_forget()
        self.listbox.grid_forget()
        self.markdownarea.config(height=30)

    def __markdownArea(self):
        self.markdownlabel = Label(text="Markdown")
        self.mdyScroll = Scrollbar(orient=VERTICAL)
        self.mdxScroll = Scrollbar(orient=HORIZONTAL)
        self.markdownarea = Text(wrap=WORD, height=10,
                                 yscrollcommand=self.mdyScroll.set,
                                 xscrollcommand=self.mdxScroll.set)
        self.copymarkdown = Button(text="Copy To Clipboard",
                                  command=self.__copyMarkdown)
        self.mdxScroll.config(command=self.markdownarea.xview)
        self.mdyScroll.config(command=self.markdownarea.yview)

    def __vidButtons(self):
        self.modtitle = Button(text='Modify titles', command=self.__modTitles)
        #self.modtitle.grid(row=5, column=0, sticky=W, columnspan=2,
        #                   padx=self.padx, pady=self.pady)
        self.getcaps = Button(text="Get captions", command=self.__getCaptions)
        self.getcaps.grid(row=5, column=2, columnspan=3, sticky=E,
                          padx=self.padx, pady=self.pady)

    def __rmVidButtons(self):
        self.modtitle.grid_remove()
        self.getcaps.grid_remove()
        self.bind('<Return>', self.search_button)

    def __search(self):
        user = self.user_entry.get()
        playlist = self.playlist_id.get()
        searchterms = self.search_terms.get()
        self.__showResults()
        self.resultSelect.config(state=DISABLED)
        self.__rmVidButtons()
        self.__rmMarkdown()
        if not self.__validparams(user, searchterms, playlist):
            return False

        if len(playlist) > 0:
            self.__searchPlaylist(playlist)
            return

        self.__searchUser(user, searchterms)

    def __showMarkdown(self):
        self.markdownlabel.grid(row=5, column=0,
                                    padx=self.padx, pady=self.pady,
                                    sticky=W)
        self.markdownarea.grid(row=6, column=0, columnspan=5,
                               padx=self.padx, pady=self.pady,
                               sticky=N + S + E + W)
        self.mdyScroll.grid(row=6, column=5, sticky=N + S)
        self.mdxScroll.grid(row=7, column=0, sticky=E + W, columnspan=5)
        self.copymarkdown.grid(row=8, column=2, columnspan=3, sticky=E,
                          padx=self.padx, pady=self.pady)

    def __rmMarkdown(self):
        self.markdownarea.grid_forget()
        self.markdownlabel.grid_forget()
        self.copymarkdown.grid_forget()
        self.mdyScroll.grid_forget()
        self.mdxScroll.grid_forget()

    def __searchPlaylist(self, playlistid):
        self.__getvids(playlistid)

    def __searchUser(self, user, searchterms):
        self.listbox.delete(0, END)
        self.__status("Searching for%splaylists by user \"%s\"" % (
                      " \"%s\" " % searchterms if len(searchterms) else " ",
                      user))
        self.playlists = []
        try:
            self.playlists = lib.yt.search.PlaylistSearch(user=user,
                                                 search=searchterms).query()
        except HTTPError:
            self.__status("User %s does not exist at youtube" % user)
            return
        if self.playlists is None or len(self.playlists) == 0:
            self.__status("Search returned no results")
            return
        self.__populateResults([v['title'] for v in self.playlists])
        self.resultSelect.config(command=self.__getVidsFromSelected,
                                 state=NORMAL)
        self.__status("")
        self.resultSelect.grid(row=5, column=4, sticky=E,
                               padx=self.padx, pady=self.pady)

    def __populateResults(self, values):
        self.listbox.delete(0, END)
        for i, val in enumerate(values):
            self.listbox.insert(i, val)
        self.listbox.activate(0)
        self.listbox.selection_set(0)

    def __getVidsFromSelected(self):
        selected = int(self.listbox.curselection()[0])
        self.__getvids(self.playlists[selected]['id'])

    def __getvids(self, playlistid):
        self.playlist_id.delete(0, END)
        self.playlist_id.insert(0, playlistid)
        self.resultSelect.grid_forget()
        title = playlistid
        if len(self.playlists) > 0:
            for playlist in self.playlists:
                if playlist['id'] == playlistid:
                    title = playlist['title']
                    break

        self.__status("Getting videos for %s" % title)
        self.listbox.delete(0, END)
        try:
            self.vids = lib.yt.search.PlaylistVideoSearch(
                                                    id=playlistid).query()
            self.__populateResults([v['title'] for v in self.vids])
            self.__status("%d Videos found" % len(self.vids))
            self.__vidButtons()
            self.bind('<Return>', self.getcaps)
        except HTTPError:
            self.__status("No videos found! is %s a valid playlist?" %
                          playlistid)

    def __status(self, msg):
        if len(msg) > 75:
            msg = msg[:70] + '...'
        self.status.config(text=msg)
        self.status.update_idletasks()

    def __trackSelect(self, vid, tracks, preftrack=None):
        pref = self.__prefAvailable(preftrack, tracks)
        if pref is None:
            sel = lib.trackSelect.TrackSelect(self, vid=vid,
                                              tracks=tracks)
            if sel.result is None:
                self.__status("skipped")
                tracks = None
            else:
                tracks = [sel.result[0]]
                if sel.preflang is not None:
                    preftrack['lang'] = sel.preflang
                if sel.prefname is not None:
                    preftrack['name'] = sel.prefname
        else:
            tracks = pref
        return tracks, preftrack

    def __getCaptions(self):
        preftrack = {'name': None, 'lang': None}
        self.listbox.delete(0, END)
        self.markdownarea.delete(1.0, END)
        self.__showMarkdown()
        for i, vid in enumerate(self.vids):
            nocapmsg = '[%02d] --NO CAPTIONS-- %s' % (i + 1, vid['title'])
            tracks = lib.yt.search.CaptionSearch(id=vid['id']).query()
            self.vids[i]['text'] = ''
            if len(tracks) == 0:
                self.__status('No captions available for %s' %
                              self.vids[i]['title'])
                self.listbox.insert(END, nocapmsg)

            elif len(tracks) > 1:
                sel = self.__trackSelect(vid, tracks, preftrack)
                if sel[0] is None:
                    msg = '[%02d] --SKIPPED-- %s' % (i + 1, vid['title'])
                    self.listbox.insert(END, msg)
                    self.listbox.see(END)
                    continue
                tracks = sel[0]

            if len(tracks) == 1:
                self.__trackCaps(i, tracks, nocapmsg)
        self.__status('')
        self.__hideResults()

    def __trackCaps(self, vidIndex, tracks, nocapmsg):
        i = vidIndex
        vid = self.vids[i]
        msg = '%02d of %02d Getting captions for %s' % (
                        i + 1, len(self.vids), self.vids[i]['title'])
        self.__status(msg)
        self.listbox.insert(END, msg)
        self.vids[i]['text'] = lib.markdown.heading(vid['title'])
        captions = lib.yt.search.GetCaptions(id=vid['id'],
                                lang=tracks[0]['lang'],
                                name=tracks[0]['name'])
        captions.query()
        captiontext = captions.textOnly()
        sleep(0.2)
        msg = nocapmsg
        if captiontext is not None and len(captiontext) > 0:
            self.vids[i]['text'] += (lib.markdown.to_utf8(captiontext)
                                     + '\n\n')
            msg = '[%02d] --DONE-- %s' % (i + 1, vid['title'])
        self.listbox.delete(END, END)
        self.listbox.insert(END, msg)
        self.listbox.see(END)
        self.markdownarea.insert(END, self.vids[i]['text'])
        self.markdownarea.see(END)

    def __prefAvailable(self, preftrack, tracks):
        if preftrack['lang'] is None:
            return None

        pref = None
        for track in tracks:
            if (track['lang'] == preftrack['lang'] and
                track['name'] == preftrack['name']):
                return [track]
            if track['lang'] == preftrack['lang'] and pref is None:
                pref = [track]

        return pref

    def __modTitles(self):
        pass

    def __validparams(self, user, searchterms, playlist):
        if len(user) == 0 and len(playlist) == 0:
            msg = "Either a valid youtube user or playlist id must be given."
            tkMessageBox.showwarning("missing information", msg)
            return False

        if len(user) > 0 and not self.__validstring(user):
            msg = "The user given contains invalid characters"
            tkMessageBox.showwarning('Bad user', msg)
            return False

        if len(playlist) > 0 and not self.__validstring(playlist):
            msg = "The playlist given contains invalid characters"
            tkMessageBox.showwarning('Bad playlist', msg)
            return False

        if len(searchterms) > 0 and not self.__validstring(searchterms, True):
            msg = "The search terms given contain invalid characters"
            tkMessageBox.showwarning('Bad search', msg)
            return False

        return True

    def __validstring(self, s, spacechar=False):
        validchars = string.letters + string.digits + string.punctuation
        if spacechar:
            validchars += ' '
        for c in s:
            if c not in validchars:
                return False
        return True

    def __copyMarkdown(self):
        self.markdownarea.clipboard_clear()
        self.markdownarea.clipboard_append(self.markdownarea.get(1.0, END))
예제 #2
0
class RingArrangement(LabelFrame):
    def __init__(self, **kwargs):
        master = None if 'master' not in kwargs else kwargs['master']
        title = None if 'title' not in kwargs else kwargs['title']
        rings = [] if 'rings' not in kwargs else kwargs['rings']
        LabelFrame.__init__(self, master, text=title)
        self.config(padx=20, pady=5)
        self.rings = []
        self.addbut = Button(text='+', command=self.userAddRing)
        for ring in rings:
            self.addRing(ring)
        self.renderRings()

    def showAddBut(self):
        self.addbut.grid(in_=self, columnspan=2)

    def userAddRing(self):
        self.addRing()
        self.renderRings()

    def addRing(self, val=None):
        if val is None:
            if len(self.rings) > 0:
                val = self.rings[-1].val.get() + 2
            else:
                val = 10
        ring = RingEntry(pos=len(self.rings), master=self)
        ring.val.set(val)
        self.rings.append(ring)
        return ring

    def renderRing(self, ring):
        self.addbut.grid_forget()
        ring.render()
        ring.grid(in_=self)
        if len(self.rings) > 1:
            rmbut = Button(master=self, text='-', padx=3, pady=0,
                           command=lambda i=ring: self.removeRing(i))
            rmbut.grid(row=int(ring.grid_info()['row']), column=1, in_=self)
        self.showAddBut()

    def renderRings(self):
        for ring in self.rings:
            self.renderRing(ring)
        self.showAddBut()

    def removeRing(self, ring):
        if len(self.rings) == 1:
            return
        self.rings.pop(ring.pos())
        self.orderRings()
        for widget in self.children:
            self.children[widget].grid_remove()
        self.renderRings()

    def orderRings(self):
        for pos, ring in enumerate(self.rings):
            ring.pos(pos)

    def vals(self, ring=None):
        if ring is None:
            return tuple([int(x.Spin.get()) for x in self.rings])
        return int(self.rings[ring].Spin.get())
예제 #3
0
class Database:
    """Opens a window for inputing the properties of a compound."""
    def __init__(self, master, system, database):
        """The constructor method."""

        self.version = system.version
        self.fonttype = system.fonttype
        self.sfont = get_superfont(self.fonttype)
        self.master = master
        self.tframe = Frame(master.tframe)
        self.frame = Frame(master.frame)
        self.bframe = Frame(master.bframe)
        self.top = None

        self.system = system
        self.database = database  #the chemical database

        self.chemicals_list = self.database.keys()
        self.chemicals_list.sort()

        self.chemicaldatas = {}

        for name in self.chemicals_list:
            self.chemicaldatas[name] = ChemicalData(name)
            self.chemicaldatas[name].read_database(self.database[name])

    def make_widgets(self):

        self.insruction = Label(
            self.tframe,
            text=
            'Please provide the following fundamental properties for the chemicals:\n'
        )

        self.blankcolumn = Label(self.tframe, text=' ', width=1)
        self.editcolumn = Label(self.tframe, text=' ', width=6)
        self.delcolumn = Label(self.tframe, text=' ', width=6)
        self.namecolumn = Label(self.tframe, text=' ', width=18)
        self.formcolumn = Label(self.tframe, text=' ', width=10)
        self.tempcolumn = Label(self.tframe, text=' ', width=10)
        self.Dwcolumn = Label(self.tframe, text=' ', width=18)
        self.Koccolumn = Label(self.tframe, text=' ', width=18)
        self.Kdoccolumn = Label(self.tframe, text=' ', width=18)
        self.Refcolumn = Label(self.tframe, text=' ', width=18)
        self.endcolumn = Label(self.tframe, text=' ', width=2)

        self.namelabel = Label(self.tframe, text='Chemical name')
        self.formlabel = Label(self.tframe, text='Formula')
        self.templabel = Label(self.tframe, text='Temperature')
        self.Dwlabel = Label(self.tframe,
                             text='Molecular diffusivity\n in water')
        self.Koclabel = Label(self.tframe,
                              text='Organic carbon\n partition coefficient')
        self.Kdoclabel = Label(
            self.tframe,
            text='Dissolved organic carbon\n partition coefficient')
        self.Reflabel = Label(self.tframe, text='Reference')

        self.tempunits = Label(self.tframe, text=unichr(176) + 'C')
        self.Dwunits = Label(self.tframe, text=u'cm\u00B2/s')
        self.Kocunits = Label(self.tframe, text='log(L/kg)')
        self.Kdocunits = Label(self.tframe, text='log(L/kg)')

        self.addwidget = Button(self.bframe,
                                text='Add new chemicals',
                                command=self.addchemicaldata,
                                width=20)
        self.tempwidget = Button(self.bframe,
                                 text='Add new temperatures',
                                 command=self.addtempdata,
                                 width=20)
        self.importwidget = Button(self.bframe,
                                   text='Import database file',
                                   command=self.importchemicaldata,
                                   width=20)
        self.savebutton = Button(self.bframe,
                                 text='Save',
                                 command=self.OK,
                                 width=20)
        self.cancelbutton = Button(self.bframe,
                                   text='Cancel',
                                   command=self.cancel,
                                   width=20)

        self.botblankcolumn = Label(self.frame, text=' ', width=1)
        self.boteditcolumn = Label(self.frame, text=' ', width=6)
        self.botdelcolumn = Label(self.frame, text=' ', width=6)
        self.botnamecolumn = Label(self.frame, text=' ', width=18)
        self.botformcolumn = Label(self.frame, text=' ', width=10)
        self.bottempcolumn = Label(self.frame, text=' ', width=10)
        self.botDwcolumn = Label(self.frame, text=' ', width=18)
        self.botKoccolumn = Label(self.frame, text=' ', width=18)
        self.botKdoccolumn = Label(self.frame, text=' ', width=18)
        self.botRefcolumn = Label(self.frame, text=' ', width=18)
        self.botendcolumn = Label(self.frame, text=' ', width=2)

        self.blank1 = Label(self.bframe, text=' ')
        self.blank2 = Label(self.bframe, text=' ')
        self.blank3 = Label(self.bframe, text=' ')

        self.insruction.grid(row=0,
                             column=0,
                             sticky='W',
                             padx=1,
                             pady=1,
                             columnspan=11)

        self.blankcolumn.grid(row=1, column=0, sticky='WE', padx=1, pady=1)
        self.editcolumn.grid(row=1, column=1, sticky='WE', padx=1, pady=1)
        self.delcolumn.grid(row=1, column=2, sticky='WE', padx=1, pady=1)
        self.namecolumn.grid(row=1, column=3, sticky='WE', padx=1, pady=1)
        self.formcolumn.grid(row=1, column=4, sticky='WE', padx=1, pady=1)
        self.tempcolumn.grid(row=1, column=5, sticky='WE', padx=1, pady=1)
        self.Dwcolumn.grid(row=1, column=6, sticky='WE', padx=1, pady=1)
        self.Koccolumn.grid(row=1, column=7, sticky='WE', padx=1, pady=1)
        self.Kdoccolumn.grid(row=1, column=8, sticky='WE', padx=1, pady=1)
        self.Refcolumn.grid(row=1, column=9, sticky='WE', padx=1, pady=1)
        self.endcolumn.grid(row=1, column=10, sticky='WE', padx=1, pady=1)

        self.namelabel.grid(row=2, column=3, sticky='WE', padx=1, pady=1)
        self.formlabel.grid(row=2, column=4, sticky='WE', padx=1, pady=1)
        self.templabel.grid(row=2, column=5, sticky='WE', padx=1, pady=1)
        self.Dwlabel.grid(row=2, column=6, sticky='WE', padx=1, pady=1)
        self.Koclabel.grid(row=2, column=7, sticky='WE', padx=1, pady=1)
        self.Kdoclabel.grid(row=2, column=8, sticky='WE', padx=1, pady=1)
        self.Reflabel.grid(row=2, column=9, sticky='WE', padx=1, pady=1)

        self.tempunits.grid(row=3, column=5, sticky='WE', padx=1, pady=1)
        self.Dwunits.grid(row=3, column=6, sticky='WE', padx=1, pady=1)
        self.Kocunits.grid(row=3, column=7, sticky='WE', padx=1, pady=1)
        self.Kdocunits.grid(row=3, column=8, sticky='WE', padx=1, pady=1)

        #Bind the "return key" to the buttons

        self.updatechemicals()

    def updatechemicals(self, event=None):

        self.addwidget.grid_forget()
        self.tempwidget.grid_forget()
        self.savebutton.grid_forget()
        self.cancelbutton.grid_forget()
        self.blank1.grid_forget()
        self.blank2.grid_forget()

        self.chemicals_list = self.chemicaldatas.keys()
        self.chemicals_list.sort()
        row = 4

        namelabellength = 18
        formlabellength = 10
        Reflabellength = 18

        for name in self.chemicals_list:
            try:
                self.chemicaldatas[name].remove_chemicalwidgets()
            except:
                pass
            self.chemicaldatas[name].chemicalwidgets(self.frame, row,
                                                     self.master)
            row = row + 1

            if namelabellength < self.chemicaldatas[
                    name].namelabel.winfo_reqwidth() / 8:
                namelabellength = int(
                    self.chemicaldatas[name].namelabel.winfo_reqwidth() /
                    8) + 1
            if formlabellength < self.chemicaldatas[
                    name].formlabel.winfo_reqwidth() / 8:
                formlabellength = int(
                    self.chemicaldatas[name].formlabel.winfo_reqwidth() /
                    8) + 1
            if Reflabellength < self.chemicaldatas[
                    name].Reflabel.winfo_reqwidth() / 8:
                Reflabellength = int(
                    self.chemicaldatas[name].Reflabel.winfo_reqwidth() / 8) + 1

        self.namecolumn.config(width=namelabellength)
        self.formcolumn.config(width=formlabellength)
        self.Refcolumn.config(width=Reflabellength)

        self.botnamecolumn.config(width=namelabellength)
        self.botformcolumn.config(width=formlabellength)
        self.botRefcolumn.config(width=Reflabellength)

        self.botblankcolumn.grid(row=row,
                                 column=0,
                                 sticky='WE',
                                 padx=1,
                                 pady=1)
        self.boteditcolumn.grid(row=row, column=1, sticky='WE', padx=1, pady=1)
        self.botdelcolumn.grid(row=row, column=2, sticky='WE', padx=1, pady=1)
        self.botnamecolumn.grid(row=row, column=3, sticky='WE', padx=1, pady=1)
        self.botformcolumn.grid(row=row, column=4, sticky='WE', padx=1, pady=1)
        self.bottempcolumn.grid(row=row, column=5, sticky='WE', padx=1, pady=1)
        self.botDwcolumn.grid(row=row, column=6, sticky='WE', padx=1, pady=1)
        self.botKoccolumn.grid(row=row, column=7, sticky='WE', padx=1, pady=1)
        self.botKdoccolumn.grid(row=row, column=8, sticky='WE', padx=1, pady=1)
        self.botRefcolumn.grid(row=row, column=9, sticky='WE', padx=1, pady=1)
        self.botendcolumn.grid(row=row, column=10, sticky='WE', padx=1, pady=1)

        self.blank2.grid(row=row)
        row = row + 1
        self.addwidget.grid(row=row, columnspan=11)
        row = row + 1
        self.tempwidget.grid(row=row, columnspan=11)
        row = row + 1
        self.importwidget.grid(row=row, columnspan=11)
        row = row + 1
        self.savebutton.grid(row=row, columnspan=11)
        row = row + 1
        self.cancelbutton.grid(row=row, columnspan=11)
        row = row + 1
        self.blank3.grid(row=row)
        row = row + 1

        self.savebutton.bind('<Return>', self.OK)
        self.cancelbutton.bind('<Return>', self.cancel)

        self.focusbutton = self.cancelbutton
        self.master.geometry()
        self.master.center()

    def addchemicaldata(self, event=None):

        new_name = 'chemical' + str(len(self.chemicals_list))

        self.chemicaldatas[new_name] = ChemicalData(new_name)

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                DatabaseEditor(self.top,
                               self.system,
                               self.chemicaldatas[new_name],
                               self.chemicaldatas,
                               editflag=0,
                               tempflag=0))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.chemicaldatas[new_name].get_chemicaldata(self.top.window)
                self.chemicaldatas[self.chemicaldatas[new_name].
                                   name] = self.chemicaldatas[new_name].copy()

            del self.chemicaldatas[new_name]

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatechemicals()

    def importchemicaldata(self):

        UserPath = os.environ['USERPROFILE']
        Filepath = tkfd.askopenfilename(initialdir=UserPath)

        if Filepath != '':
            data = open(Filepath, 'r')
            database_imported = pickle.load(data)
            data.close()
            if self.top is None:
                self.top = CapSimWindow(master=self.master, buttons=2)
                self.top.make_window(
                    DatabaseImporter(self.top, self.system, database_imported))
                self.top.tk.mainloop()

                duplicate_name = []
                duplicate_temp = []

                if self.top.window.cancelflag == 0:
                    error_check = 0
                    for name in self.top.window.chemicals_list:
                        if self.top.window.importedchemicals[name].check == 1:
                            if self.chemicals_list.count(
                                    self.top.window.importedchemicals[name].
                                    name_new) == 0:
                                self.chemicals_list.append(
                                    self.top.window.importedchemicals[name].
                                    name_new)
                                self.chemicaldatas[
                                    self.top.window.importedchemicals[name].
                                    name_new] = ChemicalData(
                                        self.top.window.
                                        importedchemicals[name].name_new)
                                self.chemicaldatas[
                                    self.top.window.importedchemicals[name].
                                    name_new].read_database(
                                        self.top.window.importedchemicals[name]
                                    )
                            else:
                                for temp in self.top.window.importedchemicals[
                                        name].temps:
                                    if self.chemicaldatas[
                                            self.top.window.
                                            importedchemicals[name].
                                            name_new].temps.count(temp) == 0:
                                        self.chemicaldatas[
                                            self.top.window.
                                            importedchemicals[name].
                                            name_new].read_temperature(
                                                self.top.window.
                                                importedchemicals[name], temp)
                                    else:
                                        duplicate_name.append(
                                            self.top.window.
                                            importedchemicals[name].name_new)
                                        duplicate_temp.append(temp)
                                        error_check = 1
                    error_message = 'The following compound information are duplicated:\n\n'
                    for na in range(len(duplicate_name)):
                        error_message = error_message + '              ' + str(
                            duplicate_name[na]) + ' @ ' + str(
                                duplicate_temp[na]) + 'C \n'

                    if error_check == 1:
                        tkmb.showerror(title=self.system.version,
                                       message=error_message)

                if self.top is not None:
                    self.top.destroy()
                    self.top = None

            elif self.top is not None:
                tkmb.showerror(
                    title=self.system.version,
                    message=
                    'Please close the existing parameter input window first.')
                self.top.tk.focus()

        self.updatechemicals()

    def addtempdata(self, event=None):

        name = self.chemicals_list[0]

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                DatabaseEditor(self.top,
                               self.system,
                               self.chemicaldatas[name],
                               self.chemicaldatas,
                               editflag=0,
                               tempflag=1))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.chemicaldatas[
                    self.top.window.name.get()].get_chemicaldata(
                        self.top.window)

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatechemicals()

    def editchemicaldata(self, name):

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                DatabaseEditor(self.top,
                               self.system,
                               self.chemicaldatas[name],
                               self.chemicaldatas,
                               editflag=1,
                               tempflag=0))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.chemicaldatas[name].get_chemicaldata(self.top.window)

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatechemicals()

    def deletechemicaldata(self, name):

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                DatabaseDeleter(self.top, self.system,
                                self.chemicaldatas[name]))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.chemicaldatas[name].get_chemicaldata(self.top.window)
            if self.top.window.cancelflag == 2:
                self.chemicaldatas[name].remove_chemicalwidgets()
                del self.chemicaldatas[name]

            if self.top is not None:
                self.top.destroy()
                self.top = None

        self.updatechemicals()

    def cancel(self, event=None):

        self.exitflag = 1
        self.frame.quit()

    def OK(self, event=None):
        """Finish and move on."""

        self.database = {}
        for name in self.chemicals_list:
            chemicaldata = self.chemicaldatas[name]
            index = self.chemicals_list.index(name)
            self.database[name] = ChemicalDatabase(chemicaldata.name,
                                                   chemicaldata.formula,
                                                   index + 1, chemicaldata.MW)
            for temp in chemicaldata.temps:
                Dw = chemicaldata.Dw[temp]
                Kow = chemicaldata.Kow[temp]
                density = chemicaldata.density[temp]
                Ref = chemicaldata.Ref[temp]
                Koc = chemicaldata.Koc[temp]
                Kdoc = chemicaldata.Kdoc[temp]
                Kf = chemicaldata.Kf[temp]
                N = chemicaldata.N[temp]

                self.database[name].add_properties(temp, Kow, density, Ref, Dw,
                                                   Koc, Kdoc, Kf, N)

        self.exitflag = 1
        self.frame.quit()
예제 #4
0
class RingArrangement(LabelFrame):
    def __init__(self, **kwargs):
        master = None if 'master' not in kwargs else kwargs['master']
        title = None if 'title' not in kwargs else kwargs['title']
        rings = [] if 'rings' not in kwargs else kwargs['rings']
        LabelFrame.__init__(self, master, text=title)
        self.config(padx=20, pady=5)
        self.rings = []
        self.addbut = Button(text='+', command=self.userAddRing)
        for ring in rings:
            self.addRing(ring)
        self.renderRings()

    def showAddBut(self):
        self.addbut.grid(in_=self, columnspan=2)

    def userAddRing(self):
        self.addRing()
        self.renderRings()

    def addRing(self, val=None):
        if val is None:
            if len(self.rings) > 0:
                val = self.rings[-1].val.get() + 2
            else:
                val = 10
        ring = RingEntry(pos=len(self.rings), master=self)
        ring.val.set(val)
        self.rings.append(ring)
        return ring

    def renderRing(self, ring):
        self.addbut.grid_forget()
        ring.render()
        ring.grid(in_=self)
        if len(self.rings) > 1:
            rmbut = Button(master=self,
                           text='-',
                           padx=3,
                           pady=0,
                           command=lambda i=ring: self.removeRing(i))
            rmbut.grid(row=int(ring.grid_info()['row']), column=1, in_=self)
        self.showAddBut()

    def renderRings(self):
        for ring in self.rings:
            self.renderRing(ring)
        self.showAddBut()

    def removeRing(self, ring):
        if len(self.rings) == 1:
            return
        self.rings.pop(ring.pos())
        self.orderRings()
        for widget in self.children:
            self.children[widget].grid_remove()
        self.renderRings()

    def orderRings(self):
        for pos, ring in enumerate(self.rings):
            ring.pos(pos)

    def vals(self, ring=None):
        if ring is None:
            return tuple([int(x.Spin.get()) for x in self.rings])
        return int(self.rings[ring].Spin.get())
예제 #5
0
class Database:
    """Opens a window for inputing the properties of a compound."""
    def __init__(self, master, system, database):
        """The constructor method."""

        self.system = system
        self.version = system.version
        self.fonttype = system.fonttype
        self.sfont = get_superfont(self.fonttype)
        self.master = master
        self.tframe = Frame(master.tframe)
        self.frame = Frame(master.frame)
        self.bframe = Frame(master.bframe)
        self.top = None

        self.database = database  #the database of values

        self.exitflag = 0
        self.names = []  #a list of the chemical names

        solids_list = self.database.keys()
        solids_list.sort()

        self.solids_list = solids_list

        self.solids = []
        for solidname in solids_list:
            self.solids.append(Solid(solids_list.index(solidname)))
            self.solids[-1].read_database(self.database[solidname])

    def make_widgets(self):

        self.instructions = Label(
            self.tframe,
            text=
            'Please provide the following fundamental properties for the material:\n'
        )

        self.blankcolumn = Label(self.tframe,
                                 text='',
                                 font='courier 10',
                                 width=1)
        self.editcolumn = Label(self.tframe,
                                text='',
                                font='courier 10',
                                width=6)
        self.delcolumn = Label(self.tframe,
                               text='',
                               font='courier 10',
                               width=6)
        self.numbercolumn = Label(self.tframe,
                                  text='',
                                  font='courier 10',
                                  width=8)
        self.namecolumn = Label(self.tframe,
                                text='',
                                font='courier 10',
                                width=18)
        self.ecolumn = Label(self.tframe, text='', font='courier 10', width=8)
        self.rhocolumn = Label(self.tframe,
                               text='',
                               font='courier 10',
                               width=12)
        self.foccolumn = Label(self.tframe,
                               text='',
                               font='courier 10',
                               width=20)
        self.tortcolumn = Label(self.tframe,
                                text='',
                                font='courier 10',
                                width=18)
        self.sorpcolumn = Label(self.tframe,
                                text='',
                                font='courier 10',
                                width=18)
        self.refcolumn = Label(self.tframe,
                               text='',
                               font='courier 10',
                               width=15)

        self.numberlabel = Label(self.tframe, text='Number')
        self.namelabel = Label(self.tframe, text='Material')
        self.elabel = Label(self.tframe, text='Porosity')
        self.rholabel = Label(self.tframe, text='Bulk density')
        self.foclabel = Label(self.tframe, text='Organic carbon fraction')
        self.tortlabel = Label(self.tframe, text='Tortuosity correction')
        self.sorplabel = Label(self.tframe, text='Sorption isotherms')
        self.reflabel = Label(self.tframe, text='Reference')

        self.rhounitlabel = Label(self.tframe, text=u'g/cm\u00B3')

        self.botblankcolumn = Label(self.frame,
                                    text='',
                                    font='courier 10',
                                    width=1)
        self.boteditcolumn = Label(self.frame,
                                   text='',
                                   font='courier 10',
                                   width=6)
        self.botdelcolumn = Label(self.frame,
                                  text='',
                                  font='courier 10',
                                  width=6)
        self.botnumbercolumn = Label(self.frame,
                                     text='',
                                     font='courier 10',
                                     width=8)
        self.botnamecolumn = Label(self.frame,
                                   text='',
                                   font='courier 10',
                                   width=18)
        self.botecolumn = Label(self.frame,
                                text='',
                                font='courier 10',
                                width=8)
        self.botrhocolumn = Label(self.frame,
                                  text='',
                                  font='courier 10',
                                  width=12)
        self.botfoccolumn = Label(self.frame,
                                  text='',
                                  font='courier 10',
                                  width=20)
        self.bottortcolumn = Label(self.frame,
                                   text='',
                                   font='courier 10',
                                   width=18)
        self.botsorpcolumn = Label(self.frame,
                                   text='',
                                   font='courier 10',
                                   width=18)
        self.botrefcolumn = Label(self.frame,
                                  text='',
                                  font='courier 10',
                                  width=15)

        self.addwidget = Button(self.bframe,
                                text='Add solids',
                                command=self.addsolid,
                                width=20)
        self.savebutton = Button(self.bframe,
                                 text='Save',
                                 width=20,
                                 command=self.save)
        self.importwidget = Button(self.bframe,
                                   text='Import database file',
                                   command=self.importsoliddata,
                                   width=20)
        self.cancelbutton = Button(self.bframe,
                                   text='Cancel',
                                   command=self.cancel,
                                   width=20)

        self.blank1 = Label(self.bframe, text=' ')
        self.blank2 = Label(self.bframe, text=' ')
        self.blank3 = Label(self.bframe, text=' ')

        #show the widgets on the grid (top to bottom and left to right)

        self.instructions.grid(row=0,
                               column=0,
                               columnspan=11,
                               padx=8,
                               sticky='W',
                               pady=10)

        self.blankcolumn.grid(row=1, column=0, sticky='WE', padx=1, pady=1)
        self.editcolumn.grid(row=1, column=1, sticky='WE', padx=1, pady=1)
        self.delcolumn.grid(row=1, column=2, sticky='WE', padx=1, pady=1)
        self.numbercolumn.grid(row=1, column=3, sticky='WE', padx=1, pady=1)
        self.namecolumn.grid(row=1, column=4, sticky='WE', padx=1, pady=1)
        self.ecolumn.grid(row=1, column=5, sticky='WE', padx=1, pady=1)
        self.rhocolumn.grid(row=1, column=6, sticky='WE', padx=1, pady=1)
        self.foccolumn.grid(row=1, column=7, sticky='WE', padx=1, pady=1)
        self.tortcolumn.grid(row=1, column=8, sticky='WE', padx=1, pady=1)
        self.sorpcolumn.grid(row=1, column=9, sticky='WE', padx=1, pady=1)
        self.refcolumn.grid(row=1, column=10, sticky='WE', padx=1, pady=1)

        self.numberlabel.grid(row=2, column=3, sticky='WE', padx=1, pady=1)
        self.namelabel.grid(row=2, column=4, sticky='WE', padx=1, pady=1)
        self.elabel.grid(row=2, column=5, sticky='WE', padx=1, pady=1)
        self.rholabel.grid(row=2, column=6, sticky='WE', padx=1, pady=1)
        self.foclabel.grid(row=2, column=7, sticky='WE', padx=1, pady=1)
        self.tortlabel.grid(row=2, column=8, sticky='WE', padx=1, pady=1)
        self.sorplabel.grid(row=2, column=9, sticky='WE', padx=1, pady=1)
        self.reflabel.grid(row=2, column=10, sticky='WE', padx=1, pady=1)

        self.rhounitlabel.grid(row=3, column=6, sticky='WE', padx=1, pady=1)

        self.updatesolids()

        #Bind the "return key" to the buttons

        self.focusbutton = self.cancelbutton

    def updatesolids(self):

        self.addwidget.grid_forget()
        self.blank1.grid_forget()
        self.blank2.grid_forget()

        self.botblankcolumn.grid_forget()
        self.boteditcolumn.grid_forget()
        self.botdelcolumn.grid_forget()
        self.botnumbercolumn.grid_forget()
        self.botnamecolumn.grid_forget()
        self.botecolumn.grid_forget()
        self.botrhocolumn.grid_forget()
        self.botfoccolumn.grid_forget()
        self.bottortcolumn.grid_forget()
        self.botsorpcolumn.grid_forget()
        self.botrefcolumn.grid_forget()

        namelabellength = 18
        reflabellength = 15

        row = 4
        for solid in self.solids:
            try:
                solid.remove_propertieswidget()
            except:
                pass
            solid.number = self.solids.index(solid) + 1
            solid.propertieswidget(self.frame, row, self.master)
            row = row + 1

            if namelabellength < solid.namelabel.winfo_reqwidth() / 8:
                namelabellength = int(solid.namelabel.winfo_reqwidth() / 8) + 1
            if reflabellength < solid.reflabel.winfo_reqwidth() / 8:
                reflabellength = int(solid.reflabel.winfo_reqwidth() / 8) + 1

        self.namecolumn.config(width=namelabellength)
        self.botnamecolumn.config(width=namelabellength)
        self.refcolumn.config(width=reflabellength)
        self.botrefcolumn.config(width=reflabellength)

        self.botblankcolumn.grid(row=row,
                                 column=0,
                                 sticky='WE',
                                 padx=1,
                                 pady=1)
        self.boteditcolumn.grid(row=row, column=1, sticky='WE', padx=1, pady=1)
        self.botdelcolumn.grid(row=row, column=2, sticky='WE', padx=1, pady=1)
        self.botnumbercolumn.grid(row=row,
                                  column=3,
                                  sticky='WE',
                                  padx=1,
                                  pady=1)
        self.botnamecolumn.grid(row=row, column=4, sticky='WE', padx=1, pady=1)
        self.botecolumn.grid(row=row, column=5, sticky='WE', padx=1, pady=1)
        self.botrhocolumn.grid(row=row, column=6, sticky='WE', padx=1, pady=1)
        self.botfoccolumn.grid(row=row, column=7, sticky='WE', padx=1, pady=1)
        self.bottortcolumn.grid(row=row, column=8, sticky='WE', padx=1, pady=1)
        self.botsorpcolumn.grid(row=row, column=9, sticky='WE', padx=1, pady=1)
        self.botrefcolumn.grid(row=row, column=10, sticky='WE', padx=1, pady=1)
        row = row + 1

        row = 0
        self.blank1.grid(row=row)
        row = row + 1
        self.blank2.grid(row=row)
        row = row + 1
        self.addwidget.grid(row=row, columnspan=11)
        row = row + 1
        self.importwidget.grid(row=row, columnspan=11)
        row = row + 1
        self.savebutton.grid(row=row, columnspan=11)
        row = row + 1
        self.cancelbutton.grid(row=row, columnspan=11)
        row = row + 1
        self.blank3.grid(row=row)

        self.savebutton.bind('<Return>', self.save)
        self.cancelbutton.bind('<Return>', self.cancel)

        self.focusbutton = self.savebutton
        self.master.geometry()

    def addsolid(self):

        self.solids.append(Solid(self.solids[-1].number + 1))

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                SolidDatabaseEditor(self.top,
                                    self.system,
                                    self.solids[-1],
                                    self.solids,
                                    editflag=0))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.solids[-1].get_solid(self.top.window)
            else:
                self.solids.remove(self.solids[-1])

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatesolids()

    def editsolid(self, number):

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                SolidDatabaseEditor(self.top,
                                    self.system,
                                    self.solids[number - 1],
                                    self.solids,
                                    editflag=1))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.solids[number - 1].get_solid(self.top.window)

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatesolids()

    def importsoliddata(self):

        UserPath = os.environ['USERPROFILE']
        Filepath = tkfd.askopenfilename(initialdir=UserPath)

        if Filepath != '':
            data = open(Filepath, 'r')
            database_imported = pickle.load(data)
            data.close()
            if self.top is None:
                self.top = CapSimWindow(master=self.master, buttons=2)
                self.top.make_window(
                    SolidDatabaseImporter(self.top, self.system,
                                          database_imported))
                self.top.tk.mainloop()

                duplicate_name = []

                if self.top.window.cancelflag == 0:
                    error_check = 0
                    for solid in self.top.window.solids:
                        if solid.check == 1:
                            if self.solids_list.count(solid.name_new) == 0:
                                self.solids_list.append(solid.name_new)
                                self.solids.append(
                                    Solid(
                                        self.solids_list.index(
                                            solid.name_new)))
                                self.solids[-1].import_coefficients(solid)
                            else:
                                duplicate_name.append(solid.name_new)
                                error_check = 1

                    error_message = 'The following compound information are duplicated:\n\n'
                    for na in range(len(duplicate_name)):
                        error_message = error_message + '              ' + str(
                            duplicate_name[na]) + ' \n'

                    if error_check == 1:
                        tkmb.showerror(title=self.system.version,
                                       message=error_message)

                if self.top is not None:
                    self.top.destroy()
                    self.top = None

            elif self.top is not None:
                tkmb.showerror(
                    title=self.system.version,
                    message=
                    'Please close the existing parameter input window first.')
                self.top.tk.focus()

        self.updatesolids()

    def deletesolid(self, number):

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                SolidDatabaseDeleter(self.top, self.system,
                                     self.solids[number - 1]))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.solids[number - 1].remove_propertieswidget()
                self.solids.remove(self.solids[number - 1])

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatesolids()

    def save(self, event=None):

        self.database = self.write_database()

        self.exitflag = 1
        self.frame.quit()

    def cancel(self, event=None):

        self.exitflag = 1
        self.frame.quit()

    def exit(self, event=None):
        """Exit CapSim."""

        if tkmb.askyesno(self.version,
                         'Do you really want to exit CapSim?') == 1:
            sys.exit()

    def write_database(self):

        soliddatabase = {}
        for solid in self.solids:
            soliddatabase[solid.name] = SolidDatabase(solid.name, solid.number,
                                                      solid.e, solid.rho,
                                                      solid.foc, solid.tort,
                                                      solid.sorp, solid.Ref)

        return soliddatabase
예제 #6
0
class MatrixProperties:
    """Gets the contaminant properties."""

    def __init__(self, master, system, materials):

        """Constructor method. Defines the parameters to be obtained in this window."""

        self.master    = master
        self.fonttype  = system.fonttype
        self.version   = system.version
        self.superfont = get_superfont(self.fonttype) #superscript font
        self.tframe    = Frame(master.tframe)
        self.frame     = Frame(master.frame)
        self.bframe    = Frame(master.bframe)
        self.top       = None                   #flag for existence of toplevel#

        self.system    = system
        self.materials = materials

        if system.matrices is None:
            self.matrices  = []
            self.nmatrices = 0
        else:
            self.matrices  = system.matrices
            self.nmatrices = system.nmatrices


    def make_widgets(self):
        """Make the widgets for the window."""

        self.bgcolor      = self.frame.cget('bg')

        # Construct all label widgets used in the problem
        self.instructions = Label(self.tframe, text = ' Please select the potential layer materials and provide the following properties:                    ')

        self.blankcolumn    = Label(self.tframe,  text ='',  width = 1)
        self.editcolumn     = Label(self.tframe,  text =' ', width = 6)
        self.delcolumn      = Label(self.tframe,  text =' ', width = 6)
        self.namecolumn     = Label(self.tframe,  text =' ', width = 20)
        self.ecolumn        = Label(self.tframe,  text =' ', width = 15)
        self.rhocolumn      = Label(self.tframe,  text =' ', width = 15)
        self.foccolumn      = Label(self.tframe,  text =' ', width = 20)
        self.endcolumn      = Label(self.tframe,  text =' ', width = 2)

        self.namelabel      = Label(self.tframe,  text = 'Matrix')
        self.elabel         = Label(self.tframe,  text = 'Porosity')
        self.rholabel       = Label(self.tframe,  text = 'Bulk density' )
        self.foclabel       = Label(self.tframe,  text = 'Organic carbon fraction')

        self.rhounit        = Label(self.tframe,  text = u'g/cm\u00B3')

        self.botblankcolumn    = Label(self.frame,  text ='', width = 1)
        self.boteditcolumn     = Label(self.frame,  text =' ', width = 6)
        self.botdelcolumn      = Label(self.frame,  text =' ', width = 6)
        self.botnamecolumn     = Label(self.frame,  text =' ', width = 20)
        self.botecolumn        = Label(self.frame,  text =' ', width = 15)
        self.botrhocolumn      = Label(self.frame,  text =' ', width = 15)
        self.botfoccolumn      = Label(self.frame,  text =' ', width = 20)
        self.botendcolumn      = Label(self.frame,  text =' ', width = 2)

        self.blank1 = Label(self.bframe, text = ' ')
        self.blank2 = Label(self.bframe, text = ' ')
        self.blank3 = Label(self.bframe, text = ' ')

        self.addwidget  = Button(self.bframe, text = 'Add materials', command = self.addmatrix,  width = 20)
        self.loadwidget = Button(self.bframe, text = 'Load materials', command = self.loadmatrix,  width = 20)
        self.mixwidget  = Button(self.bframe, text = 'Create mixtures',  command = self.addmixture,  width = 20)

        #show the widgets on the grid
        self.instructions.grid(  row    = 0, column = 0, sticky = 'W',  padx = 8, columnspan = 6,)

        self.blankcolumn.grid(   row    = 1, column = 0, sticky = 'WE', padx = 1, pady = 1)
        self.editcolumn.grid(    row    = 1, column = 1, sticky = 'WE', padx = 1, pady = 1)
        self.delcolumn.grid(     row    = 1, column = 2, sticky = 'WE', padx = 1, pady = 1)
        self.namecolumn.grid(    row    = 1, column = 3, sticky = 'WE', padx = 1, pady = 1)
        self.ecolumn.grid(       row    = 1, column = 4, sticky = 'WE', padx = 1, pady = 1)
        self.rhocolumn.grid(     row    = 1, column = 5, sticky = 'WE', padx = 1, pady = 1)
        self.foccolumn.grid(     row    = 1, column = 6, sticky = 'WE', padx = 1, pady = 1)

        self.namelabel.grid(     row    = 2, column = 3, sticky = 'WE', padx = 1, pady = 1)
        self.elabel.grid  (      row    = 2, column = 4, sticky = 'WE', padx = 1, pady = 1)
        self.rholabel.grid (     row    = 2, column = 5, sticky = 'WE', padx = 1, pady = 1)
        self.foclabel.grid (     row    = 2, column = 6, sticky = 'WE', padx = 1, pady = 1)

        self.rhounit.grid (      row    = 3, column = 5, sticky = 'WE', padx = 1, pady = 1)

        self.updatematrices()


    def updatematrices(self):

        self.addwidget.grid_forget()
        self.loadwidget.grid_forget()
        self.blank1.grid_forget()

        self.botblankcolumn.grid_forget()
        self.boteditcolumn.grid_forget()
        self.botdelcolumn.grid_forget()
        self.botnamecolumn.grid_forget()
        self.botecolumn.grid_forget()
        self.botrhocolumn.grid_forget()
        self.botfoccolumn.grid_forget()

        material_list = self.materials.keys()
        for matrix in self.matrices:
            if len(matrix.components) == 1 :
                try: material_list.remove(matrix.name)
                except: pass

        row = 4

        for matrix in self.matrices:
            try: matrix.remove_propertieswidgets()
            except:pass
            matrix.number = self.matrices.index(matrix) + 1
            matrix.propertieswidgets(self.frame, row, self.master)
            row = row + 1

        self.botblankcolumn.grid(   row    = row, column = 0, sticky = 'WE', padx = 1, pady = 1)
        self.boteditcolumn.grid(    row    = row, column = 1, sticky = 'WE', padx = 1, pady = 1)
        self.botdelcolumn.grid(     row    = row, column = 2, sticky = 'WE', padx = 1, pady = 1)
        self.botnamecolumn.grid(    row    = row, column = 3, sticky = 'WE', padx = 1, pady = 1)
        self.botecolumn.grid(       row    = row, column = 4, sticky = 'WE', padx = 1, pady = 1)
        self.botrhocolumn.grid(     row    = row, column = 5, sticky = 'WE', padx = 1, pady = 1)
        self.botfoccolumn.grid(     row    = row, column = 6, sticky = 'WE', padx = 1, pady = 1)

        row = 0
        self.blank1.grid(row = row)
        row = row + 1
        self.blank2.grid(row = row)
        row = row + 1
        self.addwidget.grid(row = row, columnspan = 11)
        row = row + 1
        if len(material_list) > 0:
            self.loadwidget.grid(row = row, columnspan = 11)
            row = row + 1
        self.mixwidget.grid(row = row, columnspan = 11)
        row = row + 1

        self.addwidget.bind('<Return>', self.addmatrix)
        self.mixwidget.bind('<Return>', self.addmixture)
        if self.nmatrices == 0:     self.focusbutton = self.addwidget
        else:                       self.focusbutton = None
        self.master.geometry()
        self.master.center()

    def addmixture(self, default = None):

        self.nmatrices = self.nmatrices + 1
        self.matrices.append(Matrix(self.nmatrices))

        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(MixtureEditor(self.top, self.system, self.matrices[-1], self.matrices, self.materials, editflag = 0))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.matrices[-1].get_matrix(self.top.window)
            else:
                self.matrices.remove(self.matrices[-1])
                self.nmatrices = self.nmatrices - 1

            for component in self.matrices[-1].components:
                for matrix in self.matrices[:-1]:
                    for sub_component in matrix.components:
                        if sub_component.name == component.name:
                            sub_component.e   = component.e
                            sub_component.rho = component.rho
                            sub_component.foc = component.foc

                    if len(matrix.components) > 1:
                        e         = 0
                        rho       = 0
                        moc       = 0
                        foc       = 0
                        fractions = 0

                        for component in matrix.components:

                            fractions = fractions + component.fraction
                            e         = e         + component.fraction * component.e
                            rho       = rho       + component.fraction * component.rho
                            moc       = moc       + component.fraction * component.rho * component.foc

                        foc = moc/rho

                        matrix.e = (round(e,2))
                        matrix.rho = (round(rho,3))
                        matrix.foc = (round(foc,3))

                    else:
                        matrix.e          = matrix.components[-1].e
                        matrix.rho        = matrix.components[-1].rho
                        matrix.foc        = matrix.components[-1].foc

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatematrices()

    def addmatrix(self, default = None):

        self.nmatrices = self.nmatrices + 1
        self.matrices.append(Matrix(self.nmatrices))

        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(MatrixEditor(self.top, self.system, self.matrices[-1], self.matrices, self.materials, editflag = 0, newflag = 1))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.matrices[-1].get_matrix(self.top.window)
            else:
                self.matrices.remove(self.matrices[-1])
                self.nmatrices = self.nmatrices - 1

            if len(self.matrices) > 0:
                for component in self.matrices[-1].components:
                    for matrix in self.matrices[:-1]:
                        for sub_component in matrix.components:
                            if sub_component.name == component.name:
                                sub_component.e   = component.e
                                sub_component.rho = component.rho
                                sub_component.foc = component.foc

                        if len(matrix.components) > 1:
                            e         = 0
                            rho       = 0
                            moc       = 0
                            foc       = 0
                            fractions = 0

                            for component in matrix.components:

                                fractions = fractions + component.fraction
                                e         = e         + component.fraction * component.e
                                rho       = rho       + component.fraction * component.rho
                                moc       = moc       + component.fraction * component.rho * component.foc

                            foc = moc/rho

                            matrix.e = (round(e,2))
                            matrix.rho = (round(rho,3))
                            matrix.foc = (round(foc,3))

                        else:
                            matrix.e          = matrix.components[-1].e
                            matrix.rho        = matrix.components[-1].rho
                            matrix.foc        = matrix.components[-1].foc

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatematrices()

    def loadmatrix(self, default = None):

        self.nmatrices = self.nmatrices + 1
        self.matrices.append(Matrix(self.nmatrices))

        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(MatrixEditor(self.top, self.system, self.matrices[-1], self.matrices, self.materials, editflag = 0, newflag = 0))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.matrices[-1].get_matrix(self.top.window)
            else:
                self.matrices.remove(self.matrices[-1])
                self.nmatrices = self.nmatrices - 1

            if len(self.matrices) > 0:
                for component in self.matrices[-1].components:
                    for matrix in self.matrices[:-1]:
                        for sub_component in matrix.components:
                            if sub_component.name == component.name:
                                sub_component.e   = component.e
                                sub_component.rho = component.rho
                                sub_component.foc = component.foc

                        if len(matrix.components) > 1:
                            e         = 0
                            rho       = 0
                            moc       = 0
                            foc       = 0
                            fractions = 0

                            for component in matrix.components:

                                fractions = fractions + component.fraction
                                e         = e         + component.fraction * component.e
                                rho       = rho       + component.fraction * component.rho
                                moc       = moc       + component.fraction * component.rho * component.foc

                            foc = moc/rho

                            matrix.e = (round(e,2))
                            matrix.rho = (round(rho,3))
                            matrix.foc = (round(foc,3))

                        else:
                            matrix.e          = matrix.components[-1].e
                            matrix.rho        = matrix.components[-1].rho
                            matrix.foc        = matrix.components[-1].foc

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatematrices()

    def editmatrix(self, number):

        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            if len(self.matrices[number - 1].components) < 2: self.top.make_window(MatrixEditor(self.top, self.system, self.matrices[number-1], self.matrices, self.materials, editflag = 1, newflag = 0))
            else:                                             self.top.make_window(MixtureEditor(self.top, self.system,self.matrices[number-1], self.matrices, self.materials, editflag = 1))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.matrices[number-1].get_matrix(self.top.window)

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatematrices()

    def deletematrix(self, number):

        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(MatrixDeleter(self.top, self.system, self.matrices[number-1]))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.matrices[number-1].remove_propertieswidgets()
                self.matrices.remove(self.matrices[number-1])
                self.nmatrices = self.nmatrices - 1

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatematrices()


    def error_check(self):

        error = 0

        if self.nmatrices == 0: error = 1

        return error

    def warning(self):

        tkmb.showerror(title = self.version, message = 'No matrices has been selected, please add matrices by pressing the button "Add materials" or the button "Add mixture"')
        self.focusbutton = None
        self.master.tk.lift()
예제 #7
0
class BatchSolver:
    """Displays the progress of CapSim for the simulation."""
    def __init__(self, master, systems, type):
        """Constructor method."""

        self.sizeflag = 0
        self.master = master
        self.tframe = Frame(master.tframe)
        self.frame = Frame(master.frame)
        self.bframe = Frame(master.bframe)
        self.version = systems[0].version
        self.fonttype = systems[0].fonttype
        self.top = None
        self.output = None
        self.progress = StringVar(value='')  #percent complete
        self.remaintime = StringVar(value='')  #percent complete
        self.abort = IntVar()  #abort flag
        self.type = type
        self.parameters = []
        self.outputs = []
        for system in systems:
            self.parameters.append(Parameters(system))  #input system

    def make_widgets(self):
        """Makes widgets for the progress window while CapSim evaluates the
        system."""

        self.instructions1 = Label(
            self.frame, text='Please choose from the following options:')
        self.instructions2 = Label(
            self.frame,
            text=
            'Please wait while CapSim simulates transport through the system...'
        )
        self.blank1 = Label(self.frame, text=' ' * 51)
        self.blank2 = Label(self.frame, text=' ' * 51)
        self.blank3 = Label(self.frame, text='')
        self.blank4 = Label(self.frame, text='')
        self.blank5 = Label(self.frame, text='')
        self.blank6 = Label(self.frame, text='')
        self.progresswidget = Label(self.frame, textvariable=self.progress)
        self.timewidget = Label(self.frame, textvariable=self.remaintime)
        self.postwidget = Label(self.frame, text='Postprocessing...')

        self.startbutton = Button(self.frame,
                                  text='Begin Simulation',
                                  command=self.solve_system,
                                  width=20)
        self.abortbutton = Button(self.frame,
                                  text='Abort Run',
                                  command=self.abortrun,
                                  width=20)

        #show the widgets on the grid

        self.instructions1.grid(row=0, columnspan=2)
        self.blank1.grid(row=1, column=0)
        self.blank2.grid(row=1, column=1)
        self.blank3.grid(row=2)
        self.blank4.grid(row=3)
        self.startbutton.grid(row=4, columnspan=2, pady=1)

        #bind the buttons to the appropriate commands

        self.startbutton.bind('<Return>', self.solve_system)
        self.abortbutton.bind('<Return>', self.abortrun)

        self.focusbutton = self.startbutton

    def solve_system(self, event=0):
        """Makes the finite difference matrices to step forward in time, pre-
        allocates memory for the output information, clears the "run" screen,
        directs the system to the appropriate solver, and grids the "run
        progress" information and "abort" button."""

        #clear the screen and start the progress bar

        self.instructions1.grid_forget()
        self.startbutton.grid_forget()

        self.instructions2.grid(row=0, columnspan=2)
        self.progresswidget.grid(row=2, columnspan=2)
        self.blank3.grid(row=3)
        self.timewidget.grid(row=4, columnspan=2)
        self.blank4.grid(row=5)
        self.abortbutton.grid(row=6, columnspan=2)
        self.blank5.grid(row=7, columnspan=2)
        self.blank6.grid(row=8, columnspan=2)

        self.master.canvas.update()
        self.master.buttonframe.grid_forget()

        self.output = []

        start = timer.time()  #real time at t = 0

        for parameters in self.parameters:

            if self.abort.get() <> 1:

                if self.type == 'Separate': start = timer.time()

                sorp = parameters.sorp
                cons = parameters.con
                dep = parameters.dep
                tidal = parameters.tidal
                reac = parameters.reac
                bio = parameters.bio
                biomix = parameters.biomix

                variable_list = ['Cn', 'Fi', 'F', 'q', 'qm', 'W', 'Cw']

                Temp = {}
                for variable in variable_list:
                    Temp[variable] = []

                #determine the grid, time step size, and set up the equations for the
                #finite differencing

                parameters.make_uniform_grid()
                if bio == 1:
                    parameters.update_bioturbation()
                    parameters.make_grid_Dbiops()

                Fis, FisL, FisM = parameters.get_initial_component_fractions()
                Cn = parameters.get_initial_concentrations()
                Fis_plus_1 = {}
                FisL_plus_1 = {}
                FisM_plus_1 = {}
                for component in parameters.components:
                    Fis_plus_1[component.name] = [
                        Fi for Fi in Fis[component.name]
                    ]
                    FisL_plus_1[component.name] = [
                        Fi for Fi in FisL[component.name]
                    ]
                    FisM_plus_1[component.name] = [
                        Fi for Fi in FisM[component.name]
                    ]
                parameters.make_matrix_parameter_vectors(Cn, Fis, FisL)
                parameters.make_transport_parameter_vectors()
                parameters.make_reaction_parameter_vectors(Cn, Fis)
                parameters.update_time_dependents()
                parameters.make_matrices()

                output = Output(parameters)
                if output.sizeflag == 1: self.show_size_error()

                t = parameters.tstart
                n = 0

                if sorp == 1 or reac == 1:
                    parameters.update_nonlinear(Cn, Fis, FisL)

                results = output.converter(parameters, Cn, FisL)
                for variable in variable_list:
                    Temp[variable].append(
                        results[variable_list.index(variable)])

                t_start = 0
                t_end = 0

                while t < (parameters.tfinal_ori + parameters.delt *
                           (2 + parameters.steps)
                           ):  #loop through time to the simulation end

                    if dep == 1:
                        Cn, Fis_plus_1, FisL_plus_1, FisM_plus_1 = parameters.update_deposition(
                            Cn, Fis, FisL, FisM, t + parameters.delt)
                    parameters.update_time_dependents()
                    if cons == 1:
                        parameters.update_consolidation(
                            t + parameters.delt, parameters.Vdar)
                    if tidal == 1:
                        parameters.update_tidal(t + parameters.delt,
                                                parameters.U_plus_1)

                    if biomix == 1:
                        parameters.make_components_matrices()
                        Fis_plus_1, FisL_plus_1, FisM_plus_1 = parameters.get_Fis_plus_1(
                            Fis_plus_1, FisL_plus_1, FisM_plus_1)
                        parameters.make_matrix_parameter_vectors(
                            Cn, Fis_plus_1, FisL_plus_1)
                        parameters.make_reaction_parameter_vectors(
                            Cn, Fis_plus_1)

                    if (cons + tidal + biomix) > 0:
                        parameters.make_transport_parameter_vectors()

                    if (cons + tidal + dep + biomix + reac + sorp) > 0:
                        parameters.make_matrices()

                    if sorp == 1 or reac == 1:
                        Cn_plus_1 = parameters.non_linear_solver(
                            Cn, Fis_plus_1, FisL_plus_1)
                    else:
                        Cn_plus_1 = parameters.get_Cn_plus_1(Cn)

                    #collect the pertinent data from the time step
                    if parameters.averageoption == 'Instaneous':
                        if output.n < len(output.times) and round(
                                output.times[output.n], 8) < round(
                                    t + parameters.delt, 8):
                            output.store_no_dep(Cn, Cn_plus_1, t,
                                                t + parameters.delt,
                                                parameters, FisL, FisL_plus_1)
                    else:
                        new_results = output.converter(parameters, Cn_plus_1,
                                                       FisL_plus_1)
                        for variable in variable_list:
                            Temp[variable].append(
                                new_results[variable_list.index(variable)])

                        if len(Temp['Cn']) >= parameters.steps:
                            results_plus_1 = []
                            for variable in variable_list:
                                results_plus_1.append(Temp[variable][0])
                                for temp in Temp[variable][1:]:
                                    results_plus_1[
                                        -1] = results_plus_1[-1] + temp
                                results_plus_1[-1] = results_plus_1[-1] / len(
                                    Temp['Cn'])

                            t_middle = (t + parameters.delt -
                                        t_end) / 2 + t_end

                            output.store(t_start, t_middle, parameters,
                                         results, results_plus_1)

                            Temp = {}
                            for variable in variable_list:
                                Temp[variable] = []
                            results = results_plus_1
                            t_start = t_middle
                            t_end = t + parameters.delt

                    t = t + parameters.delt
                    Cn = [C for C in Cn_plus_1]
                    if biomix == 1:
                        Fis = {}
                        FisL = {}
                        FisM = {}
                        for component in parameters.components:
                            Fis[component.name] = [
                                Fi for Fi in Fis_plus_1[component.name]
                            ]
                            FisL[component.name] = [
                                Fi for Fi in FisL_plus_1[component.name]
                            ]
                            FisM[component.name] = [
                                Fi for Fi in FisM_plus_1[component.name]
                            ]

                    if self.type == 'Continuous':
                        self.progress.set(
                            'Simulation Progress: ' + str(int(t)) + ' / ' +
                            str(int(self.parameters[-1].tfinal_ori)) + ' ' +
                            self.parameters[-1].timeunit)
                        self.remaintime.set(
                            'Approximate Remaining Time: %d Seconds' %
                            ((timer.time() - start) *
                             (self.parameters[-1].tfinal - t) /
                             (t - self.parameters[0].tstart)))
                    else:
                        self.progress.set(
                            'Simulation Progress: ' +
                            str(self.parameters.index(parameters)) + ' / ' +
                            str(len(self.parameters)))
                        self.remaintime.set(
                            'Approximate Remaining Time: %d Seconds' %
                            ((timer.time() - start) * (parameters.tfinal - t) /
                             (t)))

                    self.frame.update()
                    if self.abort.get() == 1: break

                if self.abort.get() <> 1: self.outputs.append(output)

        if self.abort.get() == 0:  #checks if the abort button was invoked

            self.progresswidget.grid_forget()
            self.postwidget.grid(row=2, column=0, columnspan=3)
            self.frame.update()

        self.frame.quit()

    def abortrun(self, event=0):
        """Used to abort run."""

        if tkmb.askyesno(self.version, 'Do you really want to abort?') == 1:
            self.abort.set(1)
            self.output = None
            self.outputs = None
            self.frame.quit()

    def show_size_error(self):
        """Shows ann error if the user specifies an overly complicated system
        that requires too much memory allocation."""

        tkmb.showerror(title='Memory Error',
                       message='The parameters ' +
                       'you have specified require too much memory to be ' +
                       'computed.  Please decrease the simulation time ' +
                       'and/or the transport rates to rectify this issue.')
        self.frame.quit()
class ChemicalProperties:
    """Gets the contaminant properties."""
    def __init__(self, master, system, database):
        """Constructor method. Defines the parameters to be obtained in this window."""

        self.master = master
        self.fonttype = system.fonttype
        self.version = system.version
        self.superfont = get_superfont(self.fonttype)  #superscript font
        self.tframe = Frame(master.tframe)
        self.frame = Frame(master.frame)
        self.bframe = Frame(master.bframe)
        self.top = None  #flag for existence of toplevel#

        self.system = system
        self.database = database
        self.diffunit = system.diffunit
        self.concunit = system.concunit
        self.concunits = system.concunits

        if system.chemicals is None:
            self.chemicals = []
            self.nchemicals = 0
        else:
            self.chemicals = system.chemicals
            self.nchemicals = system.nchemicals

    def make_widgets(self):
        """Make the widgets for the window."""

        self.bgcolor = self.frame.cget('bg')

        # Construct all label widgets used in the problem
        self.instructions = Label(
            self.tframe,
            text=
            ' Please provide the following chemical properties:                    '
        )

        self.blankcolumn = Label(self.tframe, text='', width=1)
        self.editcolumn = Label(self.tframe, text='', width=6)
        self.delcolumn = Label(self.tframe, text='', width=6)
        self.numbercolumn = Label(self.tframe, text='', width=6)
        self.namecolumn = Label(self.tframe, text='', width=18)
        self.MWcolumn = Label(self.tframe, text='', width=8)
        self.tempcolumn = Label(self.tframe, text='', width=10)
        self.Dwcolumn = Label(self.tframe, text='', width=16)
        self.Koccolumn = Label(self.tframe, text='', width=16)
        self.Kdoccolumn = Label(self.tframe, text='', width=18)
        self.Refcolumn = Label(self.tframe, text='', width=17)
        self.endcolumn = Label(self.tframe, text='', width=1)

        self.botblankcolumn = Label(self.frame, text='', width=1)
        self.boteditcolumn = Label(self.frame, text='', width=6)
        self.botdelcolumn = Label(self.frame, text='', width=6)
        self.botnumbercolumn = Label(self.frame, text='', width=6)
        self.botnamecolumn = Label(self.frame, text='', width=18)
        self.botMWcolumn = Label(self.frame, text='', width=8)
        self.bottempcolumn = Label(self.frame, text='', width=10)
        self.botDwcolumn = Label(self.frame, text='', width=16)
        self.botKoccolumn = Label(self.frame, text='', width=16)
        self.botKdoccolumn = Label(self.frame, text='', width=18)
        self.botRefcolumn = Label(self.frame, text='', width=17)
        self.botendcolumn = Label(self.frame, text='', width=1)

        self.numberlabel = Label(self.tframe, text='Number')
        self.namelabel = Label(self.tframe, text='Chemical name')
        self.MWlabel = Label(self.tframe, text='Molecular\n Weight')
        self.templabel = Label(self.tframe, text='Temperature')
        self.Dwlabel = Label(self.tframe,
                             text='Molecular diffusivity\n in water')
        self.Koclabel = Label(self.tframe,
                              text='Organic carbon\n partition coefficient')
        self.Kdoclabel = Label(
            self.tframe,
            text='Dissolved organic carbon\n partition coefficient')
        self.Reflabel = Label(self.tframe, text='Reference')

        self.tempunits = Label(self.tframe, text=unichr(176) + 'C')
        self.Dwunits = Label(self.tframe, text=self.diffunit)
        self.Kocunits = Label(self.tframe, text='log(L/kg)')
        self.Kdocunits = Label(self.tframe, text='log(L/kg)')

        self.blank1 = Label(self.frame, text=' ')
        self.blank2 = Label(self.bframe, text=' ')

        self.addwidget = Button(self.bframe,
                                text='Add chemicals',
                                command=self.addchemical,
                                width=20)

        #show the widgets on the grid
        self.instructions.grid(row=0,
                               column=0,
                               columnspan=9,
                               padx=1,
                               sticky='W')

        self.blankcolumn.grid(row=1, column=0, sticky='WE', padx=1, pady=1)
        self.editcolumn.grid(row=1, column=1, sticky='WE', padx=1, pady=1)
        self.delcolumn.grid(row=1, column=2, sticky='WE', padx=1, pady=1)
        self.numbercolumn.grid(row=1, column=3, sticky='WE', padx=1, pady=1)
        self.namecolumn.grid(row=1, column=4, sticky='WE', padx=1, pady=1)
        self.MWcolumn.grid(row=1, column=5, sticky='WE', padx=1, pady=1)
        self.tempcolumn.grid(row=1, column=6, sticky='WE', padx=1, pady=1)
        self.Dwcolumn.grid(row=1, column=7, sticky='WE', padx=1, pady=1)
        self.Koccolumn.grid(row=1, column=8, sticky='WE', padx=1, pady=1)
        self.Kdoccolumn.grid(row=1, column=9, sticky='WE', padx=1, pady=1)
        self.Refcolumn.grid(row=1, column=10, sticky='WE', padx=1, pady=1)
        self.endcolumn.grid(row=1, column=11, sticky='WE', padx=1, pady=1)

        self.numberlabel.grid(row=2, column=3, sticky='WE', padx=1, pady=1)
        self.namelabel.grid(row=2, column=4, sticky='WE', padx=1, pady=1)
        self.MWlabel.grid(row=2, column=5, sticky='WE', padx=1, pady=1)
        self.templabel.grid(row=2, column=6, sticky='WE', padx=1, pady=1)
        self.Dwlabel.grid(row=2, column=7, sticky='WE', padx=1, pady=1)
        self.Koclabel.grid(row=2, column=8, sticky='WE', padx=1, pady=1)
        self.Kdoclabel.grid(row=2, column=9, sticky='WE', padx=1, pady=1)
        self.Reflabel.grid(row=2, column=10, sticky='WE', padx=1, pady=1)

        self.tempunits.grid(row=3, column=6, sticky='WE', padx=1, pady=1)
        self.Dwunits.grid(row=3, column=7, sticky='WE', padx=1, pady=1)
        self.Kocunits.grid(row=3, column=8, sticky='WE', padx=1, pady=1)
        self.Kdocunits.grid(row=3, column=9, sticky='WE', padx=1, pady=1)

        self.updatechemicals()

    def updatechemicals(self):

        try:
            self.botblankcolumn.grid_forget()
            self.boteditcolumn.grid_forget()
            self.botdelcolumn.grid_forget()
            self.botnumbercolumn.grid_forget()
            self.botnamecolumn.grid_forget()
            self.botMWcolumn.grid_forget()
            self.bottempcolumn.grid_forget()
            self.botDwcolumn.grid_forget()
            self.botKoccolumn.grid_forget()
            self.botKdoccolumn.grid_forget()
            self.botRefcolumn.grid_forget()
            self.botendcolumn.grid_forget()
        except:
            pass

        chemicals_list = self.database.keys()
        for chemical in self.chemicals:
            if chemical.soluable == 1:
                try:
                    chemicals_list.remove(chemical.name)
                except:
                    pass

        self.addwidget.grid_forget()

        namelabellength = 18
        reflabellength = 18

        row = 0

        for chemical in self.chemicals:
            try:
                chemical.remove_chemicalwidgets()
            except:
                pass
            chemical.number = self.chemicals.index(chemical) + 1
            chemical.chemicalwidgets(self.frame, row, self.master)
            row = row + 1

            if namelabellength < chemical.namelabel.winfo_reqwidth() / 8:
                namelabellength = int(
                    chemical.namelabel.winfo_reqwidth() / 8) + 1
            if reflabellength < chemical.Reflabel.winfo_reqwidth(
            ) / 8 * 1.1424219345:
                reflabellength = int(
                    chemical.Reflabel.winfo_reqwidth() / 8 * 1.1424219345) + 1

        self.namecolumn.config(width=namelabellength)
        self.Refcolumn.config(width=reflabellength)
        self.botnamecolumn.config(width=namelabellength)
        self.botRefcolumn.config(width=reflabellength)

        self.botblankcolumn.grid(row=row,
                                 column=0,
                                 sticky='WE',
                                 padx=1,
                                 pady=1)
        self.boteditcolumn.grid(row=row, column=1, sticky='WE', padx=1, pady=1)
        self.botdelcolumn.grid(row=row, column=2, sticky='WE', padx=1, pady=1)
        self.botnumbercolumn.grid(row=row,
                                  column=3,
                                  sticky='WE',
                                  padx=1,
                                  pady=1)
        self.botnamecolumn.grid(row=row, column=4, sticky='WE', padx=1, pady=1)
        self.botMWcolumn.grid(row=row, column=5, sticky='WE', padx=1, pady=1)
        self.bottempcolumn.grid(row=row, column=6, sticky='WE', padx=1, pady=1)
        self.botDwcolumn.grid(row=row, column=7, sticky='WE', padx=1, pady=1)
        self.botKoccolumn.grid(row=row, column=8, sticky='WE', padx=1, pady=1)
        self.botKdoccolumn.grid(row=row, column=9, sticky='WE', padx=1, pady=1)
        self.botRefcolumn.grid(row=row, column=10, sticky='WE', padx=1, pady=1)
        self.botendcolumn.grid(row=row, column=11, sticky='WE', padx=1, pady=1)

        row = 0
        self.blank2.grid(row=row)
        row = row + 1
        if len(chemicals_list) > 0:
            self.addwidget.grid(row=row, columnspan=11)
            row = row + 1

        self.addwidget.bind('<Return>', self.addchemical)

        if self.nchemicals == 0: self.focusbutton = self.addwidget
        else: self.focusbutton = None

        self.master.geometry()
        self.master.center()

    def addchemical(self, event=None):

        self.nchemicals = self.nchemicals + 1
        self.chemicals.append(Chemical(self.nchemicals, soluable=1))

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                ChemicalEditor(self.top,
                               self.system,
                               self.chemicals[-1],
                               self.chemicals,
                               self.database,
                               editflag=0))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.chemicals[-1].get_chemical(self.top.window)
            else:
                self.chemicals.remove(self.chemicals[-1])
                self.nchemicals = self.nchemicals - 1

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatechemicals()

    def editchemical(self, number):

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                ChemicalEditor(self.top,
                               self.system,
                               self.chemicals[number - 1],
                               self.chemicals,
                               self.database,
                               editflag=1))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.chemicals[number - 1].get_chemical(self.top.window)

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatechemicals()

    def deletechemical(self, number):

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                ChemicalDeleter(self.top, self.system,
                                self.chemicals[number - 1]))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.chemicals[number - 1].remove_chemicalwidgets()
                self.chemicals.remove(self.chemicals[number - 1])
                self.nchemicals = self.nchemicals - 1

            if self.top is not None:
                self.top.destroy()
                self.top = None

        self.updatechemicals()

    def error_check(self, event=None):
        """Finish and move on.  Checks that the number chemicals are less than the
        total number of chemicals in database."""

        error = 0
        if self.nchemicals == 0: error = 1

        return error

    def warning(self):

        tkmb.showerror(
            title=self.version,
            message=
            'No chemical has been selected, please add chemicals by pressing the button "Add chemicals"'
        )
        self.focusbutton = None
        self.master.tk.lift()
class ReactionCoefficients:
    """Gets the model types for each of the layers in the system."""
    def __init__(self, master, system, editflag):
        """Constructor method. Used to defines the layers."""

        self.master = master
        self.version = system.version
        self.fonttype = system.fonttype
        self.formulatype = system.formulatype
        self.superfont = get_superfont(self.fonttype)
        self.subfont = get_superfont(self.formulatype)
        self.tframe = Frame(master.tframe)
        self.frame = Frame(master.frame)
        self.bframe = Frame(master.bframe)
        self.bgcolor = self.frame.cget('bg')
        self.top = None

        self.system = system
        self.concunit = system.concunit
        self.timeunit = system.timeunit

        self.concunits = system.concunits

        # Convert mass concentration units to corresponding molar concentration units
        if self.concunit == system.concunits[0]:
            self.concunit = system.concunits[3]
        if self.concunit == system.concunits[1]:
            self.concunit = system.concunits[4]
        if self.concunit == system.concunits[2]:
            self.concunit = system.concunits[5]

        self.reactions = system.reactions
        self.layers = system.layers
        self.coefficients = system.coefficients

        if system.coefficients == None:
            self.coefficients = {}
            for layer in self.layers:
                layerindex = self.layers.index(layer)
                self.coefficients[layer.name] = {}
                for reaction in self.reactions:
                    self.coefficients[layer.name][reaction.name] = Coefficient(
                        layer, reaction)

        self.name_max = 0
        self.formula_max = 0
        self.rate_max = 0
        self.value_max = 0
        unitindex = 0

        tkfont = tkFont.Font(font=self.formulatype)
        tksubfont = tkFont.Font(font=self.superfont)
        tksuperfont = tkFont.Font(font=self.subfont)

        for reaction in self.reactions:
            if tkfont.measure(reaction.name) > self.name_max:
                self.name_max = tkfont.measure(reaction.name)
            if tkfont.measure(reaction.equation) > self.formula_max:
                self.formula_max = tkfont.measure(reaction.equation)

            rate_len = tkfont.measure(u'r = \u03BB')
            rate_len = rate_len + tksubfont.measure(str(reaction.number) + ',')
            rate_len = rate_len + tksubfont.measure(str(10))
            for reactant in reaction.reactants:
                if reactant.index <> 0:
                    rate_len = rate_len + tkfont.measure('C')
                    rate_len = rate_len + tksubfont.measure(reactant.formula)
                    if reactant.index == int(reactant.index):
                        index = int(reactant.index)
                    else:
                        index = reactant.index

                    if index <> 1.:
                        rate_len = rate_len + tksuperfont.measure(
                            str(index) + ' ')
                    unitindex = unitindex + reactant.index

            lam_len = tkfont.measure(u'\u03BB')
            lam_len = lam_len + tksubfont.measure(str(reaction.number) + ',')
            lam_len = lam_len + tksubfont.measure(str(10))
            lam_len = lam_len + tkfont.measure(' = ' + str(1000) + ' ')

            if unitindex == int(unitindex): unitindex = int(unitindex)
            if (unitindex - 1) != 0:
                if (unitindex - 1) != 1:
                    lam_len = lam_len + tkfont.measure('(' + self.concunit +
                                                       ')')
                    lam_len = lam_len + tksuperfont.measure(
                        str(-(unitindex - 1)))
                else:
                    lam_len = lam_len + tkfont.measure(self.concunit)
            lam_len = lam_len + tkfont.measure(self.timeunit)
            lam_len = lam_len + tksuperfont.measure('-1')

            if self.rate_max < rate_len: self.rate_max = rate_len
            if self.value_max < lam_len: self.value_max = lam_len

    def make_widgets(self):
        """Makes the widgets for the GUI."""

        self.instructions = Label(
            self.tframe,
            text='Please input the reaction information in each layer:        '
        )

        self.blankcolumn = Label(self.tframe,
                                 text='',
                                 font='courier 10',
                                 width=1)
        self.editcolumn = Label(self.tframe,
                                text='',
                                font='courier 10',
                                width=6)
        self.delcolumn = Label(self.tframe,
                               text='',
                               font='courier 10',
                               width=6)
        self.layercolumn = Label(self.tframe,
                                 text='',
                                 font='courier 10',
                                 width=10)
        self.namecolumn = Label(self.tframe,
                                text='',
                                font='courier 10',
                                width=max(int(self.name_max / 8) + 1, 15))
        self.equationcolumn = Label(self.tframe,
                                    text='',
                                    font='courier 10',
                                    width=max(
                                        int(self.formula_max / 8) + 1, 20))
        self.ratecolumn = Label(self.tframe,
                                text='',
                                font='courier 10',
                                width=max(int(self.rate_max / 8) + 1, 10))
        self.coefcolumn = Label(self.tframe,
                                text='',
                                font='courier 10',
                                width=max(int(self.value_max / 8) + 1, 10))
        self.endcolumn = Label(self.tframe,
                               text='',
                               font='courier 10',
                               width=1)

        self.layerlabel = Label(self.tframe, text='Layer')
        self.namelabel = Label(self.tframe, text='Reaction')
        self.equationlabel = Label(self.tframe, text='Chemical equation')
        self.ratelabel = Label(self.tframe, text='Rate equation')
        self.coeflabel = Label(self.tframe, text='Coefficient')

        self.botblankcolumn = Label(self.frame,
                                    text='',
                                    font='courier 10',
                                    width=1)
        self.boteditcolumn = Label(self.frame,
                                   text='',
                                   font='courier 10',
                                   width=6)
        self.botdelcolumn = Label(self.frame,
                                  text='',
                                  font='courier 10',
                                  width=6)
        self.botlayercolumn = Label(self.frame,
                                    text='',
                                    font='courier 10',
                                    width=10)
        self.botnamecolumn = Label(self.frame,
                                   text='',
                                   font='courier 10',
                                   width=max(int(self.name_max / 8) + 1, 15))
        self.botequationcolumn = Label(self.frame,
                                       text='',
                                       font='courier 10',
                                       width=max(
                                           int(self.formula_max / 8) + 1, 20))
        self.botratecolumn = Label(self.frame,
                                   text='',
                                   font='courier 10',
                                   width=max(int(self.rate_max / 8) + 1, 10))
        self.botcoefcolumn = Label(self.frame,
                                   text='',
                                   font='courier 10',
                                   width=max(int(self.value_max / 8) + 1, 10))
        self.botendcolumn = Label(self.frame,
                                  text='',
                                  font='courier 10',
                                  width=1)

        self.addwidget = Button(self.bframe,
                                text='Add reactions',
                                command=self.addcoefficient,
                                width=20)
        self.blank1 = Label(self.bframe, text=' ')
        self.blank2 = Label(self.bframe, text=' ')
        #self.blank3         = Label (self.frame, text = ' ')
        self.blank4 = Label(self.bframe, text=' ')
        self.topline = Label(self.frame, width=10, text='-' * 1000)

        #show the widgets on the grid

        self.instructions.grid(row=0,
                               column=0,
                               padx=8,
                               columnspan=6,
                               sticky='W')

        self.blankcolumn.grid(row=1, column=0, sticky='WE', padx=1)
        self.layercolumn.grid(row=1, column=1, sticky='WE', padx=4)
        self.editcolumn.grid(row=1, column=2, sticky='WE', padx=1, pady=1)
        self.delcolumn.grid(row=1, column=3, sticky='WE', padx=1, pady=1)
        self.namecolumn.grid(row=1, column=4, sticky='WE', padx=4)
        self.equationcolumn.grid(row=1, column=5, sticky='WE', padx=4)
        self.ratecolumn.grid(row=1, column=6, sticky='WE', padx=4)
        self.coefcolumn.grid(row=1, column=7, sticky='WE', padx=4)
        self.endcolumn.grid(row=1, column=8, sticky='WE', padx=4)

        self.layerlabel.grid(row=2, column=1, padx=1, sticky='WE', pady=4)
        self.namelabel.grid(row=2, column=4, padx=1, sticky='WE', pady=4)
        self.equationlabel.grid(row=2, column=5, padx=1, sticky='WE', pady=4)
        self.ratelabel.grid(row=2, column=6, padx=1, sticky='WE', pady=4)
        self.coeflabel.grid(row=2, column=7, padx=1, sticky='WE', pady=4)

        #self.blank3.grid(row = 3)

        self.updatecoefficients()

    def updatecoefficients(self):

        self.addwidget.grid_forget()
        self.blank1.grid_forget()
        self.blank2.grid_forget()
        self.topline.grid_forget()

        namelabellength = 15

        full_check = 1
        self.topline.grid(row=0, column=1, columnspan=7, sticky='WE', pady=1)

        row = 1
        for layer in self.layers:
            row_layer = row
            try:
                layer.remove_reactionwidgets()
            except:
                pass
            for reaction in self.reactions:
                try:
                    self.coefficients[layer.name][
                        reaction.name].remove_propertieswidgets()
                except:
                    pass
                if self.coefficients[layer.name][reaction.name].lam <> 0:
                    self.coefficients[layer.name][
                        reaction.name].propertieswidgets(
                            self.frame, row, self.master, self.formulatype,
                            self.superfont, self.subfont, self.timeunit,
                            self.concunit)
                    row = row + 1
                else:
                    full_check = 0
            layer.reactionwidgets(self.frame, row, row_layer)
            row = row + 2

        self.botblankcolumn.grid(row=row, column=0, sticky='WE', padx=1)
        self.botlayercolumn.grid(row=row, column=1, sticky='WE', padx=4)
        self.boteditcolumn.grid(row=row, column=2, sticky='WE', padx=1, pady=1)
        self.botdelcolumn.grid(row=row, column=3, sticky='WE', padx=1, pady=1)
        self.botnamecolumn.grid(row=row, column=4, sticky='WE', padx=4)
        self.botequationcolumn.grid(row=row, column=5, sticky='WE', padx=4)
        self.botratecolumn.grid(row=row, column=6, sticky='WE', padx=4)
        self.botcoefcolumn.grid(row=row, column=7, sticky='WE', padx=4)
        self.botendcolumn.grid(row=row, column=8, sticky='WE', padx=4)
        row = row + 1

        self.blank1.grid(row=row, columnspan=11, sticky='WE')
        row = row + 1
        self.blank2.grid(row=row, columnspan=11)
        row = row + 1
        if full_check == 0:
            self.addwidget.grid(row=row, columnspan=11)
            row = row + 1
        else:
            self.blank4.grid(row=row, columnspan=11)
            row = row + 1

        self.focusbutton = None
        self.master.geometry()
        self.master.center()

    def addcoefficient(self, event=None):

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                CoefficientEditor(self.top,
                                  self.system,
                                  self.coefficients[self.layers[0].name][
                                      self.reactions[0].name],
                                  self.coefficients,
                                  editflag=0))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.coefficients[self.top.window.layer.get()][
                    self.top.window.reaction.get()].get_coefficients(
                        self.top.window)

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatecoefficients()

    def editcoefficient(self, layername, reactionname):

        if self.top is None:

            self.top = CapSimWindow(master=self.master, buttons=2)
            self.top.make_window(
                CoefficientEditor(self.top,
                                  self.system,
                                  self.coefficients[layername][reactionname],
                                  self.coefficients,
                                  editflag=1))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.coefficients[layername][reactionname].get_coefficients(
                    self.top.window)

            if self.top is not None:
                self.top.destroy()
                self.top = None

        elif self.top is not None:
            tkmb.showerror(
                title=self.system.version,
                message=
                'Please close the existing parameter input window first.')
            self.top.tk.focus()

        self.updatecoefficients()

    def delcoefficient(self, layername, reactionname):

        self.coefficients[layername][reactionname].lam = 0

        self.updatecoefficients()

    def OK(self, event=None):
        """Finish and move on.  Checks that the number chemicals are less than the
        total number of chemicals in database."""

        if self.master.window.top is not None: self.master.open_toplevel()
        else: self.master.tk.quit()
class LayerProperties:
    """Input the parameters for each of the layers in the system."""

    def __init__(self, master, system, editflag = None):
        """Constructor method. Used to defines the layers."""
        
        self.fonttype     = system.fonttype
        self.version      = system.version
        self.master       = master
        self.frame        = Frame(master.frame)
        self.tframe       = Frame(master.tframe)
        self.bframe       = Frame(master.bframe)
        self.superfont    = get_superfont(self.fonttype)
        self.top          = None

        self.system       = system
        self.lengthunit   = system.lengthunit

        if system.layers is None:
            self.layers  = []
            self.nlayers = 0
        else:
            self.layers  = system.layers
            self.nlayers = system.nlayers

        self.editflag = editflag

        print(editflag)
        if editflag == 1:
            self.num_record         = [j for j in range(self.nlayers)]

    def make_widgets(self):
        """Make the widgets for the window."""
  
        self.instructions = Label(self.tframe,  text = 'Starting with the layer nearest the overlying water, please ' +
                                  'provide the following information for each layer:' + ' '*20, justify = 'left')

        self.blankcolumn    = Label(self.tframe, text = '', font = 'courier 10', width = 1)
        self.editcolumn     = Label(self.tframe, text = '', font = 'courier 10', width = 6)
        self.delcolumn      = Label(self.tframe, text = '', font = 'courier 10', width = 6)
        self.namecolumn     = Label(self.tframe, text = '', font = 'courier 10', width = 12)
        self.typecolumn     = Label(self.tframe, text = '', font = 'courier 10', width = 15)
        self.tortcolumn     = Label(self.tframe, text = '', font = 'courier 10', width = 20)
        self.thickcolumn    = Label(self.tframe, text = '', font = 'courier 10', width = 10)
        self.alphacolumn    = Label(self.tframe, text = '', font = 'courier 10', width = 15)
        self.doccolumn      = Label(self.tframe, text = '', font = 'courier 10', width = 20)
        self.endcolumn      = Label(self.tframe, text = '', font = 'courier 10', width = 2)
        #Title Widgets

        self.material    = Label(self.tframe, text = 'Material')
        self.tortuosity  = Label(self.tframe, text = 'Tortuosity Correction ')
        self.thickness   = Label(self.tframe, text = 'Thickness')
        self.alpha       = Label(self.tframe, text = 'Hydrodynamic\n'+'Dispersivity')
        self.doclabel    = Label(self.tframe, text = 'Dissolved organic\n'+'matter concentration   ')
        
        #Unit Widgets
        
        self.thickunits  = Label(self.tframe, text = self.lengthunit)
        self.alphaunits  = Label(self.tframe, text = self.lengthunit)
        self.docunits    = Label(self.tframe, text = 'mg/L')
        
        self.botblankcolumn    = Label(self.frame, text = '', font = 'courier 10', width = 1)
        self.boteditcolumn     = Label(self.frame, text = '', font = 'courier 10', width = 6)
        self.botdelcolumn      = Label(self.frame, text = '', font = 'courier 10', width = 6)
        self.botnamecolumn     = Label(self.frame, text = '', font = 'courier 10', width = 12)
        self.bottypecolumn     = Label(self.frame, text = '', font = 'courier 10', width = 15)
        self.bottortcolumn     = Label(self.frame, text = '', font = 'courier 10', width = 20)
        self.botthickcolumn    = Label(self.frame, text = '', font = 'courier 10', width = 10)
        self.botalphacolumn    = Label(self.frame, text = '', font = 'courier 10', width = 15)
        self.botdoccolumn      = Label(self.frame, text = '', font = 'courier 10', width = 20)
        self.botendcolumn      = Label(self.frame, text = '', font = 'courier 10', width = 2)
        #a special OK button is needed to check bioturbation depth
        
        self.blank1 = Label(self.bframe, text = ' ')
        self.blank2 = Label(self.bframe, text = ' ')

        self.addwidget  = Button(self.bframe, text = 'Add layers', command = self.addlayer, width = 20)

        #show the widgets on the grid
        self.instructions.grid(row = 0, column = 0, padx = 6, sticky = 'W', columnspan = 10)
        
        self.blankcolumn.grid(  row = 1,  column = 0)
        self.editcolumn.grid(   row = 1,  column = 1)
        self.delcolumn.grid(    row = 1,  column = 2)
        self.namecolumn.grid(   row = 1,  column = 3)
        self.typecolumn.grid(   row = 1,  column = 5)
        self.tortcolumn.grid(   row = 1,  column = 4)
        self.thickcolumn.grid(  row = 1,  column = 6)
        self.alphacolumn.grid(  row = 1,  column = 7)
        self.doccolumn.grid(    row = 1,  column = 8)
        self.endcolumn .grid(   row = 1,  column = 9)

        self.material.grid(     row = 2,  column = 4, padx = 0, sticky = 'N')
        self.tortuosity.grid(   row = 2,  column = 5, padx = 0, sticky = 'N')
        self.thickness.grid(    row = 2,  column = 6, padx = 0, sticky = 'N')
        self.alpha.grid(        row = 2,  column = 7, padx = 0, sticky = 'N')
        self.doclabel.grid(     row = 2,  column = 8, padx = 0, sticky = 'N')

        self.thickunits.grid(   row = 3,  column = 6, padx = 0)
        self.alphaunits.grid(   row = 3,  column = 7, padx = 0)
        self.docunits.grid(     row = 3,  column = 8, padx = 0)

        #make entry widgets for each of the layers
        self.updatelayers()
       
    def updatelayers(self):

        self.addwidget.grid_forget()
        self.blank1.grid_forget()
        self.blank2.grid_forget()

        namelabellength = 20

        for layer in self.layers:
            try: layer.remove_propertywidgets()
            except: pass
            if self.layers[0].number == 0:  layer.number = self.layers.index(layer)
            else:                           layer.number = self.layers.index(layer) + 1
            if layer.number == 0:           layer.name   = 'Deposition'
            else:                           layer.name   = 'Layer ' + str(layer.number)

        row = 4
        for layer in self.layers:
            layer.propertywidgets(self.frame, row, self.master)
            row = row + 1
            if namelabellength < layer.typelabel.winfo_reqwidth()/8:  namelabellength = int(layer.typelabel.winfo_reqwidth()/8) + 1

        self.typecolumn.config(width = namelabellength)
        self.bottypecolumn.config(width = namelabellength)

        self.botblankcolumn.grid(  row = row,  column = 0)
        self.boteditcolumn.grid(   row = row,  column = 1)
        self.botdelcolumn.grid(    row = row,  column = 2)
        self.botnamecolumn.grid(   row = row,  column = 3)
        self.bottypecolumn.grid(   row = row,  column = 5)
        self.bottortcolumn.grid(   row = row,  column = 4)
        self.botthickcolumn.grid(  row = row,  column = 6)
        self.botalphacolumn.grid(  row = row,  column = 7)
        self.botdoccolumn.grid(    row = row,  column = 8)
        self.botendcolumn .grid(   row = row,  column = 9)

        self.blank1.grid(row = row)
        row = row + 1
        self.blank2.grid(row = row)
        row = row + 1
        self.addwidget.grid(row = row, columnspan = 11)
        row = row + 1

        self.addwidget.bind('<Return>', self.addlayer)

        if self.nlayers == 0:   self.focusbutton = self.addwidget#self.okbutton
        else:                   self.focusbutton = None
        self.master.geometry()
        self.master.center()

    def addlayer(self, default = None):

        self.nlayers = self.nlayers + 1
        layertemp = Layer(1)

        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(LayerEditor(self.top, self.system, layertemp, self.layers, editflag = 0))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                layertemp.get_layer(self.top.window)
                if self.layers == []:            self.layers.append(layertemp)
                elif self.layers[0].number == 0: self.layers.insert( layertemp.number,    layertemp)
                elif layertemp.number == 0:      self.layers.insert( 0,                   layertemp)
                else:                            self.layers.insert( layertemp.number-1,  layertemp)

                if self.editflag == 1:
                    if self.layers[0].number == 0:
                        self.num_record.insert( layertemp.number,    -1)
                    elif layertemp.number == 0:
                        self.num_record.insert( 0,                   -1)
                    else:
                        self.num_record.insert( layertemp.number-1,  -1)

            else:
                self.nlayers = self.nlayers - 1
                layertemp = 0

            if self.top is not None:
                self.top.destroy()
                self.top = None
                
        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()


        self.updatelayers()

    def editlayer(self, number):
        
        if self.layers[0].number == 0: layertemp = self.layers[number]
        else:                          layertemp = self.layers[number-1]

        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(LayerEditor(self.top, self.system, layertemp, self.layers, editflag = 1))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                layertemp.get_layer(self.top.window)
               
            if self.top is not None:
                self.top.destroy()
                self.top = None
                
        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()
            
        self.updatelayers()
        
    def deletelayer(self, number):

        if self.layers[0].number == 0: layer = self.layers[number]
        else:                          layer = self.layers[number - 1]
        
        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(LayerDeleter(self.top, self.system, layer))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                layer.remove_propertywidgets()
                if self.editflag == 1:
                    new_record      = self.num_record[:self.layers.index(layer)] + self.num_record[self.layers.index(layer)+1:]
                    self.num_record = new_record
                self.layers.remove(layer)
                self.nlayers = self.nlayers - 1

            if self.top is not None:
                self.top.destroy()
                self.top = None
                
        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()
            
        self.updatelayers()

    def error_check(self, event = None):
        """Finish and move on.  Checks that the number chemicals are less than the
        total number of chemicals in database."""

        error = 0
        if self.nlayers == 0: error = 1
        elif self.nlayers == 1 and self.layers[0].number ==0: error = 1

        return error

    def warning(self):

        tkmb.showerror(title = self.version, message = 'No layer has been created, please add layers by pressing the button "Add layers"')
        self.focusbutton = None
        self.master.tk.lift()
예제 #11
0
class Product:
    def __init__(self, number):

        self.number = number
        self.soluable = 1

    def copy(self):

        product = Product(self.number)

        product.coef = self.coef
        product.MW = self.MW
        product.name = self.name
        product.formula = self.formula
        product.soluable = self.soluable

        return product

    def propertieswidgets(self, frame, row, master, chemical_list,
                          formula_list, MW_list):

        self.master = master

        self.chemical_list = chemical_list
        self.formula_list = formula_list
        self.MW_list = MW_list

        self.middlelabel = Label(frame, width=8, justify='center', text=' || ')
        self.delwidget = Button(frame,
                                width=5,
                                justify='center',
                                text='Delete',
                                command=self.del_product)
        self.namewidget = OptionMenu(frame,
                                     self.name,
                                     *chemical_list,
                                     command=self.click_name)
        self.coefwidget = Entry(frame,
                                width=8,
                                justify='center',
                                textvariable=self.coef)
        self.fwidget = Entry(frame,
                             width=8,
                             justify='center',
                             textvariable=self.formula,
                             font='Calibri 11')

        self.middlelabel.grid(row=row, column=5, padx=2, pady=1, sticky='WE')
        self.delwidget.grid(row=row, column=6, padx=2, pady=1)
        self.coefwidget.grid(row=row, column=7, padx=2, pady=1)
        self.namewidget.grid(row=row, column=8, padx=2, pady=1, sticky='WE')
        self.fwidget.grid(row=row, column=9, padx=2, pady=1, sticky='WE')

    def click_name(self, event=None):

        self.formula.set(self.formula_list[self.chemical_list.index(
            self.name.get())])
        self.MW.set(self.MW_list[self.chemical_list.index(self.name.get())])

    def del_product(self):

        self.master.window.delproduct(self.number)

    def get_product(self):

        self.coef = self.coef.get()
        self.name = self.name.get()
        self.formula = self.formula.get()
        self.MW = self.MW.get()

    def remove_propertieswidgets(self):

        self.master = 0
        self.delwidget.grid_forget()
        self.namewidget.grid_forget()
        self.coefwidget.grid_forget()
        self.fwidget.grid_forget()
        self.middlelabel.grid_forget()

        self.delwidget = 0
        self.namewidget = 0
        self.coefwidget = 0
        self.fwidget = 0
        self.middlelabel = 0

    def get_dynamic_sorption(self, chemical):

        self.coef = 1
        self.index = 1
        self.MW = chemical.MW
        self.name = chemical.name
        self.formula = ''
        self.soluable = 0

    def get_dynamic_desorption(self, chemical):

        self.coef = 1
        self.index = 1
        self.name = chemical.name
        self.formula = ''
        self.MW = chemical.MW
        self.soluable = 1
예제 #12
0
class Reactant:
    def __init__(self, number):

        self.number = number
        self.soluable = 1

    def copy(self):

        reactant = Reactant(self.number)

        reactant.coef = self.coef
        reactant.index = self.index
        reactant.name = self.name
        reactant.formula = self.formula
        reactant.MW = self.MW
        reactant.soluable = self.soluable

        return reactant

    def propertieswidgets(self, frame, row, master, chemical_list,
                          formula_list, MW_list):

        self.master = master

        self.chemical_list = chemical_list
        self.formula_list = formula_list
        self.MW_list = MW_list

        self.delwidget = Button(frame,
                                width=5,
                                justify='center',
                                text='Delete',
                                command=self.del_reactant)
        self.namewidget = OptionMenu(frame,
                                     self.name,
                                     *chemical_list,
                                     command=self.click_name)
        self.coefwidget = Entry(frame,
                                width=8,
                                justify='center',
                                textvariable=self.coef)
        self.fwidget = Entry(frame,
                             width=8,
                             justify='center',
                             textvariable=self.formula,
                             font='Calibri 11')
        self.middlelabel = Label(frame, width=8, justify='center', text=' || ')

        self.delwidget.grid(row=row, column=1, padx=2, pady=1)
        self.coefwidget.grid(row=row, column=2, padx=2, pady=1)
        self.namewidget.grid(row=row, column=3, padx=2, pady=1, sticky='WE')
        self.fwidget.grid(row=row, column=4, padx=2, pady=1, sticky='WE')
        self.middlelabel.grid(row=row, column=5, padx=2, pady=1, sticky='WE')

    def click_name(self, event=None):

        self.formula.set(self.formula_list[self.chemical_list.index(
            self.name.get())])
        self.MW.set(self.MW_list[self.chemical_list.index(self.name.get())])

        self.master.window.updaterateequation()

    def del_reactant(self):

        self.master.window.delreactant(self.number)

    def get_reactant(self):

        self.coef = self.coef.get()
        self.name = self.name.get()
        self.formula = self.formula.get()
        self.MW = self.MW.get()
        self.index = self.index.get()

    def indexwidgets(self, frame, row):

        self.label = Label(frame, text=self.name.get())
        self.widget = Entry(frame,
                            textvariable=self.index,
                            width=6,
                            justify='center')

        self.label.grid(row=row, column=0, padx=6, pady=2)
        self.widget.grid(row=row, column=1, padx=6, pady=2)

    def remove_indexwidgets(self):

        self.label.grid_forget()
        self.widget.grid_forget()

        self.label = 0
        self.widget = 0

    def remove_propertieswidgets(self):

        self.delwidget.grid_forget()
        self.namewidget.grid_forget()
        self.coefwidget.grid_forget()
        self.fwidget.grid_forget()
        self.middlelabel.grid_forget()
        try:
            self.label.grid_forget()
            self.widget.grid_forget()
        except:
            pass

        self.master = 0
        self.delwidget = 0
        self.namewidget = 0
        self.coefwidget = 0
        self.fwidget = 0
        self.middlelabel = 0

        self.label = 0
        self.widget = 0

    def get_dynamic_sorption(self, chemical, index):

        self.coef = 1
        self.index = index
        self.name = chemical.name
        self.formula = ''
        self.MW = chemical.MW
        self.soluable = 1

    def get_dynamic_desorption(self, chemical, index):

        self.coef = 1
        self.index = index
        self.name = chemical.name
        self.formula = ''
        self.MW = chemical.MW
        self.soluable = 0
예제 #13
0
class ReactionEditor:
    """Gets the chemical reaction information for each layer."""
    def __init__(self, master, system, reaction, editflag):
        """Constructor method.  Makes the GUI using the list of "Layer" objects
        "layers." """

        # Read the Tkinter information
        self.master = master
        self.fonttype = system.fonttype
        self.formulatype = system.formulatype
        self.version = system.version
        self.superfont = get_superfont(self.fonttype)
        self.subfont = get_superfont(self.formulatype)
        self.tframe = Frame(master.tframe)
        self.frame = Frame(master.frame)
        self.bframe = Frame(master.bframe)
        self.bgcolor = self.frame.cget('bg')
        self.top = None

        self.system = system

        # Read the system information
        self.chemicals = system.chemicals
        self.reaction = reaction
        self.editflag = editflag

        # Define the reaction chemical information
        self.chemical_list = [chemical.name for chemical in self.chemicals]
        self.formula_list = [chemical.formula for chemical in self.chemicals]
        self.MW_list = [chemical.MW for chemical in self.chemicals]

        self.models = ['Fundamental', 'User-defined']

        self.name = StringVar(value='Reaction ' + str(reaction.number))
        self.model = StringVar(value=self.models[0])
        self.reactants = []
        self.products = []

        #self.stoichcoef = reaction.stoichcoef
        if editflag == 1:

            self.name = StringVar(value=reaction.name)
            self.model = StringVar(value=reaction.model)
            self.reactants = [
                reactant.copy() for reactant in reaction.reactants
            ]
            self.products = [product.copy() for product in reaction.products]

            for reactant in self.reactants:
                reactant.coef = DoubleVar(value=reactant.coef)
                reactant.index = DoubleVar(value=reactant.index)
                reactant.name = StringVar(value=reactant.name)
                reactant.formula = StringVar(value=reactant.formula)
                reactant.MW = DoubleVar(value=reactant.MW)

            for product in self.products:
                product.coef = DoubleVar(value=product.coef)
                product.name = StringVar(value=product.name)
                product.formula = StringVar(value=product.formula)
                product.MW = DoubleVar(value=product.MW)

        self.cancelflag = 0

    def make_widgets(self):

        self.instructions = Label(
            self.frame,
            text=
            'Please input the following information for the added kinetic process:        '
        )

        self.reactblankcolumn = Label(self.frame, text=' ', width=2)
        self.reactdelcolumn = Label(self.frame, text=' ', width=6)
        self.reactcoefcolumn = Label(self.frame, text=' ', width=6)
        self.reactnamecolumn = Label(self.frame, text=' ', width=20)
        self.reactformcolumn = Label(self.frame, text=' ', width=10)
        self.middlecolumn = Label(self.frame, text=' ', width=14)
        self.proddelcolumn = Label(self.frame, text=' ', width=6)
        self.prodcoefcolumn = Label(self.frame, text=' ', width=6)
        self.prodnamecolumn = Label(self.frame, text=' ', width=20)
        self.prodformcolumn = Label(self.frame, text=' ', width=10)
        self.prodblankcolumn = Label(self.frame, text=' ', width=2)

        self.nameblank = Label(self.frame, text=' ', width=10)
        self.namelabel = Label(self.frame, text='Name:', width=10)
        self.namewidget = Entry(self.frame, textvariable=self.name, width=15)

        self.modellabel = Label(self.frame, text='Kinetic model:', width=10)
        self.modelwidget = OptionMenu(self.frame,
                                      self.model,
                                      *self.models,
                                      command=self.click_model)

        self.ratelabel = Label(self.frame, text='Rate equation:', width=10)

        self.reactlabel = Label(self.frame, text='Reactants')
        self.prodlabel = Label(self.frame, text='Products')

        self.reactcoeflabel = Label(self.frame,
                                    text='Stoichiometric\ncoefficient')
        self.reactnamelabel = Label(self.frame, text='Chemical')
        self.reactformlabel = Label(self.frame, text='Formula')
        self.prodcoeflabel = Label(self.frame,
                                   text='Stoichiometric\ncoefficient')
        self.prodnamelabel = Label(self.frame, text='Chemical')
        self.prodformlabel = Label(self.frame, text='Formula')

        self.addreactwidget = Button(self.frame,
                                     text='Add reactant',
                                     width=20,
                                     command=self.addreactant)
        self.addprodwidget = Button(self.frame,
                                    text='Add product',
                                    width=20,
                                    command=self.addproduct)
        self.okbutton = Button(self.frame,
                               text='OK',
                               width=20,
                               command=self.OK)
        self.cancelbutton = Button(self.frame,
                                   text='Cancel',
                                   width=20,
                                   command=self.Cancel)
        self.blank1 = Label(self.frame, text=' ')
        self.blank2 = Label(self.frame, text=' ')

        self.instructions.grid(row=0,
                               column=0,
                               padx=8,
                               sticky='W',
                               columnspan=11)

        self.nameblank.grid(row=1, column=0, padx=2, sticky='WE', columnspan=4)

        self.namelabel.grid(row=2, column=0, padx=2, sticky='E', columnspan=3)
        self.namewidget.grid(row=2, column=3, padx=2, sticky='W')

        self.modellabel.grid(row=2, column=4, padx=2, sticky='E')
        self.modelwidget.grid(row=2,
                              column=5,
                              padx=2,
                              sticky='W',
                              columnspan=2)

        self.ratelabel.grid(row=2, column=7, padx=2, sticky='E')

        self.reactblankcolumn.grid(row=3, column=0, padx=2, sticky='WE')
        self.reactdelcolumn.grid(row=3, column=1, padx=2, sticky='WE')
        self.reactcoefcolumn.grid(row=3, column=2, padx=2, sticky='WE')
        self.reactnamecolumn.grid(row=3, column=3, padx=2, sticky='WE')
        self.reactformcolumn.grid(row=3, column=4, padx=2, sticky='WE')
        self.middlecolumn.grid(row=3, column=5, padx=2, sticky='WE')
        self.proddelcolumn.grid(row=3, column=6, padx=2, sticky='WE')
        self.prodcoefcolumn.grid(row=3, column=7, padx=2, sticky='WE')
        self.prodnamecolumn.grid(row=3, column=8, padx=2, sticky='WE')
        self.prodformcolumn.grid(row=3, column=9, padx=2, sticky='WE')
        self.prodblankcolumn.grid(row=3, column=10, padx=2, sticky='WE')

        self.reactlabel.grid(row=4,
                             column=2,
                             padx=2,
                             sticky='WE',
                             columnspan=3)
        self.prodlabel.grid(row=4, column=7, padx=2, sticky='WE', columnspan=3)

        self.reactcoeflabel.grid(row=5, column=2, padx=2, sticky='WE')
        self.reactnamelabel.grid(row=5, column=3, padx=2, sticky='WE')
        self.reactformlabel.grid(row=5, column=4, padx=2, sticky='WE')

        self.prodcoeflabel.grid(row=5, column=7, padx=2, sticky='WE')
        self.prodnamelabel.grid(row=5, column=8, padx=2, sticky='WE')
        self.prodformlabel.grid(row=5, column=9, padx=2, sticky='WE')

        self.updatereaction()

        # Build a frame for Reaction rate

        self.focusbutton = None

    def click_model(self, event=None):

        check = 0
        reactant_list = [reactant.name.get() for reactant in self.reactants]
        for name in reactant_list:
            if reactant_list.count(name) > 1:
                check = 1

        if len(self.reactants) == 0:
            tkmb.showerror(
                title=self.system.version,
                message='Please firstly input the information of reactants.')
            self.model.set('Fundamental')
            self.focusbutton = self.okbutton
            self.master.tk.lift()

        elif check == 1:
            tkmb.showerror(
                title=self.system.version,
                message=
                'At least one chemical is replicated in the reactant list, please check'
            )
            self.model.set('Fundamental')
            self.focusbutton = self.okbutton
            self.master.tk.lift()

        else:
            if self.model.get() == 'User-defined':

                if self.top is None:
                    self.top = CapSimWindow(master=self.master, buttons=2)
                    self.top.make_window(
                        UserDefined(self.top, self.system, self.reactants))
                    self.top.tk.mainloop()

                    if self.top is not None:
                        self.top.destroy()
                        self.top = None

                elif self.top is not None:
                    tkmb.showerror(
                        title=self.system.version,
                        message=
                        'Please close the existing parameter input window first.'
                    )
                    self.top.tk.focus()

            self.updaterateequation()

    def updaterateequation(self):

        try:
            self.ratewidget.grid_forget()
        except:
            pass

        font = tkFont.Font(font=self.formulatype)
        subfont = tkFont.Font(font=self.subfont)
        superfont = tkFont.Font(font=self.superfont)

        if self.model.get() == 'Fundamental':

            rate_len = font.measure(u'r = \u03BB')
            for reactant in self.reactants:
                rate_len = rate_len + font.measure('C')
                rate_len = rate_len + subfont.measure(reactant.formula.get())
                if reactant.coef.get() == int(reactant.coef.get()):
                    coef = int(reactant.coef.get())
                else:
                    coef = reactant.coef.get()
                if coef <> 1.:
                    rate_len = rate_len + superfont.measure(str(coef) + ' ')
            self.ratewidget = Text(self.frame,
                                   width=int(rate_len * 1.1424219345 / 8) + 1,
                                   height=1,
                                   font=self.formulatype)
            self.ratewidget.insert('end', u'r = \u03BB')
            for reactant in self.reactants:
                self.ratewidget.insert('end', 'C')
                self.ratewidget.insert('end', reactant.formula.get(), 'sub')
                if reactant.coef.get() == int(reactant.coef.get()):
                    coef = int(reactant.coef.get())
                else:
                    coef = reactant.coef.get()
                if coef <> 1.:
                    self.ratewidget.insert('end', str(coef) + ' ', 'super')

        if self.model.get() == 'User-defined':

            rate_len = font.measure(u'r = \u03BB')
            for reactant in self.reactants:
                if reactant.index.get() <> 0:
                    rate_len = rate_len + font.measure('C')
                    rate_len = rate_len + subfont.measure(
                        reactant.formula.get())
                    if reactant.index.get() == int(reactant.index.get()):
                        index = int(reactant.index.get())
                    else:
                        index = reactant.index.get()
                    if index <> 1.:
                        rate_len = rate_len + superfont.measure(
                            str(index) + ' ')

            self.ratewidget = Text(self.frame,
                                   width=int(rate_len * 1.1424219345 / 8) + 1,
                                   height=1,
                                   font=self.formulatype)
            self.ratewidget.insert('end', u'r = \u03BB')
            for reactant in self.reactants:
                if reactant.index.get() <> 0:
                    self.ratewidget.insert('end', 'C')
                    self.ratewidget.insert('end', reactant.formula.get(),
                                           'sub')
                    if reactant.index.get() == int(reactant.index.get()):
                        index = int(reactant.index.get())
                    else:
                        index = reactant.index.get()
                    if index <> 1.:
                        self.ratewidget.insert('end',
                                               str(index) + ' ', 'super')

        self.ratewidget.tag_config('sub', offset=-4, font=self.subfont)
        self.ratewidget.tag_config('super', offset=5, font=self.superfont)
        self.ratewidget.tag_config('right', justify='right')
        self.ratewidget.config(state='disabled',
                               background=self.bgcolor,
                               borderwidth=0,
                               spacing3=3)

        self.ratewidget.grid(row=2, column=8, padx=2, sticky='W', columnspan=3)

    def updatereaction(self):

        try:
            self.addreactwidget.grid_forget()
            self.addprodwidget.grid_forget()
            self.okbutton.grid_forget()
            self.cancelbutton.grid_forget()
        except:
            pass

        self.updaterateequation()

        row = 6

        for reactant in self.reactants:
            try:
                reactant.remove_propertieswidgets()
            except:
                pass
            reactant.propertieswidgets(self.frame, row, self.master,
                                       self.chemical_list, self.formula_list,
                                       self.MW_list)
            row = row + 1

        row_reactant = row

        row = 6

        for product in self.products:
            try:
                product.remove_propertieswidgets()
            except:
                pass
            product.propertieswidgets(self.frame, row, self.master,
                                      self.chemical_list, self.formula_list,
                                      self.MW_list)
            row = row + 1

        if row < row_reactant: row = row_reactant

        self.blank1.grid(row=row)
        row = row + 1
        self.addreactwidget.grid(row=row, columnspan=11)
        row = row + 1
        self.addprodwidget.grid(row=row, columnspan=11)
        row = row + 1
        self.okbutton.grid(row=row, columnspan=11)
        row = row + 1
        self.cancelbutton.grid(row=row, columnspan=11)
        row = row + 1
        self.blank2.grid(row=row)

        self.okbutton.bind('<Return>', self.OK)
        self.focusbutton = self.okbutton

        self.master.geometry()

    def addreactant(self):

        self.reactants.append(Reactant(len(self.reactants) + 1))

        self.reactants[-1].coef = DoubleVar(value=1)
        self.reactants[-1].name = StringVar(value=self.chemical_list[0])
        self.reactants[-1].formula = StringVar(value=self.formula_list[0])
        self.reactants[-1].index = DoubleVar(value=1)
        self.reactants[-1].MW = DoubleVar(value=self.MW_list[0])

        self.updatereaction()

    def addproduct(self):

        self.products.append(Product(len(self.products) + 1))

        self.products[-1].coef = DoubleVar(value=1)
        self.products[-1].name = StringVar(value=self.chemical_list[0])
        self.products[-1].formula = StringVar(value=self.formula_list[0])
        self.products[-1].MW = StringVar(value=self.MW_list[0])

        self.updatereaction()

    def delreactant(self, number):

        self.reactants[number - 1].remove_propertieswidgets()
        self.reactants.remove(self.reactants[number - 1])

        self.updatereaction()

    def delproduct(self, number):

        self.products[number - 1].remove_propertieswidgets()
        self.products.remove(self.products[number - 1])

        self.updatereaction()

    def OK(self, event=None):
        """Finish and move on.  Checks that the number chemicals are less than the
        total number of chemicals in database."""

        if self.model.get() == 'Fundamental':
            for reactant in self.reactants:
                reactant.index.set(reactant.coef.get())

        check = 0

        chemicals = []
        for reactant in self.reactants:
            chemicals.append(reactant.name.get())
        for product in self.products:
            chemicals.append(product.name.get())

        for chemical in chemicals:
            if chemicals.count(chemical) > 1:
                check = 1

        if self.master.window.top is not None: self.master.open_toplevel()
        elif check == 1: self.reaction_error()
        else:
            for reactant in self.reactants:
                reactant.get_reactant()
                reactant.remove_propertieswidgets()

            for product in self.products:
                product.get_product()
                product.remove_propertieswidgets()

            if (len(self.reactants) + len(self.products)) == 0:
                self.cancelflag = 1
            self.master.tk.quit()

    def reaction_error(self):

        tkmb.showerror(
            title=self.version,
            message='At least one chemical has been replicated in the reaction!'
        )
        self.focusbutton = self.okbutton
        self.master.tk.lift()

    def Cancel(self):

        try:
            self.reactants = self.reaction.reactants
            self.products = self.reaction.products

        except:

            self.cancelflag = 1

        if self.master.window.top is not None: self.master.open_toplevel()
        else: self.master.tk.quit()
class ReactionProperties:
    """Gets the model types for each of the layers in the system."""

    def __init__(self, master, system):
        """Constructor method. Used to defines the layers."""
        
        self.master         = master
        self.system         = system
        self.version        = system.version
        self.fonttype       = system.fonttype
        self.formulatype    = system.formulatype
        self.superfont      = get_superfont(self.fonttype)
        self.subfont        = get_superfont(self.formulatype)
        self.tframe         = Frame(master.tframe)
        self.frame          = Frame(master.frame)
        self.bframe         = Frame(master.bframe)
        self.bgcolor        = self.frame.cget('bg')
        self.top            = None

        self.chemicals      = system.chemicals
        
        if master.master is None: self.defaults = 1

        if system.reactions is None: self.reactions      = []
        else:                        self.reactions      = system.reactions
        
    def make_widgets(self):
        """Makes the widgets for the GUI."""

        self.instructions   = Label(self.tframe,  text  = 'Please input the kinetic processes in the system:        ')

        self.blankcolumn    = Label(self.tframe,  text = '', font = 'courier 10',  width = 1 )
        self.editcolumn     = Label(self.tframe,  text = '', font = 'courier 10',  width = 6 )
        self.delcolumn      = Label(self.tframe,  text = '', font = 'courier 10',  width = 6 )
        self.numbercolumn   = Label(self.tframe,  text = '', font = 'courier 10',  width = 5 )
        self.namecolumn     = Label(self.tframe,  text = '', font = 'courier 10',  width = 15)
        self.equationcolumn = Label(self.tframe,  text = '', font = 'courier 10',  width = 20)
        self.ratecolumn     = Label(self.tframe,  text = '', font = 'courier 10',  width = 10)
        self.endcolumn      = Label(self.tframe,  text = '', font = 'courier 10',  width = 2)
        
        self.numberlabel    = Label(self.tframe,  text = 'Number')
        self.namelabel      = Label(self.tframe,  text = 'Name')
        self.equationlabel  = Label(self.tframe,  text = 'Chemical equation')
        self.ratelabel      = Label(self.tframe,  text = 'Rate equation')

        self.botblankcolumn    = Label(self.frame,  text = '', font = 'courier 10',  width = 1 )
        self.boteditcolumn     = Label(self.frame,  text = '', font = 'courier 10',  width = 6 )
        self.botdelcolumn      = Label(self.frame,  text = '', font = 'courier 10',  width = 6 )
        self.botnumbercolumn   = Label(self.frame,  text = '', font = 'courier 10',  width = 5 )
        self.botnamecolumn     = Label(self.frame,  text = '', font = 'courier 10',  width = 15)
        self.botequationcolumn = Label(self.frame,  text = '', font = 'courier 10',  width = 20)
        self.botratecolumn     = Label(self.frame,  text = '', font = 'courier 10',  width = 10)
        self.botendcolumn      = Label(self.frame,  text = '', font = 'courier 10',  width = 2)

        self.addwidget      = Button(self.bframe, text = 'Add reactions', command = self.addreaction, width = 20)
        self.blank1         = Label (self.bframe, text = ' ')
        self.blank2         = Label (self.bframe, text = ' ')
        #show the widgets on the grid

        self.instructions.grid( row = 0, column = 0, padx = 8, columnspan = 6, sticky = 'W')

        self.blankcolumn.grid(      row = 1, column = 0, padx = 1, sticky = 'WE', pady = 1)
        self.editcolumn.grid(       row = 1, column = 1, padx = 1, sticky = 'WE', pady = 1)
        self.delcolumn.grid(        row = 1, column = 2, padx = 1, sticky = 'WE', pady = 1)
        self.numbercolumn.grid(     row = 1, column = 3, padx = 4, sticky = 'WE')
        self.namecolumn.grid(       row = 1, column = 4, padx = 4, sticky = 'WE')
        self.equationcolumn.grid(   row = 1, column = 5, padx = 4, sticky = 'WE')
        self.ratecolumn.grid(       row = 1, column = 6, padx = 4, sticky = 'WE')
        self.endcolumn.grid(        row = 1, column = 7, padx = 4, sticky = 'WE')

        self.numberlabel.grid(      row = 2, column = 3, padx = 1, sticky = 'WE', pady = 4)
        self.namelabel.grid(        row = 2, column = 4, padx = 1, sticky = 'WE', pady = 4)
        self.equationlabel.grid(    row = 2, column = 5, padx = 1, sticky = 'WE', pady = 4)
        self.ratelabel.grid(        row = 2, column = 6, padx = 1, sticky = 'WE', pady = 4)

        self.updatereactions()
        
    def updatereactions(self):
        
        self.addwidget.grid_forget()
        self.blank1.grid_forget()
        self.blank2.grid_forget()

        namelabellength         = 15
        equationlabellength     = 20
        ratelabellength         = 10

        row = 4
        
        for reaction in self.reactions:
            try: reaction.remove_propertieswidgets()
            except:pass
            reaction.number = self.reactions.index(reaction) + 1
            reaction.propertieswidgets(self.frame, row, self.master, self.formulatype, self.superfont, self.subfont, self.bgcolor)
            row = row + 1

            if namelabellength     < reaction.namelabel.winfo_reqwidth()/8:  namelabellength     = int(reaction.namelabel.winfo_reqwidth()/8) + 1
            if equationlabellength < reaction.equalabel.winfo_reqwidth()/8:  equationlabellength = int(reaction.equalabel.winfo_reqwidth()/8) + 1
            if ratelabellength     < reaction.ratewidget.winfo_reqwidth()/8: ratelabellength     = int(reaction.ratewidget.winfo_reqwidth()/8) + 1

        self.botblankcolumn.grid(      row = row, column = 0, padx = 1, sticky = 'WE',pady = 1)
        self.boteditcolumn.grid(       row = row, column = 1, padx = 1, sticky = 'WE',pady = 1)
        self.botdelcolumn.grid(        row = row, column = 2, padx = 1, sticky = 'WE',pady = 1)
        self.botnumbercolumn.grid(     row = row, column = 3, padx = 4, sticky = 'WE')
        self.botnamecolumn.grid(       row = row, column = 4, padx = 4, sticky = 'WE')
        self.botequationcolumn.grid(   row = row, column = 5, padx = 4, sticky = 'WE')
        self.botratecolumn.grid(       row = row, column = 6, padx = 4, sticky = 'WE')
        self.botendcolumn.grid(        row = row, column = 7, padx = 4, sticky = 'WE')

        self.namecolumn.config(width     = namelabellength)
        self.equationcolumn.config(width = equationlabellength)
        self.ratecolumn.config(width     = ratelabellength)

        self.botnamecolumn.config(width     = namelabellength)
        self.botequationcolumn.config(width = equationlabellength)
        self.botratecolumn.config(width     = ratelabellength)


        row = 0

        self.blank1.grid(row = row)
        row = row + 1
        self.blank2.grid(row = row)
        row = row + 1

        self.addwidget.grid(row = row, columnspan = 11)
        row = row + 1

        self.focusbutton = None
        self.master.geometry()
        self.master.center()

    def addreaction(self, event = None):

        self.reactions.append(Reaction(len(self.reactions)+1))
        
        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(ReactionEditor(self.top, self.system, self.reactions[-1], editflag = 0))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0: self.reactions[-1].get_reaction(self.top.window)
            else:
                self.reactions.remove(self.reactions[-1])
                
            if self.top is not None:
                self.top.destroy()
                self.top = None
                
        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()
                    
        self.updatereactions()
                    
    def editreaction(self, number):

        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(ReactionEditor(self.top, self.system, self.reactions[number-1], editflag = 1))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0: self.reactions[number-1].get_reaction(self.top.window)
                
            if self.top is not None:
                self.top.destroy()
                self.top = None
                
        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()
        
        self.updatereactions()
        

    def delreaction(self, number):
        
        if self.top is None:

            self.top = CapSimWindow(master = self.master, buttons = 2)
            self.top.make_window(ReactionDeleter(self.top, self.system, self.reactions[number-1]))
            self.top.tk.mainloop()

            if self.top.window.cancelflag == 0:
                self.reactions[number-1].remove_propertieswidgets()
                self.reactions.remove(self.reactions[number-1])
                
            if self.top is not None:
                self.top.destroy()
                self.top = None
                
        elif self.top is not None:
            tkmb.showerror(title = self.system.version, message = 'Please close the existing parameter input window first.')
            self.top.tk.focus()
        
        self.updatereactions()
예제 #15
0
class MixtureEditor:
    """Gets the contaminant properties."""
    def __init__(self, master, system, matrix, matrices, materials, editflag):
        """Constructor method.  Defines the parameters to be obtained in this
        window."""

        self.master = master
        self.fonttype = system.fonttype
        self.version = system.version
        self.superfont = get_superfont(self.fonttype)  #superscript font
        self.tframe = Frame(master.tframe)
        self.frame = Frame(master.frame)
        self.bframe = Frame(master.bframe)
        self.top = None  #flag for existence of toplevel#

        self.matrix = matrix
        self.matrices = matrices
        self.materials = materials

        self.mixing_models = ['Linear', 'None']

        self.name = StringVar(value='Mixture')  #matrix name
        self.model = StringVar(value=self.mixing_models[0])  #model name
        self.e = DoubleVar()  #stores the porosity
        self.rho = DoubleVar()  #stores the bulk density
        self.foc = DoubleVar()  #stores the organic carbon fraction

        self.components = []  #components

        self.editflag = editflag
        self.cancelflag = 0

        if editflag == 1:  #Detemine whether the chemical is added or edited

            for component in self.matrix.components:
                self.components.append(component.copy())
                self.components[-1].name = StringVar(
                    value=self.components[-1].name)
                self.components[-1].mfraction = DoubleVar(
                    value=self.components[-1].mfraction)

            self.name.set(self.matrix.name)
            self.model.set(self.matrix.model)
            self.e.set(self.matrix.e)
            self.rho.set(self.matrix.rho)
            self.foc.set(self.matrix.foc)

    def make_widgets(self):
        """Make the widgets for the window."""

        self.bgcolor = self.frame.cget('bg')
        self.instructions = Label(
            self.frame,
            text=
            'Please provides the following information about the mixture:                    '
        )

        self.blank1 = Label(self.frame, text=' ', width=15)

        self.blankcolumn = Label(self.frame, text='   ', width=1)
        self.delcolumn = Label(self.frame, text=' ', width=6)
        self.compcolumn = Label(self.frame, text=' ', width=18)
        self.fraccolumn = Label(self.frame, text=' ', width=10)
        self.ecolumn = Label(self.frame, text=' ', width=10)
        self.rhocolumn = Label(self.frame, text=' ', width=15)
        self.foccolumn = Label(self.frame, text=' ', width=20)

        self.namelabel = Label(self.frame, text='Name')
        self.elabel = Label(self.frame, text='Porosity')
        self.rholabel = Label(self.frame,
                              text='Bulk density (' + u'g/cm\u00B3' + ')')
        self.foclabel = Label(self.frame, text='Organic carbon fraction')

        self.namewidget = Entry(self.frame,
                                textvariable=self.name,
                                justify='center',
                                width=16)
        self.ewidget = Entry(self.frame,
                             textvariable=self.e,
                             justify='center',
                             width=10)
        self.rhowidget = Entry(self.frame,
                               textvariable=self.rho,
                               justify='center',
                               width=10)
        self.focwidget = Entry(self.frame,
                               textvariable=self.foc,
                               justify='center',
                               width=10)

        self.complabel = Label(self.frame, text='Component')
        self.compflabel = Label(self.frame, text='Weight fraction')
        self.compelabel = Label(self.frame, text='Porosity')
        self.comprholabel = Label(self.frame,
                                  text='Bulk density (' + u'g/cm\u00B3' + ')')
        self.compfoclabel = Label(self.frame, text='Organic carbon fraction')

        self.addwidget = Button(self.frame,
                                text='Add components',
                                width=20,
                                command=self.add_components)
        self.loadwidget = Button(self.frame,
                                 text='Load components',
                                 width=20,
                                 command=self.load_components)
        self.esitimator = Button(self.frame,
                                 text='Estimate Mixture Properties',
                                 width=20,
                                 command=self.estimate_mixture)
        self.okbutton = Button(self.frame,
                               text='OK',
                               width=20,
                               command=self.OK)
        self.cancelbutton = Button(self.frame,
                                   text='Cancel',
                                   width=20,
                                   command=self.Cancel)
        self.blank1 = Label(self.frame, text=' ')
        self.blank2 = Label(self.frame, text=' ')
        self.blank3 = Label(self.frame, text=' ')

        #show the widgets on the grid
        self.instructions.grid(row=0,
                               column=0,
                               columnspan=7,
                               padx=8,
                               sticky='W')

        self.blank1.grid(row=1, column=0, columnspan=2)

        self.blankcolumn.grid(row=3, column=0, sticky='WE', padx=1, pady=1)
        self.delcolumn.grid(row=3, column=1, sticky='WE', padx=1, pady=1)
        self.compcolumn.grid(row=3, column=2, sticky='WE', padx=1, pady=1)
        self.fraccolumn.grid(row=3, column=3, sticky='WE', padx=1, pady=1)
        self.ecolumn.grid(row=3, column=4, sticky='WE', padx=1, pady=1)
        self.rhocolumn.grid(row=3, column=5, sticky='WE', padx=1, pady=1)
        self.foccolumn.grid(row=3, column=6, sticky='WE', padx=1, pady=1)

        self.namelabel.grid(row=4, column=2, sticky='WE', padx=4, pady=1)
        self.elabel.grid(row=4, column=4, sticky='WE', padx=1, pady=1)
        self.rholabel.grid(row=4, column=5, sticky='WE', padx=1, pady=1)
        self.foclabel.grid(row=4, column=6, sticky='WE', padx=1, pady=1)

        self.namewidget.grid(row=5, column=2, padx=4, pady=1)
        self.ewidget.grid(row=5, column=4, padx=1, pady=1)
        self.rhowidget.grid(row=5, column=5, padx=1, pady=1)
        self.focwidget.grid(row=5, column=6, padx=1, pady=1)

        self.blank3.grid(row=6, column=0, columnspan=2)

        self.complabel.grid(row=7, column=2, sticky='WE', padx=4, pady=1)
        self.compflabel.grid(row=7, column=3, sticky='WE', padx=1, pady=1)
        self.compelabel.grid(row=7, column=4, sticky='WE', padx=1, pady=1)
        self.comprholabel.grid(row=7, column=5, sticky='WE', padx=1, pady=1)
        self.compfoclabel.grid(row=7, column=6, sticky='WE', padx=1, pady=1)

        self.update_components()

    def update_components(self):

        try:
            self.addwidget.grid_forget()
            self.okbutton.grid_forget()
            self.cancelbutton.grid_forget()
        except:
            pass

        row = 8
        for component in self.components:
            try:
                component.get_component()
                component.remove_propertieswidgets()
            except:
                pass
            component.number = self.components.index(component) + 1
            component.propertieswidgets(self.frame, row, self.master,
                                        self.materials, self.matrices)
            row = row + 1

        self.blank1.grid(row=row)
        row = row + 1
        self.addwidget.grid(row=row, columnspan=11)
        row = row + 1
        self.loadwidget.grid(row=row, columnspan=11)
        row = row + 1
        self.esitimator.grid(row=row, columnspan=11)
        row = row + 1
        self.okbutton.grid(row=row, columnspan=11)
        row = row + 1
        self.cancelbutton.grid(row=row, columnspan=11)
        row = row + 1
        self.blank2.grid(row=row)

        self.okbutton.bind('<Return>', self.OK)
        self.focusbutton = self.okbutton
        self.master.geometry()

    def add_components(self, event=None):

        total_fraction = 0
        for component in self.components:
            total_fraction = total_fraction + component.mfraction.get()

        self.components.append(MatrixComponent(len(self.components) + 1))

        self.components[-1].name = ' '
        if total_fraction > 1: self.components[-1].mfraction = 0
        else: self.components[-1].mfraction = 1 - total_fraction
        self.components[-1].fraction = 0
        self.components[-1].e = 0
        self.components[-1].rho = 0
        self.components[-1].foc = 0

        self.update_components()

    def load_components(self, event=None):

        total_fraction = 0
        for component in self.components:
            total_fraction = total_fraction + component.mfraction.get()

        self.components.append(MatrixComponent(len(self.components) + 1))

        self.components[-1].name = ' '
        if total_fraction > 1: self.components[-1].mfraction = 0
        else: self.components[-1].mfraction = 1 - total_fraction

        self.update_components()

    def del_component(self, number):

        self.components[number - 1].remove_propertieswidgets()
        self.components.remove(self.components[number - 1])

        self.update_components()

    def estimate_mixture(self):

        total_fraction = 0
        for component in self.components:
            total_fraction = total_fraction + component.mfraction.get()

        if total_fraction <> 1.: self.fraction_error()
        else: self.calculate_matrix()

        self.frame.update()
        self.update_components()

    def OK(self, event=None):
        """Finish and move on.  Checks that the number chemicals are less than the
        total number of chemicals in database."""

        components_check = 0
        component_list = [component.name for component in self.components]

        for name in component_list:
            if component_list.count(name) > 1:
                components_check = 1

        if self.editflag == 0:
            check = [(matrix.name == self.name.get())
                     for matrix in self.matrices[0:-1]]
        else:
            check = [0]

        total_fraction = 0
        rho_flag = 0
        for component in self.components:
            total_fraction = total_fraction + component.mfraction.get()
            if component.rho.get() <= 0:
                rho_flag = 1

        if self.master.window.top is not None: self.master.open_toplevel()
        elif sum(check) >= 1 or self.name.get() == '': self.matrix_error()
        elif len(self.components) < 2: self.empty_component()
        elif total_fraction <> 1.: self.fraction_error()
        elif rho_flag == 1: self.rho_error()
        elif components_check == 1: self.replicate_error()
        else:
            self.calculate_matrix()
            self.master.tk.quit()

    def matrix_error(self):

        tkmb.showerror(
            title=self.version,
            message='This matrix has already been added to the matrix list!')
        self.focusbutton = self.okbutton
        self.master.tk.lift()

    def empty_component(self):

        tkmb.showerror(
            title=self.version,
            message='The mixture must consist at least two components')
        self.focusbutton = self.okbutton
        self.master.tk.lift()

    def fraction_error(self):

        tkmb.showinfo(self.version,
                      'The sum of the weight fraction is not 1, please check')
        self.focusbutton = self.okbutton
        self.master.tk.lift()

    def rho_error(self):

        tkmb.showinfo(
            self.version,
            'The bulk density of a component must be a positive value')
        self.focusbutton = self.okbutton
        self.master.tk.lift()

    def replicate_error(self):

        tkmb.showinfo(self.version,
                      'At least one component is replicated in the mixture')
        self.focusbutton = self.okbutton
        self.master.tk.lift()

    def Cancel(self):

        try:
            self.name.set(self.matrix.name)
            self.model.set(self.matrix.model)
            self.e.set(self.matrix.e)
            self.rho.set(self.matrix.rho)
            self.foc.set(self.matrix.foc)
            self.components = self.matrix.components

        except:
            self.cancelflag = 1

        if self.master.window.top is not None: self.master.open_toplevel()
        else: self.master.tk.quit()

    def calculate_matrix(self):

        rho_flag = 0

        e = 0
        rho = 0
        moc = 0
        foc = 0
        fractions = 0

        volume = 0

        for component in self.components:
            if component.rho.get() <= 0:
                rho_flag = 1

        if rho_flag == 1:
            self.rho_error()
        else:
            for component in self.components:

                component.get_component()
                component.remove_propertieswidgets()

                volume = volume + component.mfraction / component.rho

            for component in self.components:

                component.fraction = component.mfraction / component.rho / volume

                e = e + component.fraction * component.e
                rho = rho + component.fraction * component.rho
                moc = moc + component.fraction * component.rho * component.foc

            foc = moc / rho

            self.e.set(round(e, 6))
            self.rho.set(round(rho, 6))
            self.foc.set(round(foc, 6))