Metadata-Version: 2.4
Name: copick
Version: 1.6.1
Summary: Definitions for a collaborative cryoET annotation tool.
Project-URL: Repository, https://github.com/copick/copick.git
Project-URL: Issues, https://github.com/copick/copick/issues
Project-URL: docs, https://copick.github.io/copick/
Project-URL: documentation, https://copick.github.io/copick/
Author-email: "Utz H. Ermel" <utz.ermel@czii.org>, "Kyle I. S. Harrington" <kyle@kyleharrington.com>
License: MIT License
        
        Copyright (c) 2024 Utz Ermel
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: annotation,collaborative,copick,cryo-et,cryoet,segmentation,tomography
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Requires-Python: >=3.9
Requires-Dist: click>=8.1.8
Requires-Dist: cryoet-data-portal>=4.4.1
Requires-Dist: distinctipy>=1.3.4
Requires-Dist: fsspec>=2025.5.1
Requires-Dist: mrcfile>=1.5.4
Requires-Dist: numcodecs<0.16.0
Requires-Dist: numpy>=2.0.2
Requires-Dist: ome-zarr>=0.10.2
Requires-Dist: psutil>=7.0.0
Requires-Dist: pydantic>=2
Requires-Dist: s3fs>=2025.5.1
Requires-Dist: scikit-image>=0.24.0
Requires-Dist: textual>=3.5.0
Requires-Dist: tqdm>=4.67.1
Requires-Dist: trimesh>=4.6.12
Requires-Dist: zarr<3
Provides-Extra: all
Requires-Dist: smbprotocol>=1.15.0; extra == 'all'
Requires-Dist: sshfs>=2024.6.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: black>=25.1.0; extra == 'dev'
Requires-Dist: ipython>=8.18.1; extra == 'dev'
Requires-Dist: notebook>=7.4.3; extra == 'dev'
Requires-Dist: pre-commit>=4.2.0; extra == 'dev'
Requires-Dist: ruff>=0.12.0; extra == 'dev'
Requires-Dist: textual-dev>=1.7.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-autorefs>=1.4.2; extra == 'docs'
Requires-Dist: mkdocs-material>=9.6.14; extra == 'docs'
Requires-Dist: mkdocs>=1.6.1; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.29.1; extra == 'docs'
Provides-Extra: fledgeling
Requires-Dist: pooch>=1.8.2; extra == 'fledgeling'
Requires-Dist: smbprotocol>=1.15.0; extra == 'fledgeling'
Requires-Dist: sshfs>=2024.6.0; extra == 'fledgeling'
Provides-Extra: smb
Requires-Dist: smbprotocol>=1.15.0; extra == 'smb'
Provides-Extra: ssh
Requires-Dist: sshfs>=2025.2.0; extra == 'ssh'
Provides-Extra: test
Requires-Dist: pooch>=1.8.2; extra == 'test'
Requires-Dist: pytest-cov>=6.2.1; extra == 'test'
Requires-Dist: pytest>=8.4.1; extra == 'test'
Requires-Dist: smbprotocol>=1.15.0; extra == 'test'
Requires-Dist: sshfs>=2025.2.0; extra == 'test'
Description-Content-Type: text/markdown

# copick

<div align="center">

[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
[![PyPI version](https://badge.fury.io/py/copick.svg)](https://badge.fury.io/py/copick)
[![Python](https://img.shields.io/badge/python-3.9%20|%203.10%20|%203.11%20|%203.12%20|%203.13-green)](https://pypi.org/project/copick/)
[![Tests](https://github.com/copick/copick/workflows/tests/badge.svg)](https://github.com/copick/copick/actions/workflows/test.yml)
[![codecov](https://codecov.io/gh/copick/copick/branch/main/graph/badge.svg)](https://codecov.io/gh/copick/copick)
[![Docs](https://github.com/copick/copick/workflows/docs/badge.svg)](https://copick.github.io/copick/)

</div>

**copick** is a cross-platform, storage-agnostic and server-less dataset API for cryoET datasets. Access to the data is
provided through an object-oriented API that abstracts away the underlying storage using the
[fsspec](https://filesystem-spec.readthedocs.io/en/latest/)-family of libraries.

## Why copick?

- **storage-agnostic**: Access data on local or shared filesystems, via SSH or on the cloud with the same API. No
    need for your own boilerplate!
- **cloud-ready**: Access image data quickly and in parallel thanks to multiscale OME-Zarr!
- **server-less**: No need for a dedicated server or database to access your data, just point **copick** to your data
    and go!
- **cross-platform**: **copick** works on any platform that supports Python. Compute on Linux, visualize on Windows or
    Mac, all with the same dataset API!
- **ecosystem**: Using the **copick** API allows visualizing and curating data in ChimeraX and Napari right away!

## Documentation

For more information, see the [documentation](https://copick.github.io/copick/).

## Installation

copick can be installed using pip. Using the `all` extra installs necessary requirements for all tested filesystem
implementations from the fsspec family (`local`, `s3fs`, `smb`, `sshfs`). Separate `s3`, `smb`, and `ssh` extras are available.

```shell
pip install "copick[all]"
```

> [!NOTE]
> `copick==1.2.0` will fail to install with `pip>=25`. We recommend using [`uv pip`](https://docs.astral.sh/uv/pip/) or `pip<=25` when installing copick.


## Example dataset

An example dataset can be obtained from [Zenodo](https://doi.org/10.5281/zenodo.11238625).

To test with the example dataset:

1. Download and unpack the example dataset
2. Add the location of the `sample_project`-directory in the unpacked dataset to `filesystem_overlay_only.json`
    ```json
    {
        "name": "test",
        "description": "A test project.",
        "version": "1.0.0",

        "pickable_objects": [
            {
                "name": "proteasome",
                "is_particle": true,
                "pdb_id": "3J9I",
                "label": 1,
                "color": [255, 0, 0, 255],
                "radius": 60,
                "map_threshold": 0.0418
            },
            {
                "name": "ribosome",
                "is_particle": true,
                "pdb_id": "7P6Z",
                "label": 2,
                "color": [0, 255, 0, 255],
                "radius": 150,
                "map_threshold": 0.037

            },
            {
                "name": "membrane",
                "is_particle": false,
                "label": 3,
                "color": [0, 0, 0, 255]
            }
        ],

        // Change this path to the location of sample_project
        "overlay_root": "local:///PATH/TO/EXTRACTED/PROJECT/",

        "overlay_fs_args": {
            "auto_mkdir": true
        }
    }
    ```

3. Start copick with the configuration file

    ```python
    from copick.impl.filesystem import CopickRootFSSpec
    root = CopickRootFSSpec.from_file('path/to/filesystem_overlay_only.json')
    ```

4. Access the data using the copick API

    ```python
    import zarr

    from copick.impl.filesystem import CopickRootFSSpec
    root = CopickRootFSSpec.from_file('path/to/filesystem_overlay_only.json')

    # Get a run by name
    run = root.get_run("TS_001")

     # Get a tomogram by name
    tomogram = run.get_voxel_spacing(10).get_tomogram("wbp")

    # Access the data
    group = zarr.open(tomogram.zarr())
    arrays = list(group.arrays())
    _, array = arrays[0]
    ```

## Contributing

We welcome contributions to copick! Here's how to get started:

### Development Setup

1. Clone the repository and install with development dependencies:
   ```bash
   git clone https://github.com/copick/copick.git
   cd copick
   pip install -e ".[dev,test]"
   ```

2. Install pre-commit hooks:
   ```bash
   pre-commit install
   ```

3. Run tests to ensure everything is working:
   ```bash
   pytest
   ```

### Code Quality

We use several tools to maintain code quality:

- **Black** for code formatting
- **Ruff** for linting and import sorting
- **Pre-commit hooks** to enforce standards

Before submitting a PR, ensure your code passes all checks:
```bash
black src/ tests/
ruff check --fix src/ tests/
pytest
```

### Conventional Commits

All pull requests must use [Conventional Commits](https://www.conventionalcommits.org/) for commit messages. This helps us automatically generate changelogs and determine version bumps.

Examples:
- `feat: add support for new tomogram format`
- `fix: resolve memory leak in zarr loading`
- `docs: update installation instructions`
- `test: add unit tests for mesh operations`

### Adding CLI Commands from External Packages

Copick supports a plugin system that allows external Python packages to register CLI commands. To add a command from your package:

1. In your package's `setup.py` or `pyproject.toml`, add an entry point in the `copick.commands` group:

   **setup.py**:
   ```python
   setup(
       name="my-copick-plugin",
       entry_points={
           "copick.commands": [
               "my-command=my_package.cli:my_command",
           ],
       },
   )
   ```

   **pyproject.toml**:
   ```toml
   [project.entry-points."copick.commands"]
   my-command = "my_package.cli:my_command"
   ```

2. Create a Click command in your package:
   ```python
   import click

   from copick.cli.util import add_config_option, add_debug_option
   from copick.util.log import get_logger

   @click.command()
   @add_config_option
   @add_debug_option
   @click.pass_context
   def my_command(ctx, config: str, debug: bool):
       """My custom copick command."""
       logger = get_logger(__name__, debug=debug)
       logger.info(f"Running my command with config: {config}")
   ```

3. After installing your package, the command will be available via:
   ```bash
   copick my-command --config path/to/config.json
   ```

The plugin system automatically discovers and loads all commands registered in the `copick.commands` entry point group.

## Code of Conduct

This project adheres to the Contributor Covenant [code of conduct](https://github.com/chanzuckerberg/.github/blob/main/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [opensource@chanzuckerberg.com](mailto:opensource@chanzuckerberg.com).

## Reporting Security Issues

If you believe you have found a security issue, please responsibly disclose by contacting us at [security@chanzuckerberg.com](mailto:security@chanzuckerberg.com).
