crackle-codec


Namecrackle-codec JSON
Version 0.15.0 PyPI version JSON
download
home_pagehttps://github.com/seung-lab/crackle
SummaryCrackle 3D dense segmentation compression codec.
upload_time2024-07-26 07:37:09
maintainerNone
docs_urlNone
authorWilliam Silversmith
requires_pythonNone
licenseLicense :: OSI Approved :: BSD License
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![PyPI version](https://badge.fury.io/py/crackle-codec.svg)](https://badge.fury.io/py/crackle-codec)

# Crackle: Next gen. 3D segmentation compression codec.

```bash
# Command Line Interface
crackle data.npy # creates data.ckl
crackle -m 5 data.npy # use a 5th order context model
crackle -d data.ckl # recovers data.npy
```

```python
import crackle
import numpy

labels = np.load("example.npy") # a 2D or 3D dense segmentation

binary = crackle.compress(labels, allow_pins=False, markov_model_order=0)
labels = crackle.decompress(binary)

# faster extraction of binary images
binary_image = crackle.decompress(binary, label=1241)

# get unique labels without decompressing
uniq = crackle.labels(binary) 
# get num labels without decompressing
N = crackle.num_labels(binary) 
# get min and max without decompressing
mn = crackle.min(binary)
mx = crackle.max(binary)
# check if label in array in log(N) time
has_label = crackle.contains(binary, label)

# Remap labels without decompressing. Could
# be useful for e.g. proofreading.
remapped = crackle.remap(
  binary, { 1: 2, 2: 3, ... },
  preserve_missing_labels=True
)

# change dtype to smallest possible w/o precision loss
remapped = crackle.refit(binary)
# renumber array and change dtype to smallest possible
remapped = crackle.renumber(binary, start=0)

# for working with files
# if .gz is appended to the filename, the file will be
# automatically gzipped (or ungzipped)
crackle.save(labels, "example.ckl.gz")
labels = crackle.load("example.ckl.gz")

# Save a crackle array as a numpy array
# in a memory efficient manner.
crackle.save(binary, "example.npy.gz")

arr = crackle.CrackleArray(binary)
res = arr[:10,:10,:10] # array slicing (efficient z ranges)
arr[:,:,30] = 20 # write to a crackle array (whole z slices write faster)
20 in arr # log(N) check
arr = arr.numpy() # convert to a numpy array

# building big arrays with low memory
binary = crackle.zeros([5000,5000,5000], dtype=np.uint64, order='F')

part1 = np.zeros([1000, 1000, 1000], dtype=np.uint32)
part2 = crackle.ones([1000, 1000, 1000], dtype=np.uint32)

binary = crackle.asfortranarray(binary)
binary = crackle.ascontiguousarray(binary)

# creates a crackle binary with part1 stacked atop part2
# in the z dimension. x and y dimensions must match
# without needing to decompress anything.
binary = crackle.zstack([ part1, part2 ])

# splits a crackle binary into before, middle (single slice),
# and after sections without decompressing.
before, middle, after = crackle.zsplit(binary, z=742)
```

*This repository is currently Beta. It works and the format is reasonably fixed. There may be some improvements down the line (such as 3d compression of crack codes), but they will be a new format version number.*

Crackle is a compression codec for 3D dense segmentation (labeled) images. The algorithm accepts both signed and unsigned integer labels (though the implementation currently has some restrictions on signed integers). It is written in C++ and has Python bindings. Crackle uses a two pass compression strategy where the output of crackle may be further comrpessed with a bitstream compressor like gzip, bzip2, zstd, or lzma. However, if the Crackle binary, which is already small, is not further compressed, it supports several efficient operations:

- Query if a label exists in the image
- Extract unique labels
- Remap labels
- Decode by Z-Range

Crackle is inspired by Compresso \[1\]. Compresso innovated by separating labels from boundary structures. There were conceptually four (but really five) elements in the format: header, labels, bit packed and RLE encoded binary image boundaries, and indeterminate boundary locations. 

Crackle improves upon Compresso by replacing the bit-packed boundary map with a "crack code" and can also use 3D information to reduce redundancy in labels using "pins".

See benchmarks for more information on Crackle's size and compute effiency.

## Versions

| Major Version | Format Version | Description                                                    |
|---------------|----------------|----------------------------------------------------------------|
| 1             | 0              | Initial release w/ flat, pins, crack codes with finite context modeling. Beta. |


## Stream Format

| Section   | Bytes                                     | Description                                                                                                     |
|-----------|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------|
| Header    | 24                                        | Metadata incl. length of fields.                                                                                |
| Crack Index     | header.sz * sizeof(uint32)             | Number of bytes for the crack codes in each slice.
| Labels       | header.num_label_bytes        | Can be either "flat" labels or "pins". Describes how to color connected components.                                                                                   |
| Crack Codes    | Variable length.           | Instructions for drawing crack boundaries.             |

### Header


| Attribute         | Value             | Type    | Description                                     |
|-------------------|-------------------|---------|-------------------------------------------------|
| magic             | crkl              | char[4] | File magic number.                              |
| format_version    | 0                 | u8      | Stream version.                   |
| format_field      | bitfield          | u16     | See below.                 |
| sx, sy, sz        | >= 0              | u32 x 3 | Size of array dimensions.                       |
| grid_size         | log2(grid_size)   | u8      | Stores log2 of grid dimensions in voxels.          |
| num_label_bytes   | Any.              | u32      | Number of bytes of the labels section. Note the labels come in at least two format types.          |


Format Field (u16): DDSSCLLFGOOOOURR (each letter represents a bit, left is LSB)

DD: 2^(DD) = byte width of returned array (1,2,4,8 bytes)  
SS: 2^(SS) = byte width of stored labels (sometimes you can store values in 2 bytes when the final array is 8 bytes)  
C: 1: crack codes denote impermissible boundaries 0: they denote permissible boundaries.  
LL: 0: "flat" label format, 1: fixed width pins (unused?) 2: variable width pins 3: reserved  
F: whether the array is to be rendered as C (0) or F (1) order
G: Signed (if (1), data are signed int, otherwise unsigned int)
OOOO: Nth-Order of Markov Chain (as an unsigned integer, typical values 0, or 3 to 7). If 0, markov compression is disabled.
U: if 0, unique labels are sorted, else, unsorted
R: Reserved

### Flat Label Format

| Attribute     | Type                                        | Description                                                                                                 |
|---------------|---------------------------------------------|-------------------------------------------------------------------------------------------------------------|
| num_unique    | u64                                         | Number of unique labels in this volume.                                                                     |
| unique_labels | stored_type[num_unique]                     | Sorted ascending array of all unique values in image, stored in the smallest data type that will hold them. |
| cc_per_grid   | smallest_type(sx \* sy)[sz]                 | Array containing the number of CCL IDs in each grid (usually a z-slice).                                    |
| cc_to_labels  | smallest_type(num_labels)[sum(cc_per_grid)] | Array mapping CCL IDs to their proper value by indexing the unique labels array.                            |

Flat labels are random access read, allow efficient reading of unique labels, efficient remapping, and efficient search for a given label's existence. Since the connected component labels can often use a smaller byte width than the unique values, even noise arrays can see some value from compression.

Encoding flat labels is fast.

### Condensed (Variable Width) Pins Label Format

| Attribute        | Type                                | Description                                                                                                 |
|------------------|-------------------------------------|-------------------------------------------------------------------------------------------------------------|
| background_color | stored_data_width                   | Background color of image.                                                                                  |
| num_unique       | u64                                 | Number of unique labels in this volume.                                                                     |
| unique_labels    | stored_type[num_unique]             | Sorted ascending array of all unique values in image, stored in the smallest data type that will hold them. |
| cc_per_grid   | smallest_type(sx \* sy)[sz]                 | Array containing the number of CCL IDs in each grid (usually a z-slice).                                    |
| fmt_byte         | u8                                  | 00CCDDNN  DD: 2^(DD) is the depth width NN: 2^(NN) is the num pins width, CC: 2^(CC) is the single components width.  |
| pin_section      | Bitstream to end of labels section. | Contains pin information.                                                                                   |

PIN SECTION: `| PINS FOR LABEL 0 | PINS FOR LABEL 1 | ... | PINS FOR LABEL N |`

PINS: `| num_pins | INDEX_0 | INDEX_1 | ... | INDEX_N | DEPTH_0 | DEPTH_1 | ... | DEPTH_N | num_single_labels | CC 0 | CC 1 | ... | CC N |`

Both `num_pins` and `num_single_labels` use the `num_pins_width`.

Note that INDEX_0 to INDEX_N are stored with a difference filter applied to improve compressibility.

A pin (color, position, depth) is a line segment that joins together multiple connected component IDs and labels them with a color (an index into UNIQUE LABELS) in order to use 3D information to compress the labels as compared with the flat label format. Pins are slow to compute but fast to decode, however random access is lost (a full scan of the labels section is needed to decode a subset of crack codes). The most frequent pin is replaced with a background color. Like with flat, efficient reading of unique labels, efficient remapping, and search are supported. 

Depending on the image statistics and quality of the pin solver, pins can be much smaller than flat or larger (some heuristics are used to avoid this case). An excellent example of where pins do well is a binary image where remarkable savings can be achieved in the labels section (though overall it is probably a small part of the file).

For very short pins (e.g. depth 0 or 1) that take more bytes to record than simply listing the corresponding CC label, we list the CC label instead. This calculation is made depending on the dimensions of the image and the max pin depth, and the byte width of the CCL labels.

Example calculation. For a 512 x 512 x 32 file with an average of 1000 CCL's per a slice and a maximum pin depth of 30, a pin takes 4 index + 1 depth = 5 bytes while a CCL takes 2 bytes. Therefore, depth 1 and 2 pins can be efficiently replaced with 1 and 2 CCL labels for a 60\% and 20\% savings respectively. CCLs are also difference coded to enhance second stage compressibility.

### Fixed Width Pins (disabled)

`| BACKGROUND COLOR (STORED_DATA_WIDTH) | NUM_LABELS (u64) | UNIQUE LABELS (NUM_LABELS \* STORED_DATA_WIDTH) | PIN SECTION |`

PIN SECTION: `|PIN0|PIN1|PIN2|...|PINN|`
PIN: `|LABEL|INDEX|DEPTH|`

A fixed width variant of pins has also been developed but is not enabled. It frequently is not significantly smaller than flat outside of special circumstances such as a binary image. An advantage this format would have over condensed is that the pins can be sorted and searched rapidly by index, which reduces the amount of reading one might have to do on an mmapped file. Please raise an issue if this seems like something that might be useful to you.

### Crack Code Format

CRACK CODE: `MARKOV MODEL | CHAIN 0 | CHAIN 1 | ... | CHAIN N |`

CHAIN: `| BEGINNING OF CHAIN INDEX (sizeof(sx * sy)) | BIT PACKED MOVES (2 bits each) |`

MARKOV MODEL (if enabled): `priority order of moves UDLR packed per a byte`. 4^order bytes.

The BEGINNING OF CHAIN INDEX (BOC) locates the grid vertex where the crack code will begin. Vertices are the corners of the pixel grid, with 0 at the top left and sx\*sy-1 at the bottom right (fortran order). 

The crack code is a NEWS code (up,right,left,down). Impossible combinations of directions are used to signal branching and branch termination. The next chain begins in the next byte when a termination signal causes the current branch count to reach zero.

There may be ways to further improve the design of the crack code. For example, by applying a difference filter a few more percent compression under gzip can be obtained. In the literature, there are other shorter codes such as a left,right,straight (LRS) code and fancy large context compressors that can achieve fewer than one bit per a move.

## Boundary Structure: Crack Code

Our different approach is partially inspired by the work of Zingaretti et al. \[2\]. We represent the boundary not by border voxels, but by a "crack code" that represents the edges between voxels. This code can be thought of as directions to draw edges on a graph where the vertices are where the corners of four pixels touch and the edges are the cracks in between them. 

Since this regular graph is 4-connected, each "move" in a cardinal direction can be described using two bits. To represent special symbols such as "branch" and "terminate", an impossible set of instructions on an undirected graph such as "left-right" or "up-down" can be used (occupying 4 bits). In order to avoid creating palendromic sequences such as (3, 0, 3) meaning (down, branch) but can be read (terminate, down), we can use the left-right impossible directions to rewrite it as (3, 2, 1).

While the image is 3D, we treat the image in layers because working in 3D introduces a large increase in geometric complexity (a cube has 6 faces, 12 edges, and 8 corners while a square has 4 edges and 4 corners). This increase in complexity would inflate the size of the crack code and make the implementation more difficult.

## Label Map: Method of Pins

Each 2D CCL region must has a label assigned. Due to the 2D nature of the crack code, we cannot use 3D CCL. However, for example, a solid cube of height 100 would need 100 labels to represent the same color on every slice as in Compresso.

It is still possible to reduce the amount of redundant information even without 3D CCL. For each label, we find a set of vertical line segments ("pins") that fully cover the label's 2D CCL regions. Sharp readers may note that this is the NP-hard set cover problem.

Once a reasonably small or minimal set of pins are found, they can be encoded in two forms:

Condensed Form: `[label][num_pins][pin_1][pin_2]...[pin_N]`
Fixed Width Form: `[label][pin_1][label][pin_2]...[label][pin_N]`
Pin Format: `[linear index of pin top][number of voxels to bottom]`

Fixed width example with label 1 with a pin between (1,1,1) and (1,1,5) on a 10x10x10 image: `[1][111][4]`

An alternative formulation `[label][idx1][idx2]` was shown in an experiment on `connectomics.npy.cpso` to compress slightly worse than Compresso labels. However, this alternative formulation theoretically allows arbitrary pin orientations and so might be useful for reducing the overall number of pins.

The condensed format is a bit smaller than the fixed width format, but the fixed width format enables rapid searches if the set of pins are sorted by either the label (enables fast `label in file`) or the likely more useful sorting by top index to filter candidate pins when performing random access to a z-slice.

## References

1. Matejek, B., Haehn, D., Lekschas, F., Mitzenmacher, M., Pfister, H., 2017. Compresso: Efficient Compression of Segmentation Data for Connectomics, in: Descoteaux, M., Maier-Hein, L., Franz, A., Jannin, P., Collins, D.L., Duchesne, S. (Eds.), Medical Image Computing and Computer Assisted Intervention − MICCAI 2017, Lecture Notes in Computer Science. Springer International Publishing, Cham, pp. 781–788. https://doi.org/10.1007/978-3-319-66182-7_89

2. Zingaretti, P., Gasparroni, M., Vecci, L., 1998. Fast chain coding of region boundaries. IEEE Transactions on Pattern Analysis and Machine Intelligence 20, 407–415. https://doi.org/10.1109/34.677272

3. Freeman, H., 1974. Computer Processing of Line-Drawing Images. ACM Comput. Surv. 6, 57–97. https://doi.org/10.1145/356625.356627


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/seung-lab/crackle",
    "name": "crackle-codec",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": null,
    "author": "William Silversmith",
    "author_email": "ws9@princeton.edu",
    "download_url": "https://files.pythonhosted.org/packages/52/2e/b9cdf856a5623d107cedc09d7c776b058ba9328fcc29288e75d43f2ce3cd/crackle-codec-0.15.0.tar.gz",
    "platform": null,
    "description": "[![PyPI version](https://badge.fury.io/py/crackle-codec.svg)](https://badge.fury.io/py/crackle-codec)\n\n# Crackle: Next gen. 3D segmentation compression codec.\n\n```bash\n# Command Line Interface\ncrackle data.npy # creates data.ckl\ncrackle -m 5 data.npy # use a 5th order context model\ncrackle -d data.ckl # recovers data.npy\n```\n\n```python\nimport crackle\nimport numpy\n\nlabels = np.load(\"example.npy\") # a 2D or 3D dense segmentation\n\nbinary = crackle.compress(labels, allow_pins=False, markov_model_order=0)\nlabels = crackle.decompress(binary)\n\n# faster extraction of binary images\nbinary_image = crackle.decompress(binary, label=1241)\n\n# get unique labels without decompressing\nuniq = crackle.labels(binary) \n# get num labels without decompressing\nN = crackle.num_labels(binary) \n# get min and max without decompressing\nmn = crackle.min(binary)\nmx = crackle.max(binary)\n# check if label in array in log(N) time\nhas_label = crackle.contains(binary, label)\n\n# Remap labels without decompressing. Could\n# be useful for e.g. proofreading.\nremapped = crackle.remap(\n  binary, { 1: 2, 2: 3, ... },\n  preserve_missing_labels=True\n)\n\n# change dtype to smallest possible w/o precision loss\nremapped = crackle.refit(binary)\n# renumber array and change dtype to smallest possible\nremapped = crackle.renumber(binary, start=0)\n\n# for working with files\n# if .gz is appended to the filename, the file will be\n# automatically gzipped (or ungzipped)\ncrackle.save(labels, \"example.ckl.gz\")\nlabels = crackle.load(\"example.ckl.gz\")\n\n# Save a crackle array as a numpy array\n# in a memory efficient manner.\ncrackle.save(binary, \"example.npy.gz\")\n\narr = crackle.CrackleArray(binary)\nres = arr[:10,:10,:10] # array slicing (efficient z ranges)\narr[:,:,30] = 20 # write to a crackle array (whole z slices write faster)\n20 in arr # log(N) check\narr = arr.numpy() # convert to a numpy array\n\n# building big arrays with low memory\nbinary = crackle.zeros([5000,5000,5000], dtype=np.uint64, order='F')\n\npart1 = np.zeros([1000, 1000, 1000], dtype=np.uint32)\npart2 = crackle.ones([1000, 1000, 1000], dtype=np.uint32)\n\nbinary = crackle.asfortranarray(binary)\nbinary = crackle.ascontiguousarray(binary)\n\n# creates a crackle binary with part1 stacked atop part2\n# in the z dimension. x and y dimensions must match\n# without needing to decompress anything.\nbinary = crackle.zstack([ part1, part2 ])\n\n# splits a crackle binary into before, middle (single slice),\n# and after sections without decompressing.\nbefore, middle, after = crackle.zsplit(binary, z=742)\n```\n\n*This repository is currently Beta. It works and the format is reasonably fixed. There may be some improvements down the line (such as 3d compression of crack codes), but they will be a new format version number.*\n\nCrackle is a compression codec for 3D dense segmentation (labeled) images. The algorithm accepts both signed and unsigned integer labels (though the implementation currently has some restrictions on signed integers). It is written in C++ and has Python bindings. Crackle uses a two pass compression strategy where the output of crackle may be further comrpessed with a bitstream compressor like gzip, bzip2, zstd, or lzma. However, if the Crackle binary, which is already small, is not further compressed, it supports several efficient operations:\n\n- Query if a label exists in the image\n- Extract unique labels\n- Remap labels\n- Decode by Z-Range\n\nCrackle is inspired by Compresso \\[1\\]. Compresso innovated by separating labels from boundary structures. There were conceptually four (but really five) elements in the format: header, labels, bit packed and RLE encoded binary image boundaries, and indeterminate boundary locations. \n\nCrackle improves upon Compresso by replacing the bit-packed boundary map with a \"crack code\" and can also use 3D information to reduce redundancy in labels using \"pins\".\n\nSee benchmarks for more information on Crackle's size and compute effiency.\n\n## Versions\n\n| Major Version | Format Version | Description                                                    |\n|---------------|----------------|----------------------------------------------------------------|\n| 1             | 0              | Initial release w/ flat, pins, crack codes with finite context modeling. Beta. |\n\n\n## Stream Format\n\n| Section   | Bytes                                     | Description                                                                                                     |\n|-----------|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------|\n| Header    | 24                                        | Metadata incl. length of fields.                                                                                |\n| Crack Index     | header.sz * sizeof(uint32)             | Number of bytes for the crack codes in each slice.\n| Labels       | header.num_label_bytes        | Can be either \"flat\" labels or \"pins\". Describes how to color connected components.                                                                                   |\n| Crack Codes    | Variable length.           | Instructions for drawing crack boundaries.             |\n\n### Header\n\n\n| Attribute         | Value             | Type    | Description                                     |\n|-------------------|-------------------|---------|-------------------------------------------------|\n| magic             | crkl              | char[4] | File magic number.                              |\n| format_version    | 0                 | u8      | Stream version.                   |\n| format_field      | bitfield          | u16     | See below.                 |\n| sx, sy, sz        | >= 0              | u32 x 3 | Size of array dimensions.                       |\n| grid_size         | log2(grid_size)   | u8      | Stores log2 of grid dimensions in voxels.          |\n| num_label_bytes   | Any.              | u32      | Number of bytes of the labels section. Note the labels come in at least two format types.          |\n\n\nFormat Field (u16): DDSSCLLFGOOOOURR (each letter represents a bit, left is LSB)\n\nDD: 2^(DD) = byte width of returned array (1,2,4,8 bytes)  \nSS: 2^(SS) = byte width of stored labels (sometimes you can store values in 2 bytes when the final array is 8 bytes)  \nC: 1: crack codes denote impermissible boundaries 0: they denote permissible boundaries.  \nLL: 0: \"flat\" label format, 1: fixed width pins (unused?) 2: variable width pins 3: reserved  \nF: whether the array is to be rendered as C (0) or F (1) order\nG: Signed (if (1), data are signed int, otherwise unsigned int)\nOOOO: Nth-Order of Markov Chain (as an unsigned integer, typical values 0, or 3 to 7). If 0, markov compression is disabled.\nU: if 0, unique labels are sorted, else, unsorted\nR: Reserved\n\n### Flat Label Format\n\n| Attribute     | Type                                        | Description                                                                                                 |\n|---------------|---------------------------------------------|-------------------------------------------------------------------------------------------------------------|\n| num_unique    | u64                                         | Number of unique labels in this volume.                                                                     |\n| unique_labels | stored_type[num_unique]                     | Sorted ascending array of all unique values in image, stored in the smallest data type that will hold them. |\n| cc_per_grid   | smallest_type(sx \\* sy)[sz]                 | Array containing the number of CCL IDs in each grid (usually a z-slice).                                    |\n| cc_to_labels  | smallest_type(num_labels)[sum(cc_per_grid)] | Array mapping CCL IDs to their proper value by indexing the unique labels array.                            |\n\nFlat labels are random access read, allow efficient reading of unique labels, efficient remapping, and efficient search for a given label's existence. Since the connected component labels can often use a smaller byte width than the unique values, even noise arrays can see some value from compression.\n\nEncoding flat labels is fast.\n\n### Condensed (Variable Width) Pins Label Format\n\n| Attribute        | Type                                | Description                                                                                                 |\n|------------------|-------------------------------------|-------------------------------------------------------------------------------------------------------------|\n| background_color | stored_data_width                   | Background color of image.                                                                                  |\n| num_unique       | u64                                 | Number of unique labels in this volume.                                                                     |\n| unique_labels    | stored_type[num_unique]             | Sorted ascending array of all unique values in image, stored in the smallest data type that will hold them. |\n| cc_per_grid   | smallest_type(sx \\* sy)[sz]                 | Array containing the number of CCL IDs in each grid (usually a z-slice).                                    |\n| fmt_byte         | u8                                  | 00CCDDNN  DD: 2^(DD) is the depth width NN: 2^(NN) is the num pins width, CC: 2^(CC) is the single components width.  |\n| pin_section      | Bitstream to end of labels section. | Contains pin information.                                                                                   |\n\nPIN SECTION: `| PINS FOR LABEL 0 | PINS FOR LABEL 1 | ... | PINS FOR LABEL N |`\n\nPINS: `| num_pins | INDEX_0 | INDEX_1 | ... | INDEX_N | DEPTH_0 | DEPTH_1 | ... | DEPTH_N | num_single_labels | CC 0 | CC 1 | ... | CC N |`\n\nBoth `num_pins` and `num_single_labels` use the `num_pins_width`.\n\nNote that INDEX_0 to INDEX_N are stored with a difference filter applied to improve compressibility.\n\nA pin (color, position, depth) is a line segment that joins together multiple connected component IDs and labels them with a color (an index into UNIQUE LABELS) in order to use 3D information to compress the labels as compared with the flat label format. Pins are slow to compute but fast to decode, however random access is lost (a full scan of the labels section is needed to decode a subset of crack codes). The most frequent pin is replaced with a background color. Like with flat, efficient reading of unique labels, efficient remapping, and search are supported. \n\nDepending on the image statistics and quality of the pin solver, pins can be much smaller than flat or larger (some heuristics are used to avoid this case). An excellent example of where pins do well is a binary image where remarkable savings can be achieved in the labels section (though overall it is probably a small part of the file).\n\nFor very short pins (e.g. depth 0 or 1) that take more bytes to record than simply listing the corresponding CC label, we list the CC label instead. This calculation is made depending on the dimensions of the image and the max pin depth, and the byte width of the CCL labels.\n\nExample calculation. For a 512 x 512 x 32 file with an average of 1000 CCL's per a slice and a maximum pin depth of 30, a pin takes 4 index + 1 depth = 5 bytes while a CCL takes 2 bytes. Therefore, depth 1 and 2 pins can be efficiently replaced with 1 and 2 CCL labels for a 60\\% and 20\\% savings respectively. CCLs are also difference coded to enhance second stage compressibility.\n\n### Fixed Width Pins (disabled)\n\n`| BACKGROUND COLOR (STORED_DATA_WIDTH) | NUM_LABELS (u64) | UNIQUE LABELS (NUM_LABELS \\* STORED_DATA_WIDTH) | PIN SECTION |`\n\nPIN SECTION: `|PIN0|PIN1|PIN2|...|PINN|`\nPIN: `|LABEL|INDEX|DEPTH|`\n\nA fixed width variant of pins has also been developed but is not enabled. It frequently is not significantly smaller than flat outside of special circumstances such as a binary image. An advantage this format would have over condensed is that the pins can be sorted and searched rapidly by index, which reduces the amount of reading one might have to do on an mmapped file. Please raise an issue if this seems like something that might be useful to you.\n\n### Crack Code Format\n\nCRACK CODE: `MARKOV MODEL | CHAIN 0 | CHAIN 1 | ... | CHAIN N |`\n\nCHAIN: `| BEGINNING OF CHAIN INDEX (sizeof(sx * sy)) | BIT PACKED MOVES (2 bits each) |`\n\nMARKOV MODEL (if enabled): `priority order of moves UDLR packed per a byte`. 4^order bytes.\n\nThe BEGINNING OF CHAIN INDEX (BOC) locates the grid vertex where the crack code will begin. Vertices are the corners of the pixel grid, with 0 at the top left and sx\\*sy-1 at the bottom right (fortran order). \n\nThe crack code is a NEWS code (up,right,left,down). Impossible combinations of directions are used to signal branching and branch termination. The next chain begins in the next byte when a termination signal causes the current branch count to reach zero.\n\nThere may be ways to further improve the design of the crack code. For example, by applying a difference filter a few more percent compression under gzip can be obtained. In the literature, there are other shorter codes such as a left,right,straight (LRS) code and fancy large context compressors that can achieve fewer than one bit per a move.\n\n## Boundary Structure: Crack Code\n\nOur different approach is partially inspired by the work of Zingaretti et al. \\[2\\]. We represent the boundary not by border voxels, but by a \"crack code\" that represents the edges between voxels. This code can be thought of as directions to draw edges on a graph where the vertices are where the corners of four pixels touch and the edges are the cracks in between them. \n\nSince this regular graph is 4-connected, each \"move\" in a cardinal direction can be described using two bits. To represent special symbols such as \"branch\" and \"terminate\", an impossible set of instructions on an undirected graph such as \"left-right\" or \"up-down\" can be used (occupying 4 bits). In order to avoid creating palendromic sequences such as (3, 0, 3) meaning (down, branch) but can be read (terminate, down), we can use the left-right impossible directions to rewrite it as (3, 2, 1).\n\nWhile the image is 3D, we treat the image in layers because working in 3D introduces a large increase in geometric complexity (a cube has 6 faces, 12 edges, and 8 corners while a square has 4 edges and 4 corners). This increase in complexity would inflate the size of the crack code and make the implementation more difficult.\n\n## Label Map: Method of Pins\n\nEach 2D CCL region must has a label assigned. Due to the 2D nature of the crack code, we cannot use 3D CCL. However, for example, a solid cube of height 100 would need 100 labels to represent the same color on every slice as in Compresso.\n\nIt is still possible to reduce the amount of redundant information even without 3D CCL. For each label, we find a set of vertical line segments (\"pins\") that fully cover the label's 2D CCL regions. Sharp readers may note that this is the NP-hard set cover problem.\n\nOnce a reasonably small or minimal set of pins are found, they can be encoded in two forms:\n\nCondensed Form: `[label][num_pins][pin_1][pin_2]...[pin_N]`\nFixed Width Form: `[label][pin_1][label][pin_2]...[label][pin_N]`\nPin Format: `[linear index of pin top][number of voxels to bottom]`\n\nFixed width example with label 1 with a pin between (1,1,1) and (1,1,5) on a 10x10x10 image: `[1][111][4]`\n\nAn alternative formulation `[label][idx1][idx2]` was shown in an experiment on `connectomics.npy.cpso` to compress slightly worse than Compresso labels. However, this alternative formulation theoretically allows arbitrary pin orientations and so might be useful for reducing the overall number of pins.\n\nThe condensed format is a bit smaller than the fixed width format, but the fixed width format enables rapid searches if the set of pins are sorted by either the label (enables fast `label in file`) or the likely more useful sorting by top index to filter candidate pins when performing random access to a z-slice.\n\n## References\n\n1. Matejek, B., Haehn, D., Lekschas, F., Mitzenmacher, M., Pfister, H., 2017. Compresso: Efficient Compression of Segmentation Data for Connectomics, in: Descoteaux, M., Maier-Hein, L., Franz, A., Jannin, P., Collins, D.L., Duchesne, S. (Eds.), Medical Image Computing and Computer Assisted Intervention \u2212 MICCAI 2017, Lecture Notes in Computer Science. Springer International Publishing, Cham, pp. 781\u2013788. https://doi.org/10.1007/978-3-319-66182-7_89\n\n2. Zingaretti, P., Gasparroni, M., Vecci, L., 1998. Fast chain coding of region boundaries. IEEE Transactions on Pattern Analysis and Machine Intelligence 20, 407\u2013415. https://doi.org/10.1109/34.677272\n\n3. Freeman, H., 1974. Computer Processing of Line-Drawing Images. ACM Comput. Surv. 6, 57\u201397. https://doi.org/10.1145/356625.356627\n\n",
    "bugtrack_url": null,
    "license": "License :: OSI Approved :: BSD License",
    "summary": "Crackle 3D dense segmentation compression codec.",
    "version": "0.15.0",
    "project_urls": {
        "Homepage": "https://github.com/seung-lab/crackle"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bec46e7762a8ef353423b81720c4ee5ca063894e5c55a7cd9d43ba0b4cbd2493",
                "md5": "26e0d43d016fab5bd9f6ceb37223b235",
                "sha256": "d2455c4920b2a5a3d3f6dfadf4027ce31ff847c015def7d44346fc36f6588d03"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp310-cp310-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "26e0d43d016fab5bd9f6ceb37223b235",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 366033,
            "upload_time": "2024-07-26T07:36:18",
            "upload_time_iso_8601": "2024-07-26T07:36:18.910061Z",
            "url": "https://files.pythonhosted.org/packages/be/c4/6e7762a8ef353423b81720c4ee5ca063894e5c55a7cd9d43ba0b4cbd2493/crackle_codec-0.15.0-cp310-cp310-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "53213476bfe82b649a739942f38ee84a3cbab1143b3a1f7932f834ab4f7b2f86",
                "md5": "a2abba60d401483712b466fe054d3407",
                "sha256": "7750bcc08bd63aea5f1d5c5a5c5f1ad5e5048e7ee2141499edad7eb9c8ee969c"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp310-cp310-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "a2abba60d401483712b466fe054d3407",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 297632,
            "upload_time": "2024-07-26T07:36:20",
            "upload_time_iso_8601": "2024-07-26T07:36:20.484118Z",
            "url": "https://files.pythonhosted.org/packages/53/21/3476bfe82b649a739942f38ee84a3cbab1143b3a1f7932f834ab4f7b2f86/crackle_codec-0.15.0-cp310-cp310-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d742f5a3072c831ada143f47a6beef9cd3fbe31eed9340df8fa8fd5494e65553",
                "md5": "323ed249ac7ee08521e34ce53f9547bc",
                "sha256": "f7bd5f6f047a76c44ae56f9eaa0e99e3de3c61ff4b05972a0e8d414fac559e30"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "323ed249ac7ee08521e34ce53f9547bc",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 334968,
            "upload_time": "2024-07-26T07:36:21",
            "upload_time_iso_8601": "2024-07-26T07:36:21.705218Z",
            "url": "https://files.pythonhosted.org/packages/d7/42/f5a3072c831ada143f47a6beef9cd3fbe31eed9340df8fa8fd5494e65553/crackle_codec-0.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "55dcbd7870f375723603dfe432d9fc8917f2bd937e6fc2c87ec8901fe083789b",
                "md5": "8713ae69c1f67f019d03591645531ef2",
                "sha256": "752b0ebbc4e126f5a2a170c4ed55582a7848257bdd3416c2bf421dac8a14bd30"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp310-cp310-win32.whl",
            "has_sig": false,
            "md5_digest": "8713ae69c1f67f019d03591645531ef2",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 219872,
            "upload_time": "2024-07-26T07:36:23",
            "upload_time_iso_8601": "2024-07-26T07:36:23.234722Z",
            "url": "https://files.pythonhosted.org/packages/55/dc/bd7870f375723603dfe432d9fc8917f2bd937e6fc2c87ec8901fe083789b/crackle_codec-0.15.0-cp310-cp310-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "37490126954c2c2a692864b51283cfa7762ab5eda39e5a0c24837d0fe819b212",
                "md5": "173a71cc31894c00533f1666853d34a1",
                "sha256": "906ceefd6e4cca9f357a8b6ded4ba82c1b86c8ad1ada7a67518ec99823d6a439"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "173a71cc31894c00533f1666853d34a1",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 217300,
            "upload_time": "2024-07-26T07:36:24",
            "upload_time_iso_8601": "2024-07-26T07:36:24.557410Z",
            "url": "https://files.pythonhosted.org/packages/37/49/0126954c2c2a692864b51283cfa7762ab5eda39e5a0c24837d0fe819b212/crackle_codec-0.15.0-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bcc6b65203891cdce327bab1ecbcacec0ecb659b278a2acaa6511a6bda9daf14",
                "md5": "e59d3674bebd9c05553f4ff73c737833",
                "sha256": "a63db42a5df8929ab5c46c1b089a2bab0de5a93156cf6a23fe1449800e763ab1"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp311-cp311-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "e59d3674bebd9c05553f4ff73c737833",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 367333,
            "upload_time": "2024-07-26T07:36:26",
            "upload_time_iso_8601": "2024-07-26T07:36:26.339662Z",
            "url": "https://files.pythonhosted.org/packages/bc/c6/b65203891cdce327bab1ecbcacec0ecb659b278a2acaa6511a6bda9daf14/crackle_codec-0.15.0-cp311-cp311-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fa64186b954a81111eac24824bce69f970487be8b05aa6c1dc130117fa774d6b",
                "md5": "9ae40727a0bbbf664fc7147537d5bd5d",
                "sha256": "023277192cc351f0b1ce89394c922b5f23efa69042a6d3b20739b292a1a88f6e"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp311-cp311-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "9ae40727a0bbbf664fc7147537d5bd5d",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 299174,
            "upload_time": "2024-07-26T07:36:27",
            "upload_time_iso_8601": "2024-07-26T07:36:27.952272Z",
            "url": "https://files.pythonhosted.org/packages/fa/64/186b954a81111eac24824bce69f970487be8b05aa6c1dc130117fa774d6b/crackle_codec-0.15.0-cp311-cp311-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "38013eebc5b3b81a777fdf9c57c2a545a58a1826f1abc2c85df2e29175ed332a",
                "md5": "e555a745befbd8aaa9503128768e4f8f",
                "sha256": "5cf00cb0385ad176296c222cfa322d4eb24249b30149a15019b6cdaf741ae4b6"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "e555a745befbd8aaa9503128768e4f8f",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 335799,
            "upload_time": "2024-07-26T07:36:29",
            "upload_time_iso_8601": "2024-07-26T07:36:29.403720Z",
            "url": "https://files.pythonhosted.org/packages/38/01/3eebc5b3b81a777fdf9c57c2a545a58a1826f1abc2c85df2e29175ed332a/crackle_codec-0.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3660f5c88065fa7e9c49c72b633e5424486cc1e2188f437631a6ce739bb6a855",
                "md5": "080ecd5670afa8329bfdbd147d003751",
                "sha256": "e5c58a060a2fc2562ab0c526ee3c855fe8c39e699a57ffd41c0d8638da2f92e5"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp311-cp311-win32.whl",
            "has_sig": false,
            "md5_digest": "080ecd5670afa8329bfdbd147d003751",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 220718,
            "upload_time": "2024-07-26T07:36:31",
            "upload_time_iso_8601": "2024-07-26T07:36:31.017908Z",
            "url": "https://files.pythonhosted.org/packages/36/60/f5c88065fa7e9c49c72b633e5424486cc1e2188f437631a6ce739bb6a855/crackle_codec-0.15.0-cp311-cp311-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "df33572be0c553b083f9b66244da131074e37a3ba6068aff5085b31a384d3733",
                "md5": "3d7f9ee1f4f9e6a7a48328e187369e61",
                "sha256": "3893b37d2376b6a19da87a362d32777db78260bdcb2db3504bc68b47ed4d0104"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "3d7f9ee1f4f9e6a7a48328e187369e61",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 218029,
            "upload_time": "2024-07-26T07:36:32",
            "upload_time_iso_8601": "2024-07-26T07:36:32.556979Z",
            "url": "https://files.pythonhosted.org/packages/df/33/572be0c553b083f9b66244da131074e37a3ba6068aff5085b31a384d3733/crackle_codec-0.15.0-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bcb7651ea3023269d74292a3dbf0acfda8d33219d5e1a04f012edf3fcddb41ed",
                "md5": "fe69cc6de5d8db41ad139e02b9167b02",
                "sha256": "de805e35b01f2a37065eab25b38207c4875f7b2bb050ad7f2f012ee27c611ec1"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp312-cp312-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "fe69cc6de5d8db41ad139e02b9167b02",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 367199,
            "upload_time": "2024-07-26T07:36:34",
            "upload_time_iso_8601": "2024-07-26T07:36:34.259040Z",
            "url": "https://files.pythonhosted.org/packages/bc/b7/651ea3023269d74292a3dbf0acfda8d33219d5e1a04f012edf3fcddb41ed/crackle_codec-0.15.0-cp312-cp312-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4bfddb387328ed365c0a461349b70427b473a0757d949bd0d2ff2a2e8cecef64",
                "md5": "d5a3cf27b492c1c3df5ff4f33a66f9fe",
                "sha256": "16fa86ed93754e87d3892b37f592cc7cad4639c7e6c380699aca48e5a7eb4f74"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp312-cp312-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "d5a3cf27b492c1c3df5ff4f33a66f9fe",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 298396,
            "upload_time": "2024-07-26T07:36:35",
            "upload_time_iso_8601": "2024-07-26T07:36:35.811592Z",
            "url": "https://files.pythonhosted.org/packages/4b/fd/db387328ed365c0a461349b70427b473a0757d949bd0d2ff2a2e8cecef64/crackle_codec-0.15.0-cp312-cp312-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4d3ec99520bf10b96c5c4159e93f79cbbfdde816de82d0b7fe88ca8204d621c8",
                "md5": "7f3339748ca39c641fea1e9aad8035ec",
                "sha256": "ae8df4ae60f10a52a1fcc7126c2f1f4db98f70d188f1184fc91e25b51f96fc8a"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "7f3339748ca39c641fea1e9aad8035ec",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 335345,
            "upload_time": "2024-07-26T07:36:37",
            "upload_time_iso_8601": "2024-07-26T07:36:37.137031Z",
            "url": "https://files.pythonhosted.org/packages/4d/3e/c99520bf10b96c5c4159e93f79cbbfdde816de82d0b7fe88ca8204d621c8/crackle_codec-0.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "51894c6f7df55442a75ecf85cb33408209bca238fc79744dbb704ad0c3fc68d8",
                "md5": "f03438c4c7dd50c9a3fa265a107c0ba8",
                "sha256": "44360ab1c70075817d6f16c7b47c4112d14c7c9507c348d548ddfa4e5babe7b8"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp312-cp312-win32.whl",
            "has_sig": false,
            "md5_digest": "f03438c4c7dd50c9a3fa265a107c0ba8",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 221175,
            "upload_time": "2024-07-26T07:36:38",
            "upload_time_iso_8601": "2024-07-26T07:36:38.480080Z",
            "url": "https://files.pythonhosted.org/packages/51/89/4c6f7df55442a75ecf85cb33408209bca238fc79744dbb704ad0c3fc68d8/crackle_codec-0.15.0-cp312-cp312-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "dbbc204065d52dbd706c648eb3707fbed50328f5cbd4da5dd39894cd8cc84cae",
                "md5": "a449aaa6867855e2f15f1bc70bfa44ac",
                "sha256": "ecac07979f845c4ae84a7ffa2601de3c9bdea8fb5803c19e5b24455008c7c8b8"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "a449aaa6867855e2f15f1bc70bfa44ac",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 218641,
            "upload_time": "2024-07-26T07:36:39",
            "upload_time_iso_8601": "2024-07-26T07:36:39.909783Z",
            "url": "https://files.pythonhosted.org/packages/db/bc/204065d52dbd706c648eb3707fbed50328f5cbd4da5dd39894cd8cc84cae/crackle_codec-0.15.0-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "223ca0f749445a4cde7891c236e8653fa97ed38a1047cd04bd6406c0beba4880",
                "md5": "3227b57db4874d3f5475d98b18a7181a",
                "sha256": "7cf5a9690521ae10b1cca9eb6f6b8d9737a96101cd5430fb737182988ce55ade"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp36-cp36m-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "3227b57db4874d3f5475d98b18a7181a",
            "packagetype": "bdist_wheel",
            "python_version": "cp36",
            "requires_python": null,
            "size": 364955,
            "upload_time": "2024-07-26T07:36:42",
            "upload_time_iso_8601": "2024-07-26T07:36:42.842320Z",
            "url": "https://files.pythonhosted.org/packages/22/3c/a0f749445a4cde7891c236e8653fa97ed38a1047cd04bd6406c0beba4880/crackle_codec-0.15.0-cp36-cp36m-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "25bc4eac34421b897a0dbd9309b4bd6fe75ad148212f6d8733f2eaae1b30bc4a",
                "md5": "69163defb4f8d9117d76f8a6b3657f08",
                "sha256": "7df85f4ec8ce1362e0c7a09bff5fbe51b3217fe3e1b877d5a9d47c5e9eae4d3a"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "69163defb4f8d9117d76f8a6b3657f08",
            "packagetype": "bdist_wheel",
            "python_version": "cp36",
            "requires_python": null,
            "size": 336463,
            "upload_time": "2024-07-26T07:36:44",
            "upload_time_iso_8601": "2024-07-26T07:36:44.726458Z",
            "url": "https://files.pythonhosted.org/packages/25/bc/4eac34421b897a0dbd9309b4bd6fe75ad148212f6d8733f2eaae1b30bc4a/crackle_codec-0.15.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a2e3dc244ddbb74aae96afcd23c509451beb575be1746275de06af635efc6a70",
                "md5": "5519b6bc2af4e04b33256edc01d7f32d",
                "sha256": "f332a01fb8ab88a2b9a72118429d481e44fd39bff85f1e77020e54f879ef59b8"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp36-cp36m-win32.whl",
            "has_sig": false,
            "md5_digest": "5519b6bc2af4e04b33256edc01d7f32d",
            "packagetype": "bdist_wheel",
            "python_version": "cp36",
            "requires_python": null,
            "size": 220773,
            "upload_time": "2024-07-26T07:36:45",
            "upload_time_iso_8601": "2024-07-26T07:36:45.957161Z",
            "url": "https://files.pythonhosted.org/packages/a2/e3/dc244ddbb74aae96afcd23c509451beb575be1746275de06af635efc6a70/crackle_codec-0.15.0-cp36-cp36m-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "56c7683e1fe59f55de4d11a47d13de223923706eafe518a6d1e038e6d412aab0",
                "md5": "88745e3865f9a45819970817c8dd1d47",
                "sha256": "1e83aa113615fec55dd4bf3b9c489fe30e49b2020e9742136e66f9c8833f298e"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp36-cp36m-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "88745e3865f9a45819970817c8dd1d47",
            "packagetype": "bdist_wheel",
            "python_version": "cp36",
            "requires_python": null,
            "size": 218004,
            "upload_time": "2024-07-26T07:36:47",
            "upload_time_iso_8601": "2024-07-26T07:36:47.594506Z",
            "url": "https://files.pythonhosted.org/packages/56/c7/683e1fe59f55de4d11a47d13de223923706eafe518a6d1e038e6d412aab0/crackle_codec-0.15.0-cp36-cp36m-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f3242918356e8bef134e6822e9542f62249bdc29dcafa91c78af5a8a731c645f",
                "md5": "43469c4899eef673abd7b8a117babd97",
                "sha256": "fa71fb6c974d452499f0f1eabda7170acffcf10c638e8077eb7ba67c4701a62c"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp37-cp37m-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "43469c4899eef673abd7b8a117babd97",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 365707,
            "upload_time": "2024-07-26T07:36:48",
            "upload_time_iso_8601": "2024-07-26T07:36:48.855302Z",
            "url": "https://files.pythonhosted.org/packages/f3/24/2918356e8bef134e6822e9542f62249bdc29dcafa91c78af5a8a731c645f/crackle_codec-0.15.0-cp37-cp37m-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cb5b807e5148e9f8329f65546501ada2e6ab34f64e78b5f5b952004a53fd5285",
                "md5": "cf46aa7d02d216738601ca6682af96b6",
                "sha256": "70ef147a85ac120a97ecc484b718ddba0a95f558319c8d8848f1eb91f353fbc8"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "cf46aa7d02d216738601ca6682af96b6",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 337472,
            "upload_time": "2024-07-26T07:36:50",
            "upload_time_iso_8601": "2024-07-26T07:36:50.326566Z",
            "url": "https://files.pythonhosted.org/packages/cb/5b/807e5148e9f8329f65546501ada2e6ab34f64e78b5f5b952004a53fd5285/crackle_codec-0.15.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2acf9d73002538ce6f706b6035c715ffd0c586ff13d5af548c287fd233862d95",
                "md5": "847f1128ef7e4306e347b70a1fddafea",
                "sha256": "d6b5352f459b2279739582e398043c1ecff819c8b5227b7b15c9668b7b8c7841"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp37-cp37m-win32.whl",
            "has_sig": false,
            "md5_digest": "847f1128ef7e4306e347b70a1fddafea",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 220971,
            "upload_time": "2024-07-26T07:36:52",
            "upload_time_iso_8601": "2024-07-26T07:36:52.047363Z",
            "url": "https://files.pythonhosted.org/packages/2a/cf/9d73002538ce6f706b6035c715ffd0c586ff13d5af548c287fd233862d95/crackle_codec-0.15.0-cp37-cp37m-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "901ada1da23a5cee5b1d61a031ae6744f4461be5d4a48d579d0825b9b7807f67",
                "md5": "caaf5ad08d16c220f54ff1be254828cc",
                "sha256": "ef47db4f4ebfe33d498a5745d4c1d3f0ac96a61514e5baee6d1e582f2ef6432d"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp37-cp37m-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "caaf5ad08d16c220f54ff1be254828cc",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": null,
            "size": 218339,
            "upload_time": "2024-07-26T07:36:53",
            "upload_time_iso_8601": "2024-07-26T07:36:53.249526Z",
            "url": "https://files.pythonhosted.org/packages/90/1a/da1da23a5cee5b1d61a031ae6744f4461be5d4a48d579d0825b9b7807f67/crackle_codec-0.15.0-cp37-cp37m-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "14f470603f4a27be410e24ff48d4bd7001c972263442f9c3ba0923bf8f000378",
                "md5": "1fbffeb366c510c3b1acd2ced4e62f50",
                "sha256": "935d559fbe9c5081c20b1323023c28ac081fe98e62739d8645b4b4528e9b6105"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp38-cp38-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "1fbffeb366c510c3b1acd2ced4e62f50",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 365981,
            "upload_time": "2024-07-26T07:36:54",
            "upload_time_iso_8601": "2024-07-26T07:36:54.492970Z",
            "url": "https://files.pythonhosted.org/packages/14/f4/70603f4a27be410e24ff48d4bd7001c972263442f9c3ba0923bf8f000378/crackle_codec-0.15.0-cp38-cp38-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7c52d6bc021d182235578da1ff6a3b919c8af724a95634da8e02184e3545c73a",
                "md5": "9610c7aa53cefae57a0b9d4b0c006f69",
                "sha256": "de60b59b426fb6549684419e841c5dec55a54ac0b461768344fa39b0171428d8"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp38-cp38-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "9610c7aa53cefae57a0b9d4b0c006f69",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 297518,
            "upload_time": "2024-07-26T07:36:55",
            "upload_time_iso_8601": "2024-07-26T07:36:55.818836Z",
            "url": "https://files.pythonhosted.org/packages/7c/52/d6bc021d182235578da1ff6a3b919c8af724a95634da8e02184e3545c73a/crackle_codec-0.15.0-cp38-cp38-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "facb7e9f9f930d3a208aec2c91b9ace5433b995c6c71c2bcde51be3fa9e649bb",
                "md5": "55aa57554fd829fa8af755a2d07760b0",
                "sha256": "355393bf16d2ed4fc9e1881fd2b29f90abffef0a1a4f9b9ae9bd7c26552320f3"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "55aa57554fd829fa8af755a2d07760b0",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 334262,
            "upload_time": "2024-07-26T07:36:57",
            "upload_time_iso_8601": "2024-07-26T07:36:57.048138Z",
            "url": "https://files.pythonhosted.org/packages/fa/cb/7e9f9f930d3a208aec2c91b9ace5433b995c6c71c2bcde51be3fa9e649bb/crackle_codec-0.15.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f03847f224ad6f32f0afc85895a87cd0578272820549bd36fc41f476c5e8748e",
                "md5": "d952d282e0ea41a85395a1ab4e8f181d",
                "sha256": "b52bbbac3cf7e35e1530dab284c0461c526849a84d84640c31569bd2599419a8"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp38-cp38-win32.whl",
            "has_sig": false,
            "md5_digest": "d952d282e0ea41a85395a1ab4e8f181d",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 220013,
            "upload_time": "2024-07-26T07:36:58",
            "upload_time_iso_8601": "2024-07-26T07:36:58.585777Z",
            "url": "https://files.pythonhosted.org/packages/f0/38/47f224ad6f32f0afc85895a87cd0578272820549bd36fc41f476c5e8748e/crackle_codec-0.15.0-cp38-cp38-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1dc153b2f30c15ff976b15c5fa58354b68bdfc73eeabc486bbd71552ad7c1e36",
                "md5": "cd6eced6b6b2c54d2d8c51a029cb8c11",
                "sha256": "a99d25d07cf0de31c95b1adfed890a74a0e4ea8c06a77c3b5bcc9914e263b344"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp38-cp38-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "cd6eced6b6b2c54d2d8c51a029cb8c11",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": null,
            "size": 217416,
            "upload_time": "2024-07-26T07:37:00",
            "upload_time_iso_8601": "2024-07-26T07:37:00.218820Z",
            "url": "https://files.pythonhosted.org/packages/1d/c1/53b2f30c15ff976b15c5fa58354b68bdfc73eeabc486bbd71552ad7c1e36/crackle_codec-0.15.0-cp38-cp38-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3587eb80037065cceabd0487ecb2c5037812f822a0470679fcaecd70d19eb402",
                "md5": "0ec8d2c067f51a267b51695f25f087d0",
                "sha256": "86ad004495c2e82fdd586d1ae1f7da8c55a3925e0a1befadb99b5b7cfd218168"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp39-cp39-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "0ec8d2c067f51a267b51695f25f087d0",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 366136,
            "upload_time": "2024-07-26T07:37:01",
            "upload_time_iso_8601": "2024-07-26T07:37:01.799096Z",
            "url": "https://files.pythonhosted.org/packages/35/87/eb80037065cceabd0487ecb2c5037812f822a0470679fcaecd70d19eb402/crackle_codec-0.15.0-cp39-cp39-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "acbde6cd3f79321e145ffddc7792558d2b27233ea157006e21d683ac80b8a51f",
                "md5": "e70f5f67fa08a7b1357b11153144de7e",
                "sha256": "0d2e27cf376f2ce1fecfd24c1c4d5face9f424ba08f536e47437b68fb5442634"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp39-cp39-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "e70f5f67fa08a7b1357b11153144de7e",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 297737,
            "upload_time": "2024-07-26T07:37:03",
            "upload_time_iso_8601": "2024-07-26T07:37:03.285100Z",
            "url": "https://files.pythonhosted.org/packages/ac/bd/e6cd3f79321e145ffddc7792558d2b27233ea157006e21d683ac80b8a51f/crackle_codec-0.15.0-cp39-cp39-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "183e975017ae2c5b0f25d4887404ad3bf7fb48d9c659202b23f759496920ec29",
                "md5": "59298f95961315ec9c280c464db8aa97",
                "sha256": "5331530222f9f29608a6043bef52fc3c8c9de50c8f7be6173693e3a0845fe7e8"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "59298f95961315ec9c280c464db8aa97",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 333761,
            "upload_time": "2024-07-26T07:37:04",
            "upload_time_iso_8601": "2024-07-26T07:37:04.943273Z",
            "url": "https://files.pythonhosted.org/packages/18/3e/975017ae2c5b0f25d4887404ad3bf7fb48d9c659202b23f759496920ec29/crackle_codec-0.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3cbeeecb14d1ff2a59b42c60b1a60a8e625f679b36401f975b22c8825f85330d",
                "md5": "bb5b31d99a5884d0d16a9d3670e173b5",
                "sha256": "44595490c9661b8be4c0bc3d64521b45b0f271fe5d267cec48d152dec4d70842"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp39-cp39-win32.whl",
            "has_sig": false,
            "md5_digest": "bb5b31d99a5884d0d16a9d3670e173b5",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 220104,
            "upload_time": "2024-07-26T07:37:06",
            "upload_time_iso_8601": "2024-07-26T07:37:06.144673Z",
            "url": "https://files.pythonhosted.org/packages/3c/be/eecb14d1ff2a59b42c60b1a60a8e625f679b36401f975b22c8825f85330d/crackle_codec-0.15.0-cp39-cp39-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "70f489016aaea8ee6f4e4de1cc6e189c90edd1d0f1314cdcbf25775829eb8ad1",
                "md5": "5c5526c8d5d6de6b7cb6a3a570941366",
                "sha256": "d8cad501687013ad0505bb8a259c1d0761d6bd793af33c1e3fa5242a8948d8ce"
            },
            "downloads": -1,
            "filename": "crackle_codec-0.15.0-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "5c5526c8d5d6de6b7cb6a3a570941366",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 216600,
            "upload_time": "2024-07-26T07:37:07",
            "upload_time_iso_8601": "2024-07-26T07:37:07.358904Z",
            "url": "https://files.pythonhosted.org/packages/70/f4/89016aaea8ee6f4e4de1cc6e189c90edd1d0f1314cdcbf25775829eb8ad1/crackle_codec-0.15.0-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "522eb9cdf856a5623d107cedc09d7c776b058ba9328fcc29288e75d43f2ce3cd",
                "md5": "f6f5985d659c2b0b109f5a88b9e61299",
                "sha256": "a8bb7122e4fc95222fa1c7abec1fc2b14ee411397bfc29ca1b599c55f4c26322"
            },
            "downloads": -1,
            "filename": "crackle-codec-0.15.0.tar.gz",
            "has_sig": false,
            "md5_digest": "f6f5985d659c2b0b109f5a88b9e61299",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 83953,
            "upload_time": "2024-07-26T07:37:09",
            "upload_time_iso_8601": "2024-07-26T07:37:09.076344Z",
            "url": "https://files.pythonhosted.org/packages/52/2e/b9cdf856a5623d107cedc09d7c776b058ba9328fcc29288e75d43f2ce3cd/crackle-codec-0.15.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-26 07:37:09",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "seung-lab",
    "github_project": "crackle",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "crackle-codec"
}
        
Elapsed time: 0.41572s