Skip to content
Snippets Groups Projects
Commit 4d943712 authored by David Hoksza's avatar David Hoksza
Browse files

remove empty space between compartments

parent 9b171f07
No related branches found
No related tags found
No related merge requests found
...@@ -3,6 +3,7 @@ import logging ...@@ -3,6 +3,7 @@ import logging
import numpy as np import numpy as np
from itertools import combinations from itertools import combinations
import sys import sys
import copy
from typing import List, Any, Dict, Set, Tuple, Collection, NamedTuple from typing import List, Any, Dict, Set, Tuple, Collection, NamedTuple
...@@ -32,6 +33,8 @@ class CompartmentCCNode(NamedTuple): ...@@ -32,6 +33,8 @@ class CompartmentCCNode(NamedTuple):
self.cmp_species[id].pos[0] += v[0] self.cmp_species[id].pos[0] += v[0]
self.cmp_species[id].pos[1] += v[1] self.cmp_species[id].pos[1] += v[1]
CompartmentGraphsIxs = Dict[str, List[int]]
def merge_compartments(cmp_gs: Dict[str, List[nx.MultiGraph]], g_tgt: nx.MultiGraph) -> nx.MultiGraph: def merge_compartments(cmp_gs: Dict[str, List[nx.MultiGraph]], g_tgt: nx.MultiGraph) -> nx.MultiGraph:
...@@ -275,7 +278,7 @@ def resolve_compartments_overlap(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], c ...@@ -275,7 +278,7 @@ def resolve_compartments_overlap(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], c
shift = bb1.get_rb() * dir - bb2.get_lt() * dir #this is the "distance" (one componennt is 0) by which the bb2 needs to be shifted to resolve the overlap shift = bb1.get_rb() * dir - bb2.get_lt() * dir #this is the "distance" (one componennt is 0) by which the bb2 needs to be shifted to resolve the overlap
for ix in cmp_ixs2: for ix in cmp_ixs2:
g_cc.nodes[ix]['data'].shift(shift) get_cmp_cc_node(g_cc, ix).shift(shift)
score = score_compartments_position(g_cc, gs, cmp_ixs1, cmp_ixs2) score = score_compartments_position(g_cc, gs, cmp_ixs1, cmp_ixs2)
if score['cnt_intersections'] < min_score['cnt_intersections'] or (score['cnt_intersections'] == min_score['cnt_intersections'] and score['dist'] < min_score['dist']): if score['cnt_intersections'] < min_score['cnt_intersections'] or (score['cnt_intersections'] == min_score['cnt_intersections'] and score['dist'] < min_score['dist']):
...@@ -283,10 +286,10 @@ def resolve_compartments_overlap(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], c ...@@ -283,10 +286,10 @@ def resolve_compartments_overlap(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], c
min_shift = shift min_shift = shift
for ix in cmp_ixs2: for ix in cmp_ixs2:
g_cc.nodes[ix]['data'].shift(-shift) get_cmp_cc_node(g_cc, ix).shift(-shift)
for ix in cmp_ixs2: # for ix in cmp_ixs2:
g_cc.nodes[ix]['data'].shift(min_shift) # get_cmp_cc_node(g_cc, ix).shift(min_shift)
#shift also the rest of the components which were in the direction of the shift #shift also the rest of the components which were in the direction of the shift
for ix in range(len(gs)): for ix in range(len(gs)):
...@@ -295,11 +298,11 @@ def resolve_compartments_overlap(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], c ...@@ -295,11 +298,11 @@ def resolve_compartments_overlap(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], c
if ix in cmp_ixs2 or \ if ix in cmp_ixs2 or \
(min_shift[0] < 0 and bb.get_x1() < bb2.get_x2()) or (min_shift[0] > 0 and bb.get_x2() > bb2.get_x1()) or \ (min_shift[0] < 0 and bb.get_x1() < bb2.get_x2()) or (min_shift[0] > 0 and bb.get_x2() > bb2.get_x1()) or \
(min_shift[1] < 0 and bb.get_y1() < bb2.get_y2()) or (min_shift[1] > 0 and bb.get_y2() > bb2.get_y1()): (min_shift[1] < 0 and bb.get_y1() < bb2.get_y2()) or (min_shift[1] > 0 and bb.get_y2() > bb2.get_y1()):
g_cc.nodes[ix]['data'].shift(min_shift) get_cmp_cc_node(g_cc, ix).shift(min_shift)
lt.pan(gs[ix], min_shift) lt.pan(gs[ix], min_shift)
def get_compartment_dict(gs: List[nx.MultiGraph]) -> Dict[str, List[int]]: def get_compartment_dict(gs: List[nx.MultiGraph]) -> CompartmentGraphsIxs:
cmp_ix: Dict[str, List[int]] = {} cmp_ix: Dict[str, List[int]] = {}
for i in range(len(gs)): for i in range(len(gs)):
cmp_name: str = gu.get_first_species(gs[i]).get_compartment_name() cmp_name: str = gu.get_first_species(gs[i]).get_compartment_name()
...@@ -311,11 +314,7 @@ def get_compartment_dict(gs: List[nx.MultiGraph]) -> Dict[str, List[int]]: ...@@ -311,11 +314,7 @@ def get_compartment_dict(gs: List[nx.MultiGraph]) -> Dict[str, List[int]]:
def handle_overlaps(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], cmp_ix: Dict[str, List[int]]): def handle_overlaps(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], cmp_ix: CompartmentGraphsIxs):
#First we group the connected components by compartment name
cmp_names = list(cmp_ix) cmp_names = list(cmp_ix)
for i in range(len(cmp_ix)): for i in range(len(cmp_ix)):
...@@ -323,15 +322,61 @@ def handle_overlaps(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], cmp_ix: Dict[s ...@@ -323,15 +322,61 @@ def handle_overlaps(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], cmp_ix: Dict[s
for j in range(i+1, len(cmp_ix)): for j in range(i+1, len(cmp_ix)):
cmp_name2 = cmp_names[j] cmp_name2 = cmp_names[j]
#we are obtaining the bounding boxes here and not before the cycle because they change when the compartments overlaps are bing resolved #we are obtaining the bounding boxes here and not before the cycle because they change when the compartments overlaps are bing resolved
bb1: gr.Rectangle = gr.utils.get_bounding_box([g_cc.nodes[ix]['data'].bb for ix in cmp_ix[cmp_name1]]) bb1: gr.Rectangle = gr.utils.get_bounding_box([get_cmp_cc_node(g_cc, ix).bb for ix in cmp_ix[cmp_name1]])
bb2: gr.Rectangle = gr.utils.get_bounding_box([g_cc.nodes[ix]['data'].bb for ix in cmp_ix[cmp_name2]]) bb2: gr.Rectangle = gr.utils.get_bounding_box([get_cmp_cc_node(g_cc, ix).bb for ix in cmp_ix[cmp_name2]])
if bb1.intersects_rectangle(bb2): if bb1.intersects_rectangle(bb2):
resolve_compartments_overlap(g_cc, gs, cmp_ix[cmp_name1], cmp_ix[cmp_name2], bb1, bb2) resolve_compartments_overlap(g_cc, gs, cmp_ix[cmp_name1], cmp_ix[cmp_name2], bb1, bb2)
def clear_spaces(g_cc, gs):
NotImplemented
def optimize_layout(g_cc, gs, cmp_ix): def get_cmp_cc_node(g: nx.MultiGraph, i: int) -> CompartmentCCNode:
return g.nodes[i]['data']
def get_cmp_bbs(g_cc: nx.MultiGraph, cmp_ix: CompartmentGraphsIxs) -> Dict[str, gr.Rectangle]:
bbs = {}
for cmp_name in cmp_ix:
bbs[cmp_name] = gr.utils.get_bounding_box([get_cmp_cc_node(g_cc, ix).bb for ix in cmp_ix[cmp_name]])
return bbs
def clear_spaces(g_cc: nx.MultiGraph, gs: List[nx.MultiGraph], cmp_ix: CompartmentGraphsIxs):
if len(cmp_ix) <= 1:
return
cmp_bb = get_cmp_bbs(g_cc, cmp_ix)
coords = []
for cmp_name, bb in cmp_bb.items():
coords.append({'coords': bb.get_lt(), 'begin': True, 'cmp_name': cmp_name})
coords.append({'coords': bb.get_rb(), 'begin': False, 'cmp_name': cmp_name})
sort_x = sorted(coords, key=lambda x: x['coords'][0])
sort_y = sorted(coords, key=lambda x: x['coords'][1])
for sort_coords, coord_ix in [(sort_x, 0), (sort_y, 1)]:
coord_i = sort_coords[1]
for i in range(2, len(sort_coords)):
# The first two coordinates are either one compartment or the beginning of two different compartments
coord_i_1 = coord_i
coord_i = sort_coords[i]
if not coord_i_1['begin'] and coord_i['begin']:
diff = coord_i['coords'][coord_ix] - coord_i_1['coords'][coord_ix]
shift = -(diff - settings.render.compartment_distance - settings.render.compartment_padding)
if shift < 0:
shift_vect = np.array([0,0])
shift_vect[coord_ix] = shift
for j in range(i, len(sort_coords)):
if sort_coords[j]['begin']:
for ix in cmp_ix[sort_coords[j]['cmp_name']]:
get_cmp_cc_node(g_cc, ix).shift(shift_vect)
lt.pan(gs[ix], shift_vect)
def optimize_layout(g_cc, gs):
NotImplemented NotImplemented
......
...@@ -11,6 +11,7 @@ class SettingsRender: ...@@ -11,6 +11,7 @@ class SettingsRender:
compact_optimal_dist = 300 compact_optimal_dist = 300
compartment_padding = 80 compartment_padding = 80
compartment_distance = 10
optimal_species_reaction_dist = 80 optimal_species_reaction_dist = 80
optimal_neighboring_species_dist = 80 optimal_neighboring_species_dist = 80
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment