openworm / owmeta

Unified, simple data access python library for data & facts about C. elegans anatomy
MIT License
151 stars 49 forks source link

Method to get potential extrasynaptic connectivity #281

Open clbarnes opened 7 years ago

clbarnes commented 7 years ago

As used in this paper here. The machine-readable receptor mappings and so on are in the S1 Dataset: the paper also includes some new expression data, so I've added it to issue #274.

It would be valuable and possibly not particularly difficult to write a method which takes PyOpenWorm's expression data and uses it to construct the same sort of putative extrasynaptic connectivity matrix as is used in the paper: I think doing it dynamically is the way forward as the edges aren't all experimentally verified and that would be robust to changing expression data.

By getting the graph in networkx format, we can put lots and lots of metadata on the nodes and edges, including things like EC50 values which people could filter on, or how sure we are that something is indeed a receptor (like dop-5 and dop-6, which I think at the moment are just 'expected' dopamine receptors due to sequence similarity to other dopamine receptors).

Parent to #286, #287, #288, #290

mwatts15 commented 7 years ago

@clbarnes Could you elaborate on what the extrasynaptic connectivity matrix would look like? It sounds like it would be another set of 1-to-1, unidirectional connections between neurons like the existing synaptic connections in PyOpenWorm-- is that accurate? When you suggest constructing the matrix dynamically though, it sounds like you'd want to store some data that generates the matrix and I'm having trouble reconciling those notions.

clbarnes commented 7 years ago

Sorry I missed this, but to reiterate what I said in my email so that it's out in the open:

We currently have access to:

I don't think we currently do, but could very easily, store

In the paper, we just drew 1-1, unidirectional edges between neurons expressing cognate monoamine and neuropeptide transmitters and receptors, regardless of morphology, but obviously these edges are putative in nature and not all of them have experimental backing. This connectivity will also change every time expression patterns do, and users may like to add their own expression data and so on, which would also change it.

As such, my proposal is that we add the transmitter-receptor mappings to the database dump csv (with a relationship of 'ligand' or something). We can then have a method like network.get_extrasynaptic_connectivity(monoamines: bool, neuropeptides: bool) which will basically do this underneath:

import networkx as nx

def _get_extrasynaptic_connectome(list_of_cells, cell_transmitter_mapping, transmitter_receptor_mapping, receptor_cell_mapping) 
    """
    list_of_cells: List of neuron names
    cell_transmitter_mapping: Mapping of {cell_name: {set_of_transmitters}}
    transmitter_receptor_mapping: Mapping of {transmitter: {set_of_receptors}}
    receptor_cell_mapping: Mapping of {receptor: {set_of_cells}}
    """

    extrasyn_connectome = nx.MultiDiGraph()
    for cell_name in list_of_cells:
        extrasyn_connectome.add_node(
            cell_name, 
            transmitters=cell_transmitter_mapping.get(cell_name, set()),
            receptors=set()
        )

    for source_cell, transmitter_set in cell_transmitter_mapping.items():
        for transmitter in transmitter_set:
            # filter on monoamine/neuropeptide if required
            for receptor in transmitter_receptor_mapping[transmitter]:
                for target_cell in receptor_cell_mapping[receptor]:
                    extrasyn_connectome.node[target_cell]['receptors'].add(receptor)
                    extrasyn_connectome.add_edge(source_cell, target_cell, transmitter=transmitter, receptor=receptor)

    return extrasyn_connectome

Then it'll always be accurate to whatever expression and ligand data the user has available, and we don't shoulder the blame for maintaining an authoritative extrasynaptic connectome where we don't have experimental evidence for some of the edges.

I would be inclined to do this every time the user calls the method, and return a networkx instance, rather than having it in insert_worm and have all the edges and such accessible through the pyopenworm API, because it keeps it distinct from the the 'hard' evidence-based synaptic connections, and will also be a lot simpler.

clbarnes commented 7 years ago

Discussed in slack starting https://openworm.slack.com/archives/pyopenworm/p1486224576000071