PyVisualFields 2.0.5__py3-none-any.whl → 2.0.7__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.
- PyVisualFields/Deviation_Analysis.py +118 -12
- PyVisualFields/PyGlaucoMetrics.py +25 -6
- PyVisualFields/__init__.py +1 -1
- PyVisualFields/utils.py +29 -1
- {pyvisualfields-2.0.5.dist-info → pyvisualfields-2.0.7.dist-info}/METADATA +1 -1
- {pyvisualfields-2.0.5.dist-info → pyvisualfields-2.0.7.dist-info}/RECORD +9 -9
- {pyvisualfields-2.0.5.dist-info → pyvisualfields-2.0.7.dist-info}/WHEEL +0 -0
- {pyvisualfields-2.0.5.dist-info → pyvisualfields-2.0.7.dist-info}/licenses/LICENSE +0 -0
- {pyvisualfields-2.0.5.dist-info → pyvisualfields-2.0.7.dist-info}/top_level.txt +0 -0
|
@@ -803,19 +803,111 @@ def py_getgl(df_vf: pd.DataFrame) -> pd.DataFrame:
|
|
|
803
803
|
|
|
804
804
|
# return df_gp
|
|
805
805
|
|
|
806
|
+
# def py_getglp(df_gi: pd.DataFrame) -> pd.DataFrame:
|
|
807
|
+
# """Global indices probability values."""
|
|
808
|
+
|
|
809
|
+
# nv = _nv()
|
|
810
|
+
# lut_dict = nv["glp_lut"]
|
|
811
|
+
# probs = nv["glp_probs"]
|
|
812
|
+
# idxm_0 = [i - 1 for i in (nv["glp_idxm"] or [])]
|
|
813
|
+
# idxs_0 = [i - 1 for i in (nv["glp_idxs"] or [])]
|
|
814
|
+
|
|
815
|
+
# gl_cols = ["msens", "ssens", "tmd", "tsd", "pmd", "psd", "gh", "vfi"]
|
|
816
|
+
|
|
817
|
+
# mean_cols = [gl_cols[i] for i in idxm_0 if i < len(gl_cols)]
|
|
818
|
+
# std_cols = [gl_cols[i] for i in idxs_0 if i < len(gl_cols)]
|
|
819
|
+
|
|
820
|
+
# n_probs = len(probs)
|
|
821
|
+
|
|
822
|
+
# prob_vals = np.array([
|
|
823
|
+
# _parse_lut_value(p) if isinstance(p, str) else float(p)
|
|
824
|
+
# for p in probs
|
|
825
|
+
# ])
|
|
826
|
+
|
|
827
|
+
# df_gp = df_gi.copy()
|
|
828
|
+
|
|
829
|
+
# def _prob_col_name(col):
|
|
830
|
+
# return f"{col}prob"
|
|
831
|
+
|
|
832
|
+
# def _build_col_lut(col):
|
|
833
|
+
# raw = lut_dict.get(col, [np.nan] * n_probs)
|
|
834
|
+
# return np.array([
|
|
835
|
+
# _parse_lut_value(v) if isinstance(v, str) else float(v)
|
|
836
|
+
# for v in raw
|
|
837
|
+
# ])
|
|
838
|
+
|
|
839
|
+
# # Left-tailed: lower values are abnormal
|
|
840
|
+
# for col in mean_cols:
|
|
841
|
+
# if col not in df_gi.columns:
|
|
842
|
+
# continue
|
|
843
|
+
|
|
844
|
+
# cutoffs = _build_col_lut(col)
|
|
845
|
+
# vals = df_gi[col].values.astype(float)
|
|
846
|
+
# vp = np.full(len(vals), np.nan)
|
|
847
|
+
|
|
848
|
+
# for i in range(n_probs - 1, 0, -1):
|
|
849
|
+
# vp[vals < cutoffs[i]] = prob_vals[i]
|
|
850
|
+
|
|
851
|
+
# df_gp[_prob_col_name(col)] = vp
|
|
852
|
+
|
|
853
|
+
# # Right-tailed: higher values are abnormal
|
|
854
|
+
# for col in std_cols:
|
|
855
|
+
# if col not in df_gi.columns:
|
|
856
|
+
# continue
|
|
857
|
+
|
|
858
|
+
# cutoffs = _build_col_lut(col)
|
|
859
|
+
# vals = df_gi[col].values.astype(float)
|
|
860
|
+
# vp = np.full(len(vals), np.nan)
|
|
861
|
+
|
|
862
|
+
# for i in range(n_probs - 1, 0, -1):
|
|
863
|
+
# vp[vals > cutoffs[i]] = prob_vals[i]
|
|
864
|
+
|
|
865
|
+
# df_gp[_prob_col_name(col)] = vp
|
|
866
|
+
|
|
867
|
+
# return df_gp
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
806
871
|
def py_getglp(df_gi: pd.DataFrame) -> pd.DataFrame:
|
|
807
|
-
"""
|
|
872
|
+
"""Compute missing global-index probability values only."""
|
|
808
873
|
|
|
809
874
|
nv = _nv()
|
|
810
875
|
lut_dict = nv["glp_lut"]
|
|
811
876
|
probs = nv["glp_probs"]
|
|
877
|
+
|
|
812
878
|
idxm_0 = [i - 1 for i in (nv["glp_idxm"] or [])]
|
|
813
879
|
idxs_0 = [i - 1 for i in (nv["glp_idxs"] or [])]
|
|
814
880
|
|
|
815
881
|
gl_cols = ["msens", "ssens", "tmd", "tsd", "pmd", "psd", "gh", "vfi"]
|
|
816
882
|
|
|
817
883
|
mean_cols = [gl_cols[i] for i in idxm_0 if i < len(gl_cols)]
|
|
818
|
-
std_cols
|
|
884
|
+
std_cols = [gl_cols[i] for i in idxs_0 if i < len(gl_cols)]
|
|
885
|
+
|
|
886
|
+
def _prob_col_name(col):
|
|
887
|
+
return f"{col}prob"
|
|
888
|
+
|
|
889
|
+
# candidates that can be computed
|
|
890
|
+
computable_cols = [
|
|
891
|
+
c for c in (mean_cols + std_cols)
|
|
892
|
+
if c in df_gi.columns
|
|
893
|
+
]
|
|
894
|
+
|
|
895
|
+
available_gl = [c for c in gl_cols if c in df_gi.columns]
|
|
896
|
+
missing_gl = [c for c in gl_cols if c not in df_gi.columns]
|
|
897
|
+
|
|
898
|
+
print(f"==> py_getglp: available globals: {available_gl}")
|
|
899
|
+
print(f"==> py_getglp: missing globals: {missing_gl}")
|
|
900
|
+
|
|
901
|
+
missing_prob_cols = [
|
|
902
|
+
c for c in computable_cols
|
|
903
|
+
if _prob_col_name(c) not in df_gi.columns
|
|
904
|
+
]
|
|
905
|
+
|
|
906
|
+
print(f"==> py_getglp: missing global probability indices: "
|
|
907
|
+
f"{[_prob_col_name(c) for c in missing_prob_cols]}")
|
|
908
|
+
|
|
909
|
+
if not missing_prob_cols:
|
|
910
|
+
return df_gi.copy()
|
|
819
911
|
|
|
820
912
|
n_probs = len(probs)
|
|
821
913
|
|
|
@@ -824,11 +916,6 @@ def py_getglp(df_gi: pd.DataFrame) -> pd.DataFrame:
|
|
|
824
916
|
for p in probs
|
|
825
917
|
])
|
|
826
918
|
|
|
827
|
-
df_gp = df_gi.copy()
|
|
828
|
-
|
|
829
|
-
def _prob_col_name(col):
|
|
830
|
-
return f"{col}prob"
|
|
831
|
-
|
|
832
919
|
def _build_col_lut(col):
|
|
833
920
|
raw = lut_dict.get(col, [np.nan] * n_probs)
|
|
834
921
|
return np.array([
|
|
@@ -836,9 +923,11 @@ def py_getglp(df_gi: pd.DataFrame) -> pd.DataFrame:
|
|
|
836
923
|
for v in raw
|
|
837
924
|
])
|
|
838
925
|
|
|
926
|
+
computed = {}
|
|
927
|
+
|
|
839
928
|
# Left-tailed: lower values are abnormal
|
|
840
929
|
for col in mean_cols:
|
|
841
|
-
if col not in
|
|
930
|
+
if col not in missing_prob_cols:
|
|
842
931
|
continue
|
|
843
932
|
|
|
844
933
|
cutoffs = _build_col_lut(col)
|
|
@@ -848,11 +937,11 @@ def py_getglp(df_gi: pd.DataFrame) -> pd.DataFrame:
|
|
|
848
937
|
for i in range(n_probs - 1, 0, -1):
|
|
849
938
|
vp[vals < cutoffs[i]] = prob_vals[i]
|
|
850
939
|
|
|
851
|
-
|
|
940
|
+
computed[_prob_col_name(col)] = vp
|
|
852
941
|
|
|
853
942
|
# Right-tailed: higher values are abnormal
|
|
854
943
|
for col in std_cols:
|
|
855
|
-
if col not in
|
|
944
|
+
if col not in missing_prob_cols:
|
|
856
945
|
continue
|
|
857
946
|
|
|
858
947
|
cutoffs = _build_col_lut(col)
|
|
@@ -862,10 +951,27 @@ def py_getglp(df_gi: pd.DataFrame) -> pd.DataFrame:
|
|
|
862
951
|
for i in range(n_probs - 1, 0, -1):
|
|
863
952
|
vp[vals > cutoffs[i]] = prob_vals[i]
|
|
864
953
|
|
|
865
|
-
|
|
954
|
+
computed[_prob_col_name(col)] = vp
|
|
866
955
|
|
|
867
|
-
|
|
956
|
+
if "md" in df_gi.columns and "mdprob" not in df_gi.columns:
|
|
957
|
+
cutoffs = _build_col_lut("tmd")
|
|
958
|
+
vals = df_gi["md"].values.astype(float)
|
|
959
|
+
vp = np.full(len(vals), np.nan)
|
|
868
960
|
|
|
961
|
+
for i in range(n_probs - 1, 0, -1):
|
|
962
|
+
vp[vals < cutoffs[i]] = prob_vals[i]
|
|
963
|
+
|
|
964
|
+
computed["mdprob"] = vp
|
|
965
|
+
|
|
966
|
+
if computed:
|
|
967
|
+
out = pd.concat(
|
|
968
|
+
[df_gi.copy(), pd.DataFrame(computed, index=df_gi.index)],
|
|
969
|
+
axis=1,
|
|
970
|
+
)
|
|
971
|
+
else:
|
|
972
|
+
out = df_gi.copy()
|
|
973
|
+
|
|
974
|
+
return out
|
|
869
975
|
|
|
870
976
|
def py_getallvalues(df_vf: pd.DataFrame):
|
|
871
977
|
"""Compute all deviations and global indices in one call.
|
|
@@ -311,11 +311,14 @@ def HAP2_part2_severity(row):
|
|
|
311
311
|
l_cols = [f"l{i}" for i in range(1, 55) if f"l{i}" in row.index]
|
|
312
312
|
pdp_cols = [f"pdp{i}" for i in range(1, 55) if f"pdp{i}" in row.index]
|
|
313
313
|
|
|
314
|
-
if "md" not in row.index:
|
|
315
|
-
|
|
314
|
+
# if "md" not in row.index:
|
|
315
|
+
# return "Unknown"
|
|
316
316
|
|
|
317
|
-
md
|
|
318
|
-
|
|
317
|
+
if "md" in row.index and pd.notna(row["md"]):
|
|
318
|
+
md = pd.to_numeric(row["md"], errors="coerce")
|
|
319
|
+
elif "tmd" in row.index and pd.notna(row["tmd"]):
|
|
320
|
+
md = pd.to_numeric(row["tmd"], errors="coerce")
|
|
321
|
+
else:
|
|
319
322
|
return "Unknown"
|
|
320
323
|
|
|
321
324
|
sens = pd.to_numeric(row[l_cols], errors="coerce")
|
|
@@ -371,9 +374,25 @@ def HAP2_part2_severity(row):
|
|
|
371
374
|
return "Early"
|
|
372
375
|
|
|
373
376
|
# -------------------------
|
|
374
|
-
#
|
|
377
|
+
# Moderate defect
|
|
378
|
+
# At least one criterion
|
|
375
379
|
# -------------------------
|
|
376
|
-
|
|
380
|
+
only_one_hemifield_central_lt15 = (
|
|
381
|
+
(sup_lt15 and not inf_lt15)
|
|
382
|
+
or (inf_lt15 and not sup_lt15)
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
moderate = (
|
|
386
|
+
(-12 <= md <= -6)
|
|
387
|
+
or (only_one_hemifield_central_lt15 and not any_central_0)
|
|
388
|
+
or (13 <= n_pdp_5 <= 26)
|
|
389
|
+
or (5 <= n_pdp_1 <= 13)
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
if moderate:
|
|
393
|
+
return "Moderate"
|
|
394
|
+
|
|
395
|
+
return ""
|
|
377
396
|
|
|
378
397
|
|
|
379
398
|
def Fn_HAP2_part2(df):
|
PyVisualFields/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.0.
|
|
1
|
+
__version__ = "2.0.7"
|
PyVisualFields/utils.py
CHANGED
|
@@ -119,34 +119,62 @@ META_ALIASES = {
|
|
|
119
119
|
"vfi": [
|
|
120
120
|
"vfi"
|
|
121
121
|
],
|
|
122
|
+
#probability
|
|
123
|
+
"vfiprob": [
|
|
124
|
+
"vfi_p", "vfiprob", "vfip"
|
|
125
|
+
],
|
|
122
126
|
|
|
123
127
|
"msens": [
|
|
124
128
|
"msens", "ms", "meansensitivity"
|
|
125
129
|
],
|
|
130
|
+
#probability
|
|
131
|
+
"msensprob": [
|
|
132
|
+
"msens_p", "msensprob", "msenp", "ms_p", "msprob", "msp"
|
|
133
|
+
],
|
|
126
134
|
|
|
127
135
|
"ssens": [
|
|
128
136
|
"ssens", "ss", "sdsensitivity"
|
|
129
137
|
],
|
|
138
|
+
#probability
|
|
139
|
+
"ssensprob": [
|
|
140
|
+
"ssens_p", "ssensprob", "lsenp", "ss_p", "ssprob", "ssp"
|
|
141
|
+
],
|
|
130
142
|
|
|
131
143
|
"tmd": [
|
|
132
144
|
"tmd"
|
|
133
145
|
],
|
|
146
|
+
#probability
|
|
147
|
+
"tmdprob": [
|
|
148
|
+
"tmd_p", "tmdprob", "tmdp"
|
|
149
|
+
],
|
|
134
150
|
|
|
135
151
|
"tsd": [
|
|
136
152
|
"tsd"
|
|
137
153
|
],
|
|
154
|
+
#probability
|
|
155
|
+
"tsdprob": [
|
|
156
|
+
"tsd_p", "tsdprob", "tsdp"
|
|
157
|
+
],
|
|
138
158
|
|
|
139
159
|
"pmd": [
|
|
140
160
|
"pmd"
|
|
141
161
|
],
|
|
162
|
+
#probability
|
|
163
|
+
"pmdprob": [
|
|
164
|
+
"pmd_p", "pmdprob", "pmdp"
|
|
165
|
+
],
|
|
142
166
|
|
|
143
167
|
"gh": [
|
|
144
168
|
"gh", "generalheight"
|
|
145
169
|
],
|
|
170
|
+
#probability
|
|
171
|
+
"ghprob": [
|
|
172
|
+
"gh_p", "ghprob", "ghp"
|
|
173
|
+
],
|
|
146
174
|
|
|
147
175
|
# Reliability
|
|
148
176
|
"fpr": [
|
|
149
|
-
"fpr"
|
|
177
|
+
"fpr"
|
|
150
178
|
],
|
|
151
179
|
|
|
152
180
|
"fnr": [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
PyVisualFields/Deviation_Analysis.py,sha256=
|
|
2
|
-
PyVisualFields/PyGlaucoMetrics.py,sha256
|
|
3
|
-
PyVisualFields/__init__.py,sha256=
|
|
4
|
-
PyVisualFields/utils.py,sha256=
|
|
1
|
+
PyVisualFields/Deviation_Analysis.py,sha256=KR8m73JMDDYjbj5cDEyxTFbMiyNp0C8Xy5nVTbLXQqw,31152
|
|
2
|
+
PyVisualFields/PyGlaucoMetrics.py,sha256=-Uj_pO9yxqY6-H4ZhrSRdE3zbMdnyy68wLo2i_kmvN0,23956
|
|
3
|
+
PyVisualFields/__init__.py,sha256=L4aOgvDE9n_eqL_mM_j5bO3bQ73q6ulNpnVuG8OmqWE,22
|
|
4
|
+
PyVisualFields/utils.py,sha256=sYZOqnd5kIimbZh8u0sj89pFXx6SYId5rESg_BO6AsA,25219
|
|
5
5
|
PyVisualFields/vfprogression.py,sha256=FjKtVZ3DRcS31CZRcAHMTfDxYYF3UWLTOjcr3YZdCRg,34215
|
|
6
6
|
PyVisualFields/visualFields.py,sha256=aSZaKE5pc67TyuVtrMLYtKe7lbInzVWKnpP-6ezQwHA,61905
|
|
7
7
|
PyVisualFields/pkl_files/locmaps.json,sha256=VQ8L0DvBG8GouJD_ZsgQa8O1SteDMFPFTSPaW8TgL7c,1694
|
|
@@ -18,8 +18,8 @@ PyVisualFields/pkl_files/vfctrSunyiu24d2.pkl,sha256=e2hspPbpVYWXBDVn6fJ9KRK-JYIH
|
|
|
18
18
|
PyVisualFields/pkl_files/vfpwgRetest24d2.pkl,sha256=WyWZ3mHr1JL4TCUVUu0WFpIFdqAiwvNyL_pd51duPKY,106683
|
|
19
19
|
PyVisualFields/pkl_files/vfpwgSunyiu24d2.pkl,sha256=kYIreVpqaRX-Hkl9ZPZ7agnqJplu8DxFM08X17L_fTg,14598
|
|
20
20
|
PyVisualFields/pkl_files/vfseries.pkl,sha256=aWkDkByTkgmCKH2nYZrB1hoHt-fi_FxY1gamZ6iqZu0,36363
|
|
21
|
-
pyvisualfields-2.0.
|
|
22
|
-
pyvisualfields-2.0.
|
|
23
|
-
pyvisualfields-2.0.
|
|
24
|
-
pyvisualfields-2.0.
|
|
25
|
-
pyvisualfields-2.0.
|
|
21
|
+
pyvisualfields-2.0.7.dist-info/licenses/LICENSE,sha256=m3BJDRLy-Xnz1WmgtnVniIpPIlwv0MYil80-tjCetYc,1570
|
|
22
|
+
pyvisualfields-2.0.7.dist-info/METADATA,sha256=7G6xPj_WBWENM1XJSfBga1IC3-Jpg29Af5M5FWbpOYQ,12829
|
|
23
|
+
pyvisualfields-2.0.7.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
24
|
+
pyvisualfields-2.0.7.dist-info/top_level.txt,sha256=r-Mpr1QBoJaRDJQ-POzcuukSnBCkNasixPj3P2UWWRw,15
|
|
25
|
+
pyvisualfields-2.0.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|