History of pchic_blood_cells
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] Add the date when each entry was added, and remove icon_hash beff7c9
The dates are those of the commits that first added the entries' files (2020-08-11 for the entries of the initial commit); renamed entries keep the date of their first name. Changed: none
diff --git a/entries/pchic_blood_cells/__init__.py b/entries/pchic_blood_cells/__init__.py
index 3c9dc60..1f86dd8 100644
--- a/entries/pchic_blood_cells/__init__.py
+++ b/entries/pchic_blood_cells/__init__.py
@@ -57,7 +57,7 @@ tags = ['Biological', 'Genetic', 'Weighted', 'Metadata']
url = ['https://osf.io/u8tzp/', 'https://www.chicp.org/']
citation = [('B. M. Javierre, O. S. Burren, S. P. Wilder, R. Kreuzhuber, S. M. Hill, S. Sewitz, J. Cairns, S. W. Wingett, C. Várnai, M. J. Thiecke, et al., "Lineage-Specific Genome Architecture Links Enhancers and Non-coding Disease Variants to Target Gene Promoters." Cell 167, 1369-1384.e19 (2016)',
'https://doi.org/10.1016/j.cell.2016.09.037')]
-icon_hash = None
+date_added = '2026-10-31'
upstream_license = ('Creative Commons Attribution 4.0 International (CC BY 4.0)',
'https://creativecommons.org/licenses/by/4.0/')
# OSF file ids: PCHiC_peak_matrix_cutoff5.txt.gz, PCHiC_peak_matrix_cutoff0.txt.gz,
[entries] Prefix the properties in the descriptions with (Node), (Edge) or (Graph) bc3dbbd
The lists of properties at the end of the descriptions marked edge properties with "Edge" but left node properties unmarked, or grouped them in "Nodes: `a`, ...; `b`, ..." items, so the kind of a property was often unclear. Every item now starts with (Node), (Edge) or (Graph), followed by the property names, a colon and the explanation, one item per property or group of properties; qualifications (kinds of nodes, networks) follow the names in parentheses. Properties that were only named got a short explanation, and a few items that named the wrong kind of property were corrected.
diff --git a/entries/pchic_blood_cells/__init__.py b/entries/pchic_blood_cells/__init__.py
index b7e3a06..3c9dc60 100644
--- a/entries/pchic_blood_cells/__init__.py
+++ b/entries/pchic_blood_cells/__init__.py
@@ -45,14 +45,14 @@ The cell types (abbreviations of the score properties) are: `Mon` (monocytes), `
The networks have the following properties:
-- `fragment_id`: the identifier of the restriction fragment (from the restriction map of the capture design).
-- `chr`, `start`, `end`: the chromosome and the coordinates of the fragment (GRCh37).
-- `genes`: the genes whose promoters are in the fragment, separated by `;` (Ensembl release 75; empty for fragments without annotated promoters).
-- `is_bait`: whether the fragment is a bait of the experiment (in `pchic_vs_rchic`: a PCHi-C bait).
-- Edge `dist`: the distance between the bait and the other end (positive if the bait is upstream of the other end; NaN for interactions between chromosomes).
-- Edge `Mon`, `Mac0`, ..., `tB`: the CHiCAGO scores of the interaction in each cell type (in `pchic_vs_rchic`: `PCHiC_MK`, ..., `rCHiC_MK`, ... for the two experiments).
-- Edge `cluster_id`, `cluster_post_prob` (`cutoff5`): the cluster of the interaction in the clustering of the interactions by their scores across cell types (with AutoClass, Figure 2B of the paper), and the posterior probability of the assignment.
-- Edge `is_b2b` (`reciprocal_cutoff0`): whether the interaction is between two baits."""
+- (Node) `fragment_id`: the identifier of the restriction fragment (from the restriction map of the capture design).
+- (Node) `chr`, `start`, `end`: the chromosome and the coordinates of the fragment (GRCh37).
+- (Node) `genes`: the genes whose promoters are in the fragment, separated by `;` (Ensembl release 75; empty for fragments without annotated promoters).
+- (Node) `is_bait`: whether the fragment is a bait of the experiment (in `pchic_vs_rchic`: a PCHi-C bait).
+- (Edge) `dist`: the distance between the bait and the other end (positive if the bait is upstream of the other end; NaN for interactions between chromosomes).
+- (Edge) `Mon`, `Mac0`, ..., `tB`: the CHiCAGO scores of the interaction in each cell type (in `pchic_vs_rchic`: `PCHiC_MK`, ..., `rCHiC_MK`, ... for the two experiments).
+- (Edge) `cluster_id`, `cluster_post_prob` (`cutoff5`): the cluster of the interaction in the clustering of the interactions by their scores across cell types (with AutoClass, Figure 2B of the paper), and the posterior probability of the assignment.
+- (Edge) `is_b2b` (`reciprocal_cutoff0`): whether the interaction is between two baits."""
tags = ['Biological', 'Genetic', 'Weighted', 'Metadata']
url = ['https://osf.io/u8tzp/', 'https://www.chicp.org/']
citation = [('B. M. Javierre, O. S. Burren, S. P. Wilder, R. Kreuzhuber, S. M. Hill, S. Sewitz, J. Cairns, S. W. Wingett, C. Várnai, M. J. Thiecke, et al., "Lineage-Specific Genome Architecture Links Enhancers and Non-coding Disease Variants to Target Gene Promoters." Cell 167, 1369-1384.e19 (2016)',
[entries] New entry: pchic_blood_cells 323f3d9
diff --git a/entries/pchic_blood_cells/__init__.py b/entries/pchic_blood_cells/__init__.py
new file mode 100644
index 0000000..b7e3a06
--- /dev/null
+++ b/entries/pchic_blood_cells/__init__.py
@@ -0,0 +1,155 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 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/>.
+
+import gzip
+
+import pyarrow as pa
+import pyarrow.csv as pacsv
+
+from .. import *
+
+CELLS = {"Mon": "monocytes", "Mac0": "macrophages M0", "Mac1": "macrophages M1",
+ "Mac2": "macrophages M2", "Neu": "neutrophils", "MK": "megakaryocytes",
+ "EP": "endothelial precursors", "Ery": "erythroblasts",
+ "FoeT": "fetal thymus", "nCD4": "naive CD4+ T cells",
+ "tCD4": "total CD4+ T cells", "aCD4": "activated CD4+ T cells",
+ "naCD4": "non-activated CD4+ T cells", "nCD8": "naive CD8+ T cells",
+ "tCD8": "total CD8+ T cells", "nB": "naive B cells", "tB": "total B cells"}
+
+title = "Promoter Capture Hi-C in 17 human blood cell types (2016)"
+description = r"""Networks of chromatin contacts between promoters and other regions of the human genome, measured with Promoter Capture Hi-C (PCHi-C) in 17 types of primary blood cells (and their progenitors) by Javierre et al., to link enhancers and non-coding disease variants to the genes they regulate. In Hi-C, the DNA of the cells is cross-linked, cut with the restriction enzyme HindIII, and ligated, so that pairs of fragments that are close in the three-dimensional nucleus are sequenced together; in Capture Hi-C, the ligation products are enriched for the fragments that contain a promoter (the "baits", fragments that contain annotated promoters). Significant interactions were called with CHiCAGO, whose score (a soft-thresholded $-\log$ $p$-value) is given per cell type.
+
+Nodes are HindIII restriction fragments of the genome (GRCh37 assembly), and a directed edge goes from a bait to a fragment it interacts with (the "other end"), with the CHiCAGO scores of the interaction in the cell types. Interactions between two baits are detected from the point of view of each bait, so that they can appear in both directions.
+
+- `cutoff5`: the interactions with a score of at least 5 (the threshold of the study) in at least one cell type.
+- `cutoff0`: all the interactions with a positive score in at least one cell type (the unthresholded data).
+- `reciprocal_cutoff0`: the interactions of the reciprocal capture experiment, in which fragments that interact with promoters (mostly enhancers) were captured as baits, in four cell types (megakaryocytes, erythroblasts, activated and non-activated CD4+ T cells), with a positive score in at least one of them.
+- `pchic_vs_rchic`: the interactions between the baits of PCHi-C and the baits of the reciprocal capture, with their scores in both experiments, from the point of view of PCHi-C (edges go from the PCHi-C bait to the reciprocal bait), for the four cell types of the reciprocal capture.
+
+The cell types (abbreviations of the score properties) are: `Mon` (monocytes), `Mac0`, `Mac1`, `Mac2` (macrophages M0, M1 and M2), `Neu` (neutrophils), `MK` (megakaryocytes), `EP` (endothelial precursors), `Ery` (erythroblasts), `FoeT` (fetal thymus), `nCD4`, `tCD4`, `aCD4`, `naCD4` (naive, total, activated and non-activated CD4+ T cells), `nCD8`, `tCD8` (naive and total CD8+ T cells), `nB`, `tB` (naive and total B cells).
+
+The networks have the following properties:
+
+- `fragment_id`: the identifier of the restriction fragment (from the restriction map of the capture design).
+- `chr`, `start`, `end`: the chromosome and the coordinates of the fragment (GRCh37).
+- `genes`: the genes whose promoters are in the fragment, separated by `;` (Ensembl release 75; empty for fragments without annotated promoters).
+- `is_bait`: whether the fragment is a bait of the experiment (in `pchic_vs_rchic`: a PCHi-C bait).
+- Edge `dist`: the distance between the bait and the other end (positive if the bait is upstream of the other end; NaN for interactions between chromosomes).
+- Edge `Mon`, `Mac0`, ..., `tB`: the CHiCAGO scores of the interaction in each cell type (in `pchic_vs_rchic`: `PCHiC_MK`, ..., `rCHiC_MK`, ... for the two experiments).
+- Edge `cluster_id`, `cluster_post_prob` (`cutoff5`): the cluster of the interaction in the clustering of the interactions by their scores across cell types (with AutoClass, Figure 2B of the paper), and the posterior probability of the assignment.
+- Edge `is_b2b` (`reciprocal_cutoff0`): whether the interaction is between two baits."""
+tags = ['Biological', 'Genetic', 'Weighted', 'Metadata']
+url = ['https://osf.io/u8tzp/', 'https://www.chicp.org/']
+citation = [('B. M. Javierre, O. S. Burren, S. P. Wilder, R. Kreuzhuber, S. M. Hill, S. Sewitz, J. Cairns, S. W. Wingett, C. Várnai, M. J. Thiecke, et al., "Lineage-Specific Genome Architecture Links Enhancers and Non-coding Disease Variants to Target Gene Promoters." Cell 167, 1369-1384.e19 (2016)',
+ 'https://doi.org/10.1016/j.cell.2016.09.037')]
+icon_hash = None
+upstream_license = ('Creative Commons Attribution 4.0 International (CC BY 4.0)',
+ 'https://creativecommons.org/licenses/by/4.0/')
+# OSF file ids: PCHiC_peak_matrix_cutoff5.txt.gz, PCHiC_peak_matrix_cutoff0.txt.gz,
+# rCHiC_peak_matrix_cutoff0.txt.gz, PCHiC_vs_rCHiC_peak_matrix.txt.gz
+upstream_prefix = 'https://osf.io/download'
+files = [("63hh4", "cutoff5", None),
+ ("dpmu9", "cutoff0", None),
+ ("8juyx", "reciprocal_cutoff0", None),
+ ("udk3h", "pchic_vs_rchic", None)]
+
+def fetch_upstream(force=False):
+ return fetch_upstream_files(__name__.split(".")[-1], upstream_prefix, files,
+ force)
+
+_check_rows = None
+
+@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
+ with open_upstream_file(name, fname, "rb") as fz, gzip.open(fz) as f:
+ reader = pacsv.open_csv(
+ f, read_options=pacsv.ReadOptions(block_size=1 << 26),
+ parse_options=pacsv.ParseOptions(delimiter="\t"),
+ convert_options=pacsv.ConvertOptions(
+ null_values=["NA"], strings_can_be_null=False,
+ column_types={"baitChr": pa.string(), "oeChr": pa.string(),
+ "rBaitChr": pa.string(), "rOeChr": pa.string(),
+ "dist": pa.float64()}))
+ batches = []
+ n = 0
+ for b in reader:
+ batches.append(b)
+ n += b.num_rows
+ if _check_rows is not None and n >= _check_rows:
+ break
+ t = pa.Table.from_batches(batches)
+ del batches
+ t = t.rename_columns([c.replace("rBait", "bait").replace("rOe", "oe")
+ for c in t.column_names])
+ if "baitName" not in t.column_names:
+ # reciprocal capture: the baits have no gene annotations
+ t = t.append_column("baitName", pa.array([""] * t.num_rows))
+
+ bid = t["baitID"].to_numpy()
+ oid = t["oeID"].to_numpy()
+ ids, inv = numpy.unique(numpy.concatenate([bid, oid]), return_inverse=True)
+ m = len(bid)
+ g = Graph(directed=True)
+ g.add_vertex(len(ids))
+ g.add_edge_list(numpy.stack([inv[:m], inv[m:]], axis=1))
+ g.vp.fragment_id = g.new_vp("int64_t", vals=ids)
+
+ # fragment properties, from the rows in which they appear
+ chrs = [""] * len(ids)
+ start = numpy.zeros(len(ids), dtype="int64")
+ end = numpy.zeros(len(ids), dtype="int64")
+ genes = [""] * len(ids)
+ for side, vs in (("oe", inv[m:]), ("bait", inv[:m])):
+ c = t[f"{side}Chr"].to_pylist()
+ s = t[f"{side}Start"].to_numpy()
+ e = t[f"{side}End"].to_numpy()
+ nm = t[f"{side}Name"].to_pylist()
+ for i, v in enumerate(vs):
+ chrs[v] = c[i]
+ genes[v] = "" if nm[i] in (None, ".", "NA") else nm[i]
+ start[vs] = s
+ end[vs] = e
+ g.vp.chr = g.new_vp("string", vals=chrs)
+ g.vp.start = g.new_vp("int64_t", vals=start)
+ g.vp.end = g.new_vp("int64_t", vals=end)
+ g.vp.genes = g.new_vp("string", vals=genes)
+ is_bait = numpy.zeros(len(ids), dtype="bool")
+ is_bait[inv[:m]] = True
+ g.vp.is_bait = g.new_vp("bool", vals=is_bait)
+
+ g.ep.dist = g.new_ep("double", vals=t["dist"].to_numpy(zero_copy_only=False))
+ known = {"baitChr", "baitStart", "baitEnd", "baitID", "baitName",
+ "oeChr", "oeStart", "oeEnd", "oeID", "oeName", "dist",
+ "clusterID", "clusterPostProb", "isB2B"}
+ for c in t.column_names:
+ if c in known:
+ continue
+ g.ep[c] = g.new_ep("double", vals=t[c].to_numpy(zero_copy_only=False))
+ if "clusterID" in t.column_names:
+ g.ep.cluster_id = g.new_ep("int32_t", vals=t["clusterID"].to_numpy())
+ g.ep.cluster_post_prob = g.new_ep("double", vals=t["clusterPostProb"].to_numpy())
+ if "isB2B" in t.column_names:
+ g.ep.is_b2b = g.new_ep("bool", vals=t["isB2B"].to_numpy())
+ del t
+ yield alt, g