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))
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())
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()
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())
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
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()
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()
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
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
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()
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))