Source code for svcco.branch_addition.add_bifurcation

import numba as nb
import numpy as np
from .add_edge import *
from .basis import *
from .calculate_length import *
from copy import deepcopy
import time

#@nb.jit(nopython=True,cache=True,nogil=True)
[docs]def add_bifurcation(tree,parent_edge,candidate_point,results,optimum,isforest=False): ########### UNPACK LOCAL OPTIMIZATION DATA ############## start = time.time() R0 = results[0] L0 = results[1] f_terminal = results[2] f_sister = results[3] bif_points = results[5] RR = np.array(results[6]) RL = np.array(results[7]) bifs = np.array(results[8]) flows = np.array(results[9]) main_idx = np.array(results[10]) alt_idx = np.array(results[11]) main_scale = np.array(results[12]) alt_scale = np.array(results[13]) R_terminal = results[14] R_sister = results[15] if isforest: sub_division_map = deepcopy(tree.sub_division_map) sub_division_index = deepcopy(tree.sub_division_index) else: sub_division_map = tree.sub_division_map sub_division_index = tree.sub_division_index Qterm = tree.parameters['Qterm'] tree.time['add_1'].append(time.time()-start) ########################################################### ############### Copy Data and Make New #################### start = time.time() if isforest: data = deepcopy(tree.data) else: data = tree.data #if sum(tree.data[tree.data[:,-1]==-1]) == 0: # nosegments = True #else: # nosegments = False # segment_data = deepcopy(tree.data[tree.data[:,-1]==-1]) nosegments = True data = np.vstack((data,np.zeros((2,data.shape[1])))) ## would need to be changed for adding non-linear vessels bifurcation_point = bif_points[optimum] add_edge(data[:-1,:],bifurcation_point,candidate_point,parent_edge,Qterm) data[-2,17] = np.float(parent_edge) terminal_sub_division = [-1] downstream_node = data[parent_edge,3:6] downstream_flow = data[parent_edge,22].item() bifurcation_node = data[-2,18].item() distal_node = data[parent_edge,19].item() left = data[parent_edge,15].item() right = data[parent_edge,16].item() lbif = data[parent_edge,23] rbif = data[parent_edge,24] downstream_rr = data[parent_edge,27] add_edge(data,bifurcation_point,downstream_node,parent_edge, downstream_flow,proximal_idx=bifurcation_node, distal_idx=distal_node,left_child=left, right_child=right) data[-1,17] = np.float(parent_edge) sister_sub_division = [-1] tree.time['add_2'].append(time.time()-start) #pidx_start = sub_division_index[parent_edge] #pidx_end = sub_division_index[parent_edge+1] start_time = time.time() if left > 0 or right > 0: # if this vessel is not a terminal it will have a subdivision map start = sub_division_index[parent_edge] #start of the if parent_edge+1 == len(sub_division_index): end = None else: end = sub_division_index[parent_edge+1] k = sub_division_map[start+1:end] data[k,28] = (data[k,28]/data[parent_edge,28])*f_sister[optimum] # replace the old bifurcation with the new scaling data[k,26] += 1 # incrament the depth of all subdivision vessels sister_sub_division.extend(k) data[-1,23] = lbif data[-1,24] = rbif data[-1,28] = f_sister[optimum] data[-1,27] = downstream_rr data[-2,28] = f_terminal[optimum] data[-1,25] = R_sister[optimum] data[-2,25] = R_terminal[optimum] tree.time['add_3'].append(time.time()-start_time) if int(left) > 0: data[int(left),17] = data[-1,-1] if int(right) > 0: data[int(right),17] = data[-1,-1] data[parent_edge,3:6] = bifurcation_point data[parent_edge,19] = bifurcation_node data[parent_edge,15] = data[-1,-1] data[parent_edge,16] = data[-2,-1] new_terminal_edge = int(data[-2,-1]) new_sister_edge = int(data[-1,-1]) basis(data,parent_edge.item()) length(data,parent_edge.item()) sub_division_map.extend(terminal_sub_division) #should be [-1] sub_division_index = np.append(sub_division_index,len(sub_division_map)-1) sub_division_index = np.append(sub_division_index,len(sub_division_map)) sub_division_map.extend(sister_sub_division) #should be a copy of the parent subdivision #print() #print(sub_division_index) #sub_division_index = np.argwhere(np.array(sub_division_map)==-1).flatten() #print(sub_division_index) start_time = time.time() for i in range(len(main_idx)): start = sub_division_index[main_idx[i]] if main_idx[i] == sub_division_index[-1]: end = None else: end = sub_division_index[main_idx[i]+1] if len(sub_division_map[start+1:end]) > 0 and main_idx[i] > 0: if alt_idx[i] > -1: alt_start = sub_division_index[alt_idx[i]] if alt_idx[i] == sub_division_index[-1]: alt_end = None else: alt_end = sub_division_index[alt_idx[i]+1] tmp = sub_division_map[alt_start+1:alt_end] data[tmp,28] = (data[tmp,28]/data[alt_idx[i],28])*alt_scale[i][optimum] data[main_idx[i],25] = RR[i][optimum] data[main_idx[i],27] = RL[i][optimum] data[main_idx[i],22] = flows[i] data[main_idx[i],23] = bifs[i*2][optimum] data[main_idx[i],24] = bifs[i*2+1][optimum] if main_idx[i] > 0: data[main_idx[i],28] = main_scale[i][optimum] if alt_idx[i] > -2: data[alt_idx[i],28] = alt_scale[i][optimum] data[0,21] = R0[optimum] data[0,23] = bifs[-2][optimum] data[0,24] = bifs[-1][optimum] data[0,25] = RR[-1][optimum] data[0,27] = RL[-1][optimum] data[0,22] = flows[-1] data[:,21] = data[:,28]*data[0,21] if not nosegments: segment_data[:,21] = data[segment_data[:,29].astype(int),28]*data[0,21] total_data = np.vstack((data,segment_data)) else: total_data = data #total_data = update_map(data,main_idx,alt_idx,main_scale,alt_scale,RR,RL,flows,bifs,R0,sub_division_index,np.array(sub_division_map),optimum,new_sister_edge,new_terminal_edge) main_idx = np.flip(np.sort(main_idx)) for i in range(len(main_idx)): sub_division_map.insert(sub_division_index[main_idx[i]]+1,int(new_sister_edge)) sub_division_map.insert(sub_division_index[main_idx[i]]+1,int(new_terminal_edge)) #sub_division_index[main_idx[i]] += (len(main_idx)-1-i)*2 #total_data,main_idx,sub_division_index,sub_division_map = update_map(data,main_idx,alt_idx,main_scale,alt_scale,RR,RL,flows,bifs,R0,sub_division_index,np.array(sub_division_map),optimum,new_sister_edge,new_terminal_edge,sub_division_map) #adder = 0 #for i in range(len(sub_division_index)): # sub_division_index[i] += adder # if i in main_idx: # adder += 2 tree.time['add_4'].append(time.time()-start_time) sub_division_index = update_index(sub_division_index,main_idx) #tree.time['add_4'].append(time.time()-start_time) #print() #print('main_idx: {}'.format(main_idx)) #print('manual: {}'.format(sub_division_index)) #sub_division_index = np.argwhere(np.array(sub_division_map)==-1).flatten() #print('np arg: {}'.format(sub_division_index)) #if time.time()-start > 100: # val = 0 #else: # val = time.time()-start #tree.time['add_4'].append(time.time()-start_time) return total_data,sub_division_map,sub_division_index
[docs]@nb.jit(nopython=True,cache=True,nogil=True) def update_index(sub_division_index,main_idx): adder = 0 for i in range(len(sub_division_index)): sub_division_index[i] += adder if i in main_idx: adder += 2 return sub_division_index
""" @nb.jit(nopython=True,cache=True,nogil=True) def update_map(data,main_idx,alt_idx,main_scale,alt_scale,RR,RL,flows,bifs,R0,sub_division_index,sub_division_map,optimum,new_sister_edge,new_terminal_edge): for i in range(len(main_idx)): start = sub_division_index[main_idx[i]] if main_idx[i] == sub_division_index[-1]: end = None else: end = sub_division_index[main_idx[i]+1] if len(sub_division_map[start+1:end]) > 0 and main_idx[i] > 0: if alt_idx[i] > -1: alt_start = sub_division_index[alt_idx[i]] if alt_idx[i] == sub_division_index[-1]: alt_end = None else: alt_end = sub_division_index[alt_idx[i]+1] tmp = sub_division_map[alt_start+1:alt_end] data[tmp,28] = (data[tmp,28]/data[alt_idx[i],28])*alt_scale[i][optimum] data[main_idx[i],25] = RR[i][optimum] data[main_idx[i],27] = RL[i][optimum] data[main_idx[i],22] = flows[i] data[main_idx[i],23] = bifs[i*2][optimum] data[main_idx[i],24] = bifs[i*2+1][optimum] if main_idx[i] > 0: data[main_idx[i],28] = main_scale[i][optimum] if alt_idx[i] > -2: data[alt_idx[i],28] = alt_scale[i][optimum] data[0,21] = R0[optimum] data[0,23] = bifs[-2][optimum] data[0,24] = bifs[-1][optimum] data[0,25] = RR[-1][optimum] data[0,27] = RL[-1][optimum] data[0,22] = flows[-1] data[:,21] = data[:,28]*data[0,21] return data """