Skip to content

Commit 76b69d2

Browse files
Merge pull request #78 from ArnovanHilten/dev
Add automatic testing
2 parents 5aaacdf + fadbd15 commit 76b69d2

File tree

5 files changed

+72
-31
lines changed

5 files changed

+72
-31
lines changed

.github/workflows/tests.yml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: PyTests
2+
on:
3+
- push
4+
- pull_request
5+
6+
jobs:
7+
build:
8+
runs-on: ubuntu-latest
9+
strategy:
10+
matrix:
11+
python-version: ["3.6","3.7", "3.8"]
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
- name: Set up Python ${{ matrix.python-version }}
16+
uses: actions/setup-python@v4
17+
with:
18+
python-version: ${{ matrix.python-version }}
19+
- name: Install dependencies
20+
run: |
21+
python -m pip install --upgrade pip
22+
if [ -f requirements_GenNet.txt ]; then pip install -r requirements_GenNet.txt; fi
23+
- name: Test with pytest
24+
run: |
25+
pytest

GenNet_utils/LocallyDirectedConnected_tf2.py

+13-10
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,12 @@ def build(self, input_shape):
158158
self.kernel_shape = (input_length, input_dim,
159159
self.output_length, self.filters)
160160

161-
self.kernel = self.add_weight(shape=(len(self.mask.data),), # sum of all nonzero values in mask sum(sum(mask))
161+
self.kernel = self.add_weight(shape=(len(self.mask.data)*self.filters,), # sum of all nonzero values in mask sum(sum(mask))
162162
initializer=self.kernel_initializer,
163163
name='kernel',
164164
regularizer=self.kernel_regularizer,
165165
constraint=self.kernel_constraint)
166-
self.kernel_idx = sorted(self.get_idx(self.mask))
166+
self.kernel_idx = self.get_idx(self.mask)
167167

168168
if self.use_bias:
169169
self.bias = self.add_weight(
@@ -182,8 +182,7 @@ def build(self, input_shape):
182182
self.built = True
183183

184184
def call(self, inputs):
185-
output = self.local_conv_matmul_sparse(inputs, self.mask, self.kernel, self.kernel_idx, self.output_length,
186-
self.filters)
185+
output = self.local_conv_matmul_sparse(inputs, self.mask, self.kernel, self.kernel_idx, self.output_length)
187186
if self.use_bias:
188187
output = K.bias_add(output, self.bias, data_format=self.data_format)
189188

@@ -224,7 +223,7 @@ def get_config(self):
224223
return dict(list(base_config.items()) + list(config.items()))
225224

226225

227-
def local_conv_matmul_sparse(self, inputs, mask, kernel, kernel_idx, output_length, filters):
226+
def local_conv_matmul_sparse(self, inputs, mask, kernel, kernel_idx, output_length):
228227
"""Apply N-D convolution with un-shared weights using a single matmul call.
229228
230229
Arguments:
@@ -256,19 +255,23 @@ def local_conv_matmul_sparse(self, inputs, mask, kernel, kernel_idx, output_leng
256255
inputs_flat = K.reshape(inputs, (K.shape(inputs)[0], -1))
257256

258257
output_flat = K.sparse_ops.sparse_tensor_dense_mat_mul(
259-
kernel_idx, kernel, (mask.shape[1], mask.shape[0]), inputs_flat, adjoint_b=True)
258+
kernel_idx, kernel, (mask.shape[1] * self.filters, mask.shape[0]), inputs_flat, adjoint_b=True)
260259

261260
output_flat_transpose = K.transpose(output_flat)
262-
output_reshaped = K.reshape(output_flat_transpose, [-1, output_length, filters])
261+
output_reshaped = K.reshape(output_flat_transpose, [-1, output_length, self.filters]) # gene dimension extension shaped back
263262
return output_reshaped
264263

265264

266265
def get_idx(self, mask):
267266
""""returns the transposed coordinates in tuple form:
268267
[(mask.col[0], mask,row[0])...[mask.col[n], mask.row[n])]"""
269268
coor_list = []
270-
for i, j in zip(mask.col, mask.row):
271-
coor_list.append((i, j))
272-
269+
offset = 0
270+
for fr in range(self.filters): # for each filter the gene/output dimension is expanded.
271+
filter_list=[]
272+
for i, j in zip(mask.col, mask.row):
273+
filter_list.append((i + offset, j))
274+
coor_list = coor_list + sorted(filter_list) # we sort per filter
275+
offset += mask.shape[1]
273276
return coor_list
274277

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[![DOI](https://zenodo.org/badge/240289809.svg)](https://zenodo.org/badge/latestdoi/240289809)
2+
![Build](https://github.com/ArnovanHilten/GenNet/actions/workflows/tests.yml/badge.svg)
23

34
# **GenNet**
45
**Framework for Interpretable Neural Networks for Genetics**

requirements_GenNet.txt

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ sklearn>=0.0
1515
tables>=3.6.1
1616
tqdm>=4.49.0
1717
zipp>=3.1.0
18+
pytest>=6.2.5
19+
protobuf>=3.11,<=3.20.2
1820
psutil
1921
kaleido
2022
tensorflow==2.2.0
23+
bitarray

tests/test_GenNet.py

+30-21
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,16 @@
66
from GenNet_utils.Create_plots import sunburst_plot, plot_layer_weight, manhattan_relative_importance
77
from GenNet_utils.Utility_functions import get_paths
88

9-
# import unittest
109
# TODO: add test without covariates
1110
# TODO add test with covariates for regression + classification
1211
# TODO add test with multiple genotype files.
1312
# test randomnesss after .. epoch shuffles.
14-
13+
# ToDO add test for each file.
1514

1615
def get_GenNet_path():
1716
return str(dirname(dirname(abspath(__file__)))) + "/"
1817

19-
def remove_old_test(ID):
18+
def remove_old(ID):
2019
GenNet_path = get_GenNet_path()
2120
resultpath = GenNet_path + "results/GenNet_experiment_" + str(ID) + '_/'
2221
try:
@@ -71,31 +70,44 @@ def test_convert(self):
7170
" -o {}/examples/A_to_Z/processed_data/"
7271
"/ -study_name GenNet_simulation -step all".format(GenNet_path, GenNet_path, GenNet_path) )
7372
assert test1 == 0
74-
75-
# !python GenNet.py topology -type create_annovar_input -path ./examples/A_to_Z/processed_data/ -study_name GenNet_simulation -out examples/A_to_Z/processed_data/
76-
77-
# !python GenNet.py topology -type create_gene_network -path examples/A_to_Z/processed_data/ -out examples/A_to_Z/processed_data/ -study_name GenNet_simulation
78-
79-
80-
# mkdir examples/A_to_Z/new_run_folder/
81-
# mv examples/A_to_Z/processed_data/SNP_gene_mask.npz examples/A_to_Z/new_run_folder/ # or topology.csv
82-
# mv examples/A_to_Z/processed_data/genotype.h5 examples/A_to_Z/new_run_folder/
83-
# cp examples/A_to_Z/run_folder/subjects.csv examples/A_to_Z/new_run_folder/
84-
73+
74+
def test_topology_annovar_input(self):
75+
GenNet_path = get_GenNet_path()
76+
test1 = os.system(
77+
"python {}/GenNet.py topology -type create_annovar_input -path {}//examples/A_to_Z/processed_data/ -study_name GenNet_simulation -out {}/examples/A_to_Z/processed_data/".format(GenNet_path, GenNet_path, GenNet_path) )
78+
assert test1 == 0
8579

86-
# !python GenNet.py train -path examples/A_to_Z/new_run_folder/ -ID 100001 -epochs 50
80+
def test_topology_create_gene_network(self):
81+
GenNet_path = get_GenNet_path()
82+
test1 = os.system(
83+
"python {}/GenNet.py topology -type create_gene_network -path {}/examples/A_to_Z/processed_data/ -out {}/examples/A_to_Z/processed_data/ -study_name GenNet_simulation".format(GenNet_path, GenNet_path, GenNet_path) )
84+
assert test1 == 0
8785

88-
# !python GenNet.py plot -ID 100001 -type manhattan_relative_importance
86+
def test_train_run(self):
87+
GenNet_path = get_GenNet_path()
88+
os.system('mkdir {}/examples/A_to_Z/new_run_folder/'.format(GenNet_path))
89+
os.system('cp {}/examples/A_to_Z/processed_data/topology.csv {}/examples/A_to_Z/new_run_folder/'.format(GenNet_path, GenNet_path))
90+
os.system('cp {}/examples/A_to_Z/processed_data/genotype.h5 {}/examples/A_to_Z/new_run_folder/'.format(GenNet_path, GenNet_path))
91+
os.system('cp {}/examples/A_to_Z/run_folder/subjects.csv {}/examples/A_to_Z/new_run_folder/'.format(GenNet_path, GenNet_path))
92+
test1 = os.system('python {}/GenNet.py train -path {}/examples/A_to_Z/new_run_folder/ -ID 999999997 -epochs 5'.format(GenNet_path, GenNet_path))
93+
assert test1 == 0
94+
95+
def test_manhattan_plot(self):
96+
GenNet_path = get_GenNet_path()
97+
test1 = os.system(
98+
"python {}/GenNet.py plot -ID 999999997 -type manhattan_relative_importance".format(GenNet_path) )
99+
assert test1 == 0
89100

101+
90102
class TestTrain():
91103
def test_train_classification(self):
92-
remove_old_test(999999999)
104+
remove_old(999999999)
93105
GenNet_path = get_GenNet_path()
94106
value = os.system('python {}/GenNet.py train -path {}/examples/example_classification/ -ID 999999999 -epochs 2'.format(GenNet_path, GenNet_path) )
95107
assert value == 0
96108

97109
def test_train_regression(self):
98-
remove_old_test(999999998)
110+
remove_old(999999998)
99111
GenNet_path = get_GenNet_path()
100112
value = os.system('python {}/GenNet.py train -path {}/examples/example_regression/ -ID 999999998 -problem_type regression -epochs 2'.format(GenNet_path, GenNet_path) )
101113
assert value == 0
@@ -127,8 +139,5 @@ def test_plot_layer_weight_2(self, ID):
127139
plot_layer_weight(resultpath, importance_csv, layer=1)
128140

129141

130-
# @pytest.mark.parametrize("ID", [999999999, 999999998]) # test both regression and classification
131-
# class CheckAllFiles():
132-
# def trainin_files(self, ID):
133142

134143

0 commit comments

Comments
 (0)