From 46410163ca402660434b09a8fc8ec7b12b89d8a1 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Wed, 27 Dec 2023 08:08:31 +0300 Subject: Tests: Add tests for parsing gmap files. --- pytest.ini | 3 +- r_qtl/r_qtl2.py | 31 +++++++++------- tests/r_qtl/test_files/test_gmap.zip | Bin 0 -> 542 bytes tests/r_qtl/test_files/test_gmap_transposed.zip | Bin 0 -> 594 bytes tests/r_qtl/test_r_qtl2.py | 47 ++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 tests/r_qtl/test_files/test_gmap.zip create mode 100644 tests/r_qtl/test_files/test_gmap_transposed.zip create mode 100644 tests/r_qtl/test_r_qtl2.py diff --git a/pytest.ini b/pytest.ini index 9fd309c..99e2c59 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,4 +1,5 @@ [pytest] addopts = --strict-markers markers = - slow \ No newline at end of file + slow + unit_test \ No newline at end of file diff --git a/r_qtl/r_qtl2.py b/r_qtl/r_qtl2.py index 26d6dd4..a221f26 100644 --- a/r_qtl/r_qtl2.py +++ b/r_qtl/r_qtl2.py @@ -65,20 +65,27 @@ def genotype_data(zfile: ZipFile, cdata: dict) -> Iterator[dict]: def map_data(zfile: ZipFile, map_type: str, cdata: dict) -> dict: """Read gmap files to get the genome mapping data""" assert map_type in ("genetic-map", "physical-map"), "Invalid map type" - map_key = {"genetic-map": "gmap", "physical-map": "pmap"}[map_type] - if not cdata.get("geno_transposed", False): - with zfile.open(cdata[map_key]) as gmapfile: + map_file = cdata[{ + "genetic-map": "gmap", + "physical-map": "pmap" + }[map_type]] + # TODO: Might need to check `gmap_transposed` and `pmap_transposed` instead + # of `geno_transposed` -- see + # https://github.com/rqtl/qtl2data/blob/main/ArabMAGIC/arabmagic_tair8.json + # for the *_transposed values + transposed_dict = { + "genetic-map": "gmap_transposed", + "physical-map": "pmap_transposed" + } + if not cdata.get(transposed_dict[map_type], False): + with zfile.open(map_file) as gmapfile: reader = csv.DictReader( filter(lambda line: not line.startswith("#"), io.TextIOWrapper(gmapfile)), delimiter=cdata.get("sep", ",")) - return { - line["marker"]: { - key: value for key,value in line.items() if key != "marker" - } for line in reader - } + return tuple(row for row in reader) - with zfile.open(cdata["gmap"]) as gmapfile: + with zfile.open(map_file) as gmapfile: lines = [[field.strip() for field in line.strip().split(cdata.get("sep", ","))] for line in @@ -87,11 +94,9 @@ def map_data(zfile: ZipFile, map_type: str, cdata: dict) -> dict: headers = tuple(line[0] for line in lines) return reduce( - lambda gmap, row: { - **gmap, - row[0]: dict(zip(headers[1:], row[1:]))}, + lambda gmap, row: gmap + (dict(zip(headers, row)),), zip(*(line[1:] for line in lines)), - {}) + tuple()) def read_r_qtl2_files(filepath: Path): """Read R/qtl2 format zip files.""" diff --git a/tests/r_qtl/test_files/test_gmap.zip b/tests/r_qtl/test_files/test_gmap.zip new file mode 100644 index 0000000..c8d452a Binary files /dev/null and b/tests/r_qtl/test_files/test_gmap.zip differ diff --git a/tests/r_qtl/test_files/test_gmap_transposed.zip b/tests/r_qtl/test_files/test_gmap_transposed.zip new file mode 100644 index 0000000..74a956e Binary files /dev/null and b/tests/r_qtl/test_files/test_gmap_transposed.zip differ diff --git a/tests/r_qtl/test_r_qtl2.py b/tests/r_qtl/test_r_qtl2.py new file mode 100644 index 0000000..a72b300 --- /dev/null +++ b/tests/r_qtl/test_r_qtl2.py @@ -0,0 +1,47 @@ +"""Test the parsing of the R/qtl2 data files.""" +from pathlib import Path + +import pytest +from zipfile import ZipFile + +from r_qtl import r_qtl2 as rqtl2 + +@pytest.mark.unit_test +@pytest.mark.parametrize( + "relpath,expected", + (("tests/r_qtl/test_files/test_gmap.zip", + ({"marker": "PVV4", "chr": "1", "pos": "0.000000"}, + {"marker": "AXR-1", "chr": "1", "pos": "6.250674"}, + {"marker": "HH.335C-Col/PhyA", "chr": "1", "pos": "9.303868"}, + {"marker": "EC.480C", "chr": "1", "pos": "12.577629"}, + {"marker": "EC.66C", "chr": "1", "pos": "18.392830"})), + ("tests/r_qtl/test_files/test_gmap_transposed.zip", + ({"marker": "PVV4", "chr": "1", "pos": "0.000000"}, + {"marker": "AXR-1", "chr": "1", "pos": "6.250674"}, + {"marker": "HH.335C-Col/PhyA", "chr": "1", "pos": "9.303868"}, + {"marker": "EC.480C", "chr": "1", "pos": "12.577629"}, + {"marker": "EC.66C", "chr": "1", "pos": "18.392830"})))) +def test_parse_gmap_files(relpath, expected): + """ + GIVEN: A path to a zip file, `relpath` + WHEN: we parse a gmap file + THEN: ensure the parsed data is as expected. + """ + with ZipFile(Path(relpath).absolute(), "r") as zfile: + assert rqtl2.map_data( + zfile, "genetic-map", rqtl2.control_data(zfile)) == expected + +@pytest.mark.skip(reason="Test not implemented yet.") +@pytest.mark.unit_test +@pytest.mark.parametrize( + "relpath,expected", + (("tests/r_qtl/test_files/test_pmap.zip", + ()), + ("tests/r_qtl/test_files/test_pmap_transposed.zip", + ()))) +def test_parse_pmap_files(relpath, expected): + """ + GIVEN: A path to a zip file, `relpath` + WHEN: we parse a pmap file + THEN: ensure the parsed data is as expected. + """ -- cgit v1.2.3