AdvancedAnalysisFileParser 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/AdvancedAnalysisParser.py +84 -5
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Models/FieldCondition.py +24 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Parsers/IAdvancedAnalysisFileParser.py +28 -2
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Warnings/CarrierPositiveWarning.py +10 -0
- advancedanalysisfileparser-0.1.2/AdvancedAnalysisFileParser/Warnings/ConditionWarning.py +38 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Warnings/GbaWarning.py +10 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Warnings/GenotypeWarning.py +15 -2
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Warnings/SmnWarning.py +10 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser.egg-info/PKG-INFO +7 -1
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser.egg-info/SOURCES.txt +1 -0
- advancedanalysisfileparser-0.1.2/AdvancedAnalysisFileParser.egg-info/entry_points.txt +3 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/PKG-INFO +7 -1
- advancedanalysisfileparser-0.1.2/pyproject.toml +28 -0
- advancedanalysisfileparser-0.1.0/AdvancedAnalysisFileParser/Warnings/ConditionWarning.py +0 -20
- advancedanalysisfileparser-0.1.0/pyproject.toml +0 -15
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/AdvancedAnalysisConstants.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Models/ConditionOperator.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Models/FieldWarningConfig.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Models/JsonDict.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Models/SectionConfig.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Models/__init__.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Parsers/AdvancedAnalysisFileParserFactory.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Parsers/DragenTruSightOncology500TSVParser.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Parsers/JsonSectionParser.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Parsers/OneLineTsvParser.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Parsers/__init__.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/README.md +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/TruSightOncology500.CombinedVariantOutput.tsv +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/dragen424.targeted.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/dummy_gba_affected_nonrecomb_acn2.targeted.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/dummy_gba_carrier_one_recomb_only.targeted.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/dummy_gba_phase_unknown_one_recomb_plus_variant.targeted.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/dummy_warnset_1.targeted.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/dummy_warnset_2.targeted.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/dummy_warnset_3.targeted.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/gba.tsv +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/gba_carrier_1.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/gba_carrier_2.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/gba_multiple_phase_unknown_1.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/gba_multiple_phase_unknown_2.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/gba_positive_1.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/gba_positive_2.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/hba_carrier_1.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/hba_carrier_2.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/hba_carrier_3.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/hba_carrier_4.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/hba_hemoglobin_h_disease.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/hba_silent_carrier.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/smn.tsv +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/smn_carrier.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/smn_positive.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test/smn_silent_carrier_risk.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Test_AdvancedAnalysisParser.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Warnings/IWarning.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Warnings/WarningFactory.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/Warnings/__init__.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/__init__.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/advConfig.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/dragen_500_tsv_config.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/gba_tsv_config.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/run_test_parser.py +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser/smn_tsv_config.json +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser.egg-info/dependency_links.txt +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/AdvancedAnalysisFileParser.egg-info/top_level.txt +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/LICENSE +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/MANIFEST.in +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/README.md +0 -0
- {advancedanalysisfileparser-0.1.0 → advancedanalysisfileparser-0.1.2}/setup.cfg +0 -0
|
@@ -3,9 +3,7 @@ import argparse
|
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
|
-
import re
|
|
7
6
|
from typing import Optional
|
|
8
|
-
from pathlib import Path
|
|
9
7
|
from .Models import *
|
|
10
8
|
from .Warnings import *
|
|
11
9
|
from .Parsers import *
|
|
@@ -13,17 +11,58 @@ from .AdvancedAnalysisConstants import AdvancedAnalysisConstants
|
|
|
13
11
|
|
|
14
12
|
class AdvancedAnalysisParser:
|
|
15
13
|
"""
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
AdvancedAnalysisParser
|
|
15
|
+
|
|
16
|
+
Parses special callers outputs (TSV/JSON) into a unified JSON format.
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
- Instantiate with a config dict (JsonDict) specifying input/output files and directories.
|
|
20
|
+
- Call run() to parse and write output JSON.
|
|
21
|
+
- Use from_cli() for command-line usage.
|
|
22
|
+
|
|
23
|
+
Parameters for constructor (json_request: JsonDict):
|
|
24
|
+
- input_files: List[str] (optional) - List of input file paths to parse.
|
|
25
|
+
- input_dir: str (optional) - Directory containing input files.
|
|
26
|
+
- output_dir: str (optional) - Directory to write output JSON.
|
|
27
|
+
- output_json: str (optional) - Output JSON filename.
|
|
28
|
+
- MAP_FILES: dict (optional) - Mapping for file-specific configs.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
- run(return_dict=True): Returns parsed result as JsonDict.
|
|
32
|
+
- run(return_dict=False): Writes output JSON file, returns None.
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
config = {
|
|
36
|
+
"input_files": ["file1.json", "file2.tsv"],
|
|
37
|
+
"input_dir": "./inputs",
|
|
38
|
+
"output_dir": "./outputs",
|
|
39
|
+
"output_json": "result.json"
|
|
40
|
+
}
|
|
41
|
+
parser = AdvancedAnalysisParser(config)
|
|
42
|
+
parser.run()
|
|
19
43
|
"""
|
|
20
44
|
def __init__(self, json_request: JsonDict) -> None:
|
|
45
|
+
"""
|
|
46
|
+
Initialize parser with configuration.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
json_request (JsonDict): Configuration dict. See class docstring for keys.
|
|
50
|
+
"""
|
|
21
51
|
self.output_dir: str = json_request.get(AdvancedAnalysisConstants.OUTPUT_DIR, '.')
|
|
22
52
|
self.output_json: str = json_request.get(AdvancedAnalysisConstants.OUTPUT_JSON, 'adv_analysis_output.json')
|
|
23
53
|
self.input_dir: str = json_request.get(AdvancedAnalysisConstants.INPUT_DIR, '.')
|
|
24
54
|
self.input_files: list[str] = json_request.get('input_files', [])
|
|
25
55
|
|
|
26
56
|
def run(self, return_dict: bool = False) -> Optional[JsonDict]:
|
|
57
|
+
"""
|
|
58
|
+
Parse files and output unified JSON.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
return_dict (bool): If True, returns parsed result as dict. If False, writes output file.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
JsonDict if return_dict is True, else None.
|
|
65
|
+
"""
|
|
27
66
|
result = self.parse_files()
|
|
28
67
|
if return_dict:
|
|
29
68
|
return result
|
|
@@ -34,6 +73,14 @@ class AdvancedAnalysisParser:
|
|
|
34
73
|
return None
|
|
35
74
|
|
|
36
75
|
def parse_files(self) -> JsonDict:
|
|
76
|
+
"""
|
|
77
|
+
Parse all input files specified in config.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
JsonDict: Unified parsed result from all files.
|
|
81
|
+
Raises:
|
|
82
|
+
ValueError: If no input files found.
|
|
83
|
+
"""
|
|
37
84
|
logging.info("Started parsing Advanced Analysis files")
|
|
38
85
|
if not self.input_files or self.input_files == [] and self.input_dir and os.path.exists(self.input_dir):
|
|
39
86
|
folder_files = [
|
|
@@ -59,11 +106,33 @@ class AdvancedAnalysisParser:
|
|
|
59
106
|
return result
|
|
60
107
|
|
|
61
108
|
def parse_by_config(self,parser : IAdvancedAnalysisFileParser) -> JsonDict:
|
|
109
|
+
"""
|
|
110
|
+
Parse a single file using its parser and build result.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
parser (IAdvancedAnalysisFileParser): Parser instance for the file.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
JsonDict: Parsed and formatted result for the file.
|
|
117
|
+
"""
|
|
62
118
|
caller_data: JsonDict = parser.parse()
|
|
63
119
|
return parser.build_result(caller_data)
|
|
64
120
|
|
|
65
121
|
@staticmethod
|
|
66
122
|
def _threshold_warning(w: JsonDict, parsed: JsonDict, value_key: str, threshold_key: str, label: str) -> str:
|
|
123
|
+
"""
|
|
124
|
+
Helper to generate threshold warning string if value exceeds threshold.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
w (JsonDict): Warning config dict.
|
|
128
|
+
parsed (JsonDict): Parsed data dict.
|
|
129
|
+
value_key (str): Key for value to check.
|
|
130
|
+
threshold_key (str): Key for threshold value.
|
|
131
|
+
label (str): Label for warning.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
str: Warning message or empty string.
|
|
135
|
+
"""
|
|
67
136
|
name = w.get("caller_name")
|
|
68
137
|
key = w.get(value_key)
|
|
69
138
|
threshold = w.get(threshold_key)
|
|
@@ -74,6 +143,12 @@ class AdvancedAnalysisParser:
|
|
|
74
143
|
|
|
75
144
|
@staticmethod
|
|
76
145
|
def parse_args() -> argparse.Namespace:
|
|
146
|
+
"""
|
|
147
|
+
Parse command-line arguments for CLI usage.
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
argparse.Namespace: Parsed CLI arguments.
|
|
151
|
+
"""
|
|
77
152
|
parser = argparse.ArgumentParser(
|
|
78
153
|
description="Parse special callers outputs into unified JSON"
|
|
79
154
|
)
|
|
@@ -86,6 +161,10 @@ class AdvancedAnalysisParser:
|
|
|
86
161
|
|
|
87
162
|
@classmethod
|
|
88
163
|
def from_cli(cls) -> None:
|
|
164
|
+
"""
|
|
165
|
+
Entry point for command-line usage.
|
|
166
|
+
Loads config from file and/or CLI args, runs parser.
|
|
167
|
+
"""
|
|
89
168
|
args = cls.parse_args()
|
|
90
169
|
config = {}
|
|
91
170
|
# Load config file if provided
|
|
@@ -3,15 +3,39 @@ from .ConditionOperator import ConditionOperator
|
|
|
3
3
|
|
|
4
4
|
class FieldCondition:
|
|
5
5
|
def __init__(self, operator: ConditionOperator, value: Any, message: str, field: Optional[str] = None):
|
|
6
|
+
"""
|
|
7
|
+
Create a condition to check a field value against a target value using an operator.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
operator (ConditionOperator): The comparison operator (e.g., EQ, GT, CONTAINS).
|
|
11
|
+
value (Any): The value to compare against.
|
|
12
|
+
message (str): Message to return if the condition is met.
|
|
13
|
+
field (Optional[str]): Name of the field to check (optional, for context).
|
|
14
|
+
"""
|
|
6
15
|
self.operator = operator
|
|
7
16
|
self.value = value
|
|
8
17
|
self.message = message
|
|
9
18
|
|
|
10
19
|
def check(self, value: Any) -> bool:
|
|
20
|
+
"""
|
|
21
|
+
Check if the provided value satisfies the condition.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
value (Any): The value to check.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
bool: True if the condition is met, False otherwise.
|
|
28
|
+
"""
|
|
11
29
|
func = OPERATOR_FUNCS[self.operator]
|
|
12
30
|
return func(value, self.value)
|
|
13
31
|
|
|
14
32
|
def __str__(self) -> str:
|
|
33
|
+
"""
|
|
34
|
+
Return the message associated with this condition.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
str: The message string.
|
|
38
|
+
"""
|
|
15
39
|
return self.message
|
|
16
40
|
|
|
17
41
|
# map each operator to a function that compares (field_value, target_value) → bool
|
|
@@ -5,13 +5,24 @@ from typing import Any
|
|
|
5
5
|
|
|
6
6
|
from ..Warnings import IWarning
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
8
|
+
from AdvancedAnalysisFileParser.AdvancedAnalysisConstants import AdvancedAnalysisConstants
|
|
9
|
+
from AdvancedAnalysisFileParser.Warnings.WarningFactory import WarningFactory
|
|
10
10
|
from ..Models import JsonDict
|
|
11
11
|
class IAdvancedAnalysisFileParser(ABC):
|
|
12
12
|
section_config : JsonDict
|
|
13
13
|
file_config : JsonDict
|
|
14
14
|
def __init__(self,section_config: JsonDict, file_path: str) -> None:
|
|
15
|
+
"""
|
|
16
|
+
Initialize a file parser for advanced analysis.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
section_config (JsonDict): Section configuration for parsing.
|
|
20
|
+
file_path (str): Path to the file to parse (must be .json or .tsv).
|
|
21
|
+
|
|
22
|
+
Raises:
|
|
23
|
+
ValueError: If file_path is empty or not a string.
|
|
24
|
+
FileNotFoundError: If the file does not exist.
|
|
25
|
+
"""
|
|
15
26
|
self.section_config = section_config
|
|
16
27
|
if not file_path:
|
|
17
28
|
raise ValueError("Filename cannot be empty")
|
|
@@ -29,9 +40,24 @@ class IAdvancedAnalysisFileParser(ABC):
|
|
|
29
40
|
|
|
30
41
|
@abstractmethod
|
|
31
42
|
def parse(self) -> JsonDict:
|
|
43
|
+
"""
|
|
44
|
+
Parse the file and return its data as a JsonDict.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
JsonDict: Parsed data from the file.
|
|
48
|
+
"""
|
|
32
49
|
pass
|
|
33
50
|
|
|
34
51
|
def build_result(self,data: JsonDict) -> JsonDict:
|
|
52
|
+
"""
|
|
53
|
+
Build a result dictionary from parsed data and section config.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
data (JsonDict): Parsed data from the file.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
JsonDict: Result dictionary with formatted values and warnings.
|
|
60
|
+
"""
|
|
35
61
|
result: JsonDict = {}
|
|
36
62
|
for caller_name, caller_config in self.section_config.items():
|
|
37
63
|
caller_title = caller_config.get("caller_name", None)
|
|
@@ -2,6 +2,16 @@ from .IWarning import IWarning
|
|
|
2
2
|
from ..Models import *
|
|
3
3
|
class CarrierPositiveWarning(IWarning):
|
|
4
4
|
def format(self, config: JsonDict, data: JsonDict) -> str:
|
|
5
|
+
"""
|
|
6
|
+
Generate a warning message for carrier/positive status based on conditions.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
config (JsonDict): Configuration dict with 'conditions' (list of dicts).
|
|
10
|
+
data (JsonDict): Data dict to check conditions against.
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
str: Warning message if a condition is met, else empty string.
|
|
14
|
+
"""
|
|
5
15
|
name = config.get("caller_name") or config.get("name")
|
|
6
16
|
disease = config.get("disease_name") or config.get("disease")
|
|
7
17
|
conditions = config.get("conditions",{})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from .IWarning import IWarning
|
|
2
|
+
from ..Models import JsonDict, FieldCondition, ConditionOperator
|
|
3
|
+
|
|
4
|
+
class ConditionWarning(IWarning):
|
|
5
|
+
def format(self, config: JsonDict, data: JsonDict) -> str:
|
|
6
|
+
"""
|
|
7
|
+
Generate warning messages based on a list of conditions.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
config (JsonDict): Configuration dictionary. Must contain a "conditions" key with a list of dicts,
|
|
11
|
+
each representing a FieldCondition (keys: operator, value, message, field [optional]).
|
|
12
|
+
data (JsonDict): Data dictionary to check conditions against. If a condition specifies a field, that field's value is used.
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
str: Concatenated warning messages for all triggered conditions, separated by ". ". Returns an empty string if no conditions are met.
|
|
16
|
+
|
|
17
|
+
Example config:
|
|
18
|
+
config = {
|
|
19
|
+
"conditions": [
|
|
20
|
+
{"operator": "GT", "value": 10, "message": "Value is too high", "field": "score"},
|
|
21
|
+
{"operator": "EQ", "value": 0, "message": "Value is zero"}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
"""
|
|
25
|
+
msgs = []
|
|
26
|
+
for cond_dict in config.get("conditions", []):
|
|
27
|
+
cond_dict["operator"] = ConditionOperator[cond_dict["operator"]]
|
|
28
|
+
cond = FieldCondition(**cond_dict)
|
|
29
|
+
if isinstance(data, dict):
|
|
30
|
+
if cond_dict.get("field") in data:
|
|
31
|
+
data = data[cond_dict["field"]]
|
|
32
|
+
warning = cond.__str__()
|
|
33
|
+
if warning in msgs:
|
|
34
|
+
continue
|
|
35
|
+
if cond.check(data):
|
|
36
|
+
msgs.append(warning)
|
|
37
|
+
print(f"Warning triggered by condition: {warning}")
|
|
38
|
+
return ". ".join(msgs)
|
|
@@ -3,6 +3,16 @@ from ..Models import JsonDict
|
|
|
3
3
|
|
|
4
4
|
class GbaWarning(IWarning):
|
|
5
5
|
def format(self, config: JsonDict, data: JsonDict) -> str:
|
|
6
|
+
"""
|
|
7
|
+
Generate a warning message for GBA gene analysis (e.g., Gaucher disease risk).
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
config (JsonDict): Configuration dict with keys like 'caller_name', 'disease_name'.
|
|
11
|
+
data (JsonDict): Data dict with keys like 'recombinantHaplotypes', 'variants'.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
str: Warning message if a relevant condition is met, else empty string.
|
|
15
|
+
"""
|
|
6
16
|
name = config.get("caller_name") or config.get("name") or "GBA Caller"
|
|
7
17
|
disease = config.get("disease_name") or config.get("disease") or "Gaucher disease"
|
|
8
18
|
|
|
@@ -2,6 +2,16 @@ from .IWarning import IWarning
|
|
|
2
2
|
from ..Models import JsonDict
|
|
3
3
|
class GenotypeWarning(IWarning):
|
|
4
4
|
def format(self, config: JsonDict, data: JsonDict) -> str:
|
|
5
|
+
"""
|
|
6
|
+
Generate a warning message based on genotype-to-phenotype mapping.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
config (JsonDict): Configuration dict with mapping info.
|
|
10
|
+
data (JsonDict): Data dict with genotype info.
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
str: Warning message if mapping found, else empty string.
|
|
14
|
+
"""
|
|
5
15
|
name = config.get("caller_name") or config.get("name")
|
|
6
16
|
genotype_key = config.get("genotype_data_key", "genotype")
|
|
7
17
|
sample = data.get(genotype_key)
|
|
@@ -12,11 +22,14 @@ class GenotypeWarning(IWarning):
|
|
|
12
22
|
if all(isinstance(v, str) for v in mapping.values()):
|
|
13
23
|
# Old format: genotype→phenotype
|
|
14
24
|
if sample in mapping:
|
|
15
|
-
|
|
25
|
+
phenotype = mapping[sample]
|
|
26
|
+
if phenotype != "normal":
|
|
27
|
+
warning = f"Based on {name}, this sample is defined as <b>{phenotype}</b>"
|
|
16
28
|
elif all(isinstance(v, list) for v in mapping.values()):
|
|
17
29
|
# New format: phenotype→[genotypes]
|
|
18
30
|
for phenotype, genotypes in mapping.items():
|
|
19
31
|
if sample in genotypes:
|
|
20
|
-
|
|
32
|
+
if phenotype != "normal":
|
|
33
|
+
warning = f"Based on {name}, this sample is defined as <b>{phenotype}</b>"
|
|
21
34
|
break
|
|
22
35
|
return warning
|
|
@@ -3,6 +3,16 @@ from ..Models import JsonDict
|
|
|
3
3
|
|
|
4
4
|
class SmnWarning(IWarning):
|
|
5
5
|
def format(self, config: JsonDict, data: JsonDict) -> str:
|
|
6
|
+
"""
|
|
7
|
+
Generate a warning message for SMN gene copy number analysis.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
config (JsonDict): Configuration dict with keys like 'caller_name', 'disease_name'.
|
|
11
|
+
data (JsonDict): Data dict with keys like 'smn1CopyNumber', 'variants'.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
str: Warning message if a relevant condition is met, else empty string.
|
|
15
|
+
"""
|
|
6
16
|
name = config.get("caller_name") or config.get("name") or "SMN Caller"
|
|
7
17
|
disease = config.get("disease_name") or config.get("disease") or "Spinal Muscular Atrophy"
|
|
8
18
|
smn1_cn = data.get("smn1CopyNumber")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: AdvancedAnalysisFileParser
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Parse Illumina-DRAGEN TSV/JSON outputs to unified geneyx JSON with warnings.
|
|
5
5
|
Author: Bar Cohen
|
|
6
6
|
Author-email: Bar Cohen <bar@geneyx.com>
|
|
@@ -13,6 +13,12 @@ License: MIT License
|
|
|
13
13
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
14
14
|
|
|
15
15
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
16
|
+
Project-URL: homepage, https://github.com/geneyx/AdvancedAnalysisFileParser
|
|
17
|
+
Project-URL: repository, https://github.com/geneyx/AdvancedAnalysisFileParser
|
|
18
|
+
Project-URL: documentation, https://geneyx.com/docs
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
16
22
|
Requires-Python: >=3.7
|
|
17
23
|
Description-Content-Type: text/markdown
|
|
18
24
|
License-File: LICENSE
|
|
@@ -16,6 +16,7 @@ AdvancedAnalysisFileParser/smn_tsv_config.json
|
|
|
16
16
|
AdvancedAnalysisFileParser.egg-info/PKG-INFO
|
|
17
17
|
AdvancedAnalysisFileParser.egg-info/SOURCES.txt
|
|
18
18
|
AdvancedAnalysisFileParser.egg-info/dependency_links.txt
|
|
19
|
+
AdvancedAnalysisFileParser.egg-info/entry_points.txt
|
|
19
20
|
AdvancedAnalysisFileParser.egg-info/top_level.txt
|
|
20
21
|
AdvancedAnalysisFileParser/Models/ConditionOperator.py
|
|
21
22
|
AdvancedAnalysisFileParser/Models/FieldCondition.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: AdvancedAnalysisFileParser
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Parse Illumina-DRAGEN TSV/JSON outputs to unified geneyx JSON with warnings.
|
|
5
5
|
Author: Bar Cohen
|
|
6
6
|
Author-email: Bar Cohen <bar@geneyx.com>
|
|
@@ -13,6 +13,12 @@ License: MIT License
|
|
|
13
13
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
14
14
|
|
|
15
15
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
16
|
+
Project-URL: homepage, https://github.com/geneyx/AdvancedAnalysisFileParser
|
|
17
|
+
Project-URL: repository, https://github.com/geneyx/AdvancedAnalysisFileParser
|
|
18
|
+
Project-URL: documentation, https://geneyx.com/docs
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
21
|
+
Classifier: Operating System :: OS Independent
|
|
16
22
|
Requires-Python: >=3.7
|
|
17
23
|
Description-Content-Type: text/markdown
|
|
18
24
|
License-File: LICENSE
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[project]
|
|
7
|
+
name = "AdvancedAnalysisFileParser"
|
|
8
|
+
version = "0.1.2"
|
|
9
|
+
description = "Parse Illumina-DRAGEN TSV/JSON outputs to unified geneyx JSON with warnings."
|
|
10
|
+
authors = [
|
|
11
|
+
{ name="Bar Cohen", email="bar@geneyx.com" }
|
|
12
|
+
]
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.7"
|
|
15
|
+
license = { file = "LICENSE" }
|
|
16
|
+
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent"
|
|
21
|
+
]
|
|
22
|
+
[project.urls]
|
|
23
|
+
homepage = "https://github.com/geneyx/AdvancedAnalysisFileParser"
|
|
24
|
+
repository = "https://github.com/geneyx/AdvancedAnalysisFileParser"
|
|
25
|
+
documentation = "https://geneyx.com/docs"
|
|
26
|
+
[project.scripts]
|
|
27
|
+
advanced-analysis = "AdvancedAnalysisFileParser.AdvancedAnalysisParser:from_cli"
|
|
28
|
+
function-data = "AdvancedAnalysisFileParser.AdvancedAnalysisParser:parse_files"
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from .IWarning import IWarning
|
|
2
|
-
from ..Models import JsonDict, FieldCondition, ConditionOperator
|
|
3
|
-
|
|
4
|
-
class ConditionWarning(IWarning):
|
|
5
|
-
def format(self, config: JsonDict, data: JsonDict) -> str:
|
|
6
|
-
# config["conditions"] is expected to be a list of FieldCondition-like dicts
|
|
7
|
-
msgs = []
|
|
8
|
-
for cond_dict in config.get("conditions", []):
|
|
9
|
-
cond_dict["operator"] = ConditionOperator[cond_dict["operator"]]
|
|
10
|
-
cond = FieldCondition(**cond_dict)
|
|
11
|
-
if isinstance(data, dict):
|
|
12
|
-
if cond_dict.get("field") in data:
|
|
13
|
-
data = data[cond_dict["field"]]
|
|
14
|
-
warning = cond.__str__()
|
|
15
|
-
if warning in msgs:
|
|
16
|
-
continue
|
|
17
|
-
if cond.check(data):
|
|
18
|
-
msgs.append(warning)
|
|
19
|
-
print(f"Warning triggered by condition: {warning}")
|
|
20
|
-
return ". ".join(msgs)
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools>=61.0"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
[project]
|
|
7
|
-
name = "AdvancedAnalysisFileParser"
|
|
8
|
-
version = "0.1.0"
|
|
9
|
-
description = "Parse Illumina-DRAGEN TSV/JSON outputs to unified geneyx JSON with warnings."
|
|
10
|
-
authors = [
|
|
11
|
-
{ name="Bar Cohen", email="bar@geneyx.com" }
|
|
12
|
-
]
|
|
13
|
-
readme = "README.md"
|
|
14
|
-
requires-python = ">=3.7"
|
|
15
|
-
license = { file = "LICENSE" }
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|