Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop functional tests for alt_allele_prob_file and est_alt_allele_prob with multiple metafounders #156

Merged

Large diffs are not rendered by default.

1,000 changes: 1,000 additions & 0 deletions tests/accuracy_tests/sim_for_alphapeel_accu_test/MF_cross_ped_file.txt

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,000 changes: 1,000 additions & 0 deletions tests/accuracy_tests/sim_for_alphapeel_accu_test/MF_multi_sep_geno_file.txt

Large diffs are not rendered by default.

1,000 changes: 1,000 additions & 0 deletions tests/accuracy_tests/sim_for_alphapeel_accu_test/MF_multi_sep_ped_file.txt

Large diffs are not rendered by default.

2,000 changes: 2,000 additions & 0 deletions tests/accuracy_tests/sim_for_alphapeel_accu_test/MF_multi_sep_seq_file.txt

Large diffs are not rendered by default.

691 changes: 690 additions & 1 deletion tests/accuracy_tests/sim_for_alphapeel_accu_test/sim_for_accu.R
gregorgorjanc marked this conversation as resolved.
Show resolved Hide resolved

Large diffs are not rendered by default.

1,000 changes: 1,000 additions & 0 deletions tests/accuracy_tests/sim_for_alphapeel_accu_test/single_MF_ped_file.txt

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,000 changes: 1,000 additions & 0 deletions tests/accuracy_tests/sim_for_alphapeel_accu_test/true-MF_multi_sep_dosage.txt

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2,000 changes: 2,000 additions & 0 deletions tests/accuracy_tests/sim_for_alphapeel_accu_test/true-MF_multi_sep_hap_0.5.txt

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2,000 changes: 2,000 additions & 0 deletions tests/accuracy_tests/sim_for_alphapeel_accu_test/true-MF_multi_sep_rec_prob.txt

Large diffs are not rendered by default.

4,000 changes: 4,000 additions & 0 deletions tests/accuracy_tests/sim_for_alphapeel_accu_test/true-MF_multi_sep_seg_prob.txt

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

261 changes: 252 additions & 9 deletions tests/functional_tests/run_func_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import shutil
import subprocess


def read_file(file_path, **kwargs):
Expand Down Expand Up @@ -180,6 +181,8 @@ def test_files(self):
self.output = read_and_sort_file(self.output_file_path)
self.expected = read_and_sort_file(self.expected_file_path)

# Produced dosage file correctly where multiple different files are inputted of unrelated individuals:
# Geno_file, hap_file, ped_file, penetrance, and seq_file
assert self.output == self.expected

def test_subset(self):
Expand Down Expand Up @@ -215,9 +218,10 @@ def test_subset(self):

self.output = read_and_sort_file(self.output_file_path)
self.expected = read_and_sort_file(self.expected_file_path)

# Remove the first and last column inline with start_snp (2) and stop_snp (4) command
delete_columns(self.expected, [2, 6])

# Test start_snp and stop_snp commands across different input files
# Compares the outputted genotype dosage file with the expected genotype dosage.
assert self.output == self.expected

def test_out_id_order(self):
Expand Down Expand Up @@ -260,8 +264,9 @@ def test_out_id_order(self):
)

self.output = read_file(self.output_file_path)

# Total four individuals across the five inputted files
assert len(self.output) == 4
# Check the outputted order under different commands: id, pedigree, genotypes, sequence.
assert self.output[0][0] == answer[self.test_cases]

self.command = "AlphaPeel "
Expand All @@ -279,8 +284,9 @@ def test_out_id_order(self):
)

self.output = read_file(self.output_file_path)

# one observation as one individual in seq file
assert len(self.output) == 1
# First ID equal to "seq" (id used in sequence file)
assert self.output[0][0] == "seq"

def test_est(self):
Expand Down Expand Up @@ -324,7 +330,7 @@ def test_est(self):

self.output = read_and_sort_file(self.output_file_path)
self.expected = read_and_sort_file(self.expected_file_path)

# Checking AlphaPeel runs so compares outputted genotypes, haplotypes, seq, and penetrance with expected.
assert self.output == self.expected

self.arguments.pop(self.test_cases)
Expand Down Expand Up @@ -361,7 +367,11 @@ def test_no(self):

self.generate_command()
os.system(self.command)

# When requested through commands, test the presents of file outputs:
# no_dosage, output files: alt_allele_prob, geno_error_prob, seg_error_prob
# seg_prob, output files: dosage, seg_prob, alt_allele_prob, geno_error_prob, seg_error_prob
# no_param, output file: dosage
# phased_geno_prob, output files: dosage, alt_allele_prob, geno_error_prob, seg_error_prob, phased_geno_prob
assert self.check_files() == expect[self.test_cases]

self.arguments.pop(self.test_cases)
Expand Down Expand Up @@ -420,7 +430,7 @@ def test_rec(self):
else:
self.output = read_and_sort_file(self.output_file_path)
self.expected = read_and_sort_file(self.expected_file_path)

# Check outputted dosage, phased, and seg to expected files
assert self.output == self.expected

self.input_files.pop(-1)
Expand Down Expand Up @@ -464,7 +474,7 @@ def test_sex(self):

self.output = read_and_sort_file(self.output_file_path)
self.expected = read_and_sort_file(self.expected_file_path)

#Compares outputted seg_prob files to expected.
assert self.output == self.expected
self.command = "AlphaPeel "

Expand Down Expand Up @@ -533,12 +543,245 @@ def test_out_id_only(self):

self.output = read_file(self.output_file_path)

# no dummy individuals output
# Number of observations in dosage file is 6 as no dummy individuals in output.
assert len(self.output) == 6

for ind in self.output:
assert "MotherOf" not in ind[0] and "FatherOf" not in ind[0]

def test_alt_allele_prob(self):
"""
Run the test for alt_allele_prob and est_alt_allele_prob with multiple metafounders
"""
self.test_name = "test_alt_allele_prob"
self.prepare_path()

self.input_files = ["geno_file", "ped_file"]
self.input_file_depend_on_test_cases = self.input_files
self.arguments = {"method": "multi", "out_id_only": None}

for self.test_cases in [
"default",
"alt_allele_prob_file_single",
"alt_allele_prob_file_multiple",
"est_alt_allele_prob_single",
"est_alt_allele_prob_multiple",
"both",
"incorrect_pedigree",
"default_metafounder",
"main_metafounder",
]:
# test case default: Test the default values of the alternative allele frequency
# without any input or estimation with multiple metafounders
# alt_allele_prob_file_single: Test the input option alt_allele_prob_file
# for a single metafounder
# alt_allele_prob_file_multiple: Test the input option alt_allele_prob_file
# for multiple metafounders
# est_alt_allele_prob_single: Test the option est_alt_allele_prob
# for a single metafounder
# est_alt_allele_prob_multiple: Test the option est_alt_allele_prob
# for multiple metafounders
# both: Test the case when both options are used,
# whether the inputted alternative allele probabilities are used as
# a starting point for alternative allele probabilities estimation
# incorrect_pedigree: Test case when a metafounder is written incorrectly as
# not a founder in the pedigree file
# default_metafounder: Test case when 0 is being used as parents and
# no main metafounder is being provided as input,
# test whether 0 would be replaced by the default MF_1
# main_metafounder: Test if the input option main_metafounder is working
# i.e the user defines the default metafounder where 0 is used.
# incorrect_main_metafounder: Test case when the input main_metafounder does not start with MF_,
# whether an error would be raised
# incorrect_metafounder_in_file: Test case when the names of input metafounders
# in the input alternative allele probability file do not start with MF_,
# whether an error would be raised

self.output_file_prefix = f"alt_allele_prob.{self.test_cases}"

if self.test_cases == "default":
self.output_file_to_check = "alt_allele_prob"
self.generate_command()
os.system(self.command)

self.output_file_path = os.path.join(
self.output_path,
f"{self.output_file_prefix}.{self.output_file_to_check}.txt",
)
self.expected_file_path = os.path.join(
self.path, f"true-{self.output_file_to_check}-{self.test_cases}.txt"
)

self.output = read_and_sort_file(self.output_file_path, decimal_place=1)
self.expected = read_and_sort_file(
self.expected_file_path, decimal_place=1
)
# Each metafounder has alt_allele_prob of 0.5 per marker
assert self.output == self.expected

elif self.test_cases == "alt_allele_prob_file_single":
self.input_files.append("alt_allele_prob_file")
self.input_file_depend_on_test_cases.append("alt_allele_prob_file")

self.output_file_to_check = "dosage"

self.generate_command()
os.system(self.command)

self.output_file_path = os.path.join(
self.output_path,
f"{self.output_file_prefix}.{self.output_file_to_check}.txt",
)
self.expected_file_path = os.path.join(
self.path, f"true-{self.output_file_to_check}-{self.test_cases}.txt"
)

self.output = read_and_sort_file(self.output_file_path)
self.expected = read_and_sort_file(self.expected_file_path)
# Compares the outputted dosage file to the expected based on inputted alt_allele_prob file.
assert self.output == self.expected

elif self.test_cases == "alt_allele_prob_file_multiple":
self.generate_command()
os.system(self.command)

self.output_file_path = os.path.join(
self.output_path,
f"{self.output_file_prefix}.{self.output_file_to_check}.txt",
)
self.expected_file_path = os.path.join(
self.path, f"true-{self.output_file_to_check}-{self.test_cases}.txt"
)

self.output = read_and_sort_file(self.output_file_path)
self.expected = read_and_sort_file(self.expected_file_path)
# Compares the outputted dosage file to the expected based on inputted alt_allele_prob file.
assert self.output == self.expected

self.input_files.pop(-1)
self.input_file_depend_on_test_cases.pop(-1)

elif self.test_cases == "est_alt_allele_prob_single":
self.arguments["est_alt_allele_prob"] = None
self.output_file_to_check = "alt_allele_prob"

self.generate_command()
os.system(self.command)

self.output_file_path = os.path.join(
self.output_path,
f"{self.output_file_prefix}.{self.output_file_to_check}.txt",
)
self.expected_file_path = os.path.join(
self.path, f"true-{self.output_file_to_check}-{self.test_cases}.txt"
)

self.output = read_and_sort_file(self.output_file_path)
self.expected = read_and_sort_file(self.expected_file_path)
# Compares alt_allele_prob output with expected when estimated by AlphaPeel for one metafounder
assert self.output == self.expected

elif self.test_cases == "est_alt_allele_prob_multiple":
self.generate_command()
os.system(self.command)

self.output_file_path = os.path.join(
self.output_path,
f"{self.output_file_prefix}.{self.output_file_to_check}.txt",
)
self.expected_file_path = os.path.join(
self.path, f"true-{self.output_file_to_check}-{self.test_cases}.txt"
)

self.output = read_and_sort_file(self.output_file_path)
self.expected = read_and_sort_file(self.expected_file_path)
# Compares alt_allele_prob output with expected when estimated by AlphaPeel for multiple metafounders
assert self.output == self.expected

elif self.test_cases == "both":
self.input_files.append("alt_allele_prob_file")
self.input_file_depend_on_test_cases("alt_allele_prob_file")

self.generate_command()
os.system(self.command)

self.output_file_path = os.path.join(
self.output_path,
f"{self.output_file_prefix}.{self.output_file_to_check}.txt",
)

self.output = read_and_sort_file(self.output_file_path)

# check if the estimated alt_allele_prob is in between 0.5 and 1 (include 0.5 and exclude 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@XingerTang I have not looked at the input files, but is this what we expect for the input files - that alt allele prob will be [0.5, 1]?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gregorgorjanc It is specific to the test case and the test input data I designed. In general, the input values for alt allele prob should in [0, 1].

assert all(map(lambda prob: 1 > prob >= 0.5, self.output[1:]))

self.arguments.pop("est_alt_allele_prob")

elif self.test_cases == "incorrect_pedigree":
self.generate_command()
stdout = subprocess.check_output(self.command, shell=True)

# check if error message is in the output
assert "" in stdout

self.input_files.pop(-1)
self.input_file_depend_on_test_cases(-1)

elif self.test_cases == "default_metafounder":
self.generate_command()
os.system(self.command)

self.output_file_path = os.path.join(
self.output_path,
f"{self.output_file_prefix}.{self.output_file_to_check}.txt",
)

self.output = read_and_sort_file(self.output_file_path)

# check if there is only one metafounder
assert len(self.output) == 1
# check if the name of the metafounder is MF_1
assert self.output[0][0] == "MF_1"

elif self.test_cases == "main_metafounder":
self.arguments["main_metafounder"] = "MF_test"
self.generate_command()
os.system(self.command)

self.output_file_path = os.path.join(
self.output_path,
f"{self.output_file_prefix}.{self.output_file_to_check}.txt",
)

self.output = read_and_sort_file(self.output_file_path)

# check if there is only one metafounder
assert len(self.output) == 1
# check if the name of the metafounder is MF_test
assert self.output[0][0] == "MF_test"

elif self.test_cases == "incorrect_main_metafounder":
self.arguments["main_metafounder"] = "test"
self.generate_command()
stdout = subprocess.check_output(self.command, shell=True)

# check if error message is in the output
assert "" in stdout

self.arguments.pop("main_metafounder")

elif self.test_cases == "incorrect_metafounder_in_file":
self.input_files.append("alt_allele_prob_file")
self.input_file_depend_on_test_cases.append("alt_allele_prob_file")

self.generate_command()
stdout = subprocess.check_output(self.command, shell=True)

# check if error message is in the output
assert "" in stdout

self.command = "AlphaPeel "

# TODO test_plink for PLINK
# a. binary PLINK output
# b. binary output + input
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MF_1 0 0 0 0 0
MF_2 1 1 1 1 1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MF_1 0 0 0 0 0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MF_1 0 0 0 0 0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test 0 0 0 0 0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MF_1 0.5 0.5 0.5 0.5 0.5
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
M0 9 9 9 9 9
F0 9 9 9 9 9
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
M0 9 9 9 9 9
F0 9 9 9 9 9
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
M0 1 1 1 1 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
M0 0 1 0 2 1
F0 2 0 1 2 0
M1 1 0 0 2 1
F1 1 1 1 2 0
M2 0 1 1 2 0
F2 2 0 0 2 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
M0 0 0 0 0 0
F0 1 1 1 1 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
M0 0 0 0 0 0
F0 2 2 2 2 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
M0 0 0 0 0 0
F0 0 0 0 0 0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
M0 0 0 0 0 0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
M0 0 0 0 0 0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
M0 1 1 1 1 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
M0 0 0 0 0 0
F0 0 0 0 0 0
Loading
Loading