masster 0.2.5__py3-none-any.whl → 0.3.1__py3-none-any.whl
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.
Potentially problematic release.
This version of masster might be problematic. Click here for more details.
- masster/__init__.py +27 -27
- masster/_version.py +17 -17
- masster/chromatogram.py +497 -503
- masster/data/examples/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.featureXML +199787 -0
- masster/data/examples/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.sample5 +0 -0
- masster/logger.py +318 -244
- masster/sample/__init__.py +9 -9
- masster/sample/defaults/__init__.py +15 -15
- masster/sample/defaults/find_adducts_def.py +325 -325
- masster/sample/defaults/find_features_def.py +366 -366
- masster/sample/defaults/find_ms2_def.py +285 -285
- masster/sample/defaults/get_spectrum_def.py +314 -318
- masster/sample/defaults/sample_def.py +374 -378
- masster/sample/h5.py +1321 -1297
- masster/sample/helpers.py +833 -364
- masster/sample/lib.py +762 -0
- masster/sample/load.py +1220 -1187
- masster/sample/parameters.py +131 -131
- masster/sample/plot.py +1685 -1622
- masster/sample/processing.py +1402 -1416
- masster/sample/quant.py +209 -0
- masster/sample/sample.py +393 -387
- masster/sample/sample5_schema.json +181 -181
- masster/sample/save.py +737 -736
- masster/sample/sciex.py +1213 -0
- masster/spectrum.py +1287 -1319
- masster/study/__init__.py +9 -9
- masster/study/defaults/__init__.py +21 -19
- masster/study/defaults/align_def.py +267 -267
- masster/study/defaults/export_def.py +41 -40
- masster/study/defaults/fill_chrom_def.py +264 -264
- masster/study/defaults/fill_def.py +260 -0
- masster/study/defaults/find_consensus_def.py +256 -256
- masster/study/defaults/find_ms2_def.py +163 -163
- masster/study/defaults/integrate_chrom_def.py +225 -225
- masster/study/defaults/integrate_def.py +221 -0
- masster/study/defaults/merge_def.py +256 -0
- masster/study/defaults/study_def.py +272 -269
- masster/study/export.py +674 -287
- masster/study/h5.py +1406 -886
- masster/study/helpers.py +1713 -433
- masster/study/helpers_optimized.py +317 -0
- masster/study/load.py +1231 -1078
- masster/study/parameters.py +99 -99
- masster/study/plot.py +632 -645
- masster/study/processing.py +1057 -1046
- masster/study/save.py +161 -134
- masster/study/study.py +612 -522
- masster/study/study5_schema.json +253 -241
- {masster-0.2.5.dist-info → masster-0.3.1.dist-info}/METADATA +15 -10
- masster-0.3.1.dist-info/RECORD +59 -0
- {masster-0.2.5.dist-info → masster-0.3.1.dist-info}/licenses/LICENSE +661 -661
- masster-0.2.5.dist-info/RECORD +0 -50
- {masster-0.2.5.dist-info → masster-0.3.1.dist-info}/WHEEL +0 -0
- {masster-0.2.5.dist-info → masster-0.3.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,325 +1,325 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Find Adducts Parameters Module
|
|
3
|
-
|
|
4
|
-
This module defines parameters for adduct detection in mass spectrometry data.
|
|
5
|
-
It consolidates all parameters used in the find_adducts() method with type checking,
|
|
6
|
-
validation, and comprehensive descriptions.
|
|
7
|
-
|
|
8
|
-
Classes:
|
|
9
|
-
find_adducts_defaults: Configuration parameters for the find_adducts() method.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
from __future__ import annotations
|
|
13
|
-
|
|
14
|
-
from dataclasses import dataclass, field
|
|
15
|
-
from typing import Any
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@dataclass
|
|
19
|
-
class find_adducts_defaults:
|
|
20
|
-
"""
|
|
21
|
-
Parameters for mass spectrometry adduct detection using OpenMS MetaboliteFeatureDeconvolution.
|
|
22
|
-
|
|
23
|
-
This class consolidates all parameters used in the find_adducts() method including
|
|
24
|
-
potential adducts, charge constraints, and retention time tolerances.
|
|
25
|
-
It provides type checking, validation, and comprehensive parameter descriptions.
|
|
26
|
-
|
|
27
|
-
Adduct Detection Parameters:
|
|
28
|
-
adducts: List of potential adducts or ionization mode string.
|
|
29
|
-
charge_min: Minimal possible charge state.
|
|
30
|
-
charge_max: Maximal possible charge state.
|
|
31
|
-
charge_span_max: Maximum span between different charge states.
|
|
32
|
-
retention_max_diff: Maximum retention time difference for adduct grouping.
|
|
33
|
-
retention_max_diff_local: Maximum local retention time difference.
|
|
34
|
-
|
|
35
|
-
Available Methods:
|
|
36
|
-
- validate(param_name, value): Validate a single parameter value
|
|
37
|
-
- validate_all(): Validate all parameters at once
|
|
38
|
-
- to_dict(): Convert parameters to dictionary
|
|
39
|
-
- set_from_dict(param_dict, validate=True): Update multiple parameters from dict
|
|
40
|
-
- set(param_name, value, validate=True): Set parameter value with validation
|
|
41
|
-
- get(param_name): Get parameter value
|
|
42
|
-
- get_description(param_name): Get parameter description
|
|
43
|
-
- get_info(param_name): Get full parameter metadata
|
|
44
|
-
- list_parameters(): Get list of all parameter names
|
|
45
|
-
- get_openms_adducts(): Get processed adducts list for OpenMS
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
# Adduct specification
|
|
49
|
-
adducts: list[str] | str | None = None
|
|
50
|
-
|
|
51
|
-
# Charge constraints
|
|
52
|
-
charge_min: int = 1
|
|
53
|
-
charge_max: int = 2
|
|
54
|
-
charge_span_max: int = 2
|
|
55
|
-
|
|
56
|
-
# Retention time constraints
|
|
57
|
-
retention_max_diff: float = 1.0
|
|
58
|
-
retention_max_diff_local: float = 1.0
|
|
59
|
-
|
|
60
|
-
# Parameter metadata for validation and description
|
|
61
|
-
_param_metadata: dict[str, dict[str, Any]] = field(
|
|
62
|
-
default_factory=lambda: {
|
|
63
|
-
"adducts": {
|
|
64
|
-
"dtype": "Union[List[str], str, None]",
|
|
65
|
-
"description": "List of potential adducts or ionization mode ('pos', 'neg', 'positive', 'negative')",
|
|
66
|
-
"allowed_values": ["pos", "neg", "positive", "negative"],
|
|
67
|
-
},
|
|
68
|
-
"charge_min": {
|
|
69
|
-
"dtype": int,
|
|
70
|
-
"description": "Minimal possible charge state for adduct detection",
|
|
71
|
-
"min_value": 1,
|
|
72
|
-
"max_value": 10,
|
|
73
|
-
},
|
|
74
|
-
"charge_max": {
|
|
75
|
-
"dtype": int,
|
|
76
|
-
"description": "Maximal possible charge state for adduct detection",
|
|
77
|
-
"min_value": 1,
|
|
78
|
-
"max_value": 10,
|
|
79
|
-
},
|
|
80
|
-
"charge_span_max": {
|
|
81
|
-
"dtype": int,
|
|
82
|
-
"description": "Maximum span between different charge states in the same adduct group",
|
|
83
|
-
"min_value": 1,
|
|
84
|
-
"max_value": 5,
|
|
85
|
-
},
|
|
86
|
-
"retention_max_diff": {
|
|
87
|
-
"dtype": float,
|
|
88
|
-
"description": "Maximum retention time difference (in minutes) for global adduct grouping",
|
|
89
|
-
"min_value": 0.1,
|
|
90
|
-
"max_value": 10.0,
|
|
91
|
-
},
|
|
92
|
-
"retention_max_diff_local": {
|
|
93
|
-
"dtype": float,
|
|
94
|
-
"description": "Maximum local retention time difference (in minutes) for adduct grouping",
|
|
95
|
-
"min_value": 0.1,
|
|
96
|
-
"max_value": 10.0,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
def get_info(self, param_name: str) -> dict[str, Any]:
|
|
102
|
-
"""
|
|
103
|
-
Get information about a specific parameter.
|
|
104
|
-
|
|
105
|
-
Args:
|
|
106
|
-
param_name: Name of the parameter
|
|
107
|
-
|
|
108
|
-
Returns:
|
|
109
|
-
Dictionary containing parameter metadata
|
|
110
|
-
|
|
111
|
-
Raises:
|
|
112
|
-
KeyError: If parameter name is not found
|
|
113
|
-
"""
|
|
114
|
-
if param_name not in self._param_metadata:
|
|
115
|
-
raise KeyError(f"Parameter '{param_name}' not found")
|
|
116
|
-
return self._param_metadata[param_name]
|
|
117
|
-
|
|
118
|
-
def get_description(self, param_name: str) -> str:
|
|
119
|
-
"""
|
|
120
|
-
Get description for a specific parameter.
|
|
121
|
-
|
|
122
|
-
Args:
|
|
123
|
-
param_name: Name of the parameter
|
|
124
|
-
|
|
125
|
-
Returns:
|
|
126
|
-
Parameter description string
|
|
127
|
-
"""
|
|
128
|
-
return str(self.get_info(param_name)["description"])
|
|
129
|
-
|
|
130
|
-
def validate(self, param_name: str, value: Any) -> bool:
|
|
131
|
-
"""
|
|
132
|
-
Validate a parameter value against its constraints.
|
|
133
|
-
|
|
134
|
-
Args:
|
|
135
|
-
param_name: Name of the parameter
|
|
136
|
-
value: Value to validate
|
|
137
|
-
|
|
138
|
-
Returns:
|
|
139
|
-
True if value is valid, False otherwise
|
|
140
|
-
"""
|
|
141
|
-
if param_name not in self._param_metadata:
|
|
142
|
-
return False
|
|
143
|
-
|
|
144
|
-
metadata = self._param_metadata[param_name]
|
|
145
|
-
expected_dtype = metadata["dtype"]
|
|
146
|
-
|
|
147
|
-
# Handle Union types for adducts parameter
|
|
148
|
-
if param_name == "adducts":
|
|
149
|
-
if value is None:
|
|
150
|
-
return True
|
|
151
|
-
if isinstance(value, str):
|
|
152
|
-
# Check if it's a valid ionization mode
|
|
153
|
-
allowed_values = metadata.get("allowed_values", [])
|
|
154
|
-
return value in allowed_values
|
|
155
|
-
elif isinstance(value, list):
|
|
156
|
-
# Check if all elements are strings
|
|
157
|
-
return all(isinstance(item, str) for item in value)
|
|
158
|
-
else:
|
|
159
|
-
return False
|
|
160
|
-
|
|
161
|
-
# Type checking for non-Union types
|
|
162
|
-
if expected_dtype is int:
|
|
163
|
-
if not isinstance(value, int):
|
|
164
|
-
try:
|
|
165
|
-
value = int(value)
|
|
166
|
-
except (ValueError, TypeError):
|
|
167
|
-
return False
|
|
168
|
-
elif expected_dtype is float:
|
|
169
|
-
if not isinstance(value, (int, float)):
|
|
170
|
-
try:
|
|
171
|
-
value = float(value)
|
|
172
|
-
except (ValueError, TypeError):
|
|
173
|
-
return False
|
|
174
|
-
|
|
175
|
-
# Range validation for numeric types
|
|
176
|
-
if expected_dtype in (int, float):
|
|
177
|
-
if "min_value" in metadata and value < metadata["min_value"]:
|
|
178
|
-
return False
|
|
179
|
-
if "max_value" in metadata and value > metadata["max_value"]:
|
|
180
|
-
return False
|
|
181
|
-
|
|
182
|
-
return True
|
|
183
|
-
|
|
184
|
-
def set(self, param_name: str, value: Any, validate: bool = True) -> bool:
|
|
185
|
-
"""
|
|
186
|
-
Set a parameter value with optional validation.
|
|
187
|
-
|
|
188
|
-
Args:
|
|
189
|
-
param_name: Name of the parameter
|
|
190
|
-
value: New value for the parameter
|
|
191
|
-
validate: Whether to validate the value before setting
|
|
192
|
-
|
|
193
|
-
Returns:
|
|
194
|
-
True if parameter was set successfully, False otherwise
|
|
195
|
-
"""
|
|
196
|
-
if not hasattr(self, param_name):
|
|
197
|
-
return False
|
|
198
|
-
|
|
199
|
-
if validate and not self.validate(param_name, value):
|
|
200
|
-
return False
|
|
201
|
-
|
|
202
|
-
# Convert to expected type if needed
|
|
203
|
-
if param_name in self._param_metadata:
|
|
204
|
-
expected_dtype = self._param_metadata[param_name]["dtype"]
|
|
205
|
-
if expected_dtype is int and not isinstance(value, int):
|
|
206
|
-
try:
|
|
207
|
-
value = int(value)
|
|
208
|
-
except (ValueError, TypeError):
|
|
209
|
-
if validate:
|
|
210
|
-
return False
|
|
211
|
-
elif expected_dtype is float and not isinstance(value, float):
|
|
212
|
-
try:
|
|
213
|
-
value = float(value)
|
|
214
|
-
except (ValueError, TypeError):
|
|
215
|
-
if validate:
|
|
216
|
-
return False
|
|
217
|
-
|
|
218
|
-
setattr(self, param_name, value)
|
|
219
|
-
|
|
220
|
-
# Trigger dynamic calculation if this is the adducts parameter
|
|
221
|
-
if param_name == "adducts":
|
|
222
|
-
self._update_openms_adducts()
|
|
223
|
-
|
|
224
|
-
return True
|
|
225
|
-
|
|
226
|
-
def get(self, param_name: str) -> Any:
|
|
227
|
-
"""
|
|
228
|
-
Get the value of a parameter by name.
|
|
229
|
-
|
|
230
|
-
Args:
|
|
231
|
-
param_name: Name of the parameter
|
|
232
|
-
|
|
233
|
-
Returns:
|
|
234
|
-
Current value of the parameter
|
|
235
|
-
"""
|
|
236
|
-
if not hasattr(self, param_name):
|
|
237
|
-
raise KeyError(f"Parameter '{param_name}' not found")
|
|
238
|
-
return getattr(self, param_name)
|
|
239
|
-
|
|
240
|
-
def set_from_dict(
|
|
241
|
-
self,
|
|
242
|
-
param_dict: dict[str, Any],
|
|
243
|
-
validate: bool = True,
|
|
244
|
-
) -> list[str]:
|
|
245
|
-
"""
|
|
246
|
-
Update multiple parameters from a dictionary.
|
|
247
|
-
|
|
248
|
-
Args:
|
|
249
|
-
param_dict: Dictionary of parameter names and values
|
|
250
|
-
validate: Whether to validate values before setting
|
|
251
|
-
|
|
252
|
-
Returns:
|
|
253
|
-
List of parameter names that could not be set
|
|
254
|
-
"""
|
|
255
|
-
failed_params = []
|
|
256
|
-
|
|
257
|
-
for param_name, value in param_dict.items():
|
|
258
|
-
if not self.set(param_name, value, validate):
|
|
259
|
-
failed_params.append(param_name)
|
|
260
|
-
|
|
261
|
-
return failed_params
|
|
262
|
-
|
|
263
|
-
def to_dict(self) -> dict[str, Any]:
|
|
264
|
-
"""
|
|
265
|
-
Convert parameters to dictionary, excluding metadata.
|
|
266
|
-
|
|
267
|
-
Returns:
|
|
268
|
-
Dictionary of parameter names and values
|
|
269
|
-
"""
|
|
270
|
-
return {k: v for k, v in self.__dict__.items() if not k.startswith("_")}
|
|
271
|
-
|
|
272
|
-
def list_parameters(self) -> list[str]:
|
|
273
|
-
"""
|
|
274
|
-
Get list of all parameter names.
|
|
275
|
-
|
|
276
|
-
Returns:
|
|
277
|
-
List of parameter names
|
|
278
|
-
"""
|
|
279
|
-
return [k for k in self.__dict__.keys() if not k.startswith("_")]
|
|
280
|
-
|
|
281
|
-
def validate_all(self) -> tuple[bool, list[str]]:
|
|
282
|
-
"""
|
|
283
|
-
Validate all parameters in the instance.
|
|
284
|
-
|
|
285
|
-
Returns:
|
|
286
|
-
Tuple of (all_valid, list_of_invalid_params)
|
|
287
|
-
- all_valid: True if all parameters are valid, False otherwise
|
|
288
|
-
- list_of_invalid_params: List of parameter names that failed validation
|
|
289
|
-
"""
|
|
290
|
-
invalid_params = []
|
|
291
|
-
|
|
292
|
-
for param_name in self.list_parameters():
|
|
293
|
-
if param_name in self._param_metadata:
|
|
294
|
-
current_value = getattr(self, param_name)
|
|
295
|
-
if not self.validate(param_name, current_value):
|
|
296
|
-
invalid_params.append(param_name)
|
|
297
|
-
|
|
298
|
-
return len(invalid_params) == 0, invalid_params
|
|
299
|
-
|
|
300
|
-
def _update_openms_adducts(self) -> None:
|
|
301
|
-
"""
|
|
302
|
-
Update the internal OpenMS adducts list when adducts parameter changes.
|
|
303
|
-
This is called automatically when the adducts parameter is set.
|
|
304
|
-
"""
|
|
305
|
-
# This will update the internal state that get_openms_adducts() uses
|
|
306
|
-
pass
|
|
307
|
-
|
|
308
|
-
def get_openms_adducts(self) -> list[str]:
|
|
309
|
-
"""
|
|
310
|
-
Get the processed adducts list for OpenMS MetaboliteFeatureDeconvolution.
|
|
311
|
-
|
|
312
|
-
Returns:
|
|
313
|
-
List of adduct strings formatted for OpenMS
|
|
314
|
-
"""
|
|
315
|
-
adducts = self.adducts
|
|
316
|
-
|
|
317
|
-
if adducts is None or adducts in ["pos", "positive"]:
|
|
318
|
-
return ["H:+:0.4", "Na:+:0.3", "NH4:+:0.3"]
|
|
319
|
-
elif adducts in ["neg", "negative"]:
|
|
320
|
-
return ["H-1:-:1", "CH2O2:0:0.5"]
|
|
321
|
-
elif isinstance(adducts, list):
|
|
322
|
-
return adducts
|
|
323
|
-
else:
|
|
324
|
-
# Fallback to positive mode if unexpected format
|
|
325
|
-
return ["H:+:0.4", "Na:+:0.3", "NH4:+:0.3"]
|
|
1
|
+
"""
|
|
2
|
+
Find Adducts Parameters Module
|
|
3
|
+
|
|
4
|
+
This module defines parameters for adduct detection in mass spectrometry data.
|
|
5
|
+
It consolidates all parameters used in the find_adducts() method with type checking,
|
|
6
|
+
validation, and comprehensive descriptions.
|
|
7
|
+
|
|
8
|
+
Classes:
|
|
9
|
+
find_adducts_defaults: Configuration parameters for the find_adducts() method.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from dataclasses import dataclass, field
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class find_adducts_defaults:
|
|
20
|
+
"""
|
|
21
|
+
Parameters for mass spectrometry adduct detection using OpenMS MetaboliteFeatureDeconvolution.
|
|
22
|
+
|
|
23
|
+
This class consolidates all parameters used in the find_adducts() method including
|
|
24
|
+
potential adducts, charge constraints, and retention time tolerances.
|
|
25
|
+
It provides type checking, validation, and comprehensive parameter descriptions.
|
|
26
|
+
|
|
27
|
+
Adduct Detection Parameters:
|
|
28
|
+
adducts: List of potential adducts or ionization mode string.
|
|
29
|
+
charge_min: Minimal possible charge state.
|
|
30
|
+
charge_max: Maximal possible charge state.
|
|
31
|
+
charge_span_max: Maximum span between different charge states.
|
|
32
|
+
retention_max_diff: Maximum retention time difference for adduct grouping.
|
|
33
|
+
retention_max_diff_local: Maximum local retention time difference.
|
|
34
|
+
|
|
35
|
+
Available Methods:
|
|
36
|
+
- validate(param_name, value): Validate a single parameter value
|
|
37
|
+
- validate_all(): Validate all parameters at once
|
|
38
|
+
- to_dict(): Convert parameters to dictionary
|
|
39
|
+
- set_from_dict(param_dict, validate=True): Update multiple parameters from dict
|
|
40
|
+
- set(param_name, value, validate=True): Set parameter value with validation
|
|
41
|
+
- get(param_name): Get parameter value
|
|
42
|
+
- get_description(param_name): Get parameter description
|
|
43
|
+
- get_info(param_name): Get full parameter metadata
|
|
44
|
+
- list_parameters(): Get list of all parameter names
|
|
45
|
+
- get_openms_adducts(): Get processed adducts list for OpenMS
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
# Adduct specification
|
|
49
|
+
adducts: list[str] | str | None = None
|
|
50
|
+
|
|
51
|
+
# Charge constraints
|
|
52
|
+
charge_min: int = 1
|
|
53
|
+
charge_max: int = 2
|
|
54
|
+
charge_span_max: int = 2
|
|
55
|
+
|
|
56
|
+
# Retention time constraints
|
|
57
|
+
retention_max_diff: float = 1.0
|
|
58
|
+
retention_max_diff_local: float = 1.0
|
|
59
|
+
|
|
60
|
+
# Parameter metadata for validation and description
|
|
61
|
+
_param_metadata: dict[str, dict[str, Any]] = field(
|
|
62
|
+
default_factory=lambda: {
|
|
63
|
+
"adducts": {
|
|
64
|
+
"dtype": "Union[List[str], str, None]",
|
|
65
|
+
"description": "List of potential adducts or ionization mode ('pos', 'neg', 'positive', 'negative')",
|
|
66
|
+
"allowed_values": ["pos", "neg", "positive", "negative"],
|
|
67
|
+
},
|
|
68
|
+
"charge_min": {
|
|
69
|
+
"dtype": int,
|
|
70
|
+
"description": "Minimal possible charge state for adduct detection",
|
|
71
|
+
"min_value": 1,
|
|
72
|
+
"max_value": 10,
|
|
73
|
+
},
|
|
74
|
+
"charge_max": {
|
|
75
|
+
"dtype": int,
|
|
76
|
+
"description": "Maximal possible charge state for adduct detection",
|
|
77
|
+
"min_value": 1,
|
|
78
|
+
"max_value": 10,
|
|
79
|
+
},
|
|
80
|
+
"charge_span_max": {
|
|
81
|
+
"dtype": int,
|
|
82
|
+
"description": "Maximum span between different charge states in the same adduct group",
|
|
83
|
+
"min_value": 1,
|
|
84
|
+
"max_value": 5,
|
|
85
|
+
},
|
|
86
|
+
"retention_max_diff": {
|
|
87
|
+
"dtype": float,
|
|
88
|
+
"description": "Maximum retention time difference (in minutes) for global adduct grouping",
|
|
89
|
+
"min_value": 0.1,
|
|
90
|
+
"max_value": 10.0,
|
|
91
|
+
},
|
|
92
|
+
"retention_max_diff_local": {
|
|
93
|
+
"dtype": float,
|
|
94
|
+
"description": "Maximum local retention time difference (in minutes) for adduct grouping",
|
|
95
|
+
"min_value": 0.1,
|
|
96
|
+
"max_value": 10.0,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def get_info(self, param_name: str) -> dict[str, Any]:
|
|
102
|
+
"""
|
|
103
|
+
Get information about a specific parameter.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
param_name: Name of the parameter
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
Dictionary containing parameter metadata
|
|
110
|
+
|
|
111
|
+
Raises:
|
|
112
|
+
KeyError: If parameter name is not found
|
|
113
|
+
"""
|
|
114
|
+
if param_name not in self._param_metadata:
|
|
115
|
+
raise KeyError(f"Parameter '{param_name}' not found")
|
|
116
|
+
return self._param_metadata[param_name]
|
|
117
|
+
|
|
118
|
+
def get_description(self, param_name: str) -> str:
|
|
119
|
+
"""
|
|
120
|
+
Get description for a specific parameter.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
param_name: Name of the parameter
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Parameter description string
|
|
127
|
+
"""
|
|
128
|
+
return str(self.get_info(param_name)["description"])
|
|
129
|
+
|
|
130
|
+
def validate(self, param_name: str, value: Any) -> bool:
|
|
131
|
+
"""
|
|
132
|
+
Validate a parameter value against its constraints.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
param_name: Name of the parameter
|
|
136
|
+
value: Value to validate
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
True if value is valid, False otherwise
|
|
140
|
+
"""
|
|
141
|
+
if param_name not in self._param_metadata:
|
|
142
|
+
return False
|
|
143
|
+
|
|
144
|
+
metadata = self._param_metadata[param_name]
|
|
145
|
+
expected_dtype = metadata["dtype"]
|
|
146
|
+
|
|
147
|
+
# Handle Union types for adducts parameter
|
|
148
|
+
if param_name == "adducts":
|
|
149
|
+
if value is None:
|
|
150
|
+
return True
|
|
151
|
+
if isinstance(value, str):
|
|
152
|
+
# Check if it's a valid ionization mode
|
|
153
|
+
allowed_values = metadata.get("allowed_values", [])
|
|
154
|
+
return value in allowed_values
|
|
155
|
+
elif isinstance(value, list):
|
|
156
|
+
# Check if all elements are strings
|
|
157
|
+
return all(isinstance(item, str) for item in value)
|
|
158
|
+
else:
|
|
159
|
+
return False
|
|
160
|
+
|
|
161
|
+
# Type checking for non-Union types
|
|
162
|
+
if expected_dtype is int:
|
|
163
|
+
if not isinstance(value, int):
|
|
164
|
+
try:
|
|
165
|
+
value = int(value)
|
|
166
|
+
except (ValueError, TypeError):
|
|
167
|
+
return False
|
|
168
|
+
elif expected_dtype is float:
|
|
169
|
+
if not isinstance(value, (int, float)):
|
|
170
|
+
try:
|
|
171
|
+
value = float(value)
|
|
172
|
+
except (ValueError, TypeError):
|
|
173
|
+
return False
|
|
174
|
+
|
|
175
|
+
# Range validation for numeric types
|
|
176
|
+
if expected_dtype in (int, float):
|
|
177
|
+
if "min_value" in metadata and value < metadata["min_value"]:
|
|
178
|
+
return False
|
|
179
|
+
if "max_value" in metadata and value > metadata["max_value"]:
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
return True
|
|
183
|
+
|
|
184
|
+
def set(self, param_name: str, value: Any, validate: bool = True) -> bool:
|
|
185
|
+
"""
|
|
186
|
+
Set a parameter value with optional validation.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
param_name: Name of the parameter
|
|
190
|
+
value: New value for the parameter
|
|
191
|
+
validate: Whether to validate the value before setting
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
True if parameter was set successfully, False otherwise
|
|
195
|
+
"""
|
|
196
|
+
if not hasattr(self, param_name):
|
|
197
|
+
return False
|
|
198
|
+
|
|
199
|
+
if validate and not self.validate(param_name, value):
|
|
200
|
+
return False
|
|
201
|
+
|
|
202
|
+
# Convert to expected type if needed
|
|
203
|
+
if param_name in self._param_metadata:
|
|
204
|
+
expected_dtype = self._param_metadata[param_name]["dtype"]
|
|
205
|
+
if expected_dtype is int and not isinstance(value, int):
|
|
206
|
+
try:
|
|
207
|
+
value = int(value)
|
|
208
|
+
except (ValueError, TypeError):
|
|
209
|
+
if validate:
|
|
210
|
+
return False
|
|
211
|
+
elif expected_dtype is float and not isinstance(value, float):
|
|
212
|
+
try:
|
|
213
|
+
value = float(value)
|
|
214
|
+
except (ValueError, TypeError):
|
|
215
|
+
if validate:
|
|
216
|
+
return False
|
|
217
|
+
|
|
218
|
+
setattr(self, param_name, value)
|
|
219
|
+
|
|
220
|
+
# Trigger dynamic calculation if this is the adducts parameter
|
|
221
|
+
if param_name == "adducts":
|
|
222
|
+
self._update_openms_adducts()
|
|
223
|
+
|
|
224
|
+
return True
|
|
225
|
+
|
|
226
|
+
def get(self, param_name: str) -> Any:
|
|
227
|
+
"""
|
|
228
|
+
Get the value of a parameter by name.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
param_name: Name of the parameter
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
Current value of the parameter
|
|
235
|
+
"""
|
|
236
|
+
if not hasattr(self, param_name):
|
|
237
|
+
raise KeyError(f"Parameter '{param_name}' not found")
|
|
238
|
+
return getattr(self, param_name)
|
|
239
|
+
|
|
240
|
+
def set_from_dict(
|
|
241
|
+
self,
|
|
242
|
+
param_dict: dict[str, Any],
|
|
243
|
+
validate: bool = True,
|
|
244
|
+
) -> list[str]:
|
|
245
|
+
"""
|
|
246
|
+
Update multiple parameters from a dictionary.
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
param_dict: Dictionary of parameter names and values
|
|
250
|
+
validate: Whether to validate values before setting
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
List of parameter names that could not be set
|
|
254
|
+
"""
|
|
255
|
+
failed_params = []
|
|
256
|
+
|
|
257
|
+
for param_name, value in param_dict.items():
|
|
258
|
+
if not self.set(param_name, value, validate):
|
|
259
|
+
failed_params.append(param_name)
|
|
260
|
+
|
|
261
|
+
return failed_params
|
|
262
|
+
|
|
263
|
+
def to_dict(self) -> dict[str, Any]:
|
|
264
|
+
"""
|
|
265
|
+
Convert parameters to dictionary, excluding metadata.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
Dictionary of parameter names and values
|
|
269
|
+
"""
|
|
270
|
+
return {k: v for k, v in self.__dict__.items() if not k.startswith("_")}
|
|
271
|
+
|
|
272
|
+
def list_parameters(self) -> list[str]:
|
|
273
|
+
"""
|
|
274
|
+
Get list of all parameter names.
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
List of parameter names
|
|
278
|
+
"""
|
|
279
|
+
return [k for k in self.__dict__.keys() if not k.startswith("_")]
|
|
280
|
+
|
|
281
|
+
def validate_all(self) -> tuple[bool, list[str]]:
|
|
282
|
+
"""
|
|
283
|
+
Validate all parameters in the instance.
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
Tuple of (all_valid, list_of_invalid_params)
|
|
287
|
+
- all_valid: True if all parameters are valid, False otherwise
|
|
288
|
+
- list_of_invalid_params: List of parameter names that failed validation
|
|
289
|
+
"""
|
|
290
|
+
invalid_params = []
|
|
291
|
+
|
|
292
|
+
for param_name in self.list_parameters():
|
|
293
|
+
if param_name in self._param_metadata:
|
|
294
|
+
current_value = getattr(self, param_name)
|
|
295
|
+
if not self.validate(param_name, current_value):
|
|
296
|
+
invalid_params.append(param_name)
|
|
297
|
+
|
|
298
|
+
return len(invalid_params) == 0, invalid_params
|
|
299
|
+
|
|
300
|
+
def _update_openms_adducts(self) -> None:
|
|
301
|
+
"""
|
|
302
|
+
Update the internal OpenMS adducts list when adducts parameter changes.
|
|
303
|
+
This is called automatically when the adducts parameter is set.
|
|
304
|
+
"""
|
|
305
|
+
# This will update the internal state that get_openms_adducts() uses
|
|
306
|
+
pass
|
|
307
|
+
|
|
308
|
+
def get_openms_adducts(self) -> list[str]:
|
|
309
|
+
"""
|
|
310
|
+
Get the processed adducts list for OpenMS MetaboliteFeatureDeconvolution.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
List of adduct strings formatted for OpenMS
|
|
314
|
+
"""
|
|
315
|
+
adducts = self.adducts
|
|
316
|
+
|
|
317
|
+
if adducts is None or adducts in ["pos", "positive"]:
|
|
318
|
+
return ["H:+:0.4", "Na:+:0.3", "NH4:+:0.3"]
|
|
319
|
+
elif adducts in ["neg", "negative"]:
|
|
320
|
+
return ["H-1:-:1", "CH2O2:0:0.5"]
|
|
321
|
+
elif isinstance(adducts, list):
|
|
322
|
+
return adducts
|
|
323
|
+
else:
|
|
324
|
+
# Fallback to positive mode if unexpected format
|
|
325
|
+
return ["H:+:0.4", "Na:+:0.3", "NH4:+:0.3"]
|