11import numpy as np
22import pytest
33from scipy .sparse import issparse
4+ from scipy .stats import pearsonr
45
56from cellmapper .model .cellmapper import CellMapper
67
@@ -18,17 +19,17 @@ class TestQueryToReferenceMapping:
1819 """Tests for query-to-reference mapping functionality in CellMapper."""
1920
2021 def test_label_transfer (self , cmap , expected_label_transfer_metrics ):
21- cmap .transfer_labels ( obs_keys = "leiden" )
22+ cmap .map_obs ( key = "leiden" )
2223 cmap .evaluate_label_transfer (label_key = "leiden" )
2324 assert_metrics_close (cmap .label_transfer_metrics , expected_label_transfer_metrics )
2425
2526 def test_embedding_transfer (self , cmap ):
26- cmap .transfer_embeddings ( obsm_keys = "X_pca" )
27+ cmap .map_obsm ( key = "X_pca" )
2728 assert "X_pca_pred" in cmap .query .obsm
2829 assert cmap .query .obsm ["X_pca_pred" ].shape [0 ] == cmap .query .n_obs
2930
3031 def test_expression_transfer (self , cmap , expected_expression_transfer_metrics ):
31- cmap .transfer_expression ( layer_key = "X" )
32+ cmap .map_layers ( key = "X" )
3233 cmap .evaluate_expression_transfer (layer_key = "X" , method = "pearson" )
3334 assert_metrics_close (cmap .expression_transfer_metrics , expected_expression_transfer_metrics )
3435
@@ -41,7 +42,7 @@ def test_compute_mapping_matrix_all_methods(self, cmap, method):
4142
4243 @pytest .mark .parametrize ("layer_key" , ["X" , "counts" ])
4344 def test_expression_transfer_layers (self , cmap , layer_key ):
44- cmap .transfer_expression ( layer_key = layer_key )
45+ cmap .map_layers ( key = layer_key )
4546 assert cmap .query_imputed is not None
4647 assert cmap .query_imputed .X .shape [0 ] == cmap .query .n_obs
4748
@@ -58,7 +59,7 @@ def test_expression_transfer_layers(self, cmap, layer_key):
5859 ],
5960 )
6061 def test_fit_various_combinations (self , cmap , obs_keys , obsm_keys , layer_key ):
61- cmap .fit (obs_keys = obs_keys , obsm_keys = obsm_keys , layer_key = layer_key )
62+ cmap .map (obs_keys = obs_keys , obsm_keys = obsm_keys , layer_key = layer_key )
6263 if obs_keys is not None :
6364 keys = [obs_keys ] if isinstance (obs_keys , str ) else obs_keys
6465 for key in keys :
@@ -71,11 +72,11 @@ def test_fit_various_combinations(self, cmap, obs_keys, obsm_keys, layer_key):
7172 assert cmap .query_imputed is not None
7273 assert cmap .query_imputed .X .shape [0 ] == cmap .query .n_obs
7374
74- def test_transfer_labels_self_mapping (self , query_reference_adata ):
75+ def test_map_obs_self_mapping (self , query_reference_adata ):
7576 """Check mapping to self."""
7677 _ , reference = query_reference_adata
7778 cm = CellMapper (reference , reference )
78- cm .fit (
79+ cm .map (
7980 knn_method = "sklearn" ,
8081 mapping_method = "jaccard" ,
8182 obs_keys = "leiden" ,
@@ -174,13 +175,13 @@ def test_query_imputed_invalid_type(self, cmap):
174175 with pytest .raises (TypeError ):
175176 cmap .query_imputed = [1 , 2 , 3 ]
176177
177- def test_query_imputed_integration_with_transfer_expression (self , cmap , random_imputed_data ):
178- """Test that transfer_expression correctly uses the query_imputed property."""
178+ def test_query_imputed_integration_with_map_layers (self , cmap , random_imputed_data ):
179+ """Test that map_layers correctly uses the query_imputed property."""
179180 # First check query_imputed is None
180181 assert cmap .query_imputed is None
181182
182- # Transfer expression
183- cmap .transfer_expression ( layer_key = "X" )
183+ # Map expression
184+ cmap .map_layers ( key = "X" )
184185
185186 # Verify query_imputed was set
186187 assert cmap .query_imputed is not None
@@ -255,3 +256,51 @@ def test_compute_neighbors_fallback(self, cmap, n_comps, fallback_representation
255256 assert key_added in cmap .query .obsm
256257 assert cmap .reference .obsm [key_added ].shape [1 ] == n_comps
257258 assert cmap .query .obsm [key_added ].shape [1 ] == n_comps
259+
260+ def test_map_obs_numerical_data_type_detection (self , query_reference_adata ):
261+ """Test that numerical data types are correctly detected in map_obs."""
262+ query , reference = query_reference_adata
263+
264+ # Add some numerical data to reference
265+ reference .obs ["numerical_score" ] = np .random .rand (reference .n_obs )
266+ reference .obs ["integer_score" ] = np .random .randint (0 , 100 , reference .n_obs )
267+
268+ # Create CellMapper and compute mapping matrix
269+ cmap = CellMapper (query = query , reference = reference )
270+ cmap .compute_neighbors (n_neighbors = 30 , use_rep = "X_pca" , method = "sklearn" )
271+ cmap .compute_mapping_matrix (method = "gaussian" )
272+
273+ # Test float and integer data
274+ for key in ["numerical_score" , "integer_score" ]:
275+ cmap .map_obs (key = key )
276+ assert f"{ key } _pred" in cmap .query .obs
277+ assert cmap .query .obs [f"{ key } _pred" ].dtype .kind == "f"
278+
279+ def test_map_obs_pseudotime_cross_mapping (self , query_reference_adata ):
280+ """Test mapping pseudotime values in cross-mapping mode - should still have reasonable correlation."""
281+ query , reference = query_reference_adata
282+
283+ # Create CellMapper and compute mapping matrix
284+ cmap = CellMapper (query = query , reference = reference )
285+ cmap .compute_neighbors (n_neighbors = 30 , use_rep = "X_pca" , method = "sklearn" )
286+ cmap .compute_mapping_matrix (method = "gaussian" )
287+
288+ # Map pseudotime
289+ cmap .map_obs (key = "dpt_pseudotime" )
290+
291+ # Check that pseudotime was mapped
292+ assert "dpt_pseudotime_pred" in cmap .query .obs
293+ assert cmap .query .obs ["dpt_pseudotime_pred" ].dtype == reference .obs ["dpt_pseudotime" ].dtype
294+
295+ # Check correlation between actual and predicted pseudotime in query subset
296+ # (Note: query is a subset of the original data, so we can compare)
297+ query_original_pt = query .obs ["dpt_pseudotime" ]
298+ query_predicted_pt = cmap .query .obs ["dpt_pseudotime_pred" ]
299+
300+ correlation , _ = pearsonr (query_original_pt , query_predicted_pt )
301+
302+ # Cross-mapping should still have reasonably high correlation, though lower than self-mapping
303+ assert correlation > 0.99 , f"Cross-mapping pseudotime correlation too low: { correlation } "
304+
305+ # Verify no confidence scores for numerical data
306+ assert "dpt_pseudotime_conf" not in cmap .query .obs
0 commit comments