Skip to content

Commit

Permalink
Merge pull request #6 from openworm/development
Browse files Browse the repository at this point in the history
Added initial Cook reader (herm only, no muscles)
  • Loading branch information
yasinthanvickneswaran authored Feb 28, 2024
2 parents 985a330 + fee6bf9 commit 9963501
Show file tree
Hide file tree
Showing 78 changed files with 856 additions and 82 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,13 @@ arm64
/examples/test/images/c302_C1_Oscillator.net.nml
/examples/test/images/LEMS_c302_C1_Oscillator.xml
/c302/VarshneyDataReader2.py
/
/examples/test/images/LEMS_c302_C1_Full.xml
/examples/test/images/LEMS_c302_C1_Muscles.xml
/examples/test/images/LEMS_c302_C1_Social.xml
/examples/test/images/LEMS_c302_C1_Syns.xml
/examples/test/images/c302_C1_Full.net.nml
/examples/test/images/c302_C1_Muscles.net.nml
/examples/test/images/c302_C1_Pharyngeal.net.nml
/examples/test/images/c302_C1_Social.net.nml
/examples/test/images/c302_C1_Syns.net.nml
13 changes: 11 additions & 2 deletions c302/ConnectomeReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ def convert_to_preferred_muscle_name(muscle):
return muscle + "???"

def get_all_muscle_prefixes():
return ["pm", "vm", "um", "BWM-D", "BWM-V", "LegacyBodyWallMuscles"]
return ["pm", "vm", "um", "BWM-D", "BWM-V", "LegacyBodyWallMuscles", "vBWM", "dBWM"]


def get_body_wall_muscle_prefixes():
return ["BWM-D", "BWM-V", "LegacyBodyWallMuscles"]
return ["BWM-D", "BWM-V", "LegacyBodyWallMuscles", "vBWM", "dBWM"]


def is_muscle(cell):
Expand All @@ -48,6 +48,15 @@ def is_body_wall_muscle(cell):
def is_neuron(cell):
return not is_body_wall_muscle(cell)


def remove_leading_index_zero(cell):
"""
Returns neuron name with an index without leading zero. E.g. VB01 -> VB1.
"""
if is_neuron(cell) and cell[-2:].startswith("0"):
return "%s%s" % (cell[:-2], cell[-1:])
return cell

class ConnectionInfo:

def __init__(self,
Expand Down
188 changes: 188 additions & 0 deletions c302/Cook2019DataReader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# -*- coding: utf-8 -*-

############################################################

# A simple script to read the values in herm_full_edgelist.csv.

# This is on of a number of interchangeable "Readers" which can
# be used to get connection data for c302

############################################################

import csv

from c302.ConnectomeReader import ConnectionInfo
from c302.ConnectomeReader import analyse_connections
from c302.ConnectomeReader import convert_to_preferred_muscle_name
from c302.ConnectomeReader import is_neuron
from c302.ConnectomeReader import is_body_wall_muscle
from c302.ConnectomeReader import remove_leading_index_zero

from openpyxl import load_workbook

import os
import numpy as np

from c302 import print_

spreadsheet_location = os.path.dirname(os.path.abspath(__file__))+"/data/"
filename = "%sSI 5 Connectome adjacency matrices.xlsx" % spreadsheet_location

HERM_CHEM = 'hermaphrodite chemical'
HERM_GAP_SYMM = 'herm gap jn symmetric'

pre_range = {HERM_CHEM:range(4,304),
HERM_GAP_SYMM:range(4,472)}

post_range = {HERM_CHEM:range(4,457),
HERM_GAP_SYMM:range(4,472)}


def get_synclass(cell, syntype):
#TODO: fix this dirty hack
if syntype == "GapJunction":
return "Generic_GJ"
else:
if cell.startswith("DD") or cell.startswith("VD"):
return "GABA"
return "Acetylcholine"

class Cook2019DataReader():

verbose = False

def __init__(self):

wb = load_workbook(filename)
print_("Opened the Excel file: " + filename)

self.pre_cells = {}
self.post_cells = {}
self.conn_nums = {}

for conn_type in [HERM_CHEM, HERM_GAP_SYMM]:

sheet = wb.get_sheet_by_name(conn_type)
print('Looking at sheet: %s'%conn_type)

self.pre_cells[conn_type] = []
self.post_cells[conn_type] = []

for i in pre_range[conn_type]:
self.pre_cells[conn_type].append(sheet['C%i'%i].value)

if self.verbose: print(' - Pre cells for %s (%i):\n%s'%(conn_type, len(self.pre_cells[conn_type]), self.pre_cells[conn_type]))

for i in post_range[conn_type]:
self.post_cells[conn_type].append(sheet.cell(row=3, column=i).value)

if self.verbose: print(' - Post cells for %s (%i):\n%s'%(conn_type, len(self.post_cells[conn_type]), self.post_cells[conn_type]))

self.conn_nums[conn_type] = np.zeros([len(self.pre_cells[conn_type]),len(self.post_cells[conn_type])], dtype=int)

for i in range(len(self.pre_cells[conn_type])):
for j in range(len(self.post_cells[conn_type])):
row =4+i
col = 4+j
val = sheet.cell(row=row, column=col).value
#print('Cell (%i,%i) [row %i, col %i] = %s'%(i,j,row, col, val))
if val is not None:
self.conn_nums[conn_type][i,j] = int(val)

if self.verbose: print(' - Conns for %s (%s):\n%s'%(conn_type, self.conn_nums[conn_type].shape, self.conn_nums[conn_type]))



def read_data(self, include_nonconnected_cells=False):
"""
Args:
include_nonconnected_cells (bool): Also append neurons without known connections to other neurons to the 'cells' list. True if they should get appended, False otherwise.
Returns:
cells (:obj:`list` of :obj:`str`): List of neurons
conns (:obj:`list` of :obj:`ConnectionInfo`): List of connections from neuron to neuron
"""

if not include_nonconnected_cells:
raise Exception('Option include_nonconnected_cells=False not supported')

conns = []
cells = []
for conn_type in [HERM_CHEM, HERM_GAP_SYMM]:

for pre_index in range(len(self.pre_cells[conn_type])):
for post_index in range(len(self.post_cells[conn_type])):

pre = remove_leading_index_zero(self.pre_cells[conn_type][pre_index])
post = remove_leading_index_zero(self.post_cells[conn_type][post_index])

if is_body_wall_muscle(post):
continue # post is a BWM so ignore

num = self.conn_nums[conn_type][pre_index,post_index]
if num>0:
syntype = 'Send' if conn_type == HERM_CHEM else "GapJunction"
synclass = get_synclass(pre, syntype)

conns.append(ConnectionInfo(pre, post, num, syntype, synclass))
#print ConnectionInfo(pre, post, num, syntype, synclass)
if pre not in cells:
cells.append(pre)
if post not in cells:
cells.append(post)

return cells, conns


def read_muscle_data(self):
"""
Returns:
neurons (:obj:`list` of :obj:`str`): List of motor neurons. Each neuron has at least one connection with a post-synaptic muscle cell.
muscles (:obj:`list` of :obj:`str`): List of muscle cells.
conns (:obj:`list` of :obj:`ConnectionInfo`): List of neuron-muscle connections.
"""

neurons = []
muscles = []
conns = []

'''
with open(filename, 'r') as f:
reader = csv.DictReader(f)
print_("Opened file: " + filename)
for row in reader:
pre, post, num, syntype, synclass = parse_row(row)
if not (is_neuron(pre) or is_body_wall_muscle(pre)) or not is_body_wall_muscle(post):
continue
if is_neuron(pre):
pre = remove_leading_index_zero(pre)
else:
pre = get_old_muscle_name(pre)
post = get_old_muscle_name(post)
conns.append(ConnectionInfo(pre, post, num, syntype, synclass))
if is_neuron(pre) and pre not in neurons:
neurons.append(pre)
elif is_body_wall_muscle(pre) and pre not in muscles:
muscles.append(pre)
if post not in muscles:
muscles.append(post)'''

return neurons, muscles, conns


def main():

cdr = Cook2019DataReader()
read_data = cdr.read_data
read_muscle_data = cdr.read_muscle_data

cells, neuron_conns = read_data(include_nonconnected_cells=True)
neurons2muscles, muscles, muscle_conns = read_muscle_data()

analyse_connections(cells, neuron_conns, neurons2muscles, muscles, muscle_conns)

if __name__ == '__main__':
main()
19 changes: 19 additions & 0 deletions c302/Cook2019HermReader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Temporary class to allow this to be used in comparison notebook.
# Should be tidied up.

from c302.Cook2019DataReader import Cook2019DataReader

from c302.ConnectomeReader import analyse_connections

cdr = Cook2019DataReader()
read_data = cdr.read_data
read_muscle_data = cdr.read_muscle_data

def main1():
cells, neuron_conns = read_data(include_nonconnected_cells=True)
neurons2muscles, muscles, muscle_conns = read_muscle_data()
analyse_connections(cells, neuron_conns, neurons2muscles, muscles, muscle_conns)


if __name__ == '__main__':
main1()
2 changes: 1 addition & 1 deletion c302/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ def _get_cell_info(bnd, cells):
for name in fixed_up_names:
cell = next(ctx(Cell).query(name=name).load(), None)
if cell is None:
print_("No matching cell for %s" % name)
#print_("No matching cell for %s" % name)
continue

normalized_name = cell.name()
Expand Down
14 changes: 13 additions & 1 deletion c302/c302_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,8 @@ def generate_conn_matrix(nml_doc, save_fig_dir=None, verbose=False, figsize=defa
configs = ['c302_C0_Muscles.net.nml']
configs = ['c302_C0_Syns.net.nml', 'c302_C0_Social.net.nml','c302_C0_Muscles.net.nml','c302_C0_Pharyngeal.net.nml','c302_C0_Oscillator.net.nml','c302_C0_Full.net.nml']

figsize=(6.4,4.8)

if '-phar' in sys.argv:

configs = ['c302_C0_Pharyngeal.net.nml']
Expand All @@ -585,11 +587,21 @@ def generate_conn_matrix(nml_doc, save_fig_dir=None, verbose=False, figsize=defa

configs = ['c302_C1_Oscillator.net.nml']

elif '-musc' in sys.argv:

configs = ['c302_C1_Muscles.net.nml']
figsize=(10,10)

elif '-full' in sys.argv:

configs = ['c302_C1_Full.net.nml']
figsize=(10,10)

for c in configs:

nml_doc = read_neuroml2_file('examples/%s'%c)

generate_conn_matrix(nml_doc, save_fig_dir='./examples/summary/images', figsize=(6.4,4.8))
generate_conn_matrix(nml_doc, save_fig_dir='./examples/summary/images', figsize=figsize)

if not '-nogui' in sys.argv:
plt.show()
Binary file added c302/data/SI 5 Connectome adjacency matrices.xlsx
Binary file not shown.
Loading

0 comments on commit 9963501

Please sign in to comment.