def generate_basic_graph_with_mapping( VISJS=False) -> (GraphDataStruct, dict): mapping = {} # Create a graphe structure if VISJS: tmp_meta = Metadata(Source.VISJS) else: tmp_meta = Metadata(Source.DBDUMP) tmp_graph = GraphDataStruct(tmp_meta) # For each cluster, fetch all pictures and store it for cluster_id in range(0, 2): tmp_graph.add_cluster( Cluster(label="", tmp_id=cluster_id, image="")) for id in range(0, 3): pic_id = str(cluster_id) + "_" + str(id) + "OLD" pic_image = str(cluster_id) + "_" + str(id) + "IMAGE" # Prepare mapping mapping[pic_image] = str(cluster_id) + "_" + str(id) + "NEW" # Label = picture score, here tmp_graph.add_node( Node(label="picture name +" + pic_id, tmp_id=pic_id, image=pic_image)) tmp_graph.add_edge(Edge(_from=cluster_id, _to=pic_id)) return tmp_graph, mapping
def get_storage_graph(self) -> GraphDataStruct: """ # TODO : Move to API ? Export the current state of the database as a graph datastructure. This represents the storage graph of the server. :return: The storage graph of the server, as is in the database """ # Create a graphe structure tmp_meta = Metadata(Source.DBDUMP) tmp_graph = GraphDataStruct(tmp_meta) # Get all clusters cluster_list = self.get_cluster_list() # For each cluster, fetch all pictures and store it for cluster_id in cluster_list: tmp_graph.add_cluster(Cluster(label="", tmp_id=cluster_id, image="")) picture_list = self.get_pictures_of_cluster(cluster_id, with_score=True) self.logger.info(f"Picture list : {picture_list}") for picture in picture_list: # Label = picture score, here tmp_graph.add_node(Node(label=picture[1], tmp_id=picture[0], image="")) tmp_graph.add_edge(Edge(_from=cluster_id, _to=picture[0])) return tmp_graph
def test_get_clusters_of(self): tmp_graph = self.generate_basic_graph() tmp_graph.add_node(Node(label="to_find", tmp_id="10", image="")) tmp_graph.add_edge(Edge(_from="10", _to=0)) cluster = tmp_graph.get_clusters_of("10") pprint.pprint(cluster) self.assertEqual(cluster.id, 0)
def get_basic_graph(): graph_1 = graph_datastructure.GraphDataStruct(Metadata(Source.DBDUMP)) graph_1.add_cluster( Cluster(label="cluster_1", tmp_id="c1", image="image_c1")) graph_1.add_cluster( Cluster(label="cluster_2", tmp_id="c2", image="image_c2")) graph_1.add_cluster( Cluster(label="cluster_3", tmp_id="c3", image="image_c3")) graph_1.add_node(Node(label="node_1", tmp_id="n1", image="image_n1")) graph_1.add_node(Node(label="node_2", tmp_id="n2", image="image_n2")) graph_1.add_node(Node(label="node_3", tmp_id="n3", image="image_n3")) graph_1.add_node(Node(label="node_4", tmp_id="n4", image="image_n4")) graph_1.add_edge(Edge(_from="n1", _to="c1")) graph_1.add_edge(Edge(_from="n4", _to="c1")) graph_1.add_edge(Edge(_from="n2", _to="c2")) graph_1.add_edge(Edge(_from="n3", _to="c3")) return graph_1
def generate_basic_graph() -> GraphDataStruct: # Create a graphe structure tmp_meta = Metadata(Source.DBDUMP) tmp_graph = GraphDataStruct(tmp_meta) # For each cluster, fetch all pictures and store it for cluster_id in range(0, 2): tmp_graph.add_cluster( Cluster(label="", tmp_id=cluster_id, image="")) for id in range(0, 3): pic_id = str(cluster_id) + "_" + str(id) # Label = picture score, here tmp_graph.add_node( Node(label="picture name +" + pic_id, tmp_id=pic_id, image="")) tmp_graph.add_edge(Edge(_from=cluster_id, _to=pic_id)) return tmp_graph
def test_compute_score_for_one_threshold(self): # Graph example. Please check documentation for more information cal_conf = Default_calibrator_conf() quality_evaluator = similarity_graph_quality_evaluator.similarity_graph_quality_evaluator( cal_conf) requests_results = [ # 1 to 2 and 3 { "list_pictures": [{ "cluster_id": "XXX", "decision": "YES", "distance": 0.1, "image_id": "2" }, { "cluster_id": "XXX", "decision": "YES", "distance": 0.6, "image_id": "3" }], "request_id": "1", "status": "matches_found", "request_time": 0 }, { "list_pictures": [{ "cluster_id": "XXX", "decision": "YES", "distance": 0.3, "image_id": "6" }], "request_id": "2", "status": "matches_found", "request_time": 0 }, { "list_pictures": [{ "cluster_id": "XXX", "decision": "YES", "distance": 0.2, "image_id": "1" }], "request_id": "3", "status": "matches_found", "request_time": 0 }, { "list_pictures": [{ "cluster_id": "XXX", "decision": "YES", "distance": 0.4, "image_id": "2" }], "request_id": "4", "status": "matches_found", "request_time": 0 }, { "list_pictures": [{ "cluster_id": "XXX", "decision": "YES", "distance": 0.6, "image_id": "4" }], "request_id": "5", "status": "matches_found", "request_time": 0 }, { "list_pictures": [{ "cluster_id": "XXX", "decision": "YES", "distance": 0.7, "image_id": "2" }], "request_id": "6", "status": "matches_found", "request_time": 0 } ] # Create the reference graph graph_data_struct = GraphDataStruct(Metadata(Source.DBDUMP)) graph_data_struct.add_cluster(Cluster(label="A", tmp_id="A", image="A")) graph_data_struct.add_cluster(Cluster(label="B", tmp_id="B", image="B")) graph_data_struct.add_cluster(Cluster(label="C", tmp_id="C", image="C")) graph_data_struct.add_node(Node(label="1", tmp_id="1", image="1")) graph_data_struct.add_node(Node(label="2", tmp_id="2", image="2")) graph_data_struct.add_node(Node(label="3", tmp_id="3", image="3")) graph_data_struct.add_node(Node(label="4", tmp_id="4", image="4")) graph_data_struct.add_node(Node(label="5", tmp_id="5", image="5")) graph_data_struct.add_node(Node(label="6", tmp_id="6", image="6")) graph_data_struct.add_edge(Edge(_from="1", _to="A")) graph_data_struct.add_edge(Edge(_from="2", _to="A")) graph_data_struct.add_edge(Edge(_from="3", _to="A")) graph_data_struct.add_edge(Edge(_from="4", _to="B")) graph_data_struct.add_edge(Edge(_from="5", _to="B")) graph_data_struct.add_edge(Edge(_from="6", _to="C")) pprint.pprint(requests_results) pprint.pprint(graph_data_struct.export_as_dict()) quality_evaluator.cal_conf.NB_TO_CHECK = 1 dist_threshold = 0 stats_datastruct = quality_evaluator.compute_score_for_one_threshold( requests_results, graph_data_struct, dist_threshold) print(stats_datastruct) self.assertEqual(stats_datastruct.P, 3) self.assertEqual(stats_datastruct.N, 3) self.assertAlmostEqual(stats_datastruct.TPR, 0.0, delta=0.05) self.assertAlmostEqual(stats_datastruct.TNR, 1.0, delta=0.05) self.assertAlmostEqual(stats_datastruct.FPR, 0.0, delta=0.05) self.assertAlmostEqual(stats_datastruct.FNR, 1.0, delta=0.05) dist_threshold = 0.5 stats_datastruct = quality_evaluator.compute_score_for_one_threshold( requests_results, graph_data_struct, dist_threshold) print(stats_datastruct) self.assertEqual(stats_datastruct.P, 3) self.assertEqual(stats_datastruct.N, 3) self.assertAlmostEqual(stats_datastruct.TPR, 0.66, delta=0.05) self.assertAlmostEqual(stats_datastruct.TNR, 0.33, delta=0.05) self.assertAlmostEqual(stats_datastruct.FPR, 0.66, delta=0.05) self.assertAlmostEqual(stats_datastruct.FNR, 0.33, delta=0.05) dist_threshold = 1 stats_datastruct = quality_evaluator.compute_score_for_one_threshold( requests_results, graph_data_struct, dist_threshold) print(stats_datastruct) self.assertEqual(stats_datastruct.P, 3) self.assertEqual(stats_datastruct.N, 3) self.assertAlmostEqual(stats_datastruct.TPR, 1.0, delta=0.05) self.assertAlmostEqual(stats_datastruct.TNR, 0.0, delta=0.05) self.assertAlmostEqual(stats_datastruct.FPR, 1.0, delta=0.05) self.assertAlmostEqual(stats_datastruct.FNR, 0.0, delta=0.05) quality_evaluator.cal_conf.NB_TO_CHECK = 3 dist_threshold = 0.5 stats_datastruct = quality_evaluator.compute_score_for_one_threshold( requests_results, graph_data_struct, dist_threshold) print(stats_datastruct) self.assertEqual(stats_datastruct.P, 4) self.assertEqual(stats_datastruct.N, 3) self.assertAlmostEqual(stats_datastruct.TPR, 0.5, delta=0.05) self.assertAlmostEqual(stats_datastruct.TNR, 0.33, delta=0.05) self.assertAlmostEqual(stats_datastruct.FPR, 0.66, delta=0.05) self.assertAlmostEqual(stats_datastruct.FNR, 0.5, delta=0.05)
def results_list_to_graph(requests_list, nb_match: int = 1, yes_maybe_no_mode: bool = False) -> GraphDataStruct: """ Construct a graph from results list of requests on the database Hypothesis : All database pictures are requested pictures Edges are colored : from green to red depending on the match index (Best is green) :param requests_list: a List of results extracted from server :param nb_match: Number of matches per pictures to add to the graph (1=first level match/best match, 2 = 2 best match per picture, etc.) :return: A graph datastructure """ logger = logging.getLogger(__name__) # logger.debug(f"Received request_list : {pformat(requests_list)}") graph = GraphDataStruct(meta=Metadata(source=Source.DBDUMP)) # Color Managemement # FF0000 = red # 00FF00 = green short_color_list = ["#00FF00", "#887700", "#CC3300", "#FF0000"] color_list = ["#00FF00", "#11EE00", "#22DD00", "#33CC00", "#44BB00", "#55AA00", "#669900", "#778800", "#887700", "#996600", "#AA5500", "#BB4400", "#CC3300", "#DD2200", "#EE1100", "#FF0000"] if nb_match < 4: # We only have 4 colors if we don't want that much matches. # This way, first match is green, second orange, third red, etc. color_list = short_color_list # TODO : Print all YES match # For each request for curr_req_1 in requests_list: # logger.debug(f"Curent request : {pformat(curr_req_1)}") req_id = curr_req_1.get("request_id", None) # Requested picture => add a node graph.add_node(Node(label=req_id, tmp_id=req_id, image=req_id)) # For each request for curr_req_2 in requests_list: # We remove the picture "itself" from the matches tmp_clean_matches = get_clear_matches(curr_req_2) req_id = curr_req_2.get("request_id", None) # Add edge for each best pictures for i in range(min(nb_match, len(tmp_clean_matches))): dist = round(tmp_clean_matches[i].get("distance", None), 4) deci = tmp_clean_matches[i].get("decision", "UNKNOWN") dest_id = tmp_clean_matches[i].get("image_id", None) if dist is None: logger.error(f"Problem with request, no distance: {pformat(curr_req_2)}") continue if dest_id is None: logger.error(f"Problem with request, no match's image id: {pformat(curr_req_2)}") continue if yes_maybe_no_mode: # set threshold depending on Yes/Maybe/No in VisJS # By creatin a fictive distance, depending on the decision fictive_dist = scoring_datastrutures.DecisionTypes.get_fictive_dist(deci) # Add a fictive edge graph.add_edge(Edge(_from=req_id, _to=dest_id, color={"color": color_list[i % len(color_list)]}, label=deci + ":" + str(dist), value=fictive_dist)) else: graph.add_edge(Edge(_from=req_id, _to=dest_id, color={"color": color_list[i % len(color_list)]}, label=deci + ":" + str(dist), value=dist)) return graph