insitupy-spatial 0.6.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. insitupy_spatial-0.6.1/LICENSE +29 -0
  2. insitupy_spatial-0.6.1/PKG-INFO +164 -0
  3. insitupy_spatial-0.6.1/README.md +130 -0
  4. insitupy_spatial-0.6.1/insitupy/__init__.py +33 -0
  5. insitupy_spatial-0.6.1/insitupy/_constants.py +68 -0
  6. insitupy_spatial-0.6.1/insitupy/_core/__init__.py +0 -0
  7. insitupy_spatial-0.6.1/insitupy/_core/_callbacks.py +168 -0
  8. insitupy_spatial-0.6.1/insitupy/_core/_checks.py +197 -0
  9. insitupy_spatial-0.6.1/insitupy/_core/_deprecated.py +24 -0
  10. insitupy_spatial-0.6.1/insitupy/_core/_layers.py +312 -0
  11. insitupy_spatial-0.6.1/insitupy/_core/_mixins.py +22 -0
  12. insitupy_spatial-0.6.1/insitupy/_core/_save.py +150 -0
  13. insitupy_spatial-0.6.1/insitupy/_core/_widgets.py +521 -0
  14. insitupy_spatial-0.6.1/insitupy/_core/_xenium.py +201 -0
  15. insitupy_spatial-0.6.1/insitupy/_core/config.py +91 -0
  16. insitupy_spatial-0.6.1/insitupy/_core/dataclasses.py +1214 -0
  17. insitupy_spatial-0.6.1/insitupy/_core/insitudata.py +2298 -0
  18. insitupy_spatial-0.6.1/insitupy/_core/insituexperiment.py +908 -0
  19. insitupy_spatial-0.6.1/insitupy/_core/reader.py +137 -0
  20. insitupy_spatial-0.6.1/insitupy/_core/registration.py +290 -0
  21. insitupy_spatial-0.6.1/insitupy/_exceptions.py +163 -0
  22. insitupy_spatial-0.6.1/insitupy/_warnings.py +5 -0
  23. insitupy_spatial-0.6.1/insitupy/datasets/README.md +4 -0
  24. insitupy_spatial-0.6.1/insitupy/datasets/__init__.py +6 -0
  25. insitupy_spatial-0.6.1/insitupy/datasets/datasets.py +467 -0
  26. insitupy_spatial-0.6.1/insitupy/datasets/download.py +70 -0
  27. insitupy_spatial-0.6.1/insitupy/images/__init__.py +5 -0
  28. insitupy_spatial-0.6.1/insitupy/images/axes.py +41 -0
  29. insitupy_spatial-0.6.1/insitupy/images/io.py +317 -0
  30. insitupy_spatial-0.6.1/insitupy/images/registration.py +425 -0
  31. insitupy_spatial-0.6.1/insitupy/images/utils.py +301 -0
  32. insitupy_spatial-0.6.1/insitupy/io/__init__.py +2 -0
  33. insitupy_spatial-0.6.1/insitupy/io/baysor.py +53 -0
  34. insitupy_spatial-0.6.1/insitupy/io/files.py +56 -0
  35. insitupy_spatial-0.6.1/insitupy/io/geo.py +142 -0
  36. insitupy_spatial-0.6.1/insitupy/io/io.py +261 -0
  37. insitupy_spatial-0.6.1/insitupy/io/plots.py +27 -0
  38. insitupy_spatial-0.6.1/insitupy/palettes.py +81 -0
  39. insitupy_spatial-0.6.1/insitupy/plotting/__init__.py +5 -0
  40. insitupy_spatial-0.6.1/insitupy/plotting/_colors.py +178 -0
  41. insitupy_spatial-0.6.1/insitupy/plotting/expression_along_axis.py +980 -0
  42. insitupy_spatial-0.6.1/insitupy/plotting/go.py +255 -0
  43. insitupy_spatial-0.6.1/insitupy/plotting/plots.py +186 -0
  44. insitupy_spatial-0.6.1/insitupy/plotting/volcano.py +110 -0
  45. insitupy_spatial-0.6.1/insitupy/utils/__init__.py +3 -0
  46. insitupy_spatial-0.6.1/insitupy/utils/_calc.py +173 -0
  47. insitupy_spatial-0.6.1/insitupy/utils/_patterns.py +522 -0
  48. insitupy_spatial-0.6.1/insitupy/utils/_regression.py +326 -0
  49. insitupy_spatial-0.6.1/insitupy/utils/_scanorama.py +69 -0
  50. insitupy_spatial-0.6.1/insitupy/utils/deg.py +58 -0
  51. insitupy_spatial-0.6.1/insitupy/utils/go.py +429 -0
  52. insitupy_spatial-0.6.1/insitupy/utils/panels.py +69 -0
  53. insitupy_spatial-0.6.1/insitupy/utils/preprocessing.py +151 -0
  54. insitupy_spatial-0.6.1/insitupy/utils/qc.py +87 -0
  55. insitupy_spatial-0.6.1/insitupy/utils/spatialdata.py +307 -0
  56. insitupy_spatial-0.6.1/insitupy/utils/utils.py +393 -0
  57. insitupy_spatial-0.6.1/pyproject.toml +41 -0
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, J. Wirth
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ * Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.3
2
+ Name: insitupy-spatial
3
+ Version: 0.6.1
4
+ Summary: Package introducing the InSituPy framework to analyze single-cell spatial transcriptomics data.
5
+ License: BSD-3-Clause
6
+ Author: Johannes Wirth
7
+ Author-email: jwrth <j.wirth@tum.de>
8
+ Requires-Python: >=3.9.0,<3.10.0
9
+ Classifier: License :: OSI Approved :: BSD License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Requires-Dist: adjusttext (>=1.3.0,<2.0.0)
13
+ Requires-Dist: dask (>=2023.9.2,<2024.0.0)
14
+ Requires-Dist: dask-image (==2023.8.1)
15
+ Requires-Dist: fastparquet (>=2023.10.1,<2024.0.0)
16
+ Requires-Dist: fiona (==1.10.0)
17
+ Requires-Dist: geopandas (>=0.14.4,<1.0.0)
18
+ Requires-Dist: napari[all] (==0.4.18)
19
+ Requires-Dist: numpy (==1.26.4)
20
+ Requires-Dist: opencv-python (==4.8.0.76)
21
+ Requires-Dist: openpyxl (>=3.1.2,<4.0.0)
22
+ Requires-Dist: parse (==1.19.1)
23
+ Requires-Dist: plottable (==0.1.5)
24
+ Requires-Dist: pyarrow (>=14.0.1,<15.0.0)
25
+ Requires-Dist: pytest (>=7.4.2,<8.0.0)
26
+ Requires-Dist: scanpy[leiden] (==1.10.3)
27
+ Requires-Dist: scikit-image (>=0.21.0,<1.0.0)
28
+ Requires-Dist: scikit-misc (==0.3.1)
29
+ Requires-Dist: toml (>=0.10.2,<1.0.0)
30
+ Requires-Dist: xmltodict (==0.13.0)
31
+ Requires-Dist: zarr (>=2.16.1,<3.0.0)
32
+ Description-Content-Type: text/markdown
33
+
34
+ # InSituPy: A framework for histology-guided, multi-sample analysis of single-cell spatial transcriptomics data
35
+
36
+ <p align="center">
37
+ <img src="https://github.com/SpatialPathology/InSituPy/blob/main/logo/insitupy_logo.png?raw=true?raw=true" width="500">
38
+ </p>
39
+
40
+ InSituPy is a Python package designed to facilitate the analysis of single-cell spatial transcriptomics data. With InSituPy, you can easily load, visualize, and analyze the data, enabling and simplifying the comprehensive exploration of spatial gene expression patterns within tissue sections and across multiple samples.
41
+ Currently the analysis is focused on data from the [_Xenium In Situ_](https://www.10xgenomics.com/platforms/xenium) methodology but a broader range of reading functions will be implemented in the future.
42
+
43
+ ## Latest changes
44
+
45
+ ### Update to `>=0.6.0`
46
+ * Changed reading logic of `cell_names` in `BoundariesData`: this might lead to issues with backward compatibility but generalizes the reading of boundaries data opening it for other technologies.
47
+ * Adapt viewer for smaller screens
48
+ * Revised automated registration pipeline:
49
+ * Fixed issue with large multiplexed IF images.
50
+ * Area dependent number of minimum matches to make registration pipeline also work on small images.
51
+ * add registration demo notebook for pancreas data
52
+ * by default remove history of variable data when calling `.save()`
53
+
54
+ ### Update to `0.5.0`
55
+ #### Major changes in reading/loading logic!
56
+ This might conflict with the backwards compatibility of this version! If there are issues with loading reading `InSituPy` projects saved with older version, please let me know to find workarounds!
57
+ * Reduced focus on Xenium method in data structure
58
+ * `InSituData.read()` substitutes `read_xenium` for reading of `InSituPy` projects. `read_xenium` used now to read data from Xenium data folders
59
+
60
+ ## Installation
61
+
62
+ ### Prerequisites
63
+
64
+ 1. **Create and activate a conda environment:**
65
+
66
+ ```bash
67
+ conda create --name insitupy python=3.9
68
+ conda activate insitupy
69
+ ```
70
+
71
+ ### Method 1: Installation from Cloned Repository
72
+
73
+ 1. **Clone the repository to your local machine:**
74
+
75
+ ```bash
76
+ git clone https://github.com/jwrth/InSituPy.git
77
+ ```
78
+
79
+ 2. **Navigate to the cloned repository and select the right branch:**
80
+
81
+ ```bash
82
+ cd InSituPy
83
+
84
+ # Optionally: switch to dev branch
85
+ git checkout dev
86
+ ```
87
+
88
+ 3. **Install the required packages using `pip` within the conda environment:**
89
+
90
+ ```bash
91
+ # basic installation
92
+ pip install .
93
+
94
+ # for developmental purposes add the -e flag
95
+ pip install -e .
96
+ ```
97
+
98
+ ### Method 2: Direct Installation from GitHub
99
+
100
+ 1. **Install directly from GitHub:**
101
+
102
+ ```bash
103
+ # for installation without napari use
104
+ pip install git+https://github.com/jwrth/InSituPy.git
105
+ ```
106
+
107
+ Make sure you have Conda installed on your system before proceeding with these steps. If not, you can install Miniconda or Anaconda from [https://docs.conda.io/en/latest/miniconda.html](https://docs.conda.io/en/latest/miniconda.html).
108
+
109
+ To ensure that the InSituPy package is available as a kernel in Jupyter notebooks within your conda environment, you can follow the instructions [here](https://ipython.readthedocs.io/en/stable/install/kernel_install.html).
110
+
111
+ ## Getting started
112
+
113
+ ### Documentation
114
+
115
+ For detailed instructions on using InSituPy, refer to the [official documentation](https://InSituPy.readthedocs.io), which will be made public after publication. The documentation will provide comprehensive guides on installation, usage, and advanced features.
116
+
117
+
118
+ ### Tutorials
119
+
120
+ Explore the tutorials in `./notebooks/` to learn how to use InSituPy:
121
+
122
+ #### Sample level analysis
123
+
124
+ These tutorials focus on the preprocessing, analysis and handling of individual samples.
125
+
126
+ 1. [Registration of additional images](notebooks/01_InSituPy_demo_register_images.ipynb) - Learn how to register additional images to the spatial transcriptomics data.
127
+ 1. Alternatively this is also implemented for an example dataset from [pancreatic cancer](notebooks/pancreas/01panc_InSituPy_demo_register_images.ipynb)
128
+ 3. [Basic analysis functionalities](notebooks/02_InSituPy_demo_analyze.ipynb) - Learn about the basic functionalities, such as loading of data, basic preprocessing and interactive visualization with napari.
129
+ 4. [Add annotations](notebooks/03_InSituPy_demo_annotations.ipynb) - Learn how to add annotations from external software such as [QuPath](https://qupath.github.io/) and do annotations in the napari viewer.
130
+ 5. [Crop data](notebooks/04_InSituPy_demo_crop.ipynb) - Learn how to crop your data to focus your analysis on specific areas in the tissue.
131
+ 6. [Cell type annotation](notebooks/05_InSituPy_cell_type_annotation.ipynb) - Shows an example workflow to annotate the cell types.
132
+ 7. [Explore gene expression along axis](notebooks/06_InSituPy_gene_expression_along_axis_pattern.ipynb) - Example cases showing how to correlate gene expression with e.g. the distance to histological annotations.
133
+ 8. [Build an `InSituData` object from scratch](notebooks/09_InSituPy_build_objects_from_scratch.ipynb) - General introduction on how to build an `InSituData` object from scratch.
134
+
135
+ #### Experiment-level analysis
136
+
137
+ This set of tutorials focuses on
138
+
139
+ 1. [Analyze multiple samples at once with InSituPy](notebooks/07_InSituPy_InSituExperiment.ipynb) - Introduces the main concepts behind the `InSituExperiment` class and how to work with multiple samples at once.
140
+ 2. [Differential gene expression analysis](notebooks/08_InSituPy_differential_gene_expression.ipynb) - Perform differential gene expression analysis within one sample and across multiple samples.
141
+
142
+ ### Example data
143
+
144
+ If you want to test the pipeline on different example datasets, [this notebook](notebooks/00_InSituPy_demo_datasets.ipynb) provides an overview of functions to download _Xenium In Situ_ data from official sources.
145
+
146
+ ## Features
147
+
148
+ - **Data Preprocessing:** InSituPy provides functions for normalizing, filtering, and transforming raw in situ transcriptomics data.
149
+ - **Interactive Visualization:** Create interactive plots using [napari](https://napari.org/stable/#) to easily explore spatial gene expression patterns.
150
+ - **Annotation:** Annotate _Xenium In Situ_ data in the napari viewer or import annotations from external tools like [QuPath](https://qupath.github.io/).
151
+ - **Multi-sample analysis:** Perform analysis on an experiment-level, i.e. with multiple samples at once.
152
+
153
+ ## Contributing
154
+
155
+ Contributions are welcome! If you find any issues or have suggestions for new features, please open an [issue](https://github.com/SpatialPathology/InSituPy/issues) or submit a pull request.
156
+
157
+ ## License
158
+
159
+ InSituPy is licensed under the [BSD-3-Clause](LICENSE).
160
+
161
+ ---
162
+
163
+ **InSituPy** is developed and maintained by [Johannes Wirth](https://github.com/jwrth) and [Anna Chernysheva](https://github.com/annachernysheva179). Feedback is highly appreciated and hopefully **InSituPy** helps you with your analysis of spatial transcriptomics data. The package is thought to be a starting point to simplify the analysis of in situ sequencing data in Python and it would be exciting to integrate functionalities for larger and more comprehensive data structures. Currently, the framework focuses on the analysis of _Xenium In Situ_ data but it is planned to integrate more methodologies and any support on this is highly welcomed.
164
+
@@ -0,0 +1,130 @@
1
+ # InSituPy: A framework for histology-guided, multi-sample analysis of single-cell spatial transcriptomics data
2
+
3
+ <p align="center">
4
+ <img src="https://github.com/SpatialPathology/InSituPy/blob/main/logo/insitupy_logo.png?raw=true?raw=true" width="500">
5
+ </p>
6
+
7
+ InSituPy is a Python package designed to facilitate the analysis of single-cell spatial transcriptomics data. With InSituPy, you can easily load, visualize, and analyze the data, enabling and simplifying the comprehensive exploration of spatial gene expression patterns within tissue sections and across multiple samples.
8
+ Currently the analysis is focused on data from the [_Xenium In Situ_](https://www.10xgenomics.com/platforms/xenium) methodology but a broader range of reading functions will be implemented in the future.
9
+
10
+ ## Latest changes
11
+
12
+ ### Update to `>=0.6.0`
13
+ * Changed reading logic of `cell_names` in `BoundariesData`: this might lead to issues with backward compatibility but generalizes the reading of boundaries data opening it for other technologies.
14
+ * Adapt viewer for smaller screens
15
+ * Revised automated registration pipeline:
16
+ * Fixed issue with large multiplexed IF images.
17
+ * Area dependent number of minimum matches to make registration pipeline also work on small images.
18
+ * add registration demo notebook for pancreas data
19
+ * by default remove history of variable data when calling `.save()`
20
+
21
+ ### Update to `0.5.0`
22
+ #### Major changes in reading/loading logic!
23
+ This might conflict with the backwards compatibility of this version! If there are issues with loading reading `InSituPy` projects saved with older version, please let me know to find workarounds!
24
+ * Reduced focus on Xenium method in data structure
25
+ * `InSituData.read()` substitutes `read_xenium` for reading of `InSituPy` projects. `read_xenium` used now to read data from Xenium data folders
26
+
27
+ ## Installation
28
+
29
+ ### Prerequisites
30
+
31
+ 1. **Create and activate a conda environment:**
32
+
33
+ ```bash
34
+ conda create --name insitupy python=3.9
35
+ conda activate insitupy
36
+ ```
37
+
38
+ ### Method 1: Installation from Cloned Repository
39
+
40
+ 1. **Clone the repository to your local machine:**
41
+
42
+ ```bash
43
+ git clone https://github.com/jwrth/InSituPy.git
44
+ ```
45
+
46
+ 2. **Navigate to the cloned repository and select the right branch:**
47
+
48
+ ```bash
49
+ cd InSituPy
50
+
51
+ # Optionally: switch to dev branch
52
+ git checkout dev
53
+ ```
54
+
55
+ 3. **Install the required packages using `pip` within the conda environment:**
56
+
57
+ ```bash
58
+ # basic installation
59
+ pip install .
60
+
61
+ # for developmental purposes add the -e flag
62
+ pip install -e .
63
+ ```
64
+
65
+ ### Method 2: Direct Installation from GitHub
66
+
67
+ 1. **Install directly from GitHub:**
68
+
69
+ ```bash
70
+ # for installation without napari use
71
+ pip install git+https://github.com/jwrth/InSituPy.git
72
+ ```
73
+
74
+ Make sure you have Conda installed on your system before proceeding with these steps. If not, you can install Miniconda or Anaconda from [https://docs.conda.io/en/latest/miniconda.html](https://docs.conda.io/en/latest/miniconda.html).
75
+
76
+ To ensure that the InSituPy package is available as a kernel in Jupyter notebooks within your conda environment, you can follow the instructions [here](https://ipython.readthedocs.io/en/stable/install/kernel_install.html).
77
+
78
+ ## Getting started
79
+
80
+ ### Documentation
81
+
82
+ For detailed instructions on using InSituPy, refer to the [official documentation](https://InSituPy.readthedocs.io), which will be made public after publication. The documentation will provide comprehensive guides on installation, usage, and advanced features.
83
+
84
+
85
+ ### Tutorials
86
+
87
+ Explore the tutorials in `./notebooks/` to learn how to use InSituPy:
88
+
89
+ #### Sample level analysis
90
+
91
+ These tutorials focus on the preprocessing, analysis and handling of individual samples.
92
+
93
+ 1. [Registration of additional images](notebooks/01_InSituPy_demo_register_images.ipynb) - Learn how to register additional images to the spatial transcriptomics data.
94
+ 1. Alternatively this is also implemented for an example dataset from [pancreatic cancer](notebooks/pancreas/01panc_InSituPy_demo_register_images.ipynb)
95
+ 3. [Basic analysis functionalities](notebooks/02_InSituPy_demo_analyze.ipynb) - Learn about the basic functionalities, such as loading of data, basic preprocessing and interactive visualization with napari.
96
+ 4. [Add annotations](notebooks/03_InSituPy_demo_annotations.ipynb) - Learn how to add annotations from external software such as [QuPath](https://qupath.github.io/) and do annotations in the napari viewer.
97
+ 5. [Crop data](notebooks/04_InSituPy_demo_crop.ipynb) - Learn how to crop your data to focus your analysis on specific areas in the tissue.
98
+ 6. [Cell type annotation](notebooks/05_InSituPy_cell_type_annotation.ipynb) - Shows an example workflow to annotate the cell types.
99
+ 7. [Explore gene expression along axis](notebooks/06_InSituPy_gene_expression_along_axis_pattern.ipynb) - Example cases showing how to correlate gene expression with e.g. the distance to histological annotations.
100
+ 8. [Build an `InSituData` object from scratch](notebooks/09_InSituPy_build_objects_from_scratch.ipynb) - General introduction on how to build an `InSituData` object from scratch.
101
+
102
+ #### Experiment-level analysis
103
+
104
+ This set of tutorials focuses on
105
+
106
+ 1. [Analyze multiple samples at once with InSituPy](notebooks/07_InSituPy_InSituExperiment.ipynb) - Introduces the main concepts behind the `InSituExperiment` class and how to work with multiple samples at once.
107
+ 2. [Differential gene expression analysis](notebooks/08_InSituPy_differential_gene_expression.ipynb) - Perform differential gene expression analysis within one sample and across multiple samples.
108
+
109
+ ### Example data
110
+
111
+ If you want to test the pipeline on different example datasets, [this notebook](notebooks/00_InSituPy_demo_datasets.ipynb) provides an overview of functions to download _Xenium In Situ_ data from official sources.
112
+
113
+ ## Features
114
+
115
+ - **Data Preprocessing:** InSituPy provides functions for normalizing, filtering, and transforming raw in situ transcriptomics data.
116
+ - **Interactive Visualization:** Create interactive plots using [napari](https://napari.org/stable/#) to easily explore spatial gene expression patterns.
117
+ - **Annotation:** Annotate _Xenium In Situ_ data in the napari viewer or import annotations from external tools like [QuPath](https://qupath.github.io/).
118
+ - **Multi-sample analysis:** Perform analysis on an experiment-level, i.e. with multiple samples at once.
119
+
120
+ ## Contributing
121
+
122
+ Contributions are welcome! If you find any issues or have suggestions for new features, please open an [issue](https://github.com/SpatialPathology/InSituPy/issues) or submit a pull request.
123
+
124
+ ## License
125
+
126
+ InSituPy is licensed under the [BSD-3-Clause](LICENSE).
127
+
128
+ ---
129
+
130
+ **InSituPy** is developed and maintained by [Johannes Wirth](https://github.com/jwrth) and [Anna Chernysheva](https://github.com/annachernysheva179). Feedback is highly appreciated and hopefully **InSituPy** helps you with your analysis of spatial transcriptomics data. The package is thought to be a starting point to simplify the analysis of in situ sequencing data in Python and it would be exciting to integrate functionalities for larger and more comprehensive data structures. Currently, the framework focuses on the analysis of _Xenium In Situ_ data but it is planned to integrate more methodologies and any support on this is highly welcomed.
@@ -0,0 +1,33 @@
1
+ __author__ = "Johannes Wirth"
2
+ __email__ = "j.wirth@tum.de"
3
+ __version__ = "0.6.1"
4
+
5
+ # check if napari is available
6
+ try:
7
+ import napari
8
+ WITH_NAPARI = True
9
+ except ImportError:
10
+ WITH_NAPARI = False
11
+
12
+ from insitupy._constants import CACHE
13
+
14
+ from . import images as im
15
+ from . import io
16
+ from . import plotting as pl
17
+ from . import utils
18
+ from ._core.dataclasses import AnnotationsData, BoundariesData, ImageData
19
+ from ._core.insitudata import (InSituData, calc_distance_of_cells_from,
20
+ differential_gene_expression)
21
+ from ._core.insituexperiment import InSituExperiment
22
+ from ._core.reader import read_xenium
23
+ from ._core.registration import register_images
24
+ from .palettes import CustomPalettes
25
+
26
+ __all__ = [
27
+ "InSituData",
28
+ "AnnotationsData",
29
+ "BoundariesData",
30
+ "ImageData",
31
+ "im",
32
+ "utils"
33
+ ]
@@ -0,0 +1,68 @@
1
+ import string
2
+ from pathlib import Path
3
+
4
+ import matplotlib
5
+ import matplotlib.pyplot as plt
6
+
7
+ from insitupy.palettes import CustomPalettes
8
+
9
+ # make sure that images do not exceed limits in c++ (required for cv2::remap function in cv2::warpAffine)
10
+ # see also https://www.geeksforgeeks.org/climits-limits-h-cc/
11
+ SHRT_MAX = 2**15-1 # 32767
12
+ SHRT_MIN = -(2**15-1) # -32767
13
+
14
+ # create cache dir
15
+ CACHE = Path.home() / ".cache/InSituPy/"
16
+
17
+ # modalities
18
+ MODALITIES = ["annotations", "cells", "images", "regions", "transcripts"]
19
+ LOAD_FUNCS = [
20
+ 'load_annotations',
21
+ 'load_cells',
22
+ 'load_images',
23
+ 'load_regions',
24
+ 'load_transcripts'
25
+ ]
26
+
27
+ # naming
28
+ ISPY_METADATA_FILE = ".ispy"
29
+ XENIUM_HEX_RANGE = string.ascii_lowercase[:16]
30
+ NORMAL_HEX_RANGE = "".join([str(e) for e in range(10)]) + string.ascii_lowercase[:6]
31
+ XENIUM_INT_TO_HEX_CONV_DICT = {k:v for k,v in zip(NORMAL_HEX_RANGE, XENIUM_HEX_RANGE)}
32
+ XENIUM_HEX_TO_INT_CONV_DICT = {v:k for k,v in zip(NORMAL_HEX_RANGE, XENIUM_HEX_RANGE)}
33
+
34
+ # napari layer symbols
35
+ # SHAPES_SYMBOL = "\u2605" # Star: ★
36
+ # POINTS_SYMBOL = "\u2022" # Bullet: •
37
+ ANNOTATIONS_SYMBOL = "\U0001F52C" # 🔬
38
+ POINTS_SYMBOL = "\U0001F4CD" # 📍
39
+ REGIONS_SYMBOL = "\U0001F30D" # 🌍
40
+
41
+ # annotations
42
+ FORBIDDEN_ANNOTATION_NAMES = ["rest"]
43
+
44
+ ## Matplotlib settings
45
+ # cmaps
46
+ palettes = CustomPalettes()
47
+ DEFAULT_CATEGORICAL_CMAP = palettes.tab20_mod
48
+ REGION_CMAP = matplotlib.colormaps["tab10"]
49
+ DEFAULT_CONTINUOUS_CMAP = "viridis"
50
+
51
+ # font size
52
+ def _init_mpl_fontsize(scale_factor=1):
53
+ '''
54
+ https://matplotlib.org/stable/api/matplotlib_configuration_api.html#matplotlib.rcParams
55
+ '''
56
+ SMALL_SIZE = 14*scale_factor
57
+ MEDIUM_SIZE = 16*scale_factor
58
+ BIGGER_SIZE = 18*scale_factor
59
+
60
+ plt.rc('font', size=SMALL_SIZE) # controls default text sizes
61
+ plt.rc('axes', titlesize=MEDIUM_SIZE) # fontsize of the axes title
62
+ plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
63
+ plt.rc('xtick', labelsize=SMALL_SIZE) # fontsize of the tick labels
64
+ plt.rc('ytick', labelsize=SMALL_SIZE) # fontsize of the tick labels
65
+ plt.rc('legend', fontsize=SMALL_SIZE) # legend fontsize
66
+ plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title
67
+
68
+ _init_mpl_fontsize()
File without changes
@@ -0,0 +1,168 @@
1
+ import math
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ from matplotlib.gridspec import GridSpec
6
+ from matplotlib.lines import Line2D
7
+ from pandas.api.types import is_numeric_dtype
8
+
9
+ import insitupy._core.config as config
10
+ from insitupy import WITH_NAPARI
11
+ from insitupy._constants import POINTS_SYMBOL
12
+
13
+ if WITH_NAPARI:
14
+ import napari
15
+
16
+
17
+ # geometry widget
18
+ def _update_keys_based_on_geom_type(widget, xdata):
19
+ # retrieve current value
20
+ current_geom_type = widget.geom_type.value
21
+ current_key = widget.key.value
22
+
23
+ # get either regions or annotations object
24
+ geom_data = getattr(xdata, current_geom_type.lower())
25
+ widget.key.choices = sorted(geom_data.metadata.keys(), key=str.casefold)
26
+
27
+ def _update_classes_on_key_change(widget, xdata):
28
+ # get current values for geom_type and key
29
+ current_geom_type = widget.geom_type.value
30
+ current_key = widget.key.value
31
+
32
+ # get either regions or annotations object
33
+ geom_data = getattr(xdata, current_geom_type.lower())
34
+
35
+ # update annot_class choices
36
+ widget.annot_class.choices = ["all"] + sorted(geom_data.metadata[current_key]['classes'])
37
+
38
+ def _set_show_names_based_on_geom_type(widget):
39
+ # retrieve current value
40
+ current_geom_type = widget.geom_type.value
41
+
42
+ # set the show_names tick box
43
+ if current_geom_type == "Annotations":
44
+ widget.show_names.value = False
45
+
46
+ if current_geom_type == "Regions":
47
+ widget.show_names.value = True
48
+
49
+
50
+ # Function to update the legend
51
+ def _update_categorical_legend(static_canvas, mapping, label, max_rows: int = 6):
52
+
53
+ # Calculate the number of columns needed
54
+ num_items = len(mapping)
55
+ ncols = math.ceil(num_items / max_rows)
56
+
57
+ static_canvas.figure.clear() # Clear the current figure
58
+ axes = static_canvas.figure.subplots() # Create new axes
59
+ legend_handles = [Line2D([0], [0],
60
+ marker='o', color='w', label=n,
61
+ markerfacecolor=c, markeredgecolor='k',
62
+ markersize=7) for n,c in mapping.items()]
63
+ axes.legend(handles=legend_handles, loc="center", title=label, ncols=ncols,
64
+ fontsize=8, title_fontsize=10,
65
+ labelspacing=0.7, borderpad=0.5)
66
+ axes.set_axis_off()
67
+ static_canvas.draw() # Redraw the canvas
68
+
69
+ def _update_continuous_legend(static_canvas, mapping, label):
70
+ static_canvas.figure.clear() # Clear the current figure
71
+ gs = GridSpec(1, 1, top=1.2, bottom=0.6, left=-0.5, right=1.5) # Define the grid spec
72
+ axes = static_canvas.figure.add_subplot(gs[0]) # Add subplot with the grid spec
73
+
74
+ colorbar = static_canvas.figure.colorbar(mapping, ax=axes, orientation='horizontal')
75
+ colorbar.set_label(label, fontsize=10)
76
+ colorbar.ax.tick_params(labelsize=8) # Adjust tick label size
77
+ #colorbar.set_ticks(np.linspace(norm.vmin, norm.vmax, num=5)) # Set the number of ticks
78
+ axes.set_axis_off()
79
+ static_canvas.draw() # Redraw the canvas
80
+
81
+ def _update_colorlegend():
82
+
83
+ # # automatically get layer
84
+ # candidate_layers = [l for l in config.viewer.layers if l.name.startswith(f"{config.current_data_name}")]
85
+ # try:
86
+ # # always choose the candidate layer that is on top
87
+ # layer_name = candidate_layers[-1].name
88
+ # except IndexError:
89
+ # raise ValueError("No layer with cellular transcriptomic data found. First add a layer using the 'Show Data' widget.")
90
+
91
+ # # extract layer
92
+ # layer = config.viewer.layers[layer_name]
93
+
94
+ layer = config.viewer.layers.selection.active
95
+
96
+ if isinstance(layer, napari.layers.points.points.Points):
97
+ # get values
98
+ values = layer.properties["value"]
99
+ color_values = layer.face_color
100
+
101
+
102
+ from insitupy.plotting._colors import continuous_data_to_rgba
103
+ if is_numeric_dtype(values):
104
+ rgba_list, mapping = continuous_data_to_rgba(data=values,
105
+ cmap=layer.face_colormap.name,
106
+ #upper_climit_pct=upper_climit_pct,
107
+ return_mapping=True
108
+ )
109
+
110
+ _update_continuous_legend(static_canvas=config.static_canvas,
111
+ mapping=mapping,
112
+ label=layer.name)
113
+
114
+ else:
115
+ # substitute pd.NA with np.nan
116
+ values = pd.Series(values).fillna(np.nan).values
117
+ # assume the data is categorical
118
+ #mapping = {category: tuple(rgba) for category, rgba in zip(values, color_values)}
119
+ unique_values = list(set(values))
120
+ mapping = {str(v): tuple(color_values[list(values).index(v)]) for v in unique_values}
121
+ # sort mapping dict
122
+ mapping = {elem: mapping[elem] for elem in sorted(mapping.keys())}
123
+
124
+ _update_categorical_legend(static_canvas=config.static_canvas,
125
+ mapping=mapping, label=layer.name)
126
+
127
+ # # create color mapping
128
+ # rgba_list, mapping = _data_to_rgba(values, return_mapping=True)
129
+
130
+ # if isinstance(mapping, dict):
131
+ # _update_categorical_legend(static_canvas=config.static_canvas,
132
+ # mapping=mapping, label=layer.name)
133
+ # else:
134
+ # _update_continuous_legend(static_canvas=config.static_canvas,
135
+ # mapping=mapping,
136
+ # label=layer.name)
137
+
138
+
139
+ def _refresh_widgets_after_data_change(xdata, points_widget, boundaries_widget, filter_widget):
140
+ config.init_viewer_config(xdata)
141
+
142
+ # set choices
143
+ boundaries_widget.key.choices = config.masks
144
+
145
+ # reset the currently selected key to None
146
+ points_widget.value.value = None
147
+
148
+ # add last addition to recent
149
+ points_widget.recent.choices = sorted(config.recent_selections)
150
+ points_widget.recent.value = None
151
+
152
+ # update obs in filter widget
153
+ filter_widget.obs_key.choices = config.value_dict["obs"]
154
+
155
+ # set only the last cell layer visible
156
+ cell_layers = []
157
+ for elem in xdata.viewer.layers:
158
+ if isinstance(elem, napari.layers.points.points.Points):
159
+ if not elem.name.startswith(POINTS_SYMBOL):
160
+ # only if the layer is not a point annotation layer, it is added
161
+ cell_layers.append(elem)
162
+ #point_layers = [elem for elem in xdata.viewer.layers if isinstance(elem, napari.layers.points.points.Points)]
163
+ n_cell_layers = len(cell_layers)
164
+
165
+ # # make only last cell layer visible
166
+ # for i, l in enumerate(cell_layers):
167
+ # if i < n_cell_layers-1:
168
+ # l.visible = False