comparison spatialdata_operation.xml @ 0:2adfc39ffbac draft default tip

planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/main/tools/spatialdata commit 87bff76d897c5a4277d9987cf26432a18e0458cd-dirty
author iuc
date Sat, 14 Mar 2026 15:15:58 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:2adfc39ffbac
1 <tool id="spatialdata_operation" name="SpatialData Operations" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="@PROFILE@">
2 <description>perform operations on SpatialData objects</description>
3 <macros>
4 <import>macros.xml</import>
5 </macros>
6 <expand macro="requirements"/>
7 <expand macro="creator" />
8 <command detect_errors="exit_code"><![CDATA[
9 mkdir -p input output &&
10 unzip -q '$input_spatialdata' -d input &&
11
12 ## Rename directory to spatialdata if it has a different name
13 dir_name=\$(ls -d input/*/ | head -1 | xargs basename) &&
14 if [ "\$dir_name" != "spatialdata" ]; then
15 mv "input/\$dir_name" input/spatialdata;
16 fi &&
17
18 ## run the operation pipeline
19 cat 'spdata_operation.py' &&
20 python3 'spdata_operation.py'
21 #if $operation_condi.operation in ['bounding_box_query', 'polygon_query', 'concatenate', 'transform', 'aggregate', 'to_circles', 'to_polygons', 'get_centroids', 'join_spatialelement_table', 'match_element_to_table', 'match_table_to_element', 'match_sdata_to_table', 'filter_by_table_query', 'rasterize', 'rasterize_bins', 'rasterize_bins_link_table_to_labels', 'map_raster', 'unpad_raster', 'relabel_sequential', 'sanitize_table', 'import_table', 'add_shape']:
22 && cd output && zip -r ../spatialdata.spatialdata.zip spatialdata/ && cd ..
23 #end if
24 ]]></command>
25 <configfiles>
26 <configfile name="spdata_operation_config" filename="spdata_operation.py">
27 import spatialdata as sd
28
29 ## Load the SpatialData object
30 sdata = sd.read_zarr("./input/spatialdata")
31
32 print("Input SpatialData object:")
33 print(sdata)
34
35 #if $operation_condi.operation == 'bounding_box_query':
36 ## Bounding box query
37 #set axes_list = [str(x.strip()) for x in str($operation_condi.axes).split(',')]
38 #set min_coord_list = [float(x.strip()) for x in str($operation_condi.min_coordinate).split(',')]
39 #set max_coord_list = [float(x.strip()) for x in str($operation_condi.max_coordinate).split(',')]
40 result = sd.bounding_box_query(
41 sdata,
42 axes=tuple($axes_list),
43 min_coordinate=$min_coord_list,
44 max_coordinate=$max_coord_list,
45 target_coordinate_system='$operation_condi.target_coordinate_system',
46 filter_table=$operation_condi.filter_table_bool
47 )
48
49 #else if $operation_condi.operation == 'polygon_query':
50 ## Polygon query
51 from shapely.geometry import Polygon
52 coords_str = '$operation_condi.polygon_coords'
53 coords_list = [tuple(float(y.strip()) for y in x.split(',')) for x in coords_str.split(';')]
54 polygon = Polygon(coords_list)
55 result = sd.polygon_query(
56 sdata,
57 polygon=polygon,
58 target_coordinate_system='$operation_condi.target_coordinate_system',
59 filter_table=$operation_condi.filter_table_bool,
60 clip=$operation_condi.clip_shapes_bool
61 )
62
63 #else if $operation_condi.operation == 'get_values':
64 ## Get values
65 result = sd.get_values(
66 value_key='$operation_condi.value_key',
67 sdata=sdata,
68 element_name='$operation_condi.element_name',
69 #if $operation_condi.table_name:
70 table_name='$operation_condi.table_name',
71 #end if
72 #if $operation_condi.table_layer:
73 table_layer='$operation_condi.table_layer',
74 #end if
75 return_obsm_as_is=$operation_condi.return_obsm_as_is
76 )
77
78 #else if $operation_condi.operation == 'get_element_instances':
79 ## Get element instances
80 element = sdata['$operation_condi.element_name']
81 result = sd.get_element_instances(
82 element,
83 return_background=$operation_condi.return_background_bool
84 )
85
86 #else if $operation_condi.operation == 'get_extent':
87 ## Get extent
88 #if $operation_condi.element_name:
89 result = sd.get_extent(
90 sdata['$operation_condi.element_name'],
91 coordinate_system='$operation_condi.coordinate_system',
92 exact=$operation_condi.exact_bool
93 )
94 #else:
95 result = sd.get_extent(
96 sdata,
97 coordinate_system='$operation_condi.coordinate_system',
98 exact=$operation_condi.exact_bool,
99 has_images=$operation_condi.has_images_bool,
100 has_labels=$operation_condi.has_labels_bool,
101 has_points=$operation_condi.has_points_bool,
102 has_shapes=$operation_condi.has_shapes_bool
103 )
104 #end if
105
106 #else if $operation_condi.operation == 'get_centroids':
107 ## Get centroids
108 element = sdata['$operation_condi.element_name']
109 result_element = sd.get_centroids(
110 element,
111 coordinate_system='$operation_condi.coordinate_system',
112 return_background=$operation_condi.return_background_bool
113 )
114 sanitized_name = sd.sanitize_name('$operation_condi.output_element_name')
115 sdata[sanitized_name] = result_element
116 result = sdata
117
118 #else if $operation_condi.operation == 'join_spatialelement_table':
119 ## Join SpatialElement and table
120 #set element_names_list = [str(x.strip()) for x in str($operation_condi.spatial_element_names).split(',')]
121 elements_dict, result_table = sd.join_spatialelement_table(
122 sdata=sdata,
123 spatial_element_names=$element_names_list,
124 table_name='$operation_condi.table_name',
125 how='$operation_condi.how',
126 match_rows='$operation_condi.match_rows'
127 )
128 ## Update sdata with filtered table
129 table = sdata.update_annotated_regions_metadata(table=result_table,
130 #if $operation_condi.region_key:
131 region_key='$operation_condi.region_key'
132 #end if
133 )
134
135 table_name =sd.sanitize_name('$operation_condi.output_table_name')
136 sdata[f"filtered_{table_name}"] = table
137 sdata[table_name] = result_table
138
139 result = sdata
140
141 #else if $operation_condi.operation == 'match_element_to_table':
142 ## Match element to table
143 #set element_names_list = [str(x.strip()) for x in str($operation_condi.element_names).split(',')]
144 elements_dict, result_table = sd.match_element_to_table(
145 sdata=sdata,
146 element_name=$element_names_list,
147 table_name='$operation_condi.table_name'
148 )
149 for elem_name, elem_data in elements_dict.items():
150 #if str($operation_condi.inplace_bool) == "True":
151 sdata[elem_name] = elem_data
152 #else:
153 sdata[f"matched_{elem_name}"] = elem_data
154 #end if
155
156 result = sdata
157
158 #else if $operation_condi.operation == 'match_table_to_element':
159 ## Match table to element
160 result_table = sd.match_table_to_element(
161 sdata=sdata,
162 element_name='$operation_condi.element_name',
163 table_name='$operation_condi.table_name'
164 )
165 table_name = '$operation_condi.table_name'
166 #if str($operation_condi.inplace_bool) == "True":
167 sdata.tables[f"{table_name}"] = result_table
168 #else:
169 sdata.tables[f"matched_{table_name}"] = result_table
170 #end if
171 result = sdata
172
173 #else if $operation_condi.operation == 'match_sdata_to_table':
174 ## Match SpatialData to table
175 result = sd.match_sdata_to_table(
176 sdata=sdata,
177 table_name='$operation_condi.table_name',
178 how='$operation_condi.how'
179 )
180
181 #else if $operation_condi.operation == 'filter_by_table_query':
182 ## Filter by table query
183 import annsel as an
184
185 result = sd.filter_by_table_query(
186 sdata=sdata,
187 table_name='$operation_condi.table_name',
188 filter_tables=$operation_condi.filter_tables_bool,
189 #if $operation_condi.element_names:
190 #set element_names_list = [str(x.strip()) for x in str($operation_condi.element_names).split(',')]
191 element_names = $element_names_list,
192 #else:
193 element_names = None,
194 #end if
195 #if $operation_condi.obs_expr:
196 obs_expr = $operation_condi.obs_expr,
197 #end if
198 #if $operation_condi.var_expr:
199 var_expr = $operation_condi.var_expr,
200 #end if
201 #if $operation_condi.x_expr:
202 x_expr = $operation_condi.x_expr,
203 #end if
204 #if $operation_condi.obs_names_expr:
205 obs_names_expr = $operation_condi.obs_names_expr,
206 #end if
207 #if $operation_condi.var_names_expr:
208 var_names_expr = $operation_condi.var_names_expr,
209 #end if
210 #if $operation_condi.layer:
211 layer = '$operation_condi.layer',
212 #end if
213 how='$operation_condi.how'
214 )
215
216 #else if $operation_condi.operation == 'concatenate':
217 ## Concatenate multiple SpatialData objects
218 import zipfile
219 import os
220
221 sdatas_list = [sdata]
222 #for i, filepath in enumerate($operation_condi.other_sdatas)
223 os.makedirs(f"./input_{$i}", exist_ok=True)
224 with zipfile.ZipFile('$filepath', 'r') as zip_ref:
225 zip_ref.extractall(f"./input_{$i}")
226 sdata_$i = sd.read_zarr(f"./input_{$i}/spatialdata")
227 sdatas_list.append(sdata_$i)
228 #end for
229 result = sd.concatenate(
230 sdatas=sdatas_list,
231 #if $operation_condi.region_key:
232 region_key='$operation_condi.region_key',
233 #end if
234 #if $operation_condi.instance_key:
235 instance_key='$operation_condi.instance_key',
236 #end if
237 concatenate_tables=$operation_condi.concatenate_tables_bool,
238 obs_names_make_unique=$operation_condi.obs_names_make_unique_bool,
239 modify_tables_inplace=False,
240 merge_coordinate_systems_on_name=$operation_condi.merge_coordinate_systems_on_name_bool
241 #if $operation_condi.attrs_merge:
242 ,attrs_merge='$operation_condi.attrs_merge'
243 #end if
244 )
245
246 #else if $operation_condi.operation == 'transform':
247 ## Transform element
248 element = sdata['$operation_condi.element_name']
249 #if $operation_condi.maintain_positioning_condi.maintain_positioning == 'yes':
250 ## Apply transformation with maintain_positioning=True
251 #if $operation_condi.maintain_positioning_condi.transformation_condi.transformation_type == 'identity':
252 from spatialdata.transformations import Identity
253 transformation = Identity()
254 #else if $operation_condi.maintain_positioning_condi.transformation_condi.transformation_type == 'map_axis':
255 from spatialdata.transformations import MapAxis
256 #set input_axes_list = [str(x.strip()) for x in str($operation_condi.maintain_positioning_condi.transformation_condi.map_axis_input).split(',')]
257 #set output_axes_list = [str(x.strip()) for x in str($operation_condi.maintain_positioning_condi.transformation_condi.map_axis_output).split(',')]
258 map_axis_dict = dict(zip($input_axes_list, $output_axes_list))
259 transformation = MapAxis(map_axis_dict)
260 #else if $operation_condi.maintain_positioning_condi.transformation_condi.transformation_type == 'translation':
261 from spatialdata.transformations import Translation
262 #set translation_list = [float(x.strip()) for x in str($operation_condi.maintain_positioning_condi.transformation_condi.translation).split(',')]
263 #set axes_list = [str(x.strip()) for x in str($operation_condi.maintain_positioning_condi.transformation_condi.axes).split(',')]
264 transformation = Translation($translation_list, axes=tuple($axes_list))
265 #else if $operation_condi.maintain_positioning_condi.transformation_condi.transformation_type == 'scale':
266 from spatialdata.transformations import Scale
267 #set scale_list = [float(x.strip()) for x in str($operation_condi.maintain_positioning_condi.transformation_condi.scale).split(',')]
268 #set axes_list = [str(x.strip()) for x in str($operation_condi.maintain_positioning_condi.transformation_condi.axes).split(',')]
269 transformation = Scale($scale_list, axes=tuple($axes_list))
270 #else if $operation_condi.maintain_positioning_condi.transformation_condi.transformation_type == 'affine':
271 from spatialdata.transformations import Affine
272 import ast
273 #set input_axes_list = [str(x.strip()) for x in str($operation_condi.maintain_positioning_condi.transformation_condi.input_axes).split(',')]
274 #set output_axes_list = [str(x.strip()) for x in str($operation_condi.maintain_positioning_condi.transformation_condi.output_axes).split(',')]
275 matrix = ast.literal_eval('$operation_condi.maintain_positioning_condi.transformation_condi.matrix')
276 transformation = Affine(
277 matrix,
278 input_axes=tuple($input_axes_list),
279 output_axes=tuple($output_axes_list),
280 )
281 #else if $operation_condi.maintain_positioning_condi.transformation_condi.transformation_type == 'sequence':
282 from spatialdata.transformations import Sequence, Identity, MapAxis, Translation, Scale, Affine
283 ## Execute user-provided code to create transformation list
284 transformations_list = eval('$operation_condi.maintain_positioning_condi.transformation_condi.transformations_code')
285 transformation = Sequence(transformations_list)
286 #end if
287 result_element = sd.transform(
288 element,
289 transformation=transformation,
290 maintain_positioning=True
291 )
292 #else:
293 ## Transform to a different coordinate system with maintain_positioning=False
294 result_element = sd.transform(
295 element,
296 to_coordinate_system='$operation_condi.maintain_positioning_condi.to_coordinate_system'
297 )
298 #end if
299
300 sanitized_name = sd.sanitize_name('$operation_condi.output_element_name')
301 sdata[sanitized_name] = result_element
302 result = sdata
303
304
305
306
307 #else if $operation_condi.operation == 'rasterize':
308 ## Rasterize element
309 #set axes_list = [str(x.strip()) for x in str($operation_condi.axes).split(',')]
310 #set min_coord_list = [float(x.strip()) for x in str($operation_condi.min_coordinate).split(',')]
311 #set max_coord_list = [float(x.strip()) for x in str($operation_condi.max_coordinate).split(',')]
312
313 rasterized = sd.rasterize(
314 data='$operation_condi.element_name',
315 axes=tuple($axes_list),
316 min_coordinate=$min_coord_list,
317 max_coordinate=$max_coord_list,
318 target_coordinate_system='$operation_condi.target_coordinate_system',
319 #if $operation_condi.target_unit_to_pixels:
320 target_unit_to_pixels=$operation_condi.target_unit_to_pixels,
321 #end if
322 #if $operation_condi.target_width:
323 target_width=$operation_condi.target_width,
324 #end if
325 #if $operation_condi.target_height:
326 target_height=$operation_condi.target_height,
327 #end if
328 #if $operation_condi.target_depth:
329 target_depth=$operation_condi.target_depth,
330 #end if
331 sdata=sdata,
332 #if $operation_condi.value_key:
333 value_key='$operation_condi.value_key',
334 #end if
335 #if $operation_condi.table_name:
336 table_name='$operation_condi.table_name',
337 #end if
338 #if $operation_condi.agg_func:
339 agg_func='$operation_condi.agg_func',
340 #end if
341 return_regions_as_labels=$operation_condi.return_regions_as_labels_bool,
342 return_single_channel=$operation_condi.return_single_channel_bool
343 )
344 sdata.images['rasterized_' + '$operation_condi.element_name'] = rasterized
345 result = sdata
346
347 #else if $operation_condi.operation == 'rasterize_bins':
348 ## Rasterize bins
349 rasterized = sd.rasterize_bins(
350 sdata=sdata,
351 bins='$operation_condi.bins_element',
352 table_name='$operation_condi.table_name',
353 col_key='$operation_condi.col_key',
354 row_key='$operation_condi.row_key',
355 #if $operation_condi.value_key:
356 value_key='$operation_condi.value_key',
357 #end if
358 return_region_as_labels=$operation_condi.return_regions_as_labels_bool
359 )
360
361 #if str($operation_condi.return_regions_as_labels_bool) == "True":
362 sdata.labels['rasterized_' + '$operation_condi.bins_element'] = rasterized
363 #else:
364 sdata.images['rasterized_' + '$operation_condi.bins_element'] = rasterized
365 #end if
366
367 result = sdata
368
369 #else if $operation_condi.operation == 'rasterize_bins_link_table_to_labels':
370 ## Link table to rasterized labels
371 sd.rasterize_bins_link_table_to_labels(
372 sdata=sdata,
373 table_name='$operation_condi.table_name',
374 rasterized_labels_name='$operation_condi.rasterized_labels_name'
375 )
376 result = sdata
377
378 #else if $operation_condi.operation == 'to_circles':
379 ## Convert to circles
380 element = sdata['$operation_condi.element_name']
381 #if str($operation_condi.radius) != '':
382 result_element = sd.to_circles(element, radius=$operation_condi.radius)
383 #else:
384 result_element = sd.to_circles(element)
385 #end if
386 sanitized_name = sd.sanitize_name('$operation_condi.output_element_name')
387 sdata[sanitized_name] = result_element
388 result = sdata
389
390 #else if $operation_condi.operation == 'to_polygons':
391 ## Convert to polygons
392 ## it is recommended to configure Dask to use ‘processes’ rather than ‘threads’
393 ##import dask
394 ##dask.config.set(scheduler='processes')
395
396 element = sdata['$operation_condi.element_name']
397 #if $operation_condi.buffer_resolution:
398 result_element = sd.to_polygons(element, buffer_resolution=$operation_condi.buffer_resolution)
399 #else:
400 result_element = sd.to_polygons(element)
401 #end if
402 sanitized_name = sd.sanitize_name('$operation_condi.output_element_name')
403 sdata[sanitized_name] = result_element
404 result = sdata
405
406 #else if $operation_condi.operation == 'aggregate':
407 ## Aggregate values by regions
408 result = sd.aggregate(
409 values_sdata=sdata,
410 values='$operation_condi.values_element',
411 by_sdata=sdata,
412 by='$operation_condi.by_element',
413 #if $operation_condi.value_key:
414 value_key='$operation_condi.value_key',
415 #end if
416 agg_func='$operation_condi.agg_func',
417 target_coordinate_system='$operation_condi.target_coordinate_system',
418 fractions=$operation_condi.fractions_bool,
419 region_key='$operation_condi.region_key',
420 instance_key='$operation_condi.instance_key',
421 deepcopy=$operation_condi.deepcopy_bool,
422 #if $operation_condi.table_name:
423 table_name='$operation_condi.table_name',
424 #end if
425 buffer_resolution=$operation_condi.buffer_resolution
426 )
427
428 #else if $operation_condi.operation == 'map_raster':
429 ## Map raster
430 element = sdata['$operation_condi.element_name']
431 import importlib
432 func_module, func_name = '$operation_condi.func_name'.rsplit('.', 1)
433 func = getattr(importlib.import_module(func_module), func_name)
434 mapped = sd.map_raster(
435 data=element,
436 func=func,
437 blockwise=$operation_condi.blockwise_bool,
438 #if $operation_condi.depth:
439 depth=$operation_condi.depth,
440 #end if
441 #if $operation_condi.chunks:
442 chunks=eval('$operation_condi.chunks'),
443 #end if
444 #if $operation_condi.c_coords:
445 #set c_coords_list = [x.strip() for x in str($operation_condi.c_coords).split(',')]
446 ## Try to convert to int, otherwise keep as string
447 #set c_coords_parsed = []
448 #for coord in $c_coords_list:
449 #try:
450 #silent c_coords_parsed.append(int(coord))
451 #except ValueError:
452 #silent c_coords_parsed.append(str(coord))
453 #end try
454 #end for
455 c_coords=$c_coords_parsed,
456 #end if
457 #if $operation_condi.dims:
458 #set dims_list = [str(x.strip()) for x in str($operation_condi.dims).split(',')]
459 dims=tuple($dims_list),
460 #end if
461 #if $operation_condi.transformations:
462 transformations=eval('$operation_condi.transformations'),
463 #end if
464 relabel=$operation_condi.relabel_bool
465 )
466 sdata.images['mapped_' + '$operation_condi.element_name'] = mapped
467 result = sdata
468
469 #else if $operation_condi.operation == 'unpad_raster':
470 ## Unpad raster
471 element = sdata['$operation_condi.element_name']
472 unpadded = sd.unpad_raster(element)
473 sdata.images['unpadded_${operation_condi.element_name}'] = unpadded
474 result = sdata
475
476 #else if $operation_condi.operation == 'relabel_sequential':
477 ## no good example to see how this should work and also when it works, the sdata can not be written
478 ## Relabel sequential
479 import dask.array as da
480 element = sdata['$operation_condi.element_name']
481 relabeled_arr = sd.relabel_sequential(element.data)
482 relabeled = element.copy()
483 relabeled.data = relabeled_arr
484 sanitized_name = sd.sanitize_name('$operation_condi.output_element_name')
485 sdata[sanitized_name] = relabeled
486 result = sdata
487
488 #else if $operation_condi.operation == 'are_extents_equal':
489 ## Check if extents are equal
490 extent1 = sd.get_extent(sdata['$operation_condi.element1_name'], coordinate_system='$operation_condi.coordinate_system')
491 extent2 = sd.get_extent(sdata['$operation_condi.element2_name'], coordinate_system='$operation_condi.coordinate_system')
492 result = sd.are_extents_equal(extent1, extent2, atol=$operation_condi.atol)
493
494 #else if $operation_condi.operation == 'get_pyramid_levels':
495 ## no good example to see how this should work and also when it works, the sdata can not be written
496 ## Get pyramid levels
497 element = sdata.images['$operation_condi.element_name']
498 result = sd.get_pyramid_levels(
499 element,
500 #if $operation_condi.attr:
501 attr='$operation_condi.attr',
502 #end if
503 #if $operation_condi.n:
504 n=$operation_condi.n
505 #end if
506 )
507 result[f"pyramid_{$operation_condi.element_name}"] = result.pop('pyramid')
508
509 #else if $operation_condi.operation == 'sanitize_table':
510 ## Sanitize table
511 adata = sdata['$operation_condi.table_name']
512 sd.sanitize_table(adata, inplace=True)
513 sdata.tables['$operation_condi.table_name'] = adata
514 result = sdata
515
516 #else if $operation_condi.operation == 'export_table':
517 ## Export table to anndata
518 result = sdata['$operation_condi.table_name']
519 result.write_h5ad('./output/anndata.h5ad', compression='gzip')
520
521 #else if $operation_condi.operation == 'import_table':
522 ## Import anndata table
523 import anndata as ad
524 adata = ad.read_h5ad('$operation_condi.adata')
525
526 table_name = sd.sanitize_name('$operation_condi.table_name')
527 sdata[table_name] = adata
528 result = sdata
529
530 #else if $operation_condi.operation == 'add_shape':
531 ## Add shape to SpatialData
532 from spatialdata.models import ShapesModel
533 shape_data = ShapesModel.parse('$operation_condi.shape')
534 element_name = sd.sanitize_name('$operation_condi.element_name')
535 sdata[element_name] = shape_data
536 result = sdata
537
538 #end if
539
540 print("\nOperation result:")
541 print(result)
542
543 ## Save the result
544 #if $operation_condi.operation in ['bounding_box_query', 'polygon_query', 'concatenate', 'transform', 'aggregate', 'to_circles', 'to_polygons', 'get_centroids', 'join_spatialelement_table', 'match_element_to_table', 'match_table_to_element', 'match_sdata_to_table', 'filter_by_table_query', 'rasterize', 'rasterize_bins', 'rasterize_bins_link_table_to_labels', 'map_raster', 'unpad_raster', 'relabel_sequential', 'sanitize_table', 'import_table', 'add_shape']:
545 result.write("./output/spatialdata", overwrite=True)
546
547 #else if $operation_condi.operation in ['get_values']:
548 import pandas as pd
549 ## Save DataFrame as TSV
550 if isinstance(result, pd.DataFrame):
551 result.to_csv('./output/result.tabular', sep='\t', index=True)
552 else:
553 ## If result is a Series or other, convert to DataFrame
554 pd.DataFrame(result).to_csv('./output/result.tabular', sep='\t', index=True)
555
556 #else if $operation_condi.operation in ['get_extent', 'get_element_instances', 'are_extents_equal', 'get_pyramid_levels']:
557 import json
558 import pandas as pd
559 import numpy as np
560
561 class NumpyEncoder(json.JSONEncoder):
562 def default(self, obj):
563 if isinstance(obj, np.integer):
564 return int(obj)
565 if isinstance(obj, np.floating):
566 return float(obj)
567 if isinstance(obj, np.ndarray):
568 return obj.tolist()
569 if isinstance(obj, pd.Series):
570 return obj.tolist()
571 if isinstance(obj, pd.Index):
572 return obj.tolist()
573 if isinstance(obj, pd.DataFrame):
574 return obj.to_dict(orient='records')
575 return super(NumpyEncoder, self).default(obj)
576
577 with open('./output/result.json', 'w') as f:
578 json.dump(result, f, cls=NumpyEncoder, indent=2)
579 #end if
580
581 print("\nOperation completed successfully!")
582 </configfile>
583 </configfiles>
584 <inputs>
585 <expand macro="input_spatialdata"/>
586 <conditional name="operation_condi">
587 <param name="operation" type="select" label="Operation">
588 <option value="bounding_box_query">Query a SpatialData object or SpatialElement within a bounding box. (sd.bounding_box_query)</option>
589 <option value="polygon_query">Query a SpatialData object or a SpatialElement by a polygon or multipolygon. (sd.polygon_query)</option>
590 <option value="get_values">Get the values from the element, from any location: df columns, obs or var columns (table). (sd.get_values)</option>
591 <option value="get_element_instances">Get the instances (index values) of the SpatialElement. (sd.get_element_instances)</option>
592 <option value="get_extent">Get the extent (bounding box) of a SpatialData object or a SpatialElement. (sd.get_extent)</option>
593 <option value="get_centroids">Get the centroids of the geometries contained in a SpatialElement, as a new Points element. (sd.get_centroids)</option>
594 <option value="join_spatialelement_table">Perform SQL like joins of SpatialElements and a table. (sd.join_spatialelement_table)</option>
595 <option value="match_element_to_table">Filter the elements and make the indices match those in the table. (sd.match_element_to_table)</option>
596 <option value="match_table_to_element">Filter the table and reorders the rows to match the instances (rows/labels) of the specified SpatialElement. (sd.match_table_to_element)</option>
597 <option value="match_sdata_to_table">Filter the elements of a SpatialData object to match only the rows present in the table. (sd.match_sdata_to_table)</option>
598 <!-- will be available in next release -->
599 <option value="filter_by_table_query">Filter the SpatialData object based on a set of table queries. (sd.filter_by_table_query)</option>
600 <option value="concatenate">Concatenate a list of spatial data objects (sd.concatenate)</option>
601 <option value="transform">Transform a SpatialElement using the transformation to a coordinate system, and returns the transformed element. (sd.transform)</option>
602 <option value="rasterize">Rasterize a SpatialData object or a SpatialElement (image, labels, points, shapes). (sd.rasterize)</option>
603 <option value="rasterize_bins">Rasterizes grid-like binned shapes/points annotated by a table (e.g. Visium HD data). (sd.rasterize_bins)</option>
604 <option value="rasterize_bins_link_table_to_labels">Change the annotation target of the table to the rasterized labels. (sd.rasterize_bins_link_table_to_labels)</option>
605 <option value="to_circles">Convert a set of geometries (2D/3D labels, 2D shapes) to approximated circles/spheres. (sd.to_circles)</option>
606 <option value="to_polygons">Convert a set of geometries (2D labels, 2D shapes) to approximated 2D polygons/multypolygons. (sd.to_polygons)</option>
607 <option value="aggregate">Aggregate values by given region. (sd.aggregate)</option>
608 <option value="map_raster">Apply a callable to raster data. (sd.map_raster)</option>
609 <option value="unpad_raster">Remove padding from a raster type that was eventually added by the rotation component of a transformation. (sd.unpad_raster)</option>
610 <!-- no good example to see how this should work and also when it works, the sdata can not be written
611 <option value="relabel_sequential">Relabels integers in a Dask array sequentially. (sd.relabel_sequential)</option> -->
612 <option value="are_extents_equal">Check if two data extents, as returned by get_extent() are equal up to approximation errors. (sd.are_extents_equal)</option>
613 <!-- no good example to see how this should work and also when it works, the sdata can not be written
614 <option value="get_pyramid_levels">Access the data/attribute of the pyramid levels of a multiscale spatial image. (sd.get_pyramid_levels)</option> -->
615 <option value="sanitize_table">Sanitize all keys in an AnnData table to comply with SpatialData naming rules. (sd.sanitize_table)</option>
616 <option value="export_table">Export the table of a SpatialData object to anndata</option>
617 <option value="import_table">Import anndata table to a SpatialData object</option>
618 <option value="add_shape">Add a shape to a SpatialData object</option>
619 </param>
620 <when value="bounding_box_query">
621 <param name="axes" type="text" value="x,y" label="Axes" help="Comma-separated list of axes that min_coordinate and max_coordinate refer to (e.g., 'x,y' or 'x,y,z')">
622 <expand macro="sanitize_query"/>
623 </param>
624 <param name="min_coordinate" type="text" label="Minimum coordinates" help="Comma-separated minimum coordinates along all dimensions (e.g., '0,0')">
625 <expand macro="sanitize_digits"/>
626 </param>
627 <param name="max_coordinate" type="text" label="Maximum coordinates" help="Comma-separated maximum coordinates along all dimensions (e.g., '100,100')">
628 <expand macro="sanitize_digits"/>
629 </param>
630 <param name="target_coordinate_system" type="text" value="global" label="Target coordinate system" help="The coordinate system the bounding box is defined in">
631 <expand macro="sanitize_query"/>
632 </param>
633 <param name="filter_table_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Filter table?" help="If True, the table is filtered to only contain rows annotating regions within the bounding box"/>
634 </when>
635 <when value="polygon_query">
636 <param name="polygon_coords" type="text" label="Polygon coordinates" help="Semicolon-separated list of coordinate pairs (x,y). Example: '0,0;100,0;100,100;0,100' for a square">
637 <expand macro="sanitize_digits">
638 <add value=";"/>
639 </expand>
640 </param>
641 <expand macro="param_target_coordinate_system" help="The coordinate system of the polygon"/>
642 <param name="filter_table_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Filter table?" help="Filter tables to only include tables annotating elements in the query result"/>
643 <param name="clip_shapes_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Clip shapes?" help="If True, shapes are clipped to the polygon. This behavior is implemented only when querying polygons/multipolygons or circles, and it is ignored for other types of elements (images, labels, points). Importantly, when clipping is enabled, the circles will be converted to polygons before the clipping. This may affect downstream operations that rely on the circle radius or on performance, so it is recommended to disable clipping when querying circles or when querying a SpatialData object that contains circles."/>
644 </when>
645 <when value="get_values">
646 <param name="value_key" type="text" optional="false" label="Value key" help="Column name(s) to retrieve values from">
647 <expand macro="sanitize_query"/>
648 </param>
649 <param name="element_name" type="text" label="Element name" help="Name of the element to get values from">
650 <validator type="empty_field"/>
651 <expand macro="sanitize_query"/>
652 </param>
653 <param name="table_name" type="text" optional="true" label="Table name (optional)" help="Name of table containing the value_key">
654 <expand macro="sanitize_query"/>
655 </param>
656 <param name="table_layer" type="text" optional="true" label="Table layer (optional)" help="Layer of table to get values from. If None, values from X are used">
657 <expand macro="sanitize_query"/>
658 </param>
659 <param name="return_obsm_as_is" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Return_obsm_as_is" help="In case the value is in obsm the value of the key can be returned as is if return_obsm_as_is is True, otherwise creates a dataframe and returns it." />
660 </when>
661 <when value="get_element_instances">
662 <expand macro="param_element_name" help="Name of the element to get instances from">
663 <validator type="empty_field"/>
664 </expand>
665 <param name="return_background_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Include background?" help="If True, background label (0) is included"/>
666 </when>
667 <when value="get_extent">
668 <expand macro="param_element_name" optional="true" label="Element name (optional)" help="Name of a specific element to get extent from. Leave empty to get extent of entire SpatialData object"/>
669 <expand macro="param_coordinate_system"/>
670 <param name="exact_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Compute exact extent?" help="If False, an approximation faster to compute is given"/>
671 <param name="has_images_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Include images?" help="Include images in extent computation (only for SpatialData objects)"/>
672 <param name="has_labels_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Include labels?" help="Include labels in extent computation (only for SpatialData objects)"/>
673 <param name="has_points_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Include points?" help="Include points in extent computation (only for SpatialData objects)"/>
674 <param name="has_shapes_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Include shapes?" help="Include shapes in extent computation (only for SpatialData objects)"/>
675 </when>
676 <when value="get_centroids">
677 <expand macro="param_element_name" help="Name of the element to get centroids from"/>
678 <expand macro="param_output_element_name" value="centroids_points" help="Name for the centroids points element"/>
679 <expand macro="param_coordinate_system"/>
680 <param name="return_background_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Include background?" help="If True, centroid of background label (0) is included"/>
681 </when>
682 <when value="join_spatialelement_table">
683 <param name="spatial_element_names" type="text" optional="false" label="Spatial element name(s)" help="Comma-separated list of element names to join with table">
684 <validator type="empty_field"/>
685 <expand macro="sanitize_query"/>
686 </param>
687 <expand macro="param_table_name"/>
688 <expand macro="param_region_key" value="" optional="true" help="The column in table.obs containing the rows specifying the SpatialElements being annotated. If None the current value for region_key in the annotation metadata of the table is used. If specified but different from the current region_key, the current region_key is overwritten."/>
689 <expand macro="param_join_type" selected="left"/>
690 <param name="match_rows" type="select" label="Match rows">
691 <option value="no" selected="true">No</option>
692 <option value="left">Left (element indices priority)</option>
693 <option value="right">Right (table instance IDs priority)</option>
694 </param>
695 <param name="output_table_name" type="text" value="out_table" label="Output table name">
696 <expand macro="sanitize_query"/>
697 </param>
698 </when>
699 <when value="match_element_to_table">
700 <param name="element_names" type="text" label="Element name(s)" help="Comma-separated list of element names to match to table">
701 <expand macro="sanitize_query"/>
702 </param>
703 <expand macro="param_table_name"/>
704 <param name="inplace_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Overwrite existing element?" help="If True, the element is overwritten in-place. If False, a new element is created." />
705 </when>
706 <when value="match_table_to_element">
707 <expand macro="param_element_name" help="Name of element to match table to"/>
708 <expand macro="param_table_name"/>
709 <param name="inplace_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Overwrite existing table?" help="If True, the table is overwritten in-place. If False, a new table is created." />
710 </when>
711 <when value="match_sdata_to_table">
712 <expand macro="param_table_name"/>
713 <param name="how" type="select" label="Join type">
714 <option value="right" selected="true">Right</option>
715 <option value="left">Left</option>
716 <option value="left_exclusive">Left Exclusive</option>
717 <option value="inner">Inner</option>
718 <option value="right_exclusive">Right Exclusive</option>
719 </param>
720 </when>
721 <when value="filter_by_table_query">
722 <expand macro="param_table_name" value="table"/>
723 <param name="filter_tables_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Filter tables?" help="Filter table to contain only rows annotating regions in element_names"/>
724 <param name="element_names" type="text" optional="true" label="Element names (optional)" help="Comma-separated list of element names to filter by">
725 <expand macro="sanitize_query"/>
726 </param>
727 <param name="obs_expr" type="text" optional="true" label="Obs expression (optional)" help="Narwhals expression to filter .obs (e.g., an.col('cell_type') == 'A' or an.col('region') == 'blobs_labels'). Use an.col() to reference columns.">
728 <sanitizer>
729 <valid initial="string.printable">
730 </valid>
731 </sanitizer>
732 </param>
733 <param name="var_expr" type="text" optional="true" label="Var expression (optional)" help="Narwhals expression to filter .var">
734 <expand macro="sanitize_query"/>
735 </param>
736 <param name="x_expr" type="text" optional="true" label="X expression (optional)" help="Narwhals expression to filter .X expression matrix (e.g., an.col('channel_0_sum') > 125). Use an.col() to reference columns.">
737 <expand macro="sanitize_query"/>
738 </param>
739 <param name="obs_names_expr" type="text" optional="true" label="Obs names expression (optional)" help="Narwhals expression to filter .obs_names">
740 <expand macro="sanitize_query"/>
741 </param>
742 <param name="var_names_expr" type="text" optional="true" label="Var names expression (optional)" help="Narwhals expression to filter .var_names">
743 <expand macro="sanitize_query"/>
744 </param>
745 <param name="layer" type="text" value="table" label="The layer of the anndata.AnnData to filter the SpatialData object by" help="Only used with x_expr">
746 <expand macro="sanitize_query"/>
747 </param>
748 <param name="how" type="select" label="Join type">
749 <option value="right" selected="true">Right</option>
750 <option value="left">Left</option>
751 <option value="left_exclusive">Left Exclusive</option>
752 <option value="inner">Inner</option>
753 <option value="right_exclusive">Right Exclusive</option>
754 </param>
755 </when>
756 <when value="concatenate">
757 <param name="other_sdatas" type="data" format="spatialdata.zip" multiple="true" label="Other SpatialData objects to concatenate"/>
758 <param name="region_key" type="text" optional="true" label="Region key (optional)" help="The key to use for the region column in the concatenated object">
759 <expand macro="sanitize_query"/>
760 </param>
761 <param name="instance_key" type="text" optional="true" label="Instance key (optional)" help="The key to use for the instance column in the concatenated object">
762 <expand macro="sanitize_query"/>
763 </param>
764 <param name="concatenate_tables_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Concatenate tables?" help="Whether to merge the tables in case of having the same element name"/>
765 <param name="obs_names_make_unique_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Make obs names unique?" help="Whether to make the obs_names unique"/>
766 <param name="merge_coordinate_systems_on_name_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Merge coordinate systems on name?" help="Whether to keep coordinate system names unchanged (True) or add suffixes (False)"/>
767 <param name="attrs_merge" type="select" optional="true" label="Attributes merge strategy (optional)">
768 <option value="same">Same - all must be identical</option>
769 <option value="unique">Unique - keep values that appear only once</option>
770 <option value="first">First - use first non-missing value</option>
771 <option value="only">Only - use value if only one dataset has it</option>
772 </param>
773 </when>
774 <when value="transform">
775 <expand macro="param_element_name" help="Name of the element to transform"/>
776 <expand macro="param_output_element_name" value="transformed_element" help="Name for the transformed element"/>
777 <conditional name="maintain_positioning_condi">
778 <param name="maintain_positioning" type="select" label="Maintain positioning?">
779 <option value="yes">Yes - Apply transformation while maintaining positioning in existing coordinate systems</option>
780 <option value="no" selected="true">No - Transform to a different coordinate system</option>
781 </param>
782 <when value="yes">
783 <conditional name="transformation_condi">
784 <param name="transformation_type" type="select" label="Transformation type">
785 <option value="identity">Identity - No transformation</option>
786 <option value="map_axis">MapAxis - Map input axes to output axes</option>
787 <option value="translation">Translation</option>
788 <option value="scale">Scale</option>
789 <option value="affine">Affine - General affine transformation with matrix</option>
790 <option value="sequence">Sequence - Compose multiple transformations (Advanced)</option>
791 </param>
792 <when value="identity">
793 <!-- Identity transformation has no parameters -->
794 </when>
795 <when value="map_axis">
796 <param name="map_axis_input" type="text" label="Input axes" help="Comma-separated list of input axes (e.g., 'x,y,z')">
797 <expand macro="sanitize_query"/>
798 </param>
799 <param name="map_axis_output" type="text" label="Output axes" help="Comma-separated list of output axes corresponding to input axes (e.g., 'y,x,z' to swap x and y)">
800 <expand macro="sanitize_query"/>
801 </param>
802 </when>
803 <when value="translation">
804 <param name="translation" type="text" label="Translation vector" help="Comma-separated translation values (e.g., '10,20' for 2D)">
805 <expand macro="sanitize_digits"/>
806 </param>
807 <param name="axes" type="text" value="x,y" label="Axes" help="Comma-separated list of axes that the translation applies to (e.g., 'x,y')">
808 <expand macro="sanitize_query"/>
809 </param>
810 </when>
811 <when value="scale">
812 <param name="scale" type="text" label="Scale factors" help="Comma-separated scale values (e.g., '2,2' for 2D)">
813 <expand macro="sanitize_digits"/>
814 </param>
815 <param name="axes" type="text" value="x,y" label="Axes" help="Comma-separated list of axes that the scale applies to (e.g., 'x,y' or 'y' for single axis)">
816 <expand macro="sanitize_query"/>
817 </param>
818 </when>
819 <when value="affine">
820 <param name="matrix" type="text" label="Affine matrix" help="Affine transformation matrix as nested lists, e.g., '[[1,0,0],[0,1,0],[0,0,1]]' for 2D identity. For 2D rotation by angle θ: [[cos(θ),-sin(θ),0],[sin(θ),cos(θ),0],[0,0,1]]">
821 <expand macro="sanitize_query"/>
822 </param>
823 <param name="input_axes" type="text" value="x,y" label="Input axes" help="Comma-separated list of input axes (e.g., 'x,y')">
824 <expand macro="sanitize_query"/>
825 </param>
826 <param name="output_axes" type="text" value="x,y" label="Output axes" help="Comma-separated list of output axes (e.g., 'x,y')">
827 <expand macro="sanitize_query"/>
828 </param>
829 </when>
830 <when value="sequence">
831 <param name="transformations_code" type="text" area="true" label="Transformations list (Python code)" help="Python code to create a list of transformations. Example: [Translation([10,20], axes=('x','y')), Scale([2,2], axes=('x','y'))]. Available: Identity(), MapAxis({...}), Translation([...], axes=(...)), Scale([...], axes=(...)), Affine(matrix, input_axes=(...), output_axes=(...)). Advanced usage only.">
832 <expand macro="sanitize_query"/>
833 </param>
834 </when>
835 </conditional>
836 </when>
837 <when value="no">
838 <param name="to_coordinate_system" type="text" value="global" label="Target coordinate system" help="The coordinate system to which the data should be transformed. Must be present in the element.">
839 <expand macro="sanitize_query"/>
840 </param>
841 </when>
842 </conditional>
843 </when>
844 <when value="rasterize">
845 <expand macro="param_element_name" help="Name of element to rasterize"/>
846 <expand macro="param_axes"/>
847 <expand macro="coordinate_bounds_params"/>
848 <expand macro="param_target_coordinate_system"/>
849 <param name="target_unit_to_pixels" type="float" optional="true" label="Target unit to pixels (optional)" help="Pixels per unit"/>
850 <param name="target_width" type="float" min="0" optional="true" label="Target width (optional)" help="Width of the rasterized image in pixels"/>
851 <param name="target_height" type="float" min="0" optional="true" label="Target height (optional)" help="Height of the rasterized image in pixels"/>
852 <param name="target_depth" type="float" min="0" optional="true" label="Target depth (optional)" help="Depth of the rasterized image in pixels. Only used for 3D rasterization"/>
853 <expand macro="param_value_key" optional="true" label="Value key (optional)" help="Column name containing values to aggregate"/>
854 <expand macro="param_table_name" value="" optional="true" label="Table name (optional)" help="The table optionally containing the value_key and the name of the table in the returned SpatialData object"/>
855 <expand macro="param_agg_func" optional="true" help="Available only when rasterizing points and shapes."/>
856 <param name="return_regions_as_labels_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Return as labels?" help="Return as labels (y,x) instead of image (c,y,x)"/>
857 <param name="return_single_channel_bool" type="boolean" truevalue="True" falsevalue="None" checked="false" label="Return single channel?" help="Only used when rasterizing points and shapes and when value_key refers to a categorical column. If False, each category will be rasterized in a separate channel." />
858 </when>
859 <when value="rasterize_bins">
860 <param name="bins_element" type="text" label="Bins element name" help="Name of grid-like binned element">
861 <expand macro="sanitize_query"/>
862 </param>
863 <expand macro="param_table_name"/>
864 <param name="col_key" type="text" label="Column key" help="Column in table.obs with column indices">
865 <expand macro="sanitize_query"/>
866 </param>
867 <param name="row_key" type="text" label="Row key" help="Column in table.obs with row indices">
868 <expand macro="sanitize_query"/>
869 </param>
870 <param name="value_key" type="text" optional="true" label="Value key(s) (optional)" help="Obs columns or var names to rasterize. If None, all the var names will be used, and the returned object will be lazily constructed. Ignored if return_regions_as_labels_bool is True">
871 <expand macro="sanitize_query"/>
872 </param>
873 <param name="return_regions_as_labels_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Return as labels?" help="If False this function returns a xarray.DataArray of shape (c, y, x) with dimension of c equal to the number of key(s) specified in value_key, or the number of var names in table_name if value_key is None. If True, will return labels of shape (y, x), where each bin of the bins element will be represented as a pixel."/>
874 </when>
875 <when value="rasterize_bins_link_table_to_labels">
876 <expand macro="param_table_name"/>
877 <param name="rasterized_labels_name" type="text" label="Rasterized labels element name" help="Name of the rasterized labels element created by rasterize_bins">
878 <expand macro="sanitize_query"/>
879 </param>
880 </when>
881 <when value="to_circles">
882 <expand macro="param_element_name" help="Name of the element to convert to circles"/>
883 <expand macro="param_output_element_name" value="circle_element"/>
884 <param name="radius" type="float" min="0" optional="true" label="Radius (optional)" help="Radius for circles. Required for points, automatic for other elements"/>
885 </when>
886 <when value="to_polygons">
887 <expand macro="param_element_name" help="Name of the element to convert to polygons"/>
888 <expand macro="param_output_element_name" value="polygon_element" help="Name for the polygons element"/>
889 <param name="buffer_resolution" type="integer" optional="true" min="1" label="Buffer resolution" help="Resolution for converting circles to polygons"/>
890 </when>
891 <when value="aggregate">
892 <param name="values_element" type="text" label="Values element name" help="Name of the element of spatialdata containing values to aggregate">
893 <expand macro="sanitize_query"/>
894 </param>
895 <param name="by_element" type="text" label="Regions element name" help="Name of the element defining regions to aggregate by">
896 <expand macro="sanitize_query"/>
897 </param>
898 <expand macro="param_value_key" optional="true" label="Value key (optional)" help="Column name containing values to aggregate. Leave empty to count occurrences"/>
899 <expand macro="param_agg_func" optional="false"/>
900 <expand macro="param_target_coordinate_system"/>
901 <param name="fractions_bool" type="boolean" truevalue="True" falsevalue="False" checked="false" label="Adjust for partial overlap?" help="If True, values are weighted by overlap fraction"/>
902 <expand macro="param_region_key" help="Name for the region column in output table"/>
903 <expand macro="param_instance_key" help="Name for the instance ID column in output table"/>
904 <expand macro="param_table_name" value="" optional="true" label="Table name (optional)" help="Table containing the value_key"/>
905 <param name="deepcopy_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Deep copy shapes?" help="Whether to deepcopy shapes in result"/>
906 <param name="buffer_resolution" type="integer" min="0" value="16" label="Resolution" help=" A higher value results in a more accurate representation of the circle, but also in a more complex polygon and computation." />
907 </when>
908 <when value="map_raster">
909 <expand macro="param_element_name" label="Raster element name"/>
910 <param name="func_name" type="text" label="Function name" help="Name of numpy/scipy function to apply (e.g., 'numpy.mean')">
911 <expand macro="sanitize_query"/>
912 </param>
913 <param name="blockwise_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Process blockwise?" help="If True, func will be distributed with dask.array.map_overlap() or dask.array.map_blocks(), otherwise func is applied to the full data. If False, depth and chunks are ignored."/>
914 <param name="depth" type="integer" min="0" optional="true" label="Overlap between chunks (optional)" help="the number of elements that each chunk should share with its neighboring chunks"/>
915 <param name="chunks" type="text" optional="true" label="Chunks (optional)" help="Chunk shape of resulting blocks if the callable does not preserve the data shape. Format: nested tuples like '((1,),(100,),(100,))' for shape (1,100,100). Passed to dask.array.map_overlap() or dask.array.map_blocks(). Ignored if blockwise is False.">
916 <expand macro="sanitize_query"/>
917 </param>
918 <param name="c_coords" type="text" optional="true" label="Channel coordinates (optional)" help="Comma-separated channel coordinates for output data (integers or strings). If not provided, input channel coordinates are used. Required if func changes number of channels.">
919 <expand macro="sanitize_query"/>
920 </param>
921 <param name="dims" type="text" optional="true" label="Output dimensions (optional)" help="Comma-separated dimensions of output data (e.g., 'c,y,x' or 'y,x'). If not provided, input dimensions are used. Must be specified if callable changes dimensions.">
922 <expand macro="sanitize_query"/>
923 </param>
924 <param name="transformations" type="text" optional="true" label="Transformations JSON (optional)" help="JSON string for output transformations. If not provided, input transformations are copied. Should be specified if callable changes transformations.">
925 <expand macro="sanitize_query"/>
926 </param>
927 <param name="relabel_bool" type="boolean" truevalue="True" falsevalue="False" checked="true" label="Relabel blocks?" help="Whether to relabel blocks of output data. Ignored when output is not a labels layer. Recommended if func returns labels not unique across chunks."/>
928 </when>
929 <when value="unpad_raster">
930 <expand macro="param_element_name" label="Raster element name" help="Name of raster element to unpad"/>
931 </when>
932 <!-- no good example to see how this should work and also when it works, the sdata can not be written
933 <when value="relabel_sequential">
934 <param name="element_name" type="text" label="Labels element name" help="Name of labels element to relabel. Note that currently if a cell or entity to be labeled is split across adjacent chunks the same label is not assigned to the cell across blocks.">
935 <expand macro="sanitize_query"/>
936 </param>
937 <param name="output_element_name" type="text" value="relabeled_element" label="Output element name">
938 <expand macro="sanitize_query"/>
939 </param>
940 </when> -->
941 <when value="are_extents_equal">
942 <param name="element1_name" type="text" label="First element name">
943 <expand macro="sanitize_query"/>
944 </param>
945 <param name="element2_name" type="text" label="Second element name">
946 <expand macro="sanitize_query"/>
947 </param>
948 <expand macro="param_coordinate_system"/>
949 <param name="atol" type="float" value="0.1" label="Absolute tolerance"/>
950 </when>
951 <!-- no good example to see how this should work and also when it works, the sdata can not be written
952 <when value="get_pyramid_levels">
953 <param name="element_name" type="text" label="Multiscale image element name">
954 <expand macro="sanitize_query"/>
955 </param>
956 <param name="attr" type="text" optional="true" label="Attribute name (optional)" help="Return specific attribute instead of data. If None, return the data of the pyramid level as a DataArray, if not None, return the specified attribute within the DataArray data.">
957 <expand macro="sanitize_query"/>
958 </param>
959 <param name="n" type="integer" min="0" optional="true" label="Level number (optional)" help="Return only specific pyramid level"/>
960 </when> -->
961 <when value="sanitize_table">
962 <expand macro="param_table_name"/>
963 </when>
964 <when value="export_table">
965 <expand macro="param_table_name"/>
966 </when>
967 <when value="import_table">
968 <param name="adata" type="data" format="h5ad" label="annotated data object to add"/>
969 <expand macro="param_table_name" help="If a table name in the spatialdata is used, it will overwite"/>
970 </when>
971 <when value="add_shape">
972 <expand macro="param_element_name" help="Name of the element to add shape to"/>
973 <param name="shape" type="data" format="geojson" label="Shapes annotations"/>
974 </when>
975 </conditional>
976 </inputs>
977 <outputs>
978 <data name="spatialdata_output" format="spatialdata.zip" from_work_dir="spatialdata.spatialdata.zip" label="${tool.name} on ${on_string}: ${operation_condi.operation}">
979 <filter>operation_condi['operation'] in ['bounding_box_query', 'polygon_query', 'concatenate', 'transform', 'aggregate', 'to_circles', 'to_polygons', 'get_centroids', 'join_spatialelement_table', 'match_element_to_table', 'match_table_to_element', 'match_sdata_to_table', 'filter_by_table_query', 'rasterize', 'rasterize_bins', 'rasterize_bins_link_table_to_labels', 'map_raster', 'unpad_raster', 'relabel_sequential', 'sanitize_table', 'import_table', 'add_shape']</filter>
980 </data>
981 <data name="result_tabular" format="tabular" from_work_dir="output/result.tabular" label="${tool.name} on ${on_string}: ${operation_condi.operation} tabular result">
982 <filter>operation_condi['operation'] == 'get_values'</filter>
983 </data>
984 <data name="result_json" format="json" from_work_dir="output/result.json" label="${tool.name} on ${on_string}: ${operation_condi.operation} json result">
985 <filter>operation_condi['operation'] in ['get_extent', 'get_element_instances', 'are_extents_equal', 'get_pyramid_levels']</filter>
986 </data>
987 <data name="result_adata" format="h5ad" from_work_dir="output/anndata.h5ad" label="${tool.name} on ${on_string}: ${operation_condi.operation} anndata result">
988 <filter>operation_condi['operation'] == 'export_table'</filter>
989 </data>
990 </outputs>
991 <tests>
992 <!-- Test 1: bounding_box_query -->
993 <test expect_num_outputs="1">
994 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
995 <conditional name="operation_condi">
996 <param name="operation" value="bounding_box_query"/>
997 <param name="axes" value="x,y"/>
998 <param name="min_coordinate" value="0,0"/>
999 <param name="max_coordinate" value="100,100"/>
1000 <param name="target_coordinate_system" value="global"/>
1001 </conditional>
1002 <assert_stdout>
1003 <has_text text="bounding_box_query"/>
1004 <has_text text="axes=tuple([&apos;x&apos;, &apos;y&apos;])"/>
1005 <has_text text="min_coordinate=[0.0, 0.0]"/>
1006 <has_text text="max_coordinate=[100.0, 100.0]"/>
1007 <has_text text="target_coordinate_system=&apos;global&apos;"/>
1008 <has_text text="target_coordinate_system=&apos;global&apos;"/>
1009 <has_text text="filter_table=True"/>
1010 </assert_stdout>
1011 <output name="spatialdata_output">
1012 <assert_contents>
1013 <has_size value="55000" delta="1000"/>
1014 </assert_contents>
1015 </output>
1016 </test>
1017 <!-- Test 2: polygon_query -->
1018 <test expect_num_outputs="1">
1019 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1020 <conditional name="operation_condi">
1021 <param name="operation" value="polygon_query"/>
1022 <param name="polygon_coords" value="0,0;100,0;100,100;0,100"/>
1023 <param name="target_coordinate_system" value="global"/>
1024 </conditional>
1025 <assert_stdout>
1026 <has_text text="polygon_query"/>
1027 <has_text text="from shapely.geometry import Polygon"/>
1028 <has_text text="0,0;100,0;100,100;0,100"/>
1029 <has_text text="clip=False"/>
1030 <has_text text="Operation completed successfully"/>
1031 </assert_stdout>
1032 <output name="spatialdata_output">
1033 <assert_contents>
1034 <has_size value="50000" delta="10000"/>
1035 </assert_contents>
1036 </output>
1037 </test>
1038 <!-- Test 3: get_values -->
1039 <test expect_num_outputs="1">
1040 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1041 <conditional name="operation_condi">
1042 <param name="operation" value="get_values"/>
1043 <param name="value_key" value="ABCC11"/>
1044 <param name="element_name" value="cell_labels"/>
1045 <param name="table_name" value="table"/>
1046 </conditional>
1047 <assert_stdout>
1048 <has_text text="get_values"/>
1049 <has_text_matching expression="value_key='ABCC11',\n sdata=sdata,\n element_name='cell_labels',\n table_name='table',\n return_obsm_as_is=False"/>
1050 <has_text text="Operation completed successfully"/>
1051 </assert_stdout>
1052 <output name="result_tabular">
1053 <assert_contents>
1054 <has_n_lines n="359"/>
1055 <has_n_columns n="2"/>
1056 <has_text text="ABCC11"/>
1057 </assert_contents>
1058 </output>
1059 </test>
1060 <!-- Test 4: get_element_instances -->
1061 <test expect_num_outputs="1">
1062 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1063 <conditional name="operation_condi">
1064 <param name="operation" value="get_element_instances"/>
1065 <param name="element_name" value="cell_labels"/>
1066 <param name="return_background_bool" value="false"/>
1067 </conditional>
1068 <assert_stdout>
1069 <has_text text="get_element_instances"/>
1070 <has_text_matching expression=" element,\n return_background=False"/>
1071 <has_text text="Operation completed successfully"/>
1072 </assert_stdout>
1073 <output name="result_json">
1074 <assert_contents>
1075 <has_n_lines n="360"/>
1076 </assert_contents>
1077 </output>
1078 </test>
1079 <!-- Test 5: get_extent -->
1080 <test expect_num_outputs="1">
1081 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1082 <conditional name="operation_condi">
1083 <param name="operation" value="get_extent"/>
1084 <param name="coordinate_system" value="global"/>
1085 </conditional>
1086 <assert_stdout>
1087 <has_text text="get_extent"/>
1088 <has_text_matching expression="has_images=True,\n has_labels=True,\n has_points=True,\n has_shapes=True"/>
1089 <has_text text="Operation completed successfully"/>
1090 </assert_stdout>
1091 <output name="result_json">
1092 <assert_contents>
1093 <has_text text="6915.0"/>
1094 <has_text text="2963.0"/>
1095 </assert_contents>
1096 </output>
1097 </test>
1098 <!-- Test 6: get_centroids -->
1099 <test expect_num_outputs="1">
1100 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1101 <conditional name="operation_condi">
1102 <param name="operation" value="get_centroids"/>
1103 <param name="element_name" value="cell_labels"/>
1104 <param name="output_element_name" value="cell_centroids"/>
1105 <param name="coordinate_system" value="global"/>
1106 </conditional>
1107 <assert_stdout>
1108 <has_text text="get_centroids"/>
1109 <has_text text="Operation completed successfully"/>
1110 </assert_stdout>
1111 <output name="spatialdata_output">
1112 <assert_contents>
1113 <has_size value="7500000" delta="100000"/>
1114 <has_archive_member path="spatialdata/zarr.json">
1115 <has_text text="&quot;zarr_format&quot;: 3"/>
1116 <has_text text="points/cell_centroids"/>
1117 </has_archive_member>
1118 </assert_contents>
1119 </output>
1120 </test>
1121 <!-- Test 7: join_spatialelement_table -->
1122 <test expect_num_outputs="1">
1123 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1124 <conditional name="operation_condi">
1125 <param name="operation" value="join_spatialelement_table"/>
1126 <param name="spatial_element_names" value="cell_labels"/>
1127 <param name="table_name" value="table"/>
1128 <param name="region_key" value="region"/>
1129 <param name="output_table_name" value="filtered_table"/>
1130 </conditional>
1131 <assert_stdout>
1132 <has_text text="join_spatialelement_table"/>
1133 <has_text text="Operation completed successfully"/>
1134 </assert_stdout>
1135 <output name="spatialdata_output">
1136 <assert_contents>
1137 <has_size value="7600000" delta="100000"/>
1138 <has_archive_member path="spatialdata/zarr.json">
1139 <has_text text="&quot;zarr_format&quot;: 3"/>
1140 <has_text text="tables/filtered_table"/>
1141 <has_text text="tables/filtered_filtered_table"/>
1142 </has_archive_member>
1143 </assert_contents>
1144 </output>
1145 </test>
1146 <!-- Test 8: match_element_to_table -->
1147 <test expect_num_outputs="1">
1148 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/visium_spatialdata.spatialdata.zip"/>
1149 <conditional name="operation_condi">
1150 <param name="operation" value="match_element_to_table"/>
1151 <param name="element_names" value="Test_Visium"/>
1152 <param name="table_name" value="table"/>
1153 </conditional>
1154 <assert_stdout>
1155 <has_text text="match_element_to_table"/>
1156 <has_text_matching expression="element_name=\['Test_Visium'\],\n table_name='table'"/>
1157 <has_text text="Operation completed successfully"/>
1158 </assert_stdout>
1159 <output name="spatialdata_output">
1160 <assert_contents>
1161 <has_size value="85000000" delta="1000000"/>
1162 <has_archive_member path="spatialdata/zarr.json">
1163 <has_text text="&quot;zarr_format&quot;: 3"/>
1164 <has_text text="shapes/matched_Test_Visium"/>
1165 </has_archive_member>
1166 </assert_contents>
1167 </output>
1168 </test>
1169 <!-- Test 9: match_table_to_element -->
1170 <test expect_num_outputs="1">
1171 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/visium_spatialdata.spatialdata.zip"/>
1172 <conditional name="operation_condi">
1173 <param name="operation" value="match_table_to_element"/>
1174 <param name="element_name" value="Test_Visium"/>
1175 <param name="table_name" value="table"/>
1176 </conditional>
1177 <assert_stdout>
1178 <has_text text="match_table_to_element"/>
1179 <has_text_matching expression="element_name=\'Test_Visium'\,\n table_name='table'"/>
1180 <has_text text="Operation completed successfully"/>
1181 </assert_stdout>
1182 <output name="spatialdata_output">
1183 <assert_contents>
1184 <has_size value="144000000" delta="1000000"/>
1185 <has_archive_member path="spatialdata/zarr.json">
1186 <has_text text="&quot;zarr_format&quot;: 3"/>
1187 <has_text text="tables/matched_table"/>
1188 </has_archive_member>
1189 </assert_contents>
1190 </output>
1191 </test>
1192 <!-- Test 10: match_sdata_to_table -->
1193 <test expect_num_outputs="1">
1194 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/visium_spatialdata.spatialdata.zip"/>
1195 <conditional name="operation_condi">
1196 <param name="operation" value="match_sdata_to_table"/>
1197 <param name="table_name" value="table"/>
1198 <param name="how" value="right"/>
1199 </conditional>
1200 <assert_stdout>
1201 <has_text text="match_sdata_to_table"/>
1202 <has_text_matching expression="sdata=sdata,\n table_name='table',\n how='right'"/>
1203 <has_text text="Operation completed successfully"/>
1204 </assert_stdout>
1205 <output name="spatialdata_output">
1206 <assert_contents>
1207 <has_size value="58000000" delta="1000000"/>
1208 </assert_contents>
1209 </output>
1210 </test>
1211 <!-- Test 11: filter_by_table_query -->
1212 <test expect_num_outputs="1">
1213 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1214 <conditional name="operation_condi">
1215 <param name="operation" value="filter_by_table_query"/>
1216 <param name="table_name" value="table"/>
1217 <param name="filter_tables_bool" value="true"/>
1218 <param name="obs_expr" value="an.col('region') == 'cell_labels'"/>
1219 <param name="how" value="right"/>
1220 </conditional>
1221 <assert_stdout>
1222 <has_text text="filter_by_table_query"/>
1223 <has_text text="Operation completed successfully"/>
1224 </assert_stdout>
1225 <output name="spatialdata_output">
1226 <assert_contents>
1227 <has_size value="160000" delta="20000"/>
1228 </assert_contents>
1229 </output>
1230 </test>
1231 <!-- Test 12: concatenate -->
1232 <test expect_num_outputs="1">
1233 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1234 <conditional name="operation_condi">
1235 <param name="operation" value="concatenate"/>
1236 <param name="other_sdatas" location="https://zenodo.org/records/18746346/files/visium_spatialdata.spatialdata.zip"/>
1237 </conditional>
1238 <assert_stdout>
1239 <has_text text="concatenate"/>
1240 <has_text text="sdatas_list.append(sdata_0)"/>
1241 <has_text text="Operation completed successfully"/>
1242 </assert_stdout>
1243 <output name="spatialdata_output">
1244 <assert_contents>
1245 <has_size value="93000000" delta="1000000"/>
1246 <has_archive_member path="spatialdata/zarr.json">
1247 <has_text text="&quot;zarr_format&quot;: 3"/>
1248 <has_text text="/images/he_image"/>
1249 <has_text text="/images/Test_Visium_full_image"/>
1250 </has_archive_member>
1251 </assert_contents>
1252 </output>
1253 </test>
1254 <!-- Test 13: transform with translation -->
1255 <test expect_num_outputs="1">
1256 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1257 <conditional name="operation_condi">
1258 <param name="operation" value="transform"/>
1259 <param name="element_name" value="cell_labels"/>
1260 <param name="output_element_name" value="transformed_labels"/>
1261 <conditional name="maintain_positioning_condi">
1262 <param name="maintain_positioning" value="yes"/>
1263 <conditional name="transformation_condi">
1264 <param name="transformation_type" value="translation"/>
1265 <param name="translation" value="10,20"/>
1266 <param name="axes" value="x,y"/>
1267 </conditional>
1268 </conditional>
1269 </conditional>
1270 <assert_stdout>
1271 <has_text text="transform"/>
1272 <has_text text="Operation completed successfully"/>
1273 </assert_stdout>
1274 <output name="spatialdata_output">
1275 <assert_contents>
1276 <has_size value="7500000" delta="100000"/>
1277 <has_archive_member path="spatialdata/zarr.json">
1278 <has_text text="&quot;zarr_format&quot;: 3"/>
1279 <has_text text="labels/transformed_labels"/>
1280 </has_archive_member>
1281 </assert_contents>
1282 </output>
1283 </test>
1284 <!-- Test 14: rasterize -->
1285 <test expect_num_outputs="1">
1286 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1287 <conditional name="operation_condi">
1288 <param name="operation" value="rasterize"/>
1289 <param name="element_name" value="cell_labels"/>
1290 <param name="axes" value="x,y"/>
1291 <param name="min_coordinate" value="0,0"/>
1292 <param name="max_coordinate" value="100,100"/>
1293 <param name="target_coordinate_system" value="global"/>
1294 <param name="target_width" value="100"/>
1295 </conditional>
1296 <assert_stdout>
1297 <has_text text="rasterize"/>
1298 <has_text text="Operation completed successfully"/>
1299 </assert_stdout>
1300 <output name="spatialdata_output">
1301 <assert_contents>
1302 <has_size value="7400000" delta="100000"/>
1303 <has_archive_member path="spatialdata/zarr.json">
1304 <has_text text="&quot;zarr_format&quot;: 3"/>
1305 <has_text text="images/rasterized_cell_labels"/>
1306 </has_archive_member>
1307 </assert_contents>
1308 </output>
1309 </test>
1310 <!-- Test 15: rasterize_bins -->
1311 <test expect_num_outputs="1">
1312 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/visium_hd_spatialdata.spatialdata.zip"/>
1313 <conditional name="operation_condi">
1314 <param name="operation" value="rasterize_bins"/>
1315 <param name="bins_element" value="Test_VisiumHD_square_002um"/>
1316 <param name="table_name" value="square_002um"/>
1317 <param name="col_key" value="array_col"/>
1318 <param name="row_key" value="array_row"/>
1319 <param name="value_key" value="location_id"/>
1320 <param name="return_regions_as_labels_bool" value="false"/>
1321 </conditional>
1322 <assert_stdout>
1323 <has_text text="rasterize_bins"/>
1324 <has_text text="Operation completed successfully"/>
1325 </assert_stdout>
1326 <output name="spatialdata_output">
1327 <assert_contents>
1328 <has_size value="29000000" delta="100000"/>
1329 <has_archive_member path="spatialdata/zarr.json">
1330 <has_text text="&quot;zarr_format&quot;: 3"/>
1331 <has_text text="images/rasterized_Test_VisiumHD_square_002um"/>
1332 </has_archive_member>
1333 </assert_contents>
1334 </output>
1335 </test>
1336 <!-- Test 16: rasterize_bins as labels-->
1337 <test expect_num_outputs="1">
1338 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/visium_hd_spatialdata.spatialdata.zip"/>
1339 <conditional name="operation_condi">
1340 <param name="operation" value="rasterize_bins"/>
1341 <param name="bins_element" value="Test_VisiumHD_square_002um"/>
1342 <param name="table_name" value="square_002um"/>
1343 <param name="col_key" value="array_col"/>
1344 <param name="row_key" value="array_row"/>
1345 <param name="value_key" value="location_id"/>
1346 <param name="return_regions_as_labels_bool" value="true"/>
1347 </conditional>
1348 <assert_stdout>
1349 <has_text text="rasterize_bins"/>
1350 <has_text text="Operation completed successfully"/>
1351 </assert_stdout>
1352 <output name="spatialdata_output">
1353 <assert_contents>
1354 <has_size value="29000000" delta="1000000"/>
1355 <has_archive_member path="spatialdata/zarr.json">
1356 <has_text text="&quot;zarr_format&quot;: 3"/>
1357 <has_text text="labels/rasterized_Test_VisiumHD_square_002um"/>
1358 </has_archive_member>
1359 </assert_contents>
1360 </output>
1361 </test>
1362 <!-- Test 17: rasterize_bins_link_table_to_labels -->
1363 <test expect_num_outputs="1">
1364 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/visium_hd_rasterized_spatialdata.spatialdata.zip"/>
1365 <conditional name="operation_condi">
1366 <param name="operation" value="rasterize_bins_link_table_to_labels"/>
1367 <param name="table_name" value="square_002um"/>
1368 <param name="rasterized_labels_name" value="rasterized_Test_VisiumHD_square_002um"/>
1369 </conditional>
1370 <assert_stdout>
1371 <has_text text="rasterize_bins_link_table_to_labels"/>
1372 <has_text text="Operation completed successfully"/>
1373 </assert_stdout>
1374 <output name="spatialdata_output">
1375 <assert_contents>
1376 <has_size value="29700000" delta="1000000"/>
1377 <has_archive_member path="spatialdata/zarr.json">
1378 <has_text text="&quot;zarr_format&quot;: 3"/>
1379 <has_text text="labels/rasterized_Test_VisiumHD_square_002um"/>
1380 </has_archive_member>
1381 </assert_contents>
1382 </output>
1383 </test>
1384 <!-- Test 18: to_circles -->
1385 <test expect_num_outputs="1">
1386 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1387 <conditional name="operation_condi">
1388 <param name="operation" value="to_circles"/>
1389 <param name="element_name" value="cell_labels"/>
1390 <param name="output_element_name" value="cell_circles"/>
1391 </conditional>
1392 <assert_stdout>
1393 <has_text text="to_circles"/>
1394 <has_text text="Operation completed successfully"/>
1395 </assert_stdout>
1396 <output name="spatialdata_output">
1397 <assert_contents>
1398 <has_size value="7480000" delta="20000"/>
1399 <has_archive_member path="spatialdata/zarr.json">
1400 <has_text text="&quot;zarr_format&quot;: 3"/>
1401 <has_text text="shapes/cell_circles"/>
1402 </has_archive_member>
1403 </assert_contents>
1404 </output>
1405 </test>
1406 <!-- Test 19: to_polygons -->
1407 <test expect_num_outputs="1">
1408 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1409 <conditional name="operation_condi">
1410 <param name="operation" value="to_polygons"/>
1411 <param name="element_name" value="cell_labels"/>
1412 <param name="output_element_name" value="cell_polygons"/>
1413 </conditional>
1414 <assert_stdout>
1415 <has_text text="to_polygons"/>
1416 <has_text text="Operation completed successfully"/>
1417 </assert_stdout>
1418 <output name="spatialdata_output">
1419 <assert_contents>
1420 <has_size value="7600000" delta="100000"/>
1421 <has_archive_member path="spatialdata/zarr.json">
1422 <has_text text="&quot;zarr_format&quot;: 3"/>
1423 <has_text text="shapes/cell_polygons"/>
1424 </has_archive_member>
1425 </assert_contents>
1426 </output>
1427 </test>
1428 <!-- Test 20: aggregate -->
1429 <test expect_num_outputs="1">
1430 <param name="input_spatialdata" location="https://s3.embl.de/spatialdata/spatialdata-sandbox/mouse_liver_spatialdata_0.7.1.zip"/>
1431 <conditional name="operation_condi">
1432 <param name="operation" value="aggregate"/>
1433 <param name="values_element" value="transcripts"/>
1434 <param name="by_element" value="nucleus_boundaries"/>
1435 <param name="agg_func" value="count"/>
1436 <param name="target_coordinate_system" value="global"/>
1437 </conditional>
1438 <assert_stdout>
1439 <has_text text="aggregate"/>
1440 <has_text text="&apos;table&apos;: AnnData (3375, 1)"/>
1441 <has_text text="Operation completed successfully"/>
1442 </assert_stdout>
1443 <output name="spatialdata_output">
1444 <assert_contents>
1445 <has_size value="1100000" delta="50000"/>
1446 <has_archive_member path="spatialdata/zarr.json">
1447 <has_text text="&quot;zarr_format&quot;: 3"/>
1448 <has_text text="shapes/nucleus_boundaries"/>
1449 </has_archive_member>
1450 </assert_contents>
1451 </output>
1452 </test>
1453 <!-- Test 21: map_raster -->
1454 <test expect_num_outputs="1">
1455 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1456 <conditional name="operation_condi">
1457 <param name="operation" value="map_raster"/>
1458 <param name="element_name" value="morphology_focus"/>
1459 <param name="func_name" value="numpy.log1p"/>
1460 <param name="blockwise_bool" value="true"/>
1461 </conditional>
1462 <assert_stdout>
1463 <has_text text="map_raster"/>
1464 <has_text text="Operation completed successfully"/>
1465 </assert_stdout>
1466 <output name="spatialdata_output">
1467 <assert_contents>
1468 <has_size value="13000000" delta="1000000"/>
1469 <has_archive_member path="spatialdata/zarr.json">
1470 <has_text text="&quot;zarr_format&quot;: 3"/>
1471 <has_text text="images/mapped_morphology_focus"/>
1472 </has_archive_member>
1473 </assert_contents>
1474 </output>
1475 </test>
1476 <!-- Test 22: unpad_raster -->
1477 <test expect_num_outputs="1">
1478 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1479 <conditional name="operation_condi">
1480 <param name="operation" value="unpad_raster"/>
1481 <param name="element_name" value="morphology_focus"/>
1482 </conditional>
1483 <assert_stdout>
1484 <has_text text="unpad_raster"/>
1485 <has_text text="Operation completed successfully"/>
1486 </assert_stdout>
1487 <output name="spatialdata_output">
1488 <assert_contents>
1489 <has_size value="13200000" delta="300000"/>
1490 <has_archive_member path="spatialdata/zarr.json">
1491 <has_text text="&quot;zarr_format&quot;: 3"/>
1492 <has_text text="images/unpadded_morphology_focus"/>
1493 </has_archive_member>
1494 </assert_contents>
1495 </output>
1496 </test>
1497 <!-- Test 23: relabel_sequential -->
1498 <!-- no good example to see how this should work and also when it works, the sdata can not be written
1499 <test expect_num_outputs="1">
1500 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/visium_spatialdata.spatialdata.zip"/>
1501 <conditional name="operation_condi">
1502 <param name="operation" value="relabel_sequential"/>
1503 <param name="element_name" value="Test_Visium_hires_image"/>
1504 <param name="output_element_name" value="image_relabeled"/>
1505 </conditional>
1506 <assert_stdout>
1507 <has_text text="relabel_sequential"/>
1508 <has_text text="Operation completed successfully"/>
1509 </assert_stdout>
1510 <output name="spatialdata_output">
1511 <assert_contents>
1512 <has_size value="50000" delta="20000"/>
1513 </assert_contents>
1514 </output>
1515 </test> -->
1516 <!-- Test 23: are_extents_equal -->
1517 <test expect_num_outputs="1">
1518 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1519 <conditional name="operation_condi">
1520 <param name="operation" value="are_extents_equal"/>
1521 <param name="element1_name" value="cell_labels"/>
1522 <param name="element2_name" value="nucleus_labels"/>
1523 <param name="coordinate_system" value="global"/>
1524 <param name="atol" value="0.1"/>
1525 </conditional>
1526 <assert_stdout>
1527 <has_text text="are_extents_equal"/>
1528 <has_text text="Operation completed successfully"/>
1529 </assert_stdout>
1530 <output name="result_json">
1531 <assert_contents>
1532 <has_text text="true"/>
1533 </assert_contents>
1534 </output>
1535 </test>
1536 <!-- Test 24: get_pyramid_levels -->
1537 <!-- no good example to see how this should work and also when it works, the sdata can not be written
1538 <test expect_num_outputs="2">
1539 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1540 <conditional name="operation_condi">
1541 <param name="operation" value="get_pyramid_levels"/>
1542 <param name="element_name" value="morphology_focus"/>
1543 </conditional>
1544 <assert_stdout>
1545 <has_text text="get_pyramid_levels"/>
1546 <has_text text="Operation completed successfully"/>
1547 </assert_stdout>
1548 <output name="result_json">
1549 <assert_contents>
1550 <has_size value="100" delta="5000"/>
1551 </assert_contents>
1552 </output>
1553 </test> -->
1554 <!-- Test 24: sanitize_table -->
1555 <test expect_num_outputs="1">
1556 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1557 <conditional name="operation_condi">
1558 <param name="operation" value="sanitize_table"/>
1559 <param name="table_name" value="table"/>
1560 </conditional>
1561 <assert_stdout>
1562 <has_text text="sanitize_table"/>
1563 <has_text text="Operation completed successfully"/>
1564 </assert_stdout>
1565 <output name="spatialdata_output">
1566 <assert_contents>
1567 <has_size value="7400000" delta="200000"/>
1568 </assert_contents>
1569 </output>
1570 </test>
1571 <!-- Test 25: export_table -->
1572 <test expect_num_outputs="1">
1573 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1574 <conditional name="operation_condi">
1575 <param name="operation" value="export_table"/>
1576 <param name="table_name" value="table"/>
1577 </conditional>
1578 <assert_stdout>
1579 <has_text text="Operation completed successfully"/>
1580 </assert_stdout>
1581 <output name="result_adata">
1582 <assert_contents>
1583 <has_size value="170000" delta="20000"/>
1584 <has_h5_keys keys="obs/cell_id,obs/transcript_counts"/>
1585 <has_h5_keys keys="obsm/spatial"/>
1586 </assert_contents>
1587 </output>
1588 </test>
1589 <!-- Test 26: import_table -->
1590 <test expect_num_outputs="1">
1591 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1592 <conditional name="operation_condi">
1593 <param name="operation" value="import_table"/>
1594 <param name="table_name" value="imported_table"/>
1595 <param name="adata" location="https://zenodo.org/records/17512085/files/pbmc_500_chr21.batch.h5ad"/>
1596 </conditional>
1597 <assert_stdout>
1598 <has_text text="Operation completed successfully"/>
1599 </assert_stdout>
1600 <output name="spatialdata_output">
1601 <assert_contents>
1602 <has_size value="7800000" delta="200000"/>
1603 <has_archive_member path="spatialdata/zarr.json">
1604 <has_text text="&quot;zarr_format&quot;: 3"/>
1605 <has_text text="tables/imported_table"/>
1606 </has_archive_member>
1607 </assert_contents>
1608 </output>
1609 </test>
1610 <!-- Test 27: add_shape -->
1611 <test expect_num_outputs="1">
1612 <param name="input_spatialdata" location="https://zenodo.org/records/18746346/files/xenium_spatialdata.spatialdata.zip"/>
1613 <conditional name="operation_condi">
1614 <param name="operation" value="add_shape"/>
1615 <param name="element_name" value="new_shapes"/>
1616 <param name="shape" location="https://zenodo.org/records/18746346/files/visiumhd_cell_segmentations.geojson"/>
1617 </conditional>
1618 <assert_stdout>
1619 <has_text text="Operation completed successfully"/>
1620 </assert_stdout>
1621 <output name="spatialdata_output">
1622 <assert_contents>
1623 <has_size value="7560000" delta="30000"/>
1624 <has_archive_member path="spatialdata/zarr.json">
1625 <has_text text="&quot;zarr_format&quot;: 3"/>
1626 <has_text text="shapes/new_shapes"/>
1627 </has_archive_member>
1628 </assert_contents>
1629 </output>
1630 </test>
1631 </tests>
1632 <help><![CDATA[
1633
1634 **What it does**
1635
1636 This tool performs various operations on SpatialData objects, including:
1637
1638 **Spatial Operations:**
1639 - **Bounding Box Query**: Extract data within a specified bounding box
1640 - **Polygon Query**: Extract data within a polygon region
1641 - **Get Extent**: Calculate the spatial extent (bounding box) of elements
1642 - **Transform**: Apply geometric transformations (Identity, MapAxis, Translation, Scale, Affine, Sequence)
1643 - **Aggregate**: Aggregate values from one element by regions defined in another
1644 - **Convert to Circles**: Approximate geometries as circles
1645 - **Convert to Polygons**: Convert geometries to polygons
1646 - **Get Values**: Extract values from elements or tables
1647 - **Get Element Instances**: Get the instance IDs of elements
1648 - **Get Centroids**: Calculate centroids of geometries
1649
1650 **Table Operations:**
1651 - **Join SpatialElement and Table**: SQL-like joins between elements and tables
1652 - **Match Element to Table**: Filter elements to match table indices
1653 - **Match Table to Element**: Filter and reorder table to match element instances
1654 - **Match SpatialData to Table**: Filter SpatialData to match table rows
1655 - **Filter by Table Query**: Filter SpatialData based on table queries
1656
1657 **Rasterization Operations:**
1658 - **Rasterize**: Convert spatial elements to raster images
1659 - **Rasterize Bins**: Rasterize grid-like binned data (e.g., Visium HD)
1660 - **Link Bins Table to Labels**: Link table to rasterized labels
1661 - **Map Raster**: Apply functions to raster data
1662 - **Unpad Raster**: Remove padding from rasterized data
1663
1664 **Utility Operations:**
1665 - **Relabel Sequential**: Relabel integers in labels sequentially
1666 - **Are Extents Equal**: Check if two extents are equal
1667 - **Get Pyramid Levels**: Access multiscale image pyramid levels
1668 - **Sanitize Table**: Sanitize all keys in an AnnData table
1669
1670 -----
1671
1672 **More Information**
1673
1674 - `SpatialData documentation <https://spatialdata.scverse.org/>`__
1675 - `SpatialData operations API <https://spatialdata.scverse.org/en/stable/api.html>`__
1676
1677 ]]></help>
1678 <expand macro="citations" />
1679 </tool>