📄 hmmed.py
字号:
#!/usr/bin/env python################################################################################## This file is part of Gato (Graph Algorithm Toolbox) # version _VERSION_ from _BUILDDATE_. You can find more information at # http://www.zpr.uni-koeln.de/~gato## file: HMMEd.py# author: Alexander Schliep (schliep@zpr.uni-koeln.de)## Copyright (C) 1998-2002, Alexander Schliep, Winfried Hochstaettler and # ZAIK/ZPR, Universitaet zu Koeln# # Contact: schliep@zpr.uni-koeln.de, wh@zpr.uni-koeln.de ## Information: http://gato.sf.net## This library is free software; you can redistribute it and/or# modify it under the terms of the GNU Library General Public# License as published by the Free Software Foundation; either# version 2 of the License, or (at your option) any later version.## This library is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# Library General Public License for more details.## You should have received a copy of the GNU Library General Public# License along with this library; if not, write to the Free# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#### This file is version $Revision: 1875 $ # from $Date: 2007-08-01 15:11:01 +0200 (Wed, 01 Aug 2007) $# last change by $Author: grunau $.#################################################################################from DataStructures import Point2Dfrom Graph import Graphfrom Gred import *from GraphUtil import GraphInformer, VertexWeightfrom GraphDisplay import GraphDisplayfrom GatoUtil import stripPath, extensionfrom GatoGlobals import *from GraphEditor import EditWeightsDialogfrom tkFileDialog import askopenfilename, asksaveasfilenameimport tkMessageBoxfrom tkMessageBox import askokcancelimport tkSimpleDialog import whrandomimport stringimport typesimport copyimport ProbEditorBasicsimport ProbEditorDialogsimport xmlutilfrom xmlutil import NamedDistributions, XMLElementWriter, toprettyxml, DiscreteHMMAlphabet, HMMClass, HMMState, HMM import EditObjectAttributesDialogfrom EditObjectAttributesDialog import EditObjectAttributesDialog, ValidatingString, ValidatingInt, ValidatingFloat, PopupableInt, Probability, DefaultedInt, DefaultedStringfrom MapEditor import MapEditor, NamedCollectionEditorimport editobj, editobj.editor as editordef typed_assign(var, val): result = type(var)(val) result.__dict__ = var.__dict__ #result.__dict__ = copy.copy(var.__dict__) return resultdef listFromCSV(s, type): return map(type,string.split(s,','))def csvFromList(list, perRow = None): if perRow == None: return string.join(map(str,list), ', ') else: result = "" for start in xrange(0, len(list), perRow): result += string.join(map(str,list[start:start+perRow]), ', ') + ',\n' return result[0:len(result)-2] class ValidStringEditor(editor.StringEditor): require_right_menu = 0 def get_value(self): value = getattr(self.obj, self.attr, "") self.unicode = isinstance(value, unicode) return value def set_value(self, value): editor.Editor.set_value(self, ValidatingString(value))class ProbabilityEditor(editor.FloatEditor): def get_value(self): return str(getattr(self.obj, self.attr, "")) def set_value(self, value): editor.Editor.set_value(self, Probability(editor.editobj.eval(value)))class NamedDistributions(xmlutil.NamedDistributions ): def __init__(self, itsHMM): xmlutil.NamedDistributions.__init__(self, itsHMM) def editDistributions(self, master): editor = NamedCollectionEditor(master, self) def names(self): return self.dist.keys() def add(self, name): order = tkSimpleDialog.askinteger("Distribution %s" % name, "Order", initialvalue=0) tmp = [1.0 / self.itsHMM.hmmAlphabet.size()] * self.itsHMM.hmmAlphabet.size() p = tmp * (self.itsHMM.hmmAlphabet.size() ** order) print "adding", name, order, p self.addDistribution(name, order, p) def delete(self, name): self.deleteDistribution(name) def edit(self, master, name): if self.order[name] != 0: print "Sorry, cannot edit higher order distributions yet" else: emission_probabilities = ProbEditorBasics.ProbDict({}) for code in self.itsHMM.hmmAlphabet.name.keys(): label = self.itsHMM.hmmAlphabet.name[code] weight = self.dist[name][code] emission_probabilities.update({label:weight}) e = ProbEditorBasics.emission_data(emission_probabilities) d = ProbEditorDialogs.emission_dialog(master, e, "background emission probs %s" % name) if d.success(): # write back normalized probabilities for key in emission_probabilities.keys(): code = self.itsHMM.hmmAlphabet.name2code[key] weight = self.dist[name][code] = emission_probabilities[key] / emission_probabilities.sumclass DiscreteHMMAlphabet( xmlutil.DiscreteHMMAlphabet ): def __init__(self, nrOfSymbols=0): xmlutil.DiscreteHMMAlphabet.__init__(self) if nrOfSymbols > 0: self.buildAlphabets(nrOfSymbols) def size(self): return len(self.name.keys()) def edit(self, master): mapedit = MapEditor(master, [self.name], ['code','name'], [3,5]) print mapedit.result if mapedit.result != None: new_keys = [] for (code_str, name) in mapedit.result: code = int(code_str) self.name[code] = name self.name2code[name] = code new_keys.append(code) for key in self.name.keys(): if key not in new_keys: del self.name2code[self.name[key]] del self.name[key] else: self.name2code[self.name[key]] = keyclass HMMState( xmlutil.HMMState ): def __init__(self): xmlutil.HMMState.__init__(self) self.background = PopupableInt(-1) self.background.setPopup(self.itsHMM.backgroundDistributions.code2name, self.itsHMM.backgroundDistributions.name2code, 10) self.state_class = PopupableInt(-1) self.state_class.setPopup(self.itsHMM.hmmClass.code2name, self.itsHMM.hmmClass.name2code, 10) class HMMClass( xmlutil.HMMClass ): def __init__(self): xmlutil.HMMClass.__init__(self) def edit(self, master): mapedit = MapEditor(master, [self.name, self.desc], ['code','name','desc'], [3,5,35]) print mapedit.result if mapedit.result != None: new_keys = [] for (code_str, name, desc) in mapedit.result: code = int(code_str) self.name[code] = name self.desc[code] = desc self.name2code[name] = code new_keys.append(code) for key in self.name.keys(): if key not in new_keys: del self.code2name[key] del self.name2code[self.name[key]] del self.name[key] del self.desc[key] else: self.code2name[key] = self.name[key] self.name2code[self.name[key]] = keyclass HMM (xmlutil.HMM): def __init__(self, itsEditor, graph, XMLFileName = None): xmlutil.HMM.__init__(self, XMLFileName, graph) self.itsEditor = itsEditor def Clear(self): xmlutil.HMM.Clear(self) # base class clear! self.hmmAlphabet = DiscreteHMMAlphabet() # My alphabet class (not base class) with editor widget self.hmmClass = HMMClass() # My HMMclass (not base class) with editor widget self.backgroundDistributions = NamedDistributions(self) # same reasons class HMMEditor(SAGraphEditor): def __init__(self, master=None): SAGraphEditor.__init__(self, master) self.G = Graph() self.G.directed = 1 self.G.euclidian = 0 self.G.simple = 0 self.HMM = HMM(self, self.G) def CreateWidgets(self): toolbar = Frame(self, cursor='hand2', relief=FLAT) toolbar.pack(side=LEFT, fill=Y) # Allows horizontal growth extra = Frame(toolbar, cursor='hand2', relief=SUNKEN, borderwidth=2) extra.pack(side=TOP) # Allows horizontal growth extra.rowconfigure(6,weight=1) extra.bind("<Enter>", lambda e, gd=self:gd.DefaultInfo()) px = 0 py = 3 self.toolVar = StringVar() import GatoIcons # Load Icons self.vertexIcon = PhotoImage(data=GatoIcons.vertex) self.edgeIcon = PhotoImage(data=GatoIcons.edge) self.deleteIcon = PhotoImage(data=GatoIcons.delete) self.swapIcon = PhotoImage(data=GatoIcons.swap) self.editIcon = PhotoImage(data=GatoIcons.edit) self.propIcon = PhotoImage(data=GatoIcons.edit) b = Radiobutton(extra, width=32, padx=px, pady=py, text='Add or move vertex', command=self.ChangeTool, var = self.toolVar, value='AddOrMoveVertex', indicator=0, image=self.vertexIcon) b.grid(row=0, column=0, padx=2, pady=2) b.bind("<Enter>", lambda e, gd=self:gd.UpdateInfo('Add or move vertex')) self.defaultButton = b # default doesnt work as config option b = Radiobutton(extra, width=32, padx=px, pady=py, text='Add edge', command=self.ChangeTool, var = self.toolVar, value='AddEdge', indicator=0, image=self.edgeIcon) b.grid(row=1, column=0, padx=2, pady=2) b.bind("<Enter>", lambda e, gd=self:gd.UpdateInfo('Add edge')) b = Radiobutton(extra, width=32, padx=px, pady=py, text='Delete edge or vertex', command=self.ChangeTool, var = self.toolVar, value='DeleteEdgeOrVertex', indicator=0, image=self.deleteIcon) b.grid(row=2, column=0, padx=2, pady=2) b.bind("<Enter>", lambda e, gd=self:gd.UpdateInfo('Delete edge or vertex')) b = Radiobutton(extra, width=32, padx=px, pady=py, text='Swap orientation', command=self.ChangeTool, var = self.toolVar, value='SwapOrientation', indicator=0, image=self.swapIcon) b.grid(row=3, column=0, padx=2, pady=2) b.bind("<Enter>", lambda e, gd=self:gd.UpdateInfo('Swap orientation')) b = Radiobutton(extra, width=32, padx=px, pady=py, text='Edit Weight', command=self.ChangeTool, var = self.toolVar, value='EditWeight', indicator=0, image=self.editIcon) b.grid(row=4, column=0, padx=2, pady=2) b.bind("<Enter>", lambda e, gd=self:gd.UpdateInfo('Edit Weight')) b = Radiobutton(extra, width=32, padx=px, pady=py, text='Edit Properties', command=self.ChangeTool, var = self.toolVar, value='EditProperties', indicator=0, image=self.editIcon) b.grid(row=5, column=0, padx=2, pady=2) b.bind("<Enter>", lambda e, gd=self:gd.UpdateInfo('Edit Properties')) # disable the EditProperties button## b = Radiobutton(extra, width=32, padx=px, pady=py, ## text='Edit State', ## command=self.ChangeTool,## var = self.toolVar, value='EditState', indicator=0,## image=self.editIcon)## b.grid(row=6, column=0, padx=2, pady=2)## b.bind("<Enter>", lambda e, gd=self:gd.UpdateInfo('Edit State')) GraphEditor.CreateWidgets(self) #----- Tools Menu callbacks def ChangeTool(self): self.SetEditMode(self.toolVar.get()) def MouseUp(self,event): if self.mode == 'AddOrMoveVertex': self.AddOrMoveVertexUp(event) elif self.mode == 'AddEdge': self.AddEdgeUp(event) elif self.mode == 'DeleteEdgeOrVertex': self.DeleteEdgeOrVertexUp(event) elif self.mode == 'SwapOrientation': self.SwapOrientationUp(event) elif self.mode == 'EditWeight': self.EditWeightUp(event) elif self.mode == 'EditProperties': self.EditPropertiesUp(event) elif self.mode == 'EditState': # test EditObj self.EditHMMObj(event) def makeMenuBar(self): self.menubar = Menu(self,tearoff=0) # Add file menu self.fileMenu = Menu(self.menubar, tearoff=0) self.fileMenu.add_command(label='New', command=self.NewGraph) self.fileMenu.add_command(label='Open ...', command=self.OpenGraph) self.fileMenu.add_command(label='Save', command=self.SaveGraph) self.fileMenu.add_command(label='Save as ...', command=self.SaveAsGraph) self.fileMenu.add_separator() self.fileMenu.add_command(label='Export EPSF...', command=self.ExportEPSF) self.fileMenu.add_separator() self.fileMenu.add_command(label='Quit', command=self.Quit) self.menubar.add_cascade(label="File", menu=self.fileMenu, underline=0) self.graphMenu = Menu(self.menubar, tearoff=0) self.graphMenu.add_command(label='Edit HMM', command=self.EditHMM) self.graphMenu.add_command(label='Edit Class label', command=self.EditClassLabel) # XXX Note if we change alphabet, we have to change all emissions self.graphMenu.add_command(label='Edit Alphabet', command=self.EditAlphabet) self.graphMenu.add_command(label='Edit Prior', command=self.EditPrior) self.graphMenu.add_command(label='Edit Background Distributions', command=self.EditBackgroundDistributions) self.graphMenu.add_separator() self.graphMenu.add_checkbutton(label='Grid', command=self.ToggleGridding) self.menubar.add_cascade(label="HMM", menu=self.graphMenu, underline=0) self.master.configure(menu=self.menubar) def SetGraphMenuOptions(self): if not self.gridding: self.graphMenu.invoke(self.graphMenu.index('Grid')) ############################################################ #
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -