msdt 1.0.0__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 msdt might be problematic. Click here for more details.

msdt/__init__.py ADDED
@@ -0,0 +1,112 @@
1
+ """msdt - multi-medium DT50 persistence prediction library.
2
+
3
+ Combines the four medium-optimal heteroscedastic models
4
+ (soil / sediment / water_ph7 / water_ph9). Given a DreaMS mass-spectrometry
5
+ embedding (1024-d) it returns:
6
+ - predictive interval (mu +/- 1.96*sigma_latent, log10-days and days)
7
+ - persistence probabilities p(P) / p(vP) (120 d / 180 d thresholds)
8
+ - P / vP decisions made with the best threshold of the chosen scenario
9
+ (``prec`` = precision-oriented 0.7, ``rec`` = recall-oriented 0.7)
10
+
11
+ Usage:
12
+ import msdt
13
+ out = msdt.predict("soil", "prec", dreams_1024d, models_dir="D:/models")
14
+ outs = msdt.predict_batch("water_ph7", "rec", dreams_Nx1024, models_dir="D:/models")
15
+ """
16
+ from __future__ import annotations
17
+
18
+ from typing import Any, Dict, List, Optional, Union
19
+
20
+ import numpy as np
21
+
22
+ from .engine import (
23
+ MEDIUM_CFG,
24
+ MEDIUMS,
25
+ SCENARIOS,
26
+ get_engine,
27
+ validate_scenario,
28
+ _validate_vector,
29
+ )
30
+
31
+ __all__ = ["predict", "predict_batch", "MEDIUMS", "SCENARIOS"]
32
+ __version__ = "1.0.0"
33
+
34
+
35
+ def _single_result(medium: str, scenario: str, r: Dict[str, Any]) -> Dict[str, Any]:
36
+ return {
37
+ "medium": medium,
38
+ "scenario": scenario,
39
+ "mu_log10": float(r["mu_log10"][0]),
40
+ "sigma_latent_log10": float(r["sigma_latent_log10"][0]),
41
+ "interval_log10": [float(r["interval_log10"][0, 0]), float(r["interval_log10"][0, 1])],
42
+ "interval_days": [float(r["interval_days"][0, 0]), float(r["interval_days"][0, 1])],
43
+ "p_P": float(r["p_P"][0]),
44
+ "p_vP": float(r["p_vP"][0]),
45
+ "threshold_P": float(r["threshold_P"]),
46
+ "threshold_vP": float(r["threshold_vP"]),
47
+ "is_P": bool(r["is_P"][0]),
48
+ "is_vP": bool(r["is_vP"][0]),
49
+ }
50
+
51
+
52
+ def predict(
53
+ medium: str,
54
+ scenario: str,
55
+ dreams: Union[np.ndarray, List[float]],
56
+ models_dir: Optional[str] = None,
57
+ ) -> Dict[str, Any]:
58
+ """Predict for a single compound.
59
+
60
+ Args:
61
+ medium: "soil" | "sediment" | "water_ph7" | "water_ph9"
62
+ scenario: "prec" (precision >= 0.7, max recall) | "rec" (recall >= 0.7, max precision)
63
+ dreams: DreaMS embedding, shape (1024,)
64
+ models_dir: optional directory containing {medium}/model_final.pth;
65
+ overrides MSDT_MODELS_DIR
66
+
67
+ Returns:
68
+ dict with predictive interval, p(P)/p(vP), thresholds and P/vP decisions
69
+ """
70
+ medium = str(medium).lower().strip()
71
+ scenario = validate_scenario(scenario)
72
+ x = _validate_vector(dreams, batch=False)
73
+ r = get_engine(medium, models_dir).run(x, scenario)
74
+ return _single_result(medium, scenario, r)
75
+
76
+
77
+ def predict_batch(
78
+ medium: str,
79
+ scenario: str,
80
+ dreams: Union[np.ndarray, List[List[float]]],
81
+ models_dir: Optional[str] = None,
82
+ ) -> Dict[str, Any]:
83
+ """Predict for a batch of compounds.
84
+
85
+ Args:
86
+ medium: "soil" | "sediment" | "water_ph7" | "water_ph9"
87
+ scenario: "prec" | "rec"
88
+ dreams: DreaMS embedding matrix, shape (N, 1024)
89
+ models_dir: optional directory containing {medium}/model_final.pth
90
+
91
+ Returns:
92
+ dict; scalar fields become arrays of length N (interval_* are (N, 2))
93
+ """
94
+ medium = str(medium).lower().strip()
95
+ scenario = validate_scenario(scenario)
96
+ x = _validate_vector(dreams, batch=True)
97
+ r = get_engine(medium, models_dir).run(x, scenario)
98
+ return {
99
+ "medium": medium,
100
+ "scenario": scenario,
101
+ "n": int(len(x)),
102
+ "mu_log10": r["mu_log10"],
103
+ "sigma_latent_log10": r["sigma_latent_log10"],
104
+ "interval_log10": r["interval_log10"],
105
+ "interval_days": r["interval_days"],
106
+ "p_P": r["p_P"],
107
+ "p_vP": r["p_vP"],
108
+ "threshold_P": float(r["threshold_P"]),
109
+ "threshold_vP": float(r["threshold_vP"]),
110
+ "is_P": r["is_P"],
111
+ "is_vP": r["is_vP"],
112
+ }