gp3tools 0.1.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.
gp3tools/__init__.py ADDED
@@ -0,0 +1,136 @@
1
+ """gp3tools for Python: reproducible Gazepoint GP3 analysis.
2
+
3
+ This initial stable release exposes the complete public function-name surface from the
4
+ R gp3tools v2.3.0 NAMESPACE. Core workflows have native Python implementations;
5
+ backend-specific functions without a validated native implementation use an
6
+ explicit optional R bridge rather than silently changing scientific semantics.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import inspect
12
+ from functools import wraps as _gp3_wraps
13
+
14
+ import pandas as pd
15
+
16
+ from ._compat import make_r_bridge_wrapper
17
+ from ._exports import R_EXPORTS
18
+ from ._rbridge import BackendUnavailableError
19
+ from .datasets import load_example_data, load_example_fixations, load_example_master
20
+
21
+ __version__ = "0.1.0"
22
+
23
+ _MODULE_NAMES = (
24
+ "io",
25
+ "qc",
26
+ "pupil",
27
+ "aoi",
28
+ "events",
29
+ "face",
30
+ "simulation",
31
+ "stats",
32
+ "interop",
33
+ "plotting",
34
+ "reporting",
35
+ "misc",
36
+ )
37
+
38
+ _NATIVE_SOURCE = {}
39
+ for _module_name in _MODULE_NAMES:
40
+ _module = __import__(f"{__name__}.{_module_name}", fromlist=["*"])
41
+ for _name in R_EXPORTS:
42
+ if _name in globals():
43
+ continue
44
+ if hasattr(_module, _name):
45
+ _obj = getattr(_module, _name)
46
+ globals()[_name] = _obj
47
+ _NATIVE_SOURCE[_name] = _module_name
48
+ try:
49
+ _obj._gp3tools_status = "native"
50
+ except Exception:
51
+ pass
52
+
53
+ for _name in R_EXPORTS:
54
+ if _name not in globals():
55
+ globals()[_name] = make_r_bridge_wrapper(_name)
56
+
57
+
58
+ # === VELOCITY PUBLIC DUAL CONTRACT ===
59
+ _gp3_velocity_native = globals()["detect_gazepoint_fixations_velocity"]
60
+
61
+
62
+ @_gp3_wraps(_gp3_velocity_native)
63
+ def _gp3_velocity_public(
64
+ *args,
65
+ **kwargs,
66
+ ):
67
+ result = _gp3_velocity_native(
68
+ *args,
69
+ **kwargs,
70
+ )
71
+
72
+ mode = kwargs.get("return_mode")
73
+
74
+ if mode is None:
75
+ mode = kwargs.get("return")
76
+
77
+ canonical_r4 = kwargs.get("all_gaze") is not None
78
+
79
+ if (
80
+ not canonical_r4
81
+ and mode == "both"
82
+ and isinstance(
83
+ result,
84
+ dict,
85
+ )
86
+ and "_gp3_class" not in result
87
+ ):
88
+ result = dict(result)
89
+
90
+ result["_gp3_class"] = "gp3_velocity_fixation_result"
91
+
92
+ return result
93
+
94
+
95
+ globals()["detect_gazepoint_fixations_velocity"] = _gp3_velocity_public
96
+
97
+
98
+ def api_status() -> pd.DataFrame:
99
+ """Return the frozen R-to-Python API implementation manifest."""
100
+ rows = []
101
+ for name in R_EXPORTS:
102
+ obj = globals()[name]
103
+ module = _NATIVE_SOURCE.get(name, "_compat")
104
+ adapted = {
105
+ "stats": "native-adapted",
106
+ "interop": "native-adapter",
107
+ }
108
+ status = adapted.get(module, "native") if name in _NATIVE_SOURCE else "r-bridge"
109
+ if name in {"classify_gazepoint_events_hmm", "launch_gazepoint_qc_dashboard"}:
110
+ status = "native-adapted"
111
+ try:
112
+ signature = str(inspect.signature(obj))
113
+ except Exception:
114
+ signature = ""
115
+ rows.append(
116
+ {
117
+ "r_export": name,
118
+ "python_name": name,
119
+ "status": status,
120
+ "module": module,
121
+ "signature": signature,
122
+ }
123
+ )
124
+ return pd.DataFrame(rows)
125
+
126
+
127
+ __all__ = [
128
+ *R_EXPORTS,
129
+ "R_EXPORTS",
130
+ "BackendUnavailableError",
131
+ "api_status",
132
+ "load_example_data",
133
+ "load_example_master",
134
+ "load_example_fixations",
135
+ "__version__",
136
+ ]