@@ -42,7 +42,7 @@ def visium(
4242
4343 This function reads the following files:
4444
45- - ``{vx.COUNTS_FILE!r}``: Counts and metadata file.
45+ - ``(<dataset_id>_)` {vx.COUNTS_FILE!r}` ``: Counts and metadata file.
4646 - ``{vx.IMAGE_HIRES_FILE!r}``: High resolution image.
4747 - ``{vx.IMAGE_LOWRES_FILE!r}``: Low resolution image.
4848 - ``{vx.SCALEFACTORS_FILE!r}``: Scalefactors file.
@@ -59,8 +59,8 @@ def visium(
5959 path
6060 Path to the directory containing the data.
6161 dataset_id
62- Dataset identifier. If not given will be determined automatically
63- from the ``{vx.COUNTS_FILE!r}`` file.
62+ Dataset identifier to name the constructed `SpatialData` elements. The reader will try to infer it from the
63+ ``{vx.COUNTS_FILE!r}`` file name. If the file name does not contain the dataset id, it will try to infer it from the metadata, it needs to be provided .
6464 counts_file
6565 Name of the counts file. Use only if counts is not in `h5` format.
6666 fullres_image_file
@@ -81,39 +81,53 @@ def visium(
8181 path = Path (path )
8282 imread_kwargs = dict (imread_kwargs )
8383 image_models_kwargs = dict (image_models_kwargs )
84- # get library_id
84+ # try to infer library_id from the counts file
85+ library_id = None
8586 try :
8687 patt = re .compile (f".*{ VisiumKeys .COUNTS_FILE } " )
8788 first_file = [i for i in os .listdir (path ) if patt .match (i )][0 ]
8889
8990 if f"_{ VisiumKeys .COUNTS_FILE } " in first_file :
9091 library_id = first_file .replace (f"_{ VisiumKeys .COUNTS_FILE } " , "" )
92+ counts_file = f"{ library_id } _{ VisiumKeys .COUNTS_FILE } "
93+ elif VisiumKeys .COUNTS_FILE == first_file :
94+ library_id = None
95+ counts_file = VisiumKeys .COUNTS_FILE
9196 else :
9297 raise ValueError (
93- f"Cannot determine the library_id. Expecting a file with format <library_id>_{ VisiumKeys .COUNTS_FILE } . Has "
94- f"the files been renamed?"
98+ f"Cannot determine the library_id. Expecting a file with format (<library_id>_){ VisiumKeys .COUNTS_FILE } "
99+ f". If the files have been renamed you may need to specify their file names (not their paths), with "
100+ f"some of the following arguments: `counts_file`, `fullres_image_file`, `tissue_positions_file`, "
101+ f"`scalefactors_file` arguments."
95102 )
96- counts_file = f"{ library_id } _{ VisiumKeys .COUNTS_FILE } "
97103 except IndexError as e :
98- logger .error (
99- f"{ e } . \n Error is due to the fact that the library id could not be found, this is the case when the `counts_file` is `.mtx`." ,
100- )
101- if dataset_id is None :
102- raise ValueError ("Cannot determine the `library_id`. Please provide `dataset_id`." )
103- library_id = dataset_id
104104 if counts_file is None :
105- raise ValueError ("Cannot determine the library_id. Please provide `counts_file`." )
105+ logger .error (
106+ f"{ e } . \n Error is due to the fact that the library id could not be found, if the counts file is `.mtx` (or else), Please provide a `counts_file`." ,
107+ )
108+ raise e
109+ assert counts_file is not None
110+
111+ if library_id is None and dataset_id is None :
112+ raise ValueError ("Cannot determine the `library_id`. Please provide `dataset_id`." )
106113
107114 if dataset_id is not None :
108- if dataset_id != library_id :
115+ if dataset_id != library_id and library_id is not None :
109116 logger .warning (
110117 f"`dataset_id: { dataset_id } ` does not match `library_id: { library_id } `. `dataset_id: { dataset_id } ` "
111118 f"will be used to build SpatialData."
112119 )
120+ library_id = dataset_id
113121 else :
114122 dataset_id = library_id
123+ assert dataset_id is not None
115124
116- adata , dataset_id = _read_counts (path , counts_file = counts_file , library_id = dataset_id , ** kwargs )
125+ # Yhe second element of the returned tuple is the full library as contained in the metadata of
126+ # VisiumKeys.COUNTS_FILE. For instance for the spatialdata-sandbox/visium dataset it is:
127+ # spaceranger100_count_30458_ST8059048_mm10-3_0_0_premrna
128+ # We discard this value and use the one inferred from the filename of VisiumKeys.COUNTS_FILE, or the one provided by
129+ # the user in dataset_id
130+ adata , _ = _read_counts (path , counts_file = counts_file , library_id = library_id , ** kwargs )
117131
118132 if (path / "spatial" / VisiumKeys .SPOTS_FILE_1 ).exists () or (
119133 tissue_positions_file is not None and str (VisiumKeys .SPOTS_FILE_1 ) in str (tissue_positions_file )
@@ -142,6 +156,7 @@ def visium(
142156 adata .obs = pd .merge (adata .obs , coords , how = "left" , left_index = True , right_index = True )
143157 coords = adata .obs [[VisiumKeys .SPOTS_X , VisiumKeys .SPOTS_Y ]].values
144158 adata .obsm ["spatial" ] = coords
159+ adata .obs = pd .DataFrame (adata .obs )
145160 adata .obs .drop (columns = [VisiumKeys .SPOTS_X , VisiumKeys .SPOTS_Y ], inplace = True )
146161 adata .obs ["spot_id" ] = np .arange (len (adata ))
147162 adata .var_names_make_unique ()
@@ -187,7 +202,7 @@ def visium(
187202
188203 ImagePIL .MAX_IMAGE_PIXELS = imread_kwargs .pop ("MAX_IMAGE_PIXELS" )
189204 full_image = imread (fullres_image_file , ** imread_kwargs ).squeeze ().transpose (2 , 0 , 1 )
190- full_image = DataArray (full_image , dims = ("c" , "y" , "x" ), name = dataset_id )
205+ full_image = DataArray (full_image , dims = ("c" , "y" , "x" ))
191206 images [dataset_id + "_full_image" ] = Image2DModel .parse (
192207 full_image ,
193208 scale_factors = [2 , 2 , 2 , 2 ],
@@ -199,13 +214,13 @@ def visium(
199214
200215 if (path / VisiumKeys .IMAGE_HIRES_FILE ).exists ():
201216 image_hires = imread (path / VisiumKeys .IMAGE_HIRES_FILE , ** imread_kwargs ).squeeze ().transpose (2 , 0 , 1 )
202- image_hires = DataArray (image_hires , dims = ("c" , "y" , "x" ), name = dataset_id )
217+ image_hires = DataArray (image_hires , dims = ("c" , "y" , "x" ))
203218 images [dataset_id + "_hires_image" ] = Image2DModel .parse (
204219 image_hires , transformations = {"downscaled_hires" : Identity ()}
205220 )
206221 if (path / VisiumKeys .IMAGE_LOWRES_FILE ).exists ():
207222 image_lowres = imread (path / VisiumKeys .IMAGE_LOWRES_FILE , ** imread_kwargs ).squeeze ().transpose (2 , 0 , 1 )
208- image_lowres = DataArray (image_lowres , dims = ("c" , "y" , "x" ), name = dataset_id )
223+ image_lowres = DataArray (image_lowres , dims = ("c" , "y" , "x" ))
209224 images [dataset_id + "_lowres_image" ] = Image2DModel .parse (
210225 image_lowres , transformations = {"downscaled_lowres" : Identity ()}
211226 )
0 commit comments