def split_edges_prior_to_central_dilation(G='G_standard.pkl', edges=[3], savename='G_standard_split.pkl',cf=0.8): """Splits specific edges in two end and one central parts, in order to prepare them for central dilation / constriction. WARNING: For newly added edges the source is always the smaller vertex index and the target the higher vertex index. This needs to be considered in post-processing (e.g. flow direction, position of RBCs) INPUT: G: VascularGraph edges: Edges to be split savename: Name of VascularGraph with split-edges to be saved to disk. cf: Center fraction. E.g. cf=2/3 would split the edge into 1/6, 4/6, 1/6. HOWEVER, the resulting splitting position depends on the number of available points and the spacing between the points. OUTPUT: None, VascularGraph written to disk. """ savename2=savename edges2=edges G = vgm.read_pkl(G) G.es(edges2)['split'] = [True for e in edges] G.add_points(1.) while len(G.es(split_ne=None)) > 0: eindex = G.es(split_ne=None).indices[0] dfactor = 1. vi, ei, dilated_ei = G.central_dilation(eindex, dfactor, cf) G.es[ei]['split'] = [None for e in ei] del G.es['split'] stdout.write("\rDilation Step \n") vgm.write_pkl(G, savename)
def split_and_steady_state_noRBCs(G='G_standard',edges=[3],fdilation=[1.0],cf=0.8): """Test effect of central dilation at a bifurcation of equal-flow daughter vessels. WARNING: For newly added edges the source is always the smaller vertex index and the target the higher vertex index. This needs to be considered in post-processing (e.g. flow direction, position of RBCs) INPUT: G: Input Graph as pkl-file (name without the ending .pkl) edges: list of edges which are dilated fdilation: list of factors by which the edge diameter is changed cf: Center fraction. E.g. cf=2/3 would split the edge into 1/6, 4/6, 1/6. HOWEVER, the resulting splitting position depends on the number of available points and the spacing between the points. OUTPUT: None, results written to disk. """ filename=G+'.pkl' savename='G_split.pkl' G = vgm.read_pkl(filename) G.add_points(1.) G.es['dfactor'] = [None for e in G.es] G.es[edges]['dfactor'] = fdilation while len(G.es(dfactor_ne=None)) > 0: eindex = G.es(dfactor_ne=None).indices[0] dfactor = G.es[eindex]['dfactor'] vi, ei, dilated_ei = G.central_dilation(eindex, dfactor, cf) G.es[ei]['dfactor'] = [None for e in ei] vgm.write_pkl(G, savename) LSd = vgm.LinearSystem(G) LSd.solve(method='direct')
def generate_db(): """Generates a database of vascular trees, both arterial and venous. INPUT: None OUTPUT: Arterial and venous tree database written to disk. Note that this function uses hardcoded directories and filenames! """ ### START INPUT ------------------------------------------------------- dataDir = pjoin(basedir, 'Data/2010/srXTM_processed') outDir = pjoin(basedir, 'Data/2010/vascularTrees') vtpDir = pjoin(basedir, 'Data/2010/vascularTrees/vtp') amDir = pjoin(basedir, 'Data/2010/vascularTrees/am') fileEnding = '_rr.pkl' parallel = False ### END INPUT --------------------------------------------------------- if not os.path.exists(outDir): os.mkdir(outDir) sampleDirs = glob.glob1(dataDir, '*') sampleDirs = [sd for sd in sampleDirs if os.path.isdir(os.path.join(dataDir, sd))] Processes = [] for sd in sampleDirs: print(sd) G = vgm.read_pkl(os.path.join(dataDir, sd, sd+fileEnding)) vertices = [] if ('av' in G.attributes()) and ('vv' in G.attributes()): vertices.append(G['av']) vertices.append(G['vv']) else: for vtype in ['arteries', 'veins']: coords = vgm.read_landmarks(os.path.join(dataDir, sd, vtype+'_'+sd)) vs = vgm.vertices_from_coordinates(G, coords) if max(vs[1]) > 0.0: print('WARNING: landmark file %s faulty!' % vtype+'_'+sd) vertices.append(vs[0]) if parallel: P1 = mp.Process(target=add_to_db, args=(G, vertices[0], 7., os.path.join(outDir, 'arteryDB')), kwargs={'sampleName':sd, 'vtpDir':vtpDir+'_artery','amDir':amDir+'_artery'}) P2 = mp.Process(target=add_to_db, args=(G, vertices[1], 7., os.path.join(outDir, 'veinDB')), kwargs={'sampleName':sd, 'vtpDir':vtpDir+'_vein','amDir':amDir+'_vein'}) P1.start() P2.start() P1.join() P2.join() else: add_to_db(G, vertices[0], 7., os.path.join(outDir, 'arteryDB'), sampleName=sd, vtpDir=vtpDir+'_artery',amDir=amDir+'_artery') add_to_db(G, vertices[1], 7., os.path.join(outDir, 'veinDB'), sampleName=sd, vtpDir=vtpDir+'_vein', amDir=amDir+'_vein')
def export(input_dir, output_dir): """Exports pickled iGraph files to GraphML format. INPUT: input_dir: The directory where the pickled iGraph files reside. output_dir: The directory in which to store the GraphML files. OUTPUT: GraphML files written to disk. """ files = glob.glob1(input_dir, '*.pkl') if os.path.isdir(output_dir): ans = raw_input('Directory %s exists. Overwrite files? [y/n]: ' % output_dir) if ans[0] == 'y': gml_files = glob.glob(os.path.join(output_dir, '*')) map(os.remove, gml_files) else: return else: os.mkdir(output_dir) for f in files: outname = f[:-4] + '.graphml' G = vgm.read_pkl(os.path.join(input_dir,f)) # Delete unnecessary vertex properties: v_attributes = G.vs.attribute_names() for va in v_attributes: if va not in ['r']: del G.vs[va] # Delete unnecessary edge properties: e_attributes = G.es.attribute_names() for ea in e_attributes: if ea not in ['diameter', 'diameters', 'length', 'lengths', 'points']: del G.es[ea] # Delete unnecessary graph properties: g_attributes = G.attributes() for ga in g_attributes: if ga not in ['attachmentVertex', 'sampleName', 'distanceToBorder', 'defaultUnits', 'avZOffset']: del G[ga] vgm.write_graphml(G, os.path.join(output_dir, outname))
def extend_from_db(G, attachmentVertices, dbDirectory): """Extends a VascularGraph at given attachment vertices with vascular trees chosen randomly from a tree database. INPUT: G: VascularGraph attachmentVertices: Vertices at which the vascular trees are to be attached. dbDirectory: The directory of the database as string. OUTPUT: None (G is modified in-place.) """ # Get names of database files: dbFiles = glob.glob1(dbDirectory, '*.pkl') # Determine number of vascular trees present in the database: dbCount = len(dbFiles) # At each attachment vertex, extend the VascularGraph with a vascular tree # from the database: Gtrees = vgm.VascularGraph(0) treeno = 1 G.vs['degree']=G.degree() for vertex in attachmentVertices: #print('Tree %i of %i' % (treeno, len(attachmentVertices))); treeno += 1 i = np.random.random_integers(0,dbCount-1,1)[0] vascularTree = vgm.read_pkl(os.path.join(dbDirectory, dbFiles[i])) offset = G.vs[vertex]['r'] - \ vascularTree.vs[vascularTree['attachmentVertex']]['r'] vgm.shift(vascularTree, offset) Gtrees.disjoint_union_attribute_preserving(vascularTree, 'omit') #G.union_attribute_preserving(vascularTree) if G.vs['apv'][vertex] == 1: kindAttr='pa' elif G.vs['vpv'][vertex] == 1: kindAttr='pv' else: kindAttr='n' stdout.flush() G.union_attribute_preserving(Gtrees, 'omit',kind=kindAttr)
def write_statistics(database, outfile, vType, minVcount=1): """Traverses the vessel database, assigns modified strahler orders to each vascular tree and groups segments of the same order into elements. Writes the statistics based on each tree's elements to an excel file. INPUT: database: The path to the vessel database. outfile: The name of the output file containing the vessel statistics. vType: The type of trees. This can be either 'a' (arterial) or 'v' (venous). minVcount: The minimum number of vertices in a tree to be considered in the statistics. OUTPUT: None (file written to disk). """ lengthDB = [[] for i in xrange(25)] vcountDB = [] ## Prepare excel file for writing: #font0 = xlwt.Font() #font0.name = 'Times New Roman' #font0.colour_index = 2 #font0.bold = True #style0 = xlwt.XFStyle() #style0.font = font0 #font1 = xlwt.Font() #font1.name = 'Times New Roman' #font1.colour_index = 0 #font1.bold = True #style1 = xlwt.XFStyle() #style1.font = font1 #wb = xlwt.Workbook() # Loop over trees in database and write statistics to file: trees = [(int(os.path.basename(t)[:-4]), t) for t in glob.glob(os.path.join(database, '*.pkl'))] trees = [t[1] for t in sorted(trees)] tenPercSteps = np.round(np.linspace(1, 10, 10) * len(trees) / 10.) percentages = np.linspace(10, 100, 10) print('Writing database...') treeCount = 0 for i, tree in enumerate(trees): print(tree) # Read and process tree data: G = vgm.read_pkl(tree) vcountDB.append(G.vcount()) if (i+1) in tenPercSteps: print('%i percent completed' % int(percentages[np.setmember1d(tenPercSteps, [i+1])][0])) if G.vcount() < minVcount: continue #------------------------------------------------------------- # Delete order 2 vertices and add length and conductance # (initially None for the new, joined edges). Rename the attachment # vertex (vertex indexing changes while order 2 vertices are removed): avr = G.vs[G['attachmentVertex']]['r'] G.delete_order_two_vertices() G.es['length'] = [sum(e['lengths']) for e in G.es] vgm.add_conductance(G, vType) # Delete selfloops: G.delete_selfloops() KDT = kdtree.KDTree(G.vs['r']) G['attachmentVertex'] = int(KDT.query(avr)[1]) #------------------------------------------------------------- strahler.modified_strahler_order(G, 0.99) Gel = strahler.assign_elements(G) maxOrder = max(Gel.vs['order']) cl = 0 # current line # Write tree ID, sample ID, vcount, ecount: ws = wb.add_sheet('Tree' + str(treeCount)) treeCount = treeCount + 1 ws.write(cl, 0, 'Tree ID', style0) ws.write(cl, 1, int(string.strip(os.path.basename(tree), '.pkl'))) cl = cl + 1 ws.write(cl, 0, 'Sample ID', style0) ws.write(cl, 1, G['sampleName']) cl = cl + 1 ws.write(cl, 0, 'Vertices', style0) ws.write(cl, 1, G.vcount()) cl = cl + 1 ws.write(cl, 0, 'Edges', style0) ws.write(cl, 1, G.ecount()) cl = cl + 1 ws.write(cl, 0, 'Dist to border', style0) ws.write(cl, 1, G['distanceToBorder']) cl = cl + 1 ws.write(cl, 0, 'Root offset', style0) ws.write(cl, 1, G['avZOffset']) cl = cl + 3 # Write 'order' header: ws.write(cl, 0, 'Order', style0) for order in range(maxOrder + 1): ws.write(cl, order+1, order, style0) cl = cl + 1 # Write element frequency 'N': ws.write(cl, 0, 'N', style1) for order in range(maxOrder + 1): ws.write(cl, order+1, len(Gel.vs(order_eq=order))) cl = cl + 1 # Write 'segments per element': # Note that this is the total number of elements of an order divided by # the total number of segments in that order (i.e. not on an element-by- # element basis). ws.write(cl, 0, 'SpE', style1) for order in range(maxOrder + 1): numElements = len(Gel.vs(order_eq=order)) numSegments = sum([len(v['edges']) for v in Gel.vs(order_eq=order)]) ws.write(cl, order+1, numSegments / numElements) cl = cl + 1 # Write element 'length' and 'diameter': for eProperty in ['length', 'diameter']: ws.write(cl, 0, eProperty + ' (mean) [micron]', style1) ws.write(cl+1, 0, eProperty + ' (std) [micron]', style1) for order in range(maxOrder + 1): data = [] for element in Gel.vs(order_eq=order): if eProperty == 'length': # Length of element is sum of segment-lengths: data.append(sum(G.es[element['edges']][eProperty])) else: # Diameter of element is mean of segment-diameters: data.append(np.mean(G.es[element['edges']][eProperty])) ws.write(cl, order+1, np.mean(data)) ws.write(cl+1, order+1, np.std(data)) if eProperty == 'length': lengthDB[order].append(np.mean(data)) cl = cl + 2 # Add some additional whitespace: cl = cl + 2 # Compute connectivity matrix and branching angles: cm = dict(zip(range(maxOrder + 1), [dict(zip(range(maxOrder + 1), [[] for o in range(maxOrder + 1)])) for o in range(maxOrder + 1)])) ba = dict(zip(range(maxOrder + 1), [dict(zip(range(maxOrder + 1), [[] for o in range(maxOrder + 1)])) for o in range(maxOrder + 1)])) # Loop over the elements of G, which are the vertices of Gel: for elm in Gel.vs: order = elm['order'] orderCounter = dict(zip(range(maxOrder + 1), [0 for o in range(maxOrder + 1)])) branchingAngle = dict(zip(range(maxOrder + 1), [[] for o in range(maxOrder + 1)])) # Loop over neighboring elements: for nElm in Gel.vs(Gel.neighbors(elm.index)): # Find vertex common to both elements. # Note that two elements can theoretically touch at more than # one location, here only the first common vertex is considered. vertex = int(np.array(elm['vertices'])[np.setmember1d(elm['vertices'], nElm['vertices'])][0]) # Find the edge that is part of the current element, adjacent, # and upstream to vertex. This ensures a 'natural', flow-based # choice of nElm-elm edge angle if the nElm edge connects to # than one elm-edges. # Note that edges at equal mean pressures are not considered! edges = np.array(elm['edges'])[np.setmember1d(elm['edges'], G.adjacent(vertex))] pMax = G.vs[vertex]['pressure'] edge = None for e in edges: e = int(e) # Convert from numpy integer meanP = np.mean(G.vs[G.es[e].tuple]['pressure']) if meanP > pMax: edge = e pMax = meanP # Skip this element-junction if the current element does not # contain upstream edges: if edge is None: continue # Find the edge that is part of the neighboring element, # adjacent, and downstream to vertex. This ensures a 'natural', # flow-based choice of nElm-elm edge angle if the elm edge # connects to more than one nElm-edges. # Note that edges at equal mean pressures are not considered! edges = np.array(nElm['edges'])[np.setmember1d(nElm['edges'], G.adjacent(vertex))] pMin = G.vs[vertex]['pressure'] nEdge = None for e in edges: e = int(e) # Convert from numpy integer meanP = np.mean(G.vs[G.es[e].tuple]['pressure']) if meanP < pMin: nEdge = e pMin = meanP # Skip this element-junction if the neighboring element does not # contain downstream edges: if nEdge is None: continue # Increase the count of the connectivity matrix and compute the # branching angle: orderCounter[nElm['order']] += 1 # A spherical region around the vertex is defined as the # branching region. The radius of the sphere is equal to the # maximum of the radii of the adjacent edges at the location of # the vertex. # The angle of an elements edge is then computed from the point # where the edge penetrates the sphere up to a distance of # about twice the vessel diameter away from the point of # penetration (unless of corse, the edge is shorter). # Radius of branching sphere: maxDiameter = 0 for e in G.adjacent(vertex): if G.es[e].source != vertex: d = G.es[e]['diameters'][-1] else: d = G.es[e]['diameters'][0] if d > maxDiameter: maxDiameter = d radius = maxDiameter / 2.0 # Vectors of the two branching edges: vectors = [] for e in (edge, nEdge): if G.es[e].source != vertex: points = G.es[e]['points'][::-1] else: points = G.es[e]['points'] startPoint = round(len(points) * radius / G.es[e]['length']) if startPoint > len(points)-1 or startPoint < 1: startPoint = 1 # In order to determine the direction of a vessel leaving a # bifurcation, we consider the points it comprises starting # just outside the bifurcation (i.e. at maximum radius of # all vessels incident to the bifurcation) and ending two # diameter lengths away from the bifurcation (angles # deviate least from the mean of angles determined from 1, # 2, 3, 4 diameter lengths). endPoint = min(len(points), round(len(points) * (radius + 2.0 * G.es[e]['diameter']) / G.es[e]['length'])) endPoint = max(endPoint, startPoint+1) points = points[startPoint-1:endPoint] vectors.append(vgm.average_path_direction(points)) # The magnidudes of the vectors are one, hence the angle can # be computed without dividing by them. Note that an angle of 0 # degrees means that both parent and child vessel are going in # the same direction, whereas 180 degrees signifies opposite # directions: angle = np.pi - np.arccos(np.dot(vectors[0], vectors[1])) branchingAngle[nElm['order']].append(angle) # Update the connectivity matrix and branching angle matrix with the # results of the current element: for nOrder in orderCounter.keys(): cm[order][nOrder].append(orderCounter[nOrder]) ba[order][nOrder].extend(branchingAngle[nOrder]) # Write connectivity matrix: ws.write(cl, 0, 'Connectivity matrix', style1) cl = cl + 1 ws.write(cl, 0, 'Order', style0) neo = [] # Number of elements of order o for j, order in enumerate(range(maxOrder + 1)): ws.write(cl, order+1, order, style0) ws.write(cl+j+1, 0, order, style0) neo.append(len(Gel.vs(order_eq=order))) cl = cl + 1 for order in range(maxOrder + 1): for nOrder in range(order, maxOrder + 1): # Use the following line instead of the previous, if order zero # elements never connect to other order zero elements: # for nOrder in range(max(1, order), maxOrder + 1): if cm[order][nOrder] != []: ws.write(order+cl, nOrder+1, sum(cm[order][nOrder]) / neo[nOrder]) # Equal spacing for all worksheets, irrespective of maximum order: cl = cl + 20 #cl = cl + maxOrder + 3 # Write branching angles: ws.write(cl, 0, 'Branching angles [deg]', style1) cl = cl + 1 ws.write(cl, 0, 'Order', style0) neo = [] # Number of elements of order o for j, order in enumerate(range(maxOrder + 1)): ws.write(cl, order+1, order, style0) ws.write(cl+j+1, 0, order, style0) neo.append(len(Gel.vs(order_eq=order))) cl = cl + 1 for order in range(maxOrder + 1): for nOrder in range(order, maxOrder + 1): # Use the following line instead of the previous, if order zero # elements never connect to other order zero elements: # for nOrder in range(max(1, order), maxOrder + 1): if ba[order][nOrder] != []: ws.write(order+cl, nOrder+1, np.rad2deg(np.mean(ba[order][nOrder]))) # Equal spacing for all worksheets, irrespective of maximum order: cl = cl + 20 #cl = cl + maxOrder + 3 # Compute irrigation / drainage volume: G.vs['z'] = [r[2] for r in G.vs['r']] zMin = np.min(G.vs['z']) zMax = np.max(G.vs['z']) cylinderLength = 200 intervals = vgm.intervals(zMin, zMax, (zMax - zMin) / cylinderLength) pl = np.concatenate(G.es['points'], axis=0) z = pl[:,2] if intervals == []: intervals = [[zMin, zMax]] volume = 0.0 for i, interval in enumerate(intervals): points = pl[np.nonzero(map(all, zip(z>interval[0], z<interval[1])))[0], :] # use points points = np.array(zip(points[:,0], points[:,1])) #points = np.array(G.vs(z_ge=interval[0], z_le=interval[1])['r']) # use vertices if len(points) < 3: continue # Add slab volume: com = np.mean(points, axis=0) hullpts = convex_hull.qhull(points) radius = np.mean([np.linalg.norm(com - hp) for hp in hullpts]) volume += np.pi * radius**2 * cylinderLength ws.write(cl, 0, 'Irrigation / drainage volume [microL]', style1) cl = cl + 1 ws.write(cl, 0, volume / 1e9) # Conversion micron**3 --> microL cl = cl + 3 wb.save(outfile) #wb2 = xlwt.Workbook() #ws2 = wb2.add_sheet('Element Length') cl = 0 maxOrder = 0 maxN = [] for order, ldb in enumerate(lengthDB): if len(ldb) > 0: maxOrder = order maxN.append(len(ldb)) for order in xrange(maxOrder + 1): ws2.write(0, order, order, style0) for i, l in enumerate(lengthDB[order]): ws2.write(i+1, order, l, style1) wb2.save('elmLength_' + vType + '.xls')
def split_and_evolve_to_steady_state(G='G_standard',edges=[3],fdilation=[1.0], time=4.0e3, ht0=0.4, Greference=None, plotPrms=[0., 4.0e3, 5e1, True], samplePrms=[0., 4.0e3, 2, True],cf=0.8,**kwargs): """Test effect of central dilation at a bifurcation of equal-flow daughter vessels. WARNING: For newly added edges the source is always the smaller vertex index and the target the higher vertex index. This needs to be considered in post-processing (e.g. flow direction, position of RBCs) INPUT: G: Input Graph as pkl-file (name without the ending .pkl) edges: list of edges which are dilated fdilation: list of factors by which the edge diameter is changed time: time periode which is evolved ht0: initial tube hematocrit value throughout the VascularGraph (this is ignored if Greference is defined) Greference: VascularGraph from which the initial RBC distribution is to be taken. (If set to None, RBCs will be distributed randomly, respecting the ht0 value supplied) The indices od edges and vertices as well as the direction must exactly the same. Otherwise there will be differences in the positions of RBCs plotPrms: plot parameters of RBC position plots (start, stop, step, overwrite) samplePrms: sample parameters (start, stop, step, overwrite) cf: Center fraction. E.g. cf=2/3 would split the edge into 1/6, 4/6, 1/6. HOWEVER, the resulting splitting position depends on the number of available points and the spacing between the points. **kwargs: httBC: tube hematocrit boundary condition at inflow SampleDetailed:Boolean whether every step should be samplede(True) or if the sampling is done by the given samplePrms(False) OUTPUT: None, results written to disk. """ SampleDetailed=False if 'SampleDetailed' in kwargs.keys(): SampleDetailed=kwargs['SampleDetailed'] filename=G+'.pkl' savename='G_split.pkl' G = vgm.read_pkl(filename) if kwargs.has_key('httBC'): for vi in G['av']: for ei in G.adjacent(vi): G.es[ei]['httBC']=kwargs['httBC'] G.add_points(1.) G.es['dfactor'] = [None for e in G.es] G.es[edges]['dfactor'] = fdilation while len(G.es(dfactor_ne=None)) > 0: eindex = G.es(dfactor_ne=None).indices[0] dfactor = G.es[eindex]['dfactor'] vi, ei, dilated_ei = G.central_dilation(eindex, dfactor, cf) G.es[ei]['dfactor'] = [None for e in ei] vgm.write_pkl(G, savename) if Greference is not None: Gr = vgm.read_pkl(Greference) G.es['rRBC'] = copy.deepcopy(Gr.es['rRBC']) LSd = vgm.LinearSystemHtd(G, dThreshold=10.0, ht0='current') else: LSd = vgm.LinearSystemHtd(G, dThreshold=10.0, ht0=ht0) if SampleDetailed: LSd.evolve(time=time, method='direct', plotPrms=plotPrms, samplePrms=samplePrms,SampleDetailed=True) else: LSd.evolve(time=time, method='direct', plotPrms=plotPrms, samplePrms=samplePrms)
def transient_dilation(G='G_standard',edges=[240, 243, 246, 249], fdilation=[1.1, 1.1, 0.9, 0.9], ttotal=900,ht0=0.4, ttransient=[400, 100, 10], plotstep=2, samplestep=2,**kwargs): """Load VascularGraph from disk. Run RBC-transport simulation, where a vessel is dilated at some point during the simulation. The dilation occurs in several steps. Note that there are some hard-coded variables which need to be adjusted if use-case changes! INPUT: G: Input Graph as pkl-file (name without the ending .pkl) edges: List of edges to dilate fdilation: List of dilation-factors ttotal: total time ht0: initial tube hematocrit value throughout the VascularGraph ttransient: [tinitial, tduration, steps]= [start of the dilation, time period till dilation is finished, number of steps for dilation] plotstep: timestep for plotting samplestep: timestep for sampling **kwargs: httBC: tube hematocrit boundary condition at inflow bigger: 0 = 2 Vessel network, 1= 2in2 Vessel network 2=Honeycomb wholeBr: Boolean whether the whole Branch is dilated (TRUE) or only center of the Branch is dilated (FALSE) OUTPUT: None, pre- and post-dilation VascularGraph, sample-dictionary, and RBC-plots are written to disk. """ filename=G+'.pkl' G = vgm.read_pkl(filename) if kwargs.has_key('httBC'): for vi in G['av']: for ei in G.adjacent(vi): G.es[ei]['httBC']=kwargs['httBC'] if kwargs.has_key('bigger'): NW=kwargs['bigger'] else: NW=0 if kwargs.has_key('wholeBr'): wholeBr=kwargs['wholeBr'] else: wholeBr=False G.add_points(1.) dilatedList=[] G.es['dfactor'] = [None for e in G.es] G.es[edges]['dfactor'] = 1.0 if wholeBr: dilatedList=edges else: while len(G.es(dfactor_ne=None)) > 0: eindex = G.es(dfactor_ne=None).indices[0] dfactor = G.es[eindex]['dfactor'] vi, ei, dilated_ei = G.central_dilation(eindex, dfactor, 4/5.) G.es[ei]['dfactor'] = [None for e in ei] dilatedList.append(dilated_ei) for i in range(len(dilatedList)): dilatedList[i]=dilatedList[i]-(len(dilatedList)-i-1) Gd = copy.deepcopy(G) LSd = vgm.LinearSystemHtdWCyth(Gd, dThreshold=10.0, ht0=ht0) #Run simulation without dilation till tinitial is reached LSd.evolve(time=ttransient[0], method='direct', plotPrms=[0, ttransient[0], plotstep], samplePrms=[0, ttransient[0], samplestep]) #LSd._plot_sample_average('G_pre_dilation.vtp') #vgm.write_pkl(Gd, 'G_pre_dilation.pkl') tstep = ttransient[1] / ttransient[2] Gd.es['dfactor'] = [None for e in G.es] Gd.es[dilatedList]['dfactor'] = fdilation fsteps = [Gd.es[edge]['diameter'] * (fdil - 1) / ttransient[2] for edge, fdil in zip(dilatedList, fdilation)] for step in xrange(ttransient[2]): for edge, fstep in zip(dilatedList, fsteps): Gd.es[edge]['diameter'] += fstep stdout.write("\rEdge = %g \n" %edge) stdout.write("\rDiameter = %f \n" %Gd.es[edge]['diameter']) #START: Consider Change of minDist during dilation of vessel LSd._update_minDist_and_nMax(esequence=dilatedList) LSd._update_tube_hematocrit(esequence=dilatedList) #END: Consider Change of minDist during dilation of vessel LSd._update_nominal_and_specific_resistance(esequence=dilatedList) LSd._update_eff_resistance_and_LS() LSd.evolve(time=tstep, method='direct', plotPrms=(0.0, tstep, plotstep), samplePrms=(0.0, tstep, samplestep),init=False) filename2='G_transient_dilation_'+str(step)+'.vtp' LSd._plot_sample_average(filename2) vgm.write_pkl(Gd, 'G_transient_dilation_'+str(step)+'.pkl') stdout.write("\rDilation Step = %g \n" %step) #stdout.write("\rDiameter = %f \n" %Gd.es[342]['diameter']) tstep = ttotal - ttransient[0] - ttransient[1] LSd.evolve(time=tstep, method='direct', plotPrms=(0.0, tstep, plotstep), samplePrms=(0.0, tstep, samplestep),init=False) vgm.write_pkl(Gd, 'G_post_dilation.pkl') vgm.write_vtp(Gd, 'G_post_dilation.vtp', False)