OSCR

Mapping the transcriptional diversity of calcium signaling in the mouse and human brain.

Code ↔ Paper

13 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 13 matches · 2 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
  1. [1] § STAR★Methods › Method details › Random forest classifier construction ↔ optuna/terminator/callback.py, lines 26–85 · score 0.83 · random forest classifiers, n_splits, cross validation, n_trials, Optuna, folds
  2. [2] § STAR★Methods › Method details › Gene regulatory network analysis ↔ src/pyscenic/utils.py, lines 267–399 · score 0.81 · pySCENIC, TF target gene, network inference, pipeline, Genes expressed, regulon
  3. [3] § STAR★Methods › Method details › Random forest classifier construction ↔ optuna/terminator/terminator.py, lines 33–145 · score 0.79 · random forest classifiers, n_splits, cross validation, Optuna, folds, optimization
  4. [4] § STAR★Methods › Method details › Characterization of mouse Ca2+-states ↔ scFates/tools/cluster.py, the whole file · a weak match · score 0.69 · Leiden algorithm, nearest neighbors, Scanpy, resolution, iterations, graph
  5. [5] § STAR★Methods › Method details › Gene regulatory network analysis ↔ src/pyscenic/transform.py, lines 152–264 · score 0.68 · nes_threshold, auc_threshold, kept, pySCENIC, regulon, TF
  6. [6] § STAR★Methods › Method details › Selection of Ca2+-genes ↔ gget/gget_cellxgene.py, lines 58–112 · score 0.67 · Mus musculus, Homo sapiens, diseases, Ontology, canonical, Gene
  7. [7] § STAR★Methods › Method details › Lineage inference in mouse adult brain ↔ src/scanpy/neighbors/_bbknn.py, lines 41–100 · score 0.66 · n_pcs, n_neighbors, Leiden, KNN, built, pp
  8. [8] § STAR★Methods › Method details › Lineage inference in mouse adult brain ↔ scFates/tools/cluster.py, the whole file · a weak match · score 0.66 · n_pcs, n_neighbors, Leiden, resolution, pp, weighting
  9. [9] § STAR★Methods › Method details › Pseudotemporal and bifurcation analysis ↔ scFates/tools/conversion.py, lines 12–75 · score 0.64 · scFates, principal tree, ppt, tl, pseudotemporal, fitted
  10. [10] § STAR★Methods › Method details › Selection of Ca2+-genes ↔ gget/gget_search.py, lines 72–124 · score 0.62 · Mus musculus, Homo sapiens, Database, Gene
  11. [11] § STAR★Methods › Method details › Characterization of human Ca2+-states ↔ src/pyscenic/utils.py, lines 267–399 · score 0.56 · correlation coefficients, Pearson correlations, cell
  12. [12] § STAR★Methods › Method details › Ca2+-state versus cell type discrimination ↔ src/scanpy/plotting/legacy/_anndata.py, lines 582–716 · score 0.55 · principal component, variable genes, Scanpy, PCA, PCs
  13. [13] § STAR★Methods › Method details › Ca2+-state versus cell type discrimination ↔ src/scanpy/experimental/pp/_normalization.py, lines 165–265 · score 0.54 · principal component, variable genes, PCA, PCs, scanpy

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 · 456 lines · 18 KB · GPL-3.0 · 2 matches

  1. # -*- coding: utf-8 -*-
  2. from functools import partial
  3. from itertools import chain
  4. from typing import Sequence, Type
  5. from urllib.parse import urljoin
  6. import numpy as np
  7. import pandas as pd
  8. from ctxcore.genesig import GeneSignature, Regulon, openfile
  9. from yaml import dump, load
  10. from .math import masked_rho4pairs
  11. try:
  12. from yaml import CDumper as Dumper
  13. from yaml import CLoader as Loader
  14. except ImportError:
  15. from yaml import Loader, Dumper
  16. import logging
  17. LOGGER = logging.getLogger(__name__)
  18. COLUMN_NAME_TF = "TF"
  19. COLUMN_NAME_MOTIF_ID = "MotifID"
  20. COLUMN_NAME_MOTIF_SIMILARITY_QVALUE = "MotifSimilarityQvalue"
  21. COLUMN_NAME_ORTHOLOGOUS_IDENTITY = "OrthologousIdentity"
  22. COLUMN_NAME_ANNOTATION = "Annotation"
  23. def load_motif_annotations(
  24. fname: str,
  25. column_names=(
  26. "#motif_id",
  27. "gene_name",
  28. "motif_similarity_qvalue",
  29. "orthologous_identity",
  30. "description",
  31. ),
  32. motif_similarity_fdr: float = 0.001,
  33. orthologous_identity_threshold: float = 0.0,
  34. ) -> pd.DataFrame:
  35. """
  36. Load motif annotations from a motif2TF snapshot.
  37. :param fname: the snapshot taken from motif2TF.
  38. :param column_names: the names of the columns in the snapshot to load.
  39. :param motif_similarity_fdr: The maximum False Discovery Rate to find factor annotations for enriched motifs.
  40. :param orthologuous_identity_threshold: The minimum orthologuous identity to find factor annotations
  41. for enriched motifs.
  42. :return: A dataframe.
  43. """
  44. # Create a MultiIndex for the index combining unique gene name and motif ID. This should facilitate
  45. # later merging.
  46. df = pd.read_csv(fname, sep="\t", index_col=[1, 0], usecols=column_names)
  47. df.index.names = [COLUMN_NAME_TF, COLUMN_NAME_MOTIF_ID]
  48. df.rename(
  49. columns={
  50. "motif_similarity_qvalue": COLUMN_NAME_MOTIF_SIMILARITY_QVALUE,
  51. "orthologous_identity": COLUMN_NAME_ORTHOLOGOUS_IDENTITY,
  52. "description": COLUMN_NAME_ANNOTATION,
  53. },
  54. inplace=True,
  55. )
  56. df = df[
  57. (df[COLUMN_NAME_MOTIF_SIMILARITY_QVALUE] <= motif_similarity_fdr)
  58. & (df[COLUMN_NAME_ORTHOLOGOUS_IDENTITY] >= orthologous_identity_threshold)
  59. ]
  60. return df
  61. COLUMN_NAME_TARGET = "target"
  62. COLUMN_NAME_WEIGHT = "importance"
  63. COLUMN_NAME_REGULATION = "regulation"
  64. COLUMN_NAME_CORRELATION = "rho"
  65. RHO_THRESHOLD = 0.03
  66. def _create_idx_pairs(adjacencies: pd.DataFrame, exp_mtx: pd.DataFrame) -> np.ndarray:
  67. """
  68. :precondition: The column index of the exp_mtx should be sorted in ascending order.
  69. `exp_mtx = exp_mtx.sort_index(axis=1)`
  70. """
  71. # Create sorted list of genes that take part in a TF-target link.
  72. genes = set(adjacencies.TF).union(set(adjacencies.target))
  73. sorted_genes = sorted(genes)
  74. # Find column idx in the expression matrix of each gene that takes part in a link. Having the column index of genes
  75. # sorted as well as the list of link genes makes sure that we can map indexes back to genes! This only works if
  76. # all genes we are looking for are part of the expression matrix.
  77. assert len(set(exp_mtx.columns).intersection(genes)) == len(genes)
  78. symbol2idx = dict(
  79. zip(sorted_genes, np.nonzero(exp_mtx.columns.isin(sorted_genes))[0])
  80. )
  81. # Create numpy array of idx pairs.
  82. return np.array(
  83. [
  84. [symbol2idx[s1], symbol2idx[s2]]
  85. for s1, s2 in zip(adjacencies.TF, adjacencies.target)
  86. ]
  87. )
  88. def add_correlation(
  89. adjacencies: pd.DataFrame,
  90. ex_mtx: pd.DataFrame,
  91. rho_threshold=RHO_THRESHOLD,
  92. mask_dropouts=False,
  93. ) -> pd.DataFrame:
  94. """
  95. Add correlation in expression levels between target and factor.
  96. :param adjacencies: The dataframe with the TF-target links.
  97. :param ex_mtx: The expression matrix (n_cells x n_genes).
  98. :param rho_threshold: The threshold on the correlation to decide if a target gene is activated
  99. (rho > `rho_threshold`) or repressed (rho < -`rho_threshold`).
  100. :param mask_dropouts: Do not use cells in which either the expression of the TF or the target gene is 0 when
  101. calculating the correlation between a TF-target pair.
  102. :return: The adjacencies dataframe with an extra column.
  103. """
  104. assert rho_threshold > 0, "rho_threshold should be greater than 0."
  105. # TODO: Use Spearman correlation instead of Pearson correlation coefficient: Using a non-parametric test like
  106. # Spearman rank correlation makes much more sense because we want to capture monotonic and not specifically linear
  107. # relationships between TF and target genes.
  108. # Assessment of best optimization strategy for calculating dropout masked correlations between TF-target expression:
  109. #
  110. # Measurement of time performance of masked_rho (with numba JIT): 136 µs ± 932 ns for a single pair of vectors.
  111. # For a typical dataset this translates into (for a single core):
  112. # 1. Calculating the rectangular (TFxtarget) correlation matrix:
  113. # (1,564 TFs * 19,812 targets * 136 microseconds * 10e-6)/3600.0 ~ 12 hours.
  114. # This approach calculates far too much be has the potential for easy parallelization via numba (cf. current
  115. # implementation of masked_rho_2d).
  116. # 2. Calculating only needed TF-target pairs:
  117. # (6,732,441 TF-target links * 136 microseconds * 10e-6)/3600.0 ~ 2h 30 mins.
  118. # - Many of these gene-gene links will be duplicate so there might be a potential for memoization. However because
  119. # the calculation is already quite fast and the memoization would need to take into account the commutativity of
  120. # the operation and involves hashing large numerical vectors, the benefit if this memoization might be minimal.
  121. # - Calculation of unique pairs already takes substantial amount of time and does not introduce a substantial
  122. # reduction in the number of gene-gene pairs to calculate the correlation for: 6,732,441 => 6,630,720 (2 min 9 s).
  123. # This is exactly the additional needed for calculating the rho values for these pairs. No gain here.
  124. #
  125. # The other options would have been to used the masked array abstraction provided by numpy but this again
  126. # this not allow for easy parallelization. In addition the corrcoef operation is far slower than the numba
  127. # JIT implementation: 2.36 ms ± 62 µs per loop.
  128. #
  129. # The best combined approach is to calculate rhos for pairs defined by indexes which is the approach implemented
  130. # below.
  131. # Calculate Pearson correlation to infer repression or activation.
  132. if mask_dropouts:
  133. ex_mtx = ex_mtx.sort_index(axis=1)
  134. col_idx_pairs = _create_idx_pairs(adjacencies, ex_mtx)
  135. rhos = masked_rho4pairs(ex_mtx.values, col_idx_pairs, 0.0)
  136. else:
  137. genes = list(
  138. set(adjacencies[COLUMN_NAME_TF]).union(set(adjacencies[COLUMN_NAME_TARGET]))
  139. )
  140. ex_mtx = ex_mtx[ex_mtx.columns[ex_mtx.columns.isin(genes)]]
  141. corr_mtx = pd.DataFrame(
  142. index=ex_mtx.columns,
  143. columns=ex_mtx.columns,
  144. data=np.corrcoef(ex_mtx.values.T),
  145. )
  146. rhos = np.array(
  147. [corr_mtx[s2][s1] for s1, s2 in zip(adjacencies.TF, adjacencies.target)]
  148. )
  149. regulations = (rhos > rho_threshold).astype(int) - (rhos < -rho_threshold).astype(
  150. int
  151. )
  152. return pd.DataFrame(
  153. data={
  154. COLUMN_NAME_TF: adjacencies[COLUMN_NAME_TF].values,
  155. COLUMN_NAME_TARGET: adjacencies[COLUMN_NAME_TARGET].values,
  156. COLUMN_NAME_WEIGHT: adjacencies[COLUMN_NAME_WEIGHT].values,
  157. COLUMN_NAME_REGULATION: regulations,
  158. COLUMN_NAME_CORRELATION: rhos,
  159. }
  160. )
  161. def modules4thr(adjacencies, threshold, context=frozenset(), pattern="weight>{:.3f}"):
  162. """
  163. :param adjacencies:
  164. :param threshold:
  165. :return:
  166. """
  167. for tf_name, df_grp in adjacencies[
  168. adjacencies[COLUMN_NAME_WEIGHT] > threshold
  169. ].groupby(by=COLUMN_NAME_TF):
  170. if len(df_grp) > 0:
  171. yield Regulon(
  172. name="Regulon for {}".format(tf_name),
  173. context=frozenset([pattern.format(threshold)]).union(context),
  174. transcription_factor=tf_name,
  175. gene2weight=list(
  176. zip(
  177. df_grp[COLUMN_NAME_TARGET].values,
  178. df_grp[COLUMN_NAME_WEIGHT].values,
  179. )
  180. ),
  181. gene2occurrence=[],
  182. )
  183. def modules4top_targets(adjacencies, n, context=frozenset()):
  184. """
  185. :param adjacencies:
  186. :param n:
  187. :return:
  188. """
  189. for tf_name, df_grp in adjacencies.groupby(by=COLUMN_NAME_TF):
  190. module = df_grp.nlargest(n, COLUMN_NAME_WEIGHT)
  191. if len(module) > 0:
  192. yield Regulon(
  193. name="Regulon for {}".format(tf_name),
  194. context=frozenset(["top{}".format(n)]).union(context),
  195. transcription_factor=tf_name,
  196. gene2weight=list(
  197. zip(
  198. module[COLUMN_NAME_TARGET].values,
  199. module[COLUMN_NAME_WEIGHT].values,
  200. )
  201. ),
  202. gene2occurrence=[],
  203. )
  204. def modules4top_factors(adjacencies, n, context=frozenset()):
  205. """
  206. :param adjacencies:
  207. :param n:
  208. :return:
  209. """
  210. df = adjacencies.groupby(by=COLUMN_NAME_TARGET).apply(
  211. lambda grp: grp.nlargest(n, COLUMN_NAME_WEIGHT)
  212. )
  213. for tf_name, df_grp in df.groupby(by=COLUMN_NAME_TF):
  214. if len(df_grp) > 0:
  215. yield Regulon(
  216. name=tf_name,
  217. context=frozenset(["top{}perTarget".format(n)]).union(context),
  218. transcription_factor=tf_name,
  219. gene2weight=list(
  220. zip(
  221. df_grp[COLUMN_NAME_TARGET].values,
  222. df_grp[COLUMN_NAME_WEIGHT].values,
  223. )
  224. ),
  225. gene2occurrence=[],
  226. )
  227. ACTIVATING_MODULE = "activating"
  228. REPRESSING_MODULE = "repressing"
  229. def modules_from_adjacencies(
  230. adjacencies: pd.DataFrame,
  231. ex_mtx: pd.DataFrame,
  232. thresholds=(0.75, 0.90),
  233. top_n_targets=(50,),
  234. top_n_regulators=(5, 10, 50),
  235. min_genes=20,
  236. absolute_thresholds=False,
  237. rho_dichotomize=True,
  238. keep_only_activating=True,
  239. rho_threshold=RHO_THRESHOLD,
  240. rho_mask_dropouts=False,
  241. ) -> Sequence[Regulon]:
  242. """
  243. Create modules from a dataframe containing weighted adjacencies between a TF and its target genes.
  244. :param adjacencies: The dataframe with the TF-target links. This dataframe should have the following columns:
  245. :py:const:`pyscenic.utils.COLUMN_NAME_TF`, :py:const:`pyscenic.utils.COLUMN_NAME_TARGET` and :py:const:`pyscenic.utils.COLUMN_NAME_WEIGHT` .
  246. :param ex_mtx: The expression matrix (n_cells x n_genes).
  247. :param thresholds: the first method to create the TF-modules based on the best targets for each transcription factor.
  248. :param top_n_targets: the second method is to select the top targets for a given TF.
  249. :param top_n_regulators: the alternative way to create the TF-modules is to select the best regulators for each gene.
  250. :param min_genes: The required minimum number of genes in a resulting module.
  251. :param absolute_thresholds: Use absolute thresholds or percentiles to define modules based on best targets of a TF.
  252. :param rho_dichotomize: Differentiate between activating and repressing modules based on the correlation patterns of
  253. the expression of the TF and its target genes.
  254. :param keep_only_activating: Keep only modules in which a TF activates its target genes.
  255. :param rho_threshold: The threshold on the correlation to decide if a target gene is activated
  256. (rho > `rho_threshold`) or repressed (rho < -`rho_threshold`).
  257. :param rho_mask_dropouts: Do not use cells in which either the expression of the TF or the target gene is 0 when
  258. calculating the correlation between a TF-target pair.
  259. :return: A sequence of regulons.
  260. """
  261. # Duplicate genes need to be removed from the expression matrix to avoid lookup problems in the correlation
  262. # matrix.
  263. # In addition, also make sure the expression matrix consists of floating point numbers. This requirement might
  264. # be violated when dealing with raw counts as input.
  265. ex_mtx = ex_mtx.T[~ex_mtx.columns.duplicated(keep="first")].T.astype(float)
  266. # To make the pySCENIC code more robust to the selection of the network inference method in the first step of
  267. # the pipeline, it is better to use percentiles instead of absolute values for the weight thresholds.
  268. if not absolute_thresholds:
  269. def iter_modules(adjc, context):
  270. yield from chain(
  271. chain.from_iterable(
  272. modules4thr(
  273. adjc, thr, context, pattern="weight>{}%".format(frac * 100)
  274. )
  275. for thr, frac in zip(
  276. list(adjacencies[COLUMN_NAME_WEIGHT].quantile(thresholds)),
  277. thresholds,
  278. )
  279. ),
  280. chain.from_iterable(
  281. modules4top_targets(adjc, n, context) for n in top_n_targets
  282. ),
  283. chain.from_iterable(
  284. modules4top_factors(adjc, n, context) for n in top_n_regulators
  285. ),
  286. )
  287. else:
  288. def iter_modules(adjc, context):
  289. yield from chain(
  290. chain.from_iterable(
  291. modules4thr(adjc, thr, context) for thr in thresholds
  292. ),
  293. chain.from_iterable(
  294. modules4top_targets(adjc, n, context) for n in top_n_targets
  295. ),
  296. chain.from_iterable(
  297. modules4top_factors(adjc, n, context) for n in top_n_regulators
  298. ),
  299. )
  300. if not rho_dichotomize:
  301. # Do not differentiate between activating and repressing modules.
  302. modules_iter = iter_modules(adjacencies, frozenset())
  303. else:
  304. # Relationship between TF and its target, i.e. activator or repressor, is derived using the original expression
  305. # profiles. The Pearson product-moment correlation coefficient is used to derive this information.
  306. if not {"regulation", "rho"}.issubset(adjacencies.columns):
  307. # Add correlation column and create two disjoint set of adjacencies.
  308. LOGGER.info("Calculating Pearson correlations.")
  309. # test for genes present in the adjacencies but not present in the expression matrix:
  310. unique_adj_genes = set(adjacencies[COLUMN_NAME_TF]).union(
  311. set(adjacencies[COLUMN_NAME_TARGET])
  312. ) - set(ex_mtx.columns)
  313. assert (
  314. len(unique_adj_genes) == 0
  315. ), f"Found {len(unique_adj_genes)} genes present in the network (adjacencies) output, but missing from the expression matrix. Is this a different gene expression matrix?"
  316. LOGGER.warn(
  317. f"Note on correlation calculation: the default behaviour for calculating the correlations has changed after pySCENIC verion 0.9.16. Previously, the default was to calculate the correlation between a TF and target gene using only cells with non-zero expression values (mask_dropouts=True). The current default is now to use all cells to match the behavior of the R verision of SCENIC. The original settings can be retained by setting 'rho_mask_dropouts=True' in the modules_from_adjacencies function, or '--mask_dropouts' from the CLI.\n\tDropout masking is currently set to [{rho_mask_dropouts}]."
  318. )
  319. adjacencies = add_correlation(
  320. adjacencies,
  321. ex_mtx,
  322. rho_threshold=rho_threshold,
  323. mask_dropouts=rho_mask_dropouts,
  324. )
  325. else:
  326. LOGGER.info(
  327. "Using existing Pearson correlations from the adjacencies file."
  328. )
  329. activating_modules = adjacencies[adjacencies[COLUMN_NAME_REGULATION] > 0.0]
  330. if keep_only_activating:
  331. modules_iter = iter_modules(
  332. activating_modules, frozenset([ACTIVATING_MODULE])
  333. )
  334. else:
  335. repressing_modules = adjacencies[adjacencies[COLUMN_NAME_REGULATION] < 0.0]
  336. modules_iter = chain(
  337. iter_modules(activating_modules, frozenset([ACTIVATING_MODULE])),
  338. iter_modules(repressing_modules, frozenset([REPRESSING_MODULE])),
  339. )
  340. # Derive modules for these adjacencies.
  341. # + Add the transcription factor to the module.
  342. # [We are unable to assess if a TF works in a direct self-regulating way, either inhibiting its own expression or
  343. # activating it. Therefore the most unbiased way forward is to add the TF to both activating as well as
  344. # repressing modules]
  345. # + Filter for minimum number of genes.
  346. LOGGER.info("Creating modules.")
  347. def add_tf(module):
  348. return module.add(module.transcription_factor)
  349. return list(filter(lambda m: len(m) >= min_genes, map(add_tf, modules_iter)))
  350. def save_to_yaml(signatures: Sequence[Type[GeneSignature]], fname: str):
  351. """
  352. :param signatures:
  353. :return:
  354. """
  355. with openfile(fname, "w") as f:
  356. f.write(dump(signatures, default_flow_style=False, Dumper=Dumper))
  357. def load_from_yaml(fname: str) -> Sequence[Type[GeneSignature]]:
  358. """
  359. :param fname:
  360. :return:
  361. """
  362. with openfile(fname, "r") as f:
  363. return load(f.read(), Loader=Loader)
  364. COLUMN_NAME_MOTIF_URL = "MotifURL"
  365. def add_motif_url(df: pd.DataFrame, base_url: str):
  366. """
  367. :param df:
  368. :param base_url:
  369. :return:
  370. """
  371. df[("Enrichment", COLUMN_NAME_MOTIF_URL)] = list(
  372. map(partial(urljoin, base_url), df.index.get_level_values(COLUMN_NAME_MOTIF_ID))
  373. )
  374. return df
  375. def load_motifs(fname: str, sep: str = ",") -> pd.DataFrame:
  376. """
  377. :param fname:
  378. :param sep:
  379. :return:
  380. """
  381. from .transform import COLUMN_NAME_CONTEXT, COLUMN_NAME_TARGET_GENES
  382. df = pd.read_csv(
  383. fname, sep=sep, index_col=[0, 1], header=[0, 1], skipinitialspace=True
  384. )
  385. df[("Enrichment", COLUMN_NAME_CONTEXT)] = df[
  386. ("Enrichment", COLUMN_NAME_CONTEXT)
  387. ].apply(lambda s: eval(s))
  388. df[("Enrichment", COLUMN_NAME_TARGET_GENES)] = df[
  389. ("Enrichment", COLUMN_NAME_TARGET_GENES)
  390. ].apply(lambda s: eval(s))
  391. return df

utils.py at commit 06bafba, under GPL-3.0 · at the source

Overview

Authors: Ibrahim Al Rayyes1, Lauri Louhivuori1, Ivar Dehnisch Ellström1, Erik Smedler2,3,4, Per Uhlén1
ORCID iDs: Per Uhlén
  1. Division of Molecular Neurobiology, Department of Medical Biochemistry and Biophysics, Karolinska Institutet, 17177 Stockholm, Sweden
  2. Department of Neuroscience and Physiology, University of Gothenburg, 40530 Gothenburg, Sweden
  3. The Wallenberg Centre for Molecular and Translational Medicine, 40530 Gothenburg, Sweden
  4. Psykiatri Affektiva, Department of Psychiatry, Region Västra Götaland, 41132 Gothenburg, Sweden
Journal: iScience, volume 29, issue 6, article 116055
Dates: received 10 November 2025; accepted 5 May 2026; published online 28 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1016/j.isci.2026.116055 · PMID 42256280 · PMCID PMC13233772 · OpenAlex W7162657469
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: genetics / omics (modality), human (organism), mouse (organism)
Methods: Smoothing, state filtering, decompositions, Machine learning, Preprocessing, Connectivity, Statistics
Keywords: Biological sciences, Neuroscience, Transcriptomics
Topic: Protein Kinase Regulation and GTPase Signaling (Molecular Biology, Biochemistry, Genetics and Molecular Biology), according to OpenAlex
Funding: Vetenskapsrådet (2021-03108, 2025-02414, 2022-02185); Hjärnfonden (FO2020-0199, FO2024-0057-TK-138); Swedish cancer society (22 2454 Pj, 25 4957 Pj); Karolinska Institutet
Citations: not cited yet (Europe PMC); 50 references in the paper

Abstract

Calcium (Ca2+) signaling is a key regulator of brain function and development. Here, we comprehensively analyze the Ca2+ signaling transcriptome in the adult mouse brain and the developing human brain to reveal the basis of signaling specificity. We show that neurons organize into non-stochastic Ca2+ states that reflect cell-type identity and capture subtle functional differences. These states arise from lineage-specific developmental Ca2+ programs that are detectable already in progenitor stages, and may precede differentiation into mature neuronal cell types. During neocortical development, many Ca2+ signaling genes, such as ADGRV1, NCALD, and CREB5, peak at distinct developmental stages, are evolutionarily conserved, and reflect transcriptional heterogeneity within progenitors associated with cell-fate decisions. Together, our findings provide an in-depth understanding of how a tightly regulated Ca2+ signaling transcriptome encodes cell-state-specific signaling programs and demonstrate that Ca2+ signaling is precisely tailored to distinct cell states.

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 13 matches between paragraphs and lines of code.

dpeerlab/cellrank

License: none: the authors keep all their rights
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: bf3e59569ed7beaeaacfedeeb75cffac1fd460cf, 19 January 2022
Size: 2 files, 0 scripts
Software Heritage: archived
Found in: the text, “Key resources table”
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
1 file

pachterlab/gget

License: BSD-2-Clause
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 7f0376ab4a77bbd48debed8a5371b1e2560740bb, 24 September 2026
Languages: Python (59)
Size: 208 files, 59 scripts
Software Heritage: archived
Found in: the text, “Key resources table”
Holds: README, license file, CITATION.cff, environment (pyproject.toml), tests, continuous integration, documentation
Tools: pandas (23 files), NumPy (10 files), Matplotlib (4 files)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
61 files

slowkow/harmonypy

License: GPL-3.0
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: dbd0984705530761f1e0a11ab5744345935437a0, 16 September 2026
Languages: Python (11), C++ (2), R (1), Shell (1)
Size: 40 files, 15 scripts
Software Heritage: archived
Found in: the text, “Key resources table”
Holds: README, license file, environment (pyproject.toml), tests, continuous integration
Not found: CITATION.cff, documentation
Tools: Harmony (9 files), NumPy (8 files), pandas (6 files), h5py (3 files), Matplotlib (2 files), SciPy (2 files), data.table (1 file), UMAP (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
17 files

gillislab/MetaNeighbor

License: MIT
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: a0aad62868621241caef857350318ff674d94704, 9 January 2025
Languages: R (18)
Size: 70 files, 18 scripts
Software Heritage: not archived
Found in: the text, “Key resources table”
Holds: README, license file, environment (DESCRIPTION), tests, documentation, 1 notebook
Not found: CITATION.cff, continuous integration
Tools: tidyverse (4 files), igraph (2 files), SingleCellExperiment (2 files), ggplot2 (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
20 files

optuna/optuna

License: MIT
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 0d05a967362d22414d759b3e3f382f2d883d948b, 25 September 2026
Languages: Python (381)
Size: 472 files, 381 scripts
Software Heritage: archived
Found in: the text, “Key resources table”
Holds: README, license file, CITATION.cff, environment (pyproject.toml), tests, continuous integration, documentation
Tools: NumPy (115 files), Plotly (18 files), PyTorch (13 files), scikit-learn (13 files), SciPy (10 files), LightGBM (3 files), Matplotlib (3 files), pandas (3 files)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
383 files

aertslab/pySCENIC

License: GPL-3.0
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 06bafba412792f6efa5a552a23bb221cc3bdea1b, 9 January 2025
Languages: Python (31), Jupyter (12), Shell (3)
Size: 90 files, 46 scripts
Software Heritage: not archived
Found in: the text, “Key resources table”
Holds: README, license file, environment (Dockerfile, pyscenic_with_scanpy.Dockerfile, requirements.doc.txt, requirements.txt, requirements_docker_with_scanpy.txt, setup.cfg, setup.py), tests, continuous integration, documentation, 12 notebooks
Not found: CITATION.cff
Tools: pandas (25 files), NumPy (15 files), seaborn (7 files), Matplotlib (5 files), anndata (3 files), scikit-learn (3 files), SciPy (3 files), NetworkX (1 file), Numba (1 file), Scanpy (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
48 files

scverse/scanpy

License: BSD-3-Clause
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 7db89c60639ed01c027ae8a10af65ff972232cda, 27 September 2026
Languages: Python (215), Jupyter (11), R (2)
Size: 886 files, 228 scripts
Software Heritage: archived
Found in: the text, “Key resources table”
Holds: README, license file, environment (pyproject.toml), tests, continuous integration, documentation, 11 notebooks
Not found: CITATION.cff
Tools: anndata (50 files), NumPy (40 files), Scanpy (27 files), pandas (26 files), Matplotlib (15 files), SciPy (12 files), scikit-learn (9 files), Numba (6 files), h5py (5 files), igraph (4 files), seaborn (2 files), UMAP (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
106 files

theislab/scarches

License: BSD-3-Clause
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: d35cde61fff4dec6b86660817f4750fa35ff836d, 26 June 2026
Languages: Python (79), Jupyter (18)
Size: 119 files, 97 scripts
Software Heritage: archived
Found in: the text, “Key resources table”
Holds: README, license file, environment (setup.py, docs/requirements.txt), tests, continuous integration, documentation, 18 notebooks
Not found: CITATION.cff
Tools: Scanpy (9 files), NumPy (8 files), PyTorch (6 files), Matplotlib (5 files), anndata (3 files), pandas (2 files), PyTorch Geometric (1 file), scikit-learn (1 file), SciPy (1 file), Squidpy (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
12 files

LouisFaure/scFates

License: BSD-3-Clause
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 8d8c0e629d7197fcf9801cc595bd23bdbf9f8118, 9 July 2026
Languages: Python (50), R (1), Shell (1)
Size: 86 files, 52 scripts
Software Heritage: not archived
Found in: the text, “Key resources table”
Holds: README, license file, environment (Dockerfile, environment.yml, pyproject.toml, docs/requirements.txt), tests, continuous integration, documentation
Not found: CITATION.cff
Tools: NumPy (35 files), anndata (29 files), pandas (28 files), Matplotlib (24 files), igraph (21 files), Scanpy (19 files), SciPy (11 files), rpy2 (8 files), statsmodels (7 files), scikit-learn (6 files), CuPy (4 files), Numba (2 files), seaborn (2 files), Monocle 3 (1 file), NetworkX (1 file), Plotly (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
54 files

simslab/schpf

License: BSD-2-Clause
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: df4cb468b17f62a832e7e2594c8579812ae30566, 14 February 2026
Languages: Python (16)
Size: 46 files, 16 scripts
Software Heritage: not archived
Found in: the text, “Key resources table”
Holds: README, license file, environment (setup.cfg, setup.py), tests, documentation
Not found: CITATION.cff, continuous integration
Tools: NumPy (10 files), SciPy (9 files), pandas (3 files), Numba (1 file), scikit-learn (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
18 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:

  • 10 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 701 scripts, each with its path and the digest of its content;
  • 13 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

No dataset and no data link were found in the paper.

Data and code availability

• This paper analyzes existing, publicly available data. Accession numbers are listed in the key resources table. • This paper does not report original code. Any scripts or notebooks used to generate figures are available from the lead contact upon request. • Any other information required to reanalyze the data reported in this paper is available from the lead contact upon request.

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, 28 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 5 authors, 3 keywords, 4 funders, 48 references.

Cite

This paper

Al Rayyes, I., Louhivuori, L., Ellström, I. D., Smedler, E., & Uhlén, P. (2026). Mapping the transcriptional diversity of calcium signaling in the mouse and human brain. iScience, 29(6), 116055. https://doi.org/10.1016/j.isci.2026.116055

BibTeX

@article{alrayyes2026mapping,
author = {Al Rayyes, Ibrahim and Louhivuori, Lauri and Ellström, Ivar Dehnisch and Smedler, Erik and Uhlén, Per},
title = {{Mapping the transcriptional diversity of calcium signaling in the mouse and human brain}},
journal = {iScience},
year = {2026},
month = may,
volume = {29},
number = {6},
pages = {116055},
publisher = {Elsevier},
issn = {2589-0042},
doi = {10.1016/j.isci.2026.116055},
url = {https://doi.org/10.1016/j.isci.2026.116055},
pmid = {42256280},
pmcid = {PMC13233772}
}

RIS

TY - JOUR
AU - Al Rayyes, Ibrahim
AU - Louhivuori, Lauri
AU - Ellström, Ivar Dehnisch
AU - Smedler, Erik
AU - Uhlén, Per
TI - Mapping the transcriptional diversity of calcium signaling in the mouse and human brain
T2 - iScience
J2 - iScience
PY - 2026
DA - 2026/05/28
VL - 29
IS - 6
SP - 116055
SN - 2589-0042
PB - Elsevier
DO - 10.1016/j.isci.2026.116055
UR - https://doi.org/10.1016/j.isci.2026.116055
LA - en
ER -

CSL-JSON

{
"id": "10.1016/j.isci.2026.116055",
"type": "article-journal",
"title": "Mapping the transcriptional diversity of calcium signaling in the mouse and human brain",
"container-title": "iScience",
"author": [
{
"family": "Al Rayyes",
"given": "Ibrahim"
},
{
"family": "Louhivuori",
"given": "Lauri"
},
{
"family": "Ellström",
"given": "Ivar Dehnisch"
},
{
"family": "Smedler",
"given": "Erik"
},
{
"family": "Uhlén",
"given": "Per"
}
],
"container-title-short": "iScience",
"volume": "29",
"issue": "6",
"page": "116055",
"DOI": "10.1016/j.isci.2026.116055",
"PMID": "42256280",
"PMCID": "PMC13233772",
"ISSN": "2589-0042",
"publisher": "Elsevier",
"URL": "https://doi.org/10.1016/j.isci.2026.116055",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
28
]
]
}
}

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.xcrm.2026.102766 [code]
A longitudinal single-cell and spatial multiomic atlas of pediatric high-grade glioma.
Journal: Cell reports. Medicine
In common: rpy2, Monocle 3, Harmony, 18 other tools, genetics / omics, 3 references
[2] doi:10.1038/s41593-026-02267-3 [code]
Spatial proteomic analysis in human Alzheimer's disease brains enables identification of microenvironment-dependent microglial cell states.
Journal: Nature neuroscience
In common: CuPy, rpy2, Monocle 3, 16 other tools, genetics / omics, 2 references
[3] doi:10.1016/j.stem.2026.05.005 [code]
Generation of human appetite-regulating neurons and tanycytes from pluripotent stem cells.
Journal: Cell stem cell
In common: Squidpy, rpy2, Monocle 3, 14 other tools, 3 references
[4] doi:10.1186/s13059-026-04177-w [code]
Genomic sequence evolution underlying human neocortical interareal diversification.
Journal: Genome biology
In common: Squidpy, Monocle 3, UMAP, 13 other tools, genetics / omics, mouse, 4 references
[5] doi:10.1038/s44318-026-00818-9 [code]
FAM134B-mediated ER-phagy degrades APP and suppresses Alzheimer's disease pathology.
Journal: The EMBO journal
In common: Monocle 3, Harmony, SingleCellExperiment, 16 other tools, mouse
[6] doi:10.1038/s41586-026-10629-x [code]
Whole-genome duplication shaped cell-type evolution in the vertebrate brain.
Journal: Nature
In common: Harmony, UMAP, anndata, 13 other tools, genetics / omics, mouse, 4 references
[7] doi:10.21203/rs.3.rs-9676637/v1 [code]
A Comprehensive Benchmarking of Spatial Deconvolution and Domain Detection Methods across Diverse Tissues and Spatial Transcriptomic Technologies
Journal: Research Square (preprint)
In common: Squidpy, rpy2, PyTorch Geometric, 15 other tools, genetics / omics
[8] doi:10.1038/s41592-026-03194-8 [code]
Beyond benchmarking: an expert-guided consensus approach to spatially aware clustering.
Journal: Nature methods
In common: Squidpy, rpy2, PyTorch Geometric, 14 other tools, genetics / omics, 1 reference
[9] doi:10.64898/2026.03.30.714220 [code]
An integrated single cell and spatial omics atlas of human prenatal development
Journal: bioRxiv (preprint)
In common: Squidpy, CuPy, UMAP, 12 other tools, 3 references
[10] doi:10.1038/s41467-026-71803-3 [code]
Charting the transition from in vitro gliogenesis to the in vivo maturation of human glial progenitor cells transplanted into the hypomyelinated mouse brain.
Journal: Nature communications
In common: Squidpy, anndata, Numba, 13 other tools, genetics / omics, mouse, 3 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.

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.