Skip to content

Commit 0c8f77c

Browse files
authored
Fixed reads given multiple lanes (#114)
* Fixed reads given multiple lanes * Refactored code * Added tests
1 parent cbd0a3a commit 0c8f77c

File tree

2 files changed

+52
-18
lines changed

2 files changed

+52
-18
lines changed

checkQC/handlers/q30_handler.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,25 @@ def collect(self, signal):
2727
self.error_results.append(value)
2828

2929
def check_qc(self):
30+
lane_no = 0
3031

31-
index_count = 0
32-
non_index_count = 0
3332
for error_dict in self.error_results:
3433
lane_nbr = int(error_dict["lane"])
34+
35+
# restart counters for different lanes
36+
if lane_nbr != lane_no:
37+
index_count = 0
38+
non_index_count = 0
39+
lane_no = lane_nbr
40+
3541
percent_q30 = error_dict["percent_q30"]
3642
is_index_read = error_dict.get("is_index_read", False)
3743
read_or_index_text = "index read" if is_index_read else "read"
3844
# Differentiate read values for indexed from non-indexed reads
3945
index_count += 1 if is_index_read else 0
4046
non_index_count += 1 if not is_index_read else 0
41-
4247
read = index_count if is_index_read else non_index_count
43-
48+
4449
if self.error() != self.UNKNOWN and percent_q30 < self.error():
4550
yield QCErrorFatal(
4651
"%Q30 {:.2f} was too low on lane: {} for {}: {}".format(

tests/handlers/test_q30_handler.py

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,43 +9,72 @@ class TestQ30Handler(HandlerTestBase):
99

1010
def setUp(self):
1111
key = "percent_q30"
12-
qc_config = {'name': 'Q30Handler', 'error': 70, 'warning': 80}
12+
qc_config = {"name": "Q30Handler", "error": 70, "warning": 80}
1313
value_1 = {"lane": 1, "read": 1, "percent_q30": 82}
14-
value_2 = {"lane": 1, "read": 2, "percent_q30": 90}
15-
value_3 = {"lane": 1, "read": 3, "percent_q30": 50, "is_index_read": True}
14+
value_2 = {"lane": 1, "read": 2, "percent_q30": 50, "is_index_read": True}
15+
value_3 = {"lane": 1, "read": 3, "percent_q30": 50, "is_index_read": True}
16+
value_4 = {"lane": 1, "read": 4, "percent_q30": 60}
17+
value_5 = {"lane": 2, "read": 1, "percent_q30": 90}
18+
value_6 = {"lane": 2, "read": 2, "percent_q30": 50, "is_index_read": True}
19+
value_7 = {"lane": 2, "read": 3, "percent_q30": 50}
20+
value_8 = {"lane": 2, "read": 4, "percent_q30": 40}
1621
q30_handler = Q30Handler(qc_config)
1722
q30_handler.collect((key, value_1))
1823
q30_handler.collect((key, value_2))
1924
q30_handler.collect((key, value_3))
25+
q30_handler.collect((key, value_4))
26+
q30_handler.collect((key, value_5))
27+
q30_handler.collect((key, value_6))
28+
q30_handler.collect((key, value_7))
29+
q30_handler.collect((key, value_8))
2030
self.q30_handler = q30_handler
2131

2232
def set_qc_config(self, qc_config):
2333
self.q30_handler.qc_config = qc_config
2434

2535
def test_all_is_fine(self):
26-
qc_config = {'name': 'Q30Handler', 'error': 70, 'warning': 80}
36+
qc_config = {"name": "Q30Handler", "error": 20, "warning": 30}
2737
self.set_qc_config(qc_config)
2838
errors_and_warnings = list(self.q30_handler.check_qc())
29-
self.assertIn("index read", f"{errors_and_warnings}")
30-
self.assertEqual(f"{errors_and_warnings}", "[Fatal QC error: %Q30 50.00 was too low on lane: 1 for index read: 1]")
39+
self.assertEqual(errors_and_warnings, [])
3140

3241
def test_warning(self):
33-
qc_config = {'name': 'Q30Handler', 'error': 70, 'warning': 85}
42+
qc_config = {"name": "Q30Handler", "error": 40, "warning": 60}
3443
self.set_qc_config(qc_config)
3544
errors_and_warnings = list(self.q30_handler.check_qc())
36-
self.assertEqual(len(errors_and_warnings), 2)
45+
self.assertEqual(len(errors_and_warnings), 5)
3746

3847
class_names = self.map_errors_and_warnings_to_class_names(errors_and_warnings)
39-
self.assertListEqual(class_names, ['QCErrorWarning', 'QCErrorFatal'])
48+
self.assertListEqual(
49+
class_names,
50+
["QCErrorWarning", "QCErrorWarning", "QCErrorWarning", "QCErrorWarning", "QCErrorWarning"],
51+
)
4052

4153
def test_error(self):
42-
qc_config = {'name': 'Q30Handler', 'error': 95, 'warning': 98}
54+
qc_config = {"name": "Q30Handler", "error": 95, "warning": 98}
4355
self.set_qc_config(qc_config)
4456
errors_and_warnings = list(self.q30_handler.check_qc())
45-
self.assertEqual(len(errors_and_warnings), 3)
57+
self.assertEqual(len(errors_and_warnings), 8)
58+
59+
self.assertEqual(
60+
str(errors_and_warnings),
61+
str("[Fatal QC error: %Q30 82.00 was too low on lane: 1 for read: 1, Fatal QC error: %Q30 50.00 was too low on lane: 1 for index read: 1, Fatal QC error: %Q30 50.00 was too low on lane: 1 for index read: 2, Fatal QC error: %Q30 60.00 was too low on lane: 1 for read: 2, Fatal QC error: %Q30 90.00 was too low on lane: 2 for read: 1, Fatal QC error: %Q30 50.00 was too low on lane: 2 for index read: 1, Fatal QC error: %Q30 50.00 was too low on lane: 2 for read: 2, Fatal QC error: %Q30 40.00 was too low on lane: 2 for read: 3]")
62+
)
63+
64+
def test_max_read(self):
65+
qc_config = {"name": "Q30Handler", "error": 99, "warning": 99}
66+
self.set_qc_config(qc_config)
67+
errors_and_warnings = list(self.q30_handler.check_qc())
68+
self.assertEqual(len(errors_and_warnings), 8)
69+
70+
[
71+
self.assertLessEqual(
72+
int(str(read).split("read: ")[1]), 4
73+
)
74+
for read in errors_and_warnings
75+
]
76+
4677

47-
class_names = self.map_errors_and_warnings_to_class_names(errors_and_warnings)
48-
self.assertListEqual(class_names, ['QCErrorFatal', 'QCErrorFatal', 'QCErrorFatal'])
4978

50-
if __name__ == '__main__':
79+
if __name__ == "__main__":
5180
unittest.main()

0 commit comments

Comments
 (0)