Skip to content

Commit 9b50918

Browse files
committed
refactor: use new algorithm system
1 parent 025811e commit 9b50918

File tree

2 files changed

+73
-57
lines changed

2 files changed

+73
-57
lines changed

spras/tiedie.py

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from pathlib import Path
2+
from typing import Optional
23

34
import pandas as pd
5+
from pydantic import BaseModel, ConfigDict
46

57
from spras.config.container_schema import ProcessedContainerSettings
68
from spras.containers import prepare_volume, run_container_and_log
@@ -11,9 +13,35 @@
1113
from spras.prm import PRM
1214
from spras.util import add_rank_column, duplicate_edges, raw_pathway_df
1315

14-
__all__ = ["TieDIE"]
16+
__all__ = ["TieDIE", "TieDIEParams"]
1517

16-
class TieDIE(PRM):
18+
class TieDIEParams(BaseModel):
19+
s: float = 1
20+
"""Network size control factor"""
21+
22+
d_expr: Optional[str] = None
23+
"""List of significantly differentially expressed genes,
24+
along with log-FC or FC values (i.e. by edgeR for RNA-Seq or SAM for microarray data.)
25+
Generated by a sample-dichotomy of interest."""
26+
27+
a: Optional[float] = None
28+
"""Linker Cutoff (overrides the Size factor)"""
29+
30+
c: int = 3
31+
"""Search depth for causal paths"""
32+
33+
p: int = 1000
34+
"""Number of random permutations performed for significance analysis"""
35+
36+
pagerank: bool = False
37+
"""Use Personalized PageRank to Diffuse """
38+
39+
all_paths: bool = False
40+
"""Use all paths instead of only causal paths"""
41+
42+
model_config = ConfigDict(extra='forbid', use_attribute_docstrings=True)
43+
44+
class TieDIE(PRM[TieDIEParams]):
1745
# we need edges (weighted), source set (with prizes), and target set (with prizes).
1846
required_inputs = ["edges", "sources", "targets"]
1947
dois = ["10.1093/bioinformatics/btt471"]
@@ -24,6 +52,9 @@ def generate_inputs(data, filename_map):
2452
Access fields from the dataset and write the required input files
2553
@param data: dataset
2654
@param filename_map: a dict mapping file types in the required_inputs to the filename for that type
55+
- source: input node types with sources (required)
56+
- target: input node types with targets (required)
57+
- edges: input edges file (required)
2758
"""
2859
# ensures the required input are within the filename_map
2960
for input_type in TieDIE.required_inputs:
@@ -62,39 +93,22 @@ def generate_inputs(data, filename_map):
6293

6394
# Skips parameter validation step
6495
@staticmethod
65-
def run(edges=None, sources=None, targets=None, output_file=None, s: float = 1.0 , c: int = 3 , p: int = 1000, pagerank: bool = False, all_paths: bool = False, container_settings=None):
66-
"""
67-
Run TieDIE with Docker
68-
@param source: input node types with sources (required)
69-
@param target: input node types with targets (required)
70-
@param edges: input edges file (required)
71-
@param output_file: path to the output pathway file (required)
72-
@param s: Network size control factor (optional) (default 1)
73-
@param d_expr: List of significantly differentially expressed genes, along with log-FC or FC values (i.e. by edgeR for RNA-Seq or SAM for microarray data.) Generated by a sample-dichotomy of interest. (optional)
74-
@param a: Linker Cutoff (overrides the Size factor) (optional)
75-
@param c: Search depth for causal paths (optional) (default 3)
76-
@param p: Number of random permutations performed for significance analysis (optional) (default 1000)
77-
@param pagerank: Use Personalized PageRank to Diffuse (optional)
78-
@param all_paths: Use all paths instead of only causal paths (optional) (default False)
79-
@param singularity: if True, run using the Singularity container instead of the Docker container
80-
"""
81-
96+
def run(inputs, output_file, args=None, container_settings=None):
97+
if not args: args = TieDIEParams()
8298
if not container_settings: container_settings = ProcessedContainerSettings()
83-
if not edges or not sources or not targets or not output_file:
84-
raise ValueError("Required TieDIE arguments are missing")
8599

86100
work_dir = "/spras"
87101

88102
# Each volume is a tuple (src, dest) - data generated by Docker
89103
volumes = list()
90104

91-
bind_path, edges_file = prepare_volume(edges, work_dir, container_settings)
105+
bind_path, edges_file = prepare_volume(inputs["edges"], work_dir, container_settings)
92106
volumes.append(bind_path)
93107

94-
bind_path, sources_file = prepare_volume(sources, work_dir, container_settings)
108+
bind_path, sources_file = prepare_volume(inputs["sources"], work_dir, container_settings)
95109
volumes.append(bind_path)
96110

97-
bind_path, targets_file = prepare_volume(targets, work_dir, container_settings)
111+
bind_path, targets_file = prepare_volume(inputs["targets"], work_dir, container_settings)
98112
volumes.append(bind_path)
99113

100114
out_dir = Path(output_file).parent
@@ -110,11 +124,11 @@ def run(edges=None, sources=None, targets=None, output_file=None, s: float = 1.0
110124
"--up_heats", sources_file,
111125
"--down_heats", targets_file,
112126
"--network", edges_file,
113-
"--size", str(s),
114-
"--depth", str(c),
115-
"--permute", str(p),
116-
"--pagerank", "True" if pagerank else "False",
117-
"--all_paths", "False" if all_paths else "False",
127+
"--size", str(args.s),
128+
"--depth", str(args.c),
129+
"--permute", str(args.p),
130+
"--pagerank", "True" if args.pagerank else "False",
131+
"--all_paths", "False" if args.all_paths else "False",
118132
"--output_folder", mapped_out_dir,
119133
]
120134

test/TieDIE/test_tiedie.py

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import pytest
55

66
from spras.config.container_schema import ContainerFramework, ProcessedContainerSettings
7-
from spras.tiedie import TieDIE
7+
from spras.tiedie import TieDIE, TieDIEParams
88

99
TEST_DIR = Path('test', 'TieDIE')
1010
OUT_FILES = TEST_DIR / 'output' / 'output1' / 'tiedie_pathway.txt'
@@ -19,68 +19,70 @@ def test_tiedie_required(self):
1919
out_path = Path(OUT_FILES)
2020
out_path.unlink(missing_ok=True)
2121
# Only include required arguments
22-
TieDIE.run(sources=TEST_DIR / 'input' / 'source1.txt',
23-
targets=TEST_DIR / 'input' / 'target1.txt',
24-
edges=TEST_DIR / 'input' / 'pathway1.txt',
22+
TieDIE.run({"sources": TEST_DIR / 'input' / 'source1.txt',
23+
"targets": TEST_DIR / 'input' / 'target1.txt',
24+
"edges": TEST_DIR / 'input' / 'pathway1.txt'},
2525
output_file=OUT_FILES)
2626
assert out_path.exists()
2727

2828
def test_tiedie_alternative_graph(self):
2929
out_path = Path(OUT_FILES_1)
3030
out_path.unlink(missing_ok=True)
31-
TieDIE.run(sources=TEST_DIR / 'input' / 'source2.txt',
32-
targets=TEST_DIR / 'input' / 'target2.txt',
33-
edges=TEST_DIR / 'input' / 'pathway2.txt',
34-
output_file=OUT_FILES_1)
31+
TieDIE.run({"sources": TEST_DIR / 'input' / 'source2.txt',
32+
"targets": TEST_DIR / 'input' / 'target2.txt',
33+
"edges": TEST_DIR / 'input' / 'pathway2.txt'},
34+
output_file=OUT_FILES_1)
3535
assert out_path.exists()
3636

3737
def test_tiedie_some_optional(self):
3838
out_path = Path(OUT_FILES)
3939
out_path.unlink(missing_ok=True)
4040
# Include optional argument
41-
TieDIE.run(sources=TEST_DIR / 'input' / 'source1.txt',
42-
targets=TEST_DIR / 'input' / 'target1.txt',
43-
edges=TEST_DIR / 'input' / 'pathway1.txt',
44-
output_file=OUT_FILES,
41+
TieDIE.run({"sources": TEST_DIR / 'input' / 'source1.txt',
42+
"targets": TEST_DIR / 'input' / 'target1.txt',
43+
"edges": TEST_DIR / 'input' / 'pathway1.txt'},
44+
output_file=OUT_FILES,
45+
args=TieDIEParams(
4546
s=1.1,
4647
p=2000,
47-
pagerank = True)
48+
pagerank=True))
4849
assert out_path.exists()
4950

5051
def test_tiedie_all_optional(self):
5152
out_path = Path(OUT_FILES)
5253
out_path.unlink(missing_ok=True)
5354
# Include optional argument
54-
TieDIE.run(sources=TEST_DIR / 'input' / 'source1.txt',
55-
targets=TEST_DIR / 'input' / 'target1.txt',
56-
edges=TEST_DIR / 'input' / 'pathway1.txt',
57-
output_file=OUT_FILES,
58-
s=1.1,
55+
TieDIE.run({"sources": TEST_DIR / 'input' / 'source1.txt',
56+
"targets": TEST_DIR / 'input' / 'target1.txt',
57+
"edges": TEST_DIR / 'input' / 'pathway1.txt'},
58+
output_file=OUT_FILES,
59+
args=TieDIEParams(s=1.1,
5960
c=4,
6061
p=2000,
6162
pagerank=True,
62-
all_paths=True)
63+
all_paths=True))
6364
assert out_path.exists()
6465

6566
def test_tiedie_missing(self):
6667
# Test the expected error is raised when required arguments are missing
6768
with pytest.raises(ValueError):
6869
# No edges file
69-
TieDIE.run(sources=TEST_DIR / 'input' / '/source1.txt',
70-
targets=TEST_DIR / 'input' / '/target1.txt',
71-
output_file=OUT_FILES)
70+
TieDIE.run({"sources": TEST_DIR / 'input' / '/source1.txt',
71+
"targets": TEST_DIR / 'input' / '/target1.txt'},
72+
output_file=OUT_FILES)
7273

7374
@pytest.mark.skipif(not shutil.which('singularity'), reason='Singularity not found on system')
7475
def test_tiedie_singularity(self):
7576
out_path = Path(OUT_FILES)
7677
out_path.unlink(missing_ok=True)
7778
# Only include required arguments and run with Singularity
78-
TieDIE.run(sources=TEST_DIR / 'input' / 'source1.txt',
79-
targets=TEST_DIR / 'input' / 'target1.txt',
80-
edges=TEST_DIR / 'input' / 'pathway1.txt',
81-
output_file=OUT_FILES,
79+
TieDIE.run({"sources": TEST_DIR / 'input' / 'source1.txt',
80+
"targets": TEST_DIR / 'input' / 'target1.txt',
81+
"edges": TEST_DIR / 'input' / 'pathway1.txt'},
82+
output_file=OUT_FILES,
83+
args=TieDIEParams(
8284
s=1.1,
8385
p=2000,
84-
pagerank=True,
85-
container_settings=ProcessedContainerSettings(framework=ContainerFramework.singularity))
86+
pagerank=True),
87+
container_settings=ProcessedContainerSettings(framework=ContainerFramework.singularity))
8688
assert out_path.exists()

0 commit comments

Comments
 (0)