Source code for svcco.forest_utils.compete_add

# Competitive growth of Multiple Vascular Networks within a Shared Domain
import numpy as np
import os #remove before final
import time #not neccessary?
from ..branch_addition.check import *
from ..branch_addition.close import *
from ..branch_addition.local_func_v7 import *
from ..collision.sphere_proximity import *
from ..collision.collision import *
from ..branch_addition.add_bifurcation import *
from ..branch_addition.sample_triad import *
from ..branch_addition.triangle import * #might not need
from ..branch_addition.basis import *
#from scipy import interpolate
#from scipy.spatial import KDTree
from ..branch_addition.get_point import *
from copy import deepcopy
#from .geodesic import extract_surface,geodesic
#from scipy.sparse.csgraph import shortest_path
#from .add_geodesic_path import *
import pyvista as pv
import random
from tqdm import tqdm

[docs]def compete_add(forest,network_ids=-1,radius_buffer=0.05,exact=True): #Find a viable new point to add within all_network_ids = list(range(forest.number_of_networks)) if network_ids == -1: network_ids = all_network_ids #points,_ = forest.boundary.pick(size=prefetch,homogeneous=True,replacement=False) #points = points.tolist() active_network_ids = deepcopy(network_ids) active_network_tree_ids = [list(range(forest.trees_per_network[net])) for net in all_network_ids] scale = len(network_ids) volume = deepcopy(forest.boundary.volume) forest.boundary.volume = forest.boundary.volume/scale #networks_copy = deepcopy(forest.networks) unused_networks = list(set(all_network_ids) - set(active_network_ids)) while len(active_network_ids) > 0: for nid in active_network_ids: for njd in active_network_tree_ids[nid]: ## New if forest.networks[nid][njd].data.shape[0] < 100: if len(forest.networks[nid][njd].rng_points) <= 1: forest.networks[nid][njd].rng_points,_ = forest.boundary.pick(size=min(len(forest.boundary.tet_verts),10000),homogeneous=True,replacement=False) forest.networks[nid][njd].rng_points = forest.networks[nid][njd].rng_points.tolist() for n in range(len(forest.networks[nid][njd].rng_points)): pt = np.array(forest.networks[nid][njd].rng_points.pop(0)) if exact: other_vessels,distances = close_exact(forest.networks[nid][njd].data,pt) else: other_vessels,distances = close(forest.networks[nid][njd].data,pt) minimum_distance = min(distances) retry = False for idx in network_ids: for jdx in list(range(forest.trees_per_network[idx])): if idx == nid: continue if forest.networks[nid][njd].data.shape[0] < 100: other_vessels,distances = close_exact(forest.networks[idx][jdx].data,pt) else: other_vessels,distances = close(forest.networks[idx][jdx].data,pt) if min(distances) < minimum_distance: retry = True break if retry: break if retry: continue else: forest.networks[nid][njd].rng_points.insert(-1,pt.tolist()) ## #print(len(forest.networks[nid][njd].rng_points)) #print("Check: {}".format(forest.networks[nid][njd].rng_points[0])) vessel,data,sub_division_map,sub_division_index,threshold = forest.networks[nid][njd].add(-1,0,isforest=True,radius_buffer=radius_buffer) point = data[-2,3:6] #new terminal point #print(point) closest_network = nid _,closest_value = close_exact(forest.networks[nid][njd].data[vessel,:].reshape(1,forest.networks[nid][njd].data.shape[1]),point) escape = False for idx in network_ids: for jdx in list(range(forest.trees_per_network[idx])): if idx == nid: continue if exact: other_vessels,distances = close_exact(forest.networks[idx][jdx].data,point) else: other_vessels,distances = close(forest.networks[idx][jdx].data,point) minimum_distance = min(distances) minimum_vessel_point = (forest.networks[idx][jdx].data[other_vessels[0],0:3] + forest.networks[idx][jdx].data[other_vessels[0],3:6])/2 if minimum_distance < closest_value: vessel_within = True if not forest.convex: subdivisions = 5 for sub in range(1,2*subdivisions): tmp = point*(sub/(2*subdivisions)) + minimum_vessel_point*(1-sub/(2*subdivisions)) if not forest.boundary.within(tmp[0],tmp[1],tmp[2],2): vessel_within = False break if not vessel_within: continue else: escape = True break if escape: break if escape: #forest.networks[nid][njd] = deepcopy(networks_copy[nid][njd]) continue new_vessels = np.vstack((data[vessel,:],data[-2,:],data[-1,:])) repeat = False check_networks = unused_networks + [nid] for nikd in range(len(unused_networks)): if nikd == nid: check_trees = list(range(len(forest.networks[nikd]))) check_trees.remove(njd) else: check_trees = list(range(len(forest.networks[nikd]))) for njkd in check_trees: if not forest.networks[nikd][njkd].collision_free(new_vessels,radius_buffer=radius_buffer): repeat = True break if repeat: break if repeat: #forest.networks[nid][njd] = deepcopy(networks_copy[nid][njd]) continue else: forest.networks[nid][njd].data = data forest.networks[nid][njd].parameters['edge_num'] += 2 forest.networks[nid][njd].sub_division_map = sub_division_map forest.networks[nid][njd].sub_division_index = sub_division_index #print("List {}: {}, Id: {}".format(nid,active_network_tree_ids[nid],njd)) active_network_tree_ids[nid].remove(njd) if len(active_network_tree_ids[nid]) == 0: active_network_ids.remove(nid) #print("Active Networks: {}".format(active_network_ids)) forest.boundary.volume = volume