-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cosmx - ValueError: Affine matrix must be homogeneous. #213
Comments
Hi, can you set a breakpoint/add a print and copy-paste the matrix here please? |
The expression matrix? |
No I mean the affine matrix, since the error is coming from there. In this case the |
Sorry for the slow response. Took me a while to try and debug and get a sensible output that might make sense for you. In the end I modified the Output:printing out
<AffineTransform(matrix=
[[ 8.10368448e-01, -5.52281315e-01, 1.23965615e+04],
[ 3.19759226e-01, -6.79466884e-02, 1.53052481e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 8.10368448e-01 -5.52281315e-01 1.23965615e+04]
[ 3.19759226e-01 -6.79466884e-02 1.53052481e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 1.52916069e-09, 1.45160000e+04],
[ 6.02308243e-06, -9.99996320e-01, 1.56674966e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 1.52916069e-09 1.45160000e+04]
[ 6.02308243e-06 -9.99996320e-01 1.56674966e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, -4.03841338e-11, 1.87750000e+04],
[ 1.40818796e-06, -9.99999676e-01, 1.56674993e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 -4.03841338e-11 1.87750000e+04]
[ 1.40818796e-06 -9.99999676e-01 1.56674993e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, -1.25917955e-09, 2.30410000e+04],
[ 2.84186251e-07, -9.99987522e-01, 1.56674951e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 -1.25917955e-09 2.30410000e+04]
[ 2.84186251e-07 -9.99987522e-01 1.56674951e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 1.92296269e-16, 1.02500000e+04],
[-2.88444403e-16, -1.00000000e+00, 1.52408000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 1.92296269e-16 1.02500000e+04]
[-2.88444403e-16 -1.00000000e+00 1.52408000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, -1.92296269e-16, 1.45160000e+04],
[ 4.50694380e-18, -1.00000000e+00, 1.52408000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 -1.92296269e-16 1.45160000e+04]
[ 4.50694380e-18 -1.00000000e+00 1.52408000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, -1.92296269e-16, 1.87750000e+04],
[-1.08166651e-16, -1.00000000e+00, 1.52408000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 -1.92296269e-16 1.87750000e+04]
[-1.08166651e-16 -1.00000000e+00 1.52408000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.0000000e+00, 0.0000000e+00, 2.3041000e+04],
[ 1.1417591e-16, -1.0000000e+00, 1.5240800e+05],
[ 0.0000000e+00, 0.0000000e+00, 1.0000000e+00]])>
printing out.params
[[ 1.0000000e+00 0.0000000e+00 2.3041000e+04]
[ 1.1417591e-16 -1.0000000e+00 1.5240800e+05]
[ 0.0000000e+00 0.0000000e+00 1.0000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 0.00000000e+00, 2.73080000e+04],
[ 5.76888806e-16, -1.00000000e+00, 1.52408000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 0.00000000e+00 2.73080000e+04]
[ 5.76888806e-16 -1.00000000e+00 1.52408000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 0.00000000e+00, 1.02500000e+04],
[ 3.61306661e-16, -1.00000000e+00, 1.48150000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 0.00000000e+00 1.02500000e+04]
[ 3.61306661e-16 -1.00000000e+00 1.48150000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 1.92296269e-16, 1.45160000e+04],
[ 2.40370336e-17, -1.00000000e+00, 1.48150000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 1.92296269e-16 1.45160000e+04]
[ 2.40370336e-17 -1.00000000e+00 1.48150000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 1.92296269e-16, 1.87750000e+04],
[ 4.20648088e-17, -1.00000000e+00, 1.48150000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 1.92296269e-16 1.87750000e+04]
[ 4.20648088e-17 -1.00000000e+00 1.48150000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 1.92296269e-16, 2.30410000e+04],
[ 2.13328673e-16, -1.00000000e+00, 1.48150000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 1.92296269e-16 2.30410000e+04]
[ 2.13328673e-16 -1.00000000e+00 1.48150000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 5.76888806e-16, 2.73080000e+04],
[-1.41217572e-16, -1.00000000e+00, 1.48150000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 5.76888806e-16 2.73080000e+04]
[-1.41217572e-16 -1.00000000e+00 1.48150000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, -2.88444403e-16, 1.02500000e+04],
[ 3.36518470e-16, -1.00000000e+00, 1.43883000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 -2.88444403e-16 1.02500000e+04]
[ 3.36518470e-16 -1.00000000e+00 1.43883000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 0.00000000e+00, 1.45160000e+04],
[-4.20648088e-17, -1.00000000e+00, 1.43883000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 0.00000000e+00 1.45160000e+04]
[-4.20648088e-17 -1.00000000e+00 1.43883000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 1.92296269e-16, 1.87750000e+04],
[-1.44222201e-16, -1.00000000e+00, 1.43883000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 1.92296269e-16 1.87750000e+04]
[-1.44222201e-16 -1.00000000e+00 1.43883000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, -1.92296269e-16, 2.30410000e+04],
[-1.20185168e-17, -1.00000000e+00, 1.43883000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 -1.92296269e-16 2.30410000e+04]
[-1.20185168e-17 -1.00000000e+00 1.43883000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 3.84592537e-16, 2.73080000e+04],
[ 2.64407369e-16, -1.00000000e+00, 1.43883000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 3.84592537e-16 2.73080000e+04]
[ 2.64407369e-16 -1.00000000e+00 1.43883000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 0.00000000e+00, 1.45160000e+04],
[ 9.61481343e-17, -1.00000000e+00, 1.39616000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 0.00000000e+00 1.45160000e+04]
[ 9.61481343e-17 -1.00000000e+00 1.39616000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 0.00000000e+00, 1.87750000e+04],
[ 2.93702504e-16, -1.00000000e+00, 1.39616000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 0.00000000e+00 1.87750000e+04]
[ 2.93702504e-16 -1.00000000e+00 1.39616000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, -5.76888806e-16, 2.30410000e+04],
[-9.61481343e-17, -1.00000000e+00, 1.39616000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 -5.76888806e-16 2.30410000e+04]
[-9.61481343e-17 -1.00000000e+00 1.39616000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 2.30755522e-15, 2.73080000e+04],
[ 2.74022183e-15, -1.00000000e+00, 1.39616000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 2.30755522e-15 2.73080000e+04]
[ 2.74022183e-15 -1.00000000e+00 1.39616000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, -2.94213291e-14, 3.56500000e+04],
[-3.65362910e-15, -1.00000000e+00, 1.57066000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 -2.94213291e-14 3.56500000e+04]
[-3.65362910e-15 -1.00000000e+00 1.57066000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 0.00000000e+00, 3.99160000e+04],
[-9.61481343e-17, -1.00000000e+00, 1.57066000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 0.00000000e+00 3.99160000e+04]
[-9.61481343e-17 -1.00000000e+00 1.57066000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 1.92296269e-16, 4.41830000e+04],
[-2.40370336e-17, -1.00000000e+00, 1.57066000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 1.92296269e-16 4.41830000e+04]
[-2.40370336e-17 -1.00000000e+00 1.57066000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[ 1.00000000e+00, 1.92296269e-16, 4.84500000e+04],
[ 1.92296269e-16, -1.00000000e+00, 1.57066000e+05],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])>
printing out.params
[[ 1.00000000e+00 1.92296269e-16 4.84500000e+04]
[ 1.92296269e-16 -1.00000000e+00 1.57066000e+05]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
printing out
<AffineTransform(matrix=
[[nan, nan, nan],
[nan, nan, nan],
[nan, nan, nan]])>
printing out.params
[[nan nan nan]
[nan nan nan]
[nan nan nan]] Followed by error:[/nemo/stp/babs/working/bootj/projects/swantonc/imran.noorani/in839/analysis/init-rocker-renv/venv/lib/python3.12/site-packages/numpy/core/numeric.py:407](http://localhost:8888/venv/lib/python3.12/site-packages/numpy/core/numeric.py#line=406): RuntimeWarning: invalid value encountered in cast
multiarray.copyto(res, fill_value, casting='unsafe')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[9], line 2
1 # Trial the spatialdata_io way of loading data - FAILS - GitHub issue raised.
----> 2 adata1 = sp.cosmx(sample_dir, dataset_id = 'GCIN10692_TMA2')
File [/nemo/stp/babs/working/bootj/projects/swantonc/imran.noorani/in839/analysis/init-rocker-renv/venv/lib/python3.12/site-packages/spatialdata_io/readers/cosmx.py:152](http://localhost:8888/venv/lib/python3.12/site-packages/spatialdata_io/readers/cosmx.py#line=151), in cosmx(path, dataset_id, transcripts, imread_kwargs, image_models_kwargs)
150 print('printing out.params')
151 print(out.params)
--> 152 affine_transforms_to_global[fov] = Affine(
153 # out.params, input_coordinate_system=input_cs, output_coordinate_system=output_cs
154 out.params,
155 input_axes=("x", "y"),
156 output_axes=("x", "y"),
157 )
159 table.obsm["global"] = table.obs[[CosmxKeys.X_GLOBAL_CELL, CosmxKeys.Y_GLOBAL_CELL]].to_numpy()
160 table.obsm["spatial"] = table.obs[[CosmxKeys.X_LOCAL_CELL, CosmxKeys.Y_LOCAL_CELL]].to_numpy()
File [/nemo/stp/babs/working/bootj/projects/swantonc/imran.noorani/in839/analysis/init-rocker-renv/venv/lib/python3.12/site-packages/spatialdata/transformations/transformations.py:523](http://localhost:8888/venv/lib/python3.12/site-packages/spatialdata/transformations/transformations.py#line=522), in Affine.__init__(self, matrix, input_axes, output_axes)
521 raise ValueError("Invalid shape for affine matrix.")
522 if not np.array_equal(self.matrix[-1, :-1], np.zeros(len(input_axes))):
--> 523 raise ValueError("Affine matrix must be homogeneous.")
524 assert self.matrix[-1, -1] == 1.0
ValueError: Affine matrix must be homogeneous. |
I believe this is caused by your source data including FOVs with just a single cell. If these FOVs are kept, you run into a problem when estimating the affine transformation from local to global coordinates. Attempting to do that with just a pair of a single coordinate leads to diff --git a/src/spatialdata_io/readers/cosmx.py b/src/spatialdata_io/readers/cosmx.py
index 57e9f5d..343b940 100644
--- a/src/spatialdata_io/readers/cosmx.py
+++ b/src/spatialdata_io/readers/cosmx.py
@@ -129,6 +129,10 @@ def cosmx(
)
adata.var_names = counts.columns
+ # Filter out single-cell FOVs since we cannot define a transform to global from a single cell
+ num_cells = adata.obs[['fov']].groupby('fov').size()
+ adata = adata[adata.obs['fov'].isin(num_cells[num_cells > 2].index)]
+
table = TableModel.parse(
adata,
region=list(set(adata.obs[CosmxKeys.REGION_KEY].astype(str).tolist())), happy to open a PR if that's helpful. |
Thanks, that patch works for me! Might be useful to have this incorporated. I suspect this is because we have round tissue sections, but the FOVs are square grids therefore inevitably there are FOVs on the edge of the tissue which aren't capturing much tissue if any tissue at all. Thanks again! |
Thanks for the details @jamesboot and @clwgg for the solution. @clwgg could you please make a PR with the fix? Thanks 😊 |
Hi,
I'm trying to read in some CosMx data - I have a dataset formatted into a folder with the CellLabels and CellComposite directories and then the relevant CSV files. When I execute the code below:
I get the following error:
Any recommendations on how to address this?
Cheers
The text was updated successfully, but these errors were encountered: