https://github.com/seung-lab/fastremap

Remap, mask, renumber, unique, and in-place transposition of 3D labeled images. Point cloud too.

https://github.com/seung-lab/fastremap

Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (8.1%) to scientific vocabulary

Keywords

array-manipulations biomedical-image-processing cython in-place in-place-transposition looping masking numpy point-cloud python python3 remap remapping renumbering transpose unique
Last synced: 5 months ago · JSON representation

Repository

Remap, mask, renumber, unique, and in-place transposition of 3D labeled images. Point cloud too.

Basic Info
Statistics
  • Stars: 63
  • Watchers: 18
  • Forks: 8
  • Open Issues: 1
  • Releases: 0
Topics
array-manipulations biomedical-image-processing cython in-place in-place-transposition looping masking numpy point-cloud python python3 remap remapping renumbering transpose unique
Created about 7 years ago · Last pushed 6 months ago
Metadata Files
Readme Changelog License Authors

README.md

PyPI version

fastremap

Renumber and relabel Numpy arrays at C++ speed and physically convert rectangular Numpy arrays between C and Fortran order using an in-place transposition.

```python import fastremap

uniq, cts = fastremap.unique(labels, return_counts=True) # may be much faster than np.unique

idxs = fastremap.indices(labels, 1231) # important for huge arrays

labels, remapping = fastremap.renumber(labels, inplace=True) # relabel values from 1 and refit data type ptc = fastremap.pointcloud(labels) # dict of coordinates by label

labels = fastremap.refit(labels) # resize the data type of the array to fit extrema labels = fastremap.refit(labels, value=-35) # resize the data type to fit the value provided

widerdtype = fastremap.widendtype(np.uint32) # np.uint64 narrowerdtype = fastremap.narrowdtype(np.uint32) # np.uint16

remap all occurances of 1 -> 2

labels = fastremap.remap(labels, { 1: 2 }, preservemissinglabels=True, in_place=True)

labels = fastremap.mask(labels, [1,5,13]) # set all occurances of 1,5,13 to 0 labels = fastremap.mask_except(labels, [1,5,13]) # set all labels except 1,5,13 to 0

mapping = fastremap.componentmap([ 1, 2, 3, 4 ], [ 5, 5, 6, 7 ]) # { 1: 5, 2: 5, 3: 6, 4: 7 } mapping = fastremap.inversecomponent_map([ 1, 2, 1, 3 ], [ 4, 4, 5, 6 ]) # { 1: [ 4, 5 ], 2: [ 4 ], 3: [ 6 ] }

fastremap.transpose(labels) # physically transpose labels in-place fastremap.ascontiguousarray(labels) # try to perform a physical in-place transposition to C order fastremap.asfortranarray(labels) # try to perform a physical in-place transposition to F order

minval, maxval = fastremap.minmax(labels) # faster version of (np.min(labels), np.max(labels))

computes number of matching adjacent pixel pairs in an image

numpairs = fastremap.pixelpairs(labels)
n_foreground = fastremap.foreground(labels) # number of nonzero voxels

computes the cutout.tobytes(order) of each chunk and returns

the binaries indexed by fortran order in the order specified (C or F)

If the input image is F contiguous and F is requested, or C and C order,

and the image is larger than a single chunk, this will be significantly

faster than iterating and using tobytes.

binaries = fastremap.tobytes(labels, (64,64,64), order="F") ```

All Available Functions

  • unique: Faster implementation of np.unique.
  • renumber: Relabel array from 1 to N which can often use smaller datatypes.
  • indices: Optimized search for matching values.
  • remap: Custom relabeling of values in an array from a dictionary.
  • refit: Resize the data type of an array to the smallest that can contain the most extreme values in it.
  • narrow_dtype: Find the next sized up dtype. e.g. uint16 -> uint32
  • widen_dtype: Find the next sized down dtype. e.g. uint16 -> uint8
  • mask: Zero out labels in an array specified by a given list.
  • mask_except: Zero out all labels except those specified in a given list.
  • component_map: Extract an int-to-int dictionary mapping of labels from one image containing component labels to another parent labels.
  • inversecomponentmap: Extract an int-to-list-of-ints dictionary mapping from an image containing groups of components to an image containing the components.
  • remapfromarray: Same as remap, but the map is an array where the key is the array index and the value is the value.
  • remapfromarray_kv: Same as remap, but the map consists of two equal sized arrays, the first containing keys, the second containing values.
  • transpose: Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, apply the stock np.transpose function otherwise.
  • asfortranarray: Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, apply the stock np.asfortranarray function otherwise.
  • ascontiguousarray: Perform an in-place matrix transposition for rectangular arrays if memory is contiguous, apply the stock np.ascontiguousarray function otherwise.
  • minmax: Compute the min and max of an array in one pass.
  • pixel_pairs: Computes the number of adjacent matching memory locations in an image. A quick heuristic for understanding if the image statistics are roughly similar to a connectomics segmentation.
  • foreground: Count the number of non-zero voxels rapidly.
  • point_cloud: Get the X,Y,Z locations of each foreground voxel grouped by label.
  • tobytes: Compute the tobytes of an image divided into a grid and return the resultant binaries indexed by their gridpoint in fortran order with the binary in the order requested (C or F).

pip Installation

bash pip install fastremap

If not, a C++ compiler is required.

bash pip install numpy pip install fastremap --no-binary :all:

Manual Installation

A C++ compiler is required.

```bash sudo apt-get install g++ python3-dev mkvirtualenv -p python3 fastremap pip install numpy

Choose one:

python setup.py develop
python setup.py install ```

The Problem of Remapping

Python loops are slow, so Numpy is often used to perform remapping on large arrays (hundreds of megabytes or gigabytes). In order to efficiently remap an array in Numpy you need a key-value array where the index is the key and the value is the contents of that index.

```python import numpy as np

original = np.array([ 1, 3, 5, 5, 10 ]) remap = np.array([ 0, -5, 0, 6, 0, 0, 2, 0, 0, 0, -100 ])

Keys: 0 1 2 3 4 5 6 7 8 9 10

remapped = remap[ original ]

[ -5, 6, 2, 2, -100 ] ```

If there are 32 or 64 bit labels in the array, this becomes impractical as the size of the array can grow larger than RAM. Therefore, it would be helpful to be able to perform this mapping using a C speed loop. Numba can be used for this in some circumstances. However, this library provides an alternative.

```python import numpy as np import fastremap

mappings = { 1: 100, 2: 200, -3: 7, }

arr = np.array([5, 1, 2, -5, -3, 10, 6])

Custom remapping of -3, 5, and 6 leaving the rest alone

arr = fastremap.remap(arr, mappings, preservemissinglabels=True)

result: [ 5, 100, 200, -5, 7, 10, 6 ]

```

The Problem of Renumbering

Sometimes a 64-bit array contains values that could be represented by an 8-bit array. However, similarly to the remapping problem, Python loops can be too slow to do this. Numpy doesn't provide a convenient way to do it either. Therefore this library provides an alternative solution.

```python import fastremap import numpy as np

arr = np.array([ 283732875, 439238823, 283732875, 182812404, 0 ], dtype=np.int64)

arr, remapping = fastremap.renumber(arr, preserve_zero=True) # Returns uint8 array

arr = [ 1, 2, 1, 3, 0 ] remapping = { 0: 0, 283732875: 1, 439238823: 2, 182812404: 3 }

arr, remapping = fastremap.renumber(arr, preserve_zero=False) # Returns uint8 array

arr = [ 1, 2, 1, 3, 4 ] remapping = { 0: 4, 283732875: 1, 439238823: 2, 182812404: 3 }

arr, remapping = fastremap.renumber(arr, preservezero=False, inplace=True) # Mutate arr to use less memory

arr = [ 1, 2, 1, 3, 4 ] remapping = { 0: 4, 283732875: 1, 439238823: 2, 182812404: 3 } ```

The Problem of In-Place Transposition

When transitioning between different media, e.g. CPU to GPU, CPU to Network, CPU to disk, it's often necessary to physically transpose multi-dimensional arrays to reformat as C or Fortran order. Tranposing matrices is also a common action in linear algebra, but often you can get away with just changing the strides.

An out-of-place transposition is easy to write, and often faster, but it will spike peak memory consumption. This library grants the user the option of performing an in-place transposition which trades CPU time for peak memory usage. In the special case of square or cubic arrays, the in-place transpisition is both lower memory and faster.

  • fastremap.asfortranarray: Same as np.asfortranarray but will perform the transposition in-place for 1, 2, 3, and 4D arrays. 2D and 3D square matrices are faster to process than with Numpy.
  • fastremap.ascontiguousarray: Same as np.ascontiguousarray but will perform the transposition in-place for 1, 2, 3, and 4D arrays. 2D and 3D square matrices are faster to process than with Numpy.

```python import fastremap import numpy as np

arr = np.ones((512,512,512), dtype=np.float32) arr = fastremap.asfortranarray(x)

arr = np.ones((512,512,512), dtype=np.float32, order='F') arr = fastremap.ascontiguousarray(x) ```

C++ Usage

The in-place matrix transposition is implemented in ipt.hpp. If you're working in C++, you can also use it directly like so:

```cpp

include "ipt.hpp"

int main() {

int sx = 128; int sy = 124; int sz = 103; int sw = 3;

auto* arr = ....;

// All primitive number types supported // The array will be modified in place, // so these functions are void type. ipt::ipt(arr, sx, sy); // 2D ipt::ipt(arr, sx, sy, sz); // 3D ipt::ipt(arr, sx, sy, sz, sw); // 4D

return 0; } ```

--
Made with <3

Owner

  • Name: seung-lab
  • Login: seung-lab
  • Kind: organization

GitHub Events

Total
  • Issues event: 9
  • Watch event: 13
  • Delete event: 6
  • Issue comment event: 14
  • Push event: 20
  • Pull request review event: 7
  • Pull request review comment event: 4
  • Pull request event: 5
  • Fork event: 1
  • Create event: 13
Last Year
  • Issues event: 9
  • Watch event: 13
  • Delete event: 6
  • Issue comment event: 14
  • Push event: 20
  • Pull request review event: 7
  • Pull request review comment event: 4
  • Pull request event: 5
  • Fork event: 1
  • Create event: 13

Committers

Last synced: 11 months ago

All Time
  • Total Commits: 156
  • Total Committers: 4
  • Avg Commits per committer: 39.0
  • Development Distribution Score (DDS): 0.019
Past Year
  • Commits: 24
  • Committers: 2
  • Avg Commits per committer: 12.0
  • Development Distribution Score (DDS): 0.042
Top Committers
Name Email Commits
William Silversmith w****h@g****m 153
Max m****1 1
Andreas Schwab s****b@l****g 1
William Silversmith w****h@g****m 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 21
  • Total pull requests: 27
  • Average time to close issues: about 1 month
  • Average time to close pull requests: 20 days
  • Total issue authors: 15
  • Total pull request authors: 5
  • Average comments per issue: 3.62
  • Average comments per pull request: 0.78
  • Merged pull requests: 24
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 5
  • Pull requests: 3
  • Average time to close issues: about 12 hours
  • Average time to close pull requests: 6 days
  • Issue authors: 3
  • Pull request authors: 1
  • Average comments per issue: 3.2
  • Average comments per pull request: 1.67
  • Merged pull requests: 3
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • MattTheCuber (3)
  • william-silversmith (3)
  • selvakarna (3)
  • davidackerman (2)
  • psobolewskiPhD (1)
  • denvercal1234GitHub (1)
  • normanrz (1)
  • stuarteberg (1)
  • sdorkenw (1)
  • ceesem (1)
  • jingpengw (1)
  • ivonindima (1)
  • carsen-stringer (1)
  • jbms (1)
  • manuel-castro (1)
Pull Request Authors
  • william-silversmith (21)
  • MattTheCuber (5)
  • normanrz (2)
  • andreas-schwab (1)
  • maxme1 (1)
Top Labels
Issue Labels
bug (5) enhancement (4) question (3) installation (1)
Pull Request Labels
enhancement (20) bug (3) installation (1) refactor (1)

Packages

  • Total packages: 2
  • Total downloads:
    • pypi 62,878 last-month
  • Total docker downloads: 232,479
  • Total dependent packages: 24
    (may contain duplicates)
  • Total dependent repositories: 64
    (may contain duplicates)
  • Total versions: 51
  • Total maintainers: 1
pypi.org: fastremap

Remap, mask, renumber, unique, and in-place transposition of 3D labeled images. Point cloud too.

  • Versions: 48
  • Dependent Packages: 23
  • Dependent Repositories: 63
  • Downloads: 62,878 Last month
  • Docker Downloads: 232,479
Rankings
Dependent packages count: 0.7%
Docker downloads count: 1.4%
Downloads: 1.8%
Dependent repos count: 1.9%
Average: 5.3%
Stargazers count: 10.6%
Forks count: 15.4%
Maintainers (1)
Last synced: 6 months ago
conda-forge.org: fastremap
  • Versions: 3
  • Dependent Packages: 1
  • Dependent Repositories: 1
Rankings
Dependent repos count: 24.4%
Dependent packages count: 29.0%
Average: 38.2%
Stargazers count: 45.1%
Forks count: 54.2%
Last synced: 6 months ago

Dependencies

.github/workflows/build_wheel.yml actions
  • actions/checkout v2 composite
  • actions/upload-artifact v2 composite
  • docker/setup-qemu-action v1 composite
  • joerick/cibuildwheel v2.3.1 composite
requirements.txt pypi
  • numpy *
requirements_dev.txt pypi
  • cython * development
  • pytest * development
  • tox * development
  • twine * development