Metadata-Version: 2.3
Name: fusion-tools
Version: 3.6.27
Summary: Modular visualization and analysis dashboard creation for high-resolution microscopy images.
License: Apache Software License
Author: Sam Border
Author-email: sam.border2256@gmail.com
Requires-Python: >=3.8
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: anndata (>=0.11.4,<0.12.0)
Requires-Dist: dash (>=3.1.1,<4.0.0)
Requires-Dist: dash-bootstrap-components (>=2.0.3,<3.0.0)
Requires-Dist: dash-extensions (>=2.0.4,<3.0.0)
Requires-Dist: dash-leaflet (>=1.1.3,<2.0.0)
Requires-Dist: dash-mantine-components (>=2.1.0,<3.0.0)
Requires-Dist: dash-uploader (>=0.6.1,<0.7.0)
Requires-Dist: fastapi (>=0.115.14,<0.116.0)
Requires-Dist: geojson (>=3.2.0,<4.0.0)
Requires-Dist: geopandas (>=1.1.1,<2.0.0)
Requires-Dist: girder-client (>=3.2.8,<4.0.0)
Requires-Dist: girder-job-sequence (>=0.2.7,<0.3.0)
Requires-Dist: large-image[multi,ometiff,openjpeg,openslide,pil,tifffile,zarr] (>=1.32.11,<2.0.0)
Requires-Dist: lxml (>=5.3.1)
Requires-Dist: pandas (>=2.3.0,<3.0.0)
Requires-Dist: rasterio (>=1.4.3,<2.0.0)
Requires-Dist: scikit-image (>=0.25.2,<0.26.0)
Requires-Dist: shapely (>=2.1.1,<3.0.0)
Requires-Dist: sqlalchemy (>=2.0.41,<3.0.0)
Requires-Dist: statsmodels (>=0.14.4,<0.15.0)
Requires-Dist: tqdm (>=4.67.1,<5.0.0)
Requires-Dist: typing-extensions (>=4.14.0,<5.0.0)
Requires-Dist: umap-learn (>=0.5.8,<0.6.0)
Requires-Dist: uuid (>=1.30,<2.0)
Requires-Dist: uvicorn (>=0.35.0,<0.36.0)
Description-Content-Type: text/markdown

# *fusion-tools*
Modular visualization and analysis dashboard creation for high-resolution microscopy images.


## Installation

`fusion-tools` is deployed through PyPI and can be installed using:
```bash
$ pip install fusion-tools
```

## Usage

`fusion-tools` is intended to bring some of the functionality found in FUSION to developers working with whole slide images (WSIs) stored locally. 

One such example would be the `Visualization` and `SlideMap` class:
<div align="center">
    <img src="docs/images/local-slide-viewer.PNG">
</div>

```python
from fusion_tools.visualization import Visualization
from fusion_tools.components import SlideMap

vis_session = Visualization(
    local_slides = [path_to_slide]
    components = [
        [
            SlideMap()
        ]
    ]
)

vis_session.start()

```

The `Visualization` class lets users construct custom layouts of different tools by passing a list containing rows, columns, and tabs. (e.g. [ [column in row 1], [ [ tab 1 in column 2 in row 1, tab 2 in column 2 in row 1] ], [ [ column 1 in row 2 ] ] ] ).

By passing a list of paths to locally-stored whole slide images (WSIs), `fusion-tools` automatically generates a `LocalTileServer` which is bundled in with the `Visualization` session to allow for high-resolution image viewing.

<div align="center">
    <img src="docs/images/slide-annotations-layout.PNG">
</div>


```python

from fusion_tools.visualization import Visualization
from fusion_tools.components import SlideMap, OverlayOptions, PropertyViewer
from fusion_tools.utils.shapes import load_aperio


path_to_slide = '/path/to/wsi.svs'
path_to_annotations = '/path/to/aperio_annotations.xml'

annotations = load_aperio(path_to_annotations)

vis_session = Visualization(
    local_slides = [path_to_slide],
    local_annotations = [annotations],
    components = [
        [
            SlideMap(),
            [
                OverlayOptions(),
                PropertyViewer()
            ]
        ]
    ]
)

vis_session.start()

```

You can also access remote tile servers (either through `DSATileServer` or `CustomTileServer`) as well as annotations stored on a [Digital Slide Archive](https://digitalslidearchive.github.io/digital_slide_archive/) instance.

<div align="center">
    <img src="docs/images/remote-slide-annotations.PNG">
</div>


```python

from fusion_tools.visualization import Visualization
from fusion_tools.handler.dsa_handler import DSAHandler
from fusion_tools.components import SlideMap

# Grabbing first item from demo DSA instance
base_url = 'https://demo.kitware.com/histomicstk/api/v1'
item_id = '5bbdeed1e629140048d01bcb'

# Starting the DSAHandler to grab information:
dsa_handler = DSAHandler(
    girderApiUrl = base_url
)

# Checking how many annotations this item has:
#print('This item has the following annotations: ')
#print(dsa_handler.query_annotation_count(item=item_id).to_dict('records'))

vis_session = Visualization(
    tileservers = [dsa_handler.get_tile_server(item_id)],
    components = [
        [
            SlideMap()
        ]
    ]
)

vis_session.start()


```

You can also use some of `segmentation` components for adding labels and annotations to structures in the slide.

### Creating annotations on top of structures
<div align="center">
    <img src="docs/images/feature-annotation.PNG">
</div>

### Applying labels to many structures at the same time
<div align="center">
    <img src="docs/images/bulk-labels.PNG">
</div>

```python

from fusion_tools.visualization import Visualization
from fusion_tools.handler.dsa_handler import DSAHandler
from fusion_tools.components import SlideMap, FeatureAnnotation, BulkLabels

# Grabbing first item from demo DSA instance
base_url = 'https://demo.kitware.com/histomicstk/api/v1'
item_id = '5bbdeed1e629140048d01bcb'

# Starting the DSAHandler to grab information:
dsa_handler = DSAHandler(
    girderApiUrl = base_url
)

# Checking how many annotations this item has:
#print('This item has the following annotations: ')
#print(dsa_handler.query_annotation_count(item=item_id).to_dict('records'))

vis_session = Visualization(
    tileservers = [dsa_handler.get_tile_server(item_id)],
    components = [
        [
            SlideMap(),
            [
                FeatureAnnotation(
                    storage_path = os.getcwd()+'\\tests\\Test_Annotations\\',
                    labels_format = 'json',
                    annotations_format = 'rgb'
                ),
                BulkLabels()
            ]
        ]
    ]
)

vis_session.start()


```

### New in *fusion-tools*>2.0.0!
Now you can add multiple slides to a single visualization session and you can even view them side-by-side!
- By default, components in the same *row* are **linked**, or they can interact with each other through callbacks. This can be updated using the "linkage" kwarg when initializing a `Visualization` session.
- If two of the same types of components (e.g., two `SlideMap` components) are placed in the same row and "linkage" is set to "row", callbacks will not work. **Beware!**

```python

from fusion_tools.visualization import Visualization
from fusion_tools.components import SlideMap, OverlayOptions, PropertyViewer, PropertyPlotter
from fusion_tools.handler.dsa_handler import DSAHandler

# Mixed types of slides and annotations
local_slide_list = ['slide1.tif','slide2.ome.tif','slide3.svs']
local_annotations_list = ['slide1_annotations.xml','slide2 annotations.json','annotations for slide3.h5ad']

dsa_handler = DSAHandler(
    girderApiUrl = 'http://example_dsa_address.com/api/v1'
)

dsa_items_list = [
    'item_uuid_1',
    'item_uuid_2'
]

dsa_tileservers = [dsa_handler.get_tile_server(i) for i in dsa_items_list]

# Setting linkage to "col" to enable side-by-side visualization
vis_sess = Visualization(
    local_slides = local_slide_list,
    local_annotations = local_annotations_list,
    tileservers = dsa_tileservers,
    linkage = 'col',
    components = [
        [
            [
                SlideMap(),
                OverlayOptions(),
                PropertyViewer(),
                PropertyPlotter()
            ],            
            [
                SlideMap(),
                OverlayOptions(),
                PropertyViewer(),
                PropertyPlotter()
            ]
        ]
    ],
    app_options={'port': 8050}
)

vis_sess.start()


```
<div align="center">
    <img src="docs/images/side-by-side-view.PNG">
</div>


## Examples:

For more examples including how to load specific types of spatial --omics datasets (*10x Visium, VisiumHD, MxIF, etc.*) see this dedicated example page:

https://spborder.github.io/fusion-welcome-page/

<div align="center">
    <img src="docs/images/fusion-welcome-page.png">
</div>

## Contributing

Open to contributions. Feel free to submit a PR or post feature requests in [Issues](https://github.com/spborder/fusion-tools/issues)

### Open Projects:
- Automated segmentation workflow for locally stored images (active-learning, SAM, etc.)
- Monitoring long-running model training/other external processes


## License
`fusion-tools` was created by Samuel Border. It is licensed under the terms of the Apache 2.0 License


