def load_bn_from_file(self, file_name): """ Load a bayesian network to show. Initially, the bn can be loaded by itself, but vertex positions must be loaded independently. """ try: # load bayesian network self.disc_bn = DiscreteBayesianNetworkExt() self.disc_bn.load(file_name) ### Load Vertex locations json_data = dic_from_json_file(file_name) # Vertex locations if "vertex_loc" in json_data.keys(): self.dict_to_gpoints(json_data["vertex_loc"]) else: vl = ugraphic.create_vertex_locations(self.disc_bn) self.dict_to_gpoints(vl) except Exception: ugraphic.show_warning(self.window, "Error loading the Bayesian Network", Exception) return self._draw_mode_edit()
def infer_bn(self, evidences): """ :param evidences: evidences to create a bayesian network. each evidence is an instance of Evidence. """ # Create an empty BN. disc_bn = DiscreteBayesianNetworkExt() bn_evidences = {} # self.vertex_locations = {} new_nodes = True # Generate inferred variables based on evidence rules for i, e in enumerate(evidences): # vertex location in map. evidence_location = [e.x, e.y] ## Create a node for this evidence evidence_name = "'" + e.var + "'" + str(evidence_location) + "_" + str(i) # states disc_bn.add_vertex(evidence_name, e.var_states) # evidence bn_evidences[evidence_name] = e.evidence_state # Save location self.vertex_locations[evidence_name] = evidence_location # A new node was added to infer new_nodes = True # Run the rules until while new_nodes: n_ve = len(disc_bn.V) + len(disc_bn.E) # evaluate each evidence rule for r in self.rules: # number of vertices and edges r.generate_inference(disc_bn, evidences, bn_evidences, self.vertex_locations) # There is new edges or vertices after applying the rules new_n_ve = len(disc_bn.V) + len(disc_bn.E) new_nodes = new_n_ve > n_ve # return the created bn return disc_bn, bn_evidences
def __init__(self, window, disc_bn=DiscreteBayesianNetworkExt()): self.window = window # Create graphic widgets self.box_disc_bn, self.drawing_box, self.toolbar_edit, self.toolbar_evidence, self.bedit, self.brun, self.bvertex, \ self.bclear_evidence = ugraphic.create_widget( res.TAB_DISC_BAYES_NET_GLADE, [BOX_DISC_BN, DRAWING_BOX, TB_EDIT_BN, TB_EVIDENCE, RB_EDIT, RB_RUN, RB_VERTEX, RB_CLEAR_EVIDENCE], self) super(BoxDiscreteBN, self).__init__(spacing=1) self.pack_start(self.box_disc_bn, True, True, 0) self.set_visible(True) self.drawer = GraphDrawer() self.drawing_box.pack_start(self.drawer.get_drawing_area(), True, True, 0) self.mode = Mode.edit_vertex # Temporal vertex for edge self.vertex_1 = None self.selected_vertex = None self.selected_edge = None self.marginals = None self.evidences = {} # Temporal arrow for mouse motion self.tmp_arrow = None # Graph self.disc_bn = disc_bn # Vertex locations to draw self.vertex_locations = {} self.clicked_point = None self.button_pressed = False # connect listeners self.drawer.clicked_element_listener = self.clicked_element self.drawer.clicked_clear_space_listener = self.clicked_clear_space self.drawer.right_click_elem_listener = self.right_clicked_elem self.drawer.double_clicked_element_listener = self.double_click_on_elem # Graphical objects in the background self.background_gobjs = []
def do_activate(self): # Graph vertices = ["A", "B", "C", "D"] edges = [["A", "B"], ["C", "B"], ["D", "B"]] states = { "A": ["atrue", "afalse"], "B": ["true", "false"], "C": ["ctrue", "cfalse"], "D": ["1", "2", "3"] } cpt_v = "D" disc_bn = DiscreteBayesianNetworkExt() disc_bn.set_vertices(vertices) disc_bn.E = edges # States for s, iss in states.items(): for i in iss: disc_bn.add_state(s, i) gtable = gwidgets.GraphicCptTable(disc_bn, cpt_v) # table = gwidgets.create_treeview_for_cpt(vertices, edges, states, cpt_v) ## Window window = Gtk.Window(application=self, title="CPT for " + cpt_v) window.set_default_size(250, 100) window.set_border_width(10) # the label we use to show the selection label = Gtk.Label() label.set_text("fads") # a grid to attach the widgets grid = Gtk.Grid() grid.attach(gtable.view, 0, 0, 1, 1) grid.attach(label, 0, 1, 1, 1) # attach the grid to the window window.add(grid) window.show_all() if window: window.connect("destroy", Gtk.main_quit)
def do_activate(self): # Graph vertices = ["A", "B", "C", "D"] edges = [["A", "B"], ["C", "B"], ["D", "B"]] states = {"A": ["atrue", "afalse"], "B": ["true", "false"], "C": ["ctrue", "cfalse"], "D": ["1", "2", "3"]} cpt_v = "D" disc_bn = DiscreteBayesianNetworkExt() disc_bn.set_vertices(vertices) disc_bn.E = edges # States for s, iss in states.items(): for i in iss: disc_bn.add_state(s, i) gtable = gwidgets.GraphicCptTable(disc_bn, cpt_v) # table = gwidgets.create_treeview_for_cpt(vertices, edges, states, cpt_v) ## Window window = Gtk.Window(application=self, title="CPT for " + cpt_v) window.set_default_size(250, 100) window.set_border_width(10) # the label we use to show the selection label = Gtk.Label() label.set_text("fads") # a grid to attach the widgets grid = Gtk.Grid() grid.attach(gtable.view, 0, 0, 1, 1) grid.attach(label, 0, 1, 1, 1) # attach the grid to the window window.add(grid) window.show_all() if window: window.connect("destroy", Gtk.main_quit)
class BoxDiscreteBN(Gtk.Box): """ Gtk Box to show and edit a discrete bayesian network. """ def __init__(self, window, disc_bn=DiscreteBayesianNetworkExt()): self.window = window # Create graphic widgets self.box_disc_bn, self.drawing_box, self.toolbar_edit, self.toolbar_evidence, self.bedit, self.brun, self.bvertex, \ self.bclear_evidence = ugraphic.create_widget( res.TAB_DISC_BAYES_NET_GLADE, [BOX_DISC_BN, DRAWING_BOX, TB_EDIT_BN, TB_EVIDENCE, RB_EDIT, RB_RUN, RB_VERTEX, RB_CLEAR_EVIDENCE], self) super(BoxDiscreteBN, self).__init__(spacing=1) self.pack_start(self.box_disc_bn, True, True, 0) self.set_visible(True) self.drawer = GraphDrawer() self.drawing_box.pack_start(self.drawer.get_drawing_area(), True, True, 0) self.mode = Mode.edit_vertex # Temporal vertex for edge self.vertex_1 = None self.selected_vertex = None self.selected_edge = None self.marginals = None self.evidences = {} # Temporal arrow for mouse motion self.tmp_arrow = None # Graph self.disc_bn = disc_bn # Vertex locations to draw self.vertex_locations = {} self.clicked_point = None self.button_pressed = False # connect listeners self.drawer.clicked_element_listener = self.clicked_element self.drawer.clicked_clear_space_listener = self.clicked_clear_space self.drawer.right_click_elem_listener = self.right_clicked_elem self.drawer.double_clicked_element_listener = self.double_click_on_elem # Graphical objects in the background self.background_gobjs = [] def double_click_on_elem(self, elem): if self.mode == Mode.run or self.selected_vertex is None: return # Show cpt dialog self.show_edit_var_dialog() self.clicked_point = None self.selected_vertex = None self.drawer.dynamic_arrow = None self.draw_graph() def clicked_clear_space(self, p): if self.mode == Mode.edit_vertex: # Crate vertex vname = self.get_new_vertex_name() # new vertex self.vertex_locations[vname] = GPoint(p[0], p[1]) self.disc_bn.add_vertex(vname) elif self.mode == Mode.edit_edge: self.drawer.dynamic_arrow = None self.selected_vertex = None self.draw_graph() def right_clicked_elem(self, elem, event): if self.mode == Mode.edit_vertex or self.mode == Mode.edit_edge: if isinstance(elem, GVertex) or isinstance(elem, GArrow): self.show_edit_popup(event) def organize_graph(self, random=True): v_locts = ugraphic.create_vertex_locations(self.disc_bn, random=random) self.dict_to_gpoints(v_locts) self.draw_graph() def dict_to_gpoints(self, v_locts): for vname, point in v_locts.items(): self.vertex_locations[vname] = GPoint(point[0], point[1]) def gpoints_to_dict(self): l_loc = {} for vname, gpoint in self.vertex_locations.items(): l_loc[vname] = [gpoint.x, gpoint.y] return l_loc def get_new_vertex_name(self): """ Vertex name generator to create incremental variables and does not generate incompatibility with assigned names by user . """ counter = 1 new_name = DEFAULT_NODE_NAME + ' ' + str(counter) while new_name in self.disc_bn.get_vertices(): counter += 1 new_name = DEFAULT_NODE_NAME + ' ' + str(counter) return new_name def draw_graph(self): if self.mode == Mode.edit_vertex or self.mode == Mode.edit_edge: self._draw_mode_edit() else: self._draw_mode_run() def _draw_mode_edit(self): ## Configure drawer vl = self.vertex_locations # Graphic elements gelements = list(self.background_gobjs) # Edges for e in self.disc_bn.get_edges(): arrow = GArrow(self.vertex_locations[e[0]], self.vertex_locations[e[1]]) if e == self.selected_edge: arrow.selected = True gelements.append(arrow) # Vertices for vname, p in vl.items(): v = GVertex(p, vname) v.translatable = True if self.selected_vertex == vname: v.selected = True gelements.append(v) self.drawer.set_graphic_objects(gelements) self.drawer.repaint() def _draw_mode_run(self): ## Configure drawer vl = self.vertex_locations # Graphic elements boxes = [] dboxes = {} for vname, p in vl.items(): evidence = {} if vname in self.evidences: evidence = self.evidences[vname] b = GStateBox(p, vname, self.marginals[vname], evidence) b.translatable = True dboxes[vname] = b boxes.append(b) # Edges bedges = [] for e in self.disc_bn.get_edges(): arrow = GBoxArrow(dboxes[e[0]], dboxes[e[1]]) bedges.append(arrow) self.drawer.set_graphic_objects(self.background_gobjs + bedges + boxes) self.drawer.repaint() def editing_action(self, p): """ Action for adding vertices or edges. """ # if self.transform is not None: p = self.drawer.transform_point(p) # p = [p[0] - self.translation[0], p[1] - self.translation[1]] #### Mode Edit ##### self._draw_mode_edit() ####### MODE EDIT EDGE if self.mode_edit == Mode.edge: # If there is not a initial vertex selected if self.vertex_1 is None and self.selected_vertex is not None: self.vertex_1 = self.selected_vertex # If there is an initial vertex elif self.vertex_1 is not None and self.selected_vertex is None: #Select anything self.vertex_1 = None # draw a dynamic arrow self.drawer.set_dynamic_arrow(self.selected_edge) elif self.vertex_1 is not None and self.selected_vertex is not None: if not self.vertex_1 == self.selected_vertex and self.selected_vertex is not None: self.disc_bn.add_edge([self.vertex_1, self.selected_vertex]) self.vertex_1 = None self.selected_vertex = None self.tmp_arrow = None self.draw_graph() def change_vertex_name_h(self, old_name, new_name): #vertex locations self.vertex_locations[new_name] = self.vertex_locations.pop(old_name) # Change in BN self.disc_bn.change_vertex_name(old_name, new_name) #selected vertex if self.selected_vertex == old_name: self.selected_vertex = new_name def show_edit_popup(self, event): #Draw selected node self.drawer.repaint() menu = Gtk.Menu() menu_it = Gtk.MenuItem() menu_it.set_label("Edit") menu = Gtk.Menu() menuitem = Gtk.MenuItem(label="RadioMenuItem") menuitem.set_submenu(menu) # Edit selected vertex if self.selected_vertex is not None: menu_it = Gtk.MenuItem("Edit Variable") # Click on edit vertex data. def event_edit(widget, event): menu.destroy() self.show_edit_var_dialog() menu_it.connect("button-release-event", event_edit) menu.append(menu_it) # Delete variable or edge menu_it_del = Gtk.MenuItem("Delete") menu_it_del.connect("button-release-event", self.on_delete) menu.append(menu_it_del) menu.show_all() menu.popup(None, None, None, None, event.button, event.time) def set_mode(self, mode): """ Select Edit or Run mode. """ self.mode = mode if self.mode == Mode.edit_edge or self.mode == Mode.edit_vertex: self.bedit.set_active(True) self.toolbar_edit.set_visible(True) self.toolbar_evidence.set_visible(False) if self.mode == Mode.edit_vertex: self.bvertex.set_active(True) elif self.mode == Mode.run: self.brun.set_active(True) # Validate BN for v in self.disc_bn.get_vertices(): # Validate cycles try: self.disc_bn.toporder() except Exception: ugraphic.show_warning(self.window, "The Bayesian Network contains cycles.") return # Validate that the BN has all the cpts ok = self.disc_bn.validate_cprob(v) if not ok: ugraphic.show_warning(self.window, v + " is not valid.", "please, check the probability table.") self.bedit.set_active(True) return # compute marginals self.marginals = self.disc_bn.compute_marginals(self.evidences) self.toolbar_edit.set_visible(False) self.toolbar_evidence.set_visible(True) self.bclear_evidence.set_visible_horizontal(True) print "aqui pasa" self.selected_vertex = None self.selected_edge = None self.draw_graph() def show_edit_var_dialog(self): cpt_dialog = CptDialog() # Create clone of disc_bn new_disc_bn = self.disc_bn.clone() cpt_dialog.show_cpt_dialog(self.window, new_disc_bn, self.selected_vertex) new_var_name = cpt_dialog.get_var_name() ## Cancel button, new_var_name is assigned if new_var_name is None: return self.disc_bn = new_disc_bn if not new_var_name == self.selected_vertex: self.change_vertex_name_h(self.selected_vertex, new_var_name) self.selected_edge = None self.selected_vertex = None self.draw_graph() def save_bn_to_file(self, file_name): # if does not have extension if not file_name.endswith(FILE_EXTENSION): file_name += FILE_EXTENSION bn = { "vertex_loc": self.gpoints_to_dict(), "E": self.disc_bn.get_edges(), "V": self.disc_bn.get_vertices(), "Vdata": self.disc_bn.get_vdata()} dic_to_file(bn, file_name) def load_bn_from_file(self, file_name): """ Load a bayesian network to show. Initially, the bn can be loaded by itself, but vertex positions must be loaded independently. """ try: # load bayesian network self.disc_bn = DiscreteBayesianNetworkExt() self.disc_bn.load(file_name) ### Load Vertex locations json_data = dic_from_json_file(file_name) # Vertex locations if "vertex_loc" in json_data.keys(): self.dict_to_gpoints(json_data["vertex_loc"]) else: vl = ugraphic.create_vertex_locations(self.disc_bn) self.dict_to_gpoints(vl) except Exception: ugraphic.show_warning(self.window, "Error loading the Bayesian Network", Exception) return self._draw_mode_edit() ########### Listeners #################### def on_clear_evidence(self, button): """ Event to clear all evidence """ self.evidences = {} self.marginals = self.disc_bn.compute_marginals(self.evidences) self.draw_graph() def on_zoom(self, button): """ Zoom event by button. """ self.drawer.restore_zoom() def on_key_press(self, widget, event): """ Key event generated by box container. """ # Supr key is pressed if event.keyval == KEY_SUPR_CODE: self.on_delete(None) elif event.keyval == KEY_E_CODE: self.bedit.set_active(True) elif event.keyval == KEY_R_CODE: self.brun.set_active(True) def on_mode(self, radio_tool): """ Event to choose the 'edit mode' or the 'run mode'. """ if not radio_tool.get_active(): return True # Edit button, then select edit_vertex mode if radio_tool.get_label() == RB_EDIT: self.mode = Mode.edit_vertex self.set_mode(Mode.edit_vertex) if radio_tool.get_label() == RB_RUN: self.set_mode(Mode.run) def on_edit_mode(self, radiotool): """ Click on buttons: edit_vertex or edit_node :param radiotool: selected button :return: """ if not radiotool.get_active(): return True # Radio selected if radiotool.get_label() == RB_VERTEX: self.mode = Mode.edit_vertex elif radiotool.get_label() == RB_EDGE: self.mode = Mode.edit_edge elif radiotool.get_label() == RB_MANUAL: pass else: print "not supported" # No selections self.selected_edge = None self.selected_vertex = None self.draw_graph() def on_organize(self, widget): """ Estimate good places to draw each vertex of the graph. """ self.organize_graph() def on_delete(self, *widget): # Delete vertex if self.selected_vertex is not None: self.vertex_locations.pop(self.selected_vertex) # Delete from model self.disc_bn.remove_vertex(self.selected_vertex) # Delete edge elif self.selected_edge is not None: # Delete from model self.disc_bn.remove_edge(self.selected_edge) # Non selected self.selected_vertex = None self.selected_edge = None self.drawer.dynamic_arrow = None # Draw self.draw_graph() def clicked_element(self, gelement): # Edge is clicked if isinstance(gelement, GArrow): if self.mode == Mode.edit_vertex or self.mode == Mode.edit_edge: # Selected edge edge = [] for vname, p in self.vertex_locations.iteritems(): if p == gelement.p1: edge.append(vname) break for vname, p in self.vertex_locations.iteritems(): if p == gelement.p2: edge.append(vname) break gelement.selected = True self.selected_edge = edge self.selected_vertex = None # Vertex is clicked if isinstance(gelement, GVertex): self.selected_edge = None if self.mode == Mode.edit_vertex: gelement.selected = True self.selected_vertex = gelement.name elif self.mode == Mode.edit_edge: new_selection = gelement.name # if there is not selected a source vertex. if self.selected_vertex is None: self.selected_vertex = new_selection self.drawer.dynamic_arrow = self.vertex_locations[new_selection] # the second vertex was selected. else: # Create the new vertex self.disc_bn.add_edge([self.selected_vertex, new_selection]) self.selected_vertex = None self.drawer.dynamic_arrow = None # get selected state for evidence. only works on run_mode. if isinstance(gelement, GStateBox): new_evidence = gelement.selected_state if new_evidence is not None: self.evidences[gelement.name] = new_evidence # compute marginals again self.marginals = self.disc_bn.compute_marginals(self.evidences) self.draw_graph() self.draw_graph()
from gi.repository import Gtk, GObject import random from lib_sallybn.disc_bayes_net.DiscreteBayesianNetworkExt import DiscreteBayesianNetworkExt from lib_sallybn.disc_bayes_net.BoxDiscreteBN import BoxDiscreteBN # Create window window = Gtk.Window() window.set_size_request(800, 600) ## Discrete bn disc_bn = DiscreteBayesianNetworkExt() # Vertex and its states disc_bn.add_vertex("A", states=["true1", "false1"]) disc_bn.add_vertex("C", states=["true", "false"]) disc_bn.add_vertex("B", states=["true", "false"]) # Edges disc_bn.add_edge(["A", "B"]) disc_bn.add_edge(["C", "B"]) # CPTs cprob_b = { "['true1', 'true']": [.3, .7], "['true1', 'false']": [.9, .1], "['false1', 'true']": [.05, .95], "['false1', 'false']": [.5, .5] } cprob_a = [.3, .7] cprob_c = [.2, .8]
from infengine.gis import shape_writer from lib_sallybn.disc_bayes_net.DiscreteBayesianNetworkExt import DiscreteBayesianNetworkExt from lib_sallybn.drawer.GPoint import GPoint from lib_sallybn.util import ufile file_name = 'output.bn' disc_bn = DiscreteBayesianNetworkExt() disc_bn.load(file_name) vertex_locations = {} ### Load Vertex locations json_data = ufile.dic_from_json_file(file_name) # Vertex locations if "vertex_loc" in json_data.keys(): for vname, point in json_data["vertex_loc"].items(): vertex_locations[vname] = GPoint(point[0], point[1]) shape_writer.write(disc_bn, vertex_locations, {})
class BoxDiscreteBN(Gtk.Box): """ Gtk Box to show and edit a discrete bayesian network. """ def __init__(self, window, disc_bn=DiscreteBayesianNetworkExt()): self.window = window # Create graphic widgets self.box_disc_bn, self.drawing_box, self.toolbar_edit, self.toolbar_evidence, self.bedit, self.brun, self.bvertex, \ self.bclear_evidence = ugraphic.create_widget( res.TAB_DISC_BAYES_NET_GLADE, [BOX_DISC_BN, DRAWING_BOX, TB_EDIT_BN, TB_EVIDENCE, RB_EDIT, RB_RUN, RB_VERTEX, RB_CLEAR_EVIDENCE], self) super(BoxDiscreteBN, self).__init__(spacing=1) self.pack_start(self.box_disc_bn, True, True, 0) self.set_visible(True) self.drawer = GraphDrawer() self.drawing_box.pack_start(self.drawer.get_drawing_area(), True, True, 0) self.mode = Mode.edit_vertex # Temporal vertex for edge self.vertex_1 = None self.selected_vertex = None self.selected_edge = None self.marginals = None self.evidences = {} # Temporal arrow for mouse motion self.tmp_arrow = None # Graph self.disc_bn = disc_bn # Vertex locations to draw self.vertex_locations = {} self.clicked_point = None self.button_pressed = False # connect listeners self.drawer.clicked_element_listener = self.clicked_element self.drawer.clicked_clear_space_listener = self.clicked_clear_space self.drawer.right_click_elem_listener = self.right_clicked_elem self.drawer.double_clicked_element_listener = self.double_click_on_elem # Graphical objects in the background self.background_gobjs = [] def double_click_on_elem(self, elem): if self.mode == Mode.run or self.selected_vertex is None: return # Show cpt dialog self.show_edit_var_dialog() self.clicked_point = None self.selected_vertex = None self.drawer.dynamic_arrow = None self.draw_graph() def clicked_clear_space(self, p): if self.mode == Mode.edit_vertex: # Crate vertex vname = self.get_new_vertex_name() # new vertex self.vertex_locations[vname] = GPoint(p[0], p[1]) self.disc_bn.add_vertex(vname) elif self.mode == Mode.edit_edge: self.drawer.dynamic_arrow = None self.selected_vertex = None self.draw_graph() def right_clicked_elem(self, elem, event): if self.mode == Mode.edit_vertex or self.mode == Mode.edit_edge: if isinstance(elem, GVertex) or isinstance(elem, GArrow): self.show_edit_popup(event) def organize_graph(self, random=True): v_locts = ugraphic.create_vertex_locations(self.disc_bn, random=random) self.dict_to_gpoints(v_locts) self.draw_graph() def dict_to_gpoints(self, v_locts): for vname, point in v_locts.items(): self.vertex_locations[vname] = GPoint(point[0], point[1]) def gpoints_to_dict(self): l_loc = {} for vname, gpoint in self.vertex_locations.items(): l_loc[vname] = [gpoint.x, gpoint.y] return l_loc def get_new_vertex_name(self): """ Vertex name generator to create incremental variables and does not generate incompatibility with assigned names by user . """ counter = 1 new_name = DEFAULT_NODE_NAME + ' ' + str(counter) while new_name in self.disc_bn.get_vertices(): counter += 1 new_name = DEFAULT_NODE_NAME + ' ' + str(counter) return new_name def draw_graph(self): if self.mode == Mode.edit_vertex or self.mode == Mode.edit_edge: self._draw_mode_edit() else: self._draw_mode_run() def _draw_mode_edit(self): ## Configure drawer vl = self.vertex_locations # Graphic elements gelements = list(self.background_gobjs) # Edges for e in self.disc_bn.get_edges(): arrow = GArrow(self.vertex_locations[e[0]], self.vertex_locations[e[1]]) if e == self.selected_edge: arrow.selected = True gelements.append(arrow) # Vertices for vname, p in vl.items(): v = GVertex(p, vname) v.translatable = True if self.selected_vertex == vname: v.selected = True gelements.append(v) self.drawer.set_graphic_objects(gelements) self.drawer.repaint() def _draw_mode_run(self): ## Configure drawer vl = self.vertex_locations # Graphic elements boxes = [] dboxes = {} for vname, p in vl.items(): evidence = {} if vname in self.evidences: evidence = self.evidences[vname] b = GStateBox(p, vname, self.marginals[vname], evidence) b.translatable = True dboxes[vname] = b boxes.append(b) # Edges bedges = [] for e in self.disc_bn.get_edges(): arrow = GBoxArrow(dboxes[e[0]], dboxes[e[1]]) bedges.append(arrow) self.drawer.set_graphic_objects(self.background_gobjs + bedges + boxes) self.drawer.repaint() def editing_action(self, p): """ Action for adding vertices or edges. """ # if self.transform is not None: p = self.drawer.transform_point(p) # p = [p[0] - self.translation[0], p[1] - self.translation[1]] #### Mode Edit ##### self._draw_mode_edit() ####### MODE EDIT EDGE if self.mode_edit == Mode.edge: # If there is not a initial vertex selected if self.vertex_1 is None and self.selected_vertex is not None: self.vertex_1 = self.selected_vertex # If there is an initial vertex elif self.vertex_1 is not None and self.selected_vertex is None: #Select anything self.vertex_1 = None # draw a dynamic arrow self.drawer.set_dynamic_arrow(self.selected_edge) elif self.vertex_1 is not None and self.selected_vertex is not None: if not self.vertex_1 == self.selected_vertex and self.selected_vertex is not None: self.disc_bn.add_edge( [self.vertex_1, self.selected_vertex]) self.vertex_1 = None self.selected_vertex = None self.tmp_arrow = None self.draw_graph() def change_vertex_name_h(self, old_name, new_name): #vertex locations self.vertex_locations[new_name] = self.vertex_locations.pop(old_name) # Change in BN self.disc_bn.change_vertex_name(old_name, new_name) #selected vertex if self.selected_vertex == old_name: self.selected_vertex = new_name def show_edit_popup(self, event): #Draw selected node self.drawer.repaint() menu = Gtk.Menu() menu_it = Gtk.MenuItem() menu_it.set_label("Edit") menu = Gtk.Menu() menuitem = Gtk.MenuItem(label="RadioMenuItem") menuitem.set_submenu(menu) # Edit selected vertex if self.selected_vertex is not None: menu_it = Gtk.MenuItem("Edit Variable") # Click on edit vertex data. def event_edit(widget, event): menu.destroy() self.show_edit_var_dialog() menu_it.connect("button-release-event", event_edit) menu.append(menu_it) # Delete variable or edge menu_it_del = Gtk.MenuItem("Delete") menu_it_del.connect("button-release-event", self.on_delete) menu.append(menu_it_del) menu.show_all() menu.popup(None, None, None, None, event.button, event.time) def set_mode(self, mode): """ Select Edit or Run mode. """ self.mode = mode if self.mode == Mode.edit_edge or self.mode == Mode.edit_vertex: self.bedit.set_active(True) self.toolbar_edit.set_visible(True) self.toolbar_evidence.set_visible(False) if self.mode == Mode.edit_vertex: self.bvertex.set_active(True) elif self.mode == Mode.run: self.brun.set_active(True) # Validate BN for v in self.disc_bn.get_vertices(): # Validate cycles try: self.disc_bn.toporder() except Exception: ugraphic.show_warning( self.window, "The Bayesian Network contains cycles.") return # Validate that the BN has all the cpts ok = self.disc_bn.validate_cprob(v) if not ok: ugraphic.show_warning( self.window, v + " is not valid.", "please, check the probability table.") self.bedit.set_active(True) return # compute marginals self.marginals = self.disc_bn.compute_marginals(self.evidences) self.toolbar_edit.set_visible(False) self.toolbar_evidence.set_visible(True) self.bclear_evidence.set_visible_horizontal(True) print "aqui pasa" self.selected_vertex = None self.selected_edge = None self.draw_graph() def show_edit_var_dialog(self): cpt_dialog = CptDialog() # Create clone of disc_bn new_disc_bn = self.disc_bn.clone() cpt_dialog.show_cpt_dialog(self.window, new_disc_bn, self.selected_vertex) new_var_name = cpt_dialog.get_var_name() ## Cancel button, new_var_name is assigned if new_var_name is None: return self.disc_bn = new_disc_bn if not new_var_name == self.selected_vertex: self.change_vertex_name_h(self.selected_vertex, new_var_name) self.selected_edge = None self.selected_vertex = None self.draw_graph() def save_bn_to_file(self, file_name): # if does not have extension if not file_name.endswith(FILE_EXTENSION): file_name += FILE_EXTENSION bn = { "vertex_loc": self.gpoints_to_dict(), "E": self.disc_bn.get_edges(), "V": self.disc_bn.get_vertices(), "Vdata": self.disc_bn.get_vdata() } dic_to_file(bn, file_name) def load_bn_from_file(self, file_name): """ Load a bayesian network to show. Initially, the bn can be loaded by itself, but vertex positions must be loaded independently. """ try: # load bayesian network self.disc_bn = DiscreteBayesianNetworkExt() self.disc_bn.load(file_name) ### Load Vertex locations json_data = dic_from_json_file(file_name) # Vertex locations if "vertex_loc" in json_data.keys(): self.dict_to_gpoints(json_data["vertex_loc"]) else: vl = ugraphic.create_vertex_locations(self.disc_bn) self.dict_to_gpoints(vl) except Exception: ugraphic.show_warning(self.window, "Error loading the Bayesian Network", Exception) return self._draw_mode_edit() ########### Listeners #################### def on_clear_evidence(self, button): """ Event to clear all evidence """ self.evidences = {} self.marginals = self.disc_bn.compute_marginals(self.evidences) self.draw_graph() def on_zoom(self, button): """ Zoom event by button. """ self.drawer.restore_zoom() def on_key_press(self, widget, event): """ Key event generated by box container. """ # Supr key is pressed if event.keyval == KEY_SUPR_CODE: self.on_delete(None) elif event.keyval == KEY_E_CODE: self.bedit.set_active(True) elif event.keyval == KEY_R_CODE: self.brun.set_active(True) def on_mode(self, radio_tool): """ Event to choose the 'edit mode' or the 'run mode'. """ if not radio_tool.get_active(): return True # Edit button, then select edit_vertex mode if radio_tool.get_label() == RB_EDIT: self.mode = Mode.edit_vertex self.set_mode(Mode.edit_vertex) if radio_tool.get_label() == RB_RUN: self.set_mode(Mode.run) def on_edit_mode(self, radiotool): """ Click on buttons: edit_vertex or edit_node :param radiotool: selected button :return: """ if not radiotool.get_active(): return True # Radio selected if radiotool.get_label() == RB_VERTEX: self.mode = Mode.edit_vertex elif radiotool.get_label() == RB_EDGE: self.mode = Mode.edit_edge elif radiotool.get_label() == RB_MANUAL: pass else: print "not supported" # No selections self.selected_edge = None self.selected_vertex = None self.draw_graph() def on_organize(self, widget): """ Estimate good places to draw each vertex of the graph. """ self.organize_graph() def on_delete(self, *widget): # Delete vertex if self.selected_vertex is not None: self.vertex_locations.pop(self.selected_vertex) # Delete from model self.disc_bn.remove_vertex(self.selected_vertex) # Delete edge elif self.selected_edge is not None: # Delete from model self.disc_bn.remove_edge(self.selected_edge) # Non selected self.selected_vertex = None self.selected_edge = None self.drawer.dynamic_arrow = None # Draw self.draw_graph() def clicked_element(self, gelement): # Edge is clicked if isinstance(gelement, GArrow): if self.mode == Mode.edit_vertex or self.mode == Mode.edit_edge: # Selected edge edge = [] for vname, p in self.vertex_locations.iteritems(): if p == gelement.p1: edge.append(vname) break for vname, p in self.vertex_locations.iteritems(): if p == gelement.p2: edge.append(vname) break gelement.selected = True self.selected_edge = edge self.selected_vertex = None # Vertex is clicked if isinstance(gelement, GVertex): self.selected_edge = None if self.mode == Mode.edit_vertex: gelement.selected = True self.selected_vertex = gelement.name elif self.mode == Mode.edit_edge: new_selection = gelement.name # if there is not selected a source vertex. if self.selected_vertex is None: self.selected_vertex = new_selection self.drawer.dynamic_arrow = self.vertex_locations[ new_selection] # the second vertex was selected. else: # Create the new vertex self.disc_bn.add_edge( [self.selected_vertex, new_selection]) self.selected_vertex = None self.drawer.dynamic_arrow = None # get selected state for evidence. only works on run_mode. if isinstance(gelement, GStateBox): new_evidence = gelement.selected_state if new_evidence is not None: self.evidences[gelement.name] = new_evidence # compute marginals again self.marginals = self.disc_bn.compute_marginals(self.evidences) self.draw_graph() self.draw_graph()
def infer_bn(self, evidences): """ :param evidences: evidences to create a bayesian network. each evidence is an instance of Evidence. """ # Create an empty BN. disc_bn = DiscreteBayesianNetworkExt() bn_evidences = {} # self.vertex_locations = {} new_nodes = True # Generate inferred variables based on evidence rules # for i, e in enumerate(evidences): # # vertex location in map. # evidence_location = [e.x, e.y] # # ## Create a node for this evidence # evidence_name = "'" + e.var + "'" + str(evidence_location) + "_" + str(i) # # states # disc_bn.add_vertex(evidence_name, e.var_states) # # # evidence # bn_evidences[evidence_name] = e.evidence_state # # # Save location # self.vertex_locations[evidence_name] = evidence_location # # # A new node was added to infer # new_nodes = True # Organize evidences for variables: evid_grid = evidence_to_grid(evidences, self.map_grid) # For each variable for var_name, grid in evid_grid.items(): # For each cell for i, j in zip(grid.n_rows, grid.n_columns): true_evidences, false_evidences = grid.get(i, j) cell_location = grid.cell_center(i, j) #True values for te in range(true_evidences): evidence_name = "'" + var_name + "' " + str([i, j]) + "_true_" + str(te) #Add to bn disc_bn.add_vertex(evidence_name, VAR_STATES) # Evidences bn_evidences[evidence_name] = VAR_STATES[1] # Save location self.vertex_locations[evidence_name] = cell_location #False values for fe in range(false_evidences): evidence_name = "'" + var_name + "' " + str([i, j]) + "_false_" + str(fe) # Add to bn disc_bn.add_vertex(evidence_name, VAR_STATES) #Evidences bn_evidences[evidence_name] = VAR_STATES[0] self.vertex_locations[evidence_name] = cell_location # if not evidences if true_evidences == 0 and false_evidences == 0: evidence_name = "'" + var_name + "' " + str([i, j]) + "_no_evid" disc_bn.add_vertex(evidence_name, VAR_STATES) # Run the rules until while new_nodes: n_ve = len(disc_bn.V) + len(disc_bn.E) # evaluate each evidence rule for r in self.rules: # number of vertices and edges r.generate_inference(disc_bn, evidences, bn_evidences, self.vertex_locations) # There is new edges or vertices after applying the rules new_n_ve = len(disc_bn.V) + len(disc_bn.E) new_nodes = new_n_ve > n_ve # return the created bn return disc_bn, bn_evidences