@@ -150,7 +150,7 @@ def write(
150
150
if len (sdata .points ):
151
151
df = get_spatial_element (sdata .points , key = points_key or sdata .attrs .get (SopaAttrs .TRANSCRIPTS ))
152
152
153
- if _should_save (mode , "t" ) and df is not None :
153
+ if _should_save (mode , "t" ) and not _use_symlink ( path , sdata , "transcripts*" ) and df is not None :
154
154
gene_column = gene_column or get_feature_key (df )
155
155
if gene_column is not None :
156
156
df = to_intrinsic (sdata , df , image_key )
@@ -159,7 +159,7 @@ def write(
159
159
log .warning ("The argument 'gene_column' has to be provided to save the transcripts" )
160
160
161
161
### Saving image
162
- if _should_save (mode , "i" ):
162
+ if _should_save (mode , "i" ) and not _use_symlink ( path , sdata , "morphology*" ) :
163
163
write_image (
164
164
path ,
165
165
sdata [image_key ],
@@ -176,6 +176,26 @@ def write(
176
176
log .info (f"You can open the experiment with 'open { path / FileNames .METADATA } '" )
177
177
178
178
179
+ def _use_symlink (path : Path , sdata : SpatialData , pattern : str ) -> bool :
180
+ """Try using the Xenium output files when existing to avoid re-generating large files."""
181
+ if SopaAttrs .XENIUM_OUTPUT_PATH not in sdata .attrs :
182
+ return False
183
+
184
+ files = list (Path (sdata .attrs [SopaAttrs .XENIUM_OUTPUT_PATH ]).glob (pattern ))
185
+ for file in files :
186
+ target = path / file .name
187
+
188
+ if target .exists ():
189
+ if not target .is_symlink (): # avoid removing non-symlink files
190
+ return False
191
+ target .unlink ()
192
+
193
+ target .symlink_to (file )
194
+ log .info (f"Created symlink { target } -> { file } " )
195
+
196
+ return len (files ) > 0
197
+
198
+
179
199
def _get_n_obs (sdata : SpatialData , geo_df : gpd .GeoDataFrame , table_key : str ) -> int :
180
200
if table_key in sdata .tables :
181
201
return sdata .tables [table_key ].n_obs
0 commit comments