Skip to content

Commit dba5188

Browse files
committed
Merge branch 'main' into metrics/morans_i
2 parents 6022ba0 + fb7cc07 commit dba5188

3 files changed

Lines changed: 137 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
## NEW FUNCTIONALITY
88

99
* Added `spaTrack` method (PR #4).
10+
* Added `Spearman's correlation` metric (PR #5).
1011

1112
## MAJOR CHANGES
1213

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
__merge__: ../../api/comp_metric.yaml
2+
3+
name: spearman_corr
4+
5+
info:
6+
metrics:
7+
- name: spearman_corr
8+
label: Spearman's Corr
9+
summary: "Computes the Spearman rank correlation coefficient between inferred and ground-truth pseudotime."
10+
description: |
11+
Calculates the Spearman rank correlation coefficient (rho) between predicted cell pseudotime
12+
values and the true ground-truth pseudotime. Measures monotonic relationships regardless of linearity.
13+
references:
14+
doi:
15+
- 10.1038/s41592-020-0772-5
16+
bibtex: |
17+
@article{Virtanen_2020,
18+
author = {Virtanen, Pauli and Gommers, Ralf and Oliphant, Travis E. and Haberland, Matt and Reddy, Tyler and Cournapeau, David and Burovski, Evgeni and Peterson, Pearu and Weckesser, Warren and Bright, Jonathan and {van der Walt}, St{\'e}fan J. and Brett, Matthew and Wilson, Joshua and Jarrod Millman, K. and Mayorov, Nikolay and Nelson, Andrew R. J. and Jones, Eric and Kern, Robert and Larson, Eric and Carey, C. J. and Polat, {\dot{I}}lhan and Feng, Yu and Moore, Eric W. and VanderPlas, Jake and Laxalde, Denis and Perktold, Josef and Cimrman, Robert and Henriksen, Ian and Quintero, E. A. and Harris, Charles R. and Archibald, Anne M. and Ribeiro, Ant{\^o}nio H. and Pedregosa, Fabian and {van Mulbregt}, Paul and {SciPy 1.0 Contributors}},
19+
title = {Author Correction: SciPy 1.0: fundamental algorithms for scientific computing in Python},
20+
journal = {Nature Methods},
21+
volume = {17},
22+
number = {3},
23+
pages = {352},
24+
year = {2020},
25+
doi = {10.1038/s41592-020-0772-5}
26+
}
27+
links:
28+
documentation: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.spearmanr.html
29+
repository: https://github.com/scipy/scipy
30+
min: -1
31+
max: 1
32+
maximize: true
33+
34+
resources:
35+
- type: python_script
36+
path: script.py
37+
38+
engines:
39+
- type: docker
40+
image: python:3.11-slim
41+
setup:
42+
- type: apt
43+
packages:
44+
- procps # required by Nextflow
45+
- git # pip needs it to install openproblems core from git+https
46+
- type: python
47+
packages:
48+
- anndata~=0.10.0
49+
- scanpy~=1.10.0
50+
- scipy
51+
- pandas
52+
- pyyaml
53+
- requests
54+
- jsonschema
55+
github:
56+
- "openproblems-bio/core#subdirectory=packages/python/openproblems"
57+
58+
runners:
59+
- type: executable
60+
- type: nextflow
61+
directives:
62+
label: [midtime,midmem,midcpu]
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import anndata as ad
2+
import numpy as np
3+
import pandas as pd
4+
from scipy import stats
5+
6+
## VIASH START
7+
# Note: this section is auto-generated by viash at runtime. To edit it, make changes
8+
# in config.vsh.yaml and then run `viash config inject config.vsh.yaml`.
9+
par = {
10+
'input_solution': 'resources_test/task_spatial_trajectory_inference/cxg_mouse_pancreas_atlas/solution.h5ad',
11+
'input_prediction': 'resources_test/task_spatial_trajectory_inference/cxg_mouse_pancreas_atlas/prediction.h5ad',
12+
'output': 'output.h5ad',
13+
}
14+
meta = {
15+
'name': 'spearman_corr'
16+
}
17+
## VIASH END
18+
19+
20+
def compute_spearman(true_values, inferred_values):
21+
"""Calculates Spearman rank correlation on finite overlapping values."""
22+
mask = np.isfinite(true_values) & np.isfinite(inferred_values)
23+
24+
if mask.sum() < 2:
25+
return 0.0
26+
27+
rho, _ = stats.spearmanr(true_values[mask], inferred_values[mask])
28+
29+
if np.isnan(rho):
30+
return 0.0
31+
32+
return float(rho)
33+
34+
# read input data
35+
print('Reading input files', flush=True)
36+
input_solution = ad.read_h5ad(par['input_solution'])
37+
input_prediction = ad.read_h5ad(par['input_prediction'])
38+
39+
assert (input_prediction.obs_names == input_solution.obs_names).all(), "obs_names not the same in prediction and solution inputs"
40+
41+
42+
# ground truth and predicted pseudotime
43+
TRUE_COL = "pseudotime_true"
44+
INFERRED_COL = "pseudotime_inferred"
45+
46+
true_vals = pd.to_numeric(input_solution.obs[TRUE_COL], errors='coerce').values
47+
inferred_vals = pd.to_numeric(input_prediction.obs[INFERRED_COL], errors='coerce').values
48+
49+
# generate results
50+
print('Compute metrics', flush=True)
51+
# metric_ids and metric_values can have length > 1
52+
# but should be of equal length
53+
54+
score = compute_spearman(true_vals, inferred_vals)
55+
56+
uns_metric_ids = [ 'spearman_corr' ]
57+
uns_metric_values = [ score ]
58+
59+
# Write output data to file
60+
print("Write output AnnData to file...", flush=True)
61+
62+
output = ad.AnnData(
63+
obs=pd.DataFrame(index=pd.Index(np.array([], dtype=str))),
64+
var=pd.DataFrame(index=pd.Index(np.array([], dtype=str))),
65+
uns={
66+
'dataset_id': input_solution.uns.get('dataset_id', 'unknown'),
67+
'normalization_id': input_solution.uns.get('normalization_id', 'unknown'),
68+
'method_id': input_prediction.uns.get('method_id', 'unknown'),
69+
'metric_ids': uns_metric_ids,
70+
'metric_values': uns_metric_values,
71+
}
72+
)
73+
74+
output.write_h5ad(par['output'], compression='gzip')

0 commit comments

Comments
 (0)