From fb37e3ca6ce4e5ace046e99a7e39d754a76ea2a5 Mon Sep 17 00:00:00 2001 From: "Tristan F.-R." Date: Tue, 29 Jul 2025 14:52:22 -0700 Subject: [PATCH 1/7] ci: try out windows --- .github/workflows/test-spras.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/test-spras.yml b/.github/workflows/test-spras.yml index d5bf2adf5..006539a4d 100644 --- a/.github/workflows/test-spras.yml +++ b/.github/workflows/test-spras.yml @@ -25,6 +25,24 @@ jobs: shell: bash --login {0} run: conda list + test_windows: + name: Run weakened windows tests + runs-on: windows-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install conda environment + uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: spras + environment-file: environment.yml + auto-activate-base: false + miniconda-version: 'latest' + - name: Run tests + shell: bash --login {0} + # Verbose output and disable stdout and stderr capturing + run: pytest -vs --ignore=test/AllPairs --ignore=test/BowTieBuilder --ignore=test/DOMINO --ignore=test/MEO --ignore=test/MinCostFlow --ignore=test/OmicsIntegrator1 --ignore=--ignore=test/OmicsIntegrator2 --ignore=test/PathLinker --ignore=test/ResponseNet --ignore=test/RWR --ignore=test/ST_RWR + # Runs the test code and Snakemake workflow in the conda environment test: name: Run tests From cf40bf3247c68443a0f9c81f49b588a6253f7608 Mon Sep 17 00:00:00 2001 From: "Tristan F.-R." Date: Tue, 29 Jul 2025 22:12:51 +0000 Subject: [PATCH 2/7] ci: typo --- .github/workflows/test-spras.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-spras.yml b/.github/workflows/test-spras.yml index 7805f0f06..1d740f232 100644 --- a/.github/workflows/test-spras.yml +++ b/.github/workflows/test-spras.yml @@ -41,7 +41,7 @@ jobs: - name: Run tests shell: bash --login {0} # Verbose output and disable stdout and stderr capturing - run: pytest -vs --ignore=test/AllPairs --ignore=test/BowTieBuilder --ignore=test/DOMINO --ignore=test/MEO --ignore=test/MinCostFlow --ignore=test/OmicsIntegrator1 --ignore=--ignore=test/OmicsIntegrator2 --ignore=test/PathLinker --ignore=test/ResponseNet --ignore=test/RWR --ignore=test/ST_RWR + run: pytest -vs --ignore=test/AllPairs --ignore=test/BowTieBuilder --ignore=test/DOMINO --ignore=test/MEO --ignore=test/MinCostFlow --ignore=test/OmicsIntegrator1 --ignore=test/OmicsIntegrator2 --ignore=test/PathLinker --ignore=test/ResponseNet --ignore=test/RWR --ignore=test/ST_RWR # Runs the test code and Snakemake workflow in the conda environment test: From ced0339a6ca7dd84885795cef9087c7f941dc84a Mon Sep 17 00:00:00 2001 From: "Tristan F.-R." Date: Tue, 29 Jul 2025 22:32:50 +0000 Subject: [PATCH 3/7] test: ignore cytoscape, attempt pca windows fix --- .github/workflows/test-spras.yml | 2 +- test/evaluate/expected/expected-pr-per-pathway-pca-chosen.txt | 4 ++-- test/evaluate/test_evaluate.py | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-spras.yml b/.github/workflows/test-spras.yml index 1d740f232..31f430eec 100644 --- a/.github/workflows/test-spras.yml +++ b/.github/workflows/test-spras.yml @@ -41,7 +41,7 @@ jobs: - name: Run tests shell: bash --login {0} # Verbose output and disable stdout and stderr capturing - run: pytest -vs --ignore=test/AllPairs --ignore=test/BowTieBuilder --ignore=test/DOMINO --ignore=test/MEO --ignore=test/MinCostFlow --ignore=test/OmicsIntegrator1 --ignore=test/OmicsIntegrator2 --ignore=test/PathLinker --ignore=test/ResponseNet --ignore=test/RWR --ignore=test/ST_RWR + run: pytest -vs --ignore=test/AllPairs --ignore=test/BowTieBuilder --ignore=test/DOMINO --ignore=test/analysis/test_cytoscape.py --ignore=test/MEO --ignore=test/MinCostFlow --ignore=test/OmicsIntegrator1 --ignore=test/OmicsIntegrator2 --ignore=test/PathLinker --ignore=test/ResponseNet --ignore=test/RWR --ignore=test/ST_RWR # Runs the test code and Snakemake workflow in the conda environment test: diff --git a/test/evaluate/expected/expected-pr-per-pathway-pca-chosen.txt b/test/evaluate/expected/expected-pr-per-pathway-pca-chosen.txt index 97c13ebc3..13c6fb8f7 100644 --- a/test/evaluate/expected/expected-pr-per-pathway-pca-chosen.txt +++ b/test/evaluate/expected/expected-pr-per-pathway-pca-chosen.txt @@ -1,2 +1,2 @@ -Pathway Precision Recall -test/evaluate/input/data-test-params-123/pathway.txt 0.6666666666666666 0.5 +Precision Recall +0.6666666666666666 0.5 diff --git a/test/evaluate/test_evaluate.py b/test/evaluate/test_evaluate.py index 4ad4d5f7b..bfd9cf2bf 100644 --- a/test/evaluate/test_evaluate.py +++ b/test/evaluate/test_evaluate.py @@ -56,7 +56,9 @@ def test_precision_recall_pca_chosen_pathway(self): Evaluation.precision_and_recall(pathway, GS_NODE_TABLE, algorithms, str(output_file), str(output_png)) chosen = pd.read_csv(output_file, sep="\t", header=0).round(8) - expected = pd.read_csv(EXPECT_DIR + "expected-pr-per-pathway-pca-chosen.txt", sep="\t", header=0).round(8) + expected = pd.read_csv(EXPECT_DIR + "expected-pr-per-pathway-pca-chosen.txt", sep="\t", header=0).round(8) + # For windows support + expected.insert(loc=0, column='Pathway', value=[Path("test", "evaluate", "input", "data-test-params-123", "pathway.txt")]) assert chosen.equals(expected) assert output_png.exists() From c9319aec00161a6132c701450e23f2bfbee09a4a Mon Sep 17 00:00:00 2001 From: "Tristan F.-R." Date: Tue, 29 Jul 2025 22:52:22 +0000 Subject: [PATCH 4/7] fix: use correct datatype --- test/evaluate/test_evaluate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/evaluate/test_evaluate.py b/test/evaluate/test_evaluate.py index bfd9cf2bf..dcfaa0d0f 100644 --- a/test/evaluate/test_evaluate.py +++ b/test/evaluate/test_evaluate.py @@ -58,7 +58,7 @@ def test_precision_recall_pca_chosen_pathway(self): chosen = pd.read_csv(output_file, sep="\t", header=0).round(8) expected = pd.read_csv(EXPECT_DIR + "expected-pr-per-pathway-pca-chosen.txt", sep="\t", header=0).round(8) # For windows support - expected.insert(loc=0, column='Pathway', value=[Path("test", "evaluate", "input", "data-test-params-123", "pathway.txt")]) + expected.insert(loc=0, column='Pathway', value=[str(Path("test", "evaluate", "input", "data-test-params-123", "pathway.txt"))]) assert chosen.equals(expected) assert output_png.exists() From 2ea77377fa6c768ecb6929e6f37080895968845c Mon Sep 17 00:00:00 2001 From: "Tristan F.-R." Date: Tue, 29 Jul 2025 23:07:52 +0000 Subject: [PATCH 5/7] ci: dbg for the fun of the game --- test/evaluate/test_evaluate.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/evaluate/test_evaluate.py b/test/evaluate/test_evaluate.py index dcfaa0d0f..4cf34c1ac 100644 --- a/test/evaluate/test_evaluate.py +++ b/test/evaluate/test_evaluate.py @@ -60,6 +60,10 @@ def test_precision_recall_pca_chosen_pathway(self): # For windows support expected.insert(loc=0, column='Pathway', value=[str(Path("test", "evaluate", "input", "data-test-params-123", "pathway.txt"))]) + pd.set_option('display.max_colwidth', None) + print() + print(chosen) + print(expected) assert chosen.equals(expected) assert output_png.exists() From 0a2415cc2d4ec31bd7517e0f0222798e6d345413 Mon Sep 17 00:00:00 2001 From: "Tristan F.-R." Date: Tue, 29 Jul 2025 23:19:00 +0000 Subject: [PATCH 6/7] fix: paths and more paths --- test/evaluate/test_evaluate.py | 96 ++++++++++++++++------------------ 1 file changed, 46 insertions(+), 50 deletions(-) diff --git a/test/evaluate/test_evaluate.py b/test/evaluate/test_evaluate.py index 4cf34c1ac..41efd333e 100644 --- a/test/evaluate/test_evaluate.py +++ b/test/evaluate/test_evaluate.py @@ -8,11 +8,11 @@ from spras.dataset import Dataset from spras.evaluation import Evaluation -INPUT_DIR = 'test/evaluate/input/' -OUT_DIR = 'test/evaluate/output/' -EXPECT_DIR = 'test/evaluate/expected/' -GS_NODE_TABLE = pd.read_csv(INPUT_DIR + 'gs_node_table.csv', header=0) -SUMMARY_FILE = INPUT_DIR + 'example_summary.txt' +INPUT_DIR = Path('test', 'evaluate', 'input') +OUT_DIR = Path('test', 'evaluate', 'output') +EXPECT_DIR = Path('test', 'evaluate', 'expected') +GS_NODE_TABLE = pd.read_csv(INPUT_DIR / 'gs_node_table.csv', header=0) +SUMMARY_FILE = INPUT_DIR / 'example_summary.txt' class TestEvaluate: @@ -38,114 +38,110 @@ def setup_class(cls): pickle.dump(dataset, f) def test_precision_recall_pca_chosen_pathway(self): - output_file = Path(OUT_DIR + "test-pr-per-pathway-pca-chosen.txt") + output_file = OUT_DIR / "test-pr-per-pathway-pca-chosen.txt" output_file.unlink(missing_ok=True) - output_png = Path(OUT_DIR + "test-pr-per-pathway-pca-chosen.png") + output_png = OUT_DIR / "test-pr-per-pathway-pca-chosen.png" output_png.unlink(missing_ok=True) - output_coordinates = Path(OUT_DIR + "pca-coordinates.tsv") + output_coordinates = OUT_DIR / "pca-coordinates.tsv" output_coordinates.unlink(missing_ok=True) - file_paths = [INPUT_DIR + "data-test-params-123/pathway.txt", INPUT_DIR + "data-test-params-456/pathway.txt", - INPUT_DIR + "data-test-params-789/pathway.txt", INPUT_DIR + "data-test-params-empty/pathway.txt"] + file_paths = [INPUT_DIR / "data-test-params-123" / "pathway.txt", INPUT_DIR / "data-test-params-456" / "pathway.txt", + INPUT_DIR / "data-test-params-789" / "pathway.txt", INPUT_DIR / "data-test-params-empty" / "pathway.txt"] algorithms = ["test"] dataframe = ml.summarize_networks(file_paths) - ml.pca(dataframe, OUT_DIR + 'pca.png', OUT_DIR + 'pca-variance.txt', output_coordinates, kde=True, remove_empty_pathways=True) + ml.pca(dataframe, str(OUT_DIR / 'pca.png'), str(OUT_DIR / 'pca-variance.txt'), output_coordinates, kde=True, remove_empty_pathways=True) - pathway = Evaluation.pca_chosen_pathway([output_coordinates], SUMMARY_FILE, INPUT_DIR) + pathway = Evaluation.pca_chosen_pathway([output_coordinates], str(SUMMARY_FILE), str(INPUT_DIR)) Evaluation.precision_and_recall(pathway, GS_NODE_TABLE, algorithms, str(output_file), str(output_png)) chosen = pd.read_csv(output_file, sep="\t", header=0).round(8) - expected = pd.read_csv(EXPECT_DIR + "expected-pr-per-pathway-pca-chosen.txt", sep="\t", header=0).round(8) + expected = pd.read_csv(EXPECT_DIR / "expected-pr-per-pathway-pca-chosen.txt", sep="\t", header=0).round(8) # For windows support expected.insert(loc=0, column='Pathway', value=[str(Path("test", "evaluate", "input", "data-test-params-123", "pathway.txt"))]) - pd.set_option('display.max_colwidth', None) - print() - print(chosen) - print(expected) assert chosen.equals(expected) assert output_png.exists() def test_precision_recall_pca_chosen_pathway_not_provided(self): - output_file = OUT_DIR +"test-pr-per-pathway-pca-chosen-not-provided.txt" - output_png = Path(OUT_DIR + "test-pr-per-pathway-pca-chosen-not-provided.png") + output_file = OUT_DIR / "test-pr-per-pathway-pca-chosen-not-provided.txt" + output_png = OUT_DIR / "test-pr-per-pathway-pca-chosen-not-provided.png" output_png.unlink(missing_ok=True) algorithms = ["test"] Evaluation.precision_and_recall([], GS_NODE_TABLE, algorithms, str(output_file), str(output_png)) chosen = pd.read_csv(output_file, sep="\t", header=0).round(8) - expected = pd.read_csv(EXPECT_DIR + 'expected-pr-per-pathway-pca-chosen-not-provided.txt', sep="\t", header=0).round(8) + expected = pd.read_csv(EXPECT_DIR / 'expected-pr-per-pathway-pca-chosen-not-provided.txt', sep="\t", header=0).round(8) assert chosen.equals(expected) assert output_png.exists() def test_node_ensemble(self): - out_path_file = Path(OUT_DIR + 'node-ensemble.csv') + out_path_file = OUT_DIR / 'node-ensemble.csv' out_path_file.unlink(missing_ok=True) - ensemble_network = [INPUT_DIR + 'ensemble-network.tsv'] - input_network = OUT_DIR + 'data.pickle' - node_ensemble_dict = Evaluation.edge_frequency_node_ensemble(GS_NODE_TABLE, ensemble_network, input_network) + ensemble_network = [INPUT_DIR / 'ensemble-network.tsv'] + input_network = OUT_DIR / 'data.pickle' + node_ensemble_dict = Evaluation.edge_frequency_node_ensemble(GS_NODE_TABLE, ensemble_network, str(input_network)) node_ensemble_dict['ensemble'].to_csv(out_path_file, sep='\t', index=False) - assert filecmp.cmp(out_path_file, EXPECT_DIR + 'expected-node-ensemble.csv', shallow=False) + assert filecmp.cmp(out_path_file, EXPECT_DIR / 'expected-node-ensemble.csv', shallow=False) def test_empty_node_ensemble(self): - out_path_file = Path(OUT_DIR + 'empty-node-ensemble.csv') + out_path_file = OUT_DIR / 'empty-node-ensemble.csv' out_path_file.unlink(missing_ok=True) - empty_ensemble_network = [INPUT_DIR + 'empty-ensemble-network.tsv'] - input_network = OUT_DIR + 'data.pickle' + empty_ensemble_network = [INPUT_DIR / 'empty-ensemble-network.tsv'] + input_network = OUT_DIR / 'data.pickle' node_ensemble_dict = Evaluation.edge_frequency_node_ensemble(GS_NODE_TABLE, empty_ensemble_network, - input_network) + str(input_network)) node_ensemble_dict['empty'].to_csv(out_path_file, sep='\t', index=False) - assert filecmp.cmp(out_path_file, EXPECT_DIR + 'expected-empty-node-ensemble.csv', shallow=False) + assert filecmp.cmp(out_path_file, EXPECT_DIR / 'expected-empty-node-ensemble.csv', shallow=False) def test_multiple_node_ensemble(self): - out_path_file = Path(OUT_DIR + 'node-ensemble.csv') + out_path_file = OUT_DIR / 'node-ensemble.csv' out_path_file.unlink(missing_ok=True) - out_path_empty_file = Path(OUT_DIR + 'empty-node-ensemble.csv') + out_path_empty_file = OUT_DIR / 'empty-node-ensemble.csv' out_path_empty_file.unlink(missing_ok=True) - ensemble_networks = [INPUT_DIR + 'ensemble-network.tsv', INPUT_DIR + 'empty-ensemble-network.tsv'] - input_network = OUT_DIR + 'data.pickle' - node_ensemble_dict = Evaluation.edge_frequency_node_ensemble(GS_NODE_TABLE, ensemble_networks, input_network) + ensemble_networks = [INPUT_DIR / 'ensemble-network.tsv', INPUT_DIR / 'empty-ensemble-network.tsv'] + input_network = OUT_DIR / 'data.pickle' + node_ensemble_dict = Evaluation.edge_frequency_node_ensemble(GS_NODE_TABLE, ensemble_networks, str(input_network)) node_ensemble_dict['ensemble'].to_csv(out_path_file, sep='\t', index=False) - assert filecmp.cmp(out_path_file, EXPECT_DIR + 'expected-node-ensemble.csv', shallow=False) + assert filecmp.cmp(out_path_file, EXPECT_DIR / 'expected-node-ensemble.csv', shallow=False) node_ensemble_dict['empty'].to_csv(out_path_empty_file, sep='\t', index=False) - assert filecmp.cmp(out_path_empty_file, EXPECT_DIR + 'expected-empty-node-ensemble.csv', shallow=False) + assert filecmp.cmp(out_path_empty_file, EXPECT_DIR / 'expected-empty-node-ensemble.csv', shallow=False) def test_precision_recall_curve_ensemble_nodes(self): - out_path_png = Path(OUT_DIR + "pr-curve-ensemble-nodes.png") + out_path_png = OUT_DIR / "pr-curve-ensemble-nodes.png" out_path_png.unlink(missing_ok=True) - out_path_file = Path(OUT_DIR + "pr-curve-ensemble-nodes.txt") + out_path_file = OUT_DIR / "pr-curve-ensemble-nodes.txt" out_path_file.unlink(missing_ok=True) - ensemble_file = pd.read_csv(INPUT_DIR + 'node-ensemble.csv', sep='\t', header=0) + ensemble_file = pd.read_csv(INPUT_DIR / 'node-ensemble.csv', sep='\t', header=0) node_ensembles_dict = {'ensemble': ensemble_file} Evaluation.precision_recall_curve_node_ensemble(node_ensembles_dict, GS_NODE_TABLE, str(out_path_png), str(out_path_file)) assert out_path_png.exists() - assert filecmp.cmp(out_path_file, EXPECT_DIR + 'expected-pr-curve-ensemble-nodes.txt', shallow=False) + assert filecmp.cmp(out_path_file, EXPECT_DIR / 'expected-pr-curve-ensemble-nodes.txt', shallow=False) def test_precision_recall_curve_ensemble_nodes_empty(self): - out_path_png = Path(OUT_DIR + "pr-curve-ensemble-nodes-empty.png") + out_path_png = OUT_DIR / "pr-curve-ensemble-nodes-empty.png" out_path_png.unlink(missing_ok=True) - out_path_file = Path(OUT_DIR + "pr-curve-ensemble-nodes-empty.txt") + out_path_file = OUT_DIR / "pr-curve-ensemble-nodes-empty.txt" out_path_file.unlink(missing_ok=True) - empty_ensemble_file = pd.read_csv(INPUT_DIR + 'node-ensemble-empty.csv', sep='\t', header=0) + empty_ensemble_file = pd.read_csv(INPUT_DIR / 'node-ensemble-empty.csv', sep='\t', header=0) node_ensembles_dict = {'ensemble': empty_ensemble_file} Evaluation.precision_recall_curve_node_ensemble(node_ensembles_dict, GS_NODE_TABLE, str(out_path_png), str(out_path_file)) assert out_path_png.exists() - assert filecmp.cmp(out_path_file, EXPECT_DIR + 'expected-pr-curve-ensemble-nodes-empty.txt', shallow=False) + assert filecmp.cmp(out_path_file, EXPECT_DIR / 'expected-pr-curve-ensemble-nodes-empty.txt', shallow=False) def test_precision_recall_curve_multiple_ensemble_nodes(self): - out_path_png = Path(OUT_DIR + "pr-curve-multiple-ensemble-nodes.png") + out_path_png = OUT_DIR / "pr-curve-multiple-ensemble-nodes.png" out_path_png.unlink(missing_ok=True) - out_path_file = Path(OUT_DIR + "pr-curve-multiple-ensemble-nodes.txt") + out_path_file = OUT_DIR / "pr-curve-multiple-ensemble-nodes.txt" out_path_file.unlink(missing_ok=True) - ensemble_file = pd.read_csv(INPUT_DIR + 'node-ensemble.csv', sep='\t', header=0) - empty_ensemble_file = pd.read_csv(INPUT_DIR + 'node-ensemble-empty.csv', sep='\t', header=0) + ensemble_file = pd.read_csv(INPUT_DIR / 'node-ensemble.csv', sep='\t', header=0) + empty_ensemble_file = pd.read_csv(INPUT_DIR / 'node-ensemble-empty.csv', sep='\t', header=0) node_ensembles_dict = {'ensemble1': ensemble_file, 'ensemble2': ensemble_file, 'ensemble3': empty_ensemble_file} Evaluation.precision_recall_curve_node_ensemble(node_ensembles_dict, GS_NODE_TABLE, str(out_path_png), str(out_path_file)) assert out_path_png.exists() - assert filecmp.cmp(out_path_file, EXPECT_DIR + 'expected-pr-curve-multiple-ensemble-nodes.txt', shallow=False) + assert filecmp.cmp(out_path_file, EXPECT_DIR / 'expected-pr-curve-multiple-ensemble-nodes.txt', shallow=False) From c271322e51a076aba18213d282b23940b876ea75 Mon Sep 17 00:00:00 2001 From: "Tristan F." Date: Sat, 6 Sep 2025 01:32:38 -0700 Subject: [PATCH 7/7] fix: type pca_chosen_pathway --- spras/evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spras/evaluation.py b/spras/evaluation.py index 732e58576..0ac361c82 100644 --- a/spras/evaluation.py +++ b/spras/evaluation.py @@ -237,7 +237,7 @@ def precision_and_recall_pca_chosen_pathway(pr_df: pd.DataFrame, output_file: st plt.close() @staticmethod - def pca_chosen_pathway(coordinates_files: list[Union[str, PathLike]], pathway_summary_file: str, output_dir: str): + def pca_chosen_pathway(coordinates_files: list[Union[str, PathLike]], pathway_summary_file: Union[str, PathLike], output_dir: Union[str, PathLike]): """ Identifies the pathway closest to a specified highest kernel density estimated (KDE) peak based on PCA coordinates