OSCR

A droplet-based long-read single-cell epigenome sequencing method for the high-throughput profiling of multidimensional regulatory elements within individual cells.

Code ↔ Paper

8 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 8 matches · 2 of them tie a paragraph to a whole file without given lines: weak matches, whose lines are not tinted
  1. [1] § Results › Allele-specific-C.Origami enables the prediction of high-resolution cell type- and allele-specific 3D chromatin architectures ↔ snp-density/SNP_density.ipynb, lines 297 to 383 · score 0.74 · sliding windows, SNP density, Mb window, C.Origami, predicted, model · Report a mismatch
  2. [2] § Materials and methods › Prediction of allele-specific 3D genome structures ↔ snp-density/SNP_density.ipynb, lines 297 to 383 · score 0.72 · sliding window, Mb window, C.Origami, prediction, model, SNP · Report a mismatch
  3. [3] § Materials and methods › Identification of allele-specific peaks ↔ src/generation/diploid-dna/01_build_haplotype_fasta.sh, the whole file · a weak match · score 0.68 · Illumina Platinum Genome, samtools, VCF, allelic, hg38, haplotype · Report a mismatch
  4. [4] § Results › Allele-specific-C.Origami enables the prediction of high-resolution cell type- and allele-specific 3D chromatin architectures ↔ snp-density/SNP_density.ipynb, lines 22 to 74 · score 0.63 · SNP density, Mb genomic windows, denser, raw, benchmark, resolution · Report a mismatch
  5. [5] § Materials and methods › Identification of allele-specific peaks ↔ snp-density/SNP_density.ipynb, lines 22 to 74 · score 0.63 · Illumina Platinum Genome, VCF, hg38, homozygous, SNP, heterozygous · Report a mismatch
  6. [6] § Materials and methods › Dimensionality reduction and clustering ↔ scripts/create_arrow.r, the whole file · a weak match · score 0.54 · create arrow, tile, TSS, score · Report a mismatch
  7. [7] § Results › Allele-specific-C.Origami enables the prediction of high-resolution cell type- and allele-specific 3D chromatin architectures ↔ tools/update_notebook_paths.py, lines 1 to 73 · score 0.50 · SNP density, benchmark, predicts, model, Mb, windows · Report a mismatch
  8. [8] § Materials and methods › Prediction of allele-specific 3D genome structures ↔ tools/update_notebook_paths.py, lines 1 to 73 · score 0.50 · dip3d, benchmarking, phased, prediction, model, Mb · Report a mismatch

Paper

Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Jupyter notebook · 406 lines · 16 KB · no license · 4 matches

  1. # %%
  2. # --- Libraries ---
  3. # dplyr : tidy data manipulation
  4. # Cairo : nice anti-aliased font rendering for PNG output (ggplot)
  5. # patchwork : compose multiple ggplots into a single figure
  6. library(dplyr)
  7. library(Cairo)
  8. library(patchwork)
  9. library(GenomicRanges)
  10. # Force ggplot/Cairo to use a real sans-serif font on this system,
  11. # otherwise font lookup falls back to a 'sans' alias that is not always
  12. # available inside Jupyter R kernels and the figure renders with boxes.
  13. CairoFonts(
  14. regular = "sans:style=Regular",
  15. bold = "sans:style=Bold",
  16. italic = "sans:style=Italic",
  17. bolditalic = "sans:style=Bold Italic,BoldItalic",
  18. symbol = "Symbol", usePUA = TRUE
  19. )
  20. # %% [markdown]
  21. # # GM12878 heterozygous SNP density map
  22. #
  23. # **Goal:** find the most informative 2 Mb genomic windows for allele-specific
  24. # analyses in GM12878 (NA12878). "Informative" here means *densely populated
  25. # with phased heterozygous SNVs* — these are the only positions where reads can
  26. # actually be assigned to a haplotype, so they bound how much allele-specific
  27. # signal you can recover from any given window.
  28. #
  29. # **Pipeline (cell-by-cell):**
  30. #
  31. # 1. Load the **Illumina Platinum Genomes 2017 NA12878 phased VCF** (hg38).
  32. # - Already statistically phased (`GT` like `0|1` / `1|0`); `PS` tag carries
  33. # the phase set ID.
  34. # 2. **Keep only useful sites:**
  35. # - drop `1|1` homozygous-alt (not informative for haplotype assignment),
  36. # - drop `1|2` / `2|1` triallelic (rare, complicates phasing),
  37. # - drop indels, keep only SNVs (`nchar(ref)==nchar(alt)==1`).
  38. # 3. Convert SNVs → `GRanges`. Convert a pre-computed bed of **10 kb tiling
  39. # bins** of GRCh38 (`GRCh38_ref/GRCh38_10000_windows.bed`) → `GRanges`.
  40. # 4. Overlap SNVs against 10 kb bins → number of phased het SNVs per 10 kb bin.
  41. # Save as `GM12878_10k_snp_counts_summary.txt` and a bedGraph view.
  42. # 5. Build **500 kb tiling bins**, count how many of the 50 child 10-kb bins
  43. # inside each 500 kb bin actually contain ≥1 SNV (i.e. the 10-kb-resolution
  44. # *coverage fraction*, not raw SNV count). Range 0–50.
  45. # 6. **Slide a 4×500 kb (=2 Mb) window with step 500 kb** over the genome,
  46. # compute `mean_value = mean(coverage_fraction across the 4 child bins)`.
  47. # Sort descending → top windows are the genomic regions with the broadest
  48. # spread of phased heterozygous SNVs at 10 kb resolution.
  49. # 7. Save as **`GM12878_2M_10k_snp_density_summary.txt`**.
  50. #
  51. # ## What `GM12878_2M_10k_snp_density_summary.txt` contains
  52. #
  53. # A genome-wide ranking of overlapping 2 Mb windows by SNV-coverage density:
  54. #
  55. # | column | type | meaning |
  56. # |---|---|---|
  57. # | `chrom` | chr | chromosome (chr1–22, chrX) |
  58. # | `start` | int | window start, hg38, 0-based |
  59. # | `end` | int | `start + 2 000 000` |
  60. # | `mean_value` | float | average # of SNV-bearing 10-kb bins per 500 kb sub-bin within this 2 Mb window. Range 0–50; higher = denser SNV coverage = more haplotype-informative window |
  61. #
  62. # Rows are sorted by `mean_value` descending, so `head -n N` gives the top-N
  63. # most SNV-dense 2 Mb windows. Used by `corigami` plan-A/plan-B benchmarks to
  64. # pick the regions where allele-specific Hi-C prediction is even meaningful.
  65. # %%
  66. # Use repository-local phased variants and reference metadata.
  67. repo_root <- normalizePath("..")
  68. vcf_path <- file.path(repo_root, "src/data/variants/illumina_PlatinumGenomes_2017_hg38_NA12878_PS.vcf.gz")
  69. chrom_sizes_path <- file.path(repo_root, "src/data/reference/GRCh38.chrom.sizes")
  70. summary_path <- file.path(repo_root, "src/data/regions/GM12878_2M_10k_snp_density_summary.txt")
  71. snp <- read.table(vcf_path)
  72. # %%
  73. # Standard VCF column layout. The trailing 'sample' column packs the
  74. # per-sample fields described by 'format' (e.g. "GT:PS" → "1|0:1000").
  75. colnames(snp) <- c("chrom","pos","id","ref","alt","qual","filter","info","format","sample")
  76. # %%
  77. # Pull just the genotype string (GT field) out of the packed sample column.
  78. # 'sample' looks like "1|0:1000" where the part before ':' is GT and after ':'
  79. # is the phase set (PS) tag. We only need GT here.
  80. snp$GT <- gsub(":.*","",snp$sample)
  81. # %%
  82. # Sanity check: how many sites of each genotype class?
  83. # 0|1, 1|0 → phased heterozygous (informative for haplotype assignment)
  84. # 1|1 → homozygous-alt (NOT informative — both haplotypes look the same)
  85. # 1|2, 2|1 → phased multi-allelic heterozygous (rare)
  86. table(snp$GT)
  87. # %%
  88. # Drop homozygous-alt (1|1). Reads covering these positions cannot be
  89. # attributed to a specific haplotype because both maternal and paternal
  90. # carry the alt allele. Keep 0|1, 1|0, and the rare 1|2 / 2|1.
  91. snp <- snp[snp$GT != "1|1",]
  92. # %%
  93. # Compute REF / ALT allele lengths so we can keep only single-nucleotide
  94. # substitutions in the next cell. Indels (length != 1) are excluded because:
  95. # 1) downstream tools we use (bcftools consensus / WhatsHap haplotag) handle
  96. # SNVs and indels differently — restricting to SNVs keeps coordinates
  97. # identical between hg38 and the haplotype-resolved consensus,
  98. # 2) indel callsets are noisier than SNV callsets in this VCF.
  99. ref_len <- lapply(1:nrow(snp), function(x) nchar(snp$ref[x])) %>% unlist()
  100. alt_len <- lapply(1:nrow(snp), function(x) nchar(snp$alt[x])) %>% unlist()
  101. # %%
  102. # Keep biallelic SNVs (single base on both REF and ALT). After this filter
  103. # we have ~2.17M phased het SNVs across autosomes + chrX.
  104. snp_used <- snp[ref_len == 1 & alt_len == 1,]
  105. # %%
  106. # Quick visual check of the kept rows.
  107. head(snp_used)
  108. # %%
  109. # Confirm chromosome coverage — autosomes 1–22 + chrX (no chrY in this VCF
  110. # because NA12878 is female, no chrM either).
  111. unique(snp_used$chrom)
  112. # %%
  113. # Convert the SNV table to a GRanges using gUtils::dt2gr.
  114. # dt2gr looks for chrom + (start|pos) + (end|pos) columns; here we only have
  115. # 'pos', so it builds zero-width ranges at each SNV position. The metadata
  116. # columns (ref, alt, GT, ...) ride along as mcols on the GRanges.
  117. library(gUtils)
  118. snp_used_gr <- dt2gr(snp_used)
  119. # %%
  120. # Inspect: should report ~2.17M ranges, 23 sequences (autosomes + X).
  121. snp_used_gr
  122. # %%
  123. # Build 10 kb GRCh38 tiles directly from the uploaded chromosome sizes.
  124. chrom_sizes <- read.table(chrom_sizes_path, col.names = c("chrom", "length"))
  125. seqinfo_hg38 <- Seqinfo(
  126. seqnames = chrom_sizes$chrom,
  127. seqlengths = chrom_sizes$length
  128. )
  129. windows_10k <- tileGenome(
  130. seqinfo_hg38,
  131. tilewidth = 10000,
  132. cut.last.tile.in.chrom = TRUE
  133. )
  134. bins <- as.data.frame(windows_10k)[, c("seqnames", "start", "end")]
  135. colnames(bins) <- c("chrom", "start", "end")
  136. bins$start <- bins$start - 1L
  137. bins$idx <- seq_len(nrow(bins))
  138. # %%
  139. # Convert the generated 10 kb table to the GRanges layout used below.
  140. bins_gr <- dt2gr(bins)
  141. # %%
  142. # Overlap 10 kb bins (query) with SNV positions (subject).
  143. # `gUtils::%*%` is the GRanges-overlap operator: it returns one row per
  144. # (query, subject) pair that overlaps. The result `ov` carries:
  145. # - query.id = bin index that the SNV falls in
  146. # - subject.id = SNV index
  147. # - all original mcols from both sides (ref, alt, GT, idx, ...)
  148. ov <- bins_gr %*% snp_used_gr
  149. # %%
  150. # Inspect: ~2.17M overlap rows. Slightly more rows than total SNVs because
  151. # a bin boundary can split a (zero-width) SNV onto two adjacent bins in
  152. # 1-based vs 0-based coord overlap.
  153. ov
  154. # %%
  155. # Per-bin SNV count: tabulate overlap rows by bin (query.id).
  156. # `Var1` (factor of bin index) is converted back to integer for joining later.
  157. ov_sum <- table(ov$query.id) %>% as.data.frame()
  158. ov_sum$Var1 <- as.integer(as.character(ov_sum$Var1))
  159. # %%
  160. # Join the SNV counts back onto the full set of 10 kb bins so that bins
  161. # WITHOUT any SNV are still represented as rows (with Freq=NA, fixed below).
  162. ov_sum <- left_join(as.data.frame(bins_gr), ov_sum, by = c("idx" = "Var1"))
  163. # %%
  164. # Fill bins with no overlapping SNV: NA -> 0.
  165. ov_sum[is.na(ov_sum$Freq),]$Freq <- 0
  166. # %%
  167. # Plotting library used by the next cell.
  168. library(ggplot2)
  169. # %%
  170. # Quick distribution sanity check: stacked-fill bar showing the fraction of
  171. # 10 kb bins with each integer SNV count (0, 1, 2, ...). Most genome-wide
  172. # bins carry 0 SNVs; the long tail at high counts represents SNV hotspots.
  173. table(ov_sum$Freq) %>%
  174. as.data.frame() %>%
  175. ggplot(., aes(x = "identity", y = Freq)) +
  176. geom_col(aes(fill = Var1), color = "black", position = "fill")
  177. # %%
  178. head(ov_sum)
  179. # %%
  180. # OUTPUT 1: per-10kb-bin SNV count, full table (with chrom/start/end/idx/Freq).
  181. write.table(ov_sum, "./GM12878_10k_snp_counts_summary.txt",
  182. row.names = F, quote = F, sep = '\t')
  183. # %%
  184. # OUTPUT 2: same data as a 4-column bedGraph (chrom, start, end, Freq) so it
  185. # can be loaded directly into IGV/UCSC as a track. Columns 1:3 = coords,
  186. # column 7 of ov_sum = Freq (after as.data.frame(GRanges) the layout is
  187. # seqnames, start, end, width, strand, idx, Freq).
  188. write.table(ov_sum[,c(1:3,7)], "./GM12878_10k_snp_counts_summary.bedGraph",
  189. row.names = F, quote = F, col.names = F, sep = '\t')
  190. # %%
  191. # Sanity: full 10 kb bin GRanges (~309k bins covering all of GRCh38).
  192. bins_gr
  193. # %%
  194. # Subset 10 kb bins to those that contain at least one SNV (~224k bins).
  195. # This is the *coverage set*: each entry is a 10 kb window that we know
  196. # carries phasing information. Used downstream to compute, per 500 kb
  197. # super-bin, how many of its 50 child 10 kb bins are informative.
  198. bin_snp <- bins_gr[unique(ov$query.id)]
  199. # %%
  200. bin_snp
  201. # %%
  202. # Build 500 kb tiles and retain chr1-22 plus chrX.
  203. windows_500k <- tileGenome(
  204. seqinfo_hg38,
  205. tilewidth = 500000,
  206. cut.last.tile.in.chrom = TRUE
  207. )
  208. bins_500k <- as.data.frame(windows_500k)[, c("seqnames", "start", "end")]
  209. colnames(bins_500k) <- c("chrom", "start", "end")
  210. bins_500k$start <- bins_500k$start - 1L
  211. bins_500k <- bins_500k[bins_500k$chrom %in% paste0("chr", c(1:22, "X")), ]
  212. bins_500k$chrom <- factor(bins_500k$chrom, levels = paste0("chr", c(1:22, "X")))
  213. bins_500k <- bins_500k %>% arrange(chrom, start)
  214. bins_500k$idx <- seq_len(nrow(bins_500k))
  215. bins_500k_gr <- dt2gr(bins_500k)
  216. # %%
  217. # For each 500 kb bin, count how many of its child 10 kb bins (from bin_snp)
  218. # carry at least one SNV. The metric we end up with is a *coverage fraction*
  219. # at 10 kb resolution — range 0..50 — not a raw SNV count. This penalises
  220. # 500 kb bins where SNVs are clustered at one spot but absent elsewhere,
  221. # which would otherwise look "rich" if you only counted SNVs.
  222. #
  223. # `filter(width > 1)` drops zero-width adjacency hits at bin boundaries
  224. # (gUtils' overlap operator emits a degenerate width=1 row when only the
  225. # boundary touches; filter to honest interior overlaps).
  226. # `n_distinct(subject.id)` == number of 10 kb bins (subject.id == bin_snp idx)
  227. # that overlap this 500 kb super-bin (query.id == bins_500k_gr idx).
  228. snp_sum <- bins_500k_gr %*% bin_snp %>% as.data.frame() %>%
  229. filter(width > 1) %>%
  230. dplyr::group_by(query.id) %>%
  231. dplyr::summarise(sum = n_distinct(subject.id))
  232. # %%
  233. # Re-attach bin coordinates to the per-bin SNV-coverage count.
  234. snp_sum <- left_join(bins_500k, snp_sum, by = c("idx" = "query.id"))
  235. # %%
  236. # 500 kb bins with no SNV-bearing children: NA -> 0.
  237. snp_sum[is.na(snp_sum$sum),]$sum <- 0
  238. # %%
  239. head(snp_sum)
  240. # %%
  241. # Genome-wide track of SNV-bearing 10 kb bins per 500 kb super-bin.
  242. # Alternating chromosome colours (black/grey, with chrX in dark red) make the
  243. # karyotype layout obvious. Useful eyeball check before sliding-window step.
  244. options(repr.plot.width = 16, repr.plot.height = 2)
  245. library(ggplot2)
  246. ggplot(snp_sum, aes(x = idx, y = sum)) +
  247. geom_point(aes(color = chrom)) +
  248. scale_color_manual(values = c(rep(c("black", "grey"), 11), "darkred")) +
  249. theme_bw() +
  250. theme(axis.text.x = element_blank(), axis.title.x = element_blank()) +
  251. ylab("Number of SNV-bearing 10kb bins per 500kb bin") +
  252. ggtitle("SNV coverage per 500kb bin (NA12878 phased het SNVs)")
  253. # %%
  254. # Re-print head as a sanity check before the sliding-window step.
  255. head(snp_sum)
  256. # %%
  257. library(dplyr)
  258. library(furrr)
  259. library(future.apply)
  260. # ---------------------------------------------------------------------------
  261. # sliding_window_genome
  262. # ---------------------------------------------------------------------------
  263. # Aggregate a per-bin numeric column over a sliding window of consecutive
  264. # bins, separately for each chromosome. With the defaults below
  265. # (window_size = 4, step = 1) and an input of 500 kb tiles, this produces
  266. # overlapping 2 Mb windows stepped every 500 kb. We pick 2 Mb because the
  267. # downstream C.Origami model takes a 2 Mb context per prediction.
  268. #
  269. # Args:
  270. # df : data.frame with required columns chrom / start / end and a
  271. # numeric column to summarise.
  272. # window_size : number of consecutive child bins per output window.
  273. # step : stride (in child-bin units).
  274. # val_col : index of the numeric column in `df` (default 5 -> 'sum').
  275. #
  276. # Returns: data.frame(chrom, start, end, mean_value), one row per window.
  277. sliding_window_genome <- function(df, window_size = 4, step = 1, val_col = 5) {
  278. # Required columns check.
  279. if (!all(c("chrom", "start", "end") %in% colnames(df))) {
  280. stop("input data.frame must contain chrom/start/end columns")
  281. }
  282. # Sort by (chrom, start) so windowing walks each chromosome left-to-right.
  283. df_sorted <- df %>%
  284. arrange(chrom, start) %>%
  285. group_by(chrom) %>%
  286. mutate(row_id = row_number()) %>%
  287. ungroup()
  288. # Per-chromosome window builder. Returns one row per valid window.
  289. process_chrom <- function(sub_df) {
  290. n <- nrow(sub_df)
  291. if (n < window_size) return(data.frame()) # skip chromosomes shorter than 1 window
  292. # Valid window start indices: 1, 1+step, 1+2*step, ... up to (n-window_size+1).
  293. window_starts <- seq(1, n - window_size + 1, by = step)
  294. # Parallelise over windows within a chromosome (future_lapply backend).
  295. future_lapply(window_starts, function(i) {
  296. window_data <- sub_df[i:(i + window_size - 1), ]
  297. data.frame(
  298. chrom = unique(window_data$chrom),
  299. start = min(window_data$start),
  300. end = max(window_data$end),
  301. mean_value = mean(window_data[[val_col]], na.rm = TRUE),
  302. stringsAsFactors = FALSE
  303. )
  304. }) %>% bind_rows()
  305. }
  306. # Split by chromosome, then map per-chromosome processing in parallel
  307. # (future_map_dfr respects the active future::plan).
  308. result <- df_sorted %>%
  309. group_split(chrom) %>%
  310. future_map_dfr(process_chrom, .progress = TRUE)
  311. # If every value in a window was NA, mean(...) returns NaN — convert to NA
  312. # so downstream filters/sorts behave consistently.
  313. result$mean_value[is.nan(result$mean_value)] <- NA
  314. return(result)
  315. }
  316. ### Smoke test ---------------------------------------------------------------
  317. # Tiny synthetic input: two chromosomes, 10 bins each, normal-distributed
  318. # values around two distinct means. Confirms the function returns rolling
  319. # means without dropping rows.
  320. set.seed(123)
  321. test_data <- data.frame(
  322. chrom = rep(c("chr1", "chr2"), each = 10),
  323. start = c(1:10 * 100, 1:10 * 150),
  324. end = c(1:10 * 100 + 99, 1:10 * 150 + 149),
  325. value = c(rnorm(10, mean = 50), rnorm(10, mean = 100))
  326. )
  327. system.time({
  328. output <- sliding_window_genome(test_data, window_size = 4, val_col = 4)
  329. })
  330. print(head(output, 5))
  331. # %%
  332. # Apply the sliding window over the 500 kb SNV-coverage track.
  333. # val_col = 5 picks the 'sum' column (chrom/start/end/idx/sum). Defaults
  334. # window_size=4, step=1 -> 2 Mb windows stepped every 500 kb.
  335. snp_sum_sw <- sliding_window_genome(snp_sum)
  336. # %%
  337. # Sort descending by mean_value: the most SNV-dense 2 Mb windows come first.
  338. # `head -n N` of the output file then gives the top-N windows.
  339. snp_sum_sw <- snp_sum_sw %>% arrange(-mean_value)
  340. # %%
  341. # Top 50 windows. mean_value is "average # of SNV-bearing 10kb bins per
  342. # 500kb sub-bin", so the theoretical max is 50 (every 10kb bin in the
  343. # window carries a SNV). The top windows reach exactly 50 — fully informative.
  344. head(snp_sum_sw, 50)
  345. # %%
  346. # Write the ranked 2 Mb SNP-density regions to the shared repository input.
  347. write.table(snp_sum_sw, summary_path,
  348. row.names = F, quote = F, sep = "\t")

SNP_density.ipynb at commit 61448fc, no license · at the source

Overview

Authors: Jiansen Lu1,2, Kexuan Chen3, Shengtao Jia4, Guodong Chen5, Xianhong Yu5, Wen Li1
ORCID iDs: Wen Li
  1. School of Laboratory Medicine and Biotechnology, Southern Medical University, Guangzhou, Guangdong China
  2. School of Medicine, Jinan University, Guangzhou, Guangdong China
  3. The Second Affiliated Hospital & Liangzhu Laboratory, Zhejiang University School of Medicine, Hangzhou, Zhejiang China
  4. Department of Cardiology, Heart Center, Zhujiang Hospital, Southern Medical University, Guangzhou, Guangdong China
  5. Shanghai MobiDrop Co. Ltd, Shanghai, China
Journal: Cell discovery, volume 12, issue 1, article 72
Dates: received 25 February 2026; accepted 19 August 2026; published online 27 October 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1038/s41421-026-00928-y · PMID 42934226 · PMCID PMC13710847 · OpenAlex W7223706128
Open access: gold, a free copy (OpenAlex)
Status: code verified (how the code is found and verified)
Categories: genetics / omics (modality), mouse (organism), cellular / molecular (subfield)
Methods: Statistics, Smoothing, state filtering, decompositions, Machine learning, Connectivity
Keywords: Chromatin analysis, Histone analysis
Topic: Genomics and Chromatin Dynamics (Molecular Biology, Biochemistry, Genetics and Molecular Biology), according to OpenAlex
Funding: National Natural Science Foundation of China (National Science Foundation of China) (32500741)
Citations: not cited yet (Europe PMC); 58 references in the paper

Abstract

Recently, long-read sequencing methods have revolutionized genomic research by allowing the resolution of previously inaccessible regions across the genome. However, the throughput and scalability of these methods have hindered their general application in the field. To address this limitation, we developed droplet-based methods for the single-cell profiling of chromatin accessibility (droplet-based single-cell Nanopore ATAC-seq, dscNanoATAC) and histone modifications (droplet-based single-cell NanoCUT&Tag, dscNanoCUT) by combining a commercial microfluidic device and long-read sequencing platform, achieving a throughput of ~5000 cells in a single experiment and significantly reducing the time and costs compared with previous techniques. With cultured mammalian cells, we demonstrated the ability of dscNanoATAC and dscNanoCUT to detect allele-specific epigenetics, neighboring co-accessibility, and regulatory elements within low-mappability regions. Furthermore, leveraging the haplotype-resolved data generated from dscNanoATAC, we optimized a deep-learning model to predict allele-specific three-dimensional genome structures with high resolution (10 kb). We also applied dscNanoATAC and dscNanoCUT in complex tissues using the mouse brain as an example, and characterized the allele-specific regulation of the imprinting gene Ube3a in neurons, obtaining insights into the mechanisms underlying the pathogenesis of Prader-Willi and Angelman syndrome. With dscNanoCUT, we systematically evaluated the activity of transposon elements and revealed their potential regulatory functions in the mouse brain. Together, dscNanoATAC and dscNanoCUT serve as a versatile and scalable long-read epigenome sequencing platform, enabling multidimensional analyses of elements ranging from chromatin accessibility to histone modifications and their interplay between chromatin structures. This platform may advance our understanding of epigenetic regulation in complex biological systems.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 8 matches between paragraphs and lines of code.

mskilab-org/gUtils

License: GPL-2.0
State: the link answers, verified on 30 October 2026
Evidence: files inventoried
Commit: 095377ab04195aecf6ebb8397072b24864c81599, 9 July 2026
Languages: R (6), Jupyter (3), Python (1)
Size: 173 files, 10 scripts
Software Heritage: not archived
Found in: the text, “Analysis of peaks in low-mappability regions”
Holds: README, license file, environment (DESCRIPTION), tests, continuous integration, documentation, 3 notebooks
Not found: CITATION.cff
Tools: data.table (2 files), tidyverse (1 file)
Availability: 1 check, the latest on 30 October 2026: the link answers
  • 30 October 2026: the link answers
12 files

LuJiansen/dscNanoSeq

License: MIT
State: the link answers, verified on 30 October 2026
Evidence: files inventoried
Commit: ec0701b9883549c9aeea2bf7ad6c2a2404e6e41d, 16 July 2026
Languages: R (3), Jupyter (1), Shell (1)
Size: 24 files, 5 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, license file, environment (environment.yaml), 1 notebook
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: tidyverse (3 files), cowplot (1 file), data.table (1 file), patchwork (1 file)
Availability: 1 check, the latest on 30 October 2026: the link answers
  • 30 October 2026: the link answers
7 files

Zenodo 15102690

License: CC-BY-4.0
State: the link answers, verified on 30 October 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: “Code availability”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 30 October 2026: the link answers (HTTP 200)
  • 30 October 2026: the link answers (HTTP 200)
At the source:

LuJiansen/AS-C.Origami

License: none: the authors keep all their rights
State: the link answers, verified on 30 October 2026
Evidence: files inventoried
Commit: 61448fc802b69ee2d1a59404f4aa582f106b7bc3, 16 July 2026
Languages: Python (5), Jupyter (3), Shell (3)
Size: 44 files, 11 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, tests, documentation, 3 notebooks
Not found: license file, CITATION.cff, environment file, continuous integration
Tools: ggplot2 (3 files), tidyverse (3 files), cowplot (2 files), data.table (2 files), NumPy (2 files), patchwork (2 files), PyTorch (2 files), reshape2 (2 files), reticulate (2 files), BCFtools (1 file), PyTorch Lightning (1 file), pysam (1 file), SAMtools (1 file)
Availability: 1 check, the latest on 30 October 2026: the link answers
  • 30 October 2026: the link answers
12 files

Zenodo 21389362

License: CC-BY-4.0
State: the link answers, verified on 30 October 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: “Code availability”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: ggplot2 (3 files), tidyverse (3 files), cowplot (2 files), data.table (2 files), NumPy (2 files), patchwork (2 files), PyTorch (2 files), reshape2 (2 files), reticulate (2 files), BCFtools (1 file), PyTorch Lightning (1 file), pysam (1 file), SAMtools (1 file)
Availability: 1 check, the latest on 30 October 2026: the link answers (HTTP 200)
  • 30 October 2026: the link answers (HTTP 200)
12 files
At the source:

Code availability

Code for dscNanoSeq pipeline is available in GitHub (https://github.com/LuJiansen/dscNanoSeq) and Zenodo (https://doi.org/10.5281/zenodo.15102690)57. Code for AS-C.Origami is deposited in GitHub (https://github.com/LuJiansen/AS-C.Origami) and Zenodo (https://doi.org/10.5281/zenodo.21389362)58.

Reproduced under the paper's license (CC BY), from the paper cited above.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 5 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 37 scripts, each with its path and the digest of its content;
  • 8 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Data Availability Statement

The sequencing data of dscNanoATAC and dscNanoCUT have been deposited in the Gene Expression Omnibus under accession code GSE293463.

Code for dscNanoSeq pipeline is available in GitHub (https://github.com/LuJiansen/dscNanoSeq) and Zenodo (https://doi.org/10.5281/zenodo.15102690)57. Code for AS-C.Origami is deposited in GitHub (https://github.com/LuJiansen/AS-C.Origami) and Zenodo (https://doi.org/10.5281/zenodo.21389362)58.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 30 October 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 6 authors, 2 keywords, 1 funder, 58 references.

Cite

This paper

Lu, J., Chen, K., Jia, S., Chen, G., Yu, X., & Li, W. (2026). A droplet-based long-read single-cell epigenome sequencing method for the high-throughput profiling of multidimensional regulatory elements within individual cells. Cell discovery, 12(1), 72. https://doi.org/10.1038/s41421-026-00928-y

BibTeX

@article{lu2026droplet,
author = {Lu, Jiansen and Chen, Kexuan and Jia, Shengtao and Chen, Guodong and Yu, Xianhong and Li, Wen},
title = {{A droplet-based long-read single-cell epigenome sequencing method for the high-throughput profiling of multidimensional regulatory elements within individual cells}},
journal = {Cell discovery},
year = {2026},
month = oct,
volume = {12},
number = {1},
pages = {72},
publisher = {Nature Publishing Group},
issn = {2056-5968},
doi = {10.1038/s41421-026-00928-y},
url = {https://doi.org/10.1038/s41421-026-00928-y},
pmid = {42934226},
pmcid = {PMC13710847}
}

RIS

TY - JOUR
AU - Lu, Jiansen
AU - Chen, Kexuan
AU - Jia, Shengtao
AU - Chen, Guodong
AU - Yu, Xianhong
AU - Li, Wen
TI - A droplet-based long-read single-cell epigenome sequencing method for the high-throughput profiling of multidimensional regulatory elements within individual cells
T2 - Cell discovery
J2 - Cell Discov
PY - 2026
DA - 2026/10/27
VL - 12
IS - 1
SP - 72
SN - 2056-5968
PB - Nature Publishing Group
DO - 10.1038/s41421-026-00928-y
UR - https://doi.org/10.1038/s41421-026-00928-y
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41421-026-00928-y",
"type": "article-journal",
"title": "A droplet-based long-read single-cell epigenome sequencing method for the high-throughput profiling of multidimensional regulatory elements within individual cells",
"container-title": "Cell discovery",
"author": [
{
"family": "Lu",
"given": "Jiansen"
},
{
"family": "Chen",
"given": "Kexuan"
},
{
"family": "Jia",
"given": "Shengtao"
},
{
"family": "Chen",
"given": "Guodong"
},
{
"family": "Yu",
"given": "Xianhong"
},
{
"family": "Li",
"given": "Wen"
}
],
"container-title-short": "Cell Discov",
"volume": "12",
"issue": "1",
"page": "72",
"DOI": "10.1038/s41421-026-00928-y",
"PMID": "42934226",
"PMCID": "PMC13710847",
"ISSN": "2056-5968",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s41421-026-00928-y",
"language": "en",
"issued": {
"date-parts": [
[
2026,
10,
27
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1038/s41594-023-01060-1 [code]
Droplet-based single-cell joint profiling of histone modifications and transcriptomes.
Journal: Nature structural & molecular biology
In common: pysam, SAMtools, patchwork, 5 other tools, genetics / omics, cellular / molecular, 10 references
[2] doi:10.1038/s41593-026-02208-0 [code]
Single-nucleus epigenomic profiling of the adult human central nervous system unveils epigenetic memory of developmental programs.
Journal: Nature neuroscience
In common: pysam, reticulate, SAMtools, 4 other tools, genetics / omics, 10 references
[3] doi:10.1038/s41587-024-02447-1 [code]
Droplet Hi-C enables scalable, single-cell profiling of chromatin architecture in heterogeneous tissues.
Journal: Nature biotechnology
In common: SAMtools, patchwork, cowplot, 6 other tools, genetics / omics, mouse, cellular / molecular, 7 references
[4] doi:10.1038/s41467-024-52463-7 [code]
A cell type-aware framework for nominating non-coding variants in Mendelian regulatory disorders.
Journal: Nature communications
In common: BCFtools, pysam, SAMtools, 8 other tools, genetics / omics, mouse, cellular / molecular, 5 references
[5] doi:10.1038/s41421-023-00642-z [code]
Fast and flexible profiling of chromatin accessibility and total RNA expression in single nuclei using Microwell-seq3.
Journal: Cell discovery
In common: BCFtools, pysam, SAMtools, 6 other tools, genetics / omics, mouse, cellular / molecular, 6 references
[6] doi:10.1038/s41467-025-57027-x [code]
Topological identification and interpretation for single-cell epigenetic regulation elucidation in multi-tasks using scAGDE.
Journal: Nature communications
In common: PyTorch Lightning, reticulate, patchwork, 7 other tools, genetics / omics, cellular / molecular, 6 references
[7] doi:10.1038/s41587-022-01535-4 [code]
Multimodal chromatin profiling using nanobody-based single-cell CUT&Tag.
Journal: Nature biotechnology
In common: pysam, reticulate, SAMtools, 5 other tools, genetics / omics, mouse, cellular / molecular, 6 references
[8] doi:10.21203/rs.3.rs-9927928/v1 [code]
Genome-wide and allele-resolved maps of the radial architecture of the mouse genome
Journal: Research Square (preprint)
In common: BCFtools, pysam, SAMtools, 7 other tools, genetics / omics, mouse, 3 references
[9] doi:10.1016/j.xgen.2026.101194 [code]
Genetic diversity and regulatory features of human-specific NOTCH2NL duplications.
Journal: Cell genomics
In common: PyTorch Lightning, pysam, SAMtools, 8 other tools, cellular / molecular, 3 references
[10] doi:10.1038/s41586-023-06824-9 [code]
Single-cell analysis of chromatin accessibility in the adult mouse brain.
Journal: Nature
In common: reticulate, patchwork, cowplot, 5 other tools, genetics / omics, mouse, cellular / molecular, 6 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/doi/10.1038/s41421-026-00928-y.svg)](https://openscicode.org/badge/doi/10.1038/s41421-026-00928-y)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/doi/10.1038/s41421-026-00928-y.svg
   :target: https://openscicode.org/badge/doi/10.1038/s41421-026-00928-y
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.1038/s41421-026-00928-y"><img src="https://openscicode.org/badge/doi/10.1038/s41421-026-00928-y.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

On GitHub, open the README, choose Edit (the pencil), paste the snippet under the title, then "Commit changes".

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.