annotate COBRAxy/test_gpr_translation_comprehensive.py @ 501:9bfd1ec3ae6f draft

Uploaded
author francesco_lapi
date Tue, 30 Sep 2025 17:06:37 +0000
parents a92d21f92956
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
493
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
1 #!/usr/bin/env python3
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
2 """
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
3 Comprehensive test suite for GPR translation functionality in COBRAxy.
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
4
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
5 This test suite covers:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
6 - Basic 1:1, 1:many, many:1 gene mappings
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
7 - Complex GPR expressions with AND/OR logic
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
8 - Translation issues tracking
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
9 - OR-only GPR flattening functionality
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
10 - Edge cases and nested expressions
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
11 - Statistical reporting
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
12 """
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
13
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
14 import cobra
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
15 import pandas as pd
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
16 import sys
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
17 import os
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
18 import logging
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
19 from typing import Dict, List, Tuple
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
20 import re
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
21
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
22 # Add the COBRAxy utils directory to the path
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
23 sys.path.append('/hdd/home/flapi/COBRAxy')
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
24 from utils import model_utils
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
25
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
26 # Configure logging
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
27 logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
28 logger = logging.getLogger(__name__)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
29
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
30 class GPRTranslationTester:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
31 """Comprehensive GPR translation test suite"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
32
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
33 def __init__(self):
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
34 self.test_results = {}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
35 self.failed_tests = []
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
36
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
37 def create_comprehensive_test_model(self) -> cobra.Model:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
38 """Create a comprehensive test model with diverse GPR patterns"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
39 model = cobra.Model('comprehensive_test_model')
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
40
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
41 # Create metabolites
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
42 metabolites = []
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
43 for i in range(30):
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
44 met = cobra.Metabolite(f'met_{chr(65+i%26)}{i//26}', compartment='c')
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
45 metabolites.append(met)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
46
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
47 reactions_data = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
48 # === BASIC CASES ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
49 ('BASIC_1to1', 'GENE1', 0, 1), # Simple 1:1 mapping
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
50 ('BASIC_1tomany', 'GENE2', 1, 2), # 1:many mapping
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
51 ('BASIC_manyto1', 'GENE3', 2, 3), # many:1 mapping
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
52 ('BASIC_unmapped', 'UNMAPPED_GENE', 3, 4), # unmapped gene
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
53
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
54 # === SIMPLE OR CASES (candidates for flattening) ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
55 ('OR_simple', 'GENE4 or GENE5', 4, 5), # Simple OR with many:1
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
56 ('OR_three', 'GENE6 or GENE7 or GENE8', 5, 6), # Three genes OR
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
57 ('OR_parentheses', '(GENE9 or GENE10)', 6, 7), # OR with parentheses
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
58 ('OR_duplicates', 'GENE11 or GENE12 or GENE11', 7, 8), # OR with duplicates after translation
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
59
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
60 # === COMPLEX OR CASES (candidates for flattening) ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
61 ('OR_nested_simple', '(GENE13 or GENE14) or (GENE15 or GENE16)', 8, 9), # Nested OR only
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
62 ('OR_many_parentheses', '((GENE17 or GENE18) or GENE19) or GENE20', 9, 10), # Multiple nesting levels
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
63 ('OR_mixed_mapping', 'GENE21 or GENE22 or GENE23', 10, 11), # Mixed 1:1, 1:many, many:1
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
64
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
65 # === AND CASES (should NOT be flattened) ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
66 ('AND_simple', 'GENE24 and GENE25', 11, 12), # Simple AND
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
67 ('AND_complex', '(GENE26 and GENE27) and GENE28', 12, 13), # Complex AND
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
68
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
69 # === MIXED AND/OR (should NOT be flattened) ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
70 ('MIXED_basic', 'GENE29 and (GENE30 or GENE31)', 13, 14), # AND with OR
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
71 ('MIXED_complex', '(GENE32 or GENE33) and (GENE34 or GENE35)', 14, 15), # OR and AND
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
72 ('MIXED_nested', '((GENE36 and GENE37) or GENE38) and GENE39', 15, 16), # Complex nesting
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
73
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
74 # === EDGE CASES ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
75 ('EDGE_single', 'GENE40', 16, 17), # Single gene
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
76 ('EDGE_empty', '', 17, 18), # Empty GPR
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
77 ('EDGE_whitespace', ' GENE41 or GENE42 ', 18, 19), # Whitespace
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
78 ('EDGE_case_sensitive', 'Gene43 OR gene44', 19, 20), # Case variations
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
79
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
80 # === STRESS TESTS ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
81 ('STRESS_long_or', 'GENE45 or GENE46 or GENE47 or GENE48 or GENE49 or GENE50', 20, 21), # Long OR chain
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
82 ('STRESS_deep_nest', '(((GENE51 or GENE52) or GENE53) or GENE54)', 21, 22), # Deep nesting
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
83 ('STRESS_complex', '(GENE55 or (GENE56 or GENE57)) or ((GENE58 or GENE59) or GENE60)', 22, 23), # Complex structure
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
84
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
85 # === TRANSLATION ISSUE TRIGGERS ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
86 ('ISSUE_1many_or', 'GENE61 or GENE62', 23, 24), # 1:many in OR (should be flattened)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
87 ('ISSUE_manyto1_and', 'GENE63 and GENE64', 24, 25), # many:1 in AND (should NOT be flattened)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
88 ('ISSUE_mixed_problems', '(GENE65 or GENE66) and GENE67', 25, 26), # Mixed problems
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
89
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
90 # === REAL-WORLD INSPIRED CASES ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
91 ('REAL_metabolism', '(ENSG001 or ENSG002) or (ENSG003 or ENSG004)', 26, 27), # Metabolic pathway
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
92 ('REAL_transport', 'TRANSPORTER1 and (COFACTOR1 or COFACTOR2)', 27, 28), # Transport reaction
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
93 ('REAL_complex_enzyme', '((SUBUNIT1 and SUBUNIT2) or SUBUNIT3) and COFACTOR3', 28, 29), # Complex enzyme
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
94 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
95
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
96 # Create reactions
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
97 for rxn_id, gpr, met_in, met_out in reactions_data:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
98 rxn = cobra.Reaction(rxn_id)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
99 if met_in < len(metabolites) and met_out < len(metabolites):
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
100 rxn.add_metabolites({metabolites[met_in]: -1, metabolites[met_out]: 1})
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
101 rxn.gene_reaction_rule = gpr
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
102 model.add_reactions([rxn])
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
103
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
104 return model
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
105
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
106 def create_comprehensive_mapping(self) -> pd.DataFrame:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
107 """Create a comprehensive gene mapping covering all test scenarios"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
108 mapping_data = {
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
109 'hgnc_symbol': [],
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
110 'ensg': []
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
111 }
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
112
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
113 # === BASIC MAPPINGS ===
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
114 # 1:1 mappings
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
115 one_to_one = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
116 ('GENE1', 'TARGET1'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
117 ('GENE24', 'TARGET24'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
118 ('GENE25', 'TARGET25'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
119 ('GENE26', 'TARGET26'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
120 ('GENE27', 'TARGET27'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
121 ('GENE28', 'TARGET28'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
122 ('GENE29', 'TARGET29'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
123 ('GENE40', 'TARGET40'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
124 ('GENE41', 'TARGET41'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
125 ('GENE42', 'TARGET42'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
126 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
127
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
128 # 1:many mappings (one source gene maps to multiple targets)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
129 one_to_many = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
130 ('GENE2', 'TARGET2A'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
131 ('GENE2', 'TARGET2B'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
132 ('GENE30', 'TARGET30A'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
133 ('GENE30', 'TARGET30B'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
134 ('GENE61', 'TARGET61A'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
135 ('GENE61', 'TARGET61B'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
136 ('GENE61', 'TARGET61C'), # Maps to 3 targets
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
137 ('GENE65', 'TARGET65A'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
138 ('GENE65', 'TARGET65B'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
139 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
140
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
141 # many:1 mappings (multiple source genes map to one target)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
142 many_to_one = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
143 ('GENE3', 'SHARED_TARGET1'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
144 ('GENE4', 'SHARED_TARGET1'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
145 ('GENE5', 'SHARED_TARGET1'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
146 ('GENE6', 'SHARED_TARGET2'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
147 ('GENE7', 'SHARED_TARGET2'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
148 ('GENE8', 'SHARED_TARGET2'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
149 ('GENE9', 'SHARED_TARGET3'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
150 ('GENE10', 'SHARED_TARGET3'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
151 ('GENE11', 'SHARED_TARGET4'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
152 ('GENE12', 'SHARED_TARGET4'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
153 ('GENE13', 'SHARED_TARGET5'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
154 ('GENE14', 'SHARED_TARGET5'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
155 ('GENE15', 'SHARED_TARGET5'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
156 ('GENE16', 'SHARED_TARGET5'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
157 ('GENE17', 'SHARED_TARGET6'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
158 ('GENE18', 'SHARED_TARGET6'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
159 ('GENE19', 'SHARED_TARGET6'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
160 ('GENE20', 'SHARED_TARGET6'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
161 ('GENE45', 'SHARED_TARGET7'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
162 ('GENE46', 'SHARED_TARGET7'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
163 ('GENE47', 'SHARED_TARGET7'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
164 ('GENE48', 'SHARED_TARGET7'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
165 ('GENE49', 'SHARED_TARGET7'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
166 ('GENE50', 'SHARED_TARGET7'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
167 ('GENE51', 'SHARED_TARGET8'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
168 ('GENE52', 'SHARED_TARGET8'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
169 ('GENE53', 'SHARED_TARGET8'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
170 ('GENE54', 'SHARED_TARGET8'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
171 ('GENE55', 'SHARED_TARGET9'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
172 ('GENE56', 'SHARED_TARGET9'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
173 ('GENE57', 'SHARED_TARGET9'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
174 ('GENE58', 'SHARED_TARGET9'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
175 ('GENE59', 'SHARED_TARGET9'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
176 ('GENE60', 'SHARED_TARGET9'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
177 ('GENE63', 'SHARED_TARGET10'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
178 ('GENE64', 'SHARED_TARGET10'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
179 ('GENE66', 'SHARED_TARGET11'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
180 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
181
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
182 # Mixed mappings for complex cases
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
183 mixed_mappings = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
184 ('GENE21', 'TARGET21'), # 1:1
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
185 ('GENE22', 'TARGET22A'), # 1:many
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
186 ('GENE22', 'TARGET22B'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
187 ('GENE23', 'SHARED_TARGET1'), # many:1 (shares with GENE3-5)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
188 ('GENE31', 'SHARED_TARGET12'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
189 ('GENE32', 'SHARED_TARGET13'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
190 ('GENE33', 'SHARED_TARGET13'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
191 ('GENE34', 'TARGET34'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
192 ('GENE35', 'TARGET35'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
193 ('GENE36', 'TARGET36'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
194 ('GENE37', 'TARGET37'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
195 ('GENE38', 'TARGET38'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
196 ('GENE39', 'TARGET39'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
197 ('GENE62', 'TARGET62A'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
198 ('GENE62', 'TARGET62B'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
199 ('GENE67', 'TARGET67'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
200 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
201
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
202 # Case sensitivity tests
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
203 case_mappings = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
204 ('Gene43', 'TARGET43'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
205 ('gene44', 'TARGET44'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
206 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
207
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
208 # Real-world inspired mappings
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
209 real_mappings = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
210 ('ENSG001', 'HUMAN_GENE1'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
211 ('ENSG002', 'HUMAN_GENE2'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
212 ('ENSG003', 'HUMAN_GENE1'), # many:1
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
213 ('ENSG004', 'HUMAN_GENE2'), # many:1
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
214 ('TRANSPORTER1', 'SLC_FAMILY1'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
215 ('COFACTOR1', 'COFACTOR_A'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
216 ('COFACTOR2', 'COFACTOR_A'), # many:1
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
217 ('COFACTOR3', 'COFACTOR_B'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
218 ('SUBUNIT1', 'COMPLEX_SUBUNIT1'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
219 ('SUBUNIT2', 'COMPLEX_SUBUNIT2'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
220 ('SUBUNIT3', 'COMPLEX_ALTERNATIVE'),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
221 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
222
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
223 # Combine all mappings
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
224 all_mappings = one_to_one + one_to_many + many_to_one + mixed_mappings + case_mappings + real_mappings
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
225
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
226 for source, target in all_mappings:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
227 mapping_data['hgnc_symbol'].append(source)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
228 mapping_data['ensg'].append(target)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
229
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
230 return pd.DataFrame(mapping_data)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
231
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
232 def analyze_mapping_statistics(self, mapping_df: pd.DataFrame) -> Dict:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
233 """Analyze mapping statistics"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
234 stats = {}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
235
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
236 source_counts = mapping_df.groupby('hgnc_symbol')['ensg'].count()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
237 target_counts = mapping_df.groupby('ensg')['hgnc_symbol'].count()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
238
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
239 stats['total_mappings'] = len(mapping_df)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
240 stats['unique_sources'] = len(source_counts)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
241 stats['unique_targets'] = len(target_counts)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
242
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
243 stats['one_to_one'] = (source_counts == 1).sum()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
244 stats['one_to_many'] = (source_counts > 1).sum()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
245 stats['many_to_one_targets'] = (target_counts > 1).sum()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
246
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
247 stats['one_to_many_details'] = {}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
248 for gene, count in source_counts[source_counts > 1].items():
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
249 targets = mapping_df[mapping_df['hgnc_symbol'] == gene]['ensg'].tolist()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
250 stats['one_to_many_details'][gene] = targets
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
251
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
252 stats['many_to_one_details'] = {}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
253 for target, count in target_counts[target_counts > 1].items():
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
254 sources = mapping_df[mapping_df['ensg'] == target]['hgnc_symbol'].tolist()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
255 stats['many_to_one_details'][target] = sources
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
256
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
257 return stats
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
258
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
259 def predict_translation_issues(self, model: cobra.Model, mapping_df: pd.DataFrame) -> Dict:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
260 """Predict which reactions will have translation issues"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
261 predictions = {}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
262 mapping_dict = {}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
263
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
264 # Build mapping dictionary
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
265 for _, row in mapping_df.iterrows():
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
266 source = row['hgnc_symbol']
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
267 target = row['ensg']
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
268 if source not in mapping_dict:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
269 mapping_dict[source] = []
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
270 mapping_dict[source].append(target)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
271
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
272 for rxn in model.reactions:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
273 if not rxn.gene_reaction_rule or rxn.gene_reaction_rule.strip() == '':
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
274 continue
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
275
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
276 # Extract genes from GPR
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
277 token_pattern = r'\b[A-Za-z0-9:_.-]+\b'
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
278 tokens = re.findall(token_pattern, rxn.gene_reaction_rule)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
279 logical_operators = {'and', 'or', 'AND', 'OR', '(', ')'}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
280 genes = [t for t in tokens if t not in logical_operators]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
281
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
282 issues = []
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
283 has_1_to_many = False
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
284 has_many_to_1 = False
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
285 has_unmapped = False
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
286
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
287 for gene in set(genes):
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
288 norm_gene = model_utils._normalize_gene_id(gene)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
289 if norm_gene in mapping_dict:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
290 targets = mapping_dict[norm_gene]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
291 if len(targets) > 1:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
292 has_1_to_many = True
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
293 issues.append(f"1:many - {gene} -> {targets}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
294 else:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
295 has_unmapped = True
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
296 issues.append(f"unmapped - {gene}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
297
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
298 # Check for many:1 mappings
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
299 target_to_sources = {}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
300 for gene in set(genes):
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
301 norm_gene = model_utils._normalize_gene_id(gene)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
302 if norm_gene in mapping_dict:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
303 for target in mapping_dict[norm_gene]:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
304 if target not in target_to_sources:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
305 target_to_sources[target] = []
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
306 target_to_sources[target].append(gene)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
307
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
308 for target, sources in target_to_sources.items():
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
309 if len(sources) > 1:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
310 has_many_to_1 = True
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
311 issues.append(f"many:1 - {sources} -> {target}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
312
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
313 if issues:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
314 predictions[rxn.id] = {
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
315 'issues': issues,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
316 'has_1_to_many': has_1_to_many,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
317 'has_many_to_1': has_many_to_1,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
318 'has_unmapped': has_unmapped,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
319 'is_or_only': self._check_if_or_only(rxn.gene_reaction_rule),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
320 'predicted_flattening': has_1_to_many or has_many_to_1 and self._check_if_or_only(rxn.gene_reaction_rule)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
321 }
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
322
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
323 return predictions
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
324
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
325 def _check_if_or_only(self, gpr: str) -> bool:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
326 """Check if GPR contains only OR operators (and parentheses)"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
327 if not gpr or gpr.strip() == '':
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
328 return False
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
329
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
330 # Remove gene names and whitespace, keep only logical operators
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
331 token_pattern = r'\b[A-Za-z0-9:_.-]+\b'
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
332 logic_only = re.sub(token_pattern, '', gpr)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
333 logic_only = re.sub(r'\s+', ' ', logic_only.strip())
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
334
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
335 # Check for AND operators
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
336 and_pattern = r'\b(and|AND)\b'
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
337 return not bool(re.search(and_pattern, logic_only))
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
338
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
339 def run_comprehensive_test(self) -> Dict:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
340 """Run the comprehensive translation test"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
341 print("="*80)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
342 print("COMPREHENSIVE GPR TRANSLATION TEST SUITE")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
343 print("="*80)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
344
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
345 # Create test model and mapping
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
346 print("\n1. Creating test model and mapping...")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
347 model = self.create_comprehensive_test_model()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
348 mapping_df = self.create_comprehensive_mapping()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
349
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
350 print(f" āœ“ Created model with {len(model.reactions)} reactions")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
351 print(f" āœ“ Created mapping with {len(mapping_df)} entries")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
352
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
353 # Analyze mapping statistics
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
354 print("\n2. Analyzing mapping statistics...")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
355 mapping_stats = self.analyze_mapping_statistics(mapping_df)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
356 print(f" āœ“ Unique source genes: {mapping_stats['unique_sources']}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
357 print(f" āœ“ Unique target genes: {mapping_stats['unique_targets']}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
358 print(f" āœ“ 1:1 mappings: {mapping_stats['one_to_one']}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
359 print(f" āœ“ 1:many mappings: {mapping_stats['one_to_many']}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
360 print(f" āœ“ Many:1 target genes: {mapping_stats['many_to_one_targets']}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
361
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
362 # Predict translation issues
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
363 print("\n3. Predicting translation issues...")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
364 predicted_issues = self.predict_translation_issues(model, mapping_df)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
365 predicted_or_only = sum(1 for pred in predicted_issues.values() if pred['is_or_only'])
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
366 predicted_flattening = sum(1 for pred in predicted_issues.values() if pred['predicted_flattening'])
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
367
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
368 print(f" āœ“ Reactions with predicted issues: {len(predicted_issues)}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
369 print(f" āœ“ OR-only reactions: {predicted_or_only}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
370 print(f" āœ“ Predicted for flattening: {predicted_flattening}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
371
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
372 # Display original GPRs
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
373 print("\n4. Original model GPRs:")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
374 for rxn in sorted(model.reactions, key=lambda x: x.id):
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
375 status = "šŸ”" if rxn.id in predicted_issues else "āœ“"
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
376 or_only = "šŸ”—" if predicted_issues.get(rxn.id, {}).get('is_or_only', False) else " "
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
377 print(f" {status}{or_only} {rxn.id:20} : {rxn.gene_reaction_rule}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
378
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
379 # Run translation
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
380 print("\n5. Running translation...")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
381 try:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
382 translated_model, translation_issues = model_utils.translate_model_genes(
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
383 model=model,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
384 mapping_df=mapping_df,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
385 target_nomenclature='ensg',
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
386 source_nomenclature='hgnc_symbol',
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
387 allow_many_to_one=True
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
388 )
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
389 print(" āœ“ Translation completed successfully")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
390 except Exception as e:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
391 print(f" āŒ Translation failed: {e}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
392 import traceback
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
393 traceback.print_exc()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
394 return {'success': False, 'error': str(e)}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
395
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
396 # Display translated GPRs
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
397 print("\n6. Translated model GPRs:")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
398 for rxn in sorted(translated_model.reactions, key=lambda x: x.id):
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
399 has_issues = "🚨" if rxn.id in translation_issues else "āœ“"
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
400 print(f" {has_issues} {rxn.id:20} : {rxn.gene_reaction_rule}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
401
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
402 # Analyze translation issues
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
403 print("\n7. Translation issues analysis:")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
404 if translation_issues:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
405 for rxn_id, issues_str in sorted(translation_issues.items()):
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
406 predicted = predicted_issues.get(rxn_id, {})
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
407 prediction_status = "āœ“ PREDICTED" if rxn_id in predicted_issues else "ā“ UNEXPECTED"
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
408 print(f" 🚨 {rxn_id:20} ({prediction_status})")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
409 # Split issues string by semicolon separator
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
410 if issues_str:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
411 issues_list = [issue.strip() for issue in issues_str.split(';') if issue.strip()]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
412 for issue in issues_list:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
413 print(f" - {issue}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
414 else:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
415 print(f" - No specific issues reported")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
416 else:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
417 print(" āœ… No translation issues detected")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
418
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
419 # Compare predictions vs actual
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
420 print("\n8. Prediction accuracy:")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
421 true_positive = set(predicted_issues.keys()) & set(translation_issues.keys())
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
422 false_positive = set(predicted_issues.keys()) - set(translation_issues.keys())
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
423 false_negative = set(translation_issues.keys()) - set(predicted_issues.keys())
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
424
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
425 print(f" āœ“ Correctly predicted issues: {len(true_positive)}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
426 print(f" ⚠ False positives: {len(false_positive)}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
427 print(f" āŒ False negatives: {len(false_negative)}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
428
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
429 if false_positive:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
430 print(" False positive reactions:")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
431 for rxn_id in false_positive:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
432 print(f" - {rxn_id}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
433
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
434 if false_negative:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
435 print(" False negative reactions:")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
436 for rxn_id in false_negative:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
437 print(f" - {rxn_id}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
438
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
439 # Test specific functionality
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
440 print("\n9. Testing OR-only GPR flattening...")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
441 flattening_tests = self.test_or_only_flattening(translated_model, translation_issues)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
442
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
443 # Summary statistics
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
444 print("\n10. Summary:")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
445 results = {
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
446 'success': True,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
447 'model_reactions': len(model.reactions),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
448 'mapping_entries': len(mapping_df),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
449 'predicted_issues': len(predicted_issues),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
450 'actual_issues': len(translation_issues),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
451 'prediction_accuracy': {
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
452 'true_positive': len(true_positive),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
453 'false_positive': len(false_positive),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
454 'false_negative': len(false_negative),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
455 'precision': len(true_positive) / len(predicted_issues) if predicted_issues else 0,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
456 'recall': len(true_positive) / len(translation_issues) if translation_issues else 0,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
457 },
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
458 'mapping_stats': mapping_stats,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
459 'flattening_tests': flattening_tests,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
460 'models': {
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
461 'original': model,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
462 'translated': translated_model
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
463 },
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
464 'issues': {
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
465 'predicted': predicted_issues,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
466 'actual': translation_issues
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
467 }
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
468 }
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
469
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
470 precision = results['prediction_accuracy']['precision']
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
471 recall = results['prediction_accuracy']['recall']
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
472 f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
473
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
474 print(f" šŸ“Š Total reactions: {len(model.reactions)}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
475 print(f" šŸ“Š Reactions with issues: {len(translation_issues)}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
476 print(f" šŸ“Š Prediction precision: {precision:.2%}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
477 print(f" šŸ“Š Prediction recall: {recall:.2%}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
478 print(f" šŸ“Š Prediction F1-score: {f1:.2%}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
479 print(f" šŸ“Š OR-only flattening tests: {flattening_tests['passed']}/{flattening_tests['total']}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
480
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
481 print("\n" + "="*80)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
482 print("TEST SUITE COMPLETED")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
483 print("="*80)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
484
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
485 return results
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
486
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
487 def test_or_only_flattening(self, model: cobra.Model, translation_issues: Dict) -> Dict:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
488 """Test the OR-only GPR flattening functionality"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
489 test_cases = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
490 # (original_gpr, expected_after_flattening, should_be_flattened)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
491 ("SHARED_TARGET1 or SHARED_TARGET1", "SHARED_TARGET1", True),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
492 ("(SHARED_TARGET2 or SHARED_TARGET2) or SHARED_TARGET2", "SHARED_TARGET2", True),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
493 ("TARGET1 or TARGET2 or TARGET1", "TARGET1 or TARGET2", True),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
494 ("(TARGET1 or TARGET2) and TARGET3", "(TARGET1 or TARGET2) and TARGET3", False), # Contains AND
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
495 ("TARGET1 and TARGET1", "TARGET1", True), # Should simplify AND duplicates too
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
496 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
497
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
498 results = {'total': 0, 'passed': 0, 'failed': [], 'details': []}
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
499
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
500 print(" Testing OR-only flattening functionality:")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
501
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
502 # Test the helper functions directly
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
503 for original, expected, should_flatten in test_cases:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
504 results['total'] += 1
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
505
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
506 # Test _is_or_only_expression
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
507 is_or_only = model_utils._is_or_only_expression(original)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
508
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
509 # Test _flatten_or_only_gpr if it should be OR-only
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
510 if should_flatten and 'and' not in original.lower():
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
511 flattened = model_utils._flatten_or_only_gpr(original)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
512 passed = flattened == expected
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
513 else:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
514 passed = not should_flatten or is_or_only == (not 'and' in original.lower())
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
515 flattened = original
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
516
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
517 status = "āœ“" if passed else "āŒ"
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
518 results['details'].append({
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
519 'original': original,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
520 'expected': expected,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
521 'flattened': flattened,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
522 'is_or_only': is_or_only,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
523 'should_flatten': should_flatten,
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
524 'passed': passed
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
525 })
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
526
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
527 if passed:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
528 results['passed'] += 1
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
529 else:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
530 results['failed'].append(f"{original} -> {flattened} (expected: {expected})")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
531
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
532 print(f" {status} '{original}' -> '{flattened}' (OR-only: {is_or_only})")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
533
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
534 # Test actual model reactions that should have been flattened
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
535 for rxn in model.reactions:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
536 if rxn.id in translation_issues:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
537 original_gpr = rxn.gene_reaction_rule
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
538 is_or_only = model_utils._is_or_only_expression(original_gpr)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
539 if is_or_only:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
540 print(f" šŸ” Real case: {rxn.id} has OR-only GPR: '{original_gpr}'")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
541
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
542 return results
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
543
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
544 def run_individual_tests():
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
545 """Run individual component tests"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
546 print("\n" + "="*80)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
547 print("INDIVIDUAL COMPONENT TESTS")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
548 print("="*80)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
549
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
550 # Test 1: OR-only detection
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
551 print("\n1. Testing OR-only detection...")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
552 or_only_cases = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
553 ("GENE1 or GENE2", True),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
554 ("(GENE1 or GENE2)", True),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
555 ("GENE1 or GENE2 or GENE3", True),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
556 ("(GENE1 or GENE2) or GENE3", True),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
557 ("((GENE1 or GENE2) or GENE3) or GENE4", True),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
558 ("GENE1 and GENE2", False),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
559 ("GENE1 or (GENE2 and GENE3)", False),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
560 ("(GENE1 or GENE2) and GENE3", False),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
561 ("GENE1", False), # Single gene
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
562 ("", False), # Empty
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
563 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
564
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
565 for gpr, expected in or_only_cases:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
566 result = model_utils._is_or_only_expression(gpr)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
567 status = "āœ“" if result == expected else "āŒ"
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
568 print(f" {status} '{gpr}' -> {result} (expected: {expected})")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
569
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
570 # Test 2: GPR flattening
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
571 print("\n2. Testing GPR flattening...")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
572 flattening_cases = [
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
573 ("GENE1 or GENE1", "GENE1"),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
574 ("(GENE1 or GENE1) or GENE2", "GENE1 or GENE2"),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
575 ("GENE1 or GENE2 or GENE1", "GENE1 or GENE2"),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
576 ("(GENE1 or GENE2) or (GENE1 or GENE3)", "GENE1 or GENE2 or GENE3"),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
577 ("((A or A) or B) or C", "A or B or C"),
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
578 ]
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
579
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
580 for original, expected in flattening_cases:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
581 result = model_utils._flatten_or_only_gpr(original)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
582 status = "āœ“" if result == expected else "āŒ"
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
583 print(f" {status} '{original}' -> '{result}' (expected: '{expected}')")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
584
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
585 def main():
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
586 """Main test function"""
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
587 print("COBRAxy GPR Translation Comprehensive Test Suite")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
588 print("=" * 80)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
589
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
590 # Run individual component tests first
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
591 run_individual_tests()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
592
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
593 # Run comprehensive test suite
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
594 tester = GPRTranslationTester()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
595 results = tester.run_comprehensive_test()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
596
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
597 # Save results for further analysis if needed
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
598 if results['success']:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
599 print(f"\nāœ… All tests completed successfully!")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
600 print(f"šŸ“ Test models and results available in results object")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
601
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
602 # Optionally save to file
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
603 try:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
604 import pickle
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
605 with open('/tmp/gpr_translation_test_results.pkl', 'wb') as f:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
606 pickle.dump(results, f)
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
607 print(f"šŸ“ Detailed results saved to /tmp/gpr_translation_test_results.pkl")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
608 except:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
609 pass
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
610 else:
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
611 print(f"\nāŒ Tests failed: {results.get('error', 'Unknown error')}")
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
612 return False
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
613
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
614 return True
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
615
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
616 if __name__ == "__main__":
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
617 success = main()
a92d21f92956 Uploaded
francesco_lapi
parents:
diff changeset
618 sys.exit(0 if success else 1)