Convergence-divergence circuits for multimodal integration of innate and learned opponent valences.
The 8 matches
- [1] § Materials and methods › UMAP › UMAP generation ↔ umap/umap_.py, lines 1485–1737 · score 0.97 · uniform manifold approximation, fuzzy simplicial, min_dist, UMAP algorithm, UMAP embedding, n_neighbors
- [2] § Materials and methods › UMAP › Clustering on UMAP ↔ umap/umap_.py, lines 1485–1737 · score 0.84 · Local density, UMAP embedding, nearest neighbors, high dimensional, NN, inverse
- [3] § Materials and methods › UMAP › UMAP generation ↔ umap/layouts.py, lines 527–658 · score 0.81 · stochastic gradient descent, fuzzy simplicial, low dimensional, metric, optimized, embedding
- [4] § Materials and methods › Geometry ↔ navis/nbl/nblast_funcs.py, lines 878–1016 · score 0.64 · dot product, nearest neighbor, NBLAST, straight, score, query
- [5] § Materials and methods › Geometry ↔ navis/nbl/synblast_funcs.py, lines 230–360 · score 0.61 · target neuron, nearest neighbor, product, NBLAST, score, query
- [6] § Materials and methods › Subcellular topology › Ranked dendrogram ↔ navis/graph/converters.py, lines 484–592 · score 0.56 · adding temporary, edge lengths, branches, tree, node, skeleton
- [7] § Materials and methods › Geometry ↔ navis/nbl/nblast_funcs.py, lines 878–1016 · score 0.55 · score matrix, nearest neighbors, NBLAST, vector, neurons
- [8] § Materials and methods › Geometry ↔ navis/nbl/synblast_funcs.py, lines 230–360 · score 0.54 · score matrix, nearest neighbors, NBLAST, morphological, vector, neurons
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 · 3,762 lines · 142 KB · BSD-3-Clause · 2 matches
- # Author: Leland McInnes <[email hidden]>
- #
- # License: BSD 3 clause
- from __future__ import print_function
- import locale
- from collections import deque
- from warnings import warn
- import time
- from scipy.optimize import curve_fit
- from sklearn.base import BaseEstimator, ClassNamePrefixFeaturesOutMixin
- from sklearn.utils import check_array, check_random_state
- from sklearn.utils.validation import check_is_fitted
- from sklearn.metrics import pairwise_distances
- from sklearn.preprocessing import normalize
- from sklearn.neighbors import KDTree
- from sklearn.decomposition import PCA, TruncatedSVD
- try:
- import joblib
- except ImportError:
- # sklearn.externals.joblib is deprecated in 0.21, will be removed in 0.23
- from sklearn.externals import joblib
- import numpy as np
- import scipy.sparse
- from scipy.sparse import tril as sparse_tril, triu as sparse_triu
- import scipy.sparse.csgraph
- import numba
- import umap.distances as dist
- import umap.sparse as sparse
- from umap.utils import (
- ts,
- csr_unique,
- fast_knn_indices,
- )
- from umap.spectral import spectral_layout, tswspectral_layout
- from umap.layouts import (
- optimize_layout_euclidean,
- optimize_layout_generic,
- optimize_layout_inverse,
- )
- from pynndescent import NNDescent
- from pynndescent.distances import named_distances as pynn_named_distances
- from pynndescent.sparse import sparse_named_distances as pynn_sparse_named_distances
- locale.setlocale(locale.LC_NUMERIC, "C")
- INT32_MIN = np.iinfo(np.int32).min + 1
- INT32_MAX = np.iinfo(np.int32).max - 1
- SMOOTH_K_TOLERANCE = 1e-5
- MIN_K_DIST_SCALE = 1e-3
- NPY_INFINITY = np.inf
- NPY_FLOATMAX = np.finfo(np.float32).max
- DISCONNECTION_DISTANCES = {
- "correlation": 2,
- "cosine": 2,
- "hellinger": 1,
- "jaccard": 1,
- "bit_jaccard": 1,
- "dice": 1,
- }
- def flatten_iter(container):
- for i in container:
- if isinstance(i, (list, tuple)):
- for j in flatten_iter(i):
- yield j
- else:
- yield i
- def flattened(container):
- return tuple(flatten_iter(container))
- def breadth_first_search(adjmat, start, min_vertices):
- explored = []
- queue = deque([start])
- levels = {start: 0}
- max_level = np.inf
- visited = np.zeros(adjmat.shape[0], dtype=np.bool_)
- visited[start] = True
- while queue:
- node = queue.popleft()
- explored.append(node)
- if max_level == np.inf and len(explored) > min_vertices:
- max_level = max(levels.values())
- if levels[node] + 1 < max_level:
- neighbors = adjmat[node].indices
- for neighbour in neighbors:
- if not visited[neighbour]:
- queue.append(neighbour)
- visited[neighbour] = True
- levels[neighbour] = levels[node] + 1
- return np.array(explored)
- def raise_disconnected_warning(
- edges_removed,
- vertices_disconnected,
- disconnection_distance,
- total_rows,
- threshold=0.1,
- verbose=False,
- ):
- """A simple wrapper function to avoid large amounts of code repetition."""
- if verbose & (vertices_disconnected == 0) & (edges_removed > 0):
- print(
- f"Disconnection_distance = {disconnection_distance} has removed {edges_removed} edges. "
- f"This is not a problem as no vertices were disconnected."
- )
- elif (vertices_disconnected > 0) & (
- vertices_disconnected <= threshold * total_rows
- ):
- warn(
- f"A few of your vertices were disconnected from the manifold. This shouldn't cause problems.\n"
- f"Disconnection_distance = {disconnection_distance} has removed {edges_removed} edges.\n"
- f"It has only fully disconnected {vertices_disconnected} vertices.\n"
- f"Use umap.utils.disconnected_vertices() to identify them.",
- )
- elif vertices_disconnected > threshold * total_rows:
- warn(
- f"A large number of your vertices were disconnected from the manifold.\n"
- f"Disconnection_distance = {disconnection_distance} has removed {edges_removed} edges.\n"
- f"It has fully disconnected {vertices_disconnected} vertices.\n"
- f"You might consider using find_disconnected_points() to find and remove these points from your data.\n"
- f"Use umap.utils.disconnected_vertices() to identify them.",
- )
- @numba.njit(
- locals={
- "psum": numba.types.float32,
- "lo": numba.types.float32,
- "mid": numba.types.float32,
- "hi": numba.types.float32,
- },
- parallel=True,
- )
- def smooth_knn_dist(distances, k, n_iter=64, local_connectivity=1.0, bandwidth=1.0):
- """Compute a continuous version of the distance to the kth nearest
- neighbor. That is, this is similar to knn-distance but allows continuous
- k values rather than requiring an integral k. In essence we are simply
- computing the distance such that the cardinality of fuzzy set we generate
- is k.
- Parameters
- ----------
- distances: array of shape (n_samples, n_neighbors)
- Distances to nearest neighbors for each sample. Each row should be a
- sorted list of distances to a given samples nearest neighbors.
- k: float
- The number of nearest neighbors to approximate for.
- n_iter: int (optional, default 64)
- We need to binary search for the correct distance value. This is the
- max number of iterations to use in such a search.
- local_connectivity: int (optional, default 1)
- The local connectivity required -- i.e. the number of nearest
- neighbors that should be assumed to be connected at a local level.
- The higher this value the more connected the manifold becomes
- locally. In practice this should be not more than the local intrinsic
- dimension of the manifold.
- bandwidth: float (optional, default 1)
- The target bandwidth of the kernel, larger values will produce
- larger return values.
- Returns
- -------
- knn_dist: array of shape (n_samples,)
- The distance to kth nearest neighbor, as suitably approximated.
- nn_dist: array of shape (n_samples,)
- The distance to the 1st nearest neighbor for each point.
- """
- target = np.log2(k) * bandwidth
- rho = np.zeros(distances.shape[0], dtype=np.float32)
- result = np.zeros(distances.shape[0], dtype=np.float32)
- # Neighbours pruned by disconnection_distance (or inf entries of a
- # precomputed distance matrix) arrive here as inf. They must be excluded
- # from rho and from the MIN_K_DIST_SCALE floor: the mean of a row that
- # contains inf is inf, which made sigma inf for every point with a pruned
- # neighbour and gave all of its remaining edges membership strength 1.0.
- flat_distances = distances.ravel()
- finite_distances = flat_distances[np.isfinite(flat_distances)]
- if finite_distances.shape[0] > 0:
- mean_distances = np.mean(finite_distances)
- else:
- mean_distances = 0.0
- for i in numba.prange(distances.shape[0]):
- lo = 0.0
- hi = NPY_FLOATMAX
- mid = 1.0
- # TODO: This is very inefficient, but will do for now. FIXME
- ith_distances = distances[i]
- finite_ith_distances = ith_distances[np.isfinite(ith_distances)]
- non_zero_dists = finite_ith_distances[finite_ith_distances > 0.0]
- if non_zero_dists.shape[0] >= local_connectivity:
- index = int(np.floor(local_connectivity))
- interpolation = local_connectivity - index
- if index > 0:
- rho[i] = non_zero_dists[index - 1]
- if interpolation > SMOOTH_K_TOLERANCE:
- rho[i] += interpolation * (
- non_zero_dists[index] - non_zero_dists[index - 1]
- )
- else:
- rho[i] = interpolation * non_zero_dists[0]
- elif non_zero_dists.shape[0] > 0:
- rho[i] = np.max(non_zero_dists)
- for n in range(n_iter):
- psum = 0.0
- for j in range(1, distances.shape[1]):
- d = distances[i, j] - rho[i]
- if d > 0:
- psum += np.exp(-(d / mid))
- else:
- psum += 1.0
- if np.fabs(psum - target) < SMOOTH_K_TOLERANCE:
- break
- if psum > target:
- hi = mid
- mid = (lo + hi) / 2.0
- else:
- lo = mid
- if hi >= NPY_FLOATMAX:
- mid *= 2
- else:
- mid = (lo + hi) / 2.0
- result[i] = mid
- # TODO: This is very inefficient, but will do for now. FIXME
- if rho[i] > 0.0:
- mean_ith_distances = np.mean(finite_ith_distances)
- if result[i] < MIN_K_DIST_SCALE * mean_ith_distances:
- result[i] = MIN_K_DIST_SCALE * mean_ith_distances
- else:
- if result[i] < MIN_K_DIST_SCALE * mean_distances:
- result[i] = MIN_K_DIST_SCALE * mean_distances
- return result, rho
- def nearest_neighbors(
- X,
- n_neighbors,
- metric,
- metric_kwds,
- angular,
- random_state,
- low_memory=True,
- use_pynndescent=True,
- n_jobs=-1,
- verbose=False,
- ):
- """Compute the ``n_neighbors`` nearest points for each data point in ``X``
- under ``metric``. This may be exact, but more likely is approximated via
- nearest neighbor descent.
- Parameters
- ----------
- X: array of shape (n_samples, n_features)
- The input data to compute the k-neighbor graph of.
- n_neighbors: int
- The number of nearest neighbors to compute for each sample in ``X``.
- metric: string or callable
- The metric to use for the computation.
- metric_kwds: dict
- Any arguments to pass to the metric computation function.
- angular: bool
- Whether to use angular rp trees in NN approximation.
- random_state: np.random state
- The random state to use for approximate NN computations.
- low_memory: bool (optional, default True)
- Whether to pursue lower memory NNdescent.
- verbose: bool (optional, default False)
- Whether to print status data during the computation.
- Returns
- -------
- knn_indices: array of shape (n_samples, n_neighbors)
- The indices on the ``n_neighbors`` closest points in the dataset.
- knn_dists: array of shape (n_samples, n_neighbors)
- The distances to the ``n_neighbors`` closest points in the dataset.
- rp_forest: list of trees
- The random projection forest used for searching (if used, None otherwise).
- """
- if verbose:
- print(ts(), "Finding Nearest Neighbors")
- if metric == "precomputed":
- # Note that this does not support sparse distance matrices yet ...
- # Compute indices of n nearest neighbors
- knn_indices = fast_knn_indices(X, n_neighbors)
- # knn_indices = np.argsort(X)[:, :n_neighbors]
- # Compute the nearest neighbor distances
- # (equivalent to np.sort(X)[:,:n_neighbors])
- # Advanced indexing already returns a fresh contiguous array, so no
- # extra .copy() is needed here.
- knn_dists = X[np.arange(X.shape[0])[:, None], knn_indices]
- # Prune any nearest neighbours that are infinite distance apart.
- disconnected_index = knn_dists == np.inf
- knn_indices[disconnected_index] = -1
- knn_search_index = None
- else:
- # TODO: Hacked values for now
- n_trees = min(64, 5 + int(round((X.shape[0]) ** 0.5 / 20.0)))
- n_iters = max(5, int(round(np.log2(X.shape[0]))))
- knn_search_index = NNDescent(
- X,
- n_neighbors=n_neighbors,
- metric=metric,
- metric_kwds=metric_kwds,
- random_state=random_state,
- n_trees=n_trees,
- n_iters=n_iters,
- max_candidates=60,
- low_memory=low_memory,
- n_jobs=n_jobs,
- verbose=verbose,
- compressed=False,
- )
- knn_indices, knn_dists = knn_search_index.neighbor_graph
- if verbose:
- print(ts(), "Finished Nearest Neighbor Search")
- return knn_indices, knn_dists, knn_search_index
- @numba.njit(
- locals={
- "knn_dists": numba.types.float32[:, ::1],
- "sigmas": numba.types.float32[::1],
- "rhos": numba.types.float32[::1],
- "val": numba.types.float32,
- },
- parallel=True,
- )
- def compute_membership_strengths(
- knn_indices,
- knn_dists,
- sigmas,
- rhos,
- return_dists=False,
- bipartite=False,
- ):
- """Construct the membership strength data for the 1-skeleton of each local
- fuzzy simplicial set -- this is formed as a sparse matrix where each row is
- a local fuzzy simplicial set, with a membership strength for the
- 1-simplex to each other data point.
- Parameters
- ----------
- knn_indices: array of shape (n_samples, n_neighbors)
- The indices on the ``n_neighbors`` closest points in the dataset.
- knn_dists: array of shape (n_samples, n_neighbors)
- The distances to the ``n_neighbors`` closest points in the dataset.
- sigmas: array of shape(n_samples)
- The normalization factor derived from the metric tensor approximation.
- rhos: array of shape(n_samples)
- The local connectivity adjustment.
- return_dists: bool (optional, default False)
- Whether to return the pairwise distance associated with each edge.
- bipartite: bool (optional, default False)
- Does the nearest neighbour set represent a bipartite graph? That is, are the
- nearest neighbour indices from the same point set as the row indices?
- Returns
- -------
- rows: array of shape (n_samples * n_neighbors)
- Row data for the resulting sparse matrix (coo format)
- cols: array of shape (n_samples * n_neighbors)
- Column data for the resulting sparse matrix (coo format)
- vals: array of shape (n_samples * n_neighbors)
- Entries for the resulting sparse matrix (coo format)
- dists: array of shape (n_samples * n_neighbors)
- Distance associated with each entry in the resulting sparse matrix
- """
- n_samples = knn_indices.shape[0]
- n_neighbors = knn_indices.shape[1]
- rows = np.zeros(knn_indices.size, dtype=np.int32)
- cols = np.zeros(knn_indices.size, dtype=np.int32)
- vals = np.zeros(knn_indices.size, dtype=np.float32)
- if return_dists:
- dists = np.zeros(knn_indices.size, dtype=np.float32)
- else:
- dists = None
- for i in range(n_samples):
- for j in range(n_neighbors):
- if knn_indices[i, j] == -1:
- continue # We didn't get the full knn for i
- # If applied to an adjacency matrix points shouldn't be similar to themselves.
- # If applied to an incidence matrix (or bipartite) then the row and column indices are different.
- if (bipartite == False) & (knn_indices[i, j] == i):
- val = 0.0
- elif knn_dists[i, j] - rhos[i] <= 0.0 or sigmas[i] == 0.0:
- val = 1.0
- else:
- val = np.exp(-((knn_dists[i, j] - rhos[i]) / (sigmas[i])))
- rows[i * n_neighbors + j] = i
- cols[i * n_neighbors + j] = knn_indices[i, j]
- vals[i * n_neighbors + j] = val
- if return_dists:
- dists[i * n_neighbors + j] = knn_dists[i, j]
- return rows, cols, vals, dists
- def fuzzy_simplicial_set(
- X,
- n_neighbors,
- random_state,
- metric,
- metric_kwds={},
- knn_indices=None,
- knn_dists=None,
- angular=False,
- set_op_mix_ratio=1.0,
- local_connectivity=1.0,
- apply_set_operations=True,
- verbose=False,
- return_dists=None,
- ):
- """Given a set of data X, a neighborhood size, and a measure of distance
- compute the fuzzy simplicial set (here represented as a fuzzy graph in
- the form of a sparse matrix) associated to the data. This is done by
- locally approximating geodesic distance at each point, creating a fuzzy
- simplicial set for each such point, and then combining all the local
- fuzzy simplicial sets into a global one via a fuzzy union.
- Parameters
- ----------
- X: array of shape (n_samples, n_features)
- The data to be modelled as a fuzzy simplicial set.
- n_neighbors: int
- The number of neighbors to use to approximate geodesic distance.
- Larger numbers induce more global estimates of the manifold that can
- miss finer detail, while smaller values will focus on fine manifold
- structure to the detriment of the larger picture.
- random_state: numpy RandomState or equivalent
- A state capable being used as a numpy random state.
- metric: string or function (optional, default 'euclidean')
- The metric to use to compute distances in high dimensional space.
- If a string is passed it must match a valid predefined metric. If
- a general metric is required a function that takes two 1d arrays and
- returns a float can be provided. For performance purposes it is
- required that this be a numba jit'd function. Valid string metrics
- include:
- * euclidean (or l2)
- * manhattan (or l1)
- * cityblock
- * braycurtis
- * canberra
- * chebyshev
- * correlation
- * cosine
- * dice
- * hamming
- * jaccard
- * kulsinski
- * ll_dirichlet
- * mahalanobis
- * matching
- * minkowski
- * rogerstanimoto
- * russellrao
- * seuclidean
- * sokalmichener
- * sokalsneath
- * sqeuclidean
- * yule
- * wminkowski
- Metrics that take arguments (such as minkowski, mahalanobis etc.)
- can have arguments passed via the metric_kwds dictionary. At this
- time care must be taken and dictionary elements must be ordered
- appropriately; this will hopefully be fixed in the future.
- metric_kwds: dict (optional, default {})
- Arguments to pass on to the metric, such as the ``p`` value for
- Minkowski distance.
- knn_indices: array of shape (n_samples, n_neighbors) (optional)
- If the k-nearest neighbors of each point has already been calculated
- you can pass them in here to save computation time. This should be
- an array with the indices of the k-nearest neighbors as a row for
- each data point.
- knn_dists: array of shape (n_samples, n_neighbors) (optional)
- If the k-nearest neighbors of each point has already been calculated
- you can pass them in here to save computation time. This should be
- an array with the distances of the k-nearest neighbors as a row for
- each data point.
- angular: bool (optional, default False)
- Whether to use angular/cosine distance for the random projection
- forest for seeding NN-descent to determine approximate nearest
- neighbors.
- set_op_mix_ratio: float (optional, default 1.0)
- Interpolate between (fuzzy) union and intersection as the set operation
- used to combine local fuzzy simplicial sets to obtain a global fuzzy
- simplicial sets. Both fuzzy set operations use the product t-norm.
- The value of this parameter should be between 0.0 and 1.0; a value of
- 1.0 will use a pure fuzzy union, while 0.0 will use a pure fuzzy
- intersection.
- local_connectivity: int (optional, default 1)
- The local connectivity required -- i.e. the number of nearest
- neighbors that should be assumed to be connected at a local level.
- The higher this value the more connected the manifold becomes
- locally. In practice this should be not more than the local intrinsic
- dimension of the manifold.
- verbose: bool (optional, default False)
- Whether to report information on the current progress of the algorithm.
- return_dists: bool or None (optional, default None)
- Whether to return the pairwise distance associated with each edge.
- Returns
- -------
- fuzzy_simplicial_set: coo_matrix
- A fuzzy simplicial set represented as a sparse matrix. The (i,
- j) entry of the matrix represents the membership strength of the
- 1-simplex between the ith and jth sample points.
- """
- if knn_indices is None or knn_dists is None:
- knn_indices, knn_dists, _ = nearest_neighbors(
- X,
- n_neighbors,
- metric,
- metric_kwds,
- angular,
- random_state,
- verbose=verbose,
- )
- knn_dists = knn_dists.astype(np.float32, copy=False)
- sigmas, rhos = smooth_knn_dist(
- knn_dists,
- float(n_neighbors),
- local_connectivity=float(local_connectivity),
- )
- rows, cols, vals, dists = compute_membership_strengths(
- knn_indices, knn_dists, sigmas, rhos, return_dists
- )
- result = scipy.sparse.coo_matrix(
- (vals, (rows, cols)), shape=(X.shape[0], X.shape[0])
- )
- result.eliminate_zeros()
- if apply_set_operations:
- transpose = result.transpose()
- prod_matrix = result.multiply(transpose)
- if set_op_mix_ratio == 1.0:
- # Default fuzzy union: the (1 - ratio) * prod_matrix term is zero, so
- # skip building/scaling/adding it (saves redundant sparse temporaries).
- result = result + transpose - prod_matrix
- elif set_op_mix_ratio == 0.0:
- # Pure fuzzy intersection.
- result = prod_matrix
- else:
- result = (
- set_op_mix_ratio * (result + transpose - prod_matrix)
- + (1.0 - set_op_mix_ratio) * prod_matrix
- )
- result.eliminate_zeros()
- if return_dists is None:
- return result, sigmas, rhos
- else:
- if return_dists:
- dmat = scipy.sparse.coo_matrix(
- (dists, (rows, cols)), shape=(X.shape[0], X.shape[0])
- )
- dists = dmat.maximum(dmat.transpose()).todok()
- else:
- dists = None
- return result, sigmas, rhos, dists
- @numba.njit()
- def fast_intersection(rows, cols, values, target, unknown_dist=1.0, far_dist=5.0):
- """Under the assumption of categorical distance for the intersecting
- simplicial set perform a fast intersection.
- Parameters
- ----------
- rows: array
- An array of the row of each non-zero in the sparse matrix
- representation.
- cols: array
- An array of the column of each non-zero in the sparse matrix
- representation.
- values: array
- An array of the value of each non-zero in the sparse matrix
- representation.
- target: array of shape (n_samples)
- The categorical labels to use in the intersection.
- unknown_dist: float (optional, default 1.0)
- The distance an unknown label (-1) is assumed to be from any point.
- far_dist float (optional, default 5.0)
- The distance between unmatched labels.
- Returns
- -------
- None
- """
- for nz in range(rows.shape[0]):
- i = rows[nz]
- j = cols[nz]
- if (target[i] == -1) or (target[j] == -1):
- values[nz] *= np.exp(-unknown_dist)
- elif target[i] != target[j]:
- values[nz] *= np.exp(-far_dist)
- return
- @numba.njit()
- def fast_metric_intersection(
- rows, cols, values, discrete_space, metric, metric_args, scale
- ):
- """Under the assumption of categorical distance for the intersecting
- simplicial set perform a fast intersection.
- Parameters
- ----------
- rows: array
- An array of the row of each non-zero in the sparse matrix
- representation.
- cols: array
- An array of the column of each non-zero in the sparse matrix
- representation.
- values: array of shape
- An array of the values of each non-zero in the sparse matrix
- representation.
- discrete_space: array of shape (n_samples, n_features)
- The vectors of categorical labels to use in the intersection.
- metric: numba function
- The function used to calculate distance over the target array.
- scale: float
- A scaling to apply to the metric.
- Returns
- -------
- None
- """
- for nz in range(rows.shape[0]):
- i = rows[nz]
- j = cols[nz]
- dist = metric(discrete_space[i], discrete_space[j], *metric_args)
- values[nz] *= np.exp(-(scale * dist))
- return
- @numba.njit()
- def reprocess_row(probabilities, k=15, n_iters=32):
- target = np.log2(k)
- lo = 0.0
- hi = NPY_INFINITY
- mid = 1.0
- for n in range(n_iters):
- psum = 0.0
- for j in range(probabilities.shape[0]):
- psum += pow(probabilities[j], mid)
- if np.fabs(psum - target) < SMOOTH_K_TOLERANCE:
- break
- if psum < target:
- hi = mid
- mid = (lo + hi) / 2.0
- else:
- lo = mid
- if hi == NPY_INFINITY:
- mid *= 2
- else:
- mid = (lo + hi) / 2.0
- return np.power(probabilities, mid)
- @numba.njit()
- def reset_local_metrics(simplicial_set_indptr, simplicial_set_data):
- for i in range(simplicial_set_indptr.shape[0] - 1):
- simplicial_set_data[simplicial_set_indptr[i] : simplicial_set_indptr[i + 1]] = (
- reprocess_row(
- simplicial_set_data[
- simplicial_set_indptr[i] : simplicial_set_indptr[i + 1]
- ]
- )
- )
- return
- def reset_local_connectivity(simplicial_set, reset_local_metric=False):
- """Reset the local connectivity requirement -- each data sample should
- have complete confidence in at least one 1-simplex in the simplicial set.
- We can enforce this by locally rescaling confidences, and then remerging the
- different local simplicial sets together.
- Parameters
- ----------
- simplicial_set: sparse matrix
- The simplicial set for which to recalculate with respect to local
- connectivity.
- Returns
- -------
- simplicial_set: sparse_matrix
- The recalculated simplicial set, now with the local connectivity
- assumption restored.
- """
- simplicial_set = normalize(simplicial_set, norm="max")
- if reset_local_metric:
- simplicial_set = simplicial_set.tocsr()
- reset_local_metrics(simplicial_set.indptr, simplicial_set.data)
- simplicial_set = simplicial_set.tocoo()
- transpose = simplicial_set.transpose()
- prod_matrix = simplicial_set.multiply(transpose)
- simplicial_set = simplicial_set + transpose - prod_matrix
- simplicial_set.eliminate_zeros()
- return simplicial_set
- def discrete_metric_simplicial_set_intersection(
- simplicial_set,
- discrete_space,
- unknown_dist=1.0,
- far_dist=5.0,
- metric=None,
- metric_kws={},
- metric_scale=1.0,
- ):
- """Combine a fuzzy simplicial set with another fuzzy simplicial set
- generated from discrete metric data using discrete distances. The target
- data is assumed to be categorical label data (a vector of labels),
- and this will update the fuzzy simplicial set to respect that label data.
- TODO: optional category cardinality based weighting of distance
- Parameters
- ----------
- simplicial_set: sparse matrix
- The input fuzzy simplicial set.
- discrete_space: array of shape (n_samples)
- The categorical labels to use in the intersection.
- unknown_dist: float (optional, default 1.0)
- The distance an unknown label (-1) is assumed to be from any point.
- far_dist: float (optional, default 5.0)
- The distance between unmatched labels.
- metric: str (optional, default None)
- If not None, then use this metric to determine the
- distance between values.
- metric_scale: float (optional, default 1.0)
- If using a custom metric scale the distance values by
- this value -- this controls the weighting of the
- intersection. Larger values weight more toward target.
- Returns
- -------
- simplicial_set: sparse matrix
- The resulting intersected fuzzy simplicial set.
- """
- simplicial_set = simplicial_set.tocoo()
- if metric is not None:
- # We presume target is now a 2d array, with each row being a
- # vector of target info
- if metric in dist.named_distances:
- metric_func = dist.named_distances[metric]
- else:
- raise ValueError("Discrete intersection metric is not recognized")
- fast_metric_intersection(
- simplicial_set.row,
- simplicial_set.col,
- simplicial_set.data,
- discrete_space,
- metric_func,
- tuple(metric_kws.values()),
- metric_scale,
- )
- else:
- fast_intersection(
- simplicial_set.row,
- simplicial_set.col,
- simplicial_set.data,
- discrete_space,
- unknown_dist,
- far_dist,
- )
- simplicial_set.eliminate_zeros()
- return reset_local_connectivity(simplicial_set)
- def general_simplicial_set_intersection(
- simplicial_set1, simplicial_set2, weight=0.5, right_complement=False
- ):
- if right_complement:
- result = simplicial_set1.tocoo()
- else:
- result = (simplicial_set1 + simplicial_set2).tocoo()
- left = simplicial_set1.tocsr()
- right = simplicial_set2.tocsr()
- sparse.general_sset_intersection(
- left.indptr,
- left.indices,
- left.data,
- right.indptr,
- right.indices,
- right.data,
- result.row,
- result.col,
- result.data,
- mix_weight=weight,
- right_complement=right_complement,
- )
- return result
- def general_simplicial_set_union(simplicial_set1, simplicial_set2):
- result = (simplicial_set1 + simplicial_set2).tocoo()
- left = simplicial_set1.tocsr()
- right = simplicial_set2.tocsr()
- sparse.general_sset_union(
- left.indptr,
- left.indices,
- left.data,
- right.indptr,
- right.indices,
- right.data,
- result.row,
- result.col,
- result.data,
- )
- return result
- def make_epochs_per_sample(weights, n_epochs):
- """Given a set of weights and number of epochs generate the number of
- epochs per sample for each weight.
- Parameters
- ----------
- weights: array of shape (n_1_simplices)
- The weights of how much we wish to sample each 1-simplex.
- n_epochs: int
- The total number of epochs we want to train for.
- Returns
- -------
- An array of number of epochs per sample, one for each 1-simplex.
- """
- result = np.full(weights.shape[0], -1.0, dtype=np.float64)
- n_samples = n_epochs * (weights / weights.max())
- positive = n_samples > 0 # compute the mask once instead of twice
- result[positive] = float(n_epochs) / np.float64(n_samples[positive])
- return result
- # scale coords so that the largest coordinate is max_coords, then add normal-distributed
- # noise with standard deviation noise
- def noisy_scale_coords(coords, random_state, max_coord=10.0, noise=0.0001):
- expansion = max_coord / np.abs(coords).max()
- coords = (coords * expansion).astype(np.float32)
- return coords + random_state.normal(scale=noise, size=coords.shape).astype(
- np.float32
- )
- @numba.njit()
- def _densmap_original_densities(
- head, tail, graph_data, dists_indptr, dists_indices, dists_data, ro, mu_sum
- ):
- for i in range(len(head)):
- j = head[i]
- k = tail[i]
- d_val = 0.0
- for idx in range(dists_indptr[j], dists_indptr[j + 1]):
- if dists_indices[idx] == k:
- d_val = dists_data[idx]
- break
- D = d_val * d_val
- mu = graph_data[i]
- ro[j] += mu * D
- ro[k] += mu * D
- mu_sum[j] += mu
- mu_sum[k] += mu
- @numba.njit()
- def _densmap_embedding_densities(
- head, tail, graph_data, dists_indptr, dists_indices, dists_data, re, mu_sum
- ):
- for i in range(len(head)):
- j = head[i]
- k = tail[i]
- d_val = 0.0
- for idx in range(dists_indptr[j], dists_indptr[j + 1]):
- if dists_indices[idx] == k:
- d_val = dists_data[idx]
- break
- mu = graph_data[i]
- weighted = mu * d_val
- re[j] += weighted
- re[k] += weighted
- mu_sum[j] += mu
- mu_sum[k] += mu
- def simplicial_set_embedding(
- data,
- graph,
- n_components,
- initial_alpha,
- a,
- b,
- gamma,
- negative_sample_rate,
- n_epochs,
- init,
- random_state,
- metric,
- metric_kwds,
- densmap,
- densmap_kwds,
- output_dens,
- output_metric=dist.named_distances_with_gradients["euclidean"],
- output_metric_kwds={},
- euclidean_output=True,
- parallel=False,
- verbose=False,
- tqdm_kwds=None,
- ):
- """Perform a fuzzy simplicial set embedding, using a specified
- initialisation method and then minimizing the fuzzy set cross entropy
- between the 1-skeletons of the high and low dimensional fuzzy simplicial
- sets.
- Parameters
- ----------
- data: array of shape (n_samples, n_features)
- The source data to be embedded by UMAP.
- graph: sparse matrix
- The 1-skeleton of the high dimensional fuzzy simplicial set as
- represented by a graph for which we require a sparse matrix for the
- (weighted) adjacency matrix.
- n_components: int
- The dimensionality of the euclidean space into which to embed the data.
- initial_alpha: float
- Initial learning rate for the SGD.
- a: float
- Parameter of differentiable approximation of right adjoint functor
- b: float
- Parameter of differentiable approximation of right adjoint functor
- gamma: float
- Weight to apply to negative samples.
- negative_sample_rate: int (optional, default 5)
- The number of negative samples to select per positive sample
- in the optimization process. Increasing this value will result
- in greater repulsive force being applied, greater optimization
- cost, but slightly more accuracy.
- n_epochs: int (optional, default 0), or list of int
- The number of training epochs to be used in optimizing the
- low dimensional embedding. Larger values result in more accurate
- embeddings. If 0 is specified a value will be selected based on
- the size of the input dataset (200 for large datasets, 500 for small).
- If a list of int is specified, then the intermediate embeddings at the
- different epochs specified in that list are returned in
- ``aux_data["embedding_list"]``.
- init: string
- How to initialize the low dimensional embedding. Options are:
- * 'spectral': use a spectral embedding of the fuzzy 1-skeleton
- * 'random': assign initial embedding positions at random.
- * 'pca': use the first n_components from PCA applied to the input data.
- * A numpy array of initial embedding positions.
- random_state: numpy RandomState or equivalent
- A state capable being used as a numpy random state.
- metric: string or callable
- The metric used to measure distance in high dimensional space; used if
- multiple connected components need to be layed out.
- metric_kwds: dict
- Key word arguments to be passed to the metric function; used if
- multiple connected components need to be layed out.
- densmap: bool
- Whether to use the density-augmented objective function to optimize
- the embedding according to the densMAP algorithm.
- densmap_kwds: dict
- Key word arguments to be used by the densMAP optimization.
- output_dens: bool
- Whether to output local radii in the original data and the embedding.
- output_metric: function
- Function returning the distance between two points in embedding space and
- the gradient of the distance wrt the first argument.
- output_metric_kwds: dict
- Key word arguments to be passed to the output_metric function.
- euclidean_output: bool
- Whether to use the faster code specialised for euclidean output metrics
- parallel: bool (optional, default False)
- Whether to run the computation using numba parallel.
- Running in parallel is non-deterministic, and is not used
- if a random seed has been set, to ensure reproducibility.
- verbose: bool (optional, default False)
- Whether to report information on the current progress of the algorithm.
- tqdm_kwds: dict
- Key word arguments to be used by the tqdm progress bar.
- Returns
- -------
- embedding: array of shape (n_samples, n_components)
- The optimized of ``graph`` into an ``n_components`` dimensional
- euclidean space.
- aux_data: dict
- Auxiliary output returned with the embedding. When densMAP extension
- is turned on, this dictionary includes local radii in the original
- data (``rad_orig``) and in the embedding (``rad_emb``).
- """
- graph = graph.tocoo()
- graph.sum_duplicates()
- n_vertices = graph.shape[1]
- # For smaller datasets we can use more epochs
- if graph.shape[0] <= 10000:
- default_epochs = 500
- else:
- default_epochs = 200
- # Use more epochs for densMAP
- if densmap:
- default_epochs += 200
- if n_epochs is None:
- n_epochs = default_epochs
- # If n_epoch is a list, get the maximum epoch to reach
- n_epochs_max = max(n_epochs) if isinstance(n_epochs, list) else n_epochs
- if n_epochs_max > 10:
- graph.data[graph.data < (graph.data.max() / float(n_epochs_max))] = 0.0
- else:
- graph.data[graph.data < (graph.data.max() / float(default_epochs))] = 0.0
- graph.eliminate_zeros()
- if isinstance(init, str) and init == "random":
- embedding = random_state.uniform(
- low=-10.0, high=10.0, size=(graph.shape[0], n_components)
- ).astype(np.float32)
- elif isinstance(init, str) and init == "pca":
- if scipy.sparse.issparse(data):
- pca = TruncatedSVD(n_components=n_components, random_state=random_state)
- else:
- pca = PCA(n_components=n_components, random_state=random_state)
- embedding = pca.fit_transform(data).astype(np.float32)
- embedding = noisy_scale_coords(
- embedding, random_state, max_coord=10, noise=0.0001
- )
- elif isinstance(init, str) and init == "spectral":
- embedding = spectral_layout(
- data,
- graph,
- n_components,
- random_state,
- metric=metric,
- metric_kwds=metric_kwds,
- )
- # We add a little noise to avoid local minima for optimization to come
- embedding = noisy_scale_coords(
- embedding, random_state, max_coord=10, noise=0.0001
- )
- elif isinstance(init, str) and init == "tswspectral":
- embedding = tswspectral_layout(
- data,
- graph,
- n_components,
- random_state,
- metric=metric,
- metric_kwds=metric_kwds,
- )
- embedding = noisy_scale_coords(
- embedding, random_state, max_coord=10, noise=0.0001
- )
- else:
- init_data = np.array(init)
- if len(init_data.shape) == 2:
- if np.unique(init_data, axis=0).shape[0] < init_data.shape[0]:
- tree = KDTree(init_data)
- dist, ind = tree.query(init_data, k=2)
- nndist = np.mean(dist[:, 1])
- embedding = init_data + random_state.normal(
- scale=0.001 * nndist, size=init_data.shape
- ).astype(np.float32)
- else:
- embedding = init_data
- epochs_per_sample = make_epochs_per_sample(graph.data, n_epochs_max)
- head = graph.row
- tail = graph.col
- weight = graph.data
- rng_state = random_state.randint(INT32_MIN, INT32_MAX, 3).astype(np.int64)
- aux_data = {}
- if densmap or output_dens:
- if verbose:
- print(ts() + " Computing original densities")
- dists = densmap_kwds["graph_dists"]
- mu_sum = np.zeros(n_vertices, dtype=np.float32)
- ro = np.zeros(n_vertices, dtype=np.float32)
- dists_csr = dists.tocsr()
- _densmap_original_densities(
- head,
- tail,
- graph.data,
- dists_csr.indptr,
- dists_csr.indices,
- dists_csr.data,
- ro,
- mu_sum,
- )
- epsilon = 1e-8
- ro = np.log(epsilon + (ro / mu_sum))
- if densmap:
- R = (ro - np.mean(ro)) / np.std(ro)
- densmap_kwds["mu"] = graph.data
- densmap_kwds["mu_sum"] = mu_sum
- densmap_kwds["R"] = R
- if output_dens:
- aux_data["rad_orig"] = ro
- embedding = (
- 10.0
- * (embedding - np.min(embedding, 0))
- / (np.max(embedding, 0) - np.min(embedding, 0))
- ).astype(np.float32, order="C")
- if euclidean_output:
- embedding = optimize_layout_euclidean(
- embedding,
- embedding,
- head,
- tail,
- n_epochs,
- n_vertices,
- epochs_per_sample,
- a,
- b,
- rng_state,
- gamma,
- initial_alpha,
- negative_sample_rate,
- parallel=parallel,
- verbose=verbose,
- densmap=densmap,
- densmap_kwds=densmap_kwds,
- tqdm_kwds=tqdm_kwds,
- move_other=True,
- )
- else:
- embedding = optimize_layout_generic(
- embedding,
- embedding,
- head,
- tail,
- n_epochs,
- n_vertices,
- epochs_per_sample,
- a,
- b,
- rng_state,
- gamma,
- initial_alpha,
- negative_sample_rate,
- output_metric,
- tuple(output_metric_kwds.values()),
- verbose=verbose,
- tqdm_kwds=tqdm_kwds,
- move_other=True,
- )
- if isinstance(embedding, list):
- aux_data["embedding_list"] = embedding
- embedding = embedding[-1].copy()
- if output_dens:
- if verbose:
- print(ts() + " Computing embedding densities")
- # Compute graph in embedding
- (
- knn_indices,
- knn_dists,
- rp_forest,
- ) = nearest_neighbors(
- embedding,
- densmap_kwds["n_neighbors"],
- "euclidean",
- {},
- False,
- random_state,
- verbose=verbose,
- )
- emb_graph, emb_sigmas, emb_rhos, emb_dists = fuzzy_simplicial_set(
- embedding,
- densmap_kwds["n_neighbors"],
- random_state,
- "euclidean",
- {},
- knn_indices,
- knn_dists,
- verbose=verbose,
- return_dists=True,
- )
- emb_graph = emb_graph.tocoo()
- emb_graph.sum_duplicates()
- emb_graph.eliminate_zeros()
- n_vertices = emb_graph.shape[1]
- mu_sum = np.zeros(n_vertices, dtype=np.float32)
- re = np.zeros(n_vertices, dtype=np.float32)
- head = emb_graph.row
- tail = emb_graph.col
- emb_dists_csr = emb_dists.tocsr()
- _densmap_embedding_densities(
- head,
- tail,
- emb_graph.data,
- emb_dists_csr.indptr,
- emb_dists_csr.indices,
- emb_dists_csr.data,
- re,
- mu_sum,
- )
- epsilon = 1e-8
- re = np.log(epsilon + (re / mu_sum))
- aux_data["rad_emb"] = re
- return embedding, aux_data
- @numba.njit()
- def init_transform(indices, weights, embedding):
- """Given indices and weights and an original embeddings
- initialize the positions of new points relative to the
- indices and weights (of their neighbors in the source data).
- Parameters
- ----------
- indices: array of shape (n_new_samples, n_neighbors)
- The indices of the neighbors of each new sample
- weights: array of shape (n_new_samples, n_neighbors)
- The membership strengths of associated 1-simplices
- for each of the new samples.
- embedding: array of shape (n_samples, dim)
- The original embedding of the source data.
- Returns
- -------
- new_embedding: array of shape (n_new_samples, dim)
- An initial embedding of the new sample points.
- """
- result = np.zeros((indices.shape[0], embedding.shape[1]), dtype=np.float32)
- for i in range(indices.shape[0]):
- for j in range(indices.shape[1]):
- for d in range(embedding.shape[1]):
- result[i, d] += weights[i, j] * embedding[indices[i, j], d]
- return result
- def init_graph_transform(graph, embedding):
- """Given a bipartite graph representing the 1-simplices and strengths between the
- new points and the original data set along with an embedding of the original points
- initialize the positions of new points relative to the strengths (of their neighbors in the source data).
- If a point is in our original data set it embeds at the original points coordinates.
- If a point has no neighbours in our original dataset it embeds as the np.nan vector.
- Otherwise a point is the weighted average of it's neighbours embedding locations.
- Parameters
- ----------
- graph: csr_matrix (n_new_samples, n_samples)
- A matrix indicating the 1-simplices and their associated strengths. These strengths should
- be values between zero and one and not normalized. One indicating that the new point was identical
- to one of our original points.
- embedding: array of shape (n_samples, dim)
- The original embedding of the source data.
- Returns
- -------
- new_embedding: array of shape (n_new_samples, dim)
- An initial embedding of the new sample points.
- """
- n_new = graph.shape[0]
- result = np.zeros((n_new, embedding.shape[1]), dtype=np.float32)
- row_nnz = np.diff(graph.indptr)
- empty_mask = row_nnz == 0
- result[empty_mask] = np.nan
- has_exact = np.zeros(n_new, dtype=bool)
- exact_data_mask = graph.data == 1.0
- if exact_data_mask.any():
- exact_positions = np.where(exact_data_mask)[0]
- exact_rows = np.searchsorted(graph.indptr, exact_positions, side="right") - 1
- _, first_idx = np.unique(exact_rows, return_index=True)
- unique_rows = exact_rows[first_idx]
- exact_cols = graph.indices[exact_positions[first_idx]]
- has_exact[unique_rows] = True
- result[unique_rows] = embedding[exact_cols]
- avg_mask = ~empty_mask & ~has_exact
- if np.any(avg_mask):
- avg_graph = graph[avg_mask]
- row_sums = np.array(avg_graph.sum(axis=1)).flatten()
- inv_sums = scipy.sparse.diags(1.0 / row_sums)
- normalized = inv_sums @ avg_graph
- result[avg_mask] = (normalized @ embedding).astype(np.float32)
- return result
- @numba.njit()
- def init_update(current_init, n_original_samples, indices):
- for i in range(n_original_samples, indices.shape[0]):
- n = 0
- for j in range(indices.shape[1]):
- for d in range(current_init.shape[1]):
- if indices[i, j] < n_original_samples:
- n += 1
- current_init[i, d] += current_init[indices[i, j], d]
- for d in range(current_init.shape[1]):
- current_init[i, d] /= n
- return
- def find_ab_params(spread, min_dist):
- """Fit a, b params for the differentiable curve used in lower
- dimensional fuzzy simplicial complex construction. We want the
- smooth curve (from a pre-defined family with simple gradient) that
- best matches an offset exponential decay.
- """
- def curve(x, a, b):
- return 1.0 / (1.0 + a * x ** (2 * b))
- xv = np.linspace(0, spread * 3, 300)
- yv = np.zeros(xv.shape)
- yv[xv < min_dist] = 1.0
- yv[xv >= min_dist] = np.exp(-(xv[xv >= min_dist] - min_dist) / spread)
- params, covar = curve_fit(curve, xv, yv)
- return params[0], params[1]
- class UMAP(BaseEstimator, ClassNamePrefixFeaturesOutMixin):
- """Uniform Manifold Approximation and Projection
- Finds a low dimensional embedding of the data that approximates
- an underlying manifold.
- Parameters
- ----------
- n_neighbors: float (optional, default 15)
- The size of local neighborhood (in terms of number of neighboring
- sample points) used for manifold approximation. Larger values
- result in more global views of the manifold, while smaller
- values result in more local data being preserved. In general
- values should be in the range 2 to 100.
- n_components: int (optional, default 2)
- The dimension of the space to embed into. This defaults to 2 to
- provide easy visualization, but can reasonably be set to any
- integer value in the range 2 to 100.
- metric: string or function (optional, default 'euclidean')
- The metric to use to compute distances in high dimensional space.
- If a string is passed it must match a valid predefined metric. If
- a general metric is required a function that takes two 1d arrays and
- returns a float can be provided. For performance purposes it is
- required that this be a numba jit'd function. Valid string metrics
- include:
- * euclidean
- * manhattan
- * chebyshev
- * minkowski
- * canberra
- * braycurtis
- * mahalanobis
- * wminkowski
- * seuclidean
- * cosine
- * correlation
- * haversine
- * hamming
- * jaccard
- * dice
- * russelrao
- * kulsinski
- * ll_dirichlet
- * hellinger
- * rogerstanimoto
- * sokalmichener
- * sokalsneath
- * yule
- Metrics that take arguments (such as minkowski, mahalanobis etc.)
- can have arguments passed via the metric_kwds dictionary. At this
- time care must be taken and dictionary elements must be ordered
- appropriately; this will hopefully be fixed in the future.
- n_epochs: int (optional, default None)
- The number of training epochs to be used in optimizing the
- low dimensional embedding. Larger values result in more accurate
- embeddings. If None is specified a value will be selected based on
- the size of the input dataset (200 for large datasets, 500 for small).
- learning_rate: float (optional, default 1.0)
- The initial learning rate for the embedding optimization.
- init: string (optional, default 'spectral')
- How to initialize the low dimensional embedding. Options are:
- * 'spectral': use a spectral embedding of the fuzzy 1-skeleton
- * 'random': assign initial embedding positions at random.
- * 'pca': use the first n_components from PCA applied to the
- input data.
- * 'tswspectral': use a spectral embedding of the fuzzy
- 1-skeleton, using a truncated singular value decomposition to
- "warm" up the eigensolver. This is intended as an alternative
- to the 'spectral' method, if that takes an excessively long
- time to complete initialization (or fails to complete).
- * A numpy array of initial embedding positions.
- min_dist: float (optional, default 0.1)
- The effective minimum distance between embedded points. Smaller values
- will result in a more clustered/clumped embedding where nearby points
- on the manifold are drawn closer together, while larger values will
- result on a more even dispersal of points. The value should be set
- relative to the ``spread`` value, which determines the scale at which
- embedded points will be spread out.
- spread: float (optional, default 1.0)
- The effective scale of embedded points. In combination with ``min_dist``
- this determines how clustered/clumped the embedded points are.
- low_memory: bool (optional, default True)
- For some datasets the nearest neighbor computation can consume a lot of
- memory. If you find that UMAP is failing due to memory constraints
- consider setting this option to True. This approach is more
- computationally expensive, but avoids excessive memory use.
- set_op_mix_ratio: float (optional, default 1.0)
- Interpolate between (fuzzy) union and intersection as the set operation
- used to combine local fuzzy simplicial sets to obtain a global fuzzy
- simplicial sets. Both fuzzy set operations use the product t-norm.
- The value of this parameter should be between 0.0 and 1.0; a value of
- 1.0 will use a pure fuzzy union, while 0.0 will use a pure fuzzy
- intersection.
- local_connectivity: int (optional, default 1)
- The local connectivity required -- i.e. the number of nearest
- neighbors that should be assumed to be connected at a local level.
- The higher this value the more connected the manifold becomes
- locally. In practice this should be not more than the local intrinsic
- dimension of the manifold.
- repulsion_strength: float (optional, default 1.0)
- Weighting applied to negative samples in low dimensional embedding
- optimization. Values higher than one will result in greater weight
- being given to negative samples.
- negative_sample_rate: int (optional, default 5)
- The number of negative samples to select per positive sample
- in the optimization process. Increasing this value will result
- in greater repulsive force being applied, greater optimization
- cost, but slightly more accuracy.
- transform_queue_size: float (optional, default 4.0)
- For transform operations (embedding new points using a trained model
- this will control how aggressively to search for nearest neighbors.
- Larger values will result in slower performance but more accurate
- nearest neighbor evaluation.
- a: float (optional, default None)
- More specific parameters controlling the embedding. If None these
- values are set automatically as determined by ``min_dist`` and
- ``spread``.
- b: float (optional, default None)
- More specific parameters controlling the embedding. If None these
- values are set automatically as determined by ``min_dist`` and
- ``spread``.
- random_state: int, RandomState instance or None, optional (default: None)
- If int, random_state is the seed used by the random number generator;
- If RandomState instance, random_state is the random number generator;
- If None, the random number generator is the RandomState instance used
- by `np.random`.
- metric_kwds: dict (optional, default None)
- Arguments to pass on to the metric, such as the ``p`` value for
- Minkowski distance. If None then no arguments are passed on.
- angular_rp_forest: bool (optional, default False)
- Whether to use an angular random projection forest to initialise
- the approximate nearest neighbor search. This can be faster, but is
- mostly only useful for a metric that uses an angular style distance such
- as cosine, correlation etc. In the case of those metrics angular forests
- will be chosen automatically.
- target_n_neighbors: int (optional, default -1)
- The number of nearest neighbors to use to construct the target simplicial
- set. If set to -1 use the ``n_neighbors`` value.
- target_metric: string or callable (optional, default 'categorical')
- The metric used to measure distance for a target array is using supervised
- dimension reduction. By default this is 'categorical' which will measure
- distance in terms of whether categories match or are different. Furthermore,
- if semi-supervised is required target values of -1 will be trated as
- unlabelled under the 'categorical' metric. If the target array takes
- continuous values (e.g. for a regression problem) then metric of 'l1'
- or 'l2' is probably more appropriate.
- target_metric_kwds: dict (optional, default None)
- Keyword argument to pass to the target metric when performing
- supervised dimension reduction. If None then no arguments are passed on.
- target_weight: float (optional, default 0.5)
- weighting factor between data topology and target topology. A value of
- 0.0 weights predominantly on data, a value of 1.0 places a strong emphasis on
- target. The default of 0.5 balances the weighting equally between data and
- target.
- transform_seed: int (optional, default 42)
- Random seed used for the stochastic aspects of the transform operation.
- This ensures consistency in transform operations.
- verbose: bool (optional, default False)
- Controls verbosity of logging.
- tqdm_kwds: dict (optional, defaul None)
- Key word arguments to be used by the tqdm progress bar.
- unique: bool (optional, default False)
- Controls if the rows of your data should be uniqued before being
- embedded. If you have more duplicates than you have ``n_neighbors``
- you can have the identical data points lying in different regions of
- your space. It also violates the definition of a metric.
- For to map from internal structures back to your data use the variable
- _unique_inverse_.
- densmap: bool (optional, default False)
- Specifies whether the density-augmented objective of densMAP
- should be used for optimization. Turning on this option generates
- an embedding where the local densities are encouraged to be correlated
- with those in the original space. Parameters below with the prefix 'dens'
- further control the behavior of this extension.
- dens_lambda: float (optional, default 2.0)
- Controls the regularization weight of the density correlation term
- in densMAP. Higher values prioritize density preservation over the
- UMAP objective, and vice versa for values closer to zero. Setting this
- parameter to zero is equivalent to running the original UMAP algorithm.
- dens_frac: float (optional, default 0.3)
- Controls the fraction of epochs (between 0 and 1) where the
- density-augmented objective is used in densMAP. The first
- (1 - dens_frac) fraction of epochs optimize the original UMAP objective
- before introducing the density correlation term.
- dens_var_shift: float (optional, default 0.1)
- A small constant added to the variance of local radii in the
- embedding when calculating the density correlation objective to
- prevent numerical instability from dividing by a small number
- output_dens: float (optional, default False)
- Determines whether the local radii of the final embedding (an inverse
- measure of local density) are computed and returned in addition to
- the embedding. If set to True, local radii of the original data
- are also included in the output for comparison; the output is a tuple
- (embedding, original local radii, embedding local radii). This option
- can also be used when densmap=False to calculate the densities for
- UMAP embeddings.
- disconnection_distance: float (optional, default np.inf or maximal value for bounded distances)
- Disconnect any vertices of distance greater than or equal to disconnection_distance when approximating the
- manifold via our k-nn graph. This is particularly useful in the case that you have a bounded metric. The
- UMAP assumption that we have a connected manifold can be problematic when you have points that are maximally
- different from all the rest of your data. The connected manifold assumption will make such points have perfect
- similarity to a random set of other points. Too many such points will artificially connect your space.
- precomputed_knn: tuple (optional, default (None,None,None))
- If the k-nearest neighbors of each point has already been calculated you
- can pass them in here to save computation time. The number of nearest
- neighbors in the precomputed_knn must be greater or equal to the
- n_neighbors parameter. This should be a tuple containing the output
- of the nearest_neighbors() function or attributes from a previously fit
- UMAP object; (knn_indices, knn_dists, knn_search_index). If you wish to use
- k-nearest neighbors data calculated by another package then provide a tuple of
- the form (knn_indices, knn_dists). The contents of the tuple should be two numpy
- arrays of shape (N, n_neighbors) where N is the number of items in the
- input data. The first array should be the integer indices of the nearest
- neighbors, and the second array should be the corresponding distances. The
- nearest neighbor of each item should be itself, e.g. the nearest neighbor of
- item 0 should be 0, the nearest neighbor of item 1 is 1 and so on. Please note
- that you will *not* be able to transform new data in this case.
- """
- def __init__(
- self,
- n_neighbors=15,
- n_components=2,
- metric="euclidean",
- metric_kwds=None,
- output_metric="euclidean",
- output_metric_kwds=None,
- n_epochs=None,
- learning_rate=1.0,
- init="spectral",
- min_dist=0.1,
- spread=1.0,
- low_memory=True,
- n_jobs=-1,
- set_op_mix_ratio=1.0,
- local_connectivity=1.0,
- repulsion_strength=1.0,
- negative_sample_rate=5,
- transform_queue_size=4.0,
- a=None,
- b=None,
- random_state=None,
- angular_rp_forest=False,
- target_n_neighbors=-1,
- target_metric="categorical",
- target_metric_kwds=None,
- target_weight=0.5,
- transform_seed=42,
- transform_mode="embedding",
- force_approximation_algorithm=False,
- verbose=False,
- tqdm_kwds=None,
- unique=False,
- densmap=False,
- dens_lambda=2.0,
- dens_frac=0.3,
- dens_var_shift=0.1,
- output_dens=False,
- disconnection_distance=None,
- precomputed_knn=(None, None, None),
- ):
- self.n_neighbors = n_neighbors
- self.metric = metric
- self.output_metric = output_metric
- self.target_metric = target_metric
- self.metric_kwds = metric_kwds
- self.output_metric_kwds = output_metric_kwds
- self.n_epochs = n_epochs
- self.init = init
- self.n_components = n_components
- self.repulsion_strength = repulsion_strength
- self.learning_rate = learning_rate
- self.spread = spread
- self.min_dist = min_dist
- self.low_memory = low_memory
- self.set_op_mix_ratio = set_op_mix_ratio
- self.local_connectivity = local_connectivity
- self.negative_sample_rate = negative_sample_rate
- self.random_state = random_state
- self.angular_rp_forest = angular_rp_forest
- self.transform_queue_size = transform_queue_size
- self.target_n_neighbors = target_n_neighbors
- self.target_metric = target_metric
- self.target_metric_kwds = target_metric_kwds
- self.target_weight = target_weight
- self.transform_seed = transform_seed
- self.transform_mode = transform_mode
- self.force_approximation_algorithm = force_approximation_algorithm
- self.verbose = verbose
- self.tqdm_kwds = tqdm_kwds
- self.unique = unique
- self.densmap = densmap
- self.dens_lambda = dens_lambda
- self.dens_frac = dens_frac
- self.dens_var_shift = dens_var_shift
- self.output_dens = output_dens
- self.disconnection_distance = disconnection_distance
- self.precomputed_knn = precomputed_knn
- self.n_jobs = n_jobs
- self.a = a
- self.b = b
- def _validate_parameters(self):
- if self.set_op_mix_ratio < 0.0 or self.set_op_mix_ratio > 1.0:
- raise ValueError("set_op_mix_ratio must be between 0.0 and 1.0")
- if self.repulsion_strength < 0.0:
- raise ValueError("repulsion_strength cannot be negative")
- if self.min_dist > self.spread:
- raise ValueError("min_dist must be less than or equal to spread")
- if self.min_dist < 0.0:
- raise ValueError("min_dist cannot be negative")
- if not isinstance(self.init, str) and not isinstance(self.init, np.ndarray):
- raise ValueError("init must be a string or ndarray")
- if isinstance(self.init, str) and self.init not in (
- "pca",
- "spectral",
- "random",
- "tswspectral",
- ):
- raise ValueError(
- 'string init values must be one of: "pca", "tswspectral",'
- ' "spectral" or "random"'
- )
- if (
- isinstance(self.init, np.ndarray)
- and self.init.shape[1] != self.n_components
- ):
- raise ValueError("init ndarray must match n_components value")
- if not isinstance(self.metric, str) and not callable(self.metric):
- raise ValueError("metric must be string or callable")
- if self.negative_sample_rate < 0:
- raise ValueError("negative sample rate must be positive")
- if self._initial_alpha < 0.0:
- raise ValueError("learning_rate must be positive")
- if self.n_neighbors < 2:
- raise ValueError("n_neighbors must be greater than 1")
- if self.target_n_neighbors < 2 and self.target_n_neighbors != -1:
- raise ValueError("target_n_neighbors must be greater than 1")
- if not isinstance(self.n_components, int):
- if isinstance(self.n_components, str):
- raise ValueError("n_components must be an int")
- if self.n_components % 1 != 0:
- raise ValueError("n_components must be a whole number")
- try:
- # this will convert other types of int (eg. numpy int64)
- # to Python int
- self.n_components = int(self.n_components)
- except ValueError:
- raise ValueError("n_components must be an int")
- if self.n_components < 1:
- raise ValueError("n_components must be greater than 0")
- self.n_epochs_list = None
- if (
- isinstance(self.n_epochs, list)
- or isinstance(self.n_epochs, tuple)
- or isinstance(self.n_epochs, np.ndarray)
- ):
- if not issubclass(
- np.array(self.n_epochs).dtype.type, np.integer
- ) or not np.all(np.array(self.n_epochs) >= 0):
- raise ValueError(
- "n_epochs must be a nonnegative integer "
- "or a list of nonnegative integers"
- )
- self.n_epochs_list = list(self.n_epochs)
- elif self.n_epochs is not None and (
- self.n_epochs < 0 or not isinstance(self.n_epochs, int)
- ):
- raise ValueError(
- "n_epochs must be a nonnegative integer "
- "or a list of nonnegative integers"
- )
- if self.metric_kwds is None:
- self._metric_kwds = {}
- else:
- self._metric_kwds = self.metric_kwds
- if self.output_metric_kwds is None:
- self._output_metric_kwds = {}
- else:
- self._output_metric_kwds = self.output_metric_kwds
- if self.target_metric_kwds is None:
- self._target_metric_kwds = {}
- else:
- self._target_metric_kwds = self.target_metric_kwds
- # check sparsity of data upfront to set proper _input_distance_func &
- # save repeated checks later on
- if scipy.sparse.isspmatrix_csr(self._raw_data):
- self._sparse_data = True
- else:
- self._sparse_data = False
- # set input distance metric & inverse_transform distance metric
- if callable(self.metric):
- in_returns_grad = self._check_custom_metric(
- self.metric, self._metric_kwds, self._raw_data
- )
- if in_returns_grad:
- _m = self.metric
- @numba.njit(fastmath=True)
- def _dist_only(x, y, *kwds):
- return _m(x, y, *kwds)[0]
- self._input_distance_func = _dist_only
- self._inverse_distance_func = self.metric
- else:
- self._input_distance_func = self.metric
- self._inverse_distance_func = None
- warn(
- "custom distance metric does not return gradient; inverse_transform will be unavailable. "
- "To enable using inverse_transform method, define a distance function that returns a tuple "
- "of (distance [float], gradient [np.array])"
- )
- elif self.metric == "precomputed":
- if self.unique:
- raise ValueError("unique is poorly defined on a precomputed metric")
- warn("using precomputed metric; inverse_transform will be unavailable")
- self._input_distance_func = self.metric
- self._inverse_distance_func = None
- elif self.metric == "hellinger" and self._raw_data.min() < 0:
- raise ValueError("Metric 'hellinger' does not support negative values")
- elif self.metric in dist.named_distances:
- if self._sparse_data:
- if self.metric in sparse.sparse_named_distances:
- self._input_distance_func = sparse.sparse_named_distances[
- self.metric
- ]
- else:
- raise ValueError(
- "Metric {} is not supported for sparse data".format(self.metric)
- )
- else:
- self._input_distance_func = dist.named_distances[self.metric]
- try:
- self._inverse_distance_func = dist.named_distances_with_gradients[
- self.metric
- ]
- except KeyError:
- warn(
- "gradient function is not yet implemented for {} distance metric; "
- "inverse_transform will be unavailable".format(self.metric)
- )
- self._inverse_distance_func = None
- elif self.metric in pynn_named_distances:
- if self._sparse_data:
- if self.metric in pynn_sparse_named_distances:
- self._input_distance_func = pynn_sparse_named_distances[self.metric]
- else:
- raise ValueError(
- "Metric {} is not supported for sparse data".format(self.metric)
- )
- else:
- self._input_distance_func = pynn_named_distances[self.metric]
- warn(
- "gradient function is not yet implemented for {} distance metric; "
- "inverse_transform will be unavailable".format(self.metric)
- )
- self._inverse_distance_func = None
- else:
- raise ValueError("metric is neither callable nor a recognised string")
- # set output distance metric
- if callable(self.output_metric):
- out_returns_grad = self._check_custom_metric(
- self.output_metric, self._output_metric_kwds
- )
- if out_returns_grad:
- self._output_distance_func = self.output_metric
- else:
- raise ValueError(
- "custom output_metric must return a tuple of (distance [float], gradient [np.array])"
- )
- elif self.output_metric == "precomputed":
- raise ValueError("output_metric cannnot be 'precomputed'")
- elif self.output_metric in dist.named_distances_with_gradients:
- self._output_distance_func = dist.named_distances_with_gradients[
- self.output_metric
- ]
- elif self.output_metric in dist.named_distances:
- raise ValueError(
- "gradient function is not yet implemented for {}.".format(
- self.output_metric
- )
- )
- else:
- raise ValueError(
- "output_metric is neither callable nor a recognised string"
- )
- # set angularity for NN search based on metric
- if self.metric in (
- "cosine",
- "correlation",
- "dice",
- "jaccard",
- "ll_dirichlet",
- "hellinger",
- ):
- self.angular_rp_forest = True
- if self.n_jobs < -1 or self.n_jobs == 0:
- raise ValueError("n_jobs must be a postive integer, or -1 (for all cores)")
- if self.n_jobs != 1 and self.random_state is not None:
- self.n_jobs = 1
- warn(
- f"n_jobs value {self.n_jobs} overridden to 1 by setting random_state. Use no seed for parallelism."
- )
- if self.dens_lambda < 0.0:
- raise ValueError("dens_lambda cannot be negative")
- if self.dens_frac < 0.0 or self.dens_frac > 1.0:
- raise ValueError("dens_frac must be between 0.0 and 1.0")
- if self.dens_var_shift < 0.0:
- raise ValueError("dens_var_shift cannot be negative")
- self._densmap_kwds = {
- "lambda": self.dens_lambda if self.densmap else 0.0,
- "frac": self.dens_frac if self.densmap else 0.0,
- "var_shift": self.dens_var_shift,
- "n_neighbors": self.n_neighbors,
- }
- if self.densmap:
- if self.output_metric not in ("euclidean", "l2"):
- raise ValueError(
- "Non-Euclidean output metric not supported for densMAP."
- )
- # This will be used to prune all edges of greater than a fixed value from our knn graph.
- # We have preset defaults described in DISCONNECTION_DISTANCES for our bounded measures.
- # Otherwise a user can pass in their own value.
- if self.disconnection_distance is None:
- self._disconnection_distance = DISCONNECTION_DISTANCES.get(
- self.metric, np.inf
- )
- elif isinstance(self.disconnection_distance, int) or isinstance(
- self.disconnection_distance, float
- ):
- self._disconnection_distance = self.disconnection_distance
- else:
- raise ValueError("disconnection_distance must either be None or a numeric.")
- if self.tqdm_kwds is None:
- self.tqdm_kwds = {}
- else:
- if isinstance(self.tqdm_kwds, dict) is False:
- raise ValueError(
- "tqdm_kwds must be a dictionary. Please provide valid tqdm "
- "parameters as key value pairs. Valid tqdm parameters can be "
- "found here: https://github.com/tqdm/tqdm#parameters"
- )
- if "desc" not in self.tqdm_kwds:
- self.tqdm_kwds["desc"] = "Epochs completed"
- if "bar_format" not in self.tqdm_kwds:
- bar_f = "{desc}: {percentage:3.0f}%| {bar} {n_fmt}/{total_fmt} [{elapsed}]"
- self.tqdm_kwds["bar_format"] = bar_f
- if hasattr(self, "knn_dists") and self.knn_dists is not None:
- if self.unique:
- raise ValueError(
- "unique is not currently available for " "precomputed_knn."
- )
- if not isinstance(self.knn_indices, np.ndarray):
- raise ValueError("precomputed_knn[0] must be ndarray object.")
- if not isinstance(self.knn_dists, np.ndarray):
- raise ValueError("precomputed_knn[1] must be ndarray object.")
- if self.knn_dists.shape != self.knn_indices.shape:
- raise ValueError(
- "precomputed_knn[0] and precomputed_knn[1]"
- " must be numpy arrays of the same size."
- )
- # #848: warn but proceed if no search index is present
- if not isinstance(self.knn_search_index, NNDescent):
- warn(
- "precomputed_knn[2] (knn_search_index) "
- "is not an NNDescent object: transforming new data with transform "
- "will be unavailable."
- )
- if self.knn_dists.shape[1] < self.n_neighbors:
- warn(
- "precomputed_knn has a lower number of neighbors than "
- "n_neighbors parameter. precomputed_knn will be ignored"
- " and the k-nn will be computed normally."
- )
- self.knn_indices = None
- self.knn_dists = None
- self.knn_search_index = None
- elif self.knn_dists.shape[0] != self._raw_data.shape[0]:
- warn(
- "precomputed_knn has a different number of samples than the"
- " data you are fitting. precomputed_knn will be ignored and"
- "the k-nn will be computed normally."
- )
- self.knn_indices = None
- self.knn_dists = None
- self.knn_search_index = None
- elif (
- self.knn_dists.shape[0] < 4096
- and not self.force_approximation_algorithm
- ):
- # force_approximation_algorithm is irrelevant for pre-computed knn
- # always set it to True which keeps downstream code paths working
- self.force_approximation_algorithm = True
- elif self.knn_dists.shape[1] > self.n_neighbors:
- # if k for precomputed_knn larger than n_neighbors we simply prune it
- self.knn_indices = self.knn_indices[:, : self.n_neighbors]
- self.knn_dists = self.knn_dists[:, : self.n_neighbors]
- def _check_custom_metric(self, metric, kwds, data=None):
- # quickly check to determine whether user-defined
- # self.metric/self.output_metric returns both distance and gradient
- if data is not None:
- # if checking the high-dimensional distance metric, test directly on
- # input data so we don't risk violating any assumptions potentially
- # hard-coded in the metric (e.g., bounded; non-negative)
- x, y = data[np.random.randint(0, data.shape[0], 2)]
- else:
- # if checking the manifold distance metric, simulate some data on a
- # reasonable interval with output dimensionality
- x, y = np.random.uniform(low=-10, high=10, size=(2, self.n_components))
- if scipy.sparse.issparse(data):
- metric_out = metric(x.indices, x.data, y.indices, y.data, **kwds)
- else:
- metric_out = metric(x, y, **kwds)
- # True if metric returns iterable of length 2, False otherwise
- return hasattr(metric_out, "__iter__") and len(metric_out) == 2
- def _populate_combined_params(self, *models):
- self.n_neighbors = flattened([m.n_neighbors for m in models])
- self.metric = flattened([m.metric for m in models])
- self.metric_kwds = flattened([m.metric_kwds for m in models])
- self.output_metric = flattened([m.output_metric for m in models])
- self.n_epochs = flattened(
- [m.n_epochs if m.n_epochs is not None else -1 for m in models]
- )
- if all([x == -1 for x in self.n_epochs]):
- self.n_epochs = None
- self.init = flattened([m.init for m in models])
- self.n_components = flattened([m.n_components for m in models])
- self.repulsion_strength = flattened([m.repulsion_strength for m in models])
- self.learning_rate = flattened([m.learning_rate for m in models])
- self.spread = flattened([m.spread for m in models])
- self.min_dist = flattened([m.min_dist for m in models])
- self.low_memory = flattened([m.low_memory for m in models])
- self.set_op_mix_ratio = flattened([m.set_op_mix_ratio for m in models])
- self.local_connectivity = flattened([m.local_connectivity for m in models])
- self.negative_sample_rate = flattened([m.negative_sample_rate for m in models])
- self.random_state = flattened([m.random_state for m in models])
- self.angular_rp_forest = flattened([m.angular_rp_forest for m in models])
- self.transform_queue_size = flattened([m.transform_queue_size for m in models])
- self.target_n_neighbors = flattened([m.target_n_neighbors for m in models])
- self.target_metric = flattened([m.target_metric for m in models])
- self.target_metric_kwds = flattened([m.target_metric_kwds for m in models])
- self.target_weight = flattened([m.target_weight for m in models])
- self.transform_seed = flattened([m.transform_seed for m in models])
- self.force_approximation_algorithm = flattened(
- [m.force_approximation_algorithm for m in models]
- )
- self.verbose = flattened([m.verbose for m in models])
- self.unique = flattened([m.unique for m in models])
- self.densmap = flattened([m.densmap for m in models])
- self.dens_lambda = flattened([m.dens_lambda for m in models])
- self.dens_frac = flattened([m.dens_frac for m in models])
- self.dens_var_shift = flattened([m.dens_var_shift for m in models])
- self.output_dens = flattened([m.output_dens for m in models])
- self.a = flattened([m.a for m in models])
- self.b = flattened([m.b for m in models])
- self._a = flattened([m._a for m in models])
- self._b = flattened([m._b for m in models])
- def __mul__(self, other):
- check_is_fitted(
- self, attributes=["graph_"], msg="Only fitted UMAP models can be combined"
- )
- check_is_fitted(
- other, attributes=["graph_"], msg="Only fitted UMAP models can be combined"
- )
- if self.graph_.shape[0] != other.graph_.shape[0]:
- raise ValueError("Only models with the equivalent samples can be combined")
- result = UMAP()
- result._populate_combined_params(self, other)
- result.graph_ = general_simplicial_set_intersection(
- self.graph_, other.graph_, 0.5
- )
- result.graph_ = reset_local_connectivity(result.graph_, True)
- if scipy.sparse.csgraph.connected_components(result.graph_)[0] > 1:
- warn(
- "Combined graph is not connected but multi-component layout is unsupported. "
- "Falling back to random initialization."
- )
- init = "random"
- else:
- init = "spectral"
- result.densmap = np.any(result.densmap)
- result.output_dens = np.any(result.output_dens)
- result._densmap_kwds = {
- "lambda": np.max(result.dens_lambda),
- "frac": np.max(result.dens_frac),
- "var_shift": np.max(result.dens_var_shift),
- "n_neighbors": np.max(result.n_neighbors),
- }
- if result.n_epochs is None:
- n_epochs = None
- else:
- n_epochs = np.max(result.n_epochs)
- result.embedding_, aux_data = simplicial_set_embedding(
- None,
- result.graph_,
- np.min(result.n_components),
- np.min(result.learning_rate),
- np.mean(result._a),
- np.mean(result._b),
- np.mean(result.repulsion_strength),
- np.mean(result.negative_sample_rate),
- n_epochs,
- init,
- check_random_state(42),
- "euclidean",
- {},
- result.densmap,
- result._densmap_kwds,
- result.output_dens,
- parallel=False,
- verbose=bool(np.max(result.verbose)),
- tqdm_kwds=self.tqdm_kwds,
- )
- if result.output_dens:
- result.rad_orig_ = aux_data["rad_orig"]
- result.rad_emb_ = aux_data["rad_emb"]
- return result
- def __add__(self, other):
- check_is_fitted(
- self, attributes=["graph_"], msg="Only fitted UMAP models can be combined"
- )
- check_is_fitted(
- other, attributes=["graph_"], msg="Only fitted UMAP models can be combined"
- )
- if self.graph_.shape[0] != other.graph_.shape[0]:
- raise ValueError("Only models with the equivalent samples can be combined")
- result = UMAP()
- result._populate_combined_params(self, other)
- result.graph_ = general_simplicial_set_union(self.graph_, other.graph_)
- result.graph_ = reset_local_connectivity(result.graph_, True)
- if scipy.sparse.csgraph.connected_components(result.graph_)[0] > 1:
- warn(
- "Combined graph is not connected but mult-component layout is unsupported. "
- "Falling back to random initialization."
- )
- init = "random"
- else:
- init = "spectral"
- result.densmap = np.any(result.densmap)
- result.output_dens = np.any(result.output_dens)
- result._densmap_kwds = {
- "lambda": np.max(result.dens_lambda),
- "frac": np.max(result.dens_frac),
- "var_shift": np.max(result.dens_var_shift),
- "n_neighbors": np.max(result.n_neighbors),
- }
- if result.n_epochs is None:
- n_epochs = None
- else:
- n_epochs = np.max(result.n_epochs)
- result.embedding_, aux_data = simplicial_set_embedding(
- None,
- result.graph_,
- np.min(result.n_components),
- np.min(result.learning_rate),
- np.mean(result._a),
- np.mean(result._b),
- np.mean(result.repulsion_strength),
- np.mean(result.negative_sample_rate),
- n_epochs,
- init,
- check_random_state(42),
- "euclidean",
- {},
- result.densmap,
- result._densmap_kwds,
- result.output_dens,
- parallel=False,
- verbose=bool(np.max(result.verbose)),
- tqdm_kwds=self.tqdm_kwds,
- )
- if result.output_dens:
- result.rad_orig_ = aux_data["rad_orig"]
- result.rad_emb_ = aux_data["rad_emb"]
- return result
- def __sub__(self, other):
- check_is_fitted(
- self, attributes=["graph_"], msg="Only fitted UMAP models can be combined"
- )
- check_is_fitted(
- other, attributes=["graph_"], msg="Only fitted UMAP models can be combined"
- )
- if self.graph_.shape[0] != other.graph_.shape[0]:
- raise ValueError("Only models with the equivalent samples can be combined")
- result = UMAP()
- result._populate_combined_params(self, other)
- result.graph_ = general_simplicial_set_intersection(
- self.graph_, other.graph_, weight=0.5, right_complement=True
- )
- result.graph_ = reset_local_connectivity(result.graph_, False)
- if scipy.sparse.csgraph.connected_components(result.graph_)[0] > 1:
- warn(
- "Combined graph is not connected but mult-component layout is unsupported. "
- "Falling back to random initialization."
- )
- init = "random"
- else:
- init = "spectral"
- result.densmap = np.any(result.densmap)
- result.output_dens = np.any(result.output_dens)
- result._densmap_kwds = {
- "lambda": np.max(result.dens_lambda),
- "frac": np.max(result.dens_frac),
- "var_shift": np.max(result.dens_var_shift),
- "n_neighbors": np.max(result.n_neighbors),
- }
- if result.n_epochs is None:
- n_epochs = None
- else:
- n_epochs = np.max(result.n_epochs)
- result.embedding_, aux_data = simplicial_set_embedding(
- None,
- result.graph_,
- np.min(result.n_components),
- np.min(result.learning_rate),
- np.mean(result._a),
- np.mean(result._b),
- np.mean(result.repulsion_strength),
- np.mean(result.negative_sample_rate),
- n_epochs,
- init,
- check_random_state(42),
- "euclidean",
- {},
- result.densmap,
- result._densmap_kwds,
- result.output_dens,
- parallel=False,
- verbose=bool(np.max(result.verbose)),
- tqdm_kwds=self.tqdm_kwds,
- )
- if result.output_dens:
- result.rad_orig_ = aux_data["rad_orig"]
- result.rad_emb_ = aux_data["rad_emb"]
- return result
- def fit(self, X, y=None, ensure_all_finite=True, **kwargs):
- """Fit X into an embedded space.
- Optionally use y for supervised dimension reduction.
- Parameters
- ----------
- X : array, shape (n_samples, n_features) or (n_samples, n_samples)
- If the metric is 'precomputed' X must be a square distance
- matrix. Otherwise it contains a sample per row. If the method
- is 'exact', X may be a sparse matrix of type 'csr', 'csc'
- or 'coo'.
- y : array, shape (n_samples)
- A target array for supervised dimension reduction. How this is
- handled is determined by parameters UMAP was instantiated with.
- The relevant attributes are ``target_metric`` and
- ``target_metric_kwds``.
- ensure_all_finite : Whether to raise an error on np.inf, np.nan, pd.NA in array.
- The possibilities are: - True: Force all values of array to be finite.
- - False: accepts np.inf, np.nan, pd.NA in array.
- - 'allow-nan': accepts only np.nan and pd.NA values in array.
- Values cannot be infinite.
- **kwargs : optional
- Any additional keyword arguments are passed to _fit_embed_data.
- """
- if self.metric in ("bit_hamming", "bit_jaccard"):
- X = check_array(
- X, dtype=np.uint8, order="C", ensure_all_finite=ensure_all_finite
- )
- else:
- X = check_array(
- X,
- dtype=np.float32,
- accept_sparse="csr",
- order="C",
- ensure_all_finite=ensure_all_finite,
- )
- self._raw_data = X
- # Handle all the optional arguments, setting default
- if self.a is None or self.b is None:
- self._a, self._b = find_ab_params(self.spread, self.min_dist)
- else:
- self._a = self.a
- self._b = self.b
- if isinstance(self.init, np.ndarray):
- init = check_array(
- self.init,
- dtype=np.float32,
- accept_sparse=False,
- ensure_all_finite=ensure_all_finite,
- )
- else:
- init = self.init
- self._initial_alpha = self.learning_rate
- self.knn_indices = self.precomputed_knn[0]
- self.knn_dists = self.precomputed_knn[1]
- # #848: allow precomputed knn to not have a search index
- if len(self.precomputed_knn) == 2:
- self.knn_search_index = None
- else:
- self.knn_search_index = self.precomputed_knn[2]
- self._validate_parameters()
- if self.verbose:
- print(str(self))
- self._original_n_threads = numba.get_num_threads()
- if self.n_jobs > 0 and self.n_jobs is not None:
- numba.set_num_threads(self.n_jobs)
- # Check if we should unique the data
- # We've already ensured that we aren't in the precomputed case
- if self.unique:
- # check if the matrix is dense
- if self._sparse_data:
- # Call a sparse unique function
- index, inverse, counts = csr_unique(X)
- else:
- index, inverse, counts = np.unique(
- X,
- return_index=True,
- return_inverse=True,
- return_counts=True,
- axis=0,
- )[1:4]
- if self.verbose:
- print(
- "Unique=True -> Number of data points reduced from ",
- X.shape[0],
- " to ",
- X[index].shape[0],
- )
- most_common = np.argmax(counts)
- print(
- "Most common duplicate is",
- index[most_common],
- " with a count of ",
- counts[most_common],
- )
- # We'll expose an inverse map when unique=True for users to map from our internal structures to their data
- self._unique_inverse_ = inverse
- # If we aren't asking for unique use the full index.
- # This will save special cases later.
- else:
- index = np.arange(X.shape[0])
- inverse = np.arange(X.shape[0])
- # Compute the indexed copy of X exactly once and reuse it everywhere
- # below. Previously X[index] was re-materialized at each call site (and
- # several times just to read .shape[0]), allocating the full N x D matrix
- # repeatedly. A single copy is kept: it also preserves UMAP's contract of
- # never mutating the caller's data (and self._raw_data) when a distance
- # metric writes into the array it is handed.
- n_index_samples = index.shape[0]
- X_indexed = X[index]
- # Error check n_neighbors based on data size
- if n_index_samples <= self.n_neighbors:
- if n_index_samples == 1:
- self.embedding_ = np.zeros(
- (1, self.n_components)
- ) # needed to sklearn comparability
- return self
- warn(
- "n_neighbors is larger than the dataset size; truncating to "
- "X.shape[0] - 1"
- )
- self._n_neighbors = n_index_samples - 1
- if self.densmap:
- self._densmap_kwds["n_neighbors"] = self._n_neighbors
- else:
- self._n_neighbors = self.n_neighbors
- # Note: unless it causes issues for setting 'index', could move this to
- # initial sparsity check above
- if self._sparse_data and not X.has_sorted_indices:
- X.sort_indices()
- random_state = check_random_state(self.random_state)
- if self.verbose:
- print(ts(), "Construct fuzzy simplicial set")
- if self.metric == "precomputed" and self._sparse_data:
- # For sparse precomputed distance matrices, we just argsort the rows to find
- # nearest neighbors. To make this easier, we expect matrices that are
- # symmetrical (so we can find neighbors by looking at rows in isolation,
- # rather than also having to consider that sample's column too).
- # print("Computing KNNs for sparse precomputed distances...")
- if sparse_tril(X).getnnz() != sparse_triu(X).getnnz():
- raise ValueError(
- "Sparse precomputed distance matrices should be symmetrical!"
- )
- if not np.all(X.diagonal() == 0):
- raise ValueError("Non-zero distances from samples to themselves!")
- if self.knn_dists is None:
- self._knn_indices = np.zeros((X.shape[0], self.n_neighbors), dtype=int)
- self._knn_dists = np.zeros(self._knn_indices.shape, dtype=float)
- # X is CSR (check_array(accept_sparse="csr")), so slice its backing
- # arrays directly instead of materializing a temporary matrix per row.
- X_indptr, X_indices, X_data = X.indptr, X.indices, X.data
- for row_id in range(X.shape[0]):
- # Find KNNs row-by-row
- row_start, row_end = X_indptr[row_id], X_indptr[row_id + 1]
- row_data = X_data[row_start:row_end]
- row_indices = X_indices[row_start:row_end]
- if len(row_data) < self._n_neighbors:
- raise ValueError(
- "Some rows contain fewer than n_neighbors distances!"
- )
- # argpartition selects the k smallest in O(d) vs O(d·log d) for argsort
- row_nn_data_indices = np.argpartition(row_data, self._n_neighbors)[
- : self._n_neighbors
- ]
- row_nn_data_indices = row_nn_data_indices[
- np.argsort(row_data[row_nn_data_indices])
- ]
- self._knn_indices[row_id] = row_indices[row_nn_data_indices]
- self._knn_dists[row_id] = row_data[row_nn_data_indices]
- else:
- self._knn_indices = self.knn_indices
- self._knn_dists = self.knn_dists
- # Disconnect any vertices farther apart than _disconnection_distance
- disconnected_index = self._knn_dists >= self._disconnection_distance
- self._knn_indices[disconnected_index] = -1
- self._knn_dists[disconnected_index] = np.inf
- edges_removed = disconnected_index.sum()
- (
- self.graph_,
- self._sigmas,
- self._rhos,
- self.graph_dists_,
- ) = fuzzy_simplicial_set(
- X_indexed,
- self.n_neighbors,
- random_state,
- "precomputed",
- self._metric_kwds,
- self._knn_indices,
- self._knn_dists,
- self.angular_rp_forest,
- self.set_op_mix_ratio,
- self.local_connectivity,
- True,
- self.verbose,
- self.densmap or self.output_dens,
- )
- # Report the number of vertices with degree 0 in our our umap.graph_
- # This ensures that they were properly disconnected.
- vertices_disconnected = np.sum(
- np.array(self.graph_.sum(axis=1)).flatten() == 0
- )
- raise_disconnected_warning(
- edges_removed,
- vertices_disconnected,
- self._disconnection_distance,
- self._raw_data.shape[0],
- verbose=self.verbose,
- )
- # Handle small cases efficiently by computing all distances
- elif n_index_samples < 4096 and not self.force_approximation_algorithm:
- self._small_data = True
- try:
- # sklearn pairwise_distances fails for callable metric on sparse data
- _m = self.metric if self._sparse_data else self._input_distance_func
- dmat = dist.numba_aware_pairwise_distances(
- X_indexed, metric=_m, **self._metric_kwds
- )
- except (ValueError, TypeError) as e:
- # metric is numba.jit'd or not supported by sklearn,
- # fallback to pairwise special
- if self._sparse_data:
- # Get a fresh metric since we are casting to dense
- if not callable(self.metric):
- _m = dist.named_distances[self.metric]
- dmat = dist.pairwise_special_metric(
- X_indexed.toarray(),
- metric=_m,
- kwds=self._metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- else:
- dmat = dist.pairwise_special_metric(
- X_indexed,
- metric=self._input_distance_func,
- kwds=self._metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- else:
- dmat = dist.pairwise_special_metric(
- X_indexed,
- metric=self._input_distance_func,
- kwds=self._metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- # set any values greater than disconnection_distance to be np.inf.
- # This will have no effect when _disconnection_distance is not set since it defaults to np.inf.
- # The default (inf) makes the comparison an all-False no-op, so skip
- # the two N x N boolean temporaries entirely; otherwise compute the
- # mask once and reuse it for both the count and the in-place fill.
- if np.isfinite(self._disconnection_distance):
- disconnected_mask = dmat >= self._disconnection_distance
- edges_removed = disconnected_mask.sum()
- dmat[disconnected_mask] = np.inf
- else:
- edges_removed = 0
- (
- self.graph_,
- self._sigmas,
- self._rhos,
- self.graph_dists_,
- ) = fuzzy_simplicial_set(
- dmat,
- self._n_neighbors,
- random_state,
- "precomputed",
- self._metric_kwds,
- None,
- None,
- self.angular_rp_forest,
- self.set_op_mix_ratio,
- self.local_connectivity,
- True,
- self.verbose,
- self.densmap or self.output_dens,
- )
- # Report the number of vertices with degree 0 in our umap.graph_
- # This ensures that they were properly disconnected.
- vertices_disconnected = np.sum(
- np.array(self.graph_.sum(axis=1)).flatten() == 0
- )
- raise_disconnected_warning(
- edges_removed,
- vertices_disconnected,
- self._disconnection_distance,
- self._raw_data.shape[0],
- verbose=self.verbose,
- )
- else:
- # Standard case
- self._small_data = False
- # Standard case
- if self._sparse_data and self.metric in pynn_sparse_named_distances:
- nn_metric = self.metric
- elif not self._sparse_data and self.metric in pynn_named_distances:
- nn_metric = self.metric
- else:
- nn_metric = self._input_distance_func
- if self.knn_dists is None:
- (
- self._knn_indices,
- self._knn_dists,
- self._knn_search_index,
- ) = nearest_neighbors(
- X_indexed,
- self._n_neighbors,
- nn_metric,
- self._metric_kwds,
- self.angular_rp_forest,
- random_state,
- self.low_memory,
- use_pynndescent=True,
- n_jobs=self.n_jobs,
- verbose=self.verbose,
- )
- else:
- self._knn_indices = self.knn_indices
- self._knn_dists = self.knn_dists
- self._knn_search_index = self.knn_search_index
- # Disconnect any vertices farther apart than _disconnection_distance
- disconnected_index = self._knn_dists >= self._disconnection_distance
- self._knn_indices[disconnected_index] = -1
- self._knn_dists[disconnected_index] = np.inf
- edges_removed = disconnected_index.sum()
- (
- self.graph_,
- self._sigmas,
- self._rhos,
- self.graph_dists_,
- ) = fuzzy_simplicial_set(
- X_indexed,
- self.n_neighbors,
- random_state,
- nn_metric,
- self._metric_kwds,
- self._knn_indices,
- self._knn_dists,
- self.angular_rp_forest,
- self.set_op_mix_ratio,
- self.local_connectivity,
- True,
- self.verbose,
- self.densmap or self.output_dens,
- )
- # Report the number of vertices with degree 0 in our umap.graph_
- # This ensures that they were properly disconnected.
- vertices_disconnected = np.sum(
- np.array(self.graph_.sum(axis=1)).flatten() == 0
- )
- raise_disconnected_warning(
- edges_removed,
- vertices_disconnected,
- self._disconnection_distance,
- self._raw_data.shape[0],
- verbose=self.verbose,
- )
- # Currently not checking if any duplicate points have differing labels
- # Might be worth throwing a warning...
- if y is not None:
- len_X = len(X) if not self._sparse_data else X.shape[0]
- if len_X != len(y):
- raise ValueError(
- "Length of x = {len_x}, length of y = {len_y}, while it must be equal.".format(
- len_x=len_X, len_y=len(y)
- )
- )
- if self.target_metric == "string":
- y_ = y[index]
- else:
- y_ = check_array(
- y, ensure_2d=False, ensure_all_finite=ensure_all_finite
- )[index]
- if self.target_metric == "categorical":
- if self.target_weight < 1.0:
- far_dist = 2.5 * (1.0 / (1.0 - self.target_weight))
- else:
- far_dist = 1.0e12
- self.graph_ = discrete_metric_simplicial_set_intersection(
- self.graph_, y_, far_dist=far_dist
- )
- elif self.target_metric in dist.DISCRETE_METRICS:
- if self.target_weight < 1.0:
- scale = 2.5 * (1.0 / (1.0 - self.target_weight))
- else:
- scale = 1.0e12
- # self.graph_ = discrete_metric_simplicial_set_intersection(
- # self.graph_,
- # y_,
- # metric=self.target_metric,
- # metric_kws=self.target_metric_kwds,
- # metric_scale=scale
- # )
- metric_kws = dist.get_discrete_params(y_, self.target_metric)
- self.graph_ = discrete_metric_simplicial_set_intersection(
- self.graph_,
- y_,
- metric=self.target_metric,
- metric_kws=metric_kws,
- metric_scale=scale,
- )
- else:
- if len(y_.shape) == 1:
- y_ = y_.reshape(-1, 1)
- if self.target_n_neighbors == -1:
- target_n_neighbors = self._n_neighbors
- else:
- target_n_neighbors = self.target_n_neighbors
- # Handle the small case as precomputed as before
- if y.shape[0] < 4096:
- try:
- ydmat = pairwise_distances(
- y_, metric=self.target_metric, **self._target_metric_kwds
- )
- except (TypeError, ValueError):
- ydmat = dist.pairwise_special_metric(
- y_,
- metric=self.target_metric,
- kwds=self._target_metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- (
- target_graph,
- target_sigmas,
- target_rhos,
- ) = fuzzy_simplicial_set(
- ydmat,
- target_n_neighbors,
- random_state,
- "precomputed",
- self._target_metric_kwds,
- None,
- None,
- False,
- 1.0,
- 1.0,
- False,
- )
- else:
- # Standard case
- (
- target_graph,
- target_sigmas,
- target_rhos,
- ) = fuzzy_simplicial_set(
- y_,
- target_n_neighbors,
- random_state,
- self.target_metric,
- self._target_metric_kwds,
- None,
- None,
- False,
- 1.0,
- 1.0,
- False,
- )
- # product = self.graph_.multiply(target_graph)
- # # self.graph_ = 0.99 * product + 0.01 * (self.graph_ +
- # # target_graph -
- # # product)
- # self.graph_ = product
- self.graph_ = general_simplicial_set_intersection(
- self.graph_, target_graph, self.target_weight
- )
- self.graph_ = reset_local_connectivity(self.graph_)
- self._supervised = True
- else:
- self._supervised = False
- if self.densmap or self.output_dens:
- self._densmap_kwds["graph_dists"] = self.graph_dists_
- if self.verbose:
- print(ts(), "Construct embedding")
- if self.transform_mode == "embedding":
- epochs = (
- self.n_epochs_list if self.n_epochs_list is not None else self.n_epochs
- )
- # Use a fresh copy of the (unmutated) raw data here, independent of
- # X_indexed: a distance metric that writes into the array it is
- # handed could otherwise corrupt the data PCA-init / densMAP read.
- self.embedding_, aux_data = self._fit_embed_data(
- self._raw_data[index],
- epochs,
- init,
- random_state, # JH why raw data?
- **kwargs,
- )
- if self.n_epochs_list is not None:
- if "embedding_list" not in aux_data:
- raise KeyError(
- "No list of embedding were found in 'aux_data'. "
- "It is likely the layout optimization function "
- "doesn't support the list of int for 'n_epochs'."
- )
- else:
- self.embedding_list_ = [
- e[inverse] for e in aux_data["embedding_list"]
- ]
- # Assign any points that are fully disconnected from our manifold(s) to have embedding
- # coordinates of np.nan. These will be filtered by our plotting functions automatically.
- # They also prevent users from being deceived a distance query to one of these points.
- # Might be worth moving this into simplicial_set_embedding or _fit_embed_data
- disconnected_vertices = np.array(self.graph_.sum(axis=1)).flatten() == 0
- if len(disconnected_vertices) > 0:
- self.embedding_[disconnected_vertices] = np.full(
- self.n_components, np.nan
- )
- self.embedding_ = self.embedding_[inverse]
- if self.output_dens:
- self.rad_orig_ = aux_data["rad_orig"][inverse]
- self.rad_emb_ = aux_data["rad_emb"][inverse]
- if self.verbose:
- print(ts() + " Finished embedding")
- numba.set_num_threads(self._original_n_threads)
- self._input_hash = joblib.hash(self._raw_data)
- if self.transform_mode == "embedding":
- # Set number of features out for sklearn API
- self._n_features_out = self.embedding_.shape[1]
- else:
- self._n_features_out = self.graph_.shape[1]
- return self
- def _fit_embed_data(self, X, n_epochs, init, random_state, **kwargs):
- """A method wrapper for simplicial_set_embedding that can be
- replaced by subclasses. Arbitrary keyword arguments can be passed
- through .fit() and .fit_transform().
- """
- return simplicial_set_embedding(
- X,
- self.graph_,
- self.n_components,
- self._initial_alpha,
- self._a,
- self._b,
- self.repulsion_strength,
- self.negative_sample_rate,
- n_epochs,
- init,
- random_state,
- self._input_distance_func,
- self._metric_kwds,
- self.densmap,
- self._densmap_kwds,
- self.output_dens,
- self._output_distance_func,
- self._output_metric_kwds,
- self.output_metric in ("euclidean", "l2"),
- self.random_state is None,
- self.verbose,
- tqdm_kwds=self.tqdm_kwds,
- )
- def fit_transform(self, X, y=None, ensure_all_finite=True, **kwargs):
- """Fit X into an embedded space and return that transformed
- output.
- Parameters
- ----------
- X : array, shape (n_samples, n_features) or (n_samples, n_samples)
- If the metric is 'precomputed' X must be a square distance
- matrix. Otherwise it contains a sample per row.
- y : array, shape (n_samples)
- A target array for supervised dimension reduction. How this is
- handled is determined by parameters UMAP was instantiated with.
- The relevant attributes are ``target_metric`` and
- ``target_metric_kwds``.
- ensure_all_finite : Whether to raise an error on np.inf, np.nan, pd.NA in array.
- The possibilities are: - True: Force all values of array to be finite.
- - False: accepts np.inf, np.nan, pd.NA in array.
- - 'allow-nan': accepts only np.nan and pd.NA values in array.
- Values cannot be infinite.
- **kwargs : Any additional keyword arguments are passed to _fit_embed_data.
- Returns
- -------
- X_new : array, shape (n_samples, n_components)
- Embedding of the training data in low-dimensional space.
- or a tuple (X_new, r_orig, r_emb) if ``output_dens`` flag is set,
- which additionally includes:
- r_orig: array, shape (n_samples)
- Local radii of data points in the original data space (log-transformed).
- r_emb: array, shape (n_samples)
- Local radii of data points in the embedding (log-transformed).
- """
- _input_dtype = getattr(X, "dtype", None)
- self.fit(X, y, ensure_all_finite, **kwargs)
- if self.transform_mode == "embedding":
- embedding = self.embedding_
- if _input_dtype is not None and np.issubdtype(_input_dtype, np.floating):
- embedding = embedding.astype(_input_dtype, copy=False)
- if self.output_dens:
- return embedding, self.rad_orig_, self.rad_emb_
- else:
- return embedding
- elif self.transform_mode == "graph":
- return self.graph_
- else:
- raise ValueError(
- "Unrecognized transform mode {}; should be one of 'embedding' or 'graph'".format(
- self.transform_mode
- )
- )
- def transform(self, X, ensure_all_finite=True):
- """Transform X into the existing embedded space and return that
- transformed output.
- Parameters
- ----------
- X : array, shape (n_samples, n_features)
- New data to be transformed.
- ensure_all_finite : Whether to raise an error on np.inf, np.nan, pd.NA in array.
- The possibilities are: - True: Force all values of array to be finite.
- - False: accepts np.inf, np.nan, pd.NA in array.
- - 'allow-nan': accepts only np.nan and pd.NA values in array.
- Values cannot be infinite.
- Returns
- -------
- X_new : array, shape (n_samples, n_components)
- Embedding of the new data in low-dimensional space.
- """
- _input_dtype = getattr(X, "dtype", None)
- # If we fit just a single instance then error
- if self._raw_data.shape[0] == 1:
- raise ValueError(
- "Transform unavailable when model was fit with only a single data sample."
- )
- # If we just have the original input then short circuit things
- if self.metric in ("bit_hamming", "bit_jaccard"):
- X = check_array(
- X, dtype=np.uint8, order="C", ensure_all_finite=ensure_all_finite
- )
- else:
- X = check_array(
- X,
- dtype=np.float32,
- accept_sparse="csr",
- order="C",
- ensure_all_finite=ensure_all_finite,
- )
- x_hash = joblib.hash(X)
- if x_hash == self._input_hash:
- if self.transform_mode == "embedding":
- embedding = self.embedding_
- if _input_dtype is not None and np.issubdtype(
- _input_dtype, np.floating
- ):
- embedding = embedding.astype(_input_dtype, copy=False)
- return embedding
- elif self.transform_mode == "graph":
- return self.graph_
- else:
- raise ValueError(
- "Unrecognized transform mode {}; should be one of 'embedding' or 'graph'".format(
- self.transform_mode
- )
- )
- if self.densmap:
- raise NotImplementedError(
- "Transforming data into an existing embedding not supported for densMAP."
- )
- # #848: knn_search_index is allowed to be None if not transforming new data,
- # so now we must validate that if it exists it is not None.
- # #1194: a precomputed metric never has a search index (nearest_neighbors
- # returns None for it), and the precomputed branch below does not need
- # one, so only enforce this for the metrics that query the index.
- if (
- self.metric != "precomputed"
- and hasattr(self, "_knn_search_index")
- and self._knn_search_index is None
- ):
- raise NotImplementedError(
- "No search index available: transforming data"
- " into an existing embedding is not supported"
- )
- # X = check_array(X, dtype=np.float32, order="C", accept_sparse="csr")
- random_state = check_random_state(self.transform_seed)
- rng_state = random_state.randint(INT32_MIN, INT32_MAX, 3).astype(np.int64)
- if self.metric == "precomputed":
- warn(
- "Transforming new data with precomputed metric. "
- "We are assuming the input data is a matrix of distances from the new points "
- "to the points in the training set. If the input matrix is sparse, it should "
- "contain distances from the new points to their nearest neighbours "
- "or approximate nearest neighbours in the training set."
- )
- assert X.shape[1] == self._raw_data.shape[0]
- if scipy.sparse.issparse(X):
- indices = np.full(
- (X.shape[0], self._n_neighbors), dtype=np.int32, fill_value=-1
- )
- dists = np.full_like(indices, dtype=np.float32, fill_value=-1)
- # X is CSR (check_array(accept_sparse="csr")), so slice its backing
- # arrays directly instead of materializing a temporary matrix per row.
- X_indptr, X_indices, X_data = X.indptr, X.indices, X.data
- for i in range(X.shape[0]):
- row_start, row_end = X_indptr[i], X_indptr[i + 1]
- row_data = X_data[row_start:row_end]
- row_indices = X_indices[row_start:row_end]
- if len(row_data) < self._n_neighbors:
- raise ValueError(
- f"Need at least n_neighbors ({self.n_neighbors}) distances for each row!"
- )
- row_nn_data_indices = np.argpartition(row_data, self._n_neighbors)[
- : self._n_neighbors
- ]
- row_nn_data_indices = row_nn_data_indices[
- np.argsort(row_data[row_nn_data_indices])
- ]
- indices[i] = row_indices[row_nn_data_indices]
- dists[i] = row_data[row_nn_data_indices]
- else:
- indices = np.argpartition(X, self._n_neighbors, axis=1)[
- :, : self._n_neighbors
- ]
- dists = np.take_along_axis(X, indices, axis=1)
- sorted_idx = np.argsort(dists, axis=1)
- indices = np.take_along_axis(indices, sorted_idx, axis=1).astype(
- np.int32
- )
- dists = np.take_along_axis(dists, sorted_idx, axis=1)
- assert np.min(indices) >= 0 and np.min(dists) >= 0.0
- elif self._small_data:
- try:
- # sklearn pairwise_distances fails for callable metric on sparse data
- _m = self.metric if self._sparse_data else self._input_distance_func
- dmat = pairwise_distances(
- X, self._raw_data, metric=_m, **self._metric_kwds
- )
- except (TypeError, ValueError):
- # metric is numba.jit'd or not supported by sklearn,
- # fallback to pairwise special
- if self._sparse_data:
- # Get a fresh metric since we are casting to dense
- if not callable(self.metric):
- _m = dist.named_distances[self.metric]
- dmat = dist.pairwise_special_metric(
- X.toarray(),
- self._raw_data.toarray(),
- metric=_m,
- kwds=self._metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- else:
- dmat = dist.pairwise_special_metric(
- X,
- self._raw_data,
- metric=self._input_distance_func,
- kwds=self._metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- else:
- dmat = dist.pairwise_special_metric(
- X,
- self._raw_data,
- metric=self._input_distance_func,
- kwds=self._metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- # Select the k nearest in row-blocks so the argpartition index
- # temporary is (block x N) rather than a full (M x N) int64 array
- # kept alive by the [:, :k] view. Per-row results are identical to
- # the full-matrix argpartition/argsort (rows are independent).
- k = self._n_neighbors
- n_t = dmat.shape[0]
- indices = np.empty((n_t, k), dtype=np.int64)
- dists = np.empty((n_t, k), dtype=dmat.dtype)
- block = 1024
- for s in range(0, n_t, block):
- e = min(s + block, n_t)
- d_block = dmat[s:e]
- part = np.argpartition(d_block, k, axis=1)[:, :k]
- r = np.arange(e - s)[:, None]
- bd = d_block[r, part]
- order = np.argsort(bd, axis=1)
- indices[s:e] = part[r, order]
- dists[s:e] = bd[r, order]
- else:
- epsilon = 0.24 if self._knn_search_index._angular_trees else 0.12
- indices, dists = self._knn_search_index.query(
- X, self.n_neighbors, epsilon=epsilon
- )
- dists = dists.astype(np.float32, order="C")
- # Remove any nearest neighbours who's distances are greater than our disconnection_distance
- indices[dists >= self._disconnection_distance] = -1
- adjusted_local_connectivity = max(0.0, self.local_connectivity - 1.0)
- sigmas, rhos = smooth_knn_dist(
- dists,
- float(self._n_neighbors),
- local_connectivity=float(adjusted_local_connectivity),
- )
- rows, cols, vals, dists = compute_membership_strengths(
- indices, dists, sigmas, rhos, bipartite=True
- )
- graph = scipy.sparse.coo_matrix(
- (vals, (rows, cols)), shape=(X.shape[0], self._raw_data.shape[0])
- )
- if self.transform_mode == "graph":
- return graph
- # This was a very specially constructed graph with constant degree.
- # That lets us do fancy unpacking by reshaping the csr matrix indices
- # and data. Doing so relies on the constant degree assumption!
- # csr_graph = normalize(graph.tocsr(), norm="l1")
- # inds = csr_graph.indices.reshape(X.shape[0], self._n_neighbors)
- # weights = csr_graph.data.reshape(X.shape[0], self._n_neighbors)
- # embedding = init_transform(inds, weights, self.embedding_)
- # This is less fast code than the above numba.jit'd code.
- # It handles the fact that our nearest neighbour graph can now contain variable numbers of vertices.
- csr_graph = graph.tocsr()
- csr_graph.eliminate_zeros()
- embedding = init_graph_transform(csr_graph, self.embedding_)
- if self.n_epochs is None:
- # For smaller datasets we can use more epochs
- if graph.shape[0] <= 10000:
- n_epochs = 100
- else:
- n_epochs = 30
- else:
- n_epochs = int(self.n_epochs // 3.0)
- graph.data[graph.data < (graph.data.max() / float(n_epochs))] = 0.0
- graph.eliminate_zeros()
- epochs_per_sample = make_epochs_per_sample(graph.data, n_epochs)
- head = graph.row
- tail = graph.col
- weight = graph.data
- # optimize_layout = make_optimize_layout(
- # self._output_distance_func,
- # tuple(self.output_metric_kwds.values()),
- # )
- if self.output_metric == "euclidean":
- embedding = optimize_layout_euclidean(
- embedding,
- self.embedding_.astype(np.float32, copy=True), # Fixes #179 & #217,
- head,
- tail,
- n_epochs,
- graph.shape[1],
- epochs_per_sample,
- self._a,
- self._b,
- rng_state,
- self.repulsion_strength,
- self._initial_alpha / 4.0,
- self.negative_sample_rate,
- self.random_state is None,
- verbose=self.verbose,
- tqdm_kwds=self.tqdm_kwds,
- )
- else:
- embedding = optimize_layout_generic(
- embedding,
- self.embedding_.astype(np.float32, copy=True), # Fixes #179 & #217
- head,
- tail,
- n_epochs,
- graph.shape[1],
- epochs_per_sample,
- self._a,
- self._b,
- rng_state,
- self.repulsion_strength,
- self._initial_alpha / 4.0,
- self.negative_sample_rate,
- self._output_distance_func,
- tuple(self._output_metric_kwds.values()),
- verbose=self.verbose,
- tqdm_kwds=self.tqdm_kwds,
- )
- if _input_dtype is not None and np.issubdtype(_input_dtype, np.floating):
- embedding = embedding.astype(_input_dtype, copy=False)
- return embedding
- def inverse_transform(self, X):
- """Transform X in the existing embedded space back into the input
- data space and return that transformed output.
- Parameters
- ----------
- X : array, shape (n_samples, n_components)
- New points to be inverse transformed.
- Returns
- -------
- X_new : array, shape (n_samples, n_features)
- Generated data points new data in data space.
- """
- if self._sparse_data:
- raise ValueError("Inverse transform not available for sparse input.")
- elif self._inverse_distance_func is None:
- raise ValueError("Inverse transform not available for given metric.")
- elif self.densmap:
- raise ValueError("Inverse transform not available for densMAP.")
- elif self.n_components >= 8:
- warn(
- "Inverse transform works best with low dimensional embeddings."
- " Results may be poor, or this approach to inverse transform"
- " may fail altogether! If you need a high dimensional latent"
- " space and inverse transform operations consider using an"
- " autoencoder."
- )
- elif self.transform_mode == "graph":
- raise ValueError(
- "Inverse transform not available for transform_mode = 'graph'"
- )
- X = check_array(X, dtype=np.float32, order="C")
- random_state = check_random_state(self.transform_seed)
- rng_state = random_state.randint(INT32_MIN, INT32_MAX, 3).astype(np.int64)
- # build Delaunay complex (Does this not assume a roughly euclidean output metric)?
- deltri = scipy.spatial.Delaunay(
- self.embedding_, incremental=True, qhull_options="QJ"
- )
- neighbors = deltri.simplices[deltri.find_simplex(X)]
- n_embed = self.embedding_.shape[0]
- simplices = deltri.simplices
- k = simplices.shape[1]
- n_s = simplices.shape[0]
- # All (vertex_a, vertex_b) pairs within each simplex — k² pairs × n_simplices
- rows = np.empty(n_s * k * k, dtype=np.int32)
- cols = np.empty(n_s * k * k, dtype=np.int32)
- for a in range(k):
- for b in range(k):
- off = (a * k + b) * n_s
- rows[off : off + n_s] = simplices[:, a]
- cols[off : off + n_s] = simplices[:, b]
- adjmat = scipy.sparse.csr_matrix(
- (np.ones(n_s * k * k, dtype=np.int8), (rows, cols)),
- shape=(n_embed, n_embed),
- )
- min_vertices = min(self._raw_data.shape[-1], self._raw_data.shape[0])
- neighborhood = [
- breadth_first_search(adjmat, v[0], min_vertices=min_vertices)
- for v in neighbors
- ]
- if callable(self.output_metric):
- # need to create another numba.jit-able wrapper for callable
- # output_metrics that return a tuple (already checked that it does
- # during param validation in `fit` method)
- _out_m = self.output_metric
- @numba.njit(fastmath=True)
- def _output_dist_only(x, y, *kwds):
- return _out_m(x, y, *kwds)[0]
- dist_only_func = _output_dist_only
- elif self.output_metric in dist.named_distances.keys():
- dist_only_func = dist.named_distances[self.output_metric]
- else:
- # shouldn't really ever get here because of checks already performed,
- # but works as a failsafe in case attr was altered manually after fitting
- raise ValueError(
- "Unrecognized output metric: {}".format(self.output_metric)
- )
- dist_args = tuple(self._output_metric_kwds.values())
- distances = [
- np.array(
- [
- dist_only_func(X[i], self.embedding_[nb], *dist_args)
- for nb in neighborhood[i]
- ]
- )
- for i in range(X.shape[0])
- ]
- idx = np.array([np.argsort(e)[:min_vertices] for e in distances])
- dists_output_space = np.array(
- [distances[i][idx[i]] for i in range(len(distances))]
- )
- indices = np.array([neighborhood[i][idx[i]] for i in range(len(neighborhood))])
- rows, cols, distances = np.array(
- [
- [i, indices[i, j], dists_output_space[i, j]]
- for i in range(indices.shape[0])
- for j in range(min_vertices)
- ]
- ).T
- # calculate membership strength of each edge
- weights = 1 / (1 + self._a * distances ** (2 * self._b))
- # compute 1-skeleton
- # convert 1-skeleton into coo_matrix adjacency matrix
- graph = scipy.sparse.coo_matrix(
- (weights, (rows, cols)), shape=(X.shape[0], self._raw_data.shape[0])
- )
- # That lets us do fancy unpacking by reshaping the csr matrix indices
- # and data. Doing so relies on the constant degree assumption!
- # csr_graph = graph.tocsr()
- csr_graph = normalize(graph.tocsr(), norm="l1")
- inds = csr_graph.indices.reshape(X.shape[0], min_vertices)
- weights = csr_graph.data.reshape(X.shape[0], min_vertices)
- inv_transformed_points = init_transform(inds, weights, self._raw_data)
- if self.n_epochs is None:
- # For smaller datasets we can use more epochs
- if graph.shape[0] <= 10000:
- n_epochs = 100
- else:
- n_epochs = 30
- else:
- n_epochs = int(self.n_epochs // 3.0)
- # graph.data[graph.data < (graph.data.max() / float(n_epochs))] = 0.0
- # graph.eliminate_zeros()
- epochs_per_sample = make_epochs_per_sample(graph.data, n_epochs)
- head = graph.row
- tail = graph.col
- weight = graph.data
- inv_transformed_points = optimize_layout_inverse(
- inv_transformed_points,
- self._raw_data,
- head,
- tail,
- weight,
- self._sigmas,
- self._rhos,
- n_epochs,
- graph.shape[1],
- epochs_per_sample,
- self._a,
- self._b,
- rng_state,
- self.repulsion_strength,
- self._initial_alpha / 4.0,
- self.negative_sample_rate,
- self._inverse_distance_func,
- tuple(self._metric_kwds.values()),
- verbose=self.verbose,
- tqdm_kwds=self.tqdm_kwds,
- )
- return inv_transformed_points
- def update(self, X, ensure_all_finite=True):
- if self.metric in ("bit_hamming", "bit_jaccard"):
- X = check_array(
- X, dtype=np.uint8, order="C", ensure_all_finite=ensure_all_finite
- )
- else:
- X = check_array(
- X,
- dtype=np.float32,
- accept_sparse="csr",
- order="C",
- ensure_all_finite=ensure_all_finite,
- )
- random_state = check_random_state(self.transform_seed)
- rng_state = random_state.randint(INT32_MIN, INT32_MAX, 3).astype(np.int64)
- original_size = self._raw_data.shape[0]
- if self.metric == "precomputed":
- raise ValueError("Update does not currently support precomputed metrics")
- if self._supervised:
- raise ValueError("Updating supervised models is not currently " "supported")
- if self._small_data:
- if self._sparse_data:
- self._raw_data = scipy.sparse.vstack([self._raw_data, X])
- else:
- self._raw_data = np.vstack([self._raw_data, X])
- if self._raw_data.shape[0] < 4096:
- # still small data
- try:
- # sklearn pairwise_distances fails for callable metric on sparse data
- _m = self.metric if self._sparse_data else self._input_distance_func
- dmat = dist.numba_aware_pairwise_distances(
- self._raw_data, metric=_m, **self._metric_kwds
- )
- except (ValueError, TypeError) as e:
- # metric is numba.jit'd or not supported by sklearn,
- # fallback to pairwise special
- if self._sparse_data:
- # Get a fresh metric since we are casting to dense
- if not callable(self.metric):
- _m = dist.named_distances[self.metric]
- dmat = dist.pairwise_special_metric(
- self._raw_data.toarray(),
- metric=_m,
- kwds=self._metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- else:
- dmat = dist.pairwise_special_metric(
- self._raw_data,
- metric=self._input_distance_func,
- kwds=self._metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- else:
- dmat = dist.pairwise_special_metric(
- self._raw_data,
- metric=self._input_distance_func,
- kwds=self._metric_kwds,
- ensure_all_finite=ensure_all_finite,
- )
- self.graph_, self._sigmas, self._rhos = fuzzy_simplicial_set(
- dmat,
- self._n_neighbors,
- random_state,
- "precomputed",
- self._metric_kwds,
- None,
- None,
- self.angular_rp_forest,
- self.set_op_mix_ratio,
- self.local_connectivity,
- True,
- self.verbose,
- )
- knn_indices = np.argsort(dmat)[:, : self.n_neighbors]
- else:
- # now large data
- self._small_data = False
- if self._sparse_data and self.metric in pynn_sparse_named_distances:
- nn_metric = self.metric
- elif not self._sparse_data and self.metric in pynn_named_distances:
- nn_metric = self.metric
- else:
- nn_metric = self._input_distance_func
- (
- self._knn_indices,
- self._knn_dists,
- self._knn_search_index,
- ) = nearest_neighbors(
- self._raw_data,
- self._n_neighbors,
- nn_metric,
- self._metric_kwds,
- self.angular_rp_forest,
- random_state,
- self.low_memory,
- use_pynndescent=True,
- n_jobs=self.n_jobs,
- verbose=self.verbose,
- )
- self.graph_, self._sigmas, self._rhos = fuzzy_simplicial_set(
- self._raw_data,
- self.n_neighbors,
- random_state,
- nn_metric,
- self._metric_kwds,
- self._knn_indices,
- self._knn_dists,
- self.angular_rp_forest,
- self.set_op_mix_ratio,
- self.local_connectivity,
- True,
- self.verbose,
- )
- knn_indices = self._knn_indices
- init = np.zeros(
- (self._raw_data.shape[0], self.n_components), dtype=np.float32
- )
- init[:original_size] = self.embedding_
- init_update(init, original_size, knn_indices)
- if self.n_epochs is None:
- n_epochs = 0
- else:
- n_epochs = self.n_epochs
- self.embedding_, aux_data = simplicial_set_embedding(
- self._raw_data,
- self.graph_,
- self.n_components,
- self._initial_alpha,
- self._a,
- self._b,
- self.repulsion_strength,
- self.negative_sample_rate,
- n_epochs,
- init,
- random_state,
- self._input_distance_func,
- self._metric_kwds,
- self.densmap,
- self._densmap_kwds,
- self.output_dens,
- self._output_distance_func,
- self._output_metric_kwds,
- self.output_metric in ("euclidean", "l2"),
- self.random_state is None,
- self.verbose,
- tqdm_kwds=self.tqdm_kwds,
- )
- else:
- self._knn_search_index.prepare()
- self._knn_search_index.update(X)
- self._raw_data = self._knn_search_index._raw_data
- (
- self._knn_indices,
- self._knn_dists,
- ) = self._knn_search_index.neighbor_graph
- if self._sparse_data and self.metric in pynn_sparse_named_distances:
- nn_metric = self.metric
- elif not self._sparse_data and self.metric in pynn_named_distances:
- nn_metric = self.metric
- else:
- nn_metric = self._input_distance_func
- self.graph_, self._sigmas, self._rhos = fuzzy_simplicial_set(
- self._raw_data,
- self.n_neighbors,
- random_state,
- nn_metric,
- self._metric_kwds,
- self._knn_indices,
- self._knn_dists,
- self.angular_rp_forest,
- self.set_op_mix_ratio,
- self.local_connectivity,
- True,
- self.verbose,
- )
- init = np.zeros(
- (self._raw_data.shape[0], self.n_components), dtype=np.float32
- )
- init[:original_size] = self.embedding_
- init_update(init, original_size, self._knn_indices)
- if self.n_epochs is None:
- n_epochs = 0
- else:
- n_epochs = self.n_epochs
- self.embedding_, aux_data = simplicial_set_embedding(
- self._raw_data,
- self.graph_,
- self.n_components,
- self._initial_alpha,
- self._a,
- self._b,
- self.repulsion_strength,
- self.negative_sample_rate,
- n_epochs,
- init,
- random_state,
- self._input_distance_func,
- self._metric_kwds,
- self.densmap,
- self._densmap_kwds,
- self.output_dens,
- self._output_distance_func,
- self._output_metric_kwds,
- self.output_metric in ("euclidean", "l2"),
- self.random_state is None,
- self.verbose,
- tqdm_kwds=self.tqdm_kwds,
- )
- if self.output_dens:
- self.rad_orig_ = aux_data["rad_orig"]
- self.rad_emb_ = aux_data["rad_emb"]
- def __repr__(self):
- from sklearn.utils._pprint import _EstimatorPrettyPrinter
- import re
- pp = _EstimatorPrettyPrinter(
- compact=True,
- indent=1,
- indent_at_name=True,
- n_max_elements_to_show=50,
- )
- pp._changed_only = True
- repr_ = pp.pformat(self)
- repr_ = re.sub("tqdm_kwds={.*},", "", repr_, flags=re.S)
- # remove empty lines
- repr_ = re.sub("\n *\n", "\n", repr_, flags=re.S)
- # remove extra whitespaces after a comma
- repr_ = re.sub(", +", ", ", repr_)
- return repr_
umap_.py at commit 1180b78, under BSD-3-Clause · at the source
Overview
- Fudan University, Shanghai, China
- Key Laboratory of Growth Regulation and Translational Research of Zhejiang Province, Research Center for Industries of the Future, School of Life Sciences, Westlake University, Hangzhou, China
- Westlake Laboratory of Life Sciences and Biomedicine, Hangzhou, China
- Institute of Basic Medical Sciences, Westlake Institute for Advanced Study, Hangzhou, China
- Zhejiang University, Hangzhou, China
Abstract
Valence detection in complex environment is critical for natural behaviors like foraging. Previous studies have explored valence processing in brain regions like lateral horn (LH) and mushroom body (MB) using simple synthetic stimuli in Drosophila. However, the neural basis for valence detection of natural objects in complex contexts remains unclear. Here, by brain-wide connectome analysis, we identified the evolutionarily conserved superior protocerebrum (SP) that integrates brain-wide multimodal inputs mainly via LH and MB, and sends widespread outputs particularly to the central complex (CX). This forms a convergence-divergence circuit resembling an autoencoder architecture, with SP as the bottleneck integrating multimodal information into low-dimensional valence signals. Specifically, SP input LH neurons integrate ethologically related innate valences for robust valence detection in natural environments, and the integration can be unimodal, such as that of diverse odors signaling food, or multimodal, such as that of wind and temperature signaling lousy weather. Opponent valences of attraction and aversion are further integrated into SP for complex valence detection. MB learned valences are also integrated into SP to update LH innate valences with recent experience for flexible valence detection. Attractive and aversive valences, either innate or learned, are integrated via excitatory and inhibitory synapses, respectively to form complex valence signals in a single SP neuron. Organized synaptic compartments support dendritic computation, with SP neurons exhibiting opposite synaptic organizations for opponent valences, indicating dendritic integration for complex valence detection. Our study highlights the importance of SP in multimodal opponent valence integration and suggests generalizable network and dendritic structures for complex valence processing.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repositories
Its files are read in the Code ↔ Paper reader above, with 8 matches between paragraphs and lines of code.
lmcinnes/umap
1180b785023ff8e8eb071de56c581d1dc8bec04e, 24 September 2026Availability: 1 check, the latest on 28 September 2026: the link answers
- 28 September 2026: the link answers
64 files
- benchmarks/
bench_adjmat_vectorize.p , Python, 98 linesy - benchmarks/
bench_fastmath_removal.p , Python, 301 linesy - ci_scripts/
install.sh , Shell, 86 lines - ci_scripts/
success.sh , Shell, 13 lines - ci_scripts/
test.sh , Shell, 12 lines - doc/
bokeh_digits_plot.py , Python, 73 lines - doc/
conf.py , Python, 239 lines - doc/
plotting_example_interac , Python, 32 linestive.py - examples/
digits/ , Python, 34 linesdigits.py - examples/
galaxy10sdss.py , Python, 275 lines - examples/
inverse_transform_exampl , Python, 60 linese.py - examples/
iris/ , Python, 37 linesiris.py - examples/
mnist_torus_sphere_examp , Python, 120 linesle.py - examples/
mnist_transform_new_data , Python, 48 lines.py - examples/
plot_algorithm_compariso , Python, 140 linesn.py - examples/
plot_fashion-mnist_examp , Python, 74 linesle.py - examples/
plot_feature_extraction_ , Python, 72 linesclassification.py - examples/
plot_mnist_example.py , Python, 35 lines - notebooks/
AnimatingUMAP.ipynb , Jupyter, 168 lines - notebooks/
Document embedding using UMAP.ipynb , Jupyter, 163 lines - notebooks/
MNIST_Landmarks.ipynb , Jupyter, 177 lines - notebooks/
Parametric_UMAP/ , Jupyter, 92 lines01.0-parametric-umap-mni st-embedding-basic.ipynb - notebooks/
Parametric_UMAP/ , Jupyter, 89 lines02.0-parametric-umap-mni st-embedding-convnet.ipy nb - notebooks/
Parametric_UMAP/ , Jupyter, 164 lines03.0-parametric-umap-mni st-embedding-convnet-wit h-reconstruction.ipynb - notebooks/
Parametric_UMAP/ , Jupyter, 144 lines04.0-parametric-umap-mni st-embedding-convnet-wit h-autoencoder-loss.ipynb - notebooks/
Parametric_UMAP/ , Jupyter, 77 lines05.0-parametric-umap-wit h-callback.ipynb - notebooks/
Parametric_UMAP/ , Jupyter, 60 lines06.0-nonparametric-umap. ipynb - notebooks/
Parametric_UMAP/ , Jupyter, 225 lines07.0-parametric-umap-glo bal-loss.ipynb - notebooks/
UMAP usage and parameters.ipynb , Jupyter, 260 lines - setup.py, Python, 5 lines
- umap/
__init__.py , Python, 42 lines - umap/
aligned_umap.py , Python, 607 lines - umap/
distances.py , Python, 1,561 lines - umap/
layouts.py , Python, 1,100 lines, 1 match - umap/
parametric_umap.py , Python, 1,402 lines - umap/
plot.py , Python, 1,692 lines - umap/
sparse.py , Python, 624 lines - umap/
spectral.py , Python, 573 lines - umap/
tests/ , Python, 50 lines__init__.py - umap/
tests/ , Python, 232 linesconftest.py - umap/
tests/ , Python, 155 linestest_aligned_umap.py - umap/
tests/ , Python, 333 linestest_chunked_parallel_sp atial_metric.py - umap/
tests/ , Python, 117 linestest_composite_models.py - umap/
tests/ , Python, 85 linestest_data_input.py - umap/
tests/ , Python, 80 linestest_densmap.py - umap/
tests/ , Python, 109 linestest_numba_aware_pairwis e_distances.py - umap/
tests/ , Python, 190 linestest_parametric_umap.py - umap/
tests/ , Python, 50 linestest_plot.py - umap/
tests/ , Python, 51 linestest_spectral.py - umap/
tests/ , Python, 1 linetest_umap.py - umap/
tests/ , Python, 82 linestest_umap_get_feature_na mes_out.py - umap/
tests/ , Python, 288 linestest_umap_grads.py - umap/
tests/ , Python, 742 linestest_umap_metrics.py - umap/
tests/ , Python, 198 linestest_umap_nn.py - umap/
tests/ , Python, 316 linestest_umap_on_iris.py - umap/
tests/ , Python, 381 linestest_umap_ops.py - umap/
tests/ , Python, 94 linestest_umap_repeated_data. py - umap/
tests/ , Python, 158 linestest_umap_trustworthines s.py - umap/
tests/ , Python, 322 linestest_umap_validation_par ams.py - umap/
umap_.py , Python, 3,762 lines, 2 matches - umap/
utils.py , Python, 228 lines - umap/
validation.py , Python, 86 lines - LICENSE.txt, License, 29 lines
- README.rst, Text, 571 lines
navis-org/navis
cb9a5915b6b3587cb81154f4f77ffc62fe12b03a, 6 September 2026Availability: 1 check, the latest on 26 September 2026: the link answers
- 26 September 2026: the link answers
303 files
- conftest.py, Python, 33 lines
- docs/
examples/ , Python, 226 lines0_io/ tutorial_io_00_skeletons .py - docs/
examples/ , Python, 120 lines0_io/ tutorial_io_01_meshes.py - docs/
examples/ , Python, 143 lines0_io/ tutorial_io_02_dotprops. py - docs/
examples/ , Python, 192 lines0_io/ tutorial_io_03_r.py - docs/
examples/ , Python, 54 lines0_io/ tutorial_io_04_pickle.py - docs/
examples/ , Python, 252 lines0_io/ zzz_tutorial_io_05_skele tonize.py - docs/
examples/ , Python, 354 lines1a_plotting_general/ tutorial_plotting_00_int ro.py - docs/
examples/ , Python, 307 lines1a_plotting_general/ tutorial_plotting_01_col ors.py - docs/
examples/ , Python, 195 lines1b_plotting_2d/ tutorial_plotting_2d_00_ skeletons.py - docs/
examples/ , Python, 206 lines1b_plotting_2d/ tutorial_plotting_2d_01_ meshes.py - docs/
examples/ , Python, 178 lines1b_plotting_2d/ tutorial_plotting_2d_02_ volumes.py - docs/
examples/ , Python, 201 lines1c_plotting_3d/ tutorial_plotting_3d_00_ skeletons.py - docs/
examples/ , Python, 150 lines1c_plotting_3d/ tutorial_plotting_3d_01_ meshes.py - docs/
examples/ , Python, 161 lines1c_plotting_3d/ tutorial_plotting_3d_02_ volumes.py - docs/
examples/ , Python, 353 lines1d_plotting_misc/ tutorial_plotting_misc_0 0_connectors.py - docs/
examples/ , Python, 100 lines1d_plotting_misc/ tutorial_plotting_misc_0 1_barcode.py - docs/
examples/ , Python, 129 lines1d_plotting_misc/ tutorial_plotting_misc_0 2_topology.py - docs/
examples/ , Python, 59 lines1d_plotting_misc/ tutorial_plotting_misc_0 3_xkcd.py - docs/
examples/ , Python, 378 lines1d_plotting_misc/ zzz_tutorial_plotting_mi sc_04_collage.py - docs/
examples/ , Python, 300 lines1e_plotting_examples/ tutorial_plotting_ex_00_ cortex.py - docs/
examples/ , Python, 451 lines2_morpho/ tutorial_morpho_00_manip ulate.py - docs/
examples/ , Python, 338 lines2_morpho/ tutorial_morpho_01_analy ze.py - docs/
examples/ , Python, 167 lines2_morpho/ tutorial_morpho_02_label _prop.py - docs/
examples/ , Python, 204 lines2_morpho/ tutorial_morpho_03_ad_sp lit.py - docs/
examples/ , Python, 476 lines2_morpho/ zzz_tutorial_morpho_05_i vscc.py - docs/
examples/ , Python, 567 lines2_morpho/ zzz_tutorial_morpho_06_i vscc_em.py - docs/
examples/ , Python, 332 lines3_interfaces/ tutorial_interfaces_00_n euron.py - docs/
examples/ , Python, 190 lines3_interfaces/ tutorial_interfaces_01_n euron2.py - docs/
examples/ , Python, 165 lines3_interfaces/ tutorial_interfaces_02_b lender.py - docs/
examples/ , Python, 101 lines4_remote/ tutorial_remote_00_neupr int.py - docs/
examples/ , Python, 110 lines4_remote/ tutorial_remote_01_cloud volume.py - docs/
examples/ , Python, 199 lines4_remote/ tutorial_remote_02_micro ns.py - docs/
examples/ , Python, 122 lines4_remote/ tutorial_remote_03_insec t_db.py - docs/
examples/ , Python, 163 lines4_remote/ tutorial_remote_04_h01.p y - docs/
examples/ , Python, 99 lines4_remote/ tutorial_remote_05_bil.p y - docs/
examples/ , Python, 456 lines5_nblast/ tutorial_nblast_00_intro .py - docs/
examples/ , Python, 147 lines5_nblast/ tutorial_nblast_03_smat. py - docs/
examples/ , Python, 159 lines5_nblast/ zzz_tutorial_nblast_01_f lycircuit.py - docs/
examples/ , Python, 160 lines5_nblast/ zzz_tutorial_nblast_02_h emibrain.py - docs/
examples/ , Python, 444 lines6_misc/ tutorial_misc_00_multipr ocess.py - docs/
examples/ , Python, 471 lines6_misc/ tutorial_misc_01_transfo rms.py - docs/
examples/ , Python, 209 lines7_ml/ tutorial_ml_00_normalize .py - docs/
examples/ , Python, 486 lines7_ml/ tutorial_ml_01_sampling. py - docs/
examples/ , Python, 184 lines7_ml/ tutorial_ml_02_augment.p y - docs/
examples/ , Python, 139 linestutorial_basic_00_basics .py - docs/
examples/ , Python, 625 linestutorial_basic_01_neuron s.py - docs/
examples/ , Python, 364 linestutorial_basic_02_neuron lists.py - docs/
examples/ , Python, 537 linestutorial_basic_03_maskin g.py - docs/
examples/ , Python, 711 linestutorial_basic_04_attach .py - docs/
gallery_conf.py , Python, 26 lines - docs/
javascripts/ , JavaScript, 10 lineskatex.js - docs/
javascripts/ , JavaScript, 19 linesmathjax.js - docs/
tools/ , Python, 1 line__init__.py - docs/
tools/ , Python, 32 linesnb_to_doc.py - download_test_data.sh, Shell, 21 lines
- examples/
colab.ipynb , Jupyter, 207 lines - main.py, Python, 24 lines
- navis/
__init__.py , Python, 41 lines - navis/
__version__.py , Python, 15 lines - navis/
_deprecated.py , Python, 321 lines - navis/
compute/ , Python, 75 lines__init__.py - navis/
compute/ , Python, 64 linesbackends/ __init__.py - navis/
compute/ , Python, 176 linesbackends/ _dask.py - navis/
compute/ , Python, 147 linesbackends/ _joblib.py - navis/
compute/ , Python, 58 linesbackends/ _pathos.py - navis/
compute/ , Python, 163 linesbackends/ _submitit.py - navis/
compute/ , Python, 769 linesbackends/ base.py - navis/
compute/ , Python, 184 linesbackends/ local.py - navis/
compute/ , Python, 641 linesdispatch.py - navis/
compute/ , Python, 188 linesthreads.py - navis/
config.py , Python, 337 lines - navis/
conftest.py , Python, 27 lines - navis/
connectivity/ , Python, 22 lines__init__.py - navis/
connectivity/ , Python, 236 linesadjacency.py - navis/
connectivity/ , Python, 118 linescnmetrics.py - navis/
connectivity/ , Python, 135 linesmatrix_utils.py - navis/
connectivity/ , Python, 181 linespredict.py - navis/
connectivity/ , Python, 494 linessimilarity.py - navis/
conversion/ , Python, 19 lines__init__.py - navis/
conversion/ , Python, 884 linesconverters.py - navis/
conversion/ , Python, 285 linesmeshing.py - navis/
conversion/ , Python, 204 lineswrappers.py - navis/
core/ , Python, 35 lines__init__.py - navis/
core/ , Python, 1,781 linesbase.py - navis/
core/ , Python, 838 linescore_utils.py - navis/
core/ , Python, 713 linesdotprop.py - navis/
core/ , Python, 367 linesmasking.py - navis/
core/ , Python, 725 linesmesh.py - navis/
core/ , Python, 1,281 linesneuronlist.py - navis/
core/ , Python, 22 linesneurons.py - navis/
core/ , Python, 824 linespipeline.py - navis/
core/ , Python, 2,525 linesschema.py - navis/
core/ , Python, 1,626 linesskeleton.py - navis/
core/ , Python, 738 linesvolumes.py - navis/
core/ , Python, 1,503 linesvoxel.py - navis/
data/ , Python, 17 lines__init__.py - navis/
data/ , Python, 220 linesload_data.py - navis/
graph/ , Python, 86 lines__init__.py - navis/
graph/ , Python, 246 linesclinic.py - navis/
graph/ , Python, 926 lines, 1 matchconverters.py - navis/
graph/ , Python, 3,635 linesgraph_utils.py - navis/
interfaces/ , Python, 46 lines__init__.py - navis/
interfaces/ , Python, 119 linesallen_celltypes.py - navis/
interfaces/ , Python, 426 linesbase.py - navis/
interfaces/ , Python, 1,255 linesblender.py - navis/
interfaces/ , Python, 1,258 linesbrain_image_library.py - navis/
interfaces/ , Python, 910 linescajal.py - navis/
interfaces/ , Python, 494 linescave_utils.py - navis/
interfaces/ , Python, 116 linesh01.py - navis/
interfaces/ , Python, 736 linesinsectbrain_db.py - navis/
interfaces/ , Python, 205 linesmicrons.py - navis/
interfaces/ , Python, 959 linesneuprint.py - navis/
interfaces/ , Python, 317 linesneuromorpho.py - navis/
interfaces/ , Python, 2 linesneuron/ __init__.py - navis/
interfaces/ , Python, 901 linesneuron/ comp.py - navis/
interfaces/ , Python, 846 linesneuron/ network.py - navis/
interfaces/ , Python, 39 linesneuron/ utils.py - navis/
interfaces/ , Python, 351 linesvfb.py - navis/
intersection/ , Python, 17 lines__init__.py - navis/
intersection/ , Python, 55 linesconvex.py - navis/
intersection/ , Python, 408 linesintersect.py - navis/
intersection/ , Python, 119 linesray.py - navis/
io/ , Python, 34 lines__init__.py - navis/
io/ , Python, 2,028 linesbase.py - navis/
io/ , Python, 1,127 lineshdf_io.py - navis/
io/ , Python, 161 linesjson_io.py - navis/
io/ , Python, 341 linesmesh_io.py - navis/
io/ , Python, 327 linesnmx_io.py - navis/
io/ , Python, 376 linesnrrd_io.py - navis/
io/ , Python, 1,251 linespq_io.py - navis/
io/ , Python, 686 linesprecomputed_io.py - navis/
io/ , Python, 1,129 linesrda_io.py - navis/
io/ , Python, 755 linesswc_io.py - navis/
io/ , Python, 294 linestiff_io.py - navis/
matching/ , Python, 17 lines__init__.py - navis/
matching/ , Python, 242 linesbipartite.py - navis/
matching/ , Python, 210 linespipeline.py - navis/
meshes/ , Python, 19 lines__init__.py - navis/
meshes/ , Python, 260 linesinternals.py - navis/
meshes/ , Python, 721 linesmesh_utils.py - navis/
meshes/ , Python, 339 linesoperations.py - navis/
ml/ , Python, 50 lines__init__.py - navis/
ml/ , Python, 686 linesaugment.py - navis/
ml/ , Python, 1,098 lineschunk.py - navis/
ml/ , Python, 316 linesnormalize.py - navis/
models/ , Python, 14 lines__init__.py - navis/
models/ , Python, 658 linesnetwork_models.py - navis/
morpho/ , Python, 47 lines__init__.py - navis/
morpho/ , Python, 555 linesanalyze.py - navis/
morpho/ , Python, 370 linesangles.py - navis/
morpho/ , Python, 154 linescaps.py - navis/
morpho/ , Python, 163 linesfq.py - navis/
morpho/ , Python, 239 linesheal.py - navis/
morpho/ , Python, 256 linesimages.py - navis/
morpho/ , Python, 840 linesivscc.py - navis/
morpho/ , Python, 2,596 linesmanipulation.py - navis/
morpho/ , Python, 1,585 linesmmetrics.py - navis/
morpho/ , Python, 428 linespersistence.py - navis/
morpho/ , Python, 582 linessubset.py - navis/
nbl/ , Python, 35 lines__init__.py - navis/
nbl/ , Python, 551 linesablast_funcs.py - navis/
nbl/ , Python, 43 linesbackends/ __init__.py - navis/
nbl/ , Python, 216 linesbackends/ base.py - navis/
nbl/ , Python, 530 linesbackends/ builtin.py - navis/
nbl/ , Python, 290 linesbackends/ fastcore.py - navis/
nbl/ , Python, 175 linesbase.py - navis/
nbl/ , Python, 1,412 lines, 2 matchesnblast_funcs.py - navis/
nbl/ , Python, 1,141 linessmat.py - navis/
nbl/ , Python, 395 lines, 2 matchessynblast_funcs.py - navis/
nbl/ , Python, 555 linesutils.py - navis/
plotting/ , Python, 24 lines__init__.py - navis/
plotting/ , Python, 436 lines_common.py - navis/
plotting/ , Python, 1,015 linescollage.py - navis/
plotting/ , Python, 805 linescolors.py - navis/
plotting/ , Python, 194 linesd.py - navis/
plotting/ , Python, 2,888 linesdd.py - navis/
plotting/ , Python, 837 linesddd.py - navis/
plotting/ , Python, 541 linesflat.py - navis/
plotting/ , Python, 1 linek3d/ __init__.py - navis/
plotting/ , Python, 9 linesk3d/ conftest.py - navis/
plotting/ , Python, 455 linesk3d/ k3d_objects.py - navis/
plotting/ , Python, 796 linesplot_utils.py - navis/
plotting/ , Python, 1 lineplotly/ __init__.py - navis/
plotting/ , Python, 9 linesplotly/ conftest.py - navis/
plotting/ , Python, 830 linesplotly/ graph_objs.py - navis/
plotting/ , Python, 307 linesrender.py - navis/
plotting/ , Python, 297 linessettings.py - navis/
plotting/ , Python, 109 linesviewer_utils.py - navis/
sampling/ , Python, 23 lines__init__.py - navis/
sampling/ , Python, 486 linesdownsampling.py - navis/
sampling/ , Python, 803 linespoints.py - navis/
sampling/ , Python, 990 linesresampling.py - navis/
sampling/ , Python, 273 linesutils.py - navis/
transforms/ , Python, 30 lines__init__.py - navis/
transforms/ , Python, 119 linesaffine.py - navis/
transforms/ , Python, 786 linesalign.py - navis/
transforms/ , Python, 263 linesbackends.py - navis/
transforms/ , Python, 417 linesbase.py - navis/
transforms/ , Python, 945 linescmtk.py - navis/
transforms/ , Python, 466 lineselastix.py - navis/
transforms/ , Python, 101 linesfactory.py - navis/
transforms/ , Python, 324 linesgrid.py - navis/
transforms/ , Python, 740 linesh5reg.py - navis/
transforms/ , Python, 215 linesh5reg_java.py - navis/
transforms/ , Python, 298 linesh5reg_numba.py - navis/
transforms/ , Python, 207 linesimages.py - navis/
transforms/ , Java, 84 linesjars/ TransformCoordinates.jav a - navis/
transforms/ , Python, 236 linesmoving_least_squares.py - navis/
transforms/ , Python, 246 linessimilarity.py - navis/
transforms/ , Python, 1,823 linestemplates.py - navis/
transforms/ , Python, 291 linesthinplate.py - navis/
transforms/ , Python, 540 linesxfm_funcs.py - navis/
utils/ , Python, 36 lines__init__.py - navis/
utils/ , Python, 238 linescave.py - navis/
utils/ , Python, 123 linescv.py - navis/
utils/ , Python, 774 linesdecorators.py - navis/
utils/ , Python, 356 lineseval.py - navis/
utils/ , Python, 25 linesexceptions.py - navis/
utils/ , Python, 145 lineshttp.py - navis/
utils/ , Python, 135 linesiterables.py - navis/
utils/ , Python, 263 linesmeshproc.py - navis/
utils/ , Python, 576 linesmisc.py - navis/
utils/ , Python, 202 linessubclasses.py - navis/
utils/ , Python, 147 linesvalidate.py - run_mypy.sh, Shell, 3 lines
- scripts/
gallery_index_hook.py , Python, 370 lines - scripts/
gen_llms_txt.py , Python, 577 lines - scripts/
gen_ref_pages.py , Python, 70 lines - scripts/
gen_ref_pages2.py , Python, 196 lines - setup.py, Python, 76 lines
- stubs/
numpy/ , Python, 1 line__init__.py - stubs/
numpy/ , Python, 4 lineslinalg.py - stubs/
pandas/ , Python, 1 line__init__.py - tests/
__init__.py , Python, 1 line - tests/
conftest.py , Python, 216 lines - tests/
fixtures/ , Python, 41 linesr_data/ generate.py - tests/
test_align.py , Python, 196 lines - tests/
test_angles.py , Python, 188 lines - tests/
test_bil.py , Python, 241 lines - tests/
test_caps.py , Python, 195 lines - tests/
test_cast_neuron.py , Python, 141 lines - tests/
test_cave_patch.py , Python, 211 lines - tests/
test_collage.py , Python, 593 lines - tests/
test_compute_backends.py , Python, 873 lines - tests/
test_compute_cluster.py , Python, 291 lines - tests/
test_compute_threads.py , Python, 325 lines - tests/
test_connected_component , Python, 354 liness.py - tests/
test_connecting_nodes.py , Python, 218 lines - tests/
test_connectivity.py , Python, 138 lines - tests/
test_deprecated_names.py , Python, 145 lines - tests/
test_dotprops.py , Python, 310 lines - tests/
test_downsample.py , Python, 378 lines - tests/
test_error_messages.py , Python, 206 lines - tests/
test_extra_edges.py , Python, 349 lines - tests/
test_face_connectivity.p , Python, 409 linesy - tests/
test_flow_metrics.py , Python, 114 lines - tests/
test_geodesic_clusters.p , Python, 223 linesy - tests/
test_geodesic_nearest.py , Python, 136 lines - tests/
test_graph_contracts.py , Python, 639 lines - tests/
test_graph_primitives.py , Python, 171 lines - tests/
test_guess_change.py , Python, 187 lines - tests/
test_heal.py , Python, 412 lines - tests/
test_heal_mesh.py , Python, 283 lines - tests/
test_interfaces_base.py , Python, 344 lines - tests/
test_io.py , Python, 780 lines - tests/
test_io_url.py , Python, 131 lines - tests/
test_ivscc.py , Python, 401 lines - tests/
test_links.py , Python, 1,511 lines - tests/
test_llms_txt.py , Python, 223 lines - tests/
test_masking.py , Python, 547 lines - tests/
test_mesh_ops.py , Python, 611 lines - tests/
test_mesh_process.py , Python, 292 lines - tests/
test_ml.py , Python, 918 lines - tests/
test_models/ , Python, 1 line__init__.py - tests/
test_models/ , Python, 72 linestest_network_models.py - tests/
test_morpho_contracts.py , Python, 251 lines - tests/
test_nbl/ , Python, 1 line__init__.py - tests/
test_nbl/ , Python, 293 linestest_extract_matches.py - tests/
test_nbl/ , Python, 259 linestest_nblast_dispatch.py - tests/
test_nbl/ , Python, 255 linestest_nblast_knn.py - tests/
test_nbl/ , Python, 131 linestest_partition.py - tests/
test_nbl/ , Python, 142 linestest_smat.py - tests/
test_neuron_methods.py , Python, 467 lines - tests/
test_neurons.py , Python, 337 lines - tests/
test_node_label_sorting. , Python, 109 linespy - tests/
test_parallel.py , Python, 288 lines - tests/
test_pipeline.py , Python, 616 lines - tests/
test_plotting.py , Python, 2,073 lines - tests/
test_propagate_labels.py , Python, 106 lines - tests/
test_quiet_logger.py , Python, 121 lines - tests/
test_resample.py , Python, 487 lines - tests/
test_sample.py , Python, 344 lines - tests/
test_schema.py , Python, 613 lines - tests/
test_sholl.py , Python, 206 lines - tests/
test_smooth.py , Python, 343 lines - tests/
test_soma.py , Python, 232 lines - tests/
test_transform_backends. , Python, 1,167 linespy - tests/
test_transforms.py , Python, 93 lines - tests/
test_tutorials.py , Python, 113 lines - tests/
test_voxel.py , Python, 1,754 lines - LICENSE, License, 674 lines
- README.md, Text, 123 lines
aplbrain/dotmotif
125fdbca18c1c8ac7ed1b8d3f595669edc36574f, 23 September 2026Availability: 1 check, the latest on 28 September 2026: the link answers
- 28 September 2026: the link answers
29 files
- docs/
examples/ , Python, 23 linesCounting Triangles in MICrONS v185.py - docs/
examples/ , Python, 17 linesSearching in neuPrint.py - dotmotif/
__init__.py , Python, 389 lines - dotmotif/
executors/ , Python, 11 linesExecutor.py - dotmotif/
executors/ , Python, 122 linesGrandIsoExecutor.py - dotmotif/
executors/ , Python, 480 linesNeo4jExecutor.py - dotmotif/
executors/ , Python, 458 linesNetworkXExecutor.py - dotmotif/
executors/ , Python, 151 linesNeuPrintExecutor.py - dotmotif/
executors/ , Python, 21 lines__init__.py - dotmotif/
executors/ , Python, 270 linestest_dm_cypher.py - dotmotif/
executors/ , Python, 717 linestest_grandisoexecutor.py - dotmotif/
executors/ , Python, 48 linestest_neo4jexecutor.py - dotmotif/
executors/ , Python, 736 linestest_networkxexecutor.py - dotmotif/
executors/ , Python, 96 linestest_neuprintexecutor.py - dotmotif/
ingest/ , Python, 207 lines__init__.py - dotmotif/
ingest/ , Python, 130 linestest_ingest.py - dotmotif/
parsers/ , Python, 11 lines__init__.py - dotmotif/
parsers/ , Python, 631 linesv2/ __init__.py - dotmotif/
parsers/ , Python, 613 linesv2/ test_v2_parser.py - dotmotif/
tests/ , Python, 1 line__init__.py - dotmotif/
tests/ , Python, 121 linestest_automorphism_exclus ion.py - dotmotif/
tests/ , Python, 256 linestest_dm_flags.py - dotmotif/
tests/ , Python, 206 linestest_multigraphs.py - dotmotif/
tests/ , Python, 87 linestest_utils.py - dotmotif/
utils.py , Python, 130 lines - dotmotif/
validators/ , Python, 182 lines__init__.py - dotmotif/
validators/ , Python, 19 linestest_dm_illegal_operator s.py - LICENSE, License, 174 lines
- README.md, Text, 88 lines
google/neuroglancer
da443d25610b23c40c4a46ed9b92129e6203e68e, 22 September 2026Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
904 files
- build_tools/
after-version-change.ts , TypeScript, 48 lines - build_tools/
build-package.ts , TypeScript, 247 lines - build_tools/
cli.ts , TypeScript, 266 lines - build_tools/
postpack.ts , TypeScript, 9 lines - build_tools/
rspack/ , JavaScript, 13 linesconfiguration_with_defin e.js - build_tools/
rspack/ , JavaScript, 12 linesrspack_config_from_cli.j s - build_tools/
update-conditions.ts , TypeScript, 147 lines - build_tools/
update-example-dependenc , TypeScript, 30 linesies.ts - build_tools/
vitest/ , TypeScript, 57 linesbuild_fake_gcs_server.ts - build_tools/
vitest/ , TypeScript, 98 linesfake_ngauth_server.ts - build_tools/
vitest/ , TypeScript, 16 linespolyfill-browser-globals -in-node.ts - build_tools/
vitest/ , TypeScript, 26 linespython_tools.ts - build_tools/
vitest/ , TypeScript, 51 linestest_data_server.ts - build_tools/
vitest/ , TypeScript, 50 linesvitest-environment-jsdom -patched/ index.ts - cors_webserver.py, Python, 62 lines
- docs/
concepts/ , Python, 59 linesdata_source_coordinate_s pace.screenshot.py - docs/
concepts/ , Python, 59 linesdata_source_coordinate_t ransform.screenshot.py - docs/
conf.py , Python, 344 lines - docs/
generate_logo.py , Python, 122 lines - docs/
update_intersphinx_inven , Python, 42 linestories.py - docs/
user-guide/ , Python, 28 linesnavigation_mouse_cross_s ection_translate.video.p y - docs/
user-guide/ , Python, 30 linesnavigation_mouse_cross_s ection_zoom.video.py - eslint.config.js, JavaScript, 124 lines
- examples/
parcel/ , JavaScript, 3 linesparcel-project-built/ src/ index.js - examples/
parcel/ , JavaScript, 3 linesparcel-project-source/ src/ index.js - examples/
rsbuild/ , TypeScript, 45 linesrsbuild-project-built/ rsbuild.config.ts - examples/
rsbuild/ , JavaScript, 3 linesrsbuild-project-built/ src/ index.js - examples/
rsbuild/ , TypeScript, 60 linesrsbuild-project-source/ rsbuild.config.ts - examples/
rsbuild/ , JavaScript, 3 linesrsbuild-project-source/ src/ index.js - examples/
rspack/ , JavaScript, 46 linesrspack-project-built/ rspack.config.js - examples/
rspack/ , JavaScript, 3 linesrspack-project-built/ src/ index.js - examples/
rspack/ , JavaScript, 61 linesrspack-project-source/ rspack.config.js - examples/
rspack/ , JavaScript, 3 linesrspack-project-source/ src/ index.js - examples/
vite/ , TypeScript, 47 linesvite-project-built/ vite.config.ts - examples/
vite/ , TypeScript, 51 linesvite-project-source/ vite.config.ts - examples/
webpack/ , JavaScript, 3 lineswebpack-project-built/ src/ index.js - examples/
webpack/ , JavaScript, 48 lineswebpack-project-built/ webpack.config.js - examples/
webpack/ , JavaScript, 3 lineswebpack-project-source/ src/ index.js - examples/
webpack/ , JavaScript, 58 lineswebpack-project-source/ webpack.config.js - ngauth_server/
auth.go , Go, 521 lines - ngauth_server/
bounded_access_token.go , Go, 95 lines - ngauth_server/
go.mod , NEURON, 30 lines - ngauth_server/
main.go , Go, 52 lines - noxfile.py, Python, 195 lines
- playwright.config.ts, TypeScript, 22 lines
- python/
build_tools/ , Shell, 12 linescibuildwheel_linux_cache _setup.sh - python/
copy_openmesh_deps.py , Python, 49 lines - python/
examples/ , Python, 83 linesagglomeration_split_tool _csv_to_sqlite.py - python/
examples/ , Python, 70 linesexample.py - python/
examples/ , Python, 30 linesexample_action.py - python/
examples/ , Python, 55 linesexample_add_cube.py - python/
examples/ , Python, 66 linesexample_annotation_prope rties.py - python/
examples/ , Python, 58 linesexample_cdf.py - python/
examples/ , Python, 58 linesexample_coordinate_array s.py - python/
examples/ , Python, 46 linesexample_coordinate_trans form.py - python/
examples/ , Python, 40 linesexample_cross_section.py - python/
examples/ , Python, 53 linesexample_dask.py - python/
examples/ , Python, 20 linesexample_fixed_token.py - python/
examples/ , Python, 39 linesexample_grid_layout.py - python/
examples/ , Python, 39 linesexample_layer_side_panel s.py - python/
examples/ , Python, 63 linesexample_local_volume_coo rdinate_arrays.py - python/
examples/ , Python, 49 linesexample_overlay.py - python/
examples/ , Python, 87 linesexample_partial_viewport .py - python/
examples/ , Python, 16 linesexample_precomputed_gcs. py - python/
examples/ , Python, 23 linesexample_read_precomputed _annotations.py - python/
examples/ , Python, 29 linesexample_row_layout.py - python/
examples/ , Python, 45 linesexample_signed_int.py - python/
examples/ , Python, 16 linesexample_single_mesh_laye r.py - python/
examples/ , Python, 76 linesexample_skeletons.py - python/
examples/ , Python, 51 linesexample_toggle_visibilit y.py - python/
examples/ , Python, 24 linesexample_tool.py - python/
examples/ , Python, 290 linesextend_segments_tool.py - python/
examples/ , Python, 250 linesflood_filling_simulation .py - python/
examples/ , Python, 115 linesinteractive_inference.py - python/
examples/ , Jupyter, 177 linesjupyter-notebook-demo.ip ynb - python/
examples/ , Python, 192 linessynaptic_partners.py - python/
examples/ , Python, 32 lineswebdriver_example.py - python/
examples/ , Python, 207 lineswrite_annotations.py - python/
ext/ , C++, 208 linessrc/ _neuroglancer.cc - python/
ext/ , C++, 232 linessrc/ compress_segmentation.cc - python/
ext/ , C/C++, 173 linessrc/ compress_segmentation.h - python/
ext/ , C++, 229 linessrc/ compress_segmentation_te st.cc - python/
ext/ , Python, 72 linessrc/ generate_marching_cubes_ tables.py - python/
ext/ , C++, 147 linessrc/ mesh_objects.cc - python/
ext/ , C/C++, 38 linessrc/ mesh_objects.h - python/
ext/ , C++, 226 linessrc/ on_demand_object_mesh_ge nerator.cc - python/
ext/ , C/C++, 61 linessrc/ on_demand_object_mesh_ge nerator.h - python/
ext/ , C++, 22 linessrc/ openmesh_dependencies.cc - python/
ext/ , C++, 479 linessrc/ voxel_mesh_generator.cc - python/
ext/ , C/C++, 246 linessrc/ voxel_mesh_generator.h - python/
ext/ , C++, 260 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ Mesh/ ArrayKernel.cc - python/
ext/ , C++, 315 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ Mesh/ ArrayKernelT.cc - python/
ext/ , C++, 1,233 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ Mesh/ PolyConnectivity.cc - python/
ext/ , C++, 458 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ Mesh/ PolyMeshT.cc - python/
ext/ , C++, 500 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ Mesh/ TriConnectivity.cc - python/
ext/ , C++, 93 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ Mesh/ TriMeshT.cc - python/
ext/ , C/C++, 111 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ System/ config.h - python/
ext/ , C++, 107 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ System/ omstream.cc - python/
ext/ , C++, 59 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ Utils/ BaseProperty.cc - python/
ext/ , C++, 85 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Core/ Utils/ SingletonT.cc - python/
ext/ , C++, 310 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Tools/ Decimater/ BaseDecimaterT.cc - python/
ext/ , C++, 369 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Tools/ Decimater/ DecimaterT.cc - python/
ext/ , C++, 159 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Tools/ Decimater/ ModQuadricT.cc - python/
ext/ , C++, 98 linesthird_party/ openmesh/ OpenMesh/ src/ OpenMesh/ Tools/ Decimater/ Observer.cc - python/
neuroglancer/ , Python, 122 lines__init__.py - python/
neuroglancer/ , Python, 86 linesasync_util.py - python/
neuroglancer/ , Python, 55 linesboss_credentials.py - python/
neuroglancer/ , Python, 39 lineschunks.py - python/
neuroglancer/ , Python, 93 linescli.py - python/
neuroglancer/ , Python, 320 linescoordinate_space.py - python/
neuroglancer/ , Python, 69 linescredentials_provider.py - python/
neuroglancer/ , Python, 56 linesdefault_credentials_mana ger.py - python/
neuroglancer/ , Python, 42 linesdownsample.py - python/
neuroglancer/ , Python, 101 linesdownsample_scales.py - python/
neuroglancer/ , Python, 57 linesdvid_credentials.py - python/
neuroglancer/ , Python, 193 linesequivalence_map.py - python/
neuroglancer/ , Python, 63 linesfutures.py - python/
neuroglancer/ , Python, 85 linesgoogle_credentials.py - python/
neuroglancer/ , Python, 59 linesjson_utils.py - python/
neuroglancer/ , Python, 649 linesjson_wrappers.py - python/
neuroglancer/ , Python, 386 lineslocal_volume.py - python/
neuroglancer/ , Python, 21 linesrandom_token.py - python/
neuroglancer/ , Python, 642 linesread_precomputed_annotat ions.py - python/
neuroglancer/ , Python, 94 linesread_precomputed_segment _properties.py - python/
neuroglancer/ , Python, 102 linesread_precomputed_skeleto ns.py - python/
neuroglancer/ , Python, 51 linesscreenshot.py - python/
neuroglancer/ , Python, 91 linessegment_colors.py - python/
neuroglancer/ , Python, 653 linesserver.py - python/
neuroglancer/ , Python, 101 linesskeleton.py - python/
neuroglancer/ , Python, 102 linesstatic/ __init__.py - python/
neuroglancer/ , Python, 64 linesstatic_file_server.py - python/
neuroglancer/ , Python, 13 linestest_util.py - python/
neuroglancer/ , Python, 47 linestest_utils.py - python/
neuroglancer/ , Python, 1 linetool/ __init__.py - python/
neuroglancer/ , Python, 904 linestool/ agglomeration_split_tool .py - python/
neuroglancer/ , Python, 68 linestool/ cube.py - python/
neuroglancer/ , Python, 139 linestool/ edit_states.py - python/
neuroglancer/ , Python, 217 linestool/ filter_bodies.py - python/
neuroglancer/ , Python, 319 linestool/ mask_tool.py - python/
neuroglancer/ , Python, 526 linestool/ merge_tool.py - python/
neuroglancer/ , Python, 92 linestool/ save_meshes.py - python/
neuroglancer/ , Python, 815 linestool/ screenshot.py - python/
neuroglancer/ , Python, 664 linestool/ video_tool.py - python/
neuroglancer/ , Python, 217 linestrackable_state.py - python/
neuroglancer/ , Python, 158 linesurl_state.py - python/
neuroglancer/ , Python, 56 linesviewer.py - python/
neuroglancer/ , Python, 507 linesviewer_base.py - python/
neuroglancer/ , Python, 360 linesviewer_config_state.py - python/
neuroglancer/ , Python, 1,996 linesviewer_state.py - python/
neuroglancer/ , Python, 189 lineswebdriver.py - python/
neuroglancer/ , Python, 376 lineswrite_annotations.py - python/
tests/ , Python, 113 linesannotation_properties_te st.py - python/
tests/ , Python, 100 linesannotation_tool_test.py - python/
tests/ , Python, 186 linesconftest.py - python/
tests/ , Python, 59 linescontext_lost_test.py - python/
tests/ , Python, 64 linesdisplay_dimensions_test. py - python/
tests/ , Python, 78 linesequivalence_map_test.py - python/
tests/ , Python, 104 linesfill_value_test.py - python/
tests/ , Python, 59 linesjson_wrappers_test.py - python/
tests/ , Python, 64 lineslinked_segment_group_tes t.py - python/
tests/ , Python, 81 lineslocal_volume_test.py - python/
tests/ , Python, 10 linesmanaged_layer_test.py - python/
tests/ , Python, 84 linesmerge_tool_test.py - python/
tests/ , Python, 74 linesn5_test.py - python/
tests/ , Python, 56 lineson_demand_mesh_generator _test.py - python/
tests/ , Python, 259 linespicking_test.py - python/
tests/ , Python, 93 linesprecomputed_test.py - python/
tests/ , Python, 41 linesscreenshot_test.py - python/
tests/ , Python, 132 linessegment_colors_test.py - python/
tests/ , Python, 97 linesselected_values_test.py - python/
tests/ , Python, 186 linesshader_controls_test.py - python/
tests/ , Python, 79 linesskeleton_options_test.py - python/
tests/ , Python, 49 linestitle_test.py - python/
tests/ , Python, 50 linesurl_state_test.py - python/
tests/ , Python, 30 linesviewer_config_state_test .py - python/
tests/ , Python, 73 linesviewer_state_roundtrip_t est.py - python/
tests/ , Python, 118 linesviewer_state_test.py - python/
tests/ , Python, 172 linesvolume_rendering_test.py - python/
tests/ , Python, 151 lineswrite_annotations_test.p y - python/
tests/ , Python, 668 lineszarr_test.py - rspack.config.ts, TypeScript, 128 lines
- setup.py, Python, 293 lines
- src/
annotation/ , TypeScript, 244 linesannotation_layer_state.t s - src/
annotation/ , TypeScript, 574 linesbackend.ts - src/
annotation/ , TypeScript, 170 linesbase.ts - src/
annotation/ , TypeScript, 704 linesbounding_box.ts - src/
annotation/ , TypeScript, 361 linesellipsoid.ts - src/
annotation/ , TypeScript, 152 linesfrontend_source.browser_ test.ts - src/
annotation/ , TypeScript, 1,058 linesfrontend_source.ts - src/
annotation/ , TypeScript, 1,940 linesindex.ts - src/
annotation/ , TypeScript, 300 linesline.ts - src/
annotation/ , TypeScript, 237 linespoint.ts - src/
annotation/ , TypeScript, 342 linespolyline.ts - src/
annotation/ , TypeScript, 1,217 linesrenderlayer.ts - src/
annotation/ , TypeScript, 49 linesselection.ts - src/
annotation/ , TypeScript, 854 linestype_handler.ts - src/
async_computation.bundle , JavaScript, 8 lines.js - src/
async_computation/ , TypeScript, 25 linesdecode_blosc.ts - src/
async_computation/ , TypeScript, 22 linesdecode_blosc_request.ts - src/
async_computation/ , TypeScript, 24 linesdecode_compresso.ts - src/
async_computation/ , TypeScript, 22 linesdecode_compresso_request .ts - src/
async_computation/ , TypeScript, 24 linesdecode_crackle.ts - src/
async_computation/ , TypeScript, 21 linesdecode_crackle_request.t s - src/
async_computation/ , TypeScript, 88 linesdecode_jpeg.ts - src/
async_computation/ , TypeScript, 29 linesdecode_jpeg_request.ts - src/
async_computation/ , TypeScript, 37 linesdecode_jxl.ts - src/
async_computation/ , TypeScript, 27 linesdecode_jxl_request.ts - src/
async_computation/ , TypeScript, 44 linesdecode_png.ts - src/
async_computation/ , TypeScript, 36 linesdecode_png_request.ts - src/
async_computation/ , TypeScript, 25 linesdecode_zstd.ts - src/
async_computation/ , TypeScript, 30 linesdecode_zstd_node.ts - src/
async_computation/ , TypeScript, 22 linesdecode_zstd_request.ts - src/
async_computation/ , TypeScript, 44 linesencode_compressed_segmen tation.ts - src/
async_computation/ , TypeScript, 33 linesencode_compressed_segmen tation_request.ts - src/
async_computation/ , TypeScript, 58 lineshandler.ts - src/
async_computation/ , TypeScript, 33 linesindex.ts - src/
async_computation/ , TypeScript, 76 linesobj_mesh.ts - src/
async_computation/ , TypeScript, 25 linesobj_mesh_request.ts - src/
async_computation/ , TypeScript, 124 linesrequest.ts - src/
async_computation/ , TypeScript, 35 linesvtk_mesh.ts - src/
async_computation/ , TypeScript, 25 linesvtk_mesh_request.ts - src/
axes_lines.ts , TypeScript, 163 lines - src/
chunk_manager/ , TypeScript, 1,391 linesbackend.ts - src/
chunk_manager/ , TypeScript, 121 linesbase.ts - src/
chunk_manager/ , TypeScript, 533 linesfrontend.ts - src/
chunk_manager/ , TypeScript, 150 linesgeneric_file_source.ts - src/
chunk_worker.bundle.js , JavaScript, 14 lines - src/
coordinate_transform.spe , TypeScript, 517 linesc.ts - src/
coordinate_transform.ts , TypeScript, 1,976 lines - src/
credentials_provider/ , TypeScript, 99 lineschunk_source_frontend.ts - src/
credentials_provider/ , TypeScript, 40 linesdefault_manager.ts - src/
credentials_provider/ , TypeScript, 85 lineshttp_request.ts - src/
credentials_provider/ , TypeScript, 207 linesindex.ts - src/
credentials_provider/ , TypeScript, 129 linesinteractive_credentials_ provider.ts - src/
credentials_provider/ , TypeScript, 94 linesoauth2.ts - src/
credentials_provider/ , TypeScript, 117 linesshared.ts - src/
credentials_provider/ , TypeScript, 20 linesshared_common.ts - src/
credentials_provider/ , TypeScript, 131 linesshared_counterpart.ts - src/
data_management_context. , TypeScript, 79 linests - src/
data_panel_layout.ts , TypeScript, 978 lines - src/
datasource/ , TypeScript, 63 linesboss/ api.ts - src/
datasource/ , TypeScript, 1 lineboss/ async_computation.ts - src/
datasource/ , TypeScript, 143 linesboss/ backend.ts - src/
datasource/ , TypeScript, 46 linesboss/ base.ts - src/
datasource/ , TypeScript, 172 linesboss/ credentials_provider.ts - src/
datasource/ , TypeScript, 980 linesboss/ frontend.ts - src/
datasource/ , TypeScript, 24 linesboss/ register_credentials_pro vider.ts - src/
datasource/ , TypeScript, 20 linesboss/ register_default.ts - src/
datasource/ , TypeScript, 108 linesbrainmaps/ api.ts - src/
datasource/ , TypeScript, 1 linebrainmaps/ async_computation.ts - src/
datasource/ , TypeScript, 1,264 linesbrainmaps/ backend.ts - src/
datasource/ , TypeScript, 123 linesbrainmaps/ base.ts - src/
datasource/ , TypeScript, 37 linesbrainmaps/ credentials_provider.ts - src/
datasource/ , TypeScript, 1,267 linesbrainmaps/ frontend.ts - src/
datasource/ , TypeScript, 29 linesbrainmaps/ register_credentials_pro vider.ts - src/
datasource/ , TypeScript, 36 linesbrainmaps/ register_default.ts - src/
datasource/ , TypeScript, 2 linesdeepzoom/ async_computation.ts - src/
datasource/ , TypeScript, 151 linesdeepzoom/ backend.ts - src/
datasource/ , TypeScript, 31 linesdeepzoom/ base.ts - src/
datasource/ , TypeScript, 345 linesdeepzoom/ frontend.ts - src/
datasource/ , TypeScript, 31 linesdeepzoom/ register_default.ts - src/
datasource/ , TypeScript, 64 linesdefault_provider.ts - src/
datasource/ , TypeScript, 102 linesdvid/ api.ts - src/
datasource/ , TypeScript, 1 linedvid/ async_computation.ts - src/
datasource/ , TypeScript, 214 linesdvid/ backend.ts - src/
datasource/ , TypeScript, 44 linesdvid/ base.ts - src/
datasource/ , TypeScript, 86 linesdvid/ credentials_provider.ts - src/
datasource/ , TypeScript, 778 linesdvid/ frontend.ts - src/
datasource/ , TypeScript, 29 linesdvid/ register_credentials_pro vider.ts - src/
datasource/ , TypeScript, 20 linesdvid/ register_default.ts - src/
datasource/ , TypeScript, 12 linesenabled_async_computatio n_modules.ts - src/
datasource/ , TypeScript, 14 linesenabled_backend_modules. ts - src/
datasource/ , TypeScript, 18 linesenabled_frontend_modules .ts - src/
datasource/ , TypeScript, 1 linegraphene/ async_computation.ts - src/
datasource/ , TypeScript, 644 linesgraphene/ backend.ts - src/
datasource/ , TypeScript, 174 linesgraphene/ base.ts - src/
datasource/ , TypeScript, 3,124 linesgraphene/ frontend.ts - src/
datasource/ , TypeScript, 23 linesgraphene/ register_default.ts - src/
datasource/ , TypeScript, 686 linesindex.ts - src/
datasource/ , TypeScript, 218 lineskvstore_completions.ts - src/
datasource/ , TypeScript, 132 lineslocal.ts - src/
datasource/ , TypeScript, 2 linesn5/ async_computation.ts - src/
datasource/ , TypeScript, 120 linesn5/ backend.ts - src/
datasource/ , TypeScript, 30 linesn5/ base.ts - src/
datasource/ , TypeScript, 723 linesn5/ frontend.ts - src/
datasource/ , TypeScript, 31 linesn5/ register_default.ts - src/
datasource/ , TypeScript, 100 linesnggraph/ credentials_provider.ts - src/
datasource/ , TypeScript, 798 linesnggraph/ frontend.ts - src/
datasource/ , TypeScript, 20 linesnggraph/ register_default.ts - src/
datasource/ , TypeScript, 316 linesnifti/ backend.ts - src/
datasource/ , TypeScript, 38 linesnifti/ base.ts - src/
datasource/ , TypeScript, 260 linesnifti/ frontend.ts - src/
datasource/ , TypeScript, 31 linesnifti/ register_default.ts - src/
datasource/ , TypeScript, 1 lineobj/ async_computation.ts - src/
datasource/ , TypeScript, 45 linesobj/ backend.ts - src/
datasource/ , TypeScript, 26 linesobj/ register_default.ts - src/
datasource/ , TypeScript, 5 linesprecomputed/ async_computation.ts - src/
datasource/ , TypeScript, 1,095 linesprecomputed/ backend.ts - src/
datasource/ , TypeScript, 118 linesprecomputed/ base.ts - src/
datasource/ , TypeScript, 1,426 linesprecomputed/ frontend.ts - src/
datasource/ , TypeScript, 30 linesprecomputed/ register_default.ts - src/
datasource/ , TypeScript, 312 linesprecomputed/ sharded.ts - src/
datasource/ , TypeScript, 137 linespython/ backend.ts - src/
datasource/ , TypeScript, 45 linespython/ base.ts - src/
datasource/ , TypeScript, 43 linespython/ frontend.browser_test.ts - src/
datasource/ , TypeScript, 671 linespython/ frontend.ts - src/
datasource/ , TypeScript, 20 linespython/ register_default.ts - src/
datasource/ , TypeScript, 1 linerender/ async_computation.ts - src/
datasource/ , TypeScript, 155 linesrender/ backend.ts - src/
datasource/ , TypeScript, 35 linesrender/ base.ts - src/
datasource/ , TypeScript, 846 linesrender/ frontend.ts - src/
datasource/ , TypeScript, 20 linesrender/ register_default.ts - src/
datasource/ , TypeScript, 163 linesstate_share.ts - src/
datasource/ , TypeScript, 1 linevtk/ async_computation.ts - src/
datasource/ , TypeScript, 72 linesvtk/ backend.ts - src/
datasource/ , TypeScript, 299 linesvtk/ parse.ts - src/
datasource/ , TypeScript, 26 linesvtk/ register_default.ts - src/
datasource/ , TypeScript, 2 lineszarr/ async_computation.ts - src/
datasource/ , TypeScript, 100 lineszarr/ backend.ts - src/
datasource/ , TypeScript, 23 lineszarr/ base.ts - src/
datasource/ , TypeScript, 35 lineszarr/ codec/ blosc/ decode.ts - src/
datasource/ , TypeScript, 30 lineszarr/ codec/ blosc/ resolve.ts - src/
datasource/ , TypeScript, 53 lineszarr/ codec/ bytes/ decode.ts - src/
datasource/ , TypeScript, 71 lineszarr/ codec/ bytes/ resolve.ts - src/
datasource/ , TypeScript, 37 lineszarr/ codec/ crc32c/ decode.ts - src/
datasource/ , TypeScript, 36 lineszarr/ codec/ crc32c/ resolve.ts - src/
datasource/ , TypeScript, 211 lineszarr/ codec/ decode.ts - src/
datasource/ , TypeScript, 36 lineszarr/ codec/ gzip/ decode.ts - src/
datasource/ , TypeScript, 39 lineszarr/ codec/ gzip/ resolve.ts - src/
datasource/ , TypeScript, 66 lineszarr/ codec/ index.ts - src/
datasource/ , TypeScript, 226 lineszarr/ codec/ resolve.ts - src/
datasource/ , TypeScript, 201 lineszarr/ codec/ sharding_indexed/ decode.ts - src/
datasource/ , TypeScript, 127 lineszarr/ codec/ sharding_indexed/ resolve.ts - src/
datasource/ , TypeScript, 36 lineszarr/ codec/ transpose/ decode.ts - src/
datasource/ , TypeScript, 113 lineszarr/ codec/ transpose/ resolve.ts - src/
datasource/ , TypeScript, 35 lineszarr/ codec/ zstd/ decode.ts - src/
datasource/ , TypeScript, 30 lineszarr/ codec/ zstd/ resolve.ts - src/
datasource/ , TypeScript, 627 lineszarr/ frontend.ts - src/
datasource/ , TypeScript, 51 lineszarr/ metadata/ index.ts - src/
datasource/ , TypeScript, 444 lineszarr/ metadata/ parse.ts - src/
datasource/ , TypeScript, 41 lineszarr/ metadata/ parse_util.ts - src/
datasource/ , TypeScript, 1,419 lineszarr/ ome.spec.ts - src/
datasource/ , TypeScript, 881 lineszarr/ ome.ts - src/
datasource/ , TypeScript, 38 lineszarr/ register_default.ts - src/
display_context.ts , TypeScript, 718 lines - src/
gpu_hash/ , TypeScript, 32 lineshash_function.ts - src/
gpu_hash/ , TypeScript, 32 lineshash_table.benchmark.ts - src/
gpu_hash/ , TypeScript, 140 lineshash_table.spec.ts - src/
gpu_hash/ , TypeScript, 456 lineshash_table.ts - src/
gpu_hash/ , TypeScript, 188 linesshader.browser_test.ts - src/
gpu_hash/ , TypeScript, 224 linesshader.ts - src/
help/ , TypeScript, 268 linesinput_event_bindings.ts - src/
kvstore/ , TypeScript, 281 linesauto_detect.ts - src/
kvstore/ , TypeScript, 65 linesbackend.ts - src/
kvstore/ , TypeScript, 109 linesbyte_range/ file_handle.ts - src/
kvstore/ , TypeScript, 75 linesbyte_range/ index.ts - src/
kvstore/ , TypeScript, 41 linesbyte_range/ register.ts - src/
kvstore/ , TypeScript, 55 lineschunk_source_frontend.ts - src/
kvstore/ , TypeScript, 185 linescontext.ts - src/
kvstore/ , TypeScript, 3 linesenabled_async_computatio n_modules.ts - src/
kvstore/ , TypeScript, 11 linesenabled_backend_modules. ts - src/
kvstore/ , TypeScript, 13 linesenabled_frontend_modules .ts - src/
kvstore/ , TypeScript, 50 linesfrontend.ts - src/
kvstore/ , TypeScript, 150 linesgcs/ index.ts - src/
kvstore/ , TypeScript, 45 linesgcs/ register.ts - src/
kvstore/ , TypeScript, 235 linesgzip/ file_handle.ts - src/
kvstore/ , TypeScript, 96 linesgzip/ index.ts - src/
kvstore/ , TypeScript, 50 linesgzip/ register.ts - src/
kvstore/ , TypeScript, 26 lineshttp/ backend.ts - src/
kvstore/ , TypeScript, 115 lineshttp/ common.ts - src/
kvstore/ , TypeScript, 61 lineshttp/ frontend.ts - src/
kvstore/ , TypeScript, 128 lineshttp/ html_directory_listing.t s - src/
kvstore/ , TypeScript, 292 lineshttp/ read.ts - src/
kvstore/ , TypeScript, 21 lineshttp/ register_backend.ts - src/
kvstore/ , TypeScript, 21 lineshttp/ register_frontend.ts - src/
kvstore/ , TypeScript, 1 lineicechunk/ async_computation.ts - src/
kvstore/ , TypeScript, 37 linesicechunk/ auto_detect.ts - src/
kvstore/ , TypeScript, 112 linesicechunk/ backend.ts - src/
kvstore/ , TypeScript, 100 linesicechunk/ complete_url.ts - src/
kvstore/ , TypeScript, 61 linesicechunk/ crockford_base32.ts - src/
kvstore/ , TypeScript, 217 linesicechunk/ decode_utils.ts - src/
kvstore/ , TypeScript, 42 linesicechunk/ frontend.ts - src/
kvstore/ , TypeScript, 77 linesicechunk/ list.ts - src/
kvstore/ , TypeScript, 102 linesicechunk/ manifest.ts - src/
kvstore/ , TypeScript, 249 linesicechunk/ metadata_cache.ts - src/
kvstore/ , TypeScript, 216 linesicechunk/ read.ts - src/
kvstore/ , TypeScript, 48 linesicechunk/ ref.ts - src/
kvstore/ , TypeScript, 46 linesicechunk/ register_backend.ts - src/
kvstore/ , TypeScript, 59 linesicechunk/ register_frontend.ts - src/
kvstore/ , TypeScript, 261 linesicechunk/ snapshot.ts - src/
kvstore/ , TypeScript, 98 linesicechunk/ url.ts - src/
kvstore/ , TypeScript, 276 linesindex.ts - src/
kvstore/ , TypeScript, 90 linesmiddleauth/ common.ts - src/
kvstore/ , TypeScript, 218 linesmiddleauth/ credentials_provider.ts - src/
kvstore/ , TypeScript, 21 linesmiddleauth/ register_backend.ts - src/
kvstore/ , TypeScript, 33 linesmiddleauth/ register_credentials_pro vider.ts - src/
kvstore/ , TypeScript, 21 linesmiddleauth/ register_frontend.ts - src/
kvstore/ , TypeScript, 182 linesngauth/ credentials_provider.ts - src/
kvstore/ , TypeScript, 84 linesngauth/ register.ts - src/
kvstore/ , TypeScript, 43 linesngauth/ register_credentials_pro vider.ts - src/
kvstore/ , TypeScript, 1 lineocdbt/ async_computation.ts - src/
kvstore/ , TypeScript, 27 linesocdbt/ auto_detect.ts - src/
kvstore/ , TypeScript, 124 linesocdbt/ backend.ts - src/
kvstore/ , TypeScript, 474 linesocdbt/ btree.ts - src/
kvstore/ , TypeScript, 153 linesocdbt/ complete_url.ts - src/
kvstore/ , TypeScript, 234 linesocdbt/ decode_utils.ts - src/
kvstore/ , TypeScript, 42 linesocdbt/ frontend.ts - src/
kvstore/ , TypeScript, 192 linesocdbt/ indirect_data_reference. ts - src/
kvstore/ , TypeScript, 101 linesocdbt/ key.ts - src/
kvstore/ , TypeScript, 232 linesocdbt/ list.ts - src/
kvstore/ , TypeScript, 167 linesocdbt/ list_versions.ts - src/
kvstore/ , TypeScript, 275 linesocdbt/ manifest.ts - src/
kvstore/ , TypeScript, 191 linesocdbt/ metadata_cache.ts - src/
kvstore/ , TypeScript, 154 linesocdbt/ read.ts - src/
kvstore/ , TypeScript, 330 linesocdbt/ read_version.ts - src/
kvstore/ , TypeScript, 46 linesocdbt/ register_backend.ts - src/
kvstore/ , TypeScript, 59 linesocdbt/ register_frontend.ts - src/
kvstore/ , TypeScript, 56 linesocdbt/ url.ts - src/
kvstore/ , TypeScript, 188 linesocdbt/ version_specifier.ts - src/
kvstore/ , TypeScript, 621 linesocdbt/ version_tree.ts - src/
kvstore/ , TypeScript, 250 linesproxy.ts - src/
kvstore/ , TypeScript, 79 linesregister.ts - src/
kvstore/ , TypeScript, 26 liness3/ backend.ts - src/
kvstore/ , TypeScript, 175 liness3/ common.ts - src/
kvstore/ , TypeScript, 52 liness3/ frontend.ts - src/
kvstore/ , TypeScript, 241 liness3/ list.ts - src/
kvstore/ , TypeScript, 21 liness3/ register_backend.ts - src/
kvstore/ , TypeScript, 21 liness3/ register_frontend.ts - src/
kvstore/ , TypeScript, 22 linesshared_common.ts - src/
kvstore/ , TypeScript, 221 linesurl.ts - src/
kvstore/ , TypeScript, 46 lineszip/ auto_detect.ts - src/
kvstore/ , TypeScript, 256 lineszip/ backend.ts - src/
kvstore/ , TypeScript, 40 lineszip/ frontend.ts - src/
kvstore/ , TypeScript, 658 lineszip/ metadata.ts - src/
kvstore/ , TypeScript, 43 lineszip/ register_backend.ts - src/
kvstore/ , TypeScript, 46 lineszip/ register_frontend.ts - src/
layer/ , TypeScript, 983 linesannotation/ index.ts - src/
layer/ , TypeScript, 94 linesannotation/ property_tools.spec.ts - src/
layer/ , TypeScript, 669 linesannotation/ property_tools.ts - src/
layer/ , TypeScript, 49 linesannotation/ shader_ui_property_list. ts - src/
layer/ , TypeScript, 56 linesannotation/ tool_state.ts - src/
layer/ , TypeScript, 5 linesenabled_frontend_modules .ts - src/
layer/ , TypeScript, 614 linesimage/ index.ts - src/
layer/ , TypeScript, 2,545 linesindex.ts - src/
layer/ , TypeScript, 501 lineslayer_data_source.ts - src/
layer/ , TypeScript, 430 linesmulti_channel_setup.ts - src/
layer/ , TypeScript, 1,416 linessegmentation/ index.ts - src/
layer/ , TypeScript, 28 linessegmentation/ json_keys.ts - src/
layer/ , TypeScript, 156 linessegmentation/ layer_controls.ts - src/
layer/ , TypeScript, 281 linessingle_mesh/ index.ts - src/
layer_group_viewer.ts , TypeScript, 638 lines - src/
layer_groups_layout.ts , TypeScript, 823 lines - src/
layout.ts , TypeScript, 51 lines - src/
main.bundle.js , JavaScript, 5 lines - src/
main.ts , TypeScript, 23 lines - src/
main_module.ts , TypeScript, 4 lines - src/
main_python.ts , TypeScript, 235 lines - src/
mesh/ , TypeScript, 894 linesbackend.ts - src/
mesh/ , TypeScript, 51 linesbase.ts - src/
mesh/ , Shell, 13 linesdraco/ build.sh - src/
mesh/ , Python, 138 linesdraco/ build_wasm.py - src/
mesh/ , C/C++, 11 linesdraco/ draco_overlay/ draco/ draco_features.h - src/
mesh/ , Python, 28 linesdraco/ generate_first_bit_table .py - src/
mesh/ , TypeScript, 130 linesdraco/ index.ts - src/
mesh/ , C++, 158 linesdraco/ neuroglancer_draco.cc - src/
mesh/ , JavaScript, 6 linesdraco/ stub.js - src/
mesh/ , TypeScript, 1,170 linesfrontend.ts - src/
mesh/ , TypeScript, 1,048 linesmultiscale.spec.ts - src/
mesh/ , TypeScript, 403 linesmultiscale.ts - src/
mesh/ , TypeScript, 321 linestriangle_strips.spec.ts - src/
mesh/ , TypeScript, 349 linestriangle_strips.ts - src/
navigation_state.ts , TypeScript, 2,377 lines - src/
object_picking.ts , TypeScript, 131 lines - src/
overlay.ts , TypeScript, 119 lines - src/
perspective_view/ , TypeScript, 50 linesbackend.ts - src/
perspective_view/ , TypeScript, 17 linesbase.ts - src/
perspective_view/ , TypeScript, 1,510 linespanel.ts - src/
perspective_view/ , TypeScript, 124 linesrender_layer.ts - src/
projection_parameters.ts , TypeScript, 78 lines - src/
python_integration/ , TypeScript, 257 linesapi.ts - src/
python_integration/ , TypeScript, 99 linescredentials_provider.ts - src/
python_integration/ , TypeScript, 52 linesevent_action_map.ts - src/
python_integration/ , TypeScript, 119 linesprefetch.ts - src/
python_integration/ , TypeScript, 87 linesremote_actions.ts - src/
python_integration/ , TypeScript, 96 linesremote_status_messages.t s - src/
python_integration/ , TypeScript, 235 linesscreenshots.ts - src/
python_integration/ , TypeScript, 598 linesvolume.ts - src/
render_coordinate_transf , TypeScript, 873 linesorm.ts - src/
render_layer_backend.ts , TypeScript, 104 lines - src/
render_layer_common.ts , TypeScript, 21 lines - src/
render_scale_statistics. , TypeScript, 161 linests - src/
rendered_data_panel.ts , TypeScript, 850 lines - src/
rendered_data_panel_pick , TypeScript, 84 linesing.spec.ts - src/
rendered_data_panel_pick , TypeScript, 163 linesing.ts - src/
renderlayer.ts , TypeScript, 290 lines - src/
segment_color.browser_te , TypeScript, 67 linesst.ts - src/
segment_color.ts , TypeScript, 181 lines - src/
segmentation_display_sta , TypeScript, 100 lineste/ backend.ts - src/
segmentation_display_sta , TypeScript, 137 lineste/ base.ts - src/
segmentation_display_sta , TypeScript, 1,175 lineste/ frontend.ts - src/
segmentation_display_sta , TypeScript, 416 lineste/ property_map.spec.ts - src/
segmentation_display_sta , TypeScript, 1,339 lineste/ property_map.ts - src/
segmentation_graph/ , TypeScript, 88 lineslocal.spec.ts - src/
segmentation_graph/ , TypeScript, 304 lineslocal.ts - src/
segmentation_graph/ , TypeScript, 29 linessegment_id.ts - src/
segmentation_graph/ , TypeScript, 146 linessource.ts - src/
shared_disjoint_sets.ts , TypeScript, 194 lines - src/
shared_watchable_value.t , TypeScript, 109 liness - src/
single_mesh/ , TypeScript, 257 linesbackend.ts - src/
single_mesh/ , TypeScript, 56 linesbase.ts - src/
single_mesh/ , TypeScript, 97 linesfrontend.browser_test.ts - src/
single_mesh/ , TypeScript, 732 linesfrontend.ts - src/
skeleton/ , TypeScript, 202 linesbackend.ts - src/
skeleton/ , TypeScript, 24 linesbase.ts - src/
skeleton/ , TypeScript, 67 linesdecode_precomputed_skele ton.ts - src/
skeleton/ , TypeScript, 34 linesdecode_swc_skeleton.spec .ts - src/
skeleton/ , TypeScript, 113 linesdecode_swc_skeleton.ts - src/
skeleton/ , TypeScript, 901 linesfrontend.ts - src/
sliceview/ , TypeScript, 583 linesbackend.ts - src/
sliceview/ , TypeScript, 65 linesbackend_chunk_decoders/ bossNpz.ts - src/
sliceview/ , TypeScript, 26 linesbackend_chunk_decoders/ compressed_segmentation. ts - src/
sliceview/ , TypeScript, 35 linesbackend_chunk_decoders/ compresso.ts - src/
sliceview/ , TypeScript, 35 linesbackend_chunk_decoders/ crackle.ts - src/
sliceview/ , TypeScript, 27 linesbackend_chunk_decoders/ index.ts - src/
sliceview/ , TypeScript, 40 linesbackend_chunk_decoders/ jpeg.ts - src/
sliceview/ , TypeScript, 38 linesbackend_chunk_decoders/ jxl.ts - src/
sliceview/ , TypeScript, 59 linesbackend_chunk_decoders/ ndstoreNpz.ts - src/
sliceview/ , TypeScript, 44 linesbackend_chunk_decoders/ png.ts - src/
sliceview/ , TypeScript, 73 linesbackend_chunk_decoders/ postprocess.ts - src/
sliceview/ , TypeScript, 52 linesbackend_chunk_decoders/ raw.ts - src/
sliceview/ , TypeScript, 202 linesbase.spec.ts - src/
sliceview/ , TypeScript, 1,065 linesbase.ts - src/
sliceview/ , TypeScript, 442 linesbounding_box_shader_help er.ts - src/
sliceview/ , TypeScript, 18 lineschunk_format_handlers.ts - src/
sliceview/ , TypeScript, 147 lineschunk_format_testing.ts - src/
sliceview/ , TypeScript, 93 lineschunk_layout.ts - src/
sliceview/ , TypeScript, 148 linescompressed_segmentation/ chunk_format.browser_tes t.ts - src/
sliceview/ , TypeScript, 426 linescompressed_segmentation/ chunk_format.ts - src/
sliceview/ , TypeScript, 256 linescompressed_segmentation/ decode_common.ts - src/
sliceview/ , TypeScript, 28 linescompressed_segmentation/ decode_uint32.ts - src/
sliceview/ , TypeScript, 28 linescompressed_segmentation/ decode_uint64.ts - src/
sliceview/ , TypeScript, 68 linescompressed_segmentation/ encode.browser_benchmark .ts - src/
sliceview/ , TypeScript, 340 linescompressed_segmentation/ encode_common.ts - src/
sliceview/ , TypeScript, 360 linescompressed_segmentation/ encode_uint32.spec.ts - src/
sliceview/ , TypeScript, 29 linescompressed_segmentation/ encode_uint32.ts - src/
sliceview/ , TypeScript, 373 linescompressed_segmentation/ encode_uint64.spec.ts - src/
sliceview/ , TypeScript, 30 linescompressed_segmentation/ encode_uint64.ts - src/
sliceview/ , TypeScript, 34 linescompressed_segmentation/ test_util.ts - src/
sliceview/ , Shell, 13 linescompresso/ build.sh - src/
sliceview/ , Shell, 23 linescompresso/ build_wasm.sh - src/
sliceview/ , C++, 33 linescompresso/ compresso_wasm.cc - src/
sliceview/ , TypeScript, 124 linescompresso/ index.ts - src/
sliceview/ , Shell, 13 linescrackle/ build.sh - src/
sliceview/ , Shell, 23 linescrackle/ build_wasm.sh - src/
sliceview/ , C++, 30 linescrackle/ crackle_wasm.cc - src/
sliceview/ , TypeScript, 159 linescrackle/ index.ts - src/
sliceview/ , TypeScript, 1,119 linesfrontend.ts - src/
sliceview/ , Shell, 22 linesjxl/ build.sh - src/
sliceview/ , Shell, 6 linesjxl/ build_wasm.sh - src/
sliceview/ , TypeScript, 166 linesjxl/ index.ts - src/
sliceview/ , Shell, 4 linesjxl/ optimize_wasm.sh - src/
sliceview/ , Rust, 109 linesjxl/ src/ lib.rs - src/
sliceview/ , TypeScript, 568 linespanel.ts - src/
sliceview/ , Shell, 13 linespng/ build.sh - src/
sliceview/ , Shell, 30 linespng/ build_wasm.sh - src/
sliceview/ , TypeScript, 258 linespng/ index.ts - src/
sliceview/ , C, 73 linespng/ png_wasm.c - src/
sliceview/ , TypeScript, 295 linesrenderlayer.ts - src/
sliceview/ , TypeScript, 157 linessingle_texture_chunk_for mat.ts - src/
sliceview/ , TypeScript, 88 linesuncompressed_chunk_forma t.browser_test.ts - src/
sliceview/ , TypeScript, 417 linesuncompressed_chunk_forma t.ts - src/
sliceview/ , TypeScript, 159 linesvolume/ backend.ts - src/
sliceview/ , TypeScript, 312 linesvolume/ base.ts - src/
sliceview/ , TypeScript, 292 linesvolume/ frontend.ts - src/
sliceview/ , TypeScript, 161 linesvolume/ image_renderlayer.ts - src/
sliceview/ , TypeScript, 729 linesvolume/ renderlayer.ts - src/
sliceview/ , TypeScript, 460 linesvolume/ segmentation_renderlayer .ts - src/
sliceview/ , TypeScript, 212 lineswire_frame.ts - src/
status.ts , TypeScript, 231 lines - src/
third_party/ , TypeScript, 260 linescodemirror-glsl.ts - src/
third_party/ , TypeScript, 31 linesjpgjs/ jpg.d.ts - src/
third_party/ , JavaScript, 5,255 linesjpgjs/ jpg.js - src/
trackable_alpha.ts , TypeScript, 29 lines - src/
trackable_blend.ts , TypeScript, 43 lines - src/
trackable_boolean.ts , TypeScript, 137 lines - src/
trackable_finite_float.t , TypeScript, 29 liness - src/
trackable_value.ts , TypeScript, 542 lines - src/
trackable_vec3.ts , TypeScript, 58 lines - src/
ui/ , TypeScript, 204 linesannotation_properties.ts - src/
ui/ , TypeScript, 1,902 linesannotation_schema_tab.ts - src/
ui/ , TypeScript, 2,940 linesannotations.ts - src/
ui/ , TypeScript, 263 linesbounded_number_input.spe c.ts - src/
ui/ , TypeScript, 100 linesbounded_number_input.ts - src/
ui/ , TypeScript, 143 linescommand.ts - src/
ui/ , TypeScript, 250 linescommand_catalog.spec.ts - src/
ui/ , TypeScript, 468 linescommand_catalog.ts - src/
ui/ , TypeScript, 355 linescommand_palette.ts - src/
ui/ , TypeScript, 132 linescommand_registry.spec.ts - src/
ui/ , TypeScript, 94 linescommand_registry.ts - src/
ui/ , TypeScript, 150 linescontext_menu.ts - src/
ui/ , TypeScript, 55 linesdefault_clipboard_handli ng.spec.ts - src/
ui/ , TypeScript, 89 linesdefault_clipboard_handli ng.ts - src/
ui/ , TypeScript, 119 linesdefault_commands.spec.ts - src/
ui/ , TypeScript, 240 linesdefault_commands.ts - src/
ui/ , TypeScript, 206 linesdefault_input_event_bind ings.ts - src/
ui/ , TypeScript, 29 linesdefault_viewer.ts - src/
ui/ , TypeScript, 71 linesdefault_viewer_setup.ts - src/
ui/ , TypeScript, 40 linesdisable_default_actions. ts - src/
ui/ , TypeScript, 110 linesdrag_and_drop.ts - src/
ui/ , TypeScript, 517 lineslayer_bar.ts - src/
ui/ , TypeScript, 597 lineslayer_data_sources_tab.t s - src/
ui/ , TypeScript, 593 lineslayer_drag_and_drop.ts - src/
ui/ , TypeScript, 487 lineslayer_list_panel.ts - src/
ui/ , TypeScript, 481 lineslayer_side_panel.ts - src/
ui/ , TypeScript, 363 lineslayer_side_panel_state.t s - src/
ui/ , TypeScript, 43 linesminimal_viewer.ts - src/
ui/ , TypeScript, 96 linesposition_drag_and_drop.t s - src/
ui/ , TypeScript, 916 linesscreenshot_menu.ts - src/
ui/ , TypeScript, 1,657 linessegment_list.ts - src/
ui/ , TypeScript, 186 linessegment_select_tools.ts - src/
ui/ , TypeScript, 532 linessegment_split_merge_tool s.ts - src/
ui/ , TypeScript, 144 linessegmentation_display_opt ions_tab.ts - src/
ui/ , TypeScript, 209 linesselection_details.ts - src/
ui/ , TypeScript, 779 linesside_panel.ts - src/
ui/ , TypeScript, 182 linesside_panel_location.ts - src/
ui/ , TypeScript, 159 linesstate_editor.ts - src/
ui/ , TypeScript, 409 linesstatistics.ts - src/
ui/ , TypeScript, 36 linestitle.ts - src/
ui/ , TypeScript, 1,014 linestool.ts - src/
ui/ , TypeScript, 42 linestool_drag_and_drop.ts - src/
ui/ , TypeScript, 1,331 linestool_palette.ts - src/
ui/ , TypeScript, 322 linestool_query.spec.ts - src/
ui/ , TypeScript, 353 linestool_query.ts - src/
ui/ , TypeScript, 174 linesurl_hash_binding.ts - src/
ui/ , TypeScript, 148 linesviewer_settings.ts - src/
uint64_map.spec.ts , TypeScript, 125 lines - src/
uint64_map.ts , TypeScript, 138 lines - src/
uint64_ordered_set.ts , TypeScript, 117 lines - src/
uint64_set.spec.ts , TypeScript, 101 lines - src/
uint64_set.ts , TypeScript, 176 lines - src/
util/ , TypeScript, 91 linesabort.spec.ts - src/
util/ , TypeScript, 137 linesabort.ts - src/
util/ , TypeScript, 206 linesaffine.spec.ts - src/
util/ , TypeScript, 66 linesaffine.ts - src/
util/ , TypeScript, 64 linesanimation_frame_debounce .ts - src/
util/ , TypeScript, 307 linesarray.spec.ts - src/
util/ , TypeScript, 652 linesarray.ts - src/
util/ , TypeScript, 123 linesautomatic_focus.ts - src/
util/ , TypeScript, 27 linesbase64.ts - src/
util/ , TypeScript, 62 linesbigint.ts - src/
util/ , TypeScript, 91 linesclipboard.spec.ts - src/
util/ , TypeScript, 59 linesclipboard.ts - src/
util/ , TypeScript, 94 linescolor.browser_test.ts - src/
util/ , TypeScript, 249 linescolor.ts - src/
util/ , TypeScript, 106 linescolorspace.ts - src/
util/ , TypeScript, 22 linescompare.ts - src/
util/ , TypeScript, 181 linescompletion.ts - src/
util/ , TypeScript, 83 linesdata_type.ts - src/
util/ , TypeScript, 101 linesdisjoint_sets.spec.ts - src/
util/ , TypeScript, 241 linesdisjoint_sets.ts - src/
util/ , TypeScript, 143 linesdisposable.ts - src/
util/ , TypeScript, 84 linesdom.ts - src/
util/ , TypeScript, 33 linesdrag_and_drop.spec.ts - src/
util/ , TypeScript, 262 linesdrag_and_drop.ts - src/
util/ , TypeScript, 112 linesdropdown.ts - src/
util/ , TypeScript, 256 linesempirical_cdf.browser_te st.ts - src/
util/ , TypeScript, 198 linesempirical_cdf.ts - src/
util/ , TypeScript, 34 linesendian.spec.ts - src/
util/ , TypeScript, 145 linesendian.ts - src/
util/ , TypeScript, 39 lineserf.ts - src/
util/ , TypeScript, 46 lineserror.ts - src/
util/ , TypeScript, 499 linesevent_action_map.ts - src/
util/ , TypeScript, 3 linesfalse.ts - src/
util/ , TypeScript, 27 linesfile_download.ts - src/
util/ , TypeScript, 78 linesfloat.ts - src/
util/ , TypeScript, 70 linesfloat32_to_string.spec.t s - src/
util/ , TypeScript, 38 linesfloat32_to_string.ts - src/
util/ , TypeScript, 128 linesframerate.spec.ts - src/
util/ , TypeScript, 338 linesframerate.ts - src/
util/ , TypeScript, 201 linesgeom.spec.ts - src/
util/ , TypeScript, 524 linesgeom.ts - src/
util/ , TypeScript, 263 linesgoogle_oauth2.ts - src/
util/ , TypeScript, 16 linesgoogle_tag_manager.ts - src/
util/ , TypeScript, 71 linesgzip.ts - src/
util/ , TypeScript, 149 lineshash.ts - src/
util/ , TypeScript, 35 lineshex.ts - src/
util/ , TypeScript, 202 lineshierarchical_map.ts - src/
util/ , TypeScript, 146 lineshttp_request.ts - src/
util/ , TypeScript, 87 linesjson.spec.ts - src/
util/ , TypeScript, 797 linesjson.ts - src/
util/ , TypeScript, 171 lineskeyboard_bindings.ts - src/
util/ , TypeScript, 46 linesleb128.spec.ts - src/
util/ , TypeScript, 52 linesleb128.ts - src/
util/ , TypeScript, 339 lineslerp.ts - src/
util/ , TypeScript, 91 lineslinked_list.ts - src/
util/ , TypeScript, 44 lineslongest_common_prefix.ts - src/
util/ , TypeScript, 381 linesmatrix.spec.ts - src/
util/ , TypeScript, 360 linesmatrix.ts - src/
util/ , TypeScript, 178 linesmemoize.spec.ts - src/
util/ , TypeScript, 172 linesmemoize.ts - src/
util/ , TypeScript, 80 linesmessage_list.ts - src/
util/ , TypeScript, 27 linesmixin.ts - src/
util/ , TypeScript, 99 linesmouse_bindings.ts - src/
util/ , TypeScript, 55 linesmouse_drag.ts - src/
util/ , TypeScript, 68 linesnpy.spec.ts - src/
util/ , TypeScript, 101 linesnpy.ts - src/
util/ , TypeScript, 22 linesnumber.ts - src/
util/ , TypeScript, 28 linesnumber_to_string.spec.ts - src/
util/ , TypeScript, 26 linesnumber_to_string.ts - src/
util/ , TypeScript, 81 linesnumpy_dtype.ts - src/
util/ , TypeScript, 32 linesobject_id.ts - src/
util/ , TypeScript, 200 linespairing_heap.ts - src/
util/ , TypeScript, 2 linespolyfills.ts - src/
util/ , TypeScript, 177 linesprogress_listener.ts - src/
util/ , TypeScript, 52 linesrandom.ts - src/
util/ , TypeScript, 61 linesranked_matches.spec.ts - src/
util/ , TypeScript, 32 linesranked_matches.ts - src/
util/ , TypeScript, 462 linesscreenshot_manager.ts - src/
util/ , TypeScript, 39 linesscroll_into_view.ts - src/
util/ , TypeScript, 79 linessi_units.spec.ts - src/
util/ , TypeScript, 194 linessi_units.ts - src/
util/ , TypeScript, 132 linessignal.spec.ts - src/
util/ , TypeScript, 144 linessignal.ts - src/
util/ , TypeScript, 35 linessignal_binding_updater.t s - src/
util/ , TypeScript, 81 linesspatial_units.ts - src/
util/ , TypeScript, 19 linesstring.ts - src/
util/ , TypeScript, 365 linestouch_bindings.ts - src/
util/ , TypeScript, 201 linestrackable.ts - src/
util/ , TypeScript, 53 linestrackable_enum.ts - src/
util/ , TypeScript, 30 linestrackable_screenshot_mod e.ts - src/
util/ , TypeScript, 3 linestrue.ts - src/
util/ , TypeScript, 131 linesvector.ts - src/
util/ , TypeScript, 102 linesvelocity_estimation.ts - src/
util/ , TypeScript, 480 linesviewer_resolution_stats. ts - src/
util/ , TypeScript, 109 lineswatchable_map.ts - src/
util/ , TypeScript, 36 lineswheel_zoom.ts - src/
util/ , TypeScript, 68 lineszorder.spec.ts - src/
util/ , TypeScript, 136 lineszorder.ts - src/
viewer.ts , TypeScript, 1,356 lines - src/
viewer_state.ts , TypeScript, 39 lines - src/
visibility_priority/ , TypeScript, 70 linesbackend.ts - src/
visibility_priority/ , TypeScript, 107 linesfrontend.ts - src/
volume_rendering/ , TypeScript, 205 linesbackend.ts - src/
volume_rendering/ , TypeScript, 197 linesbase.ts - src/
volume_rendering/ , TypeScript, 26 linestrackable_volume_renderi ng_mode.ts - src/
volume_rendering/ , TypeScript, 74 linesvolume_render_layer.brow ser_test.ts - src/
volume_rendering/ , TypeScript, 1,392 linesvolume_render_layer.ts - src/
webgl/ , TypeScript, 112 linesbounding_box.ts - src/
webgl/ , TypeScript, 131 linesbuffer.ts - src/
webgl/ , TypeScript, 108 linescircles.ts - src/
webgl/ , TypeScript, 42 linescolormaps.ts - src/
webgl/ , TypeScript, 75 linescontext.ts - src/
webgl/ , TypeScript, 278 linesdynamic_shader.ts - src/
webgl/ , TypeScript, 195 linesellipse.ts - src/
webgl/ , TypeScript, 239 linesempirical_cdf.ts - src/
webgl/ , TypeScript, 57 linesindex_emulation.browser_ test.ts - src/
webgl/ , TypeScript, 139 linesindex_emulation.ts - src/
webgl/ , TypeScript, 355 lineslerp.browser_test.ts - src/
webgl/ , TypeScript, 392 lineslerp.ts - src/
webgl/ , TypeScript, 154 lineslines.ts - src/
webgl/ , TypeScript, 412 linesoffscreen.ts - src/
webgl/ , TypeScript, 51 linesquad.ts - src/
webgl/ , TypeScript, 41 linesrectangle_grid_buffer.sp ec.ts - src/
webgl/ , TypeScript, 80 linesrectangle_grid_buffer.ts - src/
webgl/ , TypeScript, 687 linesshader.ts - src/
webgl/ , TypeScript, 99 linesshader_control_reachabil ity.ts - src/
webgl/ , TypeScript, 206 linesshader_lib.browser_test. ts - src/
webgl/ , TypeScript, 642 linesshader_lib.ts - src/
webgl/ , TypeScript, 45 linesshader_source_string_pre processing.ts - src/
webgl/ , TypeScript, 118 linesshader_testing.browser_t est.ts - src/
webgl/ , TypeScript, 375 linesshader_testing.ts - src/
webgl/ , TypeScript, 1,548 linesshader_ui_controls.brows er_test.ts - src/
webgl/ , TypeScript, 1,975 linesshader_ui_controls.ts - src/
webgl/ , TypeScript, 140 linesspheres.ts - src/
webgl/ , TypeScript, 109 linessquare_corners_buffer.ts - src/
webgl/ , TypeScript, 36 linestesting.ts - src/
webgl/ , TypeScript, 151 linestexture.ts - src/
webgl/ , TypeScript, 101 linestexture_access.browser_t est.ts - src/
webgl/ , TypeScript, 614 linestexture_access.ts - src/
webgl/ , TypeScript, 95 linestrivial_shaders.ts - src/
webgl/ , TypeScript, 80 linesvertex_id.ts - src/
widget/ , TypeScript, 23 linesadd_button.ts - src/
widget/ , TypeScript, 150 linesannotation_tool_status.t s - src/
widget/ , TypeScript, 27 linesassociate_label.ts - src/
widget/ , TypeScript, 258 lineschannel_dimensions_widge t.ts - src/
widget/ , TypeScript, 59 linescheckbox_icon.ts - src/
widget/ , TypeScript, 23 linesclose_button.ts - src/
widget/ , TypeScript, 68 linescolor.ts - src/
widget/ , TypeScript, 1,208 linescoordinate_transform.ts - src/
widget/ , TypeScript, 28 linescopy_button.ts - src/
widget/ , TypeScript, 26 linesdelete_button.ts - src/
widget/ , TypeScript, 92 linesdependent_view_widget.ts - src/
widget/ , TypeScript, 865 linesdisplay_dimensions_widge t.ts - src/
widget/ , TypeScript, 70 linesenum_widget.ts - src/
widget/ , TypeScript, 27 lineseye_button.ts - src/
widget/ , TypeScript, 23 linesfilter_button.ts - src/
widget/ , TypeScript, 22 lineshelp_button.ts - src/
widget/ , TypeScript, 35 lineshidden_submit_button.ts - src/
widget/ , TypeScript, 70 linesicon.ts - src/
widget/ , TypeScript, 936 linesinvlerp.ts - src/
widget/ , TypeScript, 249 linesinvlerp_range_finder.ts - src/
widget/ , TypeScript, 246 lineslayer_control.ts - src/
widget/ , TypeScript, 106 lineslayer_control_channel_in vlerp.ts - src/
widget/ , TypeScript, 37 lineslayer_control_checkbox.t s - src/
widget/ , TypeScript, 53 lineslayer_control_color.ts - src/
widget/ , TypeScript, 49 lineslayer_control_enum.ts - src/
widget/ , TypeScript, 134 lineslayer_control_property_i nvlerp.ts - src/
widget/ , TypeScript, 53 lineslayer_control_range.ts - src/
widget/ , TypeScript, 79 lineslayer_control_select.spe c.ts - src/
widget/ , TypeScript, 97 lineslayer_control_select.ts - src/
widget/ , TypeScript, 62 lineslayer_reference.ts - src/
widget/ , TypeScript, 39 lineslayer_type_indicator.ts - src/
widget/ , TypeScript, 129 lineslinked_layer.ts - src/
widget/ , TypeScript, 23 linesmaximize_button.ts - src/
widget/ , TypeScript, 22 linesmove_to_button.ts - src/
widget/ , TypeScript, 893 linesmultiline_autocomplete.t s - src/
widget/ , TypeScript, 79 linesnumber_input_widget.ts - src/
widget/ , TypeScript, 410 linesposition_plot.ts - src/
widget/ , TypeScript, 1,719 linesposition_widget.ts - src/
widget/ , TypeScript, 47 linesprogress_listener.ts - src/
widget/ , TypeScript, 93 linesrange.ts - src/
widget/ , TypeScript, 438 linesrender_scale_widget.ts - src/
widget/ , TypeScript, 444 linesscale_bar.ts - src/
widget/ , TypeScript, 115 linessegmentation_color_mode. ts - src/
widget/ , TypeScript, 253 linesshader_code_widget.ts - src/
widget/ , TypeScript, 380 linesshader_controls.ts - src/
widget/ , TypeScript, 27 linesstar_button.ts - src/
widget/ , TypeScript, 433 linestab_view.ts - src/
widget/ , TypeScript, 29 linestext_icon_button.ts - src/
widget/ , TypeScript, 70 linestext_input.ts - src/
widget/ , TypeScript, 47 linestooltip.ts - src/
widget/ , TypeScript, 411 linestransfer_function.browse r_test.ts - src/
widget/ , TypeScript, 2,005 linestransfer_function.ts - src/
widget/ , TypeScript, 96 linesvec3_entry_widget.ts - src/
widget/ , TypeScript, 516 linesvirtual_list.ts - src/
worker_rpc.ts , TypeScript, 446 lines - src/
worker_rpc_context.ts , TypeScript, 21 lines - testdata/
codec/ , Python, 94 linescrackle/ generate_crackle_example s.py - testdata/
codec/ , Python, 69 linesnpy/ generate_npy_examples.py - testdata/
datasource/ , Python, 69 linesn5/ generate_n5.py - testdata/
datasource/ , Python, 46 linesprecomputed/ generate_precomputed.py - testdata/
datasource/ , Python, 85 lineszarr/ ome_zarr/ generate_ome_zarr.py - testdata/
datasource/ , Python, 199 lineszarr/ zarr_v2/ from_zarr-python/ generate-v2.py - testdata/
datasource/ , Python, 31 lineszarr/ zarr_v3/ examples/ generate_zarr_v3.py - testdata/
datasource/ , Python, 553 lineszarr/ zarr_v3/ from_zarrita/ generate-v3.py - testdata/
kvstore/ , Python, 47 linesicechunk/ dump_icechunk.py - testdata/
kvstore/ , Python, 132 linesicechunk/ generate_icechunk.py - testdata/
kvstore/ , Python, 77 linesocdbt/ generate_ocdbt.py - testdata/
kvstore/ , Python, 22 lineszip/ generate_zip.py - testdata/
kvstore/ , Python, 94 lineszip/ generate_zip64.py - tests/
codec/ , TypeScript, 196 linescrackle.spec.ts - tests/
datasource/ , TypeScript, 138 linescompletion.spec.ts - tests/
datasource/ , TypeScript, 58 linesdeepzoom.browser_test.ts - tests/
datasource/ , TypeScript, 41 linesmetadata_snapshot_test_u til.ts - tests/
datasource/ , TypeScript, 24 linesn5.browser_test.ts - tests/
datasource/ , TypeScript, 26 linesnifti.browser_test.ts - tests/
datasource/ , TypeScript, 21 linesprecomputed.browser_test .ts - tests/
datasource/ , TypeScript, 33 linessuggest_name.spec.ts - tests/
datasource/ , TypeScript, 184 linestest_util.ts - tests/
datasource/ , TypeScript, 36 lineszarr.browser_test.ts - tests/
example_project_test/ , TypeScript, 31 linesbuild_client.ts - tests/
example_project_test/ , TypeScript, 29 linesbuild_package.ts - tests/
example_project_test/ , TypeScript, 37 linescapture_build_screenshot .ts - tests/
example_project_test/ , TypeScript, 83 linescapture_dev_server_scree nshot.ts - tests/
example_project_test/ , TypeScript, 60 linescapture_screenshot.ts - tests/
example_project_test/ , TypeScript, 27 linesclient_test_options.ts - tests/
example_project_test/ , TypeScript, 32 linescompare_screenshots.ts - tests/
example_project_test/ , TypeScript, 141 linesconfig.ts - tests/
example_project_test/ , TypeScript, 31 linesinstall_node_modules.ts - tests/
example_project_test/ , TypeScript, 22 linesreset_screenshot_server. ts - tests/
example_project_test/ , TypeScript, 85 linesscreenshot_comparison_se rver.ts - tests/
fixtures/ , TypeScript, 31 linesclear_cookies.ts - tests/
fixtures/ , TypeScript, 35 linesdatasource_provider.ts - tests/
fixtures/ , TypeScript, 120 linesfake_gcs_server.ts - tests/
fixtures/ , TypeScript, 152 linesfake_s3_server.ts - tests/
fixtures/ , TypeScript, 54 linesfixture.ts - tests/
fixtures/ , TypeScript, 26 linesgl_browser.ts - tests/
fixtures/ , TypeScript, 27 linesgl_node.ts - tests/
fixtures/ , TypeScript, 50 lineshttp_server.ts - tests/
fixtures/ , TypeScript, 21 linesmsw_browser.ts - tests/
fixtures/ , TypeScript, 18 linesmsw_node.ts - tests/
fixtures/ , TypeScript, 50 linesshared_kvstore_context.t s - tests/
fixtures/ , TypeScript, 89 linesstatus_message_observer. ts - tests/
fixtures/ , TypeScript, 34 linestemp_directory.ts - tests/
kvstore/ , TypeScript, 47 linesgcs.spec.ts - tests/
kvstore/ , TypeScript, 36 linesgzip.spec.ts - tests/
kvstore/ , TypeScript, 47 lineshttp.spec.ts - tests/
kvstore/ , TypeScript, 292 linesicechunk.spec.ts - tests/
kvstore/ , TypeScript, 142 linesngauth.browser_test.ts - tests/
kvstore/ , TypeScript, 1,772 linesocdbt.spec.ts - tests/
kvstore/ , TypeScript, 67 liness3.browser_test.ts - tests/
kvstore/ , TypeScript, 110 liness3.spec.ts - tests/
kvstore/ , TypeScript, 56 linestest_data.ts - tests/
kvstore/ , TypeScript, 227 linestest_util.ts - tests/
kvstore/ , TypeScript, 205 linesurl.spec.ts - tests/
kvstore/ , TypeScript, 182 lineszip.spec.ts - tests/
util/ , TypeScript, 27 linesclear_cookies.ts - tests/
util/ , TypeScript, 128 linesmsw_request_log.ts - typings/
index.d.ts , TypeScript, 2 lines - typings/
nifti-reader-js.d.ts , TypeScript, 341 lines - typings/
raw.d.ts , TypeScript, 4 lines - vitest.workspace.ts, TypeScript, 130 lines
- LICENSE, License, 202 lines
- README.md, Text, 177 lines
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;
- 1,292 scripts, each with its path and the digest of its content;
- 8 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data availability statement
The original contributions presented in this study are included in the article/
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, pages, dates, 8 authors, 6 keywords, 1 funder, 193 references.
Cite
This paper
Wang, W., Yang, Y., Liu, Q., Gao, Y., Lv, Q., Zhang, K., Ning, J., & Sun, Y. (2026). Convergence-divergence circuits for multimodal integration of innate and learned opponent valences. Frontiers in systems neuroscience, 20, 1822122. https://
BibTeX
@article{wang2026converg
author = {Wang, Wenjing and Yang, Yaokai and Liu, Qiong and Gao, Yunming and Lv, Qiantao and Zhang, Kaiqi and Ning, Jing and Sun, Yi},
title = {{Convergence-divergence
journal = {Frontiers in systems neuroscience},
year = {2026},
month = may,
volume = {20},
pages = {1822122},
publisher = {Frontiers Media SA},
issn = {1662-5137},
doi = {10.3389/
url = {https://
pmid = {42181586},
pmcid = {PMC13190573}
}
RIS
TY - JOUR
AU - Wang, Wenjing
AU - Yang, Yaokai
AU - Liu, Qiong
AU - Gao, Yunming
AU - Lv, Qiantao
AU - Zhang, Kaiqi
AU - Ning, Jing
AU - Sun, Yi
TI - Convergence-divergence circuits for multimodal integration of innate and learned opponent valences
T2 - Frontiers in systems neuroscience
J2 - Front Syst Neurosci
PY - 2026
DA - 2026/
VL - 20
SP - 1822122
SN - 1662-5137
PB - Frontiers Media SA
DO - 10.3389/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.3389/
"type": "article-journal",
"title": "Convergence-divergence circuits for multimodal integration of innate and learned opponent valences",
"container-title": "Frontiers in systems neuroscience",
"author": [
{
"family": "Wang",
"given": "Wenjing"
},
{
"family": "Yang",
"given": "Yaokai"
},
{
"family": "Liu",
"given": "Qiong"
},
{
"family": "Gao",
"given": "Yunming"
},
{
"family": "Lv",
"given": "Qiantao"
},
{
"family": "Zhang",
"given": "Kaiqi"
},
{
"family": "Ning",
"given": "Jing"
},
{
"family": "Sun",
"given": "Yi"
}
],
"container-title-short":
"volume": "20",
"page": "1822122",
"DOI": "10.3389/
"PMID": "42181586",
"PMCID": "PMC13190573",
"ISSN": "1662-5137",
"publisher": "Frontiers Media SA",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
7
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1038/s41586-026-10735-w [code]
- Distributed control circuits across a brain-and-cord connectome.Journal: NatureIn common: UMAP, igraph, NetworkX, 9 other tools, 39 references
- [2] doi:10.1371/journal.pbio.3003959 [code]
- Recurrent synapses between CO2-sensitive olfactory sensory neurons enable robust CO2 detection in Aedes aegypti mosquitoes.Journal: PLoS biologyIn common: seaborn, scikit-learn, pandas, 3 other tools, 23 references
- [3] doi:10.1038/s41467-026-72057-9 [code]
- Sex-specific behavioral feedback modulates sensorimotor processing and drives flexible social behavior.Journal: Nature communicationsIn common: Keras, UMAP, Numba, 11 other tools, systems, 13 references
- [4] doi:10.7554/elife.107589 [code]
- Distinct evolutionary trajectories of two integration centres, the central complex and mushroom bodies, across Heliconiini butterflies.Journal: eLifeIn common: Plotly, 15 references
- [5] doi:10.1016/j.xcrm.2026.102766 [code]
- A longitudinal single-cell and spatial multiomic atlas of pediatric high-grade glioma.Journal: Cell reports. MedicineIn common: tifffile, Keras, UMAP, 14 other tools, 2 references
- [6] doi:10.1038/s41467-026-72152-x [code]
- Centralized brain networks controlling antennal grooming coordination.Journal: Nature communicationsIn common: TensorFlow, NetworkX, h5py, 6 other tools, systems, 10 references
- [7] doi:10.1126/sciadv.aeh7220 [code]
- Central complex representations of self-movement are sufficient to compute wind direction in flight.Journal: Science advancesIn common: Keras, TensorFlow, seaborn, 5 other tools, 9 references
- [8] doi:10.7554/elife.96084 [code]
- Organization of circuits linking descending input to motor output in the &
lt;i& gt;Drosophila& lt;/ i& gt; Male Adult Nerve Cord connectome. Journal: eLifeIn common: igraph, systems, 13 references - [9] doi:10.1038/s42003-026-10957-8 [code]
- Brain defence by the extracellular matrix protein Cochlin.Journal: Communications biologyIn common: Keras, UMAP, igraph, 13 other tools
- [10] doi:10.7554/elife.100880 [code]
- An applicable and efficient retrograde monosynaptic circuit mapping tool for larval zebrafish.Journal: eLifeIn common: NEURON, tifffile, igraph, 12 other tools, systems
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, 1292 scripts, and 8 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:afada80b850e1c76…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
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.
