Common transcriptional changes in the brain during hibernation and Alzheimer’s disease
The 5 matches
- [1] § MATERIALS AND METHODS › Transcriptional network analysis (SCENIC) ↔ src/scenic/bin/export_to_loom.py, lines 718 to 767 · score 0.73 · PySCENIC, min regulon gene, tools, occurrence, loom, database · Report a mismatch
- [2] § MATERIALS AND METHODS › Quality control and processing of single nuclei data ↔ src/scanpy/bin/feature_selection/sc_find_variable_genes.py, lines 96 to 125 · score 0.70 · highly variable genes, min_disp, Scanpy, max, cells · Report a mismatch
- [3] § MATERIALS AND METHODS › Quality control and processing of single nuclei data ↔ src/scrublet/bin/sc_doublet_detection.py, lines 174 to 199 · score 0.68 · predicted doublets, highly variable, scrublet, variance, Raw, log · Report a mismatch
- [4] § MATERIALS AND METHODS › Transcriptional network analysis (SCENIC) ↔ src/scenic/bin/merge_motif_track_loom.py, lines 18 to 81 · score 0.65 · min regulon gene, pySCENIC, occurrence, loom, motif · Report a mismatch
- [5] § MATERIALS AND METHODS › Clustering and cell-type analysis ↔ src/scanpy/bin/cluster/sc_marker_genes.py, lines 76 to 121 · score 0.54 · Leiden algorithm, rank genes, resolutions, Cluster, cell · 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
Python · 794 lines · 35 KB · no license · 1 match
- #!/usr/bin/env python3
- import os
- import numpy as np
- import pandas as pd
- import loompy as lp
- from sklearn.manifold.t_sne import TSNE
- from pyscenic.aucell import aucell
- from pyscenic.genesig import Regulon, GeneSignature
- from typing import List, Mapping, Sequence, Optional, Dict
- from operator import attrgetter
- from multiprocessing import cpu_count
- from pyscenic.binarization import binarize
- from itertools import chain, repeat, islice
- import networkx as nx
- import zlib
- import base64
- import json
- import re
- import sys
- from collections import OrderedDict
- class Embedding:
- def __init__(self, embedding: pd.DataFrame, embedding_name: str, is_default: bool = False):
- self.embedding = embedding
- self.embedding_name = embedding_name
- self._is_default = is_default
- def get_embedding_name(self):
- return self.embedding_name
- def get_embedding(self):
- return self.embedding
- def is_default(self):
- return self._is_default
- class SCopeLoom:
- def __init__(
- self,
- filename: str = None,
- out_fname: str = None,
- ex_mtx: pd.DataFrame = None,
- regulons: List[Regulon] = None,
- cell_annotations: Optional[Mapping[str, str]] = None,
- tree_structure: Sequence[str] = None,
- title: Optional[str] = None,
- nomenclature: str = "Unknown",
- num_workers: int = cpu_count(),
- auc_mtx=None,
- auc_regulon_weights_key='gene2weight',
- auc_thresholds=None,
- compress: bool = False,
- save_additional_regulon_meta_data: bool = False, # Should be set to true only for multi-runs SCENIC
- set_generic_loom: bool = False,
- tag: str = None, # Used when merging track and motif-based SCENIC run
- col_attrs: Mapping[str, np.ndarray] = None,
- row_attrs: Mapping[str, np.ndarray] = None,
- global_attrs: Dict = None,
- embeddings: Mapping[str, pd.DataFrame] = None
- ):
- self.filename = filename
- self.out_fname = out_fname
- self.ex_mtx = ex_mtx
- self.regulons = regulons
- self.cell_annotations = cell_annotations
- self.tree_structure = tree_structure if tree_structure else ()
- self.title = title
- self.nomenclature = nomenclature
- self.num_workers = num_workers
- self.auc_mtx = auc_mtx
- self.auc_regulon_weights_key = auc_regulon_weights_key
- self.auc_thresholds = auc_thresholds
- self.compress = compress
- self.save_additional_regulon_meta_data = save_additional_regulon_meta_data
- self.tag = tag
- self.regulon_filter = None
- # Loom representation
- self.col_attrs = col_attrs if col_attrs else {}
- self.row_attrs = row_attrs if row_attrs else {}
- self.global_attrs = global_attrs if global_attrs else {}
- # Internal representation
- self.embeddings = embeddings if embeddings else {}
- # Utils
- self.id2name = OrderedDict()
- # Set Base Loom
- if set_generic_loom:
- self.set_generic_loom()
- def set_generic_loom(self):
- if(self.regulons[0].name.find('_') == -1):
- print(
- "Regulon name does not seem to be compatible with SCOPE. It should include a space to allow selection of the TF.",
- "\nPlease run: \n regulons = [r.rename(r.name.replace('(+)','_('+str(len(r))+'g)')) for r in regulons]",
- "\nor:\n regulons = [r.rename(r.name.replace('(','_(')) for r in regulons]"
- )
- self.set_cell_annotations()
- if self.auc_mtx is None:
- self.auc_mtx = self.calculate_regulon_enrichment()
- if self.auc_thresholds is None:
- self.auc_thresholds = self.binarize_regulon_enrichment()
- if len(self.embeddings.keys()) == 0:
- self.create_loom_default_embedding()
- self.regulon_gene_assignment = self.create_loom_regulon_gene_assignment()
- self.ngenes = self.calculate_nb_genes_per_cell()
- self.clusterings = self.create_loom_clusterings()
- self.regulon_thresholds = self.create_loom_md_regulon_thresholds()
- self.set_generic_col_attrs()
- self.set_generic_row_attrs()
- self.set_generic_global_attrs()
- self.set_tree()
- #######
- # I/O #
- #######
- @staticmethod
- def read_loom(filename: str, tag: str = None):
- with lp.connect(filename, mode='r', validate=False) as loom:
- # Load the content into memory
- # Set the main matrix
- ex_mtx = pd.DataFrame(loom[:, :], index=loom.ra.Gene, columns=loom.ca.CellID).T
- # Set the column, row and global attribute using the underlying Dict of the AttributeManager
- col_attrs = {k: v for k, v in loom.ca.items()}
- row_attrs = {k: v for k, v in loom.ra.items()}
- global_attrs = {k: v for k, v in loom.attrs.items()}
- # Decompress and decode the MetaData global attribute
- try:
- global_attrs["MetaData"] = SCopeLoom.decompress_decode(value=global_attrs["MetaData"])
- except Exception:
- # MetaData is uncompressed
- global_attrs["MetaData"] = json.loads(global_attrs["MetaData"])
- scope_loom = SCopeLoom(
- filename=filename,
- ex_mtx=ex_mtx,
- col_attrs=col_attrs,
- row_attrs=row_attrs,
- global_attrs=global_attrs,
- tag=tag
- )
- if 'embeddings' in scope_loom.get_meta_data():
- scope_loom.convert_loom_embeddings_repr_to_internal_repr()
- # If multi-runs mode
- is_multi_runs_mode = scope_loom.has_scenic_multi_runs_data()
- if is_multi_runs_mode:
- scope_loom.set_scenic_min_genes_regulon(min_genes_regulon=global_attrs["MetaData"]["regulonSettings"]["min_genes_regulon"])
- scope_loom.set_scenic_min_regulon_gene_occurrence(min_regulon_gene_occurrence=global_attrs["MetaData"]["regulonSettings"]["min_regulon_gene_occurrence"])
- return scope_loom
- #############
- # Meta Data #
- #############
- def add_meta_data(self, _dict):
- md = self.global_attrs["MetaData"]
- md.update(_dict)
- self.global_attrs["MetaData"] = md
- def get_meta_data(self):
- return self.global_attrs["MetaData"]
- def set_tree(self):
- assert len(self.tree_structure) <= 3, ""
- self.global_attrs.update(("SCopeTreeL{}".format(idx + 1), category) for idx, category in enumerate(list(islice(chain(self.tree_structure, repeat("")), 3))))
- #############
- # Features #
- #############
- def get_genes(self):
- return self.row_attrs['Gene']
- ################
- # Observations #
- ################
- def get_cell_ids(self):
- return self.col_attrs['CellID']
- ###############
- # Annotations #
- ###############
- def set_cell_annotations(self):
- if self.cell_annotations is None:
- self.cell_annotations = dict(zip(self.ex_mtx.index.astype(str), ['-'] * self.ex_mtx.shape[0]))
- ###########
- # Metrics #
- ###########
- def calculate_nb_genes_per_cell(self):
- # Calculate the number of genes per cell.
- binary_mtx = self.ex_mtx.copy()
- binary_mtx[binary_mtx != 0] = 1.0
- return binary_mtx.sum(axis=1).astype(int)
- def add_metrics(self, metrics: List[str]):
- md_metrics = []
- for metric in metrics:
- md_metrics.append({"name": metric})
- self.global_attrs["MetaData"].update({'metrics': md_metrics})
- ##############
- # Embeddings #
- ##############
- @staticmethod
- def get_embedding_id(embedding: Embedding, _list):
- """ Returns the appropriate index as a string given the _list
- Parameters:
- None
- Returns:
- str: Returns -1 if the given embedding is the default, 0 if the given _list is empty and length of the given _list minus 1
- """
- if embedding.is_default():
- return '-1'
- elif len(_list) == '0':
- return '0'
- else:
- return str(len(_list) - 1)
- def convert_loom_embeddings_repr_to_internal_repr(self):
- for embedding in self.get_meta_data()['embeddings']:
- self.add_embedding(
- embedding=self.get_embedding_by_id(embedding_id=embedding['id']),
- embedding_name=embedding['name'],
- is_default=True if str(embedding['id']) == '-1' else False
- )
- def get_embedding_by_id(self, embedding_id):
- if str(embedding_id) == '-1':
- return self.col_attrs['Embedding']
- x = self.col_attrs['Embeddings_X'][str(embedding_id)]
- y = self.col_attrs['Embeddings_Y'][str(embedding_id)]
- return np.column_stack((x, y))
- def has_embedding(self, embedding_name):
- return embedding_name in self.embeddings.keys()
- def add_embedding(self, embedding: np.ndarray, embedding_name, is_default: bool = False):
- df_embedding = pd.DataFrame(embedding, columns=['_X', '_Y'], index=self.ex_mtx.index)
- _embedding = Embedding(embedding=df_embedding, embedding_name=embedding_name, is_default=is_default)
- if is_default:
- self.default_embedding = _embedding
- self.embeddings[embedding_name] = _embedding
- def create_loom_default_embedding(self):
- # Create an embedding based on tSNE.
- # Name of columns should be "_X" and "_Y".
- self.add_embedding(embedding=TSNE().fit_transform(self.auc_mtx), embedding_name="tSNE (default)", is_default=True)
- def create_loom_md_embeddings_repr(self):
- """ Returns a Dictionary (Dict) for the global meta data embeddings with preformated data to be stored in Loom file format and compatible with SCope.
- Parameters:
- None
- Returns:
- dict: A Dictionary (Dict) for the global meta data embeddings with preformated data to be stored in Loom file format and compatible with SCope.
- """
- md_embeddings = []
- for _, embedding in self.embeddings.items():
- if embedding.is_default():
- md_embeddings = md_embeddings + [{'id': '-1', 'name': embedding.get_embedding_name()}]
- else:
- md_embeddings = md_embeddings + [
- {
- 'id': SCopeLoom.get_embedding_id(embedding=embedding, _list=md_embeddings),
- 'name': embedding.get_embedding_name()
- }
- ]
- return {"embeddings": md_embeddings}
- def create_loom_ca_embeddings_repr(self):
- """ Returns a Dictionary (Dict) for the embeddings with preformated data to be stored in Loom file format and compatible with SCope.
- Parameters:
- None
- Returns:
- dict: A Dictionary (Dict) for the embeddings with preformated data to be stored in Loom file format and compatible with SCope.
- """
- default_embedding = None
- embeddings_X = pd.DataFrame(index=self.ex_mtx.index)
- embeddings_Y = pd.DataFrame(index=self.ex_mtx.index)
- for _, embedding in self.embeddings.items():
- if(embedding.get_embedding().shape[1] != 2):
- raise Exception('The embedding should have two columns.')
- # Set the default embedding
- if embedding.is_default():
- default_embedding = embedding.get_embedding()
- # Update the Embeddings_[X|Y]
- embedding_id = str(SCopeLoom.get_embedding_id(embedding, embeddings_X.columns))
- embedding = embedding.get_embedding().copy()
- embedding.columns = ['_X', '_Y']
- embeddings_X = pd.merge(
- embeddings_X,
- embedding['_X'].to_frame().rename(
- columns={'_X': embedding_id}
- ).astype('float32'), left_index=True, right_index=True)
- embeddings_Y = pd.merge(
- embeddings_Y,
- embedding['_Y'].to_frame().rename(
- columns={'_Y': embedding_id}
- ).astype('float32'), left_index=True, right_index=True)
- return {
- "Embedding": SCopeLoom.df_to_named_matrix(df=default_embedding),
- "Embeddings_X": SCopeLoom.df_to_named_matrix(df=embeddings_X),
- "Embeddings_Y": SCopeLoom.df_to_named_matrix(df=embeddings_Y)
- }
- ###############
- # Clusterings #
- ###############
- def create_loom_clusterings(self):
- # Encode cell type clusters.
- # The name of the column should match the identifier of the clustering.
- return pd.DataFrame(
- data=self.ex_mtx.index.values,
- index=self.ex_mtx.index,
- columns=['0']
- ).replace(self.cell_annotations).replace(self.name2idx())
- ##########
- # SCENIC #
- ##########
- def set_scenic_min_genes_regulon(self, min_genes_regulon):
- self.scenic_min_genes_regulon = min_genes_regulon
- def set_scenic_min_regulon_gene_occurrence(self, min_regulon_gene_occurrence):
- self.scenic_min_regulon_gene_occurrence = min_regulon_gene_occurrence
- def set_regulon_filter(self, regulons):
- self.regulon_filter = regulons
- def has_scenic_multi_runs_data(self):
- return (
- 'RegulonGeneOccurrences' in self.row_attrs.keys() and 'RegulonGeneWeights' in self.row_attrs.keys()
- ) or (
- 'MotifRegulonGeneOccurrences' in self.row_attrs.keys() and 'MotifRegulonGeneWeights' in self.row_attrs.keys()
- ) or (
- 'TrackRegulonGeneOccurrences' in self.row_attrs.keys() and 'TrackRegulonGeneWeights' in self.row_attrs.keys()
- )
- def scopify_md_regulon_data(self):
- # Fix regulon objects to display properly in SCope:
- # Rename regulons in the thresholds object, motif
- md_regulon_thresholds = self.global_attrs['MetaData']['regulonThresholds']
- for _, x in enumerate(md_regulon_thresholds):
- tmp = re.sub(r"(_?)\(", '_(', x.get('regulon')) # + '-motif'
- x.update({'regulon': tmp})
- return {
- 'regulonThresholds': md_regulon_thresholds
- }
- def scopify_loom_ca_regulon_data(self):
- regulons_auc_col_attrs = list(filter(lambda col_attrs_key: 'RegulonsAUC' in col_attrs_key, self.col_attrs.keys()))
- def fix(col_attrs_key):
- regulons = pd.DataFrame(self.col_attrs[col_attrs_key], index=self.col_attrs['CellID'])
- # Add underscore for SCope compatibility:
- regulons.columns = regulons.columns.str.replace('_?\\(', '_(')
- return {
- col_attrs_key: SCopeLoom.df_to_named_matrix(regulons)
- }
- # Update the keys
- regulons_auc_col_attrs_update = map(fix, regulons_auc_col_attrs)
- # Convert list of dict to dict
- return {next(iter(x)): x.get(next(iter(x))) for x in regulons_auc_col_attrs_update}
- def scopify_loom_ra_regulon_data(self):
- regulons_row_attrs = list(filter(lambda row_attrs_key: 'Regulon' in row_attrs_key, self.row_attrs.keys()))
- def fix(row_attrs_key):
- regulons = pd.DataFrame(self.row_attrs[row_attrs_key], index=self.row_attrs['Gene'])
- # Add underscore for SCope compatibility:
- regulons.columns = regulons.columns.str.replace('_?\\(', '_(')
- return {
- row_attrs_key: SCopeLoom.df_to_named_matrix(regulons)
- }
- # Update the keys
- regulons_row_attrs_update = map(fix, regulons_row_attrs)
- # Convert list of dict to dict
- return {next(iter(x)): x.get(next(iter(x))) for x in regulons_row_attrs_update}
- def calculate_regulon_enrichment(self):
- # Calculate regulon enrichment per cell using AUCell.
- # Create regulons with weight based on given key
- print("Using {} to weight the genes when running AUCell.".format(self.auc_regulon_weights_key))
- regulon_signatures = list(map(lambda x: GeneSignature(name=x.name, gene2weight=self.get_regulon_gene_data(x, self.auc_regulon_weights_key)), self.regulons))
- auc_mtx = aucell(self.ex_mtx, regulon_signatures, num_workers=self.num_workers) # (n_cells x n_regulons)
- auc_mtx = auc_mtx.loc[self.ex_mtx.index]
- return auc_mtx
- def binarize_regulon_enrichment(self):
- _, auc_thresholds = binarize(self.auc_mtx)
- return auc_thresholds
- @staticmethod
- def format_tag(tag):
- # return f"{tag[0]}{tag[-1]}"
- return tag
- def get_regulon_gene_weights(self):
- if self.regulon_filter is not None:
- return self.row_attrs['RegulonGeneWeights'][self.regulon_filter]
- return self.row_attrs["RegulonGeneWeights"]
- def get_regulon_gene_occurrences(self):
- if self.regulon_filter is not None:
- return self.row_attrs['RegulonGeneOccurrences'][self.regulon_filter]
- return self.row_attrs["RegulonGeneOccurrences"]
- def get_regulons(self):
- if self.regulon_filter is not None:
- return self.row_attrs['Regulons'][self.regulon_filter]
- return self.row_attrs["Regulons"]
- def merge_regulon_data(self, scope_loom):
- # Check if SCENIC has been run in multi-runs mode
- is_multi_runs_mode = self.has_scenic_multi_runs_data() and scope_loom.has_scenic_multi_runs_data()
- # RegulonsAUC
- # Relabel columns with suffix indicating the regulon source
- auc_mtx = pd.DataFrame(data=self.col_attrs['RegulonsAUC'], index=self.col_attrs['CellID'])
- auc_mtx.columns = auc_mtx.columns + '-' + SCopeLoom.format_tag(self.tag)
- scope_loom_auc_mtx = pd.DataFrame(data=scope_loom.col_attrs['RegulonsAUC'], index=scope_loom.col_attrs['CellID'])
- scope_loom_auc_mtx.columns = scope_loom_auc_mtx.columns + '-' + SCopeLoom.format_tag(scope_loom.tag)
- # Regulons (regulon assignment matrices)
- regulons = pd.DataFrame(self.get_regulons(), index=self.row_attrs['Gene'])
- regulons.columns = regulons.columns + '-' + SCopeLoom.format_tag(self.tag)
- scope_loom_regulons = pd.DataFrame(scope_loom.get_regulons(), index=scope_loom.row_attrs['Gene'])
- scope_loom_regulons.columns = scope_loom_regulons.columns + '-' + SCopeLoom.format_tag(scope_loom.tag)
- # If multi-runs SCENIC
- # Rename Regulons Gene Occurrences
- if is_multi_runs_mode:
- regulon_gene_occurrences = pd.DataFrame(self.get_regulon_gene_occurrences(), index=self.row_attrs['Gene'])
- regulon_gene_occurrences.columns = regulon_gene_occurrences.columns + '-' + SCopeLoom.format_tag(self.tag)
- scope_loom_regulon_gene_occurrences = pd.DataFrame(scope_loom.get_regulon_gene_occurrences(), index=scope_loom.row_attrs['Gene'])
- scope_loom_regulon_gene_occurrences.columns = scope_loom_regulon_gene_occurrences.columns + '-' + SCopeLoom.format_tag(scope_loom.tag)
- # If multi-runs SCENIC
- # Rename Regulons Gene Weights
- if is_multi_runs_mode:
- regulon_gene_weights = pd.DataFrame(self.get_regulon_gene_weights(), index=self.row_attrs['Gene'])
- regulon_gene_weights.columns = regulon_gene_weights.columns + '-' + SCopeLoom.format_tag(self.tag)
- scope_loom_regulon_gene_weights = pd.DataFrame(scope_loom.get_regulon_gene_weights(), index=scope_loom.row_attrs['Gene'])
- scope_loom_regulon_gene_weights.columns = scope_loom_regulon_gene_weights.columns + '-' + SCopeLoom.format_tag(scope_loom.tag)
- # Combine meta data regulons
- # Rename regulons in the thresholds object, motif
- rt = self.global_attrs["MetaData"]["regulonThresholds"]
- for _, x in enumerate(rt):
- tmp = x.get('regulon') + '-' + SCopeLoom.format_tag(self.tag)
- x.update({'regulon': tmp})
- # Rename regulons in the thresholds object, track
- scope_loom_rt = scope_loom.global_attrs["MetaData"]["regulonThresholds"]
- for _, x in enumerate(scope_loom_rt):
- tmp = x.get('regulon') + '-' + SCopeLoom.format_tag(scope_loom.tag)
- x.update({'regulon': tmp})
- # blank out the "motifData" field for track-based regulons:
- x.update({'mofitData': 'NA.png'})
- # merge regulon threshold dictionaries:
- rt_merged = rt + scope_loom_rt
- # Remove because we will save them separately
- del self.row_attrs["Regulons"]
- del self.col_attrs["RegulonsAUC"]
- if is_multi_runs_mode:
- del self.row_attrs["RegulonGeneOccurrences"]
- del self.row_attrs["RegulonGeneWeights"]
- # Update the attributes
- self.row_attrs.update({f'{self.tag.capitalize()}Regulons': SCopeLoom.df_to_named_matrix(regulons)})
- self.col_attrs.update({f'{self.tag.capitalize()}RegulonsAUC': SCopeLoom.df_to_named_matrix(auc_mtx)})
- if is_multi_runs_mode:
- self.row_attrs.update({f'{self.tag.capitalize()}RegulonGeneOccurrences': SCopeLoom.df_to_named_matrix(regulon_gene_occurrences)})
- self.row_attrs.update({f'{self.tag.capitalize()}RegulonGeneWeights': SCopeLoom.df_to_named_matrix(regulon_gene_weights)})
- self.row_attrs.update({f'{scope_loom.tag.capitalize()}Regulons': SCopeLoom.df_to_named_matrix(scope_loom_regulons)})
- self.col_attrs.update({f'{scope_loom.tag.capitalize()}RegulonsAUC': SCopeLoom.df_to_named_matrix(scope_loom_auc_mtx)})
- if is_multi_runs_mode:
- self.row_attrs.update({f'{scope_loom.tag.capitalize()}RegulonGeneOccurrences': SCopeLoom.df_to_named_matrix(scope_loom_regulon_gene_occurrences)})
- self.row_attrs.update({f'{scope_loom.tag.capitalize()}RegulonGeneWeights': SCopeLoom.df_to_named_matrix(scope_loom_regulon_gene_weights)})
- self.global_attrs["MetaData"].update({'regulonThresholds': rt_merged})
- def get_regulon_gene_data(self, regulon, key):
- if key == 'gene2occurrence':
- return regulon.gene2occurrence
- if key == 'gene2weight':
- return regulon.gene2weight
- raise Exception('Cannot retrieve {} from given regulon. Not implemented.'.format(key))
- def get_regulon_meta_data(self, name, threshold):
- def fetch_logo(context):
- for elem in context:
- if elem.endswith('.png'):
- return elem
- return ""
- name2logo = {reg.name: fetch_logo(reg.context) for reg in self.regulons}
- regulon = list(filter(lambda x: x.name == name, self.regulons))[0]
- regulon_meta_data = {
- "regulon": name,
- "defaultThresholdValue": (threshold if isinstance(threshold, float) else threshold[0]),
- "defaultThresholdName": "guassian_mixture_split",
- "allThresholds": {
- "guassian_mixture_split": (threshold if isinstance(threshold, float) else threshold[0])
- },
- "motifData": name2logo.get(name, "")
- }
- if self.save_additional_regulon_meta_data:
- regulon_meta_data.update({
- "tf": regulon.transcription_factor,
- "score": regulon.score if hasattr(regulon, 'score') else 0.0,
- "orthologousIdentity": regulon.orthologous_identity if hasattr(regulon, 'orthologous_identity') else 0.0,
- "annotation": regulon.annotation if hasattr(regulon, 'annotation') else '',
- "similarityQValue": regulon.score if hasattr(regulon, 'similarity_qvalue') else 0.0
- })
- return regulon_meta_data
- def create_loom_md_regulon_thresholds(self):
- return [self.get_regulon_meta_data(name, threshold) for name, threshold in self.auc_thresholds.iteritems()]
- def create_loom_regulon_gene_assignment(self):
- # Encode genes in regulons as "binary" membership matrix.
- genes = np.array(self.ex_mtx.columns)
- n_genes = len(genes)
- n_regulons = len(self.regulons)
- data = np.zeros(shape=(n_genes, n_regulons), dtype=int)
- for idx, regulon in enumerate(self.regulons):
- data[:, idx] = np.isin(genes, regulon.genes).astype(int)
- regulon_gene_assignment = pd.DataFrame(
- data=data,
- index=self.ex_mtx.columns,
- columns=list(map(attrgetter('name'), self.regulons))
- )
- return regulon_gene_assignment
- # Multi-runs SCENIC additional data
- def encode_regulon_gene_data(self, key):
- genes = np.array(self.ex_mtx.columns)
- n_genes = len(genes)
- n_regulons = len(self.regulons)
- data = np.zeros(shape=(n_genes, n_regulons), dtype=float)
- for idx, regulon in enumerate(self.regulons):
- regulon_data = pd.DataFrame.from_dict(self.get_regulon_gene_data(regulon, key), orient='index')
- data[np.isin(genes, regulon_data.index), idx] = regulon_data[0][genes[np.isin(genes, regulon_data.index)]]
- return data
- def create_loom_regulon_gene_data(self, key):
- return pd.DataFrame(
- data=self.encode_regulon_gene_data(key=key),
- index=self.ex_mtx.columns,
- columns=list(map(attrgetter('name'), self.regulons))
- )
- def add_row_attr_regulon_gene_weights(self):
- regulon_gene_weights = self.create_loom_regulon_gene_data(key='gene2weight')
- if 'RegulonGeneWeights' not in self.row_attrs.keys():
- print("Added 'RegulonGeneWeights' to the row attributes.")
- self.row_attrs['RegulonGeneWeights'] = SCopeLoom.df_to_named_matrix(regulon_gene_weights)
- def add_row_attr_regulon_gene_occurrences(self):
- regulon_gene_occurrences = self.create_loom_regulon_gene_data(key='gene2occurrence')
- if 'RegulonGeneOccurrences' not in self.row_attrs.keys():
- print("Added 'RegulonGeneOccurrences' to the row attributes.")
- self.row_attrs['RegulonGeneOccurrences'] = SCopeLoom.df_to_named_matrix(regulon_gene_occurrences)
- ###########
- # Generic #
- ###########
- def name2idx(self):
- return dict(map(reversed, enumerate(sorted(set(self.cell_annotations.values())))))
- def set_generic_col_attrs(self):
- self.col_attrs = {
- "CellID": self.ex_mtx.index.values.astype('str'),
- "nGene": self.ngenes.values,
- "Embedding": SCopeLoom.df_to_named_matrix(self.default_embedding.get_embedding()),
- "RegulonsAUC": SCopeLoom.df_to_named_matrix(self.auc_mtx),
- "Clusterings": SCopeLoom.df_to_named_matrix(self.clusterings),
- "ClusterID": self.clusterings.values
- }
- def set_generic_row_attrs(self):
- self.row_attrs = {
- "Gene": self.ex_mtx.columns.values.astype('str'),
- "Regulons": SCopeLoom.df_to_named_matrix(self.regulon_gene_assignment)
- }
- def set_generic_global_attrs(self):
- self.global_attrs = {
- "title": os.path.splitext(os.path.basename(self.out_fname))[0] if self.title is None else self.title,
- "MetaData": {
- "embeddings": [{'id': identifier, 'name': name} for identifier, name in self.id2name.items()],
- "annotations": [{
- "name": "",
- "values": []
- }],
- "clusterings": [{
- "id": 0,
- "group": "celltype",
- "name": "Cell Type",
- "clusters": [{"id": idx, "description": name} for name, idx in self.name2idx().items()]
- }],
- "regulonThresholds": self.regulon_thresholds
- },
- "Genome": self.nomenclature
- }
- def sort(self, axis, by):
- if(axis == 0):
- if by not in self.row_attrs:
- sys.exit(f"ERROR: Cannot sort on a row attribute that does not exist")
- sorted_idx = np.argsort(self.row_attrs[by])
- for ra_key in self.row_attrs.keys():
- self.row_attrs[ra_key] = self.row_attrs[ra_key][sorted_idx]
- self.ex_mtx = self.ex_mtx[self.row_attrs[by]]
- else:
- sys.exit(f"ERROR: Sorting by column axis is not implemented")
- def merge(self, loom, overwrite_embeddings=False):
- # Check all the cells and genes are in the same order
- if not np.array_equal(a1=self.get_cell_ids(), a2=loom.get_cell_ids()):
- sys.exit(f"ERROR: Column attribute CellIDs does not match between {os.path.basename(self.filename)} and {os.path.basename(loom.filename)}")
- if not np.array_equal(a1=self.get_genes(), a2=loom.get_genes()):
- sys.exit(f"ERROR: Row attribute 'Gene' does not match between {os.path.basename(self.filename)} and {os.path.basename(loom.filename)}")
- if not np.array_equal(a1=self.get_genes(), a2=self.ex_mtx.columns):
- sys.exit(f"ERROR: Row attribute 'Gene' does not match with the features in the matrix of {os.path.basename(self.filename)}.")
- if not np.array_equal(a1=loom.get_genes(), a2=loom.ex_mtx.columns):
- sys.exit(f"ERROR: Row attribute 'Gene' does not match with the features in the matrix of {os.path.basename(loom.filename)}.")
- # Add the embeddings of the given loom (SCopeLoom) to this SCopeLoom
- if 'embeddings' in loom.get_meta_data():
- print(f"Merging embeddings from {os.path.basename(loom.filename)} into {os.path.basename(self.filename)}...")
- for embedding in loom.get_meta_data()['embeddings']:
- # Only add the embedding if not present in this loom and overwrite_embeddings is False
- if not self.has_embedding(embedding_name=embedding['name']) or overwrite_embeddings:
- print(f"Adding {embedding['name']} embedding...")
- self.add_embedding(
- embedding_name=embedding['name'],
- embedding=loom.get_embedding_by_id(embedding_id=embedding['id'])
- )
- print("Done.")
- # Add SCENIC results if present in the given loom
- if any('Regulon' in s for s in loom.row_attrs.keys()) and any('Regulon' in s for s in loom.col_attrs.keys()):
- print(f"Merging SCENIC results from {os.path.basename(loom.filename)} into {os.path.basename(self.filename)}...")
- # Regulon information from row attributes
- # All the row attributes containing the substring 'Regulon' within the given SCopeLoom
- # will be merged with this SCopeLoom
- regulons_row_attrs_keys = list(filter(lambda row_attrs_key: 'Regulon' in row_attrs_key, loom.row_attrs.keys()))
- regulons_row_attrs = {
- regulons_row_attr_key: loom.row_attrs[regulons_row_attr_key] for regulons_row_attr_key in regulons_row_attrs_keys
- }
- self.row_attrs.update(regulons_row_attrs)
- # Regulon information from column attributes
- # All the column attributes containing the substring 'Regulon' within the given SCopeLoom
- # will be merged with this SCopeLoom
- regulons_auc_col_attrs_keys = list(filter(lambda col_attrs_key: 'Regulon' in col_attrs_key, loom.col_attrs.keys()))
- regulons_auc_col_attrs = {
- regulons_auc_col_attr_key: loom.col_attrs[regulons_auc_col_attr_key] for regulons_auc_col_attr_key in regulons_auc_col_attrs_keys
- }
- self.col_attrs.update(regulons_auc_col_attrs)
- # regulonThresholds MetaData global attribute
- self.global_attrs["MetaData"].update(
- {
- 'regulonThresholds': loom.get_meta_data()['regulonThresholds']
- }
- )
- print("Done.")
- # If multi-runs mode
- is_multi_runs_mode = self.has_scenic_multi_runs_data()
- if is_multi_runs_mode:
- self.set_scenic_min_genes_regulon(min_genes_regulon=loom.scenic_min_genes_regulon)
- self.set_scenic_min_regulon_gene_occurrence(min_regulon_gene_occurrence=loom.scenic_min_regulon_gene_occurrence)
- def export(self, out_fname: str, save_embeddings: bool = True, compress_meta_data: bool = False):
- if out_fname is None:
- raise ValueError("The given out_fname cannot be None.")
- ##############
- # Embeddings #
- ##############
- if save_embeddings:
- self.col_attrs.update(self.create_loom_ca_embeddings_repr())
- self.global_attrs["MetaData"].update(self.create_loom_md_embeddings_repr())
- ##########
- # SCENIC #
- ##########
- is_multi_runs_mode = self.has_scenic_multi_runs_data()
- if is_multi_runs_mode:
- if "regulonSettings" not in self.global_attrs["MetaData"].keys():
- self.add_meta_data(_dict={
- "regulonSettings": {
- "min_genes_regulon": self.scenic_min_genes_regulon,
- "min_regulon_gene_occurrence": self.scenic_min_regulon_gene_occurrence
- }
- })
- if any('Regulon' in s for s in self.row_attrs.keys()):
- self.row_attrs.update(self.scopify_loom_ra_regulon_data())
- if any('RegulonsAUC' in s for s in self.col_attrs.keys()):
- self.col_attrs.update(self.scopify_loom_ca_regulon_data())
- if 'regulonThresholds' in self.global_attrs["MetaData"].keys():
- self.global_attrs["MetaData"].update(self.scopify_md_regulon_data())
- # Compress MetaData global attribute
- # (Should be compressed if Loompy version 2)
- self.global_attrs["MetaData"] = json.dumps(self.global_attrs["MetaData"])
- if compress_meta_data:
- self.global_attrs["MetaData"] = SCopeLoom.compress_encode(value=self.global_attrs["MetaData"])
- # Create loom file for use with the SCope tool.
- # The loom file format opted for rows as genes to facilitate growth along the column axis (i.e add more cells)
- # PySCENIC chose a different orientation because of limitation set by the feather format: selectively reading
- # information from disk can only be achieved via column selection. For the ranking databases this is of utmost
- # importance.
- lp.create(
- filename=out_fname,
- layers=self.ex_mtx.T.values,
- row_attrs=self.row_attrs,
- col_attrs=self.col_attrs,
- file_attrs=self.global_attrs
- )
- #########
- # Utils #
- #########
- @staticmethod
- def df_to_named_matrix(df: pd.DataFrame):
- # Create meta-data structure.
- # Create a numpy structured array
- return np.array([tuple(row) for row in df.values],
- dtype=np.dtype(list(zip(df.columns, df.dtypes))))
- @staticmethod
- def compress_encode(value):
- '''
- Compress using ZLIB algorithm and encode the given value in base64.
- Taken from: https://github.com/aertslab/SCopeLoomPy/blob/5438da52c4bcf48f483a1cf378b1eaa788adefcb/src/scopeloompy/utils/__init__.py#L7
- '''
- return base64.b64encode(zlib.compress(value.encode('ascii'))).decode('ascii')
- @staticmethod
- def decompress_decode(value):
- try:
- value = value.decode('ascii')
- return json.loads(zlib.decompress(base64.b64decode(value)))
- except AttributeError:
- return json.loads(zlib.decompress(base64.b64decode(value.encode('ascii'))).decode('ascii'))
export_to_loom.py at commit 58c1304, no license · at the source
Overview
- VIB-KU Leuven Center for Neuroscience; Leuven, Belgium
- KU Leuven, Department of Neurosciences, Leuven Brain Institute, Mission Lucidity; Leuven, Belgium
- Medical University of Innsbruck, Institute of Human Genetics; Innsbruck, Austria
- Universidad San Pablo-Centro de Estudios Universitarios, Facultad de Farmacia, Departamento de Química y Bioquímica; Madrid, Spain
Abstract
Hibernation demands rapid brain adaptations, involving cycles of reduced metabolic rate during torpor, followed by brief periods of arousal. Previous studies show hibernation induces a drastic increase in Tau hyperphosphorylation, but a mechanistic connection to disease remains unclear. Using single-nucleus RNA sequencing on hippocampi of golden hamsters, we unveil large transcriptional shifts across the hibernation cycle in all cell types, especially glia. Common transcriptional changes in mitochondrial and ribosomal genes are observed in all different cell types. In addition, hibernation triggers an inflammatory-like response in microglia that in part resembles cell states observed in Alzheimer’s disease, but here in the absence of Aβ-accumulation and neurodegeneration. These findings reveal brain transformations that might help preserve vital functions under extreme conditions and they suggest that early cellular changes in AD may be a natural adaptive process.
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 5 matches between paragraphs and lines of code.
aertslab/create_cisTarget_databases
304d5dc1b15e5c923908a50a1ec291c3faaccf9c, 18 June 2025Availability: 2 checks, the latest on 2 November 2026: the link answers
- 2 November 2026: the link answers
- 28 September 2026: the link answers
29 files
- bigwigaverageoverbed.py, Python, 245 lines
- cistarget_db.py, Python, 1,677 lines
- clusterbuster.py, Python, 332 lines
- combine_partial_motifs_o
r_tracks_vs_regions_or_g , Python, 278 linesenes_scores_cistarget_db s.py - combine_partial_regions_
or_genes_vs_motifs_or_tr , Python, 255 linesacks_scores_cistarget_db s.py - convert_cistarget_databa
ses_v1_to_v2.py , Python, 179 lines - convert_feather_db_to_sq
lite3_db.py , Python, 215 lines - convert_motifs_or_tracks
_vs_regions_or_genes_sco , Python, 175 linesres_to_rankings_cistarge t_dbs.py - create_cistarget_motif_d
atabases.py , Python, 572 lines - create_cistarget_track_d
atabases.py , Python, 430 lines - create_cross_species_mot
ifs_rankings_db.py , Python, 214 lines - create_fasta_with_padded
_bg_from_bed.sh , Shell, 133 lines - feather_v1_fbs/
CTable.py , Python, 117 lines - feather_v1_fbs/
CategoryMetadata.py , Python, 62 lines - feather_v1_fbs/
Column.py , Python, 97 lines - feather_v1_fbs/
DateMetadata.py , Python, 34 lines - feather_v1_fbs/
Encoding.py , Python, 14 lines - feather_v1_fbs/
PrimitiveArray.py , Python, 105 lines - feather_v1_fbs/
TimeMetadata.py , Python, 45 lines - feather_v1_fbs/
TimeUnit.py , Python, 10 lines - feather_v1_fbs/
TimestampMetadata.py , Python, 58 lines - feather_v1_fbs/
Type.py , Python, 31 lines - feather_v1_fbs/
TypeMetadata.py , Python, 11 lines - feather_v1_fbs/
__init__.py , Python, 1 line - feather_v1_or_v2.py, Python, 87 lines
- orderstatistics.py, Python, 120 lines
- test_cistarget_db.py, Python, 1,143 lines
- test_orderstatistics.py, Python, 224 lines
- README.md, Text, 689 lines
Zenodo 5751297
Availability: 1 check, the latest on 7 November 2026: the link answers (HTTP 200)
- 7 November 2026: the link answers (HTTP 200)
72 files
- docs/
conf.py , Python, 55 lines - src/
archr/ , R, 179 linesbin/ cell_calling.R - src/
archr/ , R, 109 linesbin/ createArrow_unfiltered.R - src/
bap/ , Jupyter, 214 linesbin/ bap_barcode_multiplet_re port.ipynb - src/
bwamaptools/ , Shell, 42 linesbin/ mapping_summary.sh - src/
celda/ , R, 270 linesbin/ run_decontx.R - src/
directs/ , Python, 212 linesbin/ select_default_clusterin g.py - src/
dropletutils/ , R, 98 linesbin/ barcode_selection.R - src/
flybaser/ , R, 28 linesbin/ convertFBgnToGeneSymbol. R - src/
harmony/ , Jupyter, 181 linesbin/ reports/ sc_harmony_report.ipynb - src/
harmony/ , R, 161 linesbin/ run_harmony.R - src/
pcacv/ , R, 453 linesbin/ run_pca_cv.R - src/
pycistopic/ , Python, 161 linesbin/ barcode_level_statistics .py - src/
pycistopic/ , Python, 47 linesbin/ biomart_annot.py - src/
pycistopic/ , Python, 209 linesbin/ call_cells.py - src/
pycistopic/ , Python, 142 linesbin/ compute_qc_stats.py - src/
pycistopic/ , Python, 46 linesbin/ plot_qc_stats.py - src/
pycistopic/ , Jupyter, 454 linesbin/ pycisTopic_qc_report_tem plate.ipynb - src/
scanpy/ , Python, 74 linesbin/ adjust/ sc_regress_out.py - src/
scanpy/ , Python, 216 linesbin/ aggregate/ sc_batch_effect_correcti on.py - src/
scanpy/ , Python, 119 linesbin/ cluster/ sc_clustering.py - src/
scanpy/ , Python, 134 linesbin/ cluster/ sc_clustering_preflight_ checks.py - src/
scanpy/ , Python, 121 linesbin/ cluster/ sc_marker_genes.py - src/
scanpy/ , Python, 162 linesbin/ dim_reduction/ sc_dim_reduction.py - src/
scanpy/ , Python, 129 linesbin/ feature_selection/ sc_find_variable_genes.p y - src/
scanpy/ , Python, 42 linesbin/ feature_selection/ sc_subset_variable_genes .py - src/
scanpy/ , Python, 339 linesbin/ filter/ sc_cell_gene_filtering.p y - src/
scanpy/ , Python, 75 linesbin/ nn/ sc_neighborhood_graph.py - src/
scanpy/ , Jupyter, 144 linesbin/ reports/ sc_bbknn_report.ipynb - src/
scanpy/ , Jupyter, 75 linesbin/ reports/ sc_clustering_report.ipy nb - src/
scanpy/ , Jupyter, 50 linesbin/ reports/ sc_dim_reduction_report. ipynb - src/
scanpy/ , Jupyter, 350 linesbin/ reports/ sc_filter_qc_report.ipyn b - src/
scanpy/ , Jupyter, 187 linesbin/ reports/ sc_mnncorrect_report.ipy nb - src/
scanpy/ , Jupyter, 33 linesbin/ reports/ sc_select_variable_genes _report.ipynb - src/
scanpy/ , Python, 54 linesbin/ transform/ sc_data_transformation.p y - src/
scanpy/ , Python, 67 linesbin/ transform/ sc_feature_scaling.py - src/
scanpy/ , Python, 68 linesbin/ transform/ sc_normalization.py - src/
scanpy/ , Python, 19 linesbin/ utils/ sc_neighbors.py - src/
scenic/ , Python, 86 linesbin/ add_visualization.py - src/
scenic/ , Python, 162 linesbin/ aggregate_multi_runs_fea tures.py - src/
scenic/ , Python, 112 linesbin/ aggregate_multi_runs_reg ulons.py - src/
scenic/ , Python, 62 linesbin/ append_results_to_existi ng_loom.py - src/
scenic/ , Python, 107 linesbin/ aucell_from_folder.py - src/
scenic/ , Python, 105 linesbin/ convert_multi_runs_featu res_to_regulons.py - src/
scenic/ , Python, 794 linesbin/ export_to_loom.py - src/
scenic/ , Python, 131 linesbin/ merge_motif_track_loom.p y - src/
scenic/ , Jupyter, 333 linesbin/ reports/ scenic_report.ipynb - src/
scenic/ , Python, 170 linesbin/ save_multi_runs_to_loom. py - src/
scenic/ , Python, 101 linesbin/ utils.py - src/
scrublet/ , Jupyter, 128 linesbin/ reports/ sc_doublet_detection_rep ort.ipynb - src/
scrublet/ , Python, 288 linesbin/ sc_doublet_detection.py - src/
soupx/ , R, 50 linesbin/ plot.R - src/
soupx/ , R, 120 linesbin/ run_soupx.R - src/
utils/ , R, 58 linesbin/ create_cistopic_object.R - src/
utils/ , Python, 50 linesbin/ h5ad_to_filtered_loom.py - src/
utils/ , Python, 480 linesbin/ h5ad_to_loom.py - src/
utils/ , Jupyter, 18 linesbin/ reports/ workflow_configuration_t emplate.ipynb - src/
utils/ , Python, 90 linesbin/ sc_file_concatenator.py - src/
utils/ , R, 310 linesbin/ sc_file_converter.R - src/
utils/ , Python, 306 linesbin/ sc_file_converter.py - src/
utils/ , Python, 172 linesbin/ sc_h5ad_annotate_by_cell _metadata.py - src/
utils/ , Python, 157 linesbin/ sc_h5ad_annotate_by_samp le_metadata.py - src/
utils/ , Python, 63 linesbin/ sc_h5ad_apply_obs_filter .py - src/
utils/ , Python, 68 linesbin/ sc_h5ad_extract_metadata .py - src/
utils/ , Python, 169 linesbin/ sc_h5ad_merge.py - src/
utils/ , Python, 161 linesbin/ sc_h5ad_prepare_obs_filt er.py - src/
utils/ , Python, 128 linesbin/ sc_h5ad_update.py - src/
utils/ , Python, 96 linesbin/ sc_h5ad_update_metadata. py - src/
utils/ , Python, 70 linesbin/ sc_star_concatenator.py - src/
utils/ , Python, 138 linesbin/ sra_to_metadata.py - LICENSE, License, 674 lines
- README.rst, Text, 210 lines
vib-singlecell-nf/scenic
58c130428e9c5a82dde06d6c2576f26f8fe27ecc, 8 December 2020Availability: 1 check, the latest on 7 November 2026: the link answers
- 7 November 2026: the link answers
12 files
- src/
scenic/ , Python, 86 linesbin/ add_visualization.py - src/
scenic/ , Python, 162 linesbin/ aggregate_multi_runs_fea tures.py - src/
scenic/ , Python, 112 linesbin/ aggregate_multi_runs_reg ulons.py - src/
scenic/ , Python, 62 linesbin/ append_results_to_existi ng_loom.py - src/
scenic/ , Python, 107 linesbin/ aucell_from_folder.py - src/
scenic/ , Python, 105 linesbin/ convert_multi_runs_featu res_to_regulons.py - src/
scenic/ , Python, 794 lines, 1 matchbin/ export_to_loom.py - src/
scenic/ , Python, 131 lines, 1 matchbin/ merge_motif_track_loom.p y - src/
scenic/ , Jupyter, 333 linesbin/ reports/ scenic_report.ipynb - src/
scenic/ , Python, 170 linesbin/ save_multi_runs_to_loom. py - src/
scenic/ , Python, 101 linesbin/ utils.py - README.md, Text, 2 lines
vib-singlecell-nf/vsn-pipelines
65056919560a4c82ff560c9499c199d138c8b6c7, 19 April 2023Availability: 2 checks, the latest on 7 November 2026: the link answers
- 7 November 2026: the link answers
- 2 October 2026: the link answers
72 files
- docs/
conf.py , Python, 55 lines - src/
archr/ , R, 179 linesbin/ cell_calling.R - src/
archr/ , R, 109 linesbin/ createArrow_unfiltered.R - src/
bap/ , Jupyter, 214 linesbin/ bap_barcode_multiplet_re port.ipynb - src/
bwamaptools/ , Shell, 42 linesbin/ mapping_summary.sh - src/
celda/ , R, 270 linesbin/ run_decontx.R - src/
directs/ , Python, 212 linesbin/ select_default_clusterin g.py - src/
dropletutils/ , R, 98 linesbin/ barcode_selection.R - src/
flybaser/ , R, 28 linesbin/ convertFBgnToGeneSymbol. R - src/
harmony/ , Jupyter, 181 linesbin/ reports/ sc_harmony_report.ipynb - src/
harmony/ , R, 161 linesbin/ run_harmony.R - src/
pcacv/ , R, 453 linesbin/ run_pca_cv.R - src/
pycistopic/ , Python, 161 linesbin/ barcode_level_statistics .py - src/
pycistopic/ , Python, 47 linesbin/ biomart_annot.py - src/
pycistopic/ , Python, 209 linesbin/ call_cells.py - src/
pycistopic/ , Python, 142 linesbin/ compute_qc_stats.py - src/
pycistopic/ , Python, 46 linesbin/ plot_qc_stats.py - src/
pycistopic/ , Jupyter, 454 linesbin/ pycisTopic_qc_report_tem plate.ipynb - src/
scanpy/ , Python, 74 linesbin/ adjust/ sc_regress_out.py - src/
scanpy/ , Python, 216 linesbin/ aggregate/ sc_batch_effect_correcti on.py - src/
scanpy/ , Python, 119 linesbin/ cluster/ sc_clustering.py - src/
scanpy/ , Python, 134 linesbin/ cluster/ sc_clustering_preflight_ checks.py - src/
scanpy/ , Python, 121 lines, 1 matchbin/ cluster/ sc_marker_genes.py - src/
scanpy/ , Python, 162 linesbin/ dim_reduction/ sc_dim_reduction.py - src/
scanpy/ , Python, 129 lines, 1 matchbin/ feature_selection/ sc_find_variable_genes.p y - src/
scanpy/ , Python, 42 linesbin/ feature_selection/ sc_subset_variable_genes .py - src/
scanpy/ , Python, 339 linesbin/ filter/ sc_cell_gene_filtering.p y - src/
scanpy/ , Python, 75 linesbin/ nn/ sc_neighborhood_graph.py - src/
scanpy/ , Jupyter, 144 linesbin/ reports/ sc_bbknn_report.ipynb - src/
scanpy/ , Jupyter, 75 linesbin/ reports/ sc_clustering_report.ipy nb - src/
scanpy/ , Jupyter, 50 linesbin/ reports/ sc_dim_reduction_report. ipynb - src/
scanpy/ , Jupyter, 350 linesbin/ reports/ sc_filter_qc_report.ipyn b - src/
scanpy/ , Jupyter, 187 linesbin/ reports/ sc_mnncorrect_report.ipy nb - src/
scanpy/ , Jupyter, 33 linesbin/ reports/ sc_select_variable_genes _report.ipynb - src/
scanpy/ , Python, 54 linesbin/ transform/ sc_data_transformation.p y - src/
scanpy/ , Python, 67 linesbin/ transform/ sc_feature_scaling.py - src/
scanpy/ , Python, 68 linesbin/ transform/ sc_normalization.py - src/
scanpy/ , Python, 19 linesbin/ utils/ sc_neighbors.py - src/
scenic/ , Python, 86 linesbin/ add_visualization.py - src/
scenic/ , Python, 162 linesbin/ aggregate_multi_runs_fea tures.py - src/
scenic/ , Python, 112 linesbin/ aggregate_multi_runs_reg ulons.py - src/
scenic/ , Python, 62 linesbin/ append_results_to_existi ng_loom.py - src/
scenic/ , Python, 107 linesbin/ aucell_from_folder.py - src/
scenic/ , Python, 105 linesbin/ convert_multi_runs_featu res_to_regulons.py - src/
scenic/ , Python, 794 linesbin/ export_to_loom.py - src/
scenic/ , Python, 131 linesbin/ merge_motif_track_loom.p y - src/
scenic/ , Jupyter, 333 linesbin/ reports/ scenic_report.ipynb - src/
scenic/ , Python, 170 linesbin/ save_multi_runs_to_loom. py - src/
scenic/ , Python, 101 linesbin/ utils.py - src/
scrublet/ , Jupyter, 128 linesbin/ reports/ sc_doublet_detection_rep ort.ipynb - src/
scrublet/ , Python, 288 lines, 1 matchbin/ sc_doublet_detection.py - src/
soupx/ , R, 50 linesbin/ plot.R - src/
soupx/ , R, 120 linesbin/ run_soupx.R - src/
utils/ , R, 58 linesbin/ create_cistopic_object.R - src/
utils/ , Python, 50 linesbin/ h5ad_to_filtered_loom.py - src/
utils/ , Python, 480 linesbin/ h5ad_to_loom.py - src/
utils/ , Jupyter, 18 linesbin/ reports/ workflow_configuration_t emplate.ipynb - src/
utils/ , Python, 90 linesbin/ sc_file_concatenator.py - src/
utils/ , R, 310 linesbin/ sc_file_converter.R - src/
utils/ , Python, 306 linesbin/ sc_file_converter.py - src/
utils/ , Python, 172 linesbin/ sc_h5ad_annotate_by_cell _metadata.py - src/
utils/ , Python, 157 linesbin/ sc_h5ad_annotate_by_samp le_metadata.py - src/
utils/ , Python, 63 linesbin/ sc_h5ad_apply_obs_filter .py - src/
utils/ , Python, 68 linesbin/ sc_h5ad_extract_metadata .py - src/
utils/ , Python, 169 linesbin/ sc_h5ad_merge.py - src/
utils/ , Python, 161 linesbin/ sc_h5ad_prepare_obs_filt er.py - src/
utils/ , Python, 128 linesbin/ sc_h5ad_update.py - src/
utils/ , Python, 96 linesbin/ sc_h5ad_update_metadata. py - src/
utils/ , Python, 70 linesbin/ sc_star_concatenator.py - src/
utils/ , Python, 138 linesbin/ sra_to_metadata.py - LICENSE, License, 674 lines
- README.rst, Text, 215 lines
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:
- 4 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 179 scripts, each with its path and the digest of its content;
- 5 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
- geo:GSE304024, at NCBI GEO; found in “Data, code, and materials availability:”
Data, code, and materials availability
Single-cell data is available at https://
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, 7 November 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 9 authors, 4 funders, 53 references.
Cite
This paper
Largo-Barrientos, P., Praschberger, R., León-Espinosa, G., Bultynck, P.-J., Mallopoulou, A., Machado, J. F., Poovathingal, S., Davie, K., & Verstreken, P. (2026). Common transcriptional changes in the brain during hibernation and Alzheimer’s disease. Science advances, 12(45), eaeg3486.
BibTeX
@article{largobarrientos
author = {Largo-Barrientos, Pablo and Praschberger, Roman and León-Espinosa, Gonzalo and Bultynck, Pieter-Jan and Mallopoulou, Anastasia and Machado, João F. and Poovathingal, Suresh and Davie, Kristofer and Verstreken, Patrik},
title = {{Common transcriptional changes in the brain during hibernation and Alzheimer’s disease}},
journal = {Science advances},
year = {2026},
month = nov,
volume = {12},
number = {45},
pages = {eaeg3486},
publisher = {American Association for the Advancement of Science},
issn = {2375-2548},
pmcid = {PMC13733825}
}
RIS
TY - JOUR
AU - Largo-Barrientos, Pablo
AU - Praschberger, Roman
AU - León-Espinosa, Gonzalo
AU - Bultynck, Pieter-Jan
AU - Mallopoulou, Anastasia
AU - Machado, João F.
AU - Poovathingal, Suresh
AU - Davie, Kristofer
AU - Verstreken, Patrik
TI - Common transcriptional changes in the brain during hibernation and Alzheimer’s disease
T2 - Science advances
J2 - Sci Adv
PY - 2026
DA - 2026/
VL - 12
IS - 45
SP - eaeg3486
SN - 2375-2548
PB - American Association for the Advancement of Science
LA - en
ER -
CSL-JSON
{
"id": "pmcid:PMC13733825",
"type": "article-journal",
"title": "Common transcriptional changes in the brain during hibernation and Alzheimer’s disease",
"container-title": "Science advances",
"author": [
{
"family": "Largo-Barrientos",
"given": "Pablo"
},
{
"family": "Praschberger",
"given": "Roman"
},
{
"family": "León-Espinosa",
"given": "Gonzalo"
},
{
"family": "Bultynck",
"given": "Pieter-Jan"
},
{
"family": "Mallopoulou",
"given": "Anastasia"
},
{
"family": "Machado",
"given": "João F."
},
{
"family": "Poovathingal",
"given": "Suresh"
},
{
"family": "Davie",
"given": "Kristofer"
},
{
"family": "Verstreken",
"given": "Patrik"
}
],
"container-title-short":
"volume": "12",
"issue": "45",
"page": "eaeg3486",
"PMCID": "PMC13733825",
"ISSN": "2375-2548",
"publisher": "American Association for the Advancement of Science",
"language": "en",
"issued": {
"date-parts": [
[
2026,
11,
6
]
]
}
}
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.7554/elife.98348 [code]
- Synaptic deregulation of cholinergic projection neurons causes olfactory dysfunction across five fly Parkinsonism models.Journal: eLifeIn common: Harmony, reticulate, SingleCellExperiment, 14 other tools, cellular / molecular, 3 references, 3 authors
- [2] doi:10.1038/s41593-025-02075-1 [code]
- C9orf72 hexanucleotide repeat expansions impair microglial response in ALS.Journal: Nature neuroscienceIn common: Harmony, reticulate, SingleCellExperiment, 14 other tools, cellular / molecular, 5 references, author Kristofer Davie
- [3] doi:10.1038/s41593-023-01549-4 [code]
- Single-cell transcriptomics reveals that glial cells integrate homeostatic and circadian processes to drive sleep-wake cycles.Journal: Nature neuroscienceIn common: Harmony, reticulate, SingleCellExperiment, 14 other tools, cellular / molecular, 2 references, author Kristofer Davie
- [4] doi:10.1016/j.cell.2025.06.031 [code]
- Single-cell multiregion epigenomic rewiring in Alzheimer's disease progression and cognitive resilience.Journal: CellIn common: Harmony, reticulate, BEDTools, 15 other tools, Alzheimer's / dementia, cellular / molecular, 5 references
- [5] doi:10.1038/s41592-023-01938-4 [code]
- SCENIC+: single-cell multiomic inference of enhancers and gene regulatory networks.Journal: Nature methodsIn common: Harmony, BEDTools, anndata, 13 other tools, cellular / molecular, 4 references, author Suresh Poovathingal
- [6] doi:10.1038/s41586-026-10629-x [code]
- Whole-genome duplication shaped cell-type evolution in the vertebrate brain.Journal: NatureIn common: Harmony, reticulate, BEDTools, 14 other tools, cellular / molecular, 4 references
- [7] doi:10.1038/s41593-025-02022-0 [code]
- An integrated single-nucleus and spatial transcriptomics atlas reveals the molecular landscape of the human hippocampus.Journal: Nature neuroscienceIn common: Harmony, reticulate, SingleCellExperiment, 12 other tools, 5 references
- [8] doi:10.1016/j.xgen.2025.101007 [code]
- Single-nucleus transcriptome atlas of orbitofrontal cortex in ALS with a deep learning-based decoding of alternative polyadenylation mechanisms.Journal: Cell genomicsIn common: Harmony, reticulate, BEDTools, 11 other tools, Alzheimer's / dementia, cellular / molecular, 6 references
- [9] doi:10.1016/j.neuron.2023.02.033 [code]
- Neuronal identity defines α-synuclein and tau toxicity.Journal: NeuronIn common: tidyverse, Alzheimer's / dementia, cellular / molecular, 10 references, 2 authors
- [10] doi:10.1038/s41591-024-03150-z [code]
- A brain cell atlas integrating single-cell transcriptomes across human brain regions.Journal: Nature medicineIn common: reticulate, anndata, Scanpy, 10 other tools, 8 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.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 4 repositories of the authors' code, each at its verified commit and with its license, 179 scripts, and 5 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:4d0fdcd57a923d4d…
Add the badge to the code's README
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 -->
[](https://openscicode.org/badge/repo/github.com/aertslab/create_cistarget_databases)
<!-- oscr-badge:end -->reStructuredText
.. oscr-badge:start
.. image:: https://openscicode.org/badge/repo/github.com/aertslab/create_cistarget_databases.svg
:target: https://openscicode.org/badge/repo/github.com/aertslab/create_cistarget_databases
:alt: OSCR
.. oscr-badge:endHTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/repo/github.com/aertslab/create_cistarget_databases"><img src="https://openscicode.org/badge/repo/github.com/aertslab/create_cistarget_databases.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".
- aertslab/create_cisTarget_databases: README.md on GitHub
- vib-singlecell-nf/scenic: README.md on GitHub
- vib-singlecell-nf/vsn-pipelines: README.rst on GitHub
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.
