Skip to content

Commit 57c64f5

Browse files
author
IvanARashid
authored
Merge pull request #30 from OSIPI/analysis/parallel_processing
Analysis/parallel processing
2 parents 40374d8 + ff2cd75 commit 57c64f5

File tree

6 files changed

+1693
-23
lines changed

6 files changed

+1693
-23
lines changed

.github/workflows/analysis.yml

Lines changed: 128 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,111 @@ on:
77
- 'analysis/**'
88

99
jobs:
10-
build:
10+
algorithms:
11+
runs-on: ubuntu-latest
12+
outputs: # here we use the outputs from steps, and set outputs for the job `configure`
13+
algorithms: ${{ steps.algorithms.outputs.algorithms }}
14+
steps:
15+
- uses: actions/checkout@v3
16+
- name: Set up Python
17+
id: setup_python
18+
uses: actions/setup-python@v4
19+
with:
20+
python-version: "3.11"
21+
cache: 'pip'
22+
# - name: Cache virtualenv
23+
# uses: actions/cache@v3
24+
# with:
25+
# key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}
26+
# path: .venv
27+
- name: Install dependencies
28+
run: |
29+
python -m venv .venv
30+
source .venv/bin/activate
31+
python -m pip install -r requirements.txt
32+
python -m pip install pytest
33+
- name: Read algorithms
34+
id: algorithms
35+
run: |
36+
echo 'algorithms<<EOF' >> $GITHUB_OUTPUT
37+
cat ./tests/IVIMmodels/unit_tests/algorithms.json >> $GITHUB_OUTPUT
38+
echo 'EOF' >> $GITHUB_OUTPUT
39+
- name: Log algorithms
40+
run: |
41+
echo "${{fromJson(steps.algorithms.outputs.algorithms)}}"
42+
echo "${{fromJson(steps.algorithms.outputs.algorithms).algorithms}}"
43+
- name: Log algorithms file
44+
run: cat ./tests/IVIMmodels/unit_tests/algorithms.json
1145

46+
build:
1247
runs-on: ubuntu-latest
48+
needs: algorithms
1349
continue-on-error: false
1450
strategy:
1551
fail-fast: false
52+
matrix:
53+
algorithm: ${{fromJson(needs.algorithms.outputs.algorithms).algorithms}}
54+
SNR: [10, 30, 50, 100, 200]
1655
steps:
1756
- uses: actions/checkout@v3
1857
- name: Set up Python
1958
uses: actions/setup-python@v4
2059
with:
2160
python-version: "3.11"
61+
cache: 'pip'
62+
# - name: Cache virtualenv
63+
# uses: actions/cache@v3
64+
# with:
65+
# key: venv-${{ runner.os }}-${{ steps.setup_python.outputs.python-version}}-${{ hashFiles('requirements.txt') }}
66+
# path: .venv
2267
- name: Install dependencies
2368
run: |
24-
python -m pip install --upgrade pip
25-
pip install -r requirements.txt
69+
python -m venv .venv
70+
source .venv/bin/activate
71+
python -m pip install -r requirements.txt
72+
python -m pip install pytest
73+
- name: Generate fitting data
74+
run: |
75+
source .venv/bin/activate
76+
python -m pytest -m slow --selectAlgorithm ${{ matrix.algorithm }} --saveFileName test_output_${{ matrix.algorithm }}_${{ matrix.SNR }}.csv --SNR ${{ matrix.SNR }} --fitCount 300 --saveDurationFileName test_duration_${{ matrix.algorithm }}_${{ matrix.SNR }}.csv
77+
- name: Upload raw data
78+
uses: actions/upload-artifact@v3
79+
with:
80+
name: Working_Data
81+
retention-days: 1
82+
path: |
83+
test_output_${{ matrix.algorithm }}_${{ matrix.SNR }}.csv
84+
test_duration_${{ matrix.algorithm }}_${{ matrix.SNR }}.csv
85+
86+
merge:
87+
runs-on: ubuntu-latest
88+
needs: build
89+
steps:
90+
- name: Download artifacts
91+
uses: actions/download-artifact@v3
92+
with:
93+
path: artifacts
94+
- name: Merge fitting results
95+
run: |
96+
head -n 1 $(ls artifacts/Working_Data/test_output_*.csv | head -n 1) > test_output.csv
97+
tail -q -n +2 artifacts/Working_Data/test_output_*.csv >> test_output.csv
98+
- name: Merge timing results
99+
run: |
100+
head -n 1 $(ls artifacts/Working_Data/test_duration_*.csv | head -n 1) > test_duration.csv
101+
tail -q -n +2 artifacts/Working_Data/test_duration_*.csv >> test_duration.csv
102+
- name: Upload merged artifacts
103+
uses: actions/upload-artifact@v3
104+
with:
105+
name: Data
106+
path: |
107+
test_output.csv
108+
test_duration.csv
109+
110+
analyze:
111+
runs-on: ubuntu-latest
112+
needs: merge
113+
steps:
114+
- uses: actions/checkout@v3
26115
- name: Set up R
27116
uses: r-lib/actions/setup-r@v2
28117
with:
@@ -36,23 +125,17 @@ jobs:
36125
any::tidyverse
37126
any::data.table
38127
any::ggplot2
39-
- name: Generate fitting data
40-
run: |
41-
pip install pytest
42-
python -m pytest -m slow --saveFileName test_output.csv --SNR 10 30 50 100 200 --fitCount 300 --saveDurationFileName test_duration.csv
128+
- name: Download artifacts
129+
uses: actions/download-artifact@v3
130+
with:
131+
name: Data
43132
- name: Generate figures
44133
run: Rscript --vanilla tests/IVIMmodels/unit_tests/analyze.r test_output.csv test_duration.csv
45-
- name: Upload raw data
46-
uses: actions/upload-artifact@v3
47-
with:
48-
name: Raw data
49-
path: |
50-
test_output.csv
51-
test_duration.csv
52134
- name: Upload figures
53135
uses: actions/upload-artifact@v3
136+
if: always()
54137
with:
55-
name: Fit figures
138+
name: Figures
56139
path: |
57140
D.pdf
58141
f.pdf
@@ -63,3 +146,33 @@ jobs:
63146
durations.pdf
64147
curve_plot.pdf
65148
fitted_curves.pdf
149+
150+
compare:
151+
runs-on: ubuntu-latest
152+
needs: merge
153+
steps:
154+
- uses: actions/checkout@v3
155+
- name: Set up R
156+
uses: r-lib/actions/setup-r@v2
157+
with:
158+
use-public-rspm: true
159+
- name: Install R dependencies
160+
uses: r-lib/actions/setup-r-dependencies@v2
161+
with:
162+
packages: |
163+
any::tidyverse
164+
any::assertr
165+
- name: Download artifacts
166+
uses: actions/download-artifact@v3
167+
with:
168+
name: Data
169+
- name: Test against previous results
170+
run: Rscript --vanilla tests/IVIMmodels/unit_tests/compare.r test_output.csv test_reference.csv tests/IVIMmodels/unit_tests/reference_output.csv test_results.csv
171+
- name: Upload data
172+
uses: actions/upload-artifact@v3
173+
if: always()
174+
with:
175+
name: Comparison
176+
path: |
177+
test_reference.csv
178+
test_results.csv

.github/workflows/unit_test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323
uses: actions/setup-python@v4
2424
with:
2525
python-version: ${{ matrix.python-version }}
26+
cache: 'pip'
2627
# You can test your matrix by printing the current Python version
2728
- name: Display Python version
2829
run: python -c "import sys; print(sys.version)"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ The **utils** folder contains various helpful tools.
3131

3232
## View Testing Reports
3333
[![Unit tests](https://github.com/OSIPI/TF2.4_IVIM-MRI_CodeCollection/actions/workflows/unit_test.yml/badge.svg?branch=main)](https://github.com/OSIPI/TF2.4_IVIM-MRI_CodeCollection/actions/workflows/unit_test.yml)
34+
[![Algorithm Analysis](https://github.com/OSIPI/TF2.4_IVIM-MRI_CodeCollection/actions/workflows/analysis.yml/badge.svg?branch=main)](https://github.com/OSIPI/TF2.4_IVIM-MRI_CodeCollection/actions/workflows/analysis.yml)

conftest.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ def pytest_addoption(parser):
6767
type=str,
6868
help="Saved duration results file name",
6969
)
70+
parser.addoption(
71+
"--selectAlgorithm",
72+
default=[""],
73+
nargs="+",
74+
type=str,
75+
help="Drop all algorithms except for these from the list"
76+
)
77+
parser.addoption(
78+
"--dropAlgorithm",
79+
default=[""],
80+
nargs="+",
81+
type=str,
82+
help="Drop this algorithm from the list"
83+
)
7084

7185

7286
@pytest.fixture(scope="session")
@@ -115,7 +129,6 @@ def save_duration_file(request):
115129
def rtol(request):
116130
return request.config.getoption("--rtol")
117131

118-
119132
@pytest.fixture(scope="session")
120133
def atol(request):
121134
return request.config.getoption("--atol")
@@ -137,23 +150,23 @@ def pytest_generate_tests(metafunc):
137150
if "SNR" in metafunc.fixturenames:
138151
metafunc.parametrize("SNR", metafunc.config.getoption("SNR"))
139152
if "ivim_algorithm" in metafunc.fixturenames:
140-
algorithms = algorithm_list(metafunc.config.getoption("algorithmFile"))
153+
algorithms = algorithm_list(metafunc.config.getoption("algorithmFile"), metafunc.config.getoption("selectAlgorithm"), metafunc.config.getoption("dropAlgorithm"))
141154
metafunc.parametrize("ivim_algorithm", algorithms)
142-
if "algorithm_file" in metafunc.fixturenames:
143-
metafunc.parametrize("algorithm_file", metafunc.config.getoption("algorithmFile"))
144155
if "ivim_data" in metafunc.fixturenames:
145156
data = data_list(metafunc.config.getoption("dataFile"))
146157
metafunc.parametrize("ivim_data", data)
147-
if "data_file" in metafunc.fixturenames:
148-
metafunc.parametrize("data_file", metafunc.config.getoption("dataFile"))
149158

150159

151-
def algorithm_list(filename):
160+
def algorithm_list(filename, selected, dropped):
152161
current_folder = pathlib.Path.cwd()
153162
algorithm_path = current_folder / filename
154163
with algorithm_path.open() as f:
155164
algorithm_information = json.load(f)
156-
return algorithm_information["algorithms"]
165+
algorithms = set(algorithm_information["algorithms"])
166+
algorithms = algorithms - set(dropped)
167+
if len(selected) > 0 and selected[0]:
168+
algorithms = algorithms & set(selected)
169+
return list(algorithms)
157170

158171
def data_list(filename):
159172
current_folder = pathlib.Path.cwd()

0 commit comments

Comments
 (0)