diff --git a/CHANGELOG.md b/CHANGELOG.md index e9a8396c..1b72a557 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# task_predict_modality 0.2.0 + +## NEW FUNCTIONALITY + +* `scripts/create_datasets`: Trim mod1's features when generating the test resources, so the two modalities differ in width. The common test datasets are square (134 x 134, 1500 x 1500), which let dimension mix-ups pass `viash test` (PR #51). + # task_predict_modality 0.1.1 ## NEW FUNCTIONALITY diff --git a/scripts/create_datasets/test_resources.sh b/scripts/create_datasets/test_resources.sh index 7c00b7f8..bd8f9206 100755 --- a/scripts/create_datasets/test_resources.sh +++ b/scripts/create_datasets/test_resources.sh @@ -27,6 +27,15 @@ nextflow run . \ --publish_dir "$OUTPUT_DIR" \ --output_state '$id/state.yaml' +# The common test datasets are square (134 x 134, 1500 x 1500), so a component can +# mix up n_vars(mod1) and n_vars(mod2) and still pass viash test. Trim mod1 so the +# fixture looks like a real dataset, where the two modalities differ in width. +echo "Trim mod1 features" +for name in bmmc_cite/normal bmmc_cite/swap bmmc_multiome/normal bmmc_multiome/swap; do + python scripts/create_datasets/trim_mod1_features.py \ + "$OUTPUT_DIR/openproblems_neurips2021/$name" +done + echo "Run one method" for name in bmmc_cite/normal bmmc_cite/swap bmmc_multiome/normal bmmc_multiome/swap; do diff --git a/scripts/create_datasets/trim_mod1_features.py b/scripts/create_datasets/trim_mod1_features.py new file mode 100755 index 00000000..bf0f6329 --- /dev/null +++ b/scripts/create_datasets/trim_mod1_features.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +"""Trim mod1 to fewer features than mod2 in the generated test resources. + +The common test datasets happen to be square -- bmmc_cite is 134 x 134 and +bmmc_multiome 1500 x 1500 -- so in resources_test a component can confuse +n_vars(mod1) with n_vars(mod2) and still pass `viash test`. That is not true of +any real dataset, where e.g. GEX has ~13953 features against 134 ADT proteins. + +Dropping a slice of mod1's features restores the asymmetry, so dimension +mix-ups fail in CI rather than on the first full run. +""" + +import sys +from pathlib import Path + +import anndata as ad + +# keep this fraction of mod1's features +KEEP_FRACTION = 0.75 + + +def trim(path: Path) -> None: + adata = ad.read_h5ad(path) + n_keep = int(adata.n_vars * KEEP_FRACTION) + trimmed = adata[:, :n_keep].copy() + trimmed.write_h5ad(path, compression="gzip") + print(f" {path}: {adata.n_vars} -> {trimmed.n_vars} features", flush=True) + + +def main(dataset_dir: str) -> None: + for name in ["train_mod1.h5ad", "test_mod1.h5ad"]: + trim(Path(dataset_dir) / name) + + +if __name__ == "__main__": + main(sys.argv[1])