Ejemplo n.º 1
0
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 construct_cortical_network(G, gXtm, zLim=None, 
                               originXtm=None, insertXtm=False, invivo=True,BC=[60,10,0.2]):
    """Builds a VascularGraph that includes the pial vessels, penetrating
    arterioles and draining veins, as well as the capillary bed.
    INPUT: G: VascularGraph of the pial network. This should be created using
              the function construct_pial_network().
           gXTM: VascularGraph of srXTM data. This is implanted at location
                 originXtm of the cortical network.
           zLim: Limits of capillary grid in z-direction as tuple (zMin, zMax).
                 If not supplied, it will be determined from the artificial
                 network consisting of pial and penetrating vessels, as well as
                 the SRXTM sample.
           originXtm: The origin (x,y) of the cylindrical srXTM in the cortical
                      network, i.e. the location of its rotational axis. This
                      will be the network's center of mass, if not provided.
           sf: Scaling Factor by which to multiply vertex positions and
               diameters (e.g. to convert units of pixels to microns).
           epperc: Percentage of offshoots that should be en-passent. These are
                   chosen randomly.
           BC: list with pBC at inlet, pBC at outlet, inflow tube hematocrit 
    OUTPUT: G: VascularGraph.
    Note that this function relies on input from control.py
    """
    
    # Get settings from control file:
    basedir = control.basedir
    treeDB = control.treeDB

    eps = finfo(float).eps * 1e4

    # Add offshoots and remove parts with z<0:
    print('Adding offshoots (%i arterial and %i venous)...' % 
          (len(G['apv']), len(G['vpv'])))
    t0 = time.time()
    vcount = G.vcount()
    G.vs['apv']=[0]*G.vcount()
    G.vs['vpv']=[0]*G.vcount()
    for i in G['apv']:
        G.vs[i]['apv']=1
    for i in G['vpv']:
        G.vs[i]['vpv']=1

    x=[]
    y=[]
    for i in G.vs['r']:
        x.append(i[0])
        y.append(i[1])

    xMin=np.min(x)
    xMax=np.max(x)
    yMin=np.min(y)
    yMax=np.max(y)

    stdout.flush()
    print('CHECK DEGREE 1')
    print(max(G.degree()))

    #All deg1 vertices are in apv or vpv or they are in/outlets
    #add arterial penetratiing trees
    G.vs['degree'] = G.degree()
    print('Number of Components: Only pial')
    print(len(G.components()))
    print('Should be KEPT!')
    components=len(G.components())
    #extend_from_db(G, G['apv'], os.path.join(treeDB, 'arteryDB'))
    extend_from_db(G, G['apv'], os.path.join(treeDB, 'arteryDBmouse'))
    print('Number of Components: Artery trees added')
    print(len(G.components()))
    print('CHECK DEGREE 2')
    print(max(G.degree()))
    if len(G.components()) > components:
        print('ERROR')
        print('More components than expected')
    #Assign kind
    G.vs[range(vcount, G.vcount())]['kind'] = ['a' for v in xrange(vcount, G.vcount())]            
    G.vs['degree']=G.degree()
    vcount = G.vcount()
    #add venous penetrating trees
    #extend_from_db(G, G['vpv'], os.path.join(treeDB, 'veinDB'))
    extend_from_db(G, G['vpv'], os.path.join(treeDB, 'veinDBmouse'))
    print('Number of Components: Vein trees added')
    print(len(G.components()))
    print('CHECK DEGREE 3')
    print(max(G.degree()))
    if len(G.components()) > components:
        print('ERROR')
        print('More components than expected')
    #Assign kind
    G.vs[range(vcount, G.vcount())]['kind'] = ['v' for v in xrange(vcount, G.vcount())]           
    G.vs['degree']=G.degree()
    #adding trees lead to some new dead ends at the z=0 level, in contrast to the penetrating vessels their kind 
    #is either 'a' or 'v' but not 'pa' and not 'pv'
    #Remove capillaries (d < 7 mum) in pial vessels and penetrating vessels
    print(str(len(G.es(diameter_le=7)))+' Edges have a diameter which is smaller than 7mum and are therefor removed')
    G.delete_edges(G.es(diameter_le=7))
    G.vs['degree']=G.degree()
    print('Number of Components: Capillaries deleted')
    print(len(G.components())) 
    if len(G.components()) > components:
        print('ERROR')
        print('More components than expected')
        print(components)
        print(len(G.components()))
        for i in len(G.components()):
            print(len(G.components()[i]))
    #Remove vertices where z < 0 (would be abolve pial surface)
    G.vs['z'] = [r[2] for r in G.vs['r']]
    deleteList=G.vs(z_lt=0).indices
    print('Number of vertices where z<0')
    print(len(deleteList))
    deleteList.sort(reverse=True)
    for i in range(len(deleteList)):
        G.delete_vertices(deleteList[i])
    print('Number of components: z lt 0 deleted')
    print(len(G.components()))
    if len(G.components()) > components:
        print('ERROR')
        print('More components than expected')
    G.vs['degree']=G.degree()
    G.delete_vertices(G.vs(degree_eq=0))
    print('Number of components: degree 0 deleted')
    print(len(G.components()))
    if len(G.components()) > components:
        print('ERROR')
        print('More components than expected')
    #Delete len=0 edges
    G.es['length'] = [np.linalg.norm(G.vs[e.source]['r'] - G.vs[e.target]['r']) for e in G.es]
    G.delete_edges(G.es(length_eq=0).indices)
    print('...done. Time taken: %.1f min' % ((time.time()-t0)/60.))
    G.vs['degree']=G.degree()

    #Delete double Edges
    doubleVertices=[]
    print('CHECK for doule Edges (Edges connecting two similar vertices)')
    #TODO could be changed that only really similiar edges are deleted (see preprocessing SRCTM)
    for i in range(G.vcount()):
        if len(G.neighbors(i)) != len(np.unique(G.neighbors(i))):
            print('')
            print(G.neighbors(i))
            print(np.unique(G.neighbors(i)))
            doubleVertices.append(i)
    print('Number of possible double Edges')
    print(len(doubleVertices))
    
    while len(doubleVertices) > 0:
        for i in doubleVertices:
            neighbors=[]
            print('')
            print(G.neighbors(i))
            print(G.adjacent(i)) 
            adjacents=G.adjacent(i)
            for k,j in enumerate(G.neighbors(i)):
                print('')
                print(k)
                if j in neighbors:
                    G.delete_edges(adjacents[k])
                else:
                    neighbors.append(j)
        
        doubleVertices=[]
        print('len double vertices')
        for i in range(G.vcount()):
            if len(G.neighbors(i)) != len(np.unique(G.neighbors(i))):
                doubleVertices.append(i)
        print(len(doubleVertices))

    #Assign nkind to vertex
    for i in range(G.vcount()):
        if G.vs['kind'][i]=='pa':
            G.vs[i]['nkind']=0
        elif G.vs['kind'][i]=='a':
            G.vs[i]['nkind']=2
        elif G.vs['kind'][i]=='pv':
            G.vs[i]['nkind']=1
        elif G.vs['kind'][i]=='v':
            G.vs[i]['nkind']=3

    vgm.write_pkl(G, 'stage1.pkl')
    vgm.write_pkl(G, 'stage1.vtp')
    print('number of capillaries')
    print(len(G.vs(kind_eq='c')))

    if not zLim is None:
        if max(G.vs['z']) > zLim[1]:
            print('Deleting all vessels below z=%.1f' % (zLim[1]))
            t0 = time.time()
            G.delete_vertices(G.vs(z_gt=zLim[1]))
            print('...done. Time taken: %.1f min' % ((time.time()-t0)/60.))
            vgm.write_pkl(G, 'stage1b.pkl')

    stdout.flush()
    # Add capillary bed as honeycomb network:
    # Add volume and conductance before adding capillary grid
    print('Adding capillary grid...')
    #all vertices of the network containing the pial vessels and the
    numNCVertices = G.vcount()
    vcount=G.vcount()
    ecount=G.ecount()
    t0 = time.time()
    rMin = np.min(G.vs['r'], axis=0)
    rMax = np.max((np.max(G.vs['r'], axis=0), 
                   (np.max(gXtm.vs['r'], axis=0)-np.min(gXtm.vs['r'], axis=0))), axis=0)
    if not zLim is None:
        rMin[2] = zLim[0]
        rMax[2] = zLim[1]
    print(rMin)
    print(rMax)
    #honeycomb = capillary_bed.randomized_honeycomb(gXtm, (rMin[0], rMax[0]), (rMin[1], rMax[1]), (rMin[2], rMax[2]))
    honeycomb = capillary_bed.honeycomb((rMin[0], rMax[0]), (rMin[1], rMax[1]), (rMin[2], rMax[2]),60)
    print('CHECK DEGREE HONEYCOMB')
    print(max(honeycomb.degree()))
    print(honeycomb.es.attributes())
    print('Edges with 0 length in honeycomb')
    print(len(honeycomb.es(length_eq=0)))
    honeycomb.vs['degree']=honeycomb.degree()
    print('Degree 1 vertices in honeycomb')
    print(len(honeycomb.vs(degree_eq=1)))
    #Honeycomb network is moved such that it finishes at the same level as the pial+penetrating-network
    rMinHC= np.min(honeycomb.vs['r'], axis=0)
    offset=np.array([0.,0.,rMinHC[2]*(-1)])
    print('')
    print('Honeycomb Network is shifted in z-direction by')
    print(offset)
    print('such that zmin of Honeycomb Network = 0')
    vgm.shift(honeycomb,offset)
    print('number of capillaries')
    print(len(G.vs(kind_eq='c')))
    #honeycomb network and pial+penetrating network are put together
    G.disjoint_union_attribute_preserving(honeycomb, 'omit', False)
    print('number of capillaries')
    print(len(G.vs(kind_eq='c')))
    print(len(xrange(vcount, G.vcount())))
    G.vs[range(vcount, G.vcount())]['kind'] = ['c' for v in xrange(vcount, G.vcount())]
    G.vs[range(vcount, G.vcount())]['nkind'] = [5 for v in xrange(vcount, G.vcount())]
    G.vs['capGrid']=np.zeros(G.vcount())
    G.vs[range(vcount,G.vcount())]['capGrid'] = [1]*(G.vcount()-vcount)
    G.es['capGrid']=np.zeros(G.ecount())
    G.es[range(ecount,G.ecount())]['capGrid'] = [1]*(G.ecount()-ecount)
    print('number of capillaries')
    print(len(G.vs(kind_eq='c')))
    print('number of honeycomb vertices')
    print(honeycomb.vcount())
    vcount = G.vcount()
    print(G.es.attributes())
    print('Edges with length 0')
    print(len(G.es(length_eq=0)))
    #print('...done. Time taken: %.1f min' % ((time.time()-t0)/60.))
    vgm.write_pkl(G, 'stage2.pkl')
    stdout.flush()
    # Connect offshoots to capillary grid to penetrating vessels:
    print('Connecting offshoots to capillary grid...')
    print('number of edges where lenght = 0')
    print(len(G.es(length_eq=0)))
    t0 = time.time()
    G.vs['degree'] = G.degree()
    G.vs['z'] = [r[2] for r in G.vs['r']]
    #vertices with only one adjacent edge 
    #cv edges of penetrating trees with dead end --> to be connected to capillary bed
    cv = G.vs(z_ge=0.0, degree_eq=1,capGrid_eq=0).indices
    print('Number of pials and trees')
    print(numNCVertices)
    print('in cv vertices')
    print(max(cv))
    #In and outlet of pial vessels should be preserved
    for i in G['vv']:
        if i in cv:
            cv.remove(i)
        else:
            print(G.vs[i]['r'])
    for i in G['av']:
        if i in cv:
            cv.remove(i)
        else:
            print(G.vs[i]['r'])

    print(len(G.es(length_eq=0)))
    #Capillary bed should not be attached to pial vessels
    for i in cv:
        if G.vs[i]['kind'] == 'pa':
            print('ERROR')
        if G.vs[i]['kind'] == 'pv':
            print('ERROR')
    Kdt = kdtree.KDTree(honeycomb.vs['r'], leafsize=10)
    print('Dead Ends to connect')
    print(len(cv))
    stdout.flush()
    posConnections=[]
    G.vs['degree']=G.degree()
    print('Are there degree=0 vertices')
    print(len(G.vs(degree_eq=0)))
    #Compute possible Connections for vertices. Maximum degree = 4
    G.vs['posConnections']=[3]*G.vcount()
    deg4=G.vs(degree_ge=4).indices
    G.vs[deg4]['posConnections']=[0]*len(deg4)
    deg3=G.vs(degree_eq=3).indices
    G.vs[deg3]['posConnections']=[1]*len(deg3)
    deg2=G.vs(degree_eq=2).indices
    G.vs[deg2]['posConnections']=[2]*len(deg2)
    print('posConnections assigned')
    stdout.flush()
    print('Possible number of connections')
    posConnections=np.sum(G.vs[numNCVertices:G.vcount()-1]['posConnections'])
    print(posConnections)
    stdout.flush()
    #Start connection process
    for v in cv:
        diameter = G.es[G.adjacent(v)[0]]['diameter']
        newVertexFound=0
        count= 1
        while newVertexFound != 1:
            #start with 5 possible nearest neighbors
            nearestN=Kdt.query(G.vs[v]['r'],k=10*count)
            for i in range((count-1)*10,count*10):
                newVertex=int(nearestN[1][i])
                if G.vs['posConnections'][newVertex+numNCVertices]  == 0:
                    print('No connection possible')
                else:
                   G.vs[newVertex+numNCVertices]['posConnections'] = int(np.round(G.vs[newVertex+numNCVertices]['posConnections'] - 1))
                   newVertexFound = 1
                   break
            count += 1
        print('CONNECTION FOUND')
        print(v)
        stdout.flush()
        nn = newVertex
        #Distance between analyzed endppoint and closest point in honeycomb network
	#Maximum length is set to 5 mum, TODO why is this done? why is not the acrual length used?
        #length = min(5., np.linalg.norm(G.vs[v]['r'] - G.vs[numNCVertices + nn]['r']))
        length = np.linalg.norm(G.vs[v]['r'] - G.vs[numNCVertices + nn]['r'])
        #inewEdges.append((v, numNCVertices+nn))
	#add edge between the points
        G.add_edges((v, numNCVertices + nn))
        G.es[G.ecount()-1]['diameter'] = diameter
        G.es[G.ecount()-1]['length'] = length
    print('...done. Time taken: %.1f min' % ((time.time()-t0)/60.))
    G.vs['degree'] = G.degree()
    print('CHECK DEGREE 4')
    print(max(G.degree()))


    # Remove edges with length 0 and with degree 1:
    # Deg1 vertices of artificial capillary bed, should be located at the borders of the artificial capillary bed
    print('Number of edges where length is equal to 0')
    print(len(G.es(length_eq=0)))
    G.delete_edges(G.es(length_eq=0).indices)
    print('Number of degree 1 vertices')
    G.vs['degree']=G.degree()
    print(len(G.vs(degree_eq=1)))
    deg1=G.vs(degree_eq=1).indices
    G.vs['av']=[0]*G.vcount()
    G.vs['vv']=[0]*G.vcount()
    for i in G['av']:
        deg1.remove(i)
        G.vs[i]['av']=1
    for i in G['vv']:
        deg1.remove(i)
        G.vs[i]['vv']=1
    G.delete_vertices(deg1)
    G['av']=G.vs(av_eq=1).indices 
    G['vv']=G.vs(vv_eq=1).indices 
    print('Number of degree 1 vertices')
    G.vs['degree']=G.degree()
    print(len(G.vs(degree_eq=1)))
    deg1=G.vs(degree_eq=1).indices
    for i in G['av']:
        deg1.remove(i)
    for i in G['vv']:
        deg1.remove(i)
    G.delete_vertices(deg1)
    print('Number of degree 1 vertices')
    G.vs['degree']=G.degree()
    G['av']=G.vs(av_eq=1).indices 
    G['vv']=G.vs(vv_eq=1).indices 
    print('Number of degree 1 vertices')
    deg1=G.vs(degree_eq=1).indices
    print(len(G.vs(degree_eq=1)))
    for i in G['av']:
        deg1.remove(i)
    for i in G['vv']:
        deg1.remove(i)
    G.delete_vertices(deg1)
    print('Number of degree 1 vertices')
    G.vs['degree']=G.degree()
    G['av']=G.vs(av_eq=1).indices 
    G['vv']=G.vs(vv_eq=1).indices 
    print('Number of degree 1 vertices')
    deg1=G.vs(degree_eq=1).indices
    print(len(G.vs(degree_eq=1)))

    vgm.write_vtp(G, 'stage3.vtp', False)
    vgm.write_pkl(G, 'stage3.pkl')
    stdout.flush()

    # Set conductance of all vessels:
    print('Adding conductance...')
    t0 = time.time()
    aindices = G.vs(kind='pa').indices
    aindices.extend(G.vs(kind='a').indices)
    vindices = G.vs(kind='pv').indices
    vindices.extend(G.vs(kind='v').indices)
    cindices = G.vs(kind='c').indices
    vgm.add_conductance(G, 'a', invivo,edges=G.get_vertex_edges(aindices))
    vgm.add_conductance(G, 'v', invivo,edges=G.get_vertex_edges(vindices))
    vgm.add_conductance(G, 'a', invivo,edges=G.get_vertex_edges(cindices))
    print('...done. Time taken: %.1f min' % ((time.time()-t0)/60.))
    stdout.flush()

    # Insert srXTM sample at originXtm:
    print('Embedding SRXTM...')
    t0 = time.time()
    if insertXtm:
        G = implant_srxtm.implant_srxtm(G, gXtm, originXtm)    
    print('...done. Time taken: %.1f min' % ((time.time()-t0)/60.))
    G['av']=G.vs(av_eq=1).indices
    G['vv']=G.vs(vv_eq=1).indices
    vgm.write_vtp(G, 'stage4.vtp', False)
    vgm.write_pkl(G, 'stage4.pkl')
    print('stage4 written')
    stdout.flush()
    
    # Delete obsolete graph properties:
    for vProperty in ['z', 'degree', 'nkind', 'epID', 'maxD']:
        if vProperty in G.vs.attribute_names():
            del G.vs[vProperty]
    for eProperty in ['diameter_orig', 'diameter_change', 'cost','depth']:
        if eProperty in G.es.attribute_names():
            del G.es[eProperty]
    for gPropery in ['attachmentVertex', 'sampleName', 'distanceToBorder',
                     'avZOffset']:
        if gPropery in G.attributes():
            del G[gPropery]
    
    # Add a numerical version of vessel kind to facilitate paraview display:
    nkind = {'pa':0, 'pv':1, 'a':2, 'v':3, 'c':4, 'n':5}
    for v in G.vs:
        v['nkind'] = nkind[v['kind']]
    G.vs['degree']=G.degree()
    print('CHECK DEGREE 7')
    print(max(G.vs['degree']))

    #1. If effective Diameter exists it is assigned as diameter
    if 'effDiam' in G.es.attribute_names():
        diamEff=G.es(effDiam_ne=None).indices
        print('effective diameter available')
        print(len(diamEff))
        for i in diamEff:
            G.es[i]['diameter']=G.es[i]['effDiam']

    #2. check if there are degree 0 vertices 
    G.vs['degree']=G.degree()
    deg0=G.vs(degree_eq=0).indices
    print('Degree 0 vertices?')
    print(len(deg0))
    G.delete_vertices(deg0)
    G.vs['degree']=G.degree()

    #Reassign av and vv and apv and vpv
    G['av']=G.vs(av_eq=1).indices
    G['vv']=G.vs(vv_eq=1).indices
    G['apv']=G.vs(apv_eq=1).indices
    G['vpv']=G.vs(vpv_eq=1).indices

    #Eliminate small diameters in capGrid
    diam0capGrid=G.es(diameter_lt=1.0,capGrid_eq=1.).indices
    G.es[diam0capGrid]['diameter']=[1]*len(diam0capGrid)

    #Recheck smalles diameter
    diam0=G.es(diameter_lt=1.0).indices
    if len(diam0) > 0:
        print('ERROR no small diameters should exist')

    #Recheck for loops at deadEnd vertices
    print('check for loops')
    G.es['length2'] = [np.linalg.norm(G.vs[e.source]['r'] -G.vs[e.target]['r']) for e in G.es]
    len0=G.es(length2_eq=0).indices
    print('Len0 Edges are deleted')
    print(len(len0))
    G['infoDeadEndLoops']=len(len0)
    for i in len0:
        e=G.es[i]
        if e.tuple[0] != e.tuple[1]:
            print('WARNING')
    
    G.delete_edges(len0)
    G.vs['degree']=G.degree()
    del(G.es['length2'])

    #Delete new deg1s
    print('Deleting the loops can lead to more degree 1 vertices')
    G.vs['degree']=G.degree()
    deg1=G.vs(degree_eq=1).indices
    print(len(deg1))
    while len(deg1) > len(G['av'])+len(G['vv']):
        print('')
        print(len(deg1))
        av=G.vs(av_eq=1).indices
        vv=G.vs(vv_eq=1).indices
        for i in av:
            if i in deg1:
                deg1.remove(i)
        print(len(deg1))
        for i in vv:
            if i in deg1:
                deg1.remove(i)
        print(len(deg1))
        G.delete_vertices(deg1)
        G.vs['degree']=G.degree()
        deg1=G.vs(degree_eq=1).indices
        stdout.flush()
    
    print('All newly created Dead Ends have ben elimanted')
    G.vs['degree']=G.degree()
    print(len(G.vs(degree_eq=1)))


    #Recheck the degrees of the graph
    G.vs['degree']=G.degree()
    deg1=G.vs(degree_eq=1).indices
    print('Degree 1 vertices')
    print(len(deg1))
    for i in deg1:
        if i not in G['av'] and i not in G['vv']:
            print('ERROR deg1 vertex not in av and neither in vv')

    #Recheck max and min degree
    print('min degree')
    print(min(G.degree()))
    if min(G.degree()) < 1:
        print('ERROR in min degree')
    if np.max(G.vs['degree']) > 4:
        print('ERROR in Maximum degree')
        print(np.max(G.vs['degree']))

    #Reassign av and vv and apv and vpv
    G['av']=G.vs(av_eq=1).indices
    G['vv']=G.vs(vv_eq=1).indices
    G['apv']=G.vs(apv_eq=1).indices
    G['vpv']=G.vs(vpv_eq=1).indices

    # 6. Diameter Srxtm vessels is adjusted such, that at least one RBC fits in
    #    every vessel
    if 'isSrxtm' in G.es.attribute_names():
        P=vgm.Physiology()
        vrbc=P.rbc_volume('mouse')
        G.es['minDist'] = [vrbc / (np.pi * e['diameter']**2 / 4) for e in G.es]
        maxMinDist=max(G.es['minDist'])
        countDiamChanged=0
        diamNew=[]
        edge=[]
        probEdges=G.es(length_lt=1*maxMinDist,isSrxtm_eq=1).indices
        count=0
        for i in probEdges:
            if 1*G.es['minDist'][i] > G.es['length'][i]:
                G.es[i]['diameter']=np.ceil(100*np.sqrt(4*2*vrbc/(np.pi*G.es['length'][i])))/100.
                countDiamChanged += 1
                diamNew.append(np.ceil(100*np.sqrt(4*2*vrbc/(np.pi*G.es['length'][i])))/100.)
                edge.append(i)
            count += 1
    
        print('vessel volume has been increased in')
        print(countDiamChanged)
        G.es['minDist'] = [vrbc / (np.pi * e['diameter']**2 / 4) for e in G.es]
        stdout.flush()
    
    # 7. Length is added to edges which do not have a length yet
    noLength=G.es(length_eq=None).indices
    print('Edges with no length')
    print(len(noLength))
    for i in noLength:
       e=G.es[i]
       G.es[i]['length']=np.linalg.norm(G.vs[e.source]['r']-G.vs[e.target]['r'])
    
    noLength=G.es(length_eq=None).indices
    print('Edges with no length')
    print(len(noLength))

    # 3. Assign pressure BCs
    print('Assign pressure BCs')
    for i in G['av']:
        G.vs[i]['pBC']=BC[0]
        print(G.vs[i]['pBC'])
    
    for i in G['vv']:
        G.vs[i]['pBC']=BC[1]
        print(G.vs[i]['pBC'])
    
    print('Pressure BCs assigned')

    # 4. Assign tube hematocrit boundary conditions
    print('assign inlet tube hematocrits')
    for i in G['av']:
        G.es[G.adjacent(i)[0]]['httBC']=BC[2]

    #Recheck BCs (pBC,rBC, httBC)
    for i in G['av']:
        print('')
        print(G.vs['pBC'][i])
        print(G.vs['rBC'][i])
        print(G.es[G.adjacent(i)]['httBC'])
        if G.vs['pBC'][i] == None and G.vs['rBC'][i] == None:
            print('ERROR in av boundary condition')
        if G.es[G.adjacent(i)]['httBC'] == None:
            print('ERROR in av boundary condition: httBC')
    
    for i in G['vv']:
        print('')
        print(G.vs['pBC'][i])
        print(G.vs['rBC'][i])
        if G.vs['pBC'][i] == None and G.vs['rBC'][i] == None:
            print('ERROR in vv boundary condition')
    
    stdout.flush()

    vgm.write_pkl(G, 'stage5.pkl')
    stdout.flush()
    return G
Ejemplo n.º 3
0
def prepare_for_concatenating_the_compound_NW(Ga,Gd):
        """ 1. The edge attribute 'eBlock' labels all non-capillary vessels. Hence, all
        vessels with eBlock=1 should be either arterioles (medianLabelAV=3) or venules 
        (medianLabelAV=4). The medianLabelAV label is adjusted based on neighboring edges.
        2. There might also be As and Vs which do not have an eBlock Label. 
        Their medianLabelAV will be changed to 1 (=capillaries)

        INPUT: G: Vascular graph in iGraph format.
        OUTPUT: updatedProperties eBlock and medianLabelAV
        """

        #1.Shift the realistic network, such that the centers of the NW overlap
        #2.Delete all capillaries of the artificial network which are found in the implantation region
        #3. 
        xMinCut=Gd['xMinCut']
        xMaxCut=Gd['xMaxCut']
        yMinCut=Gd['yMinCut']
        yMaxCut=Gd['yMaxCut']
        zMaxCut=Gd['zMaxCut']
        centerGd=Gd['center']
        print('shift realistic network by')
        origin = np.mean(Ga.vs['r'], axis=0)[:2]
        shift = (np.append(origin,0.)-np.append(centerGd,Gd['zMeanPial'])).tolist()
        print(shift)
        vgm.shift(Gd, shift)
        Ga.vs['z'] = [r[2] for r in Ga.vs['r']]
        Ga.vs['x'] = [r[0] for r in Ga.vs['r']]
        Ga.vs['y'] = [r[1] for r in Ga.vs['r']]
        xMinCutGa=xMinCut + shift[0]
        xMaxCutGa=xMaxCut + shift[0]
        yMinCutGa=yMinCut + shift[1]
        yMaxCutGa=yMaxCut + shift[1]
        zMaxCutGa=zMaxCut + shift[2]
        centerGa=[centerGd[0]+shift[0],centerGd[1]+shift[1]]
        Ga['xMinCut']=xMinCutGa
        Ga['xMaxCut']=xMaxCutGa
        Ga['yMinCut']=yMinCutGa
        Ga['yMaxCut']=yMaxCutGa
        Ga['zMaxCut']=zMaxCutGa
        Ga['center']=centerGa

        #First all capillary vertices lying in the center of ther artificial network ar deleted
        delVerts=Ga.vs(x_gt=xMinCutGa,x_lt=xMaxCutGa,y_gt=yMinCutGa,y_lt=yMaxCutGa,z_lt=zMaxCutGa,nkind_eq=4).indices
        Ga.delete_vertices(delVerts)

        #Now all artificial penetrating trees and artificial venules are deleted if their root point is lying
        #in the area of the implantation including points of the penetrting trees 
        #lying outside the implantation regio
        #Arteriol roots
        delVertsPA=Ga.vs(x_gt=xMinCutGa,x_lt=xMaxCutGa,y_gt=yMinCutGa,y_lt=yMaxCutGa,z_lt=zMaxCutGa,av_eq=1).indices
        delVertsWholeTree=[]
        doneVerts=[]
        for i in delVertsPA:
            treeVertices2=[i]
            while treeVertices2 != []: 
                treeVertices=[]
                for j in treeVertices2:
                    neighbors=Ga.neighbors(j)
                    for k in neighbors:
                        if Ga.vs[k]['nkind'] == 2 and k not in doneVerts:
                            treeVertices.append(k)
                            delVertsWholeTree.append(k)
                    doneVerts.append(j)
                treeVertices2=deepcopy(treeVertices)
            delVertsWholeTree.append(i)

        #Venule roots
        delVertsPA=Ga.vs(x_gt=xMinCutGa,x_lt=xMaxCutGa,y_gt=yMinCutGa,y_lt=yMaxCutGa,z_lt=zMaxCutGa,vv_eq=1).indices
        delVertsWholeTree=[]
        doneVerts=[]
        for i in delVertsPA:
            treeVertices2=[i]
            while treeVertices2 != []:
                treeVertices=[]
                for j in treeVertices2:
                    neighbors=Ga.neighbors(j)
                    for k in neighbors:
                        if Ga.vs[k]['nkind'] == 3 and k not in doneVerts:
                            treeVertices.append(k)
                            delVertsWholeTree.append(k)
                    doneVerts.append(j)
                treeVertices2=deepcopy(treeVertices)
            delVertsWholeTree.append(i)

        #Eliminate remaining a and v vessels at implant location
        delVertsPA=Ga.vs(x_gt=xMinCutGa,x_lt=xMaxCutGa,y_gt=yMinCutGa,y_lt=yMaxCutGa,z_lt=zMaxCutGa,nkind_eq=2).indices
        Ga.delete_vertices(delVertsPA)

        delVertsPV=Ga.vs(x_gt=xMinCutGa,x_lt=xMaxCutGa,y_gt=yMinCutGa,y_lt=yMaxCutGa,z_lt=zMaxCutGa,nkind_eq=3).indices
        Ga.delete_vertices(delVertsPV)

        #delete unconnected components
        while (len(Ga.components())) > 1:
            delVerts=Ga.components()[len(Ga.components())-1]
            Ga.delete_vertices(delVerts)

        return Ga,Gd
Ejemplo n.º 4
0
def implant_srxtm(Ga, Gd, origin=None, crWidth=150):
    """Implants a cylindrical srXTM sample in an artificial vascular network
    consisting of pial vessels, arterioles, venoles and capillaries. At the 
    site of insertion, artificial vessels are removed to make space for the 
    srXTM sample. At the border between artificial and data networks,
    connections are made between the respective loose ends.
    INPUT: Ga: VascularGraph of the artificial vasculature.
           Gd: VascularGraph of the srXTM data. The graph is expected to have
               the attributes 'av' and 'vv' that denote the indices of 
               endpoints of the large penetrating arteries and veins 
               respectively.
           origin: The two-dimensional origin in the xy plane, where the srXTM
                   sample should be inserted. This will be the network's 
                   center of mass, if not provided.
           crWidth: Width of connection region. After computing the center and
                    radius of the SRXTM sample, loose ends of the SRXTM at
                    radius - 2*crWidth are connected to loose ends of the
                    artificial network at radius + 2*crWidth.
    OUTPUT: Ga: Modified input Ga, with Gd inserted at origin.       
    """
    
    # Create Physiology object with appropriate default units:
    P = vgm.Physiology(Ga['defaultUnits'])
    eps = finfo(float).eps * 1e4

    # Define exceptions:
    class ShapeException(Exception):
        def __init__(self):
            return
        def __str__(self):
            return 'The shape of the srXTM sample must be cylindrical!'
            
    # Assert that the srXTM sample is cylindrical:        
    if Gd.shape() != 'cylinder':
        raise ShapeException            

    # Compute the network's center of mass as origin, if origin is not provided:
    if origin is None:
        origin = np.mean(Ga.vs['r'], axis=0)[:2]
    print('origin')
    print(origin)
    print('Original number of components')
    print(len(Ga.components()))
    stdout.flush()
    print('Kind Check')
    print(np.unique(Ga.vs['kind']))

    # Remove all vertices of Ga which are within Gd's radius of 'origin' and
    # at a depth less than the maximum depth of Gd. Leave the pial vessels
    # of Ga untouched:
    Ga.vs['distanceFromOrigin'] = [np.linalg.norm(r[:2] - origin) for r in Ga.vs['r']]
    Ga.vs['isPial'] = [0 if k not in ['pa', 'pv'] else 1 for k in Ga.vs['kind']]
    Ga.vs['z'] = [r[2] for r in Ga.vs['r']]
    radius, center = Gd.radius_and_center()
    area, length = Gd.cross_sectional_area_and_length(shape='cylinder')
    Ga.delete_vertices(Ga.vs(distanceFromOrigin_le=radius, z_le=length, isPial_eq=0))
    print('Kind Check 1 1')
    print(np.unique(Ga.vs['kind']))
    print('Center deleted')

    # Remove all non-capillaries that have lost their root:
    Ga.vs['degree'] = Ga.degree()
    #pial endpoints are located at the pial level in the area, where the realistic network is implanted
    pialEndpoints = [v.index for v in Ga.vs(degree_eq=1) if v['kind'] in ['pa', 'pv']]
    if len(pialEndpoints) > 0:
        print('pialEndpoints')
        print(pialEndpoints)
        print(len(pialEndpoints))
        Gc = copy.deepcopy(Ga)
        Gc.vs['index'] = xrange(Gc.vcount())
        del(Gc.vs['degree'])
        del(Gc.vs['distanceFromOrigin'])
        del(Gc.vs['nkind'])
        del(Gc.vs['pBC'])
        del(Gc.vs['z'])
        del(Gc.vs['isPial'])
        del(Gc.es['diameter'])
        del(Gc.es['diameter_orig'])
        del(Gc.es['diameters'])
        del(Gc.es['lengths'])
        del(Gc.es['diameter_change'])
        del(Gc.es['conductance'])
        del(Gc.es['length'])
        del(Gc.es['cost'])
        del(Gc.es['points'])
        #Gc consists of pial vessels and penetrating trees
        Gc.delete_vertices(Gc.vs(kind_eq='c').indices)
        print('Capillaries deleted')
        print('Number of components')
        print(len(Gc.components()))
        del(Gc.vs['kind'])
        #add random vertex 
        Gc.add_vertices(1)
        Gc.vs[Gc.vcount()-1]['index']=100000000000000
        Gc.vs[Gc.vcount()-1]['r']=[-500.,-500.,0.]
        pialEndpoints2 = []
        #pialEndpoints2 = pialEndpoints in Gc graph
        for i in pialEndpoints:
           pialEndpoints2.append(Gc.vs(index_eq=i).indices[0])
        #connect all pial endpoints (=in and outflows at pial level and deg1 pial vertices resulting from hole at implant position) to that random vertices
        Gc.add_edges([(v, Gc.vcount()-1) for v in pialEndpoints2])
        print('Number of components 2 --> unconnected penetrating trees')
        print(len(Gc.components()))
        #deletes connected component
        print('Kind Check 1 2')
        print(np.unique(Ga.vs['kind']))
        Gc.delete_vertices(Gc.subcomponent(Gc.vcount()-1))
        Ga.delete_vertices(Gc.vs['index'])
        #unconnected capillaries still present, but no more unconnected penetrating trees
    else:
        print('Reduce components')
        print(len(Ga.components()))
        while len(Ga.components()) > 1:
            delVertices=Ga.components()[len(Ga.components())-1]
            print(len(delVertices))
            Ga.delete_vertices(Ga.components()[len(Ga.components())-1])
            print('number of components')
            print(len(Ga.components()))
    print('Kind Check 1 3')
    print(np.unique(Ga.vs['kind']))

    #Delete unconnected capillaries
    print('Number of components 3')
    print(len(Ga.components()))
    components=Ga.components()
    delVertices=[]
    stdout.flush()
    for i in range(1,len(components)):
        delVertices = delVertices + components[i]
    if len(delVertices) > len(components[0]):
        print('ERROR --> main component deleted')
    Ga.delete_vertices(delVertices)
    print('Number of components 4')
    print(len(Ga.components()))
    
    # Insert Gd into Ga (insert realistic network into artificial network):
    print('CHECK DEGREE SRXTM')
    print(max(Gd.degree()))
    origin = np.append(origin, 0.)
    center = np.append(center, min([r[2] for r in Gd.vs['r']]))
    shift = (origin-center).tolist()
    print('shift realistic networ by')
    print(shift)
    vgm.shift(Gd, shift)
    print('Components gXTM')
    print(len(Gd.components()))
    print('Components trees and capillaries')
    print(len(Ga.components()))
    initialVcount = Ga.vcount()    
    initialEcount = Ga.ecount()
    Ga.union_attribute_preserving(Gd)
    print('Put together')
    print(len(Ga.components()))
    Ga.vs['isSrxtm'] = [0 if x < initialVcount else 1 for x in xrange(Ga.vcount())] # artificial network: 0, srXTM: 1
    Ga.es['isSrxtm'] = [0 if x < initialEcount else 1 for x in xrange(Ga.ecount())] # artificial network: 0, srXTM: 1
    stdout.flush()

    # Connect loose ends of Gd (srXTM to artificial capillary bed):
    # only dead ends in a given radius are connected
    origin = origin[:2]
    Ga.vs(isSrxtm_eq=1)['distanceFromOrigin'] = [np.linalg.norm(r[:2] - origin) for r in Ga.vs(isSrxtm_eq=1)['r']]
    #All capillary vertices which are at max 2.0*radius away from the center of the srXTM
    #possible capillary attachment vertices
    capillaryVertices = Ga.vs(isSrxtm_eq=0, distanceFromOrigin_le=radius*2.0, kind_eq='c', degree_le=3)
    Kdt = kdtree.KDTree(capillaryVertices['r'], leafsize=10)
    #all srxtm vertices in radius
    print('Connect Implant to capillary bed')
    looseEndsI = Ga.vs(distanceFromOrigin_le=radius+2*crWidth, distanceFromOrigin_ge=radius-2*crWidth, 
                       degree_eq=1, isSrxtm_eq=1).indices # srxtm capillaries and non-capillaries
    print('Remove av and vv of Srxtm from the looseEndsI list')
    print(len(looseEndsI))
    for i in Gd['av']:
        vIndex = int(np.nonzero(np.all(Gd.vs[i]['r'] == Ga.vs['r'], axis=1))[0][0])
        if vIndex in looseEndsI:
            looseEndsI.remove(vIndex)
    print(len(looseEndsI))
    for i in Gd['vv']:
        vIndex = int(np.nonzero(np.all(Gd.vs[i]['r'] == Ga.vs['r'], axis=1))[0][0])
        if vIndex in looseEndsI:
            looseEndsI.remove(vIndex)
    print(len(looseEndsI))
    print('Non capillaries artificial network')
    looseEndsI_2=Ga.vs(distanceFromOrigin_le=radius+2*crWidth, distanceFromOrigin_ge=radius-2*crWidth, 
                      degree_eq=1, isSrxtm_eq=0, kind_ne='c').indices # artificial network non-capillaries
    print(len(looseEndsI_2))
    dummy1=Ga.vs(distanceFromOrigin_le=radius+2*crWidth, distanceFromOrigin_ge=radius-2*crWidth, 
                      degree_eq=1, isSrxtm_eq=0, kind_eq='pa').indices
    dummy2=Ga.vs(distanceFromOrigin_le=radius+2*crWidth, distanceFromOrigin_ge=radius-2*crWidth, 
                      degree_eq=1, isSrxtm_eq=0, kind_eq='pv').indices
    print('Remove dummy1 (pa) from loosEndsI_2')
    print(len(looseEndsI_2))
    print(len(dummy1))
    print('Kind Check 3')
    print(np.unique(Ga.vs['kind']))
    for i in dummy1:
        if i in looseEndsI_2:
            looseEndsI_2.remove(i)
    print(len(looseEndsI_2))
    print('Remove dummy2 (pv) from loosEndsI_2')
    for i in dummy2:
        if i in looseEndsI_2:
            looseEndsI_2.remove(i)
    print(len(dummy2))
    print(len(looseEndsI_2))
    print('Exten looseEndsI')
    print(len(looseEndsI))
    looseEndsI.extend(looseEndsI_2)
    print(len(looseEndsI))
    print('Check loosEnds 2')
    looseEndesII=Ga.vs(distanceFromOrigin_le=radius+2*crWidth, distanceFromOrigin_ge=radius-2*crWidth,
                      degree_eq=1, isSrxtm_eq=0, kind_ne='c').indices
    for i in looseEndesII:
        print(Ga.vs[i]['kind'])
    print('len(looseEndsI)')
    print(len(looseEndsI))
    print('Degree one artificial')
    Ga.vs['degree']=Ga.degree()
    print(len(Ga.vs(isSrxtm_eq=0, distanceFromOrigin_le=radius*2.0, kind_eq='c',degree_le=3)))
    posConnections=[]
    for i in Ga.vs['degree']:
        if i >= 3:
            posConnections.append(0)
        elif i == 3:
            posConnections.append(1)
        elif i == 2:
            posConnections.append(2)
        else:
            posConnections.append(3)
    Ga.vs['posConnections']=posConnections
    posConnections=np.sum(Ga.vs[Ga.vs(isSrxtm_eq=0, distanceFromOrigin_le=radius*2.0, kind_eq='c', degree_le=3).indices]['posConnections'])
    print('Possible Connections')
    print(posConnections)
    looseEnds = Ga.vs(looseEndsI)
    newEdges = []
    vertex_withSrxtm=[]
    stdout.flush()
    print('Kind Check 4')
    print(np.unique(Ga.vs['kind']))
    for le in looseEnds:
        print('')
        print(le.index)
        stdout.flush()
        newVertexFound=0
        count= 1
        while newVertexFound != 1:
            #start with 5 possible nearest neighbors
            if count*5 > len(capillaryVertices):
                print('WARNING last chance to find a connecting vertex')
                print(count*5)
            nearestN=Kdt.query(le['r'],k=5*count)
            for i in range((count-1)*5,count*5):
                newVertex=capillaryVertices[int(nearestN[1][i])].index
            #newVertex=capillaryVertices[int(Kdt.query(le['r'])[1])].index
                if Ga.vs['posConnections'][newVertex]  == 0:
                    print('No connection possible')
                else:
                   Ga.vs[newVertex]['posConnections'] = Ga.vs[newVertex]['posConnections'] - 1
                   newVertexFound = 1
                   break
            count += 1
        print('CONNECTION FOUND')
        print(le.index)
        newEdges.append((le.index, newVertex))
        vertex_withSrxtm.append(le.index)
    Ga.add_edges(newEdges)
    Ga.vs['degree']=Ga.degree()
    print('CHECK DEGREE 5')
    print(max(Ga.degree()))
    #TODO think of fixed diameter and fixed length
    diameter = 7.
    length = 50.
    conductance = P.conductance(diameter, length, P.dynamic_blood_viscosity(diameter, 'a'))
    Ga.es[-len(newEdges):]['diameter'] = [diameter for e in newEdges]
    Ga.es[-len(newEdges):]['conductance'] = [conductance for e in newEdges]
    Ga.es['newEdge'] = [0 if x < Ga.ecount()-len(newEdges) else 1 for x in xrange(Ga.ecount())]
    print('Kind Check 4')
    print(np.unique(Ga.vs['kind']))
    # Connect endpoints of large penetrating vessels to pial vessels:
    #'av' - arterial inflows, 'pv' -venule outflow
    print('Standard Network av')
    print(Ga['av'])
    print(len(Ga['av']))
    print('Standard Network vv')
    print(Ga['vv'])
    print(len(Ga['vv']))
    print('Implant Network av')
    print(Gd['av'])
    print(len(Gd['av']))
    print('Implant Network vv')
    print(Gd['vv'])
    print(len(Gd['av']))
    print(zip((Gd['av'], Gd['vv']), ('pa', 'pv')))
    Ga['vWithSRXTM']=vertex_withSrxtm
    posConnections=[]
    stdout.flush()
    for i in Ga.vs['degree']:
        if i > 2:
            posConnections.append(0)
        elif i == 2:
            posConnections.append(1)
        else:
            posConnections.append(2)
    Ga.vs['posConnections']=posConnections
    print(np.unique(Ga.vs['kind']))
    for avv, pk in zip((Gd['av'], Gd['vv']), ('pa', 'pv')):
        print('CHECK')
        print(len(avv))
        print(pk)
	#alle pial vessels (either arteries or venules)
        pialIndices = Ga.vs(kind_eq=pk).indices
        print(pialIndices)
        #KDTree of all pial vessels (either arteries or venules) of main graph
        Kdt = kdtree.KDTree(Ga.vs(pialIndices)['r'], leafsize=10)
        newEdges = []
        length = []
        diameter = []
        conductance = []
        srxtmAV = []
        vs=[]
        degree0=[]
        for v in avv:
            #to find the vertex number in the new graph
            vIndex = int(np.nonzero(np.all(Gd.vs[v]['r'] == Ga.vs['r'], axis=1))[0][0])
            #corresponding vertexNumber of Inflow/Outflow vertices of srxtm 
            srxtmAV.append(vIndex)
            degree0.append(Ga.vs[vIndex]['degree'])
            vs.append(v)
	    #Closes vertex of pial vertices
            newVertexFound = 0
            count = 1
            while newVertexFound != 1:
                #pIndex = pialIndices[int(Kdt.query(Ga.vs[vIndex]['r'])[1])]
                nearestN = Kdt.query(Ga.vs[vIndex]['r'],k=5*count)
                for i in range((count-1)*5,count*5):
                    pIndex=pialIndices[int(nearestN[1][i])]
                    if Ga.vs['posConnections'][pIndex]  == 0 or pIndex in vertex_withSrxtm:
                        print('No connection possible')
                    else:
                       print('posConnections')
                       print(Ga.vs['posConnections'][pIndex])
                       Ga.vs[pIndex]['posConnections'] = Ga.vs[pIndex]['posConnections'] - 1
                       newVertexFound = 1
                       print(Ga.vs['posConnections'][pIndex])
                       break
                count += 1
            print('CONNECTION FOUND')
            print(v)
            newEdges.append((vIndex, pIndex))
            length.append(np.linalg.norm(Ga.vs[vIndex]['r'] - Ga.vs[pIndex]['r']))
            #diameter is set to the maximum diameter of the adjacent edges of the pial vertex
            diameter.append(max(Ga.es[Ga.adjacent(pIndex)]['diameter']))
            conductance.append(P.conductance(diameter[-1], length[-1], P.dynamic_blood_viscosity(diameter[-1], pk[1])))

        #inflow/outflow vertices of srxtm
        Ga['srxtm_' + pk[1]] = srxtmAV
        Ga.add_edges(newEdges)
        Ga.vs['degree']=Ga.degree()
        Ga.es[-len(newEdges):]['diameter'] = diameter
        Ga.es[-len(newEdges):]['conductance'] = conductance
	#newly introduced edges a/v
        Ga.es['newEdge_'+pk] = [0 if x < Ga.ecount()-len(newEdges) else 1 for x in xrange(Ga.ecount())]

    noneEdges=Ga.es(newEdge_pa_eq=None).indices
    Ga.es[noneEdges]['newEdge_pa']=[0]*len(noneEdges)
    Ga.vs['srxtm_a']=[0]*Ga.vcount()
    Ga.vs['srxtm_v']=[0]*Ga.vcount()
    for i in Ga['srxtm_a']:
        Ga.vs[i]['srxtm_a']=1
    for i in Ga['srxtm_v']:
        Ga.vs[i]['srxtm_v']=1
    del(Ga['srxtm_a'])
    del(Ga['srxtm_v'])

    Ga.vs['degree']=Ga.degree()
    print('CHECK DEGREE 6')
    print(max(Ga.degree()))

    # Remove Dead Ends
    # Dead Ends around the implant
    print('Delete dead ends around implant')
    deg1=Ga.vs(degree_eq=1,distanceFromOrigin_gt=radius+2*crWidth,distanceFromOrigin_lt=radius-2*crWidth,isSrxtm_eq=1).indices
    for i in deg1:
        if Ga.vs[i]['av'] == 1.0:
            deg1.remove(i)
        elif Ga.vs[i]['vv'] == 1.0:
            deg1.remove(i)

    print('avs and vvs')
    print(len(Ga.vs(av_eq=1)))
    print(len(Ga.vs(vv_eq=1)))

    while len(deg1) > 0:
        print('')
        print(len(deg1))
        Ga.delete_vertices(deg1)
        Ga.vs['degree']=Ga.degree()
        print('avs and vvs')
        print(len(Ga.vs(av_eq=1)))
        print(len(Ga.vs(vv_eq=1)))
        deg1=Ga.vs(degree_eq=1,distanceFromOrigin_gt=radius+2*crWidth,distanceFromOrigin_lt=radius-2*crWidth,isSrxtm_eq=1).indices
        for i in deg1:
            if Ga.vs[i]['av'] == 1.0:
                deg1.remove(i)
            elif Ga.vs[i]['vv'] == 1.0:
                deg1.remove(i)

    # Delete obsolete vertex properties:    
    del Ga.vs['degree']        
    stdout.flush()

    #Delte av and vv of SRXTM
    av=Ga.vs(av_eq=1).indices
    print('len av')
    print(len(av))
    for i in av:
        if Ga.vs['isSrxtm'][i]:
            Ga.vs[i]['av']=0

    av=Ga.vs(av_eq=1).indices
    print('len av')
    print(len(av))
    Ga['av']=av
    vv=Ga.vs(vv_eq=1).indices
    print('len vv')
    print(len(vv))
    for i in vv:
        if Ga.vs['isSrxtm'][i]:
            Ga.vs[i]['vv']=0

    vv=Ga.vs(vv_eq=1).indices
    print('len vv')
    print(len(vv))
    Ga['vv']=vv

    #There might be deadEnd Vertices of the artificial capillary bed where the SRXTM was implemented
    #Those vertices are delted
    #First assign capGrid = 0 to SRXTM
    capGridNone=Ga.vs(capGrid_eq=None).indices
    Ga.vs[capGridNone]['capGrid']=[0]*len(capGridNone)
    Ga.vs['degree'] = Ga.degree()
    print('Check if deg1 are only located at in- and outlet and at borders of capillary grid')
    deg1=Ga.vs(degree_eq=1).indices
    print(len(deg1))
    for i in deg1:
        if Ga.vs[i]['capGrid']  == 0:
            if Ga.vs['av'] == 0 and Ga.vs['vv'] == 0:
                print('ERROR')
                print(i)
                print(Ga.vs[i]['isSrxtm'])
                print(Ga.vs[i]['capGrid'])

    while len(deg1) > len(Ga['av'])+len(Ga['vv']):
        print('')
        print(len(deg1))
        av=Ga.vs(av_eq=1).indices
        vv=Ga.vs(vv_eq=1).indices
        for i in av:
            if i in deg1:
                deg1.remove(i)
        print(len(deg1))
        for i in vv:
            if i in deg1:
                deg1.remove(i)
        print(len(deg1))
        Ga.delete_vertices(deg1)
        Ga.vs['degree']=Ga.degree()
        deg1=Ga.vs(degree_eq=1).indices

    del Ga.vs['distanceFromOrigin']
    print('All newly created Dead Ends have ben elimanted')
    Ga.vs['degree']=Ga.degree()
    Ga['av']=Ga.vs(av_eq=1).indices
    Ga['vv']=Ga.vs(vv_eq=1).indices
    print(len(Ga.vs(degree_eq=1)))
    print(len(Ga['av']))
    print(len(Ga['vv']))
    stdout.flush()

    return Ga