History of celegans_development
The changes to the source code of this entry in the repository, newest first, each with the differences it made to the entry's files. They are also listed on GitLab.
[entries] New entry: celegans_development 0583edf
diff --git a/entries/celegans_development/__init__.py b/entries/celegans_development/__init__.py
new file mode 100644
index 0000000..50ed09a
--- /dev/null
+++ b/entries/celegans_development/__init__.py
@@ -0,0 +1,90 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2020-2026 Tiago de Paula Peixoto <tiago@skewed.de>
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from .. import *
+from openpyxl import load_workbook
+
+title = "C. elegans brain across development (2021)"
+description = r"""Connectomes of the brain (the nerve ring and ventral ganglion) of eight isogenic hermaphrodite nematodes *Caenorhabditis elegans* of different ages, from birth to adulthood, reconstructed by D. Witvliet and collaborators from serial-section electron microscopy images. Nodes are cells: neurons, as well as the body wall muscles and glia that they contact in the volume. Edges are either chemical synapses (directed, from the presynaptic to the postsynaptic cell) or gap junctions (electrical synapses, undirected).
+
+There are sixteen networks, named `<stage>_<connection type>`, one for each animal and connection type (`chemical`, `gap_junction`). The animals are, by developmental stage and approximate age (hours after birth, at 25°C, estimated from the cell division pattern):
+
+- `L1_1`, `L1_2`, `L1_3`, `L1_4`: first larval stage, at 0, 5, 8 and 16 hours.
+- `L2`: second larval stage, at 23 hours.
+- `L3`: third larval stage, at 27 hours.
+- `adult_1`, `adult_2`: young adults, at about 45 to 50 hours (their exact ages are uncertain).
+
+The nodes of both networks of an animal are all the cells that make any connection in that animal, so that cells without connections of a given type are isolated nodes. Self-loops are synapses of a cell onto itself, as recorded in the data.
+
+The networks have the following properties:
+
+- `name`: the name of the cell (e.g. `AVAL`, `BWM-DL01` for body wall muscles).
+- `synapses` (edges): the number of synapses between the two cells."""
+tags = ['Biological', 'Connectome', 'Weighted']
+url = ['https://wormwiring.org/pages/witvliet.html', 'https://nemanode.org']
+citation = [('D. Witvliet et al., "Connectomes across development reveal principles of brain maturation." Nature 596, 257-261 (2021)', 'https://doi.org/10.1038/s41586-021-03778-8')]
+icon_hash = None
+upstream_license = None
+upstream_prefix = 'https://wormwiring.org/witvliet'
+_datasets = [("1%20L1", "L1_1"), ("2%20L1", "L1_2"), ("3%20L1", "L1_3"),
+ ("4%20L1", "L1_4"), ("5%20L2", "L2"), ("6%20L3", "L3"),
+ ("7%20adult", "adult_1"), ("8%20adult", "adult_2")]
+files = [(f"witvliet_2020_{d}.xlsx", f"{alt}_{kind}", None)
+ for d, alt in _datasets for kind in ["chemical", "gap_junction"]]
+
+def fetch_upstream(force=False):
+ return fetch_upstream_files(__name__.split(".")[-1], upstream_prefix, files,
+ force)
+
+@cache_network()
+@coerce_props()
+@annotate()
+def parse(alts=None):
+ name = __name__.split(".")[-1]
+ for fname, alt, fmt in files:
+ if alts is not None and alt not in alts:
+ continue
+ kind = "chemical" if alt.endswith("_chemical") else "electrical"
+ with open_upstream_file(name, fname, "rb", seekable=True) as f:
+ wb = load_workbook(f, read_only=True)
+ rows = list(wb.worksheets[0].iter_rows(values_only=True))
+ if rows[0] != ("pre", "post", "type", "synapses"):
+ raise ValueError(f"unexpected header in {fname}: {rows[0]}")
+ cells = set()
+ edges = []
+ for pre, post, typ, syn in rows[1:]:
+ if pre is None:
+ continue
+ cells.update((pre, post))
+ if typ not in ("chemical", "electrical"):
+ raise ValueError(f"unknown connection type in {fname}: {typ}")
+ if typ == kind:
+ edges.append((pre, post, int(syn)))
+
+ g = Graph(directed=(kind == "chemical"))
+ g.vp.name = g.new_vp("string")
+ vs = {}
+ for c in sorted(cells):
+ v = g.add_vertex()
+ g.vp.name[v] = c
+ vs[c] = v
+ g.ep.synapses = g.new_ep("int")
+ for pre, post, syn in edges:
+ e = g.add_edge(vs[pre], vs[post])
+ g.ep.synapses[e] = syn
+ yield alt, g