Changelog#
This is a selection of features added, changes made and bugs fixed with each version. For a full list of changes please see the commits history on NAVis' Github repository.
dev#
Date: ongoing
To install the current dev version of NAVis:
pip uninstall navis -y
pip install git+https://github.com/navis-org/navis@master
Breaking#
-
NBLAST scores shift very slightly with navis-fastcore
>= 0.8.0. fastcore now picks its internal coordinate precision from the dtype of the input rather than always widening to float64. NAVisDotpropsstorepoints/vectas float32, so NBLAST now runs on float32 coordinates - cutting peak memory on a large all-by-all by ~45%, at a cost of ~1e-5 on the scores. Nothing in NAVis changed; upgrading fastcore is enough to see it.The scoring maths itself is untouched (it still accumulates in float64) and this does not change which neurons match: on the example neurons the k-nearest-neighbour identities are unchanged. But it is enough to break a bit-for-bit comparison against previously saved scores. Cast
.pointsand.vecttofloat64before NBLASTing if you need the old numbers exactly. - bridging graph: edge weights now mean one thing, and lower always wins.weightwas doing two jobs at once - it set the costnetworkxminimises when choosing a route, and it was also used to pick between several registrations connecting the same two templates (the old code took the highest-weight edge there). The two uses want opposite things, so no weighting could satisfy both: to stop an inverse transform pulling unrelated routes through it you had to weight it up, but to stop it being picked over a purpose-built registration you had to weight it down.Now
weightonly ever means "what this hop costs", and lower weight = more likely to be used everywhere - both when routing and when picking between parallel registrations. Which transform serves a hop is decided separately, by the newprefer_forwardargument (see below).This changes ~29% of the bridging paths in
navis-flybrains(no routes gained or lost). Most of that is NAVis no longer inverting a registration when a purpose-built one for that direction was sitting right next to it - e.g.BANC→Cell07used to invertCell07_IS2.listand now simply usesIS2_Cell07.list, at the same path length. 360 fewer routes traverse any transform backwards. - transforms now declare how expensive they are to invert, viaBaseTransform.inverse_weight_factor. It is1wherever the inverse is stored or exact (AffineTransform,H5transform,TPStransform),2forCMTKtransformand5forElastixTransform- both of which have to solve for the inverse numerically.register_transform'sweight_invnow defaults toweight * inverse_weight_factor; passing it explicitly still overrides that. -reciprocalis deprecated in favour ofinverse_weight(bridging_graph,find_bridging_path,find_all_bridging_paths) - one name for one knob. Its default also changed from0.5to1: NAVis no longer discounts inverse transforms across the board, since each transform now says for itself what inverting it costs. Passingreciprocalstill works but warns. -VoxelNeuronsnow avoid the dense grid wherever possible, which requires sparse-cubes>= 0.5.0- now pulled in assparse-cubes[skeleton], so that its dijkstra3d-sparse accelerator comes along too (skeletonization falls back toscipywithout it, but TEASAR is ~11x slower at 100k voxels and the gap widens with size). Materialising a grid larger thannavis.config.max_grid_size(4 GiB) now raises aMemoryErrorinstead of being silently OOM-killed - a neuron's grid is sized by its bounding box, so a handful of far-apart voxels can imply terabytes. Raise or disable the limit if you hit it on data you know fits. -navis.smooth_voxelstreats everything outside the neuron as empty (scipy'smode="constant"). It previously used scipy's default, which reflects at the canvas boundary and invents signal outside the imaged volume; results change for neurons touching that edge. -navis.find_somanow returns a single node ID (orNone) instead of an array of candidates. It used to hand back every node passing the radius/label filter and leave the choice to the caller, which meant a thick primary neurite could be returned alongside - or instead of - the actual soma. Candidates are now scored by the mean radius of the candidates around them (withindist_factortimes their own radius, new argument) so that the fattest region wins rather than the fattest single node, and the fattest node of that region is returned; the label-only path takes the most central node of the largest connected label component. Nodes whose radius is missing (NaNor<= 0, asguess_radiuswrites) are no longer treated as candidates, and a radius criterion that matches nothing usable no longer suppresses the label criterion. Code doingfind_soma(n)[0]orlen(find_soma(n))needs updating. - dependencies:sparse-cubes[skeleton]is now a core requirement (it backs theVoxelNeuronwork above), and the minimumnavis-fastcoremoved from0.6.1to0.7.1- still optional, but note that several of the additions below want>= 0.8.0.
Additions#
- new
navis.find_soma_mesh: soma detection forMeshNeurons, straight off the mesh. No skeletonization involved: it finds the thickest part of the neuron (the point of largest inscribed sphere) and fits an oriented ellipsoid to the surrounding surface, returning the newnavis.SomaEllipsoid-center,radii, principalaxes,inscribed_radius, plusvolume,equiv_radius,contains()anddistance_to_surface(). Withinplace=Trueit simply sets the neuron's.soma_pos. The approach is inspired by skeliner.min_soma_radius(accepts e.g."1 micron"if the neuron has units) is the main accept/reject knob and should be tuned to your data. - new functions for analyzing the angles in a skeleton (see the new section in the morphometrics tutorial):
navis.branch_angles(between child branches at each branch point - all pairwise angles at higher-order branch points),navis.path_angles(in- vs outgoing edge at each continuation node, i.e. how much the path bends),navis.root_angles(how far each edge deviates from pointing radially away from the root) andnavis.soma_exit_angles(between the neurites emanating from the soma). All return a tidy per-node DataFrame, work onMeshNeuronsvia their skeleton, and map overNeuronLists. - new
navis.cast_neuron: convert a neuron's data to a given dtype. What gets cast depends on the neuron type - nodex/y/z/radiusfor skeletons, vertices for meshes, points (and, for float dtypes, tangent vectors and alpha) forDotprops, voxel values forVoxelNeurons- plus connectors for all of them. Anything that indexes into those (mesh faces, voxel coordinates, node/parent IDs) is left alone. Handy for e.g. the float32/float64 NBLAST question above. - new
navis.transforms.SimilarityTransform: a rotation, a translation and a single uniform scale factor fitted to matched landmarks - the least-squares optimal solution in closed form via SVD (Umeyama, 1991), with optional per-landmarkweights. Setscale=Falsefor a pure rigid transform. Unlike aTPStransformit has only 7 degrees of freedom and so will generally not map the landmarks onto each other exactly - which is the point when you want the landmarks to constrain a global transform rather than warp space to fit them. -
navis.make_dotpropsis ~12x faster when navis-fastcore>= 0.8.0is installed: the tangent vectors and alpha values (96% of its runtime) now come from one parallel Rust pass instead of ascipy.spatial.cKDTreequery plus N 3x3 SVDs. Same fornavis.Dotprops.recalculate_tangents. The scipy route remains as a fallback.The two agree exactly except where the k-nearest-neighbour search hits a tied distance, which grid-quantised coordinates produce readily - there the k-th neighbour is genuinely ambiguous and the two trees may pick differently. That affects ~0.3% of points on the example neurons. -
navis.nbl.extract_matchesis much faster and gained amax_matchesguard. All three criteria now go through navis-fastcore where available:Nis 6-118x faster (the gap widens with matrix size - 2.8 s to 23 ms on a 20k x 20k matrix),threshold1.5-8x,percentage1.3-1.9x. The numpy fallback is unchanged in output but no longer quadratic in thepercentagepath, which makes it 2-6x faster on its own.max_matchesrefuses to return more than a given number of matches forthreshold/percentage, whose output size is not knowable in advance - an over-broad cutoff on a large matrix could previously take the machine down. The count is established before anything is allocated. - newnavis.graph.geodesic_clusters(): greedily partitions a skeleton or mesh into connected clusters of bounded geodesic radius. Please read its warning before using it for downsampling - the clusters are guaranteed connected and bounded, but they are not evenly sized and their centroids are not evenly spaced. Uses navis-fastcore if available, else scipy. - newnavis.nblast_knn: theknearest neighbours of every neuron, without ever building the score matrix. An all-by-all is the wrong shape for a k-NN question at scale - 164k neurons is 2.7e10 pairs and a 107 GB matrix, when what is wanted from it is a 26 MB k-NN graph (typically to feed a UMAP embedding). This computes that graph directly: each neuron is reduced to a coarse voxel-occupancy signature, then_candidatesmost similar neurons per row are shortlisted from those signatures, and the exact NBLAST score is then computed for the shortlisted pairs only. Only which neurons get shortlisted is approximate - every returned score is a real NBLAST score. Measured on 163,976 neurons, recall@20 is 0.990 at the defaultn_candidates, having scored 0.16% of pairs.Returns a tidy
query/target/score/rankframe by default;format="wide"gives thenavis.nbl.extract_matcheslayout andformat="arrays"the raw index/score arrays UMAP'sprecomputed_knnwants.Note this requires navis-fastcore - unlike the other NBLAST functions there is no built-in Python implementation to fall back on, and it raises a pointed error if fastcore is missing or too old. - the landmark transforms now have a fastcore backend too.
TPStransformand [MovingLeastSquaresTransform][navis.transforms.MovingLeastSquaresTransform] use navis-fastcore's Rust implementation when it is available, falling back tomorphops/molesqotherwise (the two agree to ~1e-13). Neither materialises the(n_points, n_landmarks)intermediate those libraries build, sobatch_sizestops mattering and peak memory no longer scales with the landmark count - which is what madeMovingLeastSquaresTransformimpractical at the landmark counts real registrations use (3400 landmarks needed ~23 GB at the default batch size). Transforming points is ~10-15x faster.TPStransformstill fits its spline withmorphopseven on the fastcore backend, because numpy's LAPACK-backed solve is faster there than fastcore's; only the point transform switches. That keeps the fastcore backend from ever being slower end-to-end (fastcore's own fit is cubic and would regress small one-shot transforms).Steered by the same
navis.config.default_transform_backendas CMTK/elastix, or per transform viabackend=. The non-fastcore option is spelled"python"here and"binary"there; both names are accepted for either. - CMTK and elastix point transforms can now run without the external binaries. If navis-fastcore is installed,CMTKtransformandElastixTransformuse its in-process Rust implementation instead of shelling out tostreamxform/transformix: no CMTK, no elastix, no subprocess and no temporary files. Results match the binaries to ~1e-6 (including which points fail), andxform_brainis 4-30x faster end-to-end. Image transforms (xform_image,to_dfield) still require CMTK.Control this with
navis.config.default_transform_backend("auto"by default - use fastcore if available, else the binaries) or per transform viabackend=. - elastix transforms are now invertible when navis-fastcore is installed - somethingtransformixcannot do at all. Note the bridging graph does not use this by default: setnavis.config.elastix_invertible = Trueto let it (see the notes onElastixTransformfor why it is off). -find_bridging_path,find_all_bridging_pathsandshortest_bridging_seqgained aprefer_forwardargument (defaultTrue): where two templates are connected by both a purpose-built registration and the inverse of its counterpart, use the purpose-built one - regardless of weight. Set it toFalseto have your graph's weights taken entirely at face value. -MovingLeastSquaresTransformgained a.matrix_affineproperty, analogous toTPStransform.matrix_affine: since moving least squares is a locally weighted affine transform, this returns the global (least-squares) affine that it converges to far away from the landmarks -VoxelNeuronsgained a proper toolkit, all of it working straight off the sparse voxels: - morphology and set algebra:dilate,erode,opening,closing,thin,fill_cavities,union,intersection,difference,symmetric_difference. Per-voxel values are carried through; set operations align neurons onto a common lattice and refuse to combine ones that do not line up. - measurements:surface_area,centroid,distance_transform,connected_components,iou,dice,grid_nbytes/voxels_nbytes. - shorthands.mesh()and.skeletonize(). -navis.skeletonizenow acceptsVoxelNeurons(via the newnavis.conversion.voxels2skeleton), closing a gap its own docstring used to flag. Defaults tomethod="wavefront"- ~4x faster than"teasar"and radii come free from the ring contraction rather than being snapped to the voxel lattice;"teasar"and"thin"remain available. - existing functions stopped densifying.navis.drop_fluffandgraph_utils._connected_componentsnow handleVoxelNeurons;navis.smooth_voxels,navis.thin_voxelsandnavis.downsample_neuronno longer allocate the grid (the latter could trip the new memory cap on exactly the sparse neurons worth downsampling). Voxel adjacency - behindneuron2nx/neuron2igraph- is ~100x faster and no longer needs the undeclared scikit-learn dependency.smooth_voxels/thin_voxelskeep abackendargument if you want the old scipy/scikit-image route. - newnavis.mlmodule: helpers for preparing neurons as machine-learning inputs. These live under their ownnavis.ml.*namespace (deliberately not lifted to the top level) and come with three tutorials. Three steps: - normalize -navis.ml.normalize_neuronmaps a neuron into a canonical frame with a single rigid-plus-uniform-scale transform (p' = s · R · (p - c)): center on the centroid/bbox/soma/an explicit point, PCA-orient (signs disambiguated deterministically and handedness preserved - neurons are never mirrored), and scale to unit RMS / extent / enclosing sphere. It goes throughnavis.xform, so connectors,Dotpropstangent vectors, radii and.unitsare all carried along consistently;return_matrix=Truereturns the 4x4 matrix so predictions made in the normalized frame can be mapped back to the original coordinates. - augment - a suite of geometry/sampling augmentations, each taking arandom_stateand returning a copy:navis.ml.jitter_neuron(per-point Gaussian noise),navis.ml.warp_neuron(smooth elastic deformation),navis.ml.rotate_neuronandnavis.ml.scale_neuron(about the centroid; scale is isotropic or anisotropic),navis.ml.translate_neuronandnavis.ml.drop_nodes(a sparser reconstruction - keeps the arbor connected and reattaches connectors to surviving nodes).navis.ml.augment_neuronchains them in one seeded, reproducible call. - sample & chunk - turn a variable-sized neuron into a fixed-size model input: newnavis.ml.sample_cable(arclength-uniform, stratified point sampling along a skeleton that interpolatesradius/other columns and records provenance) andnavis.ml.sample_surface(area-weighted mesh-surface sampling, again with per-vertex provenance), plusnavis.ml.chunk_neuron(tile a neuron into evenly-sized fragments - geodesic-connected or Euclidean - for batching). The existingsample_points_uniform(uniform subsampling of a point cloud) is also surfaced undernavis.ml. -neuprintinterface: newdedupoption for fetching synapses. In insect connectomes synapses are polyadic - a single presynapse connects to multiple postsynapses - andneuprint-pythonde-duplicates presynapses so each is reported only once.navis.interfaces.neuprint.fetch_synapses(a new thin wrapper overneuprint.fetch_synapses),fetch_skeletonsandfetch_mesh_neuronnow takededup(defaultTrue, i.e. unchanged behaviour). Withdedup=Falseeach presynapse is instead reported once per postsynaptic site it connects to, so presynapse counts reflect the number of downstream connections.
Improvements#
- a mesh's unique edges now come from navis-fastcore where available (new
navis.utils.mesh_unique_edges) instead oftrimesh.edges_unique, which sorts an(n_faces * 3, 2)array to find them. This sits underneathneuron2nx/neuron2igraphforMeshNeuronsand hence everything built on a mesh graph - geodesic distances, connected components,drop_fluff,fix_mesh. The results are seeded into trimesh's own cache (index and inverse included, sofaces_unique_edges& co. stay consistent), meaning a mesh that has already computed its edges pays nothing.
Fixes#
- a batch of
VoxelNeuronbugs, most of them on the sparse (voxels + values) backing, which until now was barely exercised - values and coordinates were free to drift apart.threshold()filtered the coordinates but not the values, leaving the two different lengths;normalize()scaled the coordinates instead of the values, corrupting the geometry outright; the documented(N, 4)constructor input silently discarded its value column; and changing.valuesdid not invalidate a cached.grid. Also fixed:convert_units()resized the neuron instead of re-labelling it (125x too small for 8 nm → µm),.volumesquared the z voxel size and dropped y,.densitycrashed on numpy 2,copy.deepcopy()raised aTypeError,flip()moved the neuron and mirrored connectors in the wrong space, and.bboxdisagreed between the two backings by one voxel. VoxelNeuronswith no filled voxels raisedValueError: zero-size array to reductionon.shape- and hence on.grid,.bbox,repr()andsummary(). Empty neurons are not exotic: an all-zero grid auto-sparsifies to nothing, anderode()/thin()/difference()can consume a thin neuron entirely..shapenow falls back to the canvas the neuron was left on (or(0, 0, 0)if it never had one), andstrip()/normalize()no-op instead of raising.- assigning
.voxelsa different number of voxels left the old.valuesin place, so.nnz/.volumekept counting voxels that no longer existed and.gridraised a broadcasting error. Mismatched values are now dropped (with a warning); values that still line up row for row are kept. Latent in1.12.0but easy to hit now that grids auto-sparsify, i.e. now that a grid-constructed neuron carries values at all. navis.meshraisedAttributeErroron the(N, 3)voxel arrays it documents (it tested.ndims, which numpy spells.ndim).navis.make_dotpropssilently produced wrong tangent vectors for point clouds containing duplicate coordinates. Points whoseknearest neighbours are all at distance zero are dropped (they have no defined tangent), but the neighbour indices were then offset by a flatn_dropped- which is only correct if every duplicate happens to sit at the start of the array. Anywhere else the indices ran past the end or went negative, and because numpy reads negative indices from the back this raised nothing: it just computed each tangent from an unrelated neighbourhood. On a 40-point cloud with a 4-point duplicate block in the middle, 39 of the 40 surviving points came back with the wrong tangent (worst case nearly perpendicular to the correct one) and alpha off by up to 0.55. The neighbour indices are no longer remapped at all.navis.nbl.extract_matchesrankedNaNas the best possible score. numpy sortsNaNto the end, so for a query that had been scored against some targets but not others - which is whatnavis.nbl.update_scoresand any hand-assembled matrix produce - the unscored pair was returned as that query's top match, with aNaNscore.NaNs are now skipped; a query with fewer thanNvalid scores gets emptymatch_k/score_kfor the remainder. Thepercentagecriterion was worse off still: oneNaNanywhere in a row made that row's thresholdNaN, so the query got no matches at all.extract_matches(..., percentage=...)listed matches worst first for distance matrices - the exact inverse of what it does for similarities, and of what theNcriterion does for either. Matches are now always best first.navis.Dotprops.recalculate_tangentsreturnedNaNalpha values for points sitting on duplicate coordinates - it has no equivalent ofmake_dotprops' duplicate check and cannot drop points (it must keep a 1:1 correspondence with.points). ThoseNaNs then propagated into every NBLAST score the neuron took part in. Such points now getalpha=0and an arbitrary unit vector, matching navis-fastcore.-
navis.sholl_analysiswas broken for most of itscenteroptions - including the default. The"centermass"branch reboundcenterfrom a preset name to an x/y/z array before the remaining branches compared it against"soma"/"root", and on numpy >= 1.25array == "soma"is an elementwise comparison, so the nextifraisedValueError: truth value of an array is ambiguous.sholl_analysis(n)with default arguments therefore did not run at all, and neither did an explicitcenter=[x, y, z]coordinate. Separately, a node ID given as a numpy integer (e.g.center=n.root[0]) failed theisinstance(center, int)check, skipped the node → coordinate lookup and was broadcast as a scalar into the distance computation - returning wrong numbers without raising.centeris now resolved by type before any string comparison. Also fixed in passing:geodesic=True, center="soma"raisedIndexError,radiidid not accept numpy integers, and an unrecognisedcenternow raises aValueErrorinstead of an obscureAttributeError.Note that
geodesic=Truenow requires a center that lies on the arbor ("root","soma"or a node ID) and raises aValueErrorfor the default"centermass", which is a coordinate. -TransformSequencewas registered as invertible even if it contained a transform that was not -neuprintinterface:fetch_skeletonsshared one client - and hence onerequests.Session- across all its worker threads, whichrequestsdoes not support.neuprint-pythonnormally hands each thread its own deepcopy of the client, but passing an explicit client into a thread bypasses that; NAVis now does the copying itself in the pool's initializer. The copies get a fresh connection pool and do not re-runClient.__init__, so this costs no extra requests. -navis.interfaces.brain_image_library: a failing root directory listing now raises instead of quietly returning an empty file table, and partial listing failures further down warn that the result is incomplete rather than passing it off as the whole dataset. -navis.conversion.mesh2skeletonignored theprogresskeyword argument it accepts
Version 1.12.0#
Date: 13/06/26
Breaking#
mirror_brainnow defaults tomirror_axis="auto", i.e. takes the mirror axis from the template brain's meta data (falling back tox). This can change results for templates whose mirror axis is notxTPStransform.matrix_rigid(added in 1.11.0) was renamed to.matrix_affine- NAVis' internal graph algorithms no longer fall back to
networkx- consequentlynavis.config.use_igraphis gone.TreeNeuron.graph,neuron2nx& co. are unaffected requests-futuresis no longer a dependency: it was only used for the parallel URL reader, which now uses a plainThreadPoolExecutor- note that a number of bug fixes below change outputs: see the entries for flow centrality on fragmented neurons,
resample_skeleton,plot1d,classify_nodesandsmall_segments
Additions#
- new interface:
navis.interfaces.brain_image_libraryprovides access to the Brain Image Library which hosts thousands of single neuron reconstructions (see new tutorial) - new function:
propagate_labelspropagates sparse labels across a neuron (see new tutorial) - new function:
split_axon_dendrite_propuses label propagation to split a neuron into axon and dendrite (see new tutorial) - new function:
sample_skeletondraws a given number of points at equal geodesic spacing along a skeleton - new function:
collapse_nodescollapses a group of nodes into a single node - NBLAST gained pluggable backends:
nblast,nblast_smart,nblast_allbyallandsynblasthave a newbackendparameter accepting"builtin"(the default),"fastcore"(requiresnavis-fastcore) or"auto". The default can be changed globally vianavis.config.default_nblast_backendand third parties can register their own backend withnavis.nbl.backends.register_backend geodesic_matrixhas a newto_parameter which restricts the columns of the matrix, mirroring the existingfrom_. Previously, the only way to get afrom_xto_block was to compute every column and subset afterwards (for the leaf-by-leaf matrix of a 45k node skeleton: 794ms/2.2GB -> 126ms/307MB)dist_betweennow accepts matched arrays of nodes and returns their pairwise distances instead of raising"Can only process single nodes". Withnavis-fastcorethis is ~750x faster than the loop it replaces (1000 pairs on a 45k node skeleton: 4.7s -> 6ms); a single pair still returns a single floatstitch_skeletonsnow exposesmin_sizeanduse_radius, which the underlying stitcher already supported but which the signature droppedNeuronListnow supports in-place scaling (nl *= 1000,nl /= 1000) which - unlikenl * 1000- does not copy every neuronface_dist_sortinggained aheal_methodparameter
Improvements#
- NAVis now requires
navis-fastcore>= 0.6.1 (still an optional dependency) classify_nodesis 6-20x faster and uses up to 40x less memory (10.3ms/6.2MB -> 0.5ms/0.1MB for a 71k node skeleton) which matters because it runs on every neuron mutation: it now usesnavis-fastcoreif available and builds thetypecolumn from integer categorical codes instead of an array of strings (the latter also speeds up the non-fastcore path by ~5x)- the subtree height (the geodesic distance from a node down to the farthest leaf below it) is now computed with
navis-fastcoreif available: 14-31x faster and ~10x less memory. This backsprune_twigswithexact=True(2.2x faster, 4x less memory) andnode_label_sorting node_label_sortingno longer builds a directed geodesic matrix (4.6 GB for a 71k node skeleton - the single largest allocation in NAVis): 4.6x faster and 31x less memory. The resulting order is unchanged. This also speeds upplot1dandskeleton_adjacency_matrixwithsort=Trueivscc_featuresno longer builds a leafs-by-all-nodes distance matrix (8.5 GB for a 71k node skeleton!) to compute a single number:max_path_lengthis now 185x faster and uses 350x less memorygeodesic_matrixnow usesnavis-fastcoreforMeshNeuronstoo: ~19-68x faster and ~30-60x less memorylongest_neuritewithfrom_root=Falseno longer builds a leafs-by-leafs distance matrix just to take its maximum: 29x faster and 125x less memory (722ms/785MB -> 25ms/6.3MB for a 71k node skeleton)distal_tonow usesnavis-fastcoreif available: 13x faster and 5x less memory (it previously asked igraph for a source-by-target block, which igraph answers by running an all-sources search)arbor_segregation_index,bending_flow,synapse_flow_centrality,flow_centrality,longest_neuriteandnode_label_sortingnow request only the geodesic distances they actually use (seeto_above)- major speed-up for
heal_skeletonandstitch_skeletons: they now usenavis-fastcoreif available (2.5-340x faster on real, fragmented skeletons, e.g. 85s -> 0.25s for a 640k node skeleton), and the built-in fallback was rewritten around a vectorized Borůvka algorithm (5-15x faster and ~7x less memory, e.g. 8s/640MB -> 0.5s/90MB for a 220k node skeleton with 5k fragments). Results are unchanged: both produce the same minimum spanning tree - major speed-up for
resample_skeleton: ~15-20x faster with the defaultmethod="linear"(e.g. 100ms -> 7ms for the example neuron; 425ms -> 64ms when densifying it to 132k nodes, asxform_braindoes) by interpolating all segments and columns in one go instead of fitting onescipy.interpolate.interp1dper column per segment. Non-linear methods (e.g."cubic") can't share that trick but still gain ~4x. It also no longer builds a KDTree and an indexed copy of the node table when the neuron has no soma, connectors or tags to re-map reroot_skeletonbuilds a node ID -> vertex index map once instead of scanning all vertices for each root: much faster on heavily fragmented neuronssplit_axon_dendriteno longer runs out of memory on very large (100k+ nodes) neurons - the assignment of orphan nodes used to build a full orphans-by-all-nodes geodesic matrix - and is faster (igraph instead ofnetworkx)drop_fluff,fix_meshand everything else built on connected components are faster:navis-fastcoreis now used forMeshNeuronstoo, igraph otherwiseskeletonizewithshave=True: fixing up the vertex map was an O(n_bristles x n_vertices) Python loop and is now a single vectorized map - a major bottleneck on large meshesrewire_skeletonnow skips the minimum spanning tree if the graph is already a forest (i.e. has no cycles)H5transformandGridTransformusescipy.ndimage.map_coordinates(~2x faster), and copies of anH5transformnow carry over the cache - previouslyxform_braincopied the transform and hence never benefitted from cachingskeletonizefor point clouds/Dotpropsusesscipy's minimum spanning tree instead ofnetworkxand now correctly handles duplicate pointsbetweeness_centrality,plot_flatandsegment_analysisare faster- reading from URLs with the default
parallel="auto"now goes parallel from 5 files onwards instead of 200. The 200 was tuned for the process pool used to read local files; URLs are read in a thread pool and are network- rather than CPU-bound. Reading e.g. 100 neurons off a remote server no longer means 100 sequential blocking requests - URL reads now share a single
requests.Session, so connections to the same host are pooled and kept alive read_*functions can now read from Google buckets (gs://...) withoutgcsfsinstalled
Fixes#
- neurons read from a list of URLs in parallel came back stripped of their identity: the parallel reader handed the downloaded bytes (instead of the URL) to the parser, so the filename was never parsed. Affected neurons had no
file, anoriginof"string", anameof"SWC"/"MESH"/... and a randomid, and anyfmtwas silently ignored - i.e. the same input produced different neurons depending onparallel.read_meshfailed outright (ReadError) since it needs the filename to determine the file type read_swc& co. no longer choke on URLs with a query string (e.g..../neuron.swc?token=123, whose file extension was previously parsed asswc?token=123) and now decode percent-encoded filenames (%20-> a space)flow_centrality,synapse_flow_centralityandarbor_segregation_indexreturned wrong values for fragmented neurons: all three work out how many leafs/synapses are proximal to a node astotal - distal, which is only valid on a single-rooted neuron. Nodes in another fragment are neither distal nor proximal but were silently counted as proximal, inflating the flow. Totals are now counted within each node's own fragment. This changes the output for fragmented neurons (they were previously wrong); single-rooted neurons are unaffected. Note thatsynapse_flow_centralitywas only affected withoutnavis-fastcore, so the two backends used to disagree;bending_flowwas never affectedTreeNeuron.small_segmentsreturned the segments in a different order depending on whethernavis-fastcorewas installed (without it, NAVis walked a Pythonset, i.e. in arbitrary hash order). They are now always ordered by the node table position of their seed node, which is whatnavis-fastcorealready did. Several functionsenumerate()the segments, so the order was ending up in their output - most visibly the row order ofsegment_analysisclassify_nodes: a node whose parent does not exist is now classified asrootinstead ofend. Such a neuron is already broken (it raises inneuron2igraph)despike_skeleton: nodes whose flanking nodes coincided were assigned a spike ratio read from uninitialised memory and were hence flagged as spikes (and removed) at randomplot1d: the bars were drawn using the length of each segment's first edge rather than the length of the whole segment. The x-axis was therefore far too short and distorted per-segment; for the example neuron it spanned 74,934 instead of 266,477 units of cable. This changes the rendered plot (it was previously wrong)resample_skeleton: the resampled neuron was consistently coarser than requested. A segment of lengthLsampled atNnodes spansN - 1intervals, but the node count wasround(L / resample_to)instead ofround(L / resample_to) + 1. This changes the output: neurons now come back with slightly more nodes and a sampling resolution much closer toresample_to(example neuron atresample_to=125: 2039 -> 2284 nodes, achieved resolution 140 -> 112)resample_skeleton:skip_errors=Truenever actually skipped anything (the failing segment raised aKeyErrorinstead); failing segments now keep their original nodes, as intendedresample_skeleton: fixed a typo (pd.to_nunmeric) that raised anAttributeErrorwhenever the new node IDs overflowed the originalint32node ID column, and aNameErrorin the "N segments skipped" warning for neurons without segmentsheal_skeleton: theuse_radiusparameter was accepted but silently ignored; it is now honouredheal_skeleton: withuse_radius, isolated nodes (which belong to no segment) were given an unrelated node's radius and were not scaled byuse_radius; they now correctly fall back to their own, scaled radiusheal_skeleton: fragments that remain disconnected (because ofmax_dist/min_size/mask) now keep their original root instead of being re-rooted arbitrarilystitch_skeletons: passingmethod=<list of node IDs>- documented as option (4) - raised a bareAssertionError. It now works and restricts the new edges to those nodes. Note that node IDs are remapped when the fragments have duplicate IDs, in which case a list of IDs is ambiguousdist_between: unreachable node pairs are now correctly reported asinf(navis-fastcore0.5.1 returned a bogus1.0; fixed in 0.6.0, which NAVis now requires)drop_fluffworks onDotpropsagainmodels.BayesianTraversalModel: corrected the traversal-probability propagation so results now match the Monte-CarloTraversalModelfor reconvergent graphs (e.g. diamonds); previously an independence assumption across time caused nodes to appear traversed too early (#194)- neuron math operators (
+,-,*,/) no longer break on neurons with integer node/connector coordinates under modernpandas simplify_mesh: passing a float ratio asFfailed with thepyfqmrandopen3dbackends because the computed face count was not an integerplot2d: fixed anAttributeErrorwithmatplotlib3.11 (which removedPoly3DCollection._vec)close3d/pop3dno longer break when there is no active viewer, andclose3dnow actually releasesconfig.primary_viewer- transforms:
GridTransformandCMTKtransformhad brokencopy()methods - forGridTransformthis droppedspacing/offsetand hence produced wrong coordinates for any copied (i.e. anyxform_brain'd) transform. Also fixedGridTransform.from_warpfieldwhen the input is an actual warpmap neuprintinterface: fixed synapses not being assigned to the correct neuron whenfetch_mesh_neuronwas called for multiple neurons withwith_synapses=Trueneuprintinterface: no longer errors on datasets whose meta data lacks fields such asinstance,size,statusorsomaLocation, and now sets the correct units for datasets with anisotropic voxels (the x voxel size was previously assumed for all three axes)neuromorphointerface: works again - it now useshttps, sends a user agent (the server was rejecting requests without one) and gained aNAVIS_NEUROMORPHO_VERIFYenvironment variable to disable SSL verification if the certificate is brokenread_precomputed: fixed reading from Google buckets- silenced
pandasdeprecation warnings inread_swcandNeuronConnector
Notes#
heal_skeletonwithuse_radiuscan give marginally different (but equally valid) results depending on whethernavis-fastcoreis installed: each node is weighted by the mean radius of its segment, but branch points belong to several segments and end up with whichever one is assigned last - and the two backends enumerate segments in a different order. Both still produce a true minimum spanning tree. This is not new but is easier to run into now that fastcore is used by default
Version 1.11.0#
Date: 27/02/26
Breaking#
- dropped support for Python 3.9
Improvements#
split_axon_dendritenow allows setting the in-/output ratio for the split (seesplitparameter)- major speed-up for
heal_skeleton - minor speed-up for
resample_skeleton - add
progressparameter tomirror_brain,symmetrize_brainandcombine_meshes persistence_vectorsnow accepts list of distances to be sampled assamplesmake_dotpropshas a newon_issueparameter that determines what to do when issues with the inputs are encountered (e.g. NaNs)- two new
VoxelNeuronmethods:flip()flips the neuron along specified axesnormalize()scales values to a 0-1 range
neuprintinterface:fetch_skeletonsandfetch_mesh_neuronwill now also look fortosomaLocationto set the root/soma if there is nosomaLocation- avoid fetching unused ROI info in
fetch_skeletonsandfetch_mesh_neuron(minor speed-up)
pointlabels_to_meshescan now also output voxels instead of meshes- transforms:
- new transform type:
GridTransformis a class for generic deformation-field transforms TPStransformnow has a.matrix_rigidproperty that extracts the rigid part of the TPS affine as a 4x4 matrixTPStransformsandMovingLeastSquaresTransformstransforms now transform in batches to avoid memory issues when transforming large numbers of points- new methods for
CMTKtransform:to_dfieldandto_grid_transformcan be used to sample the CMTK transform into a deformation field (this is experimental) - new
H5transformmethod:xform_imagecan be used to apply the transform to images (this is experimental) TransformRegistry.register_transformnow accepts an optionalweight_invparameter; can be used to penalize expensive inverse transforms (e.g. CMTK)
- new transform type:
- input/output:
read_xxxfunctions will now use threads instead of processes for parallelization when reading from URLs (much faster)read_precomputedwill now also look for.ngmeshfiles when given a folder to searchread_xxxfunction can now load data straight from Google buckets (gs://..., requires the optionalgcsfs)
Fixes#
- using
connectors="pre/postsynapses"now actually works inplot2dandplot3d - fixed an issue in
resample_skeletonwhere adding new nodes could cause an overflow error for node IDs - subsetting neuron meshes with connectors will now correctly carry over vertex IDs
- plotting skeleton where the soma has no radius will not break anymore
write_xxxfunctions do not break anymore when a neuron has id0- plotting of connectors:
- parameters
cn_alpha,cn_colorsandcn_mesh_colorsnow work across all 3d backends plot2dnow respectscn_alpha- fixed an issue where checking for available mesh backends (pyfqmr, pymeshlab, etc) could cause a crash
- Blender interface: fixed an issue adding skeletons caused by pandas >= 3.0
Full Changelog: v1.10.0...v1.11.0
Version 1.10.0#
Date: 06/02/25
Improvements#
- made reading neurons from
.tararchives much faster read_swcnow works if additional columns are present
Fixes#
opacityparameterplot3dnow works correctly when using the plotly backend- fixed an issue with Elastix transforms on Windows machines
- fixes for
navis.longest_neuritewhenfrom_root=False - fixed issues with neuPrint interface when using multiple clients
- fixed an issue with the MICrONS interface
- fixed an issue with mesh simplification and the pymeshlab and Blender backends (@floesche)
- fixed two (potential) issues in navis.longest_neurite when
from_root=False - fixed various issues related to numpy 2.0 (@floesche)
Full Changelog: v1.9.1...v1.10.0
Version 1.9.1#
Date: 24/10/24
Improvements#
- MICrONS & H01 interfaces:
fetch_neuronsnow accepts amaterializationparameter that determines which materialization version is used for synapse and nucleus queries; defaults to "auto" which meansnaviswill try to find a materialization version matching the queried root IDsfetch_neuronswill now also assign soma positions for H01 neurons (see the.soma_posneuron property)
CloudVolume.mesh.get_navis(seenavis.patch_cloudvolume) now accepts aprocess(default isFalse) parameter that determines whether the NeuroGlancer mesh is processed (deduplication of vertices, etc.); contribute by Forrest Collman
Fixes#
- fixed a bug in
navis.subset_neuronthat caused branch points to not be re-calculated
Full Changelog: v1.9.0...v1.9.1
Version 1.9.0#
Date: 17/10/24
This version brings a shiny new interface to the H01 human cortex dataset and various other quality of life improvements.
Breaking#
- The default for
radius(navis.plot2dandnavis.plot3d) was changed toFalse(from"auto"); this is to make sure that the defaults allow visualizing large numbers of skeletons, i.e. prioritizing performance over beauty
Additions#
- New interface to the H01 dataset (by Jinhan Choi and Jakob Troidl; see the new tutorial for details)
Improvements#
- I/O:
- Image data:
- new function:
navis.thin_voxelscan be used to thin images andVoxelNeuronsto single-pixel width (see also below) - new
thinparameter forread_nrrd,read_tiff
- new function:
TreeNeurons:- skeletons can now be initialized from a
(vertices, edges)tuple - see alsonavis.edges2neuron - new property:
TreeNeuron.verticesgives read-only to node (vertex) coordinates
- skeletons can now be initialized from a
VoxelNeurons:- new properties:
VoxelNeuron.nnzandVoxelNeuron.density
- new properties:
navis.drop_fluffandnavis.neuron2nxnow also works withDotprops
Experimental#
- setting
navis.config.add_units=True(default isFalsefor the time being) will add units to certain neuron properties such as.cable_lengthto make them human-readable
Full Changelog: v1.8.0...v1.9.0
Version 1.8.0#
Date: 22/09/24
This version contains a major internal rework of both navis.plot2d and navis.plot3d to make them more consistent and easier to use.
Breaking#
- Plotting: the
synapse_layoutparameter was renamed tocn_layout(matching e.g. other parameters such ascn_colors) - Negative views in
navis.plot2d(e.g.view=("x", "-z")) will now invert axes rather than changing the underlying data - Minimum version of
matplotlibis now3.9(was3.6) - The
plotlybackend is not part of a minimal install anymore (still installed usingnavis[all]) - The Vispy backend is now deprecated and will be removed in a future release
- Removed
navis.screenshot- please use the Octarine/Vispy viewer's.screenshot()method instead navis.tortuositynow calculates tortuosity as-is (i.e. without resampling) by default
Additions#
- Added Octarine as the default backend for plotting from terminal
- New Function:
navis.ivscc_featurescomputes some basic IVSCC features - New function:
navis.graph.skeleton_adjacency_matrixcomputes the node adjacency for skeletons - New function:
navis.graph.simplify_graphsimplifies skeleton graphs to only root, branch and leaf nodes while preserving branch length (i.e. weights) - New
NeuronListmethod:get_neuron_attributesis analagous todict.get NeuronListsnow implement the|(__or__) operator which can be used to get the union of twoNeuronListsnavis.Volumenow have an (optional).unitsproperty similar to neuronsTree/MeshNeuronsandDotpropsnow support addition/subtraction (similar to the already existing multiplication and division) to allow offsetting neurons
Improvements#
- Plotting:
navis.plot3d:legendgroupparameter (plotly backend) now also sets the legend group's title- new parameters for the plotly backend:
legend(defaultTrue): determines whether legends is shownlegend_orientation(defaultv): determines whether legend is aranged vertically (v) or horizontally (h)linestyle(default-): determines line style for skeletons
- default for
radiusis now"auto" navis.plot2d:- the
viewparameter now also works withmethods3dand3d_complex - the
color_byandshade_byparameters now also work when plotting skeletons withradius=True - new defaults:
radius="auto",alpha=1,figsize=None(use matplotlib defaults) - new parameters for methods
3dand3d_complex:mesh_shade=Falseandnon_view_axes3d - the
scalebarandsomaparameters can now also be dictionaries to style (color, width, etc) the scalebar/soma - the
connectorsparameter can now be used to show specific connector types (e.g.connectors="pre")
- I/O:
read_*functions are now able to read from FTP servers (ftp://...)- the
limitparameter used in manyread_*functions can now also be a regex pattern or aslice
- New parameter in
navis.resample_skeleton: usemap_columnto include arbitrary columns in the resampling navis.prune_twigsandnavis.morpho.cable_lengthnow accept amaskparameter- General improvements to docs and tutorials
Fixes#
- Memory usage of
Neuron/Listsis now correctly re-calculated when the neuron is modified - Various fixes and improvements for the MICrONS interface (
navis.interfaces.microns) navis.graph.node_label_sortingnow correctly prioritizes total branch lengthnavis.TreeNeuron.simplenow correctly drops soma nodes if they aren't root, branch or leaf points themselves
Full Changelog: v1.7.0...v1.8.0
Version 1.7.0#
Date: 25/07/24
Breaking#
- Plotting: dropped the
clusterparameter in favor of an improvedcolor_bylogic (see below)
Additions#
- NAVis now uses
navis-fastcoreif present to dramatically speed up core functions (see updated install instructions) - New method
navis.NeuronList.add_metadatato quickly add metadata to neurons
Improvements#
navis.find_somaandnavis.graph.neuron2nx(used under the hood) are now much faster- All I/O functions such as
navis.read_swcnow show which file caused an error (if any); original filenames are tracked asfileproperty navis.NeuronListwill only search the first 100 neurons for autocompletion to avoid freezing with large lists- Plotting functions:
color_bynow accepts either a list of labels (one per neuron) or the name of a neuron property navis.subset_neuronis now faster and more memory efficient when subsetting meshesnavis.TreeNeuron.cable_lengthis now faster- Fixed a bug in plotting when using vertex colors
- Fixed the progress bar in
navis.interfaces.neuprint.fetch_mesh_neuron - Fixed a bug in
navis.synblastthat caused multiprocessing to fail (pickling issue withpykdtree) navis.interfaces.neuprint.fetch_mesh_neuronwill now ignore thelodparameter if the data source does not support it instead of breaking- Fixed a number of deprecation warnings in the codebase
Full Changelog: v1.6.0...v1.7.0
Version 1.6.0#
Date: 07/04/24
Breaking#
- Dropped support for Python 3.8, per NEP 29
navis.write_swcno longer supports writing Dotprops to SWC files
Additions#
- New property
TreeNeuron.surface_area - New (experimental) functions
navis.read_parquetandnavis.write_parquetstore skeletons and dotprops in parquet files (see here for format specs) - New
navis.read_nmlfunction to read single NML file - New
navis.NeuronConnectorclass for creating connectivity graphs from groups neurons with consistent connector IDs - New method for CMTKtransforms:
navis.transforms.CMTKTransform.xform_image
Improvements#
- Improved performance for adding recordings to
CompartmentModel navis.heal_skeletonandnavis.resample_skeletonare now faster- Improved logic for splitting NBLASTs across multiple cores
navis.xform_brainnow allows specifying multiple intermediate template spaces through theviaparameter and to ignore spaces through theavoidparameter- I/O functions can now read directly from
.taror.tar.gzfiles navis.read_precomputednow accepts alimitparameter similar tonavis.read_swc
Fixes#
- Fixed interface to InsectBrainDB
navis.read_precomputed:- now correctly parses the
infofile depending on the source - reading large files (i.e. meshes) directly from a URL should not break anymore
- now correctly parses the
- Fixed writing vertex properties in
navis.write_precomputed - Fixed a bug in
navis.resample_skeleton - Fixed an occasional issue when plotting skeletons with radii
- Fixed bug in
navis.subset_neuronthat caused connectors to be dropped when using mask - Fixed a bug in
navis.despike_skeletonthat caused thereverseargument to be ignored - Fixed two small bugs in
navis.interfaces.neuprint.fetch_mesh_neuron
Full Changelog: v1.5.0...v1.6.0
Version 1.5.0#
Date: 27/07/23
Breaking#
- Dropped support for Python 3.7
Additions#
- New function:
navis.pop3dremoves the most recently added object from the vispy 3d viewer - New experimental functions for (pairwise) alignment of neurons using the
pycpdpackage:navis.nblast_align,navis.align.align_deform,navis.align.align_rigid,navis.align.align_pca,navis.align.align_pairwise - New
NeuronListmethod:navis.NeuronList.set_neuron_attributes - New utility functions:
navis.nbl.compress_scores,navis.nbl.nblast_prime
Improvements#
navis.xform_brainnow recognizes the target template's units if available- Improved persistence functions:
navis.persistence_distances,navis.persistence_vector,navis.persistence_diagram navis.longest_neuriteandnavis.cell_body_fibernow also allow removing the longest neurite and CBF, respectivelynavis.heal_skeletonnow accepts amaskparameter that allows restricting where fragments are stitched
Fixes#
- Various other bugfixes
Full Changelog: v1.4.0...v1.5.0
Version 1.4.0#
Date: 21/12/22
Breaking#
navis.flow_centralitywas renamed tonavis.synapse_flow_centralityand a new non-synapticnavis.flow_centralityfunction was added. This also impacts themethodparameter innavis.split_axon_dendrite!vispyis now a soft dependency
Additions#
- New function:
navis.read_tiffto read image stacks from TIFF files - New utility function:
navis.nbl.extract_matches
Improvements#
- NBLASTs: single progress bar instead of one for each process
- New
viaparameter fornavis.xform_brain navis.write_swccan now save Dotprops to SWC filesnavis.make_dotpropscan now downsample point cloud inputs- Various improvements to
navis.split_axon_dendrite,navis.nblast_allbyall,navis.interfaces.neuprint.fetch_mesh_neuron,navis.interfaces.neuprint.fetch_skeletons
Fixes#
- Tons of bug fixes
Full Changelog: v1.3.1...v1.4.0
Version 1.3.1#
Date: 10/06/22
Fixes#
- Various bugs fixed
Full Changelog: v1.3.0...v1.3.1
Version 1.3.0#
Date: 10/05/22
Breaking#
- As of this version
pip install naviswon't install a vispy backend
Additions#
- New interface to fetch data from Virtual Fly Brain:
navis.interfaces.vfb - Tools to build custom NBLAST score matrices
- Bayesian implementation of the network traversal model:
navis.models.network_models.BayesianTraversalModel - New morphometrics functions:
navis.segment_analysis&navis.form_factor - New function to write meshes:
navis.write_mesh
Improvements#
- NBLASTs: new
approx_nnparameter - Example neurons now come with some meta data
Fixes#
- Lots of fixes and improvements in particular for I/O-related functions
Full Changelog: v1.2.1...v1.3.0
Version 1.2.1#
Date: 25/02/22
Fixes#
- Hot fix for
navis.split_axon_dendrite
Full Changelog: v1.2.0...v1.2.1
Version 1.2.0#
Date: 24/02/22
Additions#
- New function:
navis.betweeness_centrality - New function:
navis.combine_neuronsto simply concatenate neurons - New set of persistence functions:
navis.persistence_vectors,navis.persistence_pointsandnavis.persistence_distances - Added a new interface with the Allen Cell Types Atlas
Improvements#
- Improvements to various functions: e.g.
navis.bending_flow,navis.synapse_flow_centrality,navis.split_axon_dendrite,navis.longest_neurite navis.write_nrrdandnavis.read_nrrdcan now be used to write/read Dotprops to/from NRRD filesnavis.read_swcnow accepts alimitparameter that enables reading on the first N neuronsnavis.nblast(and variants) now accept aprecisionparameternavis.simplify_mesh(and thereforenavis.downsample_neuronwith skeletons) now uses thepyfqmrif present- Improved the interface to Neuromorpho
Fixes#
- Myriads of small and big bugfixes
Full Changelog: v1.1.0...v1.2.0
Version 1.1.0#
Date: 18/11/21
Additions#
- New function:
navis.sholl_analysis - Plotly is now correctly chosen as default backend in Google colab
Fixes#
- Fixed a critical bug with plotting skeletons with plotly
5.4.0
Full Changelog: v1.0.0...v1.1.0
Version 1.0.0#
Date: 11/11/21
Breaking#
navis.MeshNeuron:__getattr__does not searchtrimeshrepresentation anymore- NBLASTs: queries/targets now MUST be
navis.Dotprops(no more automatic conversion, usenavis.make_dotprops) - Renamed functions to make it clear they work only on
TreeNeurons: smooth_neuronnavis.smooth_skeletonreroot_neuronnavis.reroot_skeletonrewire_neuronnavis.rewire_skeletondespike_neuronnavis.despike_skeletonaverage_neuronsnavis.average_skeletonsheal_fragmented_neuronnavis.heal_skeletonstitch_neuronsnavis.stitch_skeletonscut_neuronnavis.cut_skeleton- Removals and other renamings:
navis.clusteringmodule was removed and with itnavis.cluster_xyzandClustResultclass- renamed
cluster_by_synapse_placementnavis.synapse_similarity - renamed
cluster_by_connectivitynavis.connectivity_similarity - renamed
sparsenessnavis.connectivity_sparseness - renamed
navis.write_google_binarynavis.write_precomputed
navis.geodesic_matrixrenamed parametertn_idsfrom_
Additions & Improvements#
navis.NeuronList.apply()now allows omitting failuresnavis.VoxelNeuron:- new class representing neurons as voxels
- new (experimental) class representing neurons as voxels
navis.read_nrrdnow returnsVoxelNeuroninstead ofDotpropsby default- currently works with only a selection of functions
navis.TreeNeuron:- can now be initialized directly with
skeletor.Skeleton - new method:
navis.TreeNeuron.snap
- can now be initialized directly with
navis.MeshNeuron:navis.in_volume,navis.subset_neuronandnavis.break_fragmentsnow work onMeshNeurons- new properties:
.skeleton,.graphand.igraph - new methods:
navis.MeshNeuron.skeletonizeandnavis.MeshNeuron.snap - can now be initialized with
skeletor.Skeletonand(vertices, faces)tuple - plotting:
color_byparameter now works withMeshNeurons
navis.Dotprops:- new property:
.sampling_resolution(used e.g. for scaling vectors for plotting) - new method:
navis.Dotprops.snap
- new property:
- Experimental support for non-isometric
.unitsfor neurons - NBLASTs:
- new parameter
limit_distallows speeding up NBLASTs with minor precision loss - new experimental parameter
batch_sizeto NBLAST neurons in batches - overall faster initialization with large lists of neurons
- new parameter
- SWC I/O (
navis.read_swc&navis.write_swc):- by default we will now deposit neuron meta data (name, id, units) in the SWC header (see
write_metaparameter) - meta data in SWC header can also be read back (see
read_metaparameter) - filenames can now be parsed into specific neuron properties (see
fmtparameter) - node IDs now start with 0 instead of 1 when writing SWC files
- by default we will now deposit neuron meta data (name, id, units) in the SWC header (see
- I/O to/from Google neuroglancer's precomputed format:
- total rework of this module
- renamed
navis.write_google_binarynavis.write_precomputed - new function:
navis.read_precomputed
- Plotting:
- new function
navis.plot_flatplots neurons as dendrograms navis.plot3dwith plotly backend now returns a plotlyFigureinstead of a figure dictionary- new k3d backend for plotting in Jupyter environments: try
navis.plot3d(x, backend='k3d') - new parameter for
navis.plot2dandnavis.plot3d: useclusters=[0, 0, 0, 1, 1, ...]to assigns clusters and have them automatically coloured accordingly navis.plot2dnow allowsradius=Trueparameter
- new function
- Transforms:
- support for elastix (
navis.transforms.ElastixTransform) - whether transforms are invertible is now determined by existence of
__neg__method
- support for elastix (
- Most functions that work with
TreeNeuronsnow also work withMeshNeurons - New high-level wrappers to convert neurons:
navis.voxelize,navis.meshandnavis.skeletonize navis.make_dotpropsnow acceptsparallel=Trueparameter for parallel processingnavis.smooth_skeletoncan now be used to smooth arbitrary numeric columns in the node table- New function
navis.drop_fluffremoves small disconnected bits and pieces from neurons - New function
navis.patch_cloudvolumemonkey-patchescloudvolume(see the new tutorial) - New function
navis.write_nrrdwritesVoxelNeuronsto NRRD files - New functions to read/write
MeshNeurons:navis.read_meshandnavis.write_mesh - New function
navis.read_nmxreads pyKNOSSOS files - New function
navis.smooth_meshsmoothes meshes andMeshNeurons - Improved/updated the InsectBrain DB interface (see the tutorial)
- Under-the-hood fixes and improvements to:
navis.plot2d,navis.split_axon_dendrite,navis.tortuosity,navis.resample_skeleton,navis.mirror_brain - First pass at a
NEURONinterface (see the new tutorial) - First pass at interface with the Allen's MICrONS datasets (see the new tutorial)
NAVIS_SKIP_LOG_SETUPenvironment variable prevents default log setup for library use- Improved
navis.cable_overlap
Fixes#
- Under-the-hood fixes and improvements
Full Changelog: v0.6.0...v1.0.0
Version 0.6.0#
Date: 12/05/21
Additions#
- new functions:
navis.prune_at_depth,navis.read_rda,navis.cell_body_fiber - new functions to map units into neuron space:
BaseNeuron.map_unitsandnavis.to_neuron_space
Improvements#
- many spatial parameters (e.g. in
navis.resample_skeleton) can now be passed as unit string, e.g."5 microns" - many functions now accept a
parallel=Trueparameter to use multiple cores (depends onpathos) navis.read_swcandnavis.write_swccan now read/write directly from/to zip files- reworked
navis.read_json, andnavis.write_json nblastfunctions now let you use your own scoring function (thanks to Ben Pedigo!)- added
thresholdparameter tonavis.read_nrrd navis.nblast_smart: dropquantileand addscorecriterion- functions that manipulate neurons will now always return something (even if
inplace=True) navis.cut_skeletonnow always returns a singleNeuronListnavis.mirror_brainnow works withk=0/NoneDotprops- all
reroot_to_somaparameters have been renamed toreroot_soma navis.TreeNeuronnow has asoma_posproperty that can also be used to set the soma by position- made transforms more robust against points outside deformation fields
- better deal if node ID of soma is
0(e.g. during plotting) navis.neuron2tangentsnow drops zero-length vectors
Fixes#
- fixed
navis.guess_radius - fixed NBLAST progress bars in notebook environments
- fixed a couple bugs with
CMTKtransforms
Full Changelog: v0.5.3...v0.6.0
Version 0.5.3#
Date: 10/04/21
Additions#
- new functions:
navis.nblast_smart,navis.synblast,navis.symmetrize_brain navis.plot2d:rasterize=Truewill rasterize neurons (but not axes or labels) to help keep file sizes lownavis.plot3d(plotly):hover_name=Truewill show neuron names on hover
Improvements#
navis.simplify_meshnow supports 3 backends: Blender3D,open3dorpymeshlabnavis.make_dotpropscan now produceDotpropspurely from skeleton edges (setk=None)- reworked
navis.write_swc(faster, easier to work with) - a new type of landmark-based transform: moving least square transforms (thanks to Chris Barnes)
- vispy
navis.Viewer: press B to show a bounding box - moved tests from Travis to Github Actions (this now also includes testing tutorial notebooks)
Fixes#
- a great many small and big bug fixes
Full Changelog: v0.5.2...v0.5.3
Version 0.5.2#
Date: 02/02/21
Additions#
- new functions:
navis.xform,navis.write_precomputed
Improvements#
navis.downsample_neuronnow also works onDotprops- Neurons: connectors are now included in bounding box calculations
- NeuronLists: added progress bar for division / multiplication
Full Changelog: v0.5.1...v0.5.2
Version 0.5.1#
Date: 10/01/21
Fixes#
- Various under-the-hood improvements and bugfixes
Full Changelog: v0.5.0...v0.5.1
Version 0.5.0#
Date: 05/01/21
Additions#
- new functions for transforming spatial data (locations, neurons, etc) between brain spaces:
navis.xform_braintransforms data from one space to anothernavis.mirror_brainmirrors data about given axis- see the new tutorials for explanations
- low-level interfaces to work with affine, H5-, CMTK- and thin plate spline transforms
Improvements#
- de-cluttered top level namespace: some more obscure functions are now only available through modules
Full Changelog: v0.4.3...v0.5.0
Version 0.4.3#
Date: 22/12/20
Fixes#
- Small bugfixes
Full Changelog: v0.4.2...v0.4.3
Version 0.4.2#
Date: 22/12/20
Fixes#
- Small bugfixes
Full Changelog: v0.4.1...v0.4.2
Version 0.4.1#
Date: 06/12/20
Fixes#
- Critical bugfix in NBLAST
Full Changelog: v0.4.0...v0.4.1
Version 0.4.0#
Date: 06/12/20
Additions#
- native implementation of NBLAST:
navis.nblastandnavis.nblast_allbyall! - new parameter
navis.plot3d(plotly backend) withhover_id=Truewill show node IDs on hover navis.Volume.resizehas nowinplace=Falseas default
Full Changelog: v0.3.4...v0.4.0
Version 0.3.4#
Date: 24/11/20
Improvements#
- improved
navis.Dotprops: - more control over generation in
navis.make_dotprops navis.Dotpropsnow play nicely with R interface
Full Changelog: v0.3.3...v0.3.4
Version 0.3.3#
Date: 23/11/20
Additions#
- new module:
modelsfor modelling networks and neurons - new functions
navis.resample_along_axis,navis.insert_nodes,navis.remove_nodes - full rework of
navis.Dotprops: - make them a subclass of BaseNeuron
- implement
nat:dotpropsinnavis.make_dotprops - added
navis.read_nrrdandnavis.write_nrrd - side-effect: renamed
navis.from_swcread_swcandnavis.to_swcwrite_swc - improved conversion between nat and NAVis
Dotprops - full rework of topology-related functions:
navis.strahler_index,navis.segregation_index,navis.bending_flow,navis.synapse_flow_centralityandnavis.split_axon_dendritenow work better, faster and more accurately. See their docs for details.- new function:
navis.arbor_segregation_index - new
color_byandshade_byparameters forplot3dandplot2dthat lets you color/shade a neuron by custom properties (e.g. by Strahler index or compartment)
Improvements#
- neurons are now more memory efficient:
- pandas "categoricals" are used for connector and node "type" and "label" columns
- add a
.memory_usagemethod analogous to that ofpandas.DataFrames
navis.NeuronListcan now be pickled!- made
navis.Viewerfaster navis.prune_twigscan now (optionally) prune byexactlythe desired length- improved
navis.NeuronList.apply
Fixes#
- small bugfixes and improvements
Full Changelog: v0.3.2...v0.3.3
Version 0.3.2#
Date: 18/10/20
Improvements#
navis.plot2dandnavis.plot3dnow accepttrimesh.Trimeshdirectlynavis.in_volumenow works with any mesh-like object, not justnavis.Volumes
Fixes#
- lots of small bugfixes and improvements
Full Changelog: v0.3.1...v0.3.2
Version 0.3.1#
Date: 07/10/20
Additions#
- new function
navis.rewire_skeleton
Improvements#
navis.heal_skeletonandnavis.stitch_skeletonsare now much much fasternavis.reroot_skeletoncan now reroot to multiple roots in one gonavis.plot3dnow accepts asomaargument- improved caching for neurons
- improved multiplication/division of neurons
- faster
r.nblastandr.nblast_allbyall r.xform_brainnow also adjusts the soma radiusneuprint.fetch_skeletonsnow returns correct soma radius
Fixes#
- lots of small bugfixes
Full Changelog: v0.3.0...v0.3.1
Version 0.3.0#
Date: 06/10/20
Additions#
- Started module to manipulate mesh data (see e.g.
navis.simplify_mesh)
Improvements#
- Improved interfaces with R NBLAST and
xform_brain - Improved attribute caching for neurons
Full Changelog: v0.2.3...v0.3.0
Version 0.2.3#
Date: 06/09/20
Additions#
- New Neuron property
.labelthat if present will be used for plot legends - New function for R interface:
navis.interfaces.r.load_rda
Improvements#
- Blender interface: improved scatter plot generation
Version 0.2.2#
Date: 15/08/20
Additions#
- New
plot3dparameter: with plotly backend, usefigto add data to existing plotly figure - New
plot3dparameter: with vispy backend, usecenter=Falseto not re-center camera on adding new data - New
r.mirror_brainparameter: use e.g.via='FCWB'if source space does not have mirror transform - New
NeuronListmethod:append()works likelist.append() - First implementation of smarter (re-)calculation of temporary Neuron properties using
.is_staleproperty - Neurons can now be multiplied/divided by array/list of x/y/z coordinates for non-isometric transforms
Fixes#
- Fix issues with newer rpy2 versions
- Various improvements and bug fixes
Version 0.2.1#
Date: 20/04/20
Additions#
- New
plot3dparameter: with plotly backend, useradius=Trueplots TreeNeurons with radius - New
plot2dparameter:orthogonal=Falsesets view to perspective
Improvements#
- Various improvements to e.g.
nx2neuron
Version 0.2.0#
Date: 29/06/20
Breaking#
navis.nx2neuronnow returns anavis.TreeNeuroninstead of aDataFrame
Additions#
- New neuron class
navis.MeshNeuron - New
navis.TreeNeuronproperty.volume - New example data from the Janelia hemibrain data set
Improvements#
- Clean-up in neuromorpho interface
- We now use ncollpyde for ray casting (intersections)
Fixes#
- Fix bugs in
navis.Volumepickling
Version 0.1.16#
Date: 26/05/20
Fixes#
- Many small bugfixes
Version 0.1.15#
Date: 15/05/20
Improvements#
- Improvements to R and Blender interface
- Improved loading from SWCs (up to 2x faster)
TreeNeurons: allow rerooting by setting the.rootattribute
Version 0.1.14#
Date: 05/05/20
Fixes#
- Emergency fixes for critical bugs
Version 0.1.13#
Date: 05/05/20
Additions#
- new function:
navis.vary_color
Improvements#
- improvements to Blender interface and various other functions
Version 0.1.12#
Date: 02/04/20
Imnprovements#
navis.Volumeis now sublcass oftrimesh.Trimesh
Version 0.1.11#
Date: 28/02/20
Improvements#
- improved
navis.stitch_neurons: much faster now if you have iGraph
Fixes#
- fixed errors when using multiprocessing (e.g. in
NeuronList.apply) - fixed bugs in
navis.downsample_neuron
Version 0.1.10#
Date: 24/02/20
Fixes#
- Fixed bugs in Blender interface introduced in 0.1.9
Version 0.1.9#
Date: 24/02/20
Fixes#
- Removed hard-coded swapping and translation of axes in the Blender interface
- Fixed bugs in
navis.stitch_neurons
Version 0.1.8#
Date: 21/02/20
Fixes#
- Again lots of fixed bugs
Version 0.1.0#
Date: 23/05/19
Fixes#
- Many small bugfixes
Version 0.0.1#
Date: 29/01/19
Fixes#
- First commit, lots to fix.