OSCR

Single-Nucleus Transcriptomic Mapping Reveals Correlative Microglial Changes Associated with rTMS in the Motor Cortex After Spinal Cord Injury.

Code ↔ Paper

2 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 2 matches
  1. [1] § Materials and Methods › SnRNA-Seq Data Processing and Analysis Pipeline ↔ lib/python/cellranger/analysis/batch_correction.py, lines 20–103 · score 0.51 · principal component, batch, fewer, dimensionality, matrices, Cell
  2. [2] § Materials and Methods › SnRNA-Seq Data Processing and Analysis Pipeline ↔ lib/python/cellranger/websummary/web_summary_builder.py, lines 433–520 · score 0.51 · Cell Ranger, SNE, batch, gene expression, pipeline, genome

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 200 lines · 8.4 KB · MIT · 1 match

  1. #!/usr/bin/env python
  2. #
  3. # Copyright (c) 2018 10x Genomics, Inc. All rights reserved.
  4. #
  5. """Library functions for performing batch correction."""
  6. from __future__ import annotations
  7. import struct
  8. from collections import Counter
  9. import numpy as np
  10. import sklearn.neighbors as sk_neighbors
  11. from sklearn.metrics.pairwise import rbf_kernel
  12. DEFAULT_BALLTREE_LEAFSIZE = 40
  13. def batch_effect_score(
  14. dimred_matrix: np.ndarray[tuple[int, int], np.dtype[np.float64]],
  15. batch_ids: np.ndarray[int, np.dtype[np.bytes_]],
  16. knn_neighbors: int | None = None,
  17. knn_frac: float | None = 0.01,
  18. max_num_bcs: int | None = 10000,
  19. ):
  20. """Compute batch effect score on an aggregated dimension-reduced matrix.
  21. The batch effect score quantifies the degree of separation between groups of barcodes (batches).
  22. For each barcode, the fraction of its k-nearest neighbors with the same batch id is calculated.
  23. Local batch scores are computed by scaling and shifting the same-batch fractions to be strictly
  24. less than the number of batches and have expectation equal to 1 under identical batches.
  25. Finally, the average of these local batch scores is computed to obtain the overall batch effect
  26. score. A batch score of 1 indicates no separation between batches, and a batch score equal to
  27. the number of batches indicates perfect separation. A batch score less than 1 may occur in rare
  28. cases and is consistent with no batch separation.
  29. Args:
  30. dimred_matrix (np.ndarray[tuple[int, int], np.dtype[np.float64]]): dimension reduced matrix.
  31. Rows are samples and columns are features (e.g. principal components)
  32. batch_ids (np.ndarray[int, np.dtype[np.string_]]): 1-D array of batch IDs. Must have at
  33. least 2 observations per batch
  34. knn_frac (Optional[float], optional): Sets k in the k-nearest neighbors calculation to a
  35. fraction of the total barcodes (after subsampling to max_num_bcs). Defaults to 0.01.
  36. max_num_bcs (Optional[int], optional): Maximum number of barcodes to use. Larger data sets
  37. will be subsampled. Defaults to 10000.
  38. knn_neighbors (Optional[int], optional): Use a fixed k rather than knn_frac
  39. """
  40. if knn_neighbors is None and knn_frac is None:
  41. raise ValueError("One of knn_neighbors or knn_frac must be specified")
  42. num_bcs = dimred_matrix.shape[0]
  43. if num_bcs != len(batch_ids):
  44. raise ValueError("Length of batch_ids must equal number of rows in dimred_matrix")
  45. batch_counts_orig = Counter(batch_ids)
  46. # subsample barcodes if greater than the specified max_num_bcs
  47. if max_num_bcs is not None and num_bcs > max_num_bcs:
  48. np.random.seed(0)
  49. select_bc_idx = np.random.choice(num_bcs, max_num_bcs)
  50. select_bc_idx.sort()
  51. dimred_matrix = dimred_matrix[select_bc_idx]
  52. batch_ids = batch_ids[select_bc_idx]
  53. num_bcs = dimred_matrix.shape[0]
  54. # Return NaN if we completely dropped any batch or if not enough data
  55. # NOTE: this can happen due to subsampling but only for severely imbalanced cases,
  56. # e.g. 10,000x more cells in batch 1 vs 2)
  57. batch_counts = Counter(batch_ids)
  58. if len(batch_counts) != len(batch_counts_orig) or min(batch_counts.values()) < 2:
  59. return np.nan
  60. if knn_neighbors is not None:
  61. num_neighbors = knn_neighbors
  62. else:
  63. num_neighbors = int(np.ceil(knn_frac * num_bcs))
  64. # For a cell in a given batch, what fraction of other cells share the same batch?
  65. # This is the expectation of same_batch_frac below, given the null of identical batch mixing
  66. batch_counts = Counter(batch_ids)
  67. num_batches = len(batch_counts)
  68. batch_to_frac = {batch: (count - 1) / (num_bcs - 1) for batch, count in batch_counts.items()}
  69. null_same_batch_frac = np.fromiter((batch_to_frac[i] for i in batch_ids), dtype=np.float64)
  70. # What is largest that same_batch_frac can be? Correction only relevant for very small batches
  71. # (e.g. 10k total cells, 100 or fewer cells in a single batch)
  72. batch_to_max_frac = {
  73. batch: min(count - 1, num_neighbors) / num_neighbors
  74. for batch, count in batch_counts.items()
  75. }
  76. max_same_batch_frac = np.fromiter((batch_to_max_frac[i] for i in batch_ids), dtype=np.float64)
  77. balltree = sk_neighbors.BallTree(dimred_matrix, leaf_size=DEFAULT_BALLTREE_LEAFSIZE)
  78. knn_idx = balltree.query(dimred_matrix, k=num_neighbors + 1, return_distance=False)
  79. same_batch_frac = np.mean(batch_ids[:, None] == batch_ids[knn_idx[:, 1:]], axis=1)
  80. # for identical batches, local_batch_score is equal to null_same_batch_frac in expectation
  81. # we rescale to be between 1 and num_batches
  82. local_batch_score = 1 + (num_batches - 1) * (same_batch_frac - null_same_batch_frac) / (
  83. max_same_batch_frac - null_same_batch_frac
  84. )
  85. return np.mean(local_batch_score)
  86. def find_knn(curr_matrix, ref_matrix, knn):
  87. """For each row in curr_matrix, find k nearest neighbors in ref_matrix,.
  88. return an array of shape=[curr_matrix.shape[0] * knn, ], which stores
  89. the index of nearest neighbors in ref_matrix
  90. """
  91. balltree = sk_neighbors.BallTree(ref_matrix, leaf_size=DEFAULT_BALLTREE_LEAFSIZE)
  92. num_neighbors = min(ref_matrix.shape[0], knn)
  93. nn_idx = balltree.query(curr_matrix, k=num_neighbors, return_distance=False)
  94. return nn_idx.ravel().astype(int)
  95. def serialize_batch_nearest_neighbor(fp, batch_nearest_neighbor):
  96. for (a, b), s in batch_nearest_neighbor.items():
  97. fp.write(struct.pack("qqQ", a, b, len(s)))
  98. for i, j in s:
  99. fp.write(struct.pack("qq", i, j))
  100. def deserialize_batch_nearest_neighbor(fp):
  101. """>>> from cStringIO import StringIO.
  102. >>> batch1 = dict()
  103. >>> batch1[(0, 1)] = set([(1, 2), (3, 4), (5, 6)])
  104. >>> batch1[(1, 2)] = set([(7, 8), (9, 10)])
  105. >>> batch1[(3, 4)] = set([(11, 12)])
  106. >>> fp = StringIO()
  107. >>> serialize_batch_nearest_neighbor(fp, batch1)
  108. >>> fp.seek(0)
  109. >>> batch2 = deserialize_batch_nearest_neighbor(fp)
  110. >>> batch1 == batch2
  111. True
  112. """
  113. batch_nearest_neighbor = {}
  114. while True:
  115. fmt = "qqQ"
  116. sz = struct.calcsize("qqQ")
  117. buf = fp.read(sz)
  118. if len(buf) == 0:
  119. break
  120. elif len(buf) != sz:
  121. raise RuntimeError("corrupted batch_nearest_neighbor stream (key)")
  122. a, b, slen = struct.unpack(fmt, buf)
  123. fmt = "qq"
  124. sz = struct.calcsize("qq")
  125. s = set()
  126. for _ in range(slen):
  127. buf = fp.read(sz)
  128. if len(buf) != sz:
  129. raise RuntimeError("corrupted batch_nearest_neighbor stream (set)")
  130. i, j = struct.unpack(fmt, buf)
  131. s.add((i, j))
  132. batch_nearest_neighbor[(a, b)] = s
  133. return batch_nearest_neighbor
  134. def correction_vector(dimred_matrix, cur_submatrix_idx, mnn_cur_idx, mnn_ref_idx, sigma):
  135. """Compute the batch-correction vector.
  136. 1. For each MNN pair in current dataset and the reference, a pair-specific
  137. batch-correction vector is computed as the vector difference between the
  138. paired cells.
  139. 2. For each barcode in cur dataset, a batch-correction vector is calculated
  140. as a weighted average of these pair-specific vectors, as computed with a
  141. Gaussian kernel.
  142. """
  143. num_pcs = dimred_matrix.shape[1]
  144. corr_vector = np.zeros((0, num_pcs))
  145. # the number of mnn and submatrix dim might be very large, process by chunk to save memory
  146. cur_submatrix_size = len(cur_submatrix_idx)
  147. mnn_size = len(mnn_cur_idx)
  148. # based on empirical testing
  149. cur_submatrix_chunk_size = int(1e6 / num_pcs)
  150. mnn_chunk_size = int(2e7 / num_pcs)
  151. for i in range(0, cur_submatrix_size, cur_submatrix_chunk_size):
  152. cur_submatrix_chunk = cur_submatrix_idx[i : i + cur_submatrix_chunk_size]
  153. cur_submatrix = dimred_matrix[cur_submatrix_chunk]
  154. weighted_sum, weights_sum = np.zeros(cur_submatrix.shape), np.zeros(cur_submatrix.shape)
  155. for j in range(0, mnn_size, mnn_chunk_size):
  156. mnn_cur_chunk = mnn_cur_idx[j : j + mnn_chunk_size]
  157. mnn_ref_chunk = mnn_ref_idx[j : j + mnn_chunk_size]
  158. mnn_cur = dimred_matrix[mnn_cur_chunk]
  159. weights = rbf_kernel(cur_submatrix, mnn_cur, gamma=0.5 * sigma)
  160. bias = dimred_matrix[mnn_ref_chunk] - mnn_cur
  161. weighted_sum += np.dot(weights, bias)
  162. weights_sum += np.tile(np.sum(weights, axis=1), (num_pcs, 1)).T
  163. corr_vector = np.vstack((corr_vector, weighted_sum / weights_sum))
  164. return corr_vector

batch_correction.py at commit 669395e, under MIT · at the source

Overview

Authors: Kunlong Zhang1, Xinjiang Yang1,2,3, Ruibin Hou1, Rui Zhao1,2,3, Dongjin Li1, Hancheng Liao1, Fei Tian1, Xiaolong Sun1,2, Hua Yuan1
  1. Department of Rehabilitation Medicine, Xijing Hospital, Fourth Military Medical University, Xi’an, People’s Republic of China
  2. Military Medical Innovation Center, Fourth Military Medical University, Xi’an, People’s Republic of China
  3. Department of Neurobiology, School of Basic Medicine, Fourth Military Medical University, Xi’an, People’s Republic of China
Institutions: Xijing Hospital (China); Air Force Medical University (China)
Journal: Journal of inflammation research, volume 19, article 633117
Dates: received 29 June 2026; accepted 21 August 2026; published online 16 September 2026
Type: Research article · Language: English
License: CC BY-NC
Identifiers: DOI 10.2147/jir.s633117 · PMID 42765051 · PMCID PMC13590002 · OpenAlex W7213351875
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: genetics / omics (modality), other (modality), mouse (organism), other condition (population), pain (population), cellular / molecular (subfield)
Methods: Statistics, Smoothing, state filtering, decompositions
Keywords: spinal cord injury, microglia, neuroinflammation, repetitive transcranial magnetic stimulation, neuropathic pain, snRNA-seq
Topic: Pain Mechanisms and Treatments (Physiology, Medicine), according to OpenAlex
Funding: National Natural Science Foundation of China; Shaanxi Provincial Key Research and Development Program
Citations: not cited yet (Europe PMC); 41 references in the paper

Abstract

Background: Spinal cord injury (SCI)-associated neuropathic pain (NP) is a severely disabling complication with limited treatment options. Although spinal microglial activation is well documented in SCI-NP, the functional role of microglia in the primary motor cortex (M1) and their response to repetitive transcranial magnetic stimulation (rTMS) remain poorly understood.

Methods: Single-nucleus RNA sequencing (snRNA-seq) was performed on M1 tissues from Sham, SCI, and SCI+rTMS mice to identify transcriptionally distinct microglial states. Differential expression analysis, GO/KEGG pathway enrichment, and CellChat-based cell-cell communication mapping were used to characterize phenotypic changes, key signaling pathways, and intercellular crosstalk underlying microglial responses to SCI and rTMS. Real Time Quantitative PCR (RT-qPCR) and immunofluorescence were employed to validate microglial marker expression. Behavioral assessments included the Basso Mouse Scale (BMS) for locomotor function, as well as von Frey and Hargreaves tests to evaluate mechanical allodynia and thermal hyperalgesia.

Results: SCI did not alter overall cellular composition in the M1 cortex but was associated with microglial transcriptional changes suggesting transformation toward a pro-inflammatory state, with the CX3C pathway identified as a potential mediator. Whereas rTMS was correlated with a shift toward an anti-inflammatory/repair state. These findings were validated by iNOS/Arg1 and Aif1/Cx3cr1 immunofluorescence, RT-qPCR, and behavioral assays, which together were consistent with SCI severity and rTMS-associated analgesia.

Conclusion: Our snRNA-seq analysis identifies M1 cortical microglial transcriptional and communication changes that correlate with SCI-induced NP. rTMS correlates with reduced pro-inflammatory microglial signaling and enhanced repair-associated transcriptional programs. However, as these findings are correlational and do not establish causation, they provide a hypothesis-generating preclinical foundation for future mechanistic studies targeting cortical microglia with rTMS.

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

Repository

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

10XGenomics/cellranger

License: MIT
State: the link answers, verified on 26 September 2026
Evidence: files inventoried
Commit: 669395e208db7ce03354091e271d893074294d28, 16 July 2026
Languages: Rust (414), Python (302), Go (37), TypeScript (31), C (1), JavaScript (1), Shell (1)
Size: 1,007 files, 787 scripts
Software Heritage: not archived
Found in: the text, “SnRNA-Seq Data Processing and Analysis Pipeline”
Holds: README, license file, tests, continuous integration
Not found: CITATION.cff, environment file, documentation
Tools: NumPy (90 files), pandas (30 files), SciPy (24 files), h5py (20 files), scikit-learn (9 files), Pillow (6 files), OpenCV (3 files), pysam (3 files), scikit-image (2 files), Plotly (1 file), statsmodels (1 file)
Availability: 1 check, the latest on 26 September 2026: the link answers
  • 26 September 2026: the link answers
789 files

The paper's code and data availability statement is in the Data section.

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:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 787 scripts, each with its path and the digest of its content;
  • 2 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 Sharing Statement

The RNA-Seq data used in this study have been deposited in the NCBI’s Sequence Read Archive (SRA) (SRA study accession code, PRJNA1299693; https://dataview.ncbi.nlm.nih.gov/object/PRJNA1299693). Additional data that support the findings of this study are available from the corresponding authors upon reasonable request.

Reproduced under the paper's license (CC BY-NC), 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, 27 September 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 9 authors, 6 keywords, 2 funders, 40 references.

Cite

This paper

Zhang, K., Yang, X., Hou, R., Zhao, R., Li, D., Liao, H., Tian, F., Sun, X., & Yuan, H. (2026). Single-Nucleus Transcriptomic Mapping Reveals Correlative Microglial Changes Associated with rTMS in the Motor Cortex After Spinal Cord Injury. Journal of inflammation research, 19, 633117. https://doi.org/10.2147/jir.s633117

BibTeX

@article{zhang2026single,
author = {Zhang, Kunlong and Yang, Xinjiang and Hou, Ruibin and Zhao, Rui and Li, Dongjin and Liao, Hancheng and Tian, Fei and Sun, Xiaolong and Yuan, Hua},
title = {{Single-Nucleus Transcriptomic Mapping Reveals Correlative Microglial Changes Associated with rTMS in the Motor Cortex After Spinal Cord Injury}},
journal = {Journal of inflammation research},
year = {2026},
month = sep,
volume = {19},
pages = {633117},
publisher = {Dove Press},
issn = {1178-7031},
doi = {10.2147/jir.s633117},
url = {https://doi.org/10.2147/jir.s633117},
pmid = {42765051},
pmcid = {PMC13590002}
}

RIS

TY - JOUR
AU - Zhang, Kunlong
AU - Yang, Xinjiang
AU - Hou, Ruibin
AU - Zhao, Rui
AU - Li, Dongjin
AU - Liao, Hancheng
AU - Tian, Fei
AU - Sun, Xiaolong
AU - Yuan, Hua
TI - Single-Nucleus Transcriptomic Mapping Reveals Correlative Microglial Changes Associated with rTMS in the Motor Cortex After Spinal Cord Injury
T2 - Journal of inflammation research
J2 - J Inflamm Res
PY - 2026
DA - 2026/09/16
VL - 19
SP - 633117
SN - 1178-7031
PB - Dove Press
DO - 10.2147/jir.s633117
UR - https://doi.org/10.2147/jir.s633117
LA - en
ER -

CSL-JSON

{
"id": "10.2147/jir.s633117",
"type": "article-journal",
"title": "Single-Nucleus Transcriptomic Mapping Reveals Correlative Microglial Changes Associated with rTMS in the Motor Cortex After Spinal Cord Injury",
"container-title": "Journal of inflammation research",
"author": [
{
"family": "Zhang",
"given": "Kunlong"
},
{
"family": "Yang",
"given": "Xinjiang"
},
{
"family": "Hou",
"given": "Ruibin"
},
{
"family": "Zhao",
"given": "Rui"
},
{
"family": "Li",
"given": "Dongjin"
},
{
"family": "Liao",
"given": "Hancheng"
},
{
"family": "Tian",
"given": "Fei"
},
{
"family": "Sun",
"given": "Xiaolong"
},
{
"family": "Yuan",
"given": "Hua"
}
],
"container-title-short": "J Inflamm Res",
"volume": "19",
"page": "633117",
"DOI": "10.2147/jir.s633117",
"PMID": "42765051",
"PMCID": "PMC13590002",
"ISSN": "1178-7031",
"publisher": "Dove Press",
"URL": "https://doi.org/10.2147/jir.s633117",
"language": "en",
"issued": {
"date-parts": [
[
2026,
9,
16
]
]
}
}

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.1016/j.isci.2026.116825 [code]
Social hierarchy shapes behavioral and transcriptional responses to chronic stress and ketamine in male mice.
Journal: iScience
In common: Plotly, OpenCV, scikit-image, 7 other tools, genetics / omics, mouse
[2] doi:10.1002/imt2.70163 [code]
Spatial multi-omics unveils sphingolipid metabolic reprogramming within the retinal pathological niche.
Journal: iMeta
In common: Plotly, OpenCV, scikit-image, 5 other tools, genetics / omics, mouse, cellular / molecular, 1 reference
[3] doi:10.1038/s41598-026-57519-w [code]
Automated segmentation of neurons and spinal cord structures in immunofluorescence images using SpineDL.
Journal: Scientific reports
In common: Plotly, OpenCV, scikit-image, 6 other tools, other condition, mouse
[4] doi:10.1186/s13059-026-04177-w [code]
Genomic sequence evolution underlying human neocortical interareal diversification.
Journal: Genome biology
In common: pysam, Plotly, OpenCV, 5 other tools, genetics / omics, mouse, cellular / molecular
[5] doi:10.1002/alz.71649 [code]
Postmortem brain MRI reveals differential associations of subcortical and limbic volumes with cortical thinning and neurodegenerative pathologies.
Journal: Alzheimer's & dementia : the journal of the Alzheimer's Association
In common: Plotly, OpenCV, scikit-image, 6 other tools, other condition, cellular / molecular
[6] doi:10.1038/s42003-026-10957-8 [code]
Brain defence by the extracellular matrix protein Cochlin.
Journal: Communications biology
In common: Plotly, OpenCV, scikit-image, 6 other tools, mouse, cellular / molecular
[7] doi: [code]
Real-time closed-loop feedback system for mouse mesoscale cortical signal and movement control
Journal: eLife
In common: OpenCV, scikit-image, h5py, 6 other tools, mouse
[8] doi:10.7554/elife.109717 [code]
Retrosplenial cortex enables context-dependent goal-directed sensorimotor transformation.
Journal: eLife
In common: OpenCV, scikit-image, h5py, 6 other tools, mouse
[9] doi:10.1038/s41593-026-02232-0 [code]
Entorhinal cortex represents task-relevant remote locations independently of CA1.
Journal: Nature neuroscience
In common: OpenCV, scikit-image, h5py, 6 other tools, mouse
[10] doi:10.1038/s41586-026-10348-3 [code]
An enteric neuron ionotropic receptor regulates salt stress resistance.
Journal: Nature
In common: OpenCV, scikit-image, h5py, 6 other tools, cellular / molecular

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.

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: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

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