dummy-spatialdata 0.1.8__tar.gz → 0.1.9__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 (22) hide show
  1. dummy_spatialdata-0.1.9/PKG-INFO +134 -0
  2. dummy_spatialdata-0.1.9/README.md +110 -0
  3. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/pyproject.toml +1 -1
  4. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/src/dummy_spatialdata/__init__.py +2 -1
  5. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/src/dummy_spatialdata/generate_dataset.py +9 -1
  6. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/src/dummy_spatialdata/generate_imagemodel.py +9 -8
  7. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/src/dummy_spatialdata/generate_labelmodel.py +11 -10
  8. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/src/dummy_spatialdata/generate_pointmodel.py +9 -8
  9. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/src/dummy_spatialdata/generate_shapemodel.py +29 -9
  10. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/src/dummy_spatialdata/generate_tablemodel.py +12 -1
  11. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/src/dummy_spatialdata/generate_transformations.py +2 -2
  12. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/tests/test_models.py +15 -15
  13. dummy_spatialdata-0.1.8/PKG-INFO +0 -114
  14. dummy_spatialdata-0.1.8/README.md +0 -90
  15. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/.gitignore +0 -0
  16. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/examples/bird-color.png +0 -0
  17. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/examples/bird.png +0 -0
  18. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/examples/nuclei.tif +0 -0
  19. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/src/dummy_spatialdata/utils.py +0 -0
  20. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/tests/__init__.py +0 -0
  21. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/tests/test_basic.py +0 -0
  22. {dummy_spatialdata-0.1.8 → dummy_spatialdata-0.1.9}/tests/test_transformations.py +0 -0
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: dummy-spatialdata
3
+ Version: 0.1.9
4
+ Summary: A package for creating arbitrary spatialdata for testing purposes.
5
+ Project-URL: Documentation, https://dummy-spatialdata.readthedocs.io/
6
+ Project-URL: Homepage, https://github.com/BIMSBBioinfo/dummy-spatialdata
7
+ Project-URL: Source, https://github.com/BIMSBBioinfo/dummy-spatialdata
8
+ Author-email: Artür Manukyan <amanukyan.umms@gmail.com>
9
+ License: MIT
10
+ Requires-Python: >=3.12
11
+ Requires-Dist: dummy-anndata>=0.0.3
12
+ Requires-Dist: geopandas
13
+ Requires-Dist: pillow
14
+ Requires-Dist: requests
15
+ Requires-Dist: shapely
16
+ Requires-Dist: spatialdata>=0.5.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: pre-commit; extra == 'dev'
19
+ Requires-Dist: twine>=4.0.2; extra == 'dev'
20
+ Provides-Extra: test
21
+ Requires-Dist: coverage; extra == 'test'
22
+ Requires-Dist: pytest; extra == 'test'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # dummy-spatialdata
26
+
27
+ Allows generating dummy spatialdata objects, which can be useful for testing purposes.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pip install dummy-spatialdata
33
+ ```
34
+
35
+ ## Example usage
36
+
37
+ `dummy-spatialdata` is compatible with both spatialdata == 0.5.0 (zarr v2) and 0.7.2 (zarr v3)
38
+
39
+ Thus please use
40
+
41
+ 1. `conda create --name dummy_sd_env python==3.12 spatialdata==0.7.2` or
42
+ 2. `conda create --name dummy_sd_env_05 python==3.12 spatialdata==0.5.0 setuptools==75.8.0`
43
+
44
+ ```{python}
45
+ from dummy_spatialdata import generate_dataset
46
+ import dummy_anndata
47
+ import spatialdata_plot as sdp
48
+ import spatialdata as sd
49
+ import matplotlib.pyplot as plt
50
+ import numpy as np
51
+ import pandas as pd
52
+ import anndata as ad
53
+ import tempfile as tf
54
+
55
+ # generate spatialdata
56
+ sdata = generate_dataset(
57
+ images = [
58
+ {'type': 'rgb', 'scale_factors': [2,2,2], 'shape': {'x': 64, 'y': 64},
59
+ 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']},
60
+ ],
61
+ labels = [
62
+ {'n': 12, 'scale_factors': [2,2,2], 'shape': {'x': 64, 'y': 64},
63
+ 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']},
64
+ {'n': 12, 'scale_factors': [2,2,2], 'shape': {'x': 64, 'y': 64},
65
+ 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']},
66
+ ],
67
+ shapes = [
68
+ {'n': 12, 'type': 'polygon', 'shape': {'x': 64, 'y': 64},
69
+ 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']},
70
+ {'n': 12, 'type': 'circle', 'shape': {'x': 64, 'y': 64},
71
+ 'overlapping': False, 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']}
72
+ ],
73
+ points = [
74
+ {'n': 12, 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']}
75
+ ],
76
+ tables = [
77
+ {'table': dummy_anndata.generate_dataset(n_obs=12, n_vars=20), 'element': 'shape', 'element_index': 0},
78
+ {'table': dummy_anndata.generate_dataset(n_obs=12, n_vars=20), 'element': 'shape', 'element_index': 1},
79
+ {'table': dummy_anndata.generate_dataset(n_obs=12, n_vars=20), 'element': 'label', 'element_index': 0},
80
+ {'table': dummy_anndata.generate_dataset(n_obs=12, n_vars=20), 'element': 'label', 'element_index': 1},
81
+ ],
82
+ coordinate_systems = {
83
+ 'identity': {'transformations': ['identity']},
84
+ 'scale': {'transformations': ['scale']},
85
+ 'mapAxis': {'transformations': ['mapAxis']},
86
+ 'translation': {'transformations': ['translation']},
87
+ 'rotation': {'transformations': ['rotation']},
88
+ 'affine': {'transformations': ['affine']},
89
+ 'sequence': {'transformations': ['scale', 'mapAxis', 'translation', 'rotation', 'affine']}
90
+ },
91
+ SEED=13
92
+ )
93
+ sdata
94
+ ```
95
+
96
+ ```
97
+ SpatialData object
98
+ ├── Images
99
+ │ └── 'image_0': DataTree[cyx] (3, 64, 64), (3, 32, 32), (3, 16, 16), (3, 8, 8)
100
+ ├── Labels
101
+ │ ├── 'label_0': DataTree[yx] (64, 64), (32, 32), (16, 16), (8, 8)
102
+ │ └── 'label_1': DataTree[yx] (64, 64), (32, 32), (16, 16), (8, 8)
103
+ ├── Points
104
+ │ └── 'point_0': DataFrame with shape: (<Delayed>, 2) (2D points)
105
+ ├── Shapes
106
+ │ ├── 'shape_0': GeoDataFrame shape: (12, 1) (2D shapes)
107
+ │ └── 'shape_1': GeoDataFrame shape: (12, 2) (2D shapes)
108
+ └── Tables
109
+ ├── 'table_0': AnnData (12, 20)
110
+ ├── 'table_1': AnnData (12, 20)
111
+ ├── 'table_2': AnnData (12, 20)
112
+ └── 'table_3': AnnData (12, 20)
113
+ with coordinate systems:
114
+ ▸ 'affine', with elements:
115
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
116
+ ▸ 'identity', with elements:
117
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
118
+ ▸ 'mapAxis', with elements:
119
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
120
+ ▸ 'rotation', with elements:
121
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
122
+ ...
123
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
124
+ ▸ 'sequence', with elements:
125
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
126
+ ▸ 'translation', with elements:
127
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
128
+ ```
129
+
130
+ You can plot the demo data now!
131
+
132
+ ```{python}
133
+ sdata.pl.render_images('image_0').pl.render_shapes('shape_0', color='Gene001', table_name = 'table_0', table_layer = 'float_matrix').pl.show(coordinate_systems = 'affine')
134
+ ```
@@ -0,0 +1,110 @@
1
+ # dummy-spatialdata
2
+
3
+ Allows generating dummy spatialdata objects, which can be useful for testing purposes.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install dummy-spatialdata
9
+ ```
10
+
11
+ ## Example usage
12
+
13
+ `dummy-spatialdata` is compatible with both spatialdata == 0.5.0 (zarr v2) and 0.7.2 (zarr v3)
14
+
15
+ Thus please use
16
+
17
+ 1. `conda create --name dummy_sd_env python==3.12 spatialdata==0.7.2` or
18
+ 2. `conda create --name dummy_sd_env_05 python==3.12 spatialdata==0.5.0 setuptools==75.8.0`
19
+
20
+ ```{python}
21
+ from dummy_spatialdata import generate_dataset
22
+ import dummy_anndata
23
+ import spatialdata_plot as sdp
24
+ import spatialdata as sd
25
+ import matplotlib.pyplot as plt
26
+ import numpy as np
27
+ import pandas as pd
28
+ import anndata as ad
29
+ import tempfile as tf
30
+
31
+ # generate spatialdata
32
+ sdata = generate_dataset(
33
+ images = [
34
+ {'type': 'rgb', 'scale_factors': [2,2,2], 'shape': {'x': 64, 'y': 64},
35
+ 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']},
36
+ ],
37
+ labels = [
38
+ {'n': 12, 'scale_factors': [2,2,2], 'shape': {'x': 64, 'y': 64},
39
+ 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']},
40
+ {'n': 12, 'scale_factors': [2,2,2], 'shape': {'x': 64, 'y': 64},
41
+ 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']},
42
+ ],
43
+ shapes = [
44
+ {'n': 12, 'type': 'polygon', 'shape': {'x': 64, 'y': 64},
45
+ 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']},
46
+ {'n': 12, 'type': 'circle', 'shape': {'x': 64, 'y': 64},
47
+ 'overlapping': False, 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']}
48
+ ],
49
+ points = [
50
+ {'n': 12, 'coordinate_system': ['identity', 'scale', 'mapAxis', 'translation', 'rotation', 'affine', 'sequence']}
51
+ ],
52
+ tables = [
53
+ {'table': dummy_anndata.generate_dataset(n_obs=12, n_vars=20), 'element': 'shape', 'element_index': 0},
54
+ {'table': dummy_anndata.generate_dataset(n_obs=12, n_vars=20), 'element': 'shape', 'element_index': 1},
55
+ {'table': dummy_anndata.generate_dataset(n_obs=12, n_vars=20), 'element': 'label', 'element_index': 0},
56
+ {'table': dummy_anndata.generate_dataset(n_obs=12, n_vars=20), 'element': 'label', 'element_index': 1},
57
+ ],
58
+ coordinate_systems = {
59
+ 'identity': {'transformations': ['identity']},
60
+ 'scale': {'transformations': ['scale']},
61
+ 'mapAxis': {'transformations': ['mapAxis']},
62
+ 'translation': {'transformations': ['translation']},
63
+ 'rotation': {'transformations': ['rotation']},
64
+ 'affine': {'transformations': ['affine']},
65
+ 'sequence': {'transformations': ['scale', 'mapAxis', 'translation', 'rotation', 'affine']}
66
+ },
67
+ SEED=13
68
+ )
69
+ sdata
70
+ ```
71
+
72
+ ```
73
+ SpatialData object
74
+ ├── Images
75
+ │ └── 'image_0': DataTree[cyx] (3, 64, 64), (3, 32, 32), (3, 16, 16), (3, 8, 8)
76
+ ├── Labels
77
+ │ ├── 'label_0': DataTree[yx] (64, 64), (32, 32), (16, 16), (8, 8)
78
+ │ └── 'label_1': DataTree[yx] (64, 64), (32, 32), (16, 16), (8, 8)
79
+ ├── Points
80
+ │ └── 'point_0': DataFrame with shape: (<Delayed>, 2) (2D points)
81
+ ├── Shapes
82
+ │ ├── 'shape_0': GeoDataFrame shape: (12, 1) (2D shapes)
83
+ │ └── 'shape_1': GeoDataFrame shape: (12, 2) (2D shapes)
84
+ └── Tables
85
+ ├── 'table_0': AnnData (12, 20)
86
+ ├── 'table_1': AnnData (12, 20)
87
+ ├── 'table_2': AnnData (12, 20)
88
+ └── 'table_3': AnnData (12, 20)
89
+ with coordinate systems:
90
+ ▸ 'affine', with elements:
91
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
92
+ ▸ 'identity', with elements:
93
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
94
+ ▸ 'mapAxis', with elements:
95
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
96
+ ▸ 'rotation', with elements:
97
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
98
+ ...
99
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
100
+ ▸ 'sequence', with elements:
101
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
102
+ ▸ 'translation', with elements:
103
+ image_0 (Images), label_0 (Labels), label_1 (Labels), point_0 (Points), shape_0 (Shapes), shape_1 (Shapes)
104
+ ```
105
+
106
+ You can plot the demo data now!
107
+
108
+ ```{python}
109
+ sdata.pl.render_images('image_0').pl.render_shapes('shape_0', color='Gene001', table_name = 'table_0', table_layer = 'float_matrix').pl.show(coordinate_systems = 'affine')
110
+ ```
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "dummy-spatialdata"
7
- version = "0.1.8"
7
+ version = "0.1.9"
8
8
  description = "A package for creating arbitrary spatialdata for testing purposes."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -5,7 +5,7 @@ from .generate_imagemodel import generate_imagemodel
5
5
  from .generate_labelmodel import generate_labelmodel
6
6
  from .generate_shapemodel import generate_shapemodel
7
7
  from .generate_pointmodel import generate_pointmodel
8
- from .generate_tablemodel import generate_tablemodel
8
+ from .generate_tablemodel import generate_tablemodel, generate_anndata
9
9
  from .generate_transformations import (
10
10
  generate_transformations,
11
11
  get_basetransformations,
@@ -21,6 +21,7 @@ __all__ = [
21
21
  "generate_pointmodel"
22
22
  "generate_tablemodel",
23
23
  "generate_transformations",
24
+ "generate_anndata",
24
25
  "utils"
25
26
  ]
26
27
 
@@ -14,6 +14,9 @@ from .generate_pointmodel import generate_pointmodel
14
14
  from .generate_tablemodel import generate_tablemodel
15
15
  from .generate_transformations import generate_transformations
16
16
  from spatialdata.models import TableModel
17
+ from spatialdata import get_element_instances
18
+
19
+ from pandas import RangeIndex
17
20
 
18
21
  def generate_dataset(
19
22
  images: Optional[list] = None,
@@ -141,6 +144,11 @@ def generate_dataset(
141
144
  instance_key = tbl.uns['spatialdata_attrs']['instance_key']
142
145
  if region in sdata._shared_keys:
143
146
  element = getattr(sdata, element_type + 's')[region]
144
- tbl.obs['instance_id'] = element.index
147
+ if element_type == 'shape':
148
+ tbl.obs['instance_id'] = element.index
149
+ elif element_type == 'label':
150
+ tbl.obs['instance_id'] = get_element_instances(element)
151
+ else:
152
+ raise ValueError(f"Invalid element type {element_type} in region {region}. Must be either 'shape' or 'label'.")
145
153
 
146
154
  return sdata
@@ -48,10 +48,8 @@ def generate_imagemodel(
48
48
  return None
49
49
 
50
50
  # get shape
51
- input.update(
52
- {'shape': get_shape(coordinate_systems,
53
- input['coordinate_system'] if 'coordinate_system' in input else None)}
54
- )
51
+ if 'shape' not in input:
52
+ input.update({'shape': default_shape()})
55
53
 
56
54
  # get source
57
55
  resource = files('dummy_spatialdata')
@@ -76,10 +74,13 @@ def generate_imagemodel(
76
74
  coord_systems = get_basetransformations(coordinate_systems)
77
75
  if 'coordinate_system' in input:
78
76
  coord_system = input['coordinate_system']
79
- if coord_system in coord_systems:
80
- trans = {coord_system: coord_systems[coord_system]}
81
- else:
82
- trans = {key: Identity()}
77
+ trans = {}
78
+ for crd in coord_system:
79
+ if crd in coord_systems:
80
+ # trans = {crd: coord_systems[crd]}
81
+ trans.update({crd: coord_systems[crd]})
82
+ else:
83
+ trans = {key: Identity()}
83
84
  else:
84
85
  trans = {key: Identity()}
85
86
 
@@ -46,10 +46,8 @@ def generate_labelmodel(
46
46
  return None
47
47
 
48
48
  # get shape
49
- input.update(
50
- {'shape': get_shape(coordinate_systems,
51
- input['coordinate_system'] if 'coordinate_system' in input else None)}
52
- )
49
+ if 'shape' not in input:
50
+ input.update({'shape': default_shape()})
53
51
 
54
52
  # generate labels
55
53
  # mask for where values should be non-zero
@@ -58,16 +56,19 @@ def generate_labelmodel(
58
56
 
59
57
  arr = np.zeros((rows, cols), dtype=int)
60
58
  mask = np.random.rand(rows, cols) < prob_nonzero
61
- arr[mask] = np.random.randint(1, input['n'], size=mask.sum())
62
-
59
+ arr[mask] = np.random.randint(1, input['n']+1, size=mask.sum())
60
+
63
61
  # get transformations
64
62
  coord_systems = get_basetransformations(coordinate_systems)
65
63
  if 'coordinate_system' in input:
66
64
  coord_system = input['coordinate_system']
67
- if coord_system in coord_systems:
68
- trans = {coord_system: coord_systems[coord_system]}
69
- else:
70
- trans = {key: Identity()}
65
+ trans = {}
66
+ for crd in coord_system:
67
+ if crd in coord_systems:
68
+ # trans = {crd: coord_systems[crd]}
69
+ trans.update({crd: coord_systems[crd]})
70
+ else:
71
+ trans = {key: Identity()}
71
72
  else:
72
73
  trans = {key: Identity()}
73
74
 
@@ -47,10 +47,8 @@ def generate_pointmodel(
47
47
  return None
48
48
 
49
49
  # get shape
50
- input.update(
51
- {'shape': get_shape(coordinate_systems,
52
- input['coordinate_system'] if 'coordinate_system' in input else None)}
53
- )
50
+ if 'shape' not in input:
51
+ input.update({'shape': default_shape()})
54
52
 
55
53
  # generate points
56
54
  RADIUS = 0.08 * min(input['shape']['x'], input['shape']['y'])
@@ -62,10 +60,13 @@ def generate_pointmodel(
62
60
  coord_systems = get_basetransformations(coordinate_systems)
63
61
  if 'coordinate_system' in input:
64
62
  coord_system = input['coordinate_system']
65
- if coord_system in coord_systems:
66
- trans = {coord_system: coord_systems[coord_system]}
67
- else:
68
- trans = {key: Identity()}
63
+ trans = {}
64
+ for crd in coord_system:
65
+ if crd in coord_systems:
66
+ # trans = {crd: coord_systems[crd]}
67
+ trans.update({crd: coord_systems[crd]})
68
+ else:
69
+ trans = {key: Identity()}
69
70
  else:
70
71
  trans = {key: Identity()}
71
72
 
@@ -48,16 +48,21 @@ def generate_shapemodel(
48
48
  return None
49
49
 
50
50
  # get shape
51
- input.update(
52
- {'shape': get_shape(coordinate_systems,
53
- input['coordinate_system'] if 'coordinate_system' in input else None)}
54
- )
51
+ if 'shape' not in input:
52
+ input.update({'shape': default_shape()})
55
53
 
56
54
  # generate polygons
57
55
  RADIUS = 0.08 * min(input['shape']['x'], input['shape']['y'])
58
56
  MIN_GAP = 0.01 * min(input['shape']['x'], input['shape']['y'])
59
57
 
60
- centers = generate_non_overlapping_centers(input['shape']['x'], input['shape']['y'], RADIUS, input['n'], MIN_GAP, SEED)
58
+ if 'overlapping' not in input:
59
+ input['overlapping'] = True
60
+ if input['overlapping']:
61
+ centers = generate_regular_centers(input['shape']['x'], input['shape']['y'], RADIUS, input['n'], SEED)
62
+ else:
63
+ centers = generate_non_overlapping_centers(input['shape']['x'], input['shape']['y'], RADIUS, input['n'], min_gap=MIN_GAP, SEED=SEED)
64
+ # centers = generate_non_overlapping_centers(input['shape']['x'], input['shape']['y'], RADIUS, input['n'], MIN_GAP, SEED)
65
+ # centers = generate_regular_centers(input['shape']['x'], input['shape']['y'], RADIUS, input['n'], SEED)
61
66
  if input['type'] == 'polygon':
62
67
  polygon_seeds = [SEED + i for i in range(input['n'])]
63
68
  polygons = [Polygon(border_polygon_points(c, RADIUS, 10, SEED = seed)) for c, seed in zip(centers, polygon_seeds)]
@@ -73,10 +78,12 @@ def generate_shapemodel(
73
78
  coord_systems = get_basetransformations(coordinate_systems)
74
79
  if 'coordinate_system' in input:
75
80
  coord_system = input['coordinate_system']
76
- if coord_system in coord_systems:
77
- trans = {coord_system: coord_systems[coord_system]}
78
- else:
79
- trans = {key: Identity()}
81
+ trans = {}
82
+ for crd in coord_system:
83
+ if crd in coord_systems:
84
+ trans.update({crd: coord_systems[crd]})
85
+ else:
86
+ trans = {key: Identity()}
80
87
  else:
81
88
  trans = {key: Identity()}
82
89
 
@@ -109,6 +116,19 @@ def generate_non_overlapping_centers(width, height, radius, n_circles, min_gap=0
109
116
 
110
117
  return np.array(centers)
111
118
 
119
+ def generate_regular_centers(width, height, radius, n_circles, SEED=1):
120
+ centers = []
121
+ tries = 0
122
+ rng = np.random.default_rng(SEED)
123
+
124
+ for _ in range(n_circles):
125
+ x = rng.uniform(radius, width - radius)
126
+ y = rng.uniform(radius, height - radius)
127
+ candidate = (x, y)
128
+ centers.append(candidate)
129
+
130
+ return np.array(centers)
131
+
112
132
  def border_polygon_points(center, radius, n_points, SEED=1):
113
133
  cx, cy = center
114
134
  rng = np.random.default_rng(SEED)
@@ -10,6 +10,9 @@ from spatialdata.models import TableModel
10
10
  import spatialdata as sd
11
11
  from .utils import default_shape
12
12
 
13
+ import anndata as ad
14
+ import pandas as pd
15
+
13
16
  def generate_tablemodel(
14
17
  input: Optional[dict] = None
15
18
  ) -> TableModel:
@@ -44,4 +47,12 @@ def generate_tablemodel(
44
47
  'instance_key': 'instance_id',
45
48
  }
46
49
 
47
- return TableModel.parse(input['table'])
50
+ return TableModel.parse(input['table'])
51
+
52
+ # generate anndata
53
+ def generate_anndata(n_obs=12, n_vars=20):
54
+ obs = pd.DataFrame(index=[f'obs_{i}' for i in range(n_obs)])
55
+ var = pd.DataFrame(index=[f'var_{i}' for i in range(n_vars)])
56
+ X = np.random.rand(n_obs, n_vars)
57
+ adata = ad.AnnData(X=X, obs=obs, var=var)
58
+ return adata
@@ -59,9 +59,9 @@ def generate_transformations(
59
59
  elif tr == 'mapAxis':
60
60
  tr = MapAxis({"x": "y", "y": "x"})
61
61
  elif tr == 'translation':
62
- tr = Translation([10, 20], axes = ('x', 'y'))
62
+ tr = Translation([10, -20], axes = ('x', 'y'))
63
63
  elif tr == 'scale':
64
- tr = Scale([0.5, 0.5], axes = ('x', 'y'))
64
+ tr = Scale([0.3, 1.3], axes = ('x', 'y'))
65
65
  elif tr == 'rotation':
66
66
  theta = np.deg2rad(15)
67
67
  c = np.cos(theta)
@@ -26,29 +26,29 @@ from spatialdata.transformations import (
26
26
  def test_shapemodel():
27
27
 
28
28
  # returns GeoDataFrame (circle)
29
- shp = generate_shapemodel({'n': 12, 'type': 'circle', 'coordinate_system': 'global'}, 'image')
29
+ shp = generate_shapemodel({'n': 12, 'type': 'circle', 'coordinate_system': ['global']}, 'shape')
30
30
  assert isinstance(shp, gpd.GeoDataFrame)
31
31
 
32
32
  # returns GeoDataFrame (polygon)
33
- shp = generate_shapemodel({'n': 12, 'type': 'polygon', 'coordinate_system': 'global'}, 'image')
33
+ shp = generate_shapemodel({'n': 12, 'type': 'polygon', 'coordinate_system': ['global']}, 'shape')
34
34
  assert isinstance(shp, gpd.GeoDataFrame)
35
35
 
36
36
  # wrong shape type
37
37
  with pytest.raises(ValueError):
38
- shp = generate_shapemodel({'n': 12, 'type': 'art', 'coordinate_system': 'global'}, 'image')
38
+ shp = generate_shapemodel({'n': 12, 'type': 'art', 'coordinate_system': ['global']}, 'shape')
39
39
 
40
40
  # size is not defined
41
41
  with pytest.raises(KeyError):
42
- shp = generate_shapemodel({'type': 'circle', 'coordinate_system': 'global'}, 'image')
42
+ shp = generate_shapemodel({'type': 'circle', 'coordinate_system': ['global']}, 'shape')
43
43
 
44
44
  # no coordinate system returns element name as coord system and Identity transformation
45
- shp = generate_shapemodel({'n': 12, 'type': 'circle'}, 'image')
46
- assert list(shp.attrs['transform'].keys())[0] == 'image'
47
- assert get_transformation(shp, 'image') == Identity()
45
+ shp = generate_shapemodel({'n': 12, 'type': 'circle'}, 'shape')
46
+ assert list(shp.attrs['transform'].keys())[0] == 'shape'
47
+ assert get_transformation(shp, 'shape') == Identity()
48
48
 
49
49
  # parses coordinate system
50
50
  coord_system = {'global': {'transformations': ['affine'], 'shape': {'x': 2000, 'y': 2000}}}
51
- shp = generate_shapemodel({'n': 12, 'type': 'polygon', 'coordinate_system': 'global'}, 'image', coord_system)
51
+ shp = generate_shapemodel({'n': 12, 'type': 'polygon', 'coordinate_system': ['global']}, 'image', coord_system)
52
52
  assert len(list(shp.attrs['transform'].keys())) == 1
53
53
  assert list(shp.attrs['transform'].keys())[0] == 'global'
54
54
  assert isinstance(get_transformation(shp, 'global'), Affine)
@@ -60,12 +60,12 @@ def test_shapemodel():
60
60
  def test_pointmodel():
61
61
 
62
62
  # returns DataFrame
63
- pts = generate_pointmodel({'n': 12, 'coordinate_system': 'global'}, 'image')
63
+ pts = generate_pointmodel({'n': 12, 'coordinate_system': ['global']}, 'image')
64
64
  assert isinstance(pts, dd.DataFrame)
65
65
 
66
66
  # size is not defined
67
67
  with pytest.raises(KeyError):
68
- pts = generate_pointmodel({'coordinate_system': 'global'}, 'image')
68
+ pts = generate_pointmodel({'coordinate_system': ['global']}, 'image')
69
69
 
70
70
  # no coordinate system returns element name as coord system and Identity transformation
71
71
  pts = generate_pointmodel({'n': 12}, 'image')
@@ -74,7 +74,7 @@ def test_pointmodel():
74
74
 
75
75
  # parses coordinate system
76
76
  coord_system = {'global': {'transformations': ['affine'], 'shape': {'x': 2000, 'y': 2000}}}
77
- pts = generate_pointmodel({'n': 12, 'coordinate_system': 'global'}, 'image', coord_system)
77
+ pts = generate_pointmodel({'n': 12, 'coordinate_system': ['global']}, 'image', coord_system)
78
78
  assert len(list(pts.attrs['transform'].keys())) == 1
79
79
  assert list(pts.attrs['transform'].keys())[0] == 'global'
80
80
  assert isinstance(get_transformation(pts, 'global'), Affine)
@@ -86,16 +86,16 @@ def test_pointmodel():
86
86
  def test_labelmodel():
87
87
 
88
88
  # returns DataFrame
89
- lbl = generate_labelmodel({'n': 12, 'scale_factors': [2,2,3], 'coordinate_system': 'global'}, 'image')
89
+ lbl = generate_labelmodel({'n': 12, 'scale_factors': [2,2,3], 'coordinate_system': ['global']}, 'image')
90
90
  assert isinstance(lbl, xarray.DataTree)
91
91
  assert len(lbl) == 4
92
92
 
93
93
  # size is not defined
94
94
  with pytest.raises(KeyError):
95
- lbl = generate_labelmodel({'coordinate_system': 'global'}, 'image')
95
+ lbl = generate_labelmodel({'coordinate_system': ['global']}, 'image')
96
96
 
97
97
  # single scale is returned for no scale factor definition
98
- lbl = generate_labelmodel({'n': 12, 'coordinate_system': 'global'}, 'image')
98
+ lbl = generate_labelmodel({'n': 12, 'coordinate_system': ['global']}, 'image')
99
99
  assert len(lbl) == 1
100
100
 
101
101
  # no coordinate system returns element name as coord system and Identity transformation
@@ -105,7 +105,7 @@ def test_labelmodel():
105
105
 
106
106
  # parses coordinate system
107
107
  coord_system = {'global': {'transformations': ['affine'], 'shape': {'x': 2000, 'y': 2000}}}
108
- lbl = generate_labelmodel({'n': 12, 'coordinate_system': 'global'}, 'image', coord_system)
108
+ lbl = generate_labelmodel({'n': 12, 'coordinate_system': ['global']}, 'image', coord_system)
109
109
  assert len(list(dict(lbl["scale0"])["image"].attrs['transform'].keys())) == 1
110
110
  assert list(dict(lbl["scale0"])["image"].attrs['transform'].keys())[0] == 'global'
111
111
  assert isinstance(get_transformation(lbl, 'global'), Affine)
@@ -1,114 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: dummy-spatialdata
3
- Version: 0.1.8
4
- Summary: A package for creating arbitrary spatialdata for testing purposes.
5
- Project-URL: Documentation, https://dummy-spatialdata.readthedocs.io/
6
- Project-URL: Homepage, https://github.com/BIMSBBioinfo/dummy-spatialdata
7
- Project-URL: Source, https://github.com/BIMSBBioinfo/dummy-spatialdata
8
- Author-email: Artür Manukyan <amanukyan.umms@gmail.com>
9
- License: MIT
10
- Requires-Python: >=3.12
11
- Requires-Dist: dummy-anndata>=0.0.3
12
- Requires-Dist: geopandas
13
- Requires-Dist: pillow
14
- Requires-Dist: requests
15
- Requires-Dist: shapely
16
- Requires-Dist: spatialdata>=0.5.0
17
- Provides-Extra: dev
18
- Requires-Dist: pre-commit; extra == 'dev'
19
- Requires-Dist: twine>=4.0.2; extra == 'dev'
20
- Provides-Extra: test
21
- Requires-Dist: coverage; extra == 'test'
22
- Requires-Dist: pytest; extra == 'test'
23
- Description-Content-Type: text/markdown
24
-
25
- # dummy-spatialdata
26
-
27
- Allows generating dummy spatialdata objects, which can be useful for testing purposes.
28
-
29
- ## Installation
30
-
31
- ```bash
32
- pip install dummy-spatialdata
33
- ```
34
-
35
- ## Example usage
36
-
37
- `dummy-spatialdata` is compatible with both spatialdata == 0.5.0 (zarr v2) and 0.7.2 (zarr v3)
38
-
39
- Thus please use
40
-
41
- 1. `conda create --name dummy_sd_env python==3.12 spatialdata==0.7.2` or
42
- 2. `conda create --name dummy_sd_env_05 python==3.12 spatialdata==0.5.0 setuptools==75.8.0`
43
-
44
- ```{python}
45
- from dummy_spatialdata import generate_dataset
46
- import dummy_anndata
47
- import spatialdata_plot as sdp
48
- import spatialdata as sd
49
- import matplotlib.pyplot as plt
50
- import anndata as ad
51
-
52
- # generate anndata
53
- adata = dummy_anndata.generate_dataset(n_obs=12, n_vars=20)
54
-
55
- # generate spatialdata
56
- sdata = generate_dataset(
57
- images = [
58
- {'type': 'rgb', 'scale_factors': [2,2,2], 'coordinate_system': 'global'},
59
- {'type': 'grayscale', 'coordinate_system': 'global'},
60
- ],
61
- labels = [
62
- {'n': 12, 'scale_factors': [2,2,3], 'coordinate_system': 'global2'},
63
- {'n': 12, 'coordinate_system': 'global2'},
64
- ],
65
- shapes = [
66
- {'n': 12, 'type': 'circle', 'coordinate_system': 'global'},
67
- {'n': 20, 'type': 'circle'},
68
- ],
69
- points = [
70
- {'n': 12}
71
- ],
72
- tables = [
73
- {'table': adata, 'element': 'shape', 'element_index': 0}
74
- ],
75
- coordinate_systems = {
76
- 'global': {'transformations': ['affine'], 'shape': {'x': 2000, 'y': 2000}},
77
- 'global2': {'transformations': ['scale', 'translation'], 'shape':{'x': 500, 'y': 500}}
78
- },
79
- SEED=13
80
- )
81
- sdata
82
- ```
83
-
84
- ```
85
- SpatialData object
86
- ├── Images
87
- │ ├── 'image_0': DataTree[cyx] (3, 2000, 2000), (3, 1000, 1000), (3, 500, 500), (3, 250, 250)
88
- │ └── 'image_1': DataTree[cyx] (1, 2000, 2000)
89
- ├── Labels
90
- │ ├── 'label_0': DataTree[yx] (500, 500), (250, 250), (125, 125), (41, 41)
91
- │ └── 'label_1': DataTree[yx] (500, 500)
92
- ├── Points
93
- │ └── 'point_0': DataFrame with shape: (<Delayed>, 2) (2D points)
94
- ├── Shapes
95
- │ ├── 'shape_0': GeoDataFrame shape: (12, 2) (2D shapes)
96
- │ └── 'shape_1': GeoDataFrame shape: (20, 2) (2D shapes)
97
- └── Tables
98
- └── 'table_0': AnnData (12, 20)
99
- with coordinate systems:
100
- ▸ 'global', with elements:
101
- image_0 (Images), image_1 (Images), shape_0 (Shapes)
102
- ▸ 'global2', with elements:
103
- label_0 (Labels), label_1 (Labels)
104
- ▸ 'point_0', with elements:
105
- point_0 (Points)
106
- ▸ 'shape_1', with elements:
107
- shape_1 (Shapes)
108
- ```
109
-
110
- You can plot the demo data now!
111
-
112
- ```{python}
113
- sdata.pl.render_images('image_0').pl.render_shapes('shape_0', color='Gene001', table_name = 'table_0', table_layer = 'float_matrix').pl.show(coordinate_systems = 'global')
114
- ```
@@ -1,90 +0,0 @@
1
- # dummy-spatialdata
2
-
3
- Allows generating dummy spatialdata objects, which can be useful for testing purposes.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- pip install dummy-spatialdata
9
- ```
10
-
11
- ## Example usage
12
-
13
- `dummy-spatialdata` is compatible with both spatialdata == 0.5.0 (zarr v2) and 0.7.2 (zarr v3)
14
-
15
- Thus please use
16
-
17
- 1. `conda create --name dummy_sd_env python==3.12 spatialdata==0.7.2` or
18
- 2. `conda create --name dummy_sd_env_05 python==3.12 spatialdata==0.5.0 setuptools==75.8.0`
19
-
20
- ```{python}
21
- from dummy_spatialdata import generate_dataset
22
- import dummy_anndata
23
- import spatialdata_plot as sdp
24
- import spatialdata as sd
25
- import matplotlib.pyplot as plt
26
- import anndata as ad
27
-
28
- # generate anndata
29
- adata = dummy_anndata.generate_dataset(n_obs=12, n_vars=20)
30
-
31
- # generate spatialdata
32
- sdata = generate_dataset(
33
- images = [
34
- {'type': 'rgb', 'scale_factors': [2,2,2], 'coordinate_system': 'global'},
35
- {'type': 'grayscale', 'coordinate_system': 'global'},
36
- ],
37
- labels = [
38
- {'n': 12, 'scale_factors': [2,2,3], 'coordinate_system': 'global2'},
39
- {'n': 12, 'coordinate_system': 'global2'},
40
- ],
41
- shapes = [
42
- {'n': 12, 'type': 'circle', 'coordinate_system': 'global'},
43
- {'n': 20, 'type': 'circle'},
44
- ],
45
- points = [
46
- {'n': 12}
47
- ],
48
- tables = [
49
- {'table': adata, 'element': 'shape', 'element_index': 0}
50
- ],
51
- coordinate_systems = {
52
- 'global': {'transformations': ['affine'], 'shape': {'x': 2000, 'y': 2000}},
53
- 'global2': {'transformations': ['scale', 'translation'], 'shape':{'x': 500, 'y': 500}}
54
- },
55
- SEED=13
56
- )
57
- sdata
58
- ```
59
-
60
- ```
61
- SpatialData object
62
- ├── Images
63
- │ ├── 'image_0': DataTree[cyx] (3, 2000, 2000), (3, 1000, 1000), (3, 500, 500), (3, 250, 250)
64
- │ └── 'image_1': DataTree[cyx] (1, 2000, 2000)
65
- ├── Labels
66
- │ ├── 'label_0': DataTree[yx] (500, 500), (250, 250), (125, 125), (41, 41)
67
- │ └── 'label_1': DataTree[yx] (500, 500)
68
- ├── Points
69
- │ └── 'point_0': DataFrame with shape: (<Delayed>, 2) (2D points)
70
- ├── Shapes
71
- │ ├── 'shape_0': GeoDataFrame shape: (12, 2) (2D shapes)
72
- │ └── 'shape_1': GeoDataFrame shape: (20, 2) (2D shapes)
73
- └── Tables
74
- └── 'table_0': AnnData (12, 20)
75
- with coordinate systems:
76
- ▸ 'global', with elements:
77
- image_0 (Images), image_1 (Images), shape_0 (Shapes)
78
- ▸ 'global2', with elements:
79
- label_0 (Labels), label_1 (Labels)
80
- ▸ 'point_0', with elements:
81
- point_0 (Points)
82
- ▸ 'shape_1', with elements:
83
- shape_1 (Shapes)
84
- ```
85
-
86
- You can plot the demo data now!
87
-
88
- ```{python}
89
- sdata.pl.render_images('image_0').pl.render_shapes('shape_0', color='Gene001', table_name = 'table_0', table_layer = 'float_matrix').pl.show(coordinate_systems = 'global')
90
- ```