Beispiel #1
0
    def add_network_from_matrix(self, name, matrix, like_network = None, metadata = None, \
                                directed = False, hierarchical = False, hypergraph = False):
        """ Add a network to the cfile based on the given connectivity matrix and
        an already existing other network with node and surface container information.
        
        Parameters
        ----------
        name : String
            Name of the newly added network
        matrix : NxN array
            A NxN Numpy array with the values for the edges. N must be the same
            as len(like_network.graph.nodes()). The first row of the matrix
            corresponds to the `NetworkX` node with id 'n1'
        like_network : `INetwork` object, optional
            Used to copy graph node information and surface containers
        metadata : Dict, optional
            A dictionary of metadata
        directed : bool, optional
            Is the network directed?
        hierarchical : bool, optional
            Is the network hierarchical? (default: '0') Not implemented yet.
        hypergraph : bool, optional
            Is the network a hypergraph? (default: '0') Not implemented yet.
            
        Returns
        -------
        networkid : int
            The index in the list of networks in the cfile
            
        Note
        ----
        If you use this function only with name and matrix, a spring-force layout
        algorithm is applied to define the node positions. This may take some time.
        You can also use the `add_network_from_matrix_pos` and define the
        node positions by yourself.
        
        """
        from cviewer.plugins.cff.network import Network
        
        create_graph_info = False
        
        if like_network is None:
            create_graph_info = True
        else:
            # matrix has N rows and columns which is equal to the number of nodes
            assert matrix.shape[0] == matrix.shape[1] == len(like_network.graph.nodes())

        # add graph 
        import networkx as nx
        test_G = nx.from_numpy_matrix(matrix)
        
        # relabeling function
        addn = lambda nmod:'n'+str(nmod+1)
        
        # relabel graph
        test_G_corrected = nx.relabel_nodes(test_G, addn)
        
        nodes_ids = test_G_corrected.nodes()
        
        # create node positions with springlayout if create_graph_info
        if create_graph_info:
            npos = nx.spring_layout(test_G_corrected, dim = 3, weighted = True, scale = 100)
        
        # add node properties
        if not create_graph_info:
            for k, v in like_network.graph.nodes(data=True):
                if not k in nodes_ids:
                    logger.error('Node id %s is not like_network.graph' % str(k))
                # add node properties
                test_G_corrected.node[k] = v
        else:
            for k in test_G_corrected.nodes():
                li = str(npos[k].tolist())
                li = li.replace('[','')
                li = li.replace(']','')
                test_G_corrected.node[k]['dn_position'] = li
                
                
        # create a new network object
        my_network = Network(name = name, directed = directed, hierarchical = hierarchical, \
                             hypergraph = hypergraph, graph = test_G_corrected)
        
        if not metadata is None:
            my_network.metadata = metadata
            
        # setting the correct parent cfile
        my_network._parentcfile = self
                
        if not create_graph_info:
            # add surface container from like_network
            action = ThreadedParsing(self)
            for surf in like_network.surfaces:
                if surf.is_atlas:
                    tmp_surfcont = action.process_atlas(surface_node=surf._lxml_node, \
                                                        nsprefix=surf._lxml_node_prefix)
                else:
                    tmp_surfcont = action.process_surface(surface_node=surf._lxml_node, \
                                                        nsprefix=surf._lxml_node_prefix)
                my_network.add_surface_container(tmp_surfcont)


        # add the created network object to this cfile
        self.networks.append(my_network)
        
        # returns the id of the added network
        return len(self.networks)-1
Beispiel #2
0
    def run(self):
        logger.debug("Start Threaded Parsing of Connectome File ...")
        import time
        tic = time.time()
        
        # given the full path to meta.xml, create lxml tree and
        # under the precondition of having a certain file version and generator
        # one can assume some content of the .cff file
        # loop over the networks, for each network, the surfaces etc.
        # in the form of all the attributes (name, srce filename, description etc.)
        # are given to the created Network instance methods to complete
        from lxml import etree
        tree = etree.fromstring(self.metaxmlcontent)   
        nsprefix = "{%s}" % tree.nsmap[None]
        
        t = 0
        for child in tree.iterchildren():
            if child.tag == (nsprefix+'viewer-network'):
                t = t + 1

        if t != self.data.metadata.nr_of_networks:
            logger.error('The number of networks of networks in meta.xml is not correct!')
            logger.error('Loading ' + str(t) + ' network(s).')


        # find all the networks
        for child in tree.iterchildren():
            if child.tag == (nsprefix+'viewer-network'):

                # load network as string from zip
                # create temporary StringIO
                logger.info('-----------------------------------------')
                logger.info('Now loading ' + child.attrib['src'])
                logger.info('-----------------------------------------')
                
                if child.attrib.has_key('src'):
                    (tmpstring, pickled_graph, local_fname) = self.process_pickle(childnode = child)
                
                tmp_network = Network(name = child.attrib['name'],
                                    src = tmpstring,
                                    pickled_graph = pickled_graph,
                                    directed = child.attrib['directed'],
                                    hierarchical = child.attrib['hierarchical'],
                                    hypergraph = child.attrib['hypergraph'])

                # store pickled version in connectome file
                if not tmpstring is None and pickled_graph is None:
                    self.save_pickle_in_cfile(local_fname, networkref = tmp_network)

                
                # iterate over children
                for mchildren in child.iterchildren():
                    
                    # handling of the metadata
                    # -------------------------
                    if mchildren.tag == (nsprefix+'network-metadata'):
                        tmp_network.metadata = self.process_metadata(metadata_node = mchildren, nsprefix = nsprefix)
                        
                        
                    # handling of the surfaces
                    # ------------------------
                    if mchildren.tag == (nsprefix+'network-surface'):
                    
                        # load into surface
                        attr = mchildren.attrib
    
                        if attr.has_key('src'):
                            # create surface container
                            tmpsurfacecontainer = self.process_surface(surface_node = mchildren, nsprefix = nsprefix)
                            # and add it to the network
                            tmp_network.add_surface_container(tmpsurfacecontainer)

                        # adding a template atlas if stated in the meta.xml
                        if attr.has_key('addatlas'):
                            # create surface container for atlas
                            tmpsurfacecontainer = self.process_atlas(surface_node = mchildren, nsprefix = nsprefix)
                            # and add it to the network
                            tmp_network.add_surface_container(tmpsurfacecontainer)
                            
                        
                    # handling of the volumes
                    # -----------------------
                    elif mchildren.tag == (nsprefix+'network-volume'):
                        
                        # get the description, is there an easier way with lxml?
                        for desc in mchildren.iterchildren():
                            if desc.tag == (nsprefix+'description'):
                                mydescr = desc.text
                      
                        attr = mchildren.attrib
                        
                        if attr.has_key('src') and attr.has_key('name'):
                          
                            if not attr.has_key('segmentation'):
                                segm = False
                            else:
                                segm = bool(attr['segmentation'])
                          
                            # create an instance of the Volume class with it
                            tmpvolume = Volume(volumename = attr['name'], \
                                                 networkref = tmp_network, \
                                                 src = attr['src'], \
                                                 description = mydescr, \
                                                 segmentation = segm)
                            
                            # add this instance to the list of its network
                            tmp_network.add_volume(tmpvolume)
                            logger.info('Added volume ' + tmpvolume.volumename + \
                                        ' to ' + tmp_network.networkname)

                            
                    # handling of the trackfiles
                    # --------------------------
                    elif mchildren.tag == (nsprefix+'network-track'):
                        
                        # get the description, is there an easier way with lxml?
                        for desc in mchildren.iterchildren():
                            if desc.tag == (nsprefix+'description'):
                              mydescr = desc.text
                      
                        attr = mchildren.attrib
                    
                        if attr.has_key('src') and attr.has_key('name'):
                            tmptrack = Trackfile(trkname = attr['name'], tmpfname = attr['src'], \
                                                 description = mydescr, networkref = tmp_network)
                            
                            # add this instance to the list of its trackfiles
                            tmp_network.add_trackfile(tmptrack)
                            logger.info('Added trackfile ' + tmptrack.trkname + \
                                        ' to ' + tmp_network.networkname)

                # setting the correct parent cfile
                tmp_network._parentcfile = self.data
                
                # add the created network object to this cfile
                self.data.networks.append(tmp_network)

        toc = time.time()
        logger.info('Loading Connectome File DONE. (Time: %s)' % str(toc-tic))
        logger.info('-----------------------------------------')
        
        # setting data loaded flag
        self.data._data_loaded = True
        
        # with do_later, we the change in the statusbar is done in the gui main thread
        if not self.data._workbenchwin is None:
            #from enthought.pyface.timer.api import do_later
            #do_later(self.data._workbenchwin.status_bar_manager.set, message = '')
            # TEST
            from enthought.pyface.api import GUI
            GUI.invoke_later(self.data._workbenchwin.status_bar_manager.set, message = '')
Beispiel #3
0
    def add_network_from_matrix_with_pos(self, name, matrix, pos, nodeinfo_like_graph = None, \
                                         metadata = None, directed = False, hierarchical = False, hypergraph = False):
        """ Add a network to the cfil based on the given connectivity matrix and
        position information.
        
        Parameters
        ----------
        name : String
            Name of the newly added network
        matrix : NxN array
            A NxN Numpy array with the values for the edges. N must be the same
            as len(like_network.graph.nodes()). The first row of the matrix
            corresponds to the `NetworkX` node with id 'n1'
        pos : Nx3 array
            A Nx3 array with the X,Y,Z coordinates for every row (=node) of the matrix
        nodeinfo_like_graph : `NetworkX` graph
            Use the node information for the new network
        metadata : Dict
            A dictionary of metadata
        directed : bool
            Is the network directed?
        hierarchical : bool
            Is the network hierarchical? (default: '0') Not implemented yet.
        hypergraph : bool
            Is the network a hypergraph? (default: '0') Not implemented yet.
            
        Returns
        -------
        networkid : int
            The index in the list of networks in the cfile
        """
        from cviewer.plugins.cff.network import Network
        
        # create a new network object
        my_network = Network(name = name, directed = directed, hierarchical = hierarchical, \
                             hypergraph = hypergraph)
        
        if not metadata is None:
            my_network.metadata = metadata

        # add graph 
        import networkx as nx
        test_G = nx.from_numpy_matrix(matrix)
        
        # relabeling function
        addn = lambda nmod:'n'+str(nmod+1)
        
        # relabel graph
        test_G_corrected = nx.relabel_nodes(test_G, addn)

        # update the node position
        for i in range(matrix.shape[0]):
            nodeid = addn(i)
            if not nodeinfo_like_graph is None and nodeinfo_like_graph.has_node(nodeid):
                test_G_corrected.node[nodeid] = nodeinfo_like_graph.node[nodeid]
            test_G_corrected.node[nodeid]['dn_position'] = ','.join(list(map(str,pos[i, :])))

        my_network.graph = test_G_corrected
        
        # setting the correct parent cfile
        my_network._parentcfile = self


        # add the created network object to this cfile
        self.networks.append(my_network)
        
        # returns the id of the added network
        return len(self.networks)-1