Skip to main content

Visual field analysis for glaucoma without R dependencies

Project description

PyGlaucoMetrics

PyGlaucoMetrics is an open-source, pure-Python package for glaucoma detection and visual field (VF) analysis — no R or rpy2 dependency required. It accepts Humphrey Field Analyzer (HFA) 24-2 test patterns and provides a full pipeline from raw VF data to ensemble glaucoma classification, severity staging, and progression analysis, with an interactive GUI.

PyPI version License: MIT Python >=3.8


Overview

PyGlaucoMetrics is designed as an accessible GUI application and Python library that implements selected visual field analysis components from PyVisualFields. It integrates glaucoma classification criteria, HAP2 severity staging, progression analysis, and an interactive visualization interface.

Note: PyVisualFields is the underlying developer-facing library. PyGlaucoMetrics builds upon it to provide an end-user GUI and glaucoma-specific classification pipeline.


Features

  • Pure Python — all computations via numpy, scipy, and pandas; no R required
  • Automatic column standardization — any CSV with any column naming convention is accepted; columns are automatically mapped to canonical names (patientid, eyeid, l1l54, td*, pd*, etc.)
  • Missing block computation — if TD, PD, TDP, or PDP values are missing, they are computed automatically from sensitivity data
  • Dataset summary popup — on load, a summary window shows which data blocks and global indices are present or missing
  • Demo dataset — download the UW HVF dataset directly from within the GUI (no manual download needed)
  • Five glaucoma classifiers with GL/Non-GL labels and human-readable reasons:
    • HAP2 (Part 1: classification + Part 2: Early/Moderate/Severe staging)
    • UKGTS
    • LoGTS
    • Foster (requires GHT column)
    • Kang's
  • AUC-weighted ensemble decision (weights from published Table 2, Moradi et al. 2025)
  • Six-panel VF visualization — Sensitivity, TD Probability, PD Probability (row 1) + Sensitivity dB, TD Deviation, PD Deviation (row 2)
  • Progression analysis — CIGTS, PLR Nouri 2012, VFI, Schell 2014, AGIS, Global Linear Regression (GLR), Pointwise Linear Regression (PLR)
  • Save results — exports classifier CSVs, HAP2 severity bar chart, ensemble bar chart, and VF plots

Installation

Windows:

pip install PyGlaucoMetrics[windows]

Linux / macOS:

pip install PyGlaucoMetrics

Quick Start

Launch the GUI

Option 1 — Console script (recommended):

pyglaucometrics-gui

Option 2 — From Python:

from PyVisualFields.gui_pygl import main
main()

Option 3 — Run the script directly:

python gui_pygl.py

Note on import: PyGlaucoMetrics is accessed as a submodule of PyVisualFields:

from PyVisualFields import PyGlaucoMetrics

Use classifiers in Python

import pandas as pd
from PyVisualFields import visualFields, vfprogression
from PyVisualFields import PyGlaucoMetrics
from PyVisualFields.utils import (
    canonicalize_vf_df, compute_missing_blocks,
    vf_blocks, missing_blocks, print_vf_summary
)

# 1. Load and standardize (any column naming convention accepted)
df = pd.read_csv('VF_Data.csv')
df = canonicalize_vf_df(df)           # standardize column names

# Check what blocks are present
print(vf_blocks(df))          # e.g. {'sens': True, 'td': True, ...}
print(missing_blocks(df))     # e.g. ['tdp', 'pdp']
print_vf_summary(df)          # human-readable summary with ✓/✗

# 2. Compute missing blocks (TD, PD, TDP, PDP) and global indices
df = compute_missing_blocks(df)
df_gi = visualFields.getgl(df)          # MD, PSD, VFI, GH, etc.
combined = pd.concat([df, df_gi], axis=1)
final_df = combined.loc[:, ~combined.columns.duplicated()]

# 3. Run classifiers
df_hap2   = PyGlaucoMetrics.Fn_HAP2(final_df)
df_hap2   = PyGlaucoMetrics.Fn_HAP2_part2(df_hap2)
df_ukgts  = PyGlaucoMetrics.Fn_UKGTS(final_df)
df_logts  = PyGlaucoMetrics.Fn_LoGTS(final_df)
df_foster = PyGlaucoMetrics.Fn_Foster(final_df)   # requires GHT column
df_kangs  = PyGlaucoMetrics.Fn_Kangs(final_df)

# 4. View results
print(df_hap2[['l1', 'l2', 'HAP2_clf', 'HAP2_reason']].head())
# Output:
#    l1  l2 HAP2_clf                                        HAP2_reason
# 0  26  28   Non-GL
# 3  24  25       GL  GHT outside; cluster of 3 PDP points < 5% with...

print(df_hap2[['l1', 'l2', 'HAP2_clf', 'severity(HAP2_part2)']].head())
# Output:
#    l1  l2 HAP2_clf severity(HAP2_part2)
# 0  26  28   Non-GL               Early
# 3  24  25       GL               Early

print(df_ukgts[['l1', 'l2', 'UKGTS_clf', 'UKGTS_reason']].head())
# Output:
#    l1  l2 UKGTS_clf                                       UKGTS_reason
# 3  24  25        GL  Cluster of 2 TDP points < 1%; Cluster of 3 TDP...

print(df_foster[['l1', 'l2', 'Foster_clf', 'Foster_reason']].head())
# Output:
#    l1  l2 Foster_clf                                 Foster_reason
# 3  24  25         GL  GHT outside AND cluster of 3 PDP points < 5%

print(df_kangs[['l1', 'l2', 'Kangs_clf', 'Kangs_reason']].head())
# Output:
#    l1  l2 Kangs_clf                         Kangs_reason
# 4  26  26        GL  Cluster of 3 points with TD < -5 dB

GUI Workflow

  1. Click Load Dataset — choose between:
    • 📥 Use UW Demo Dataset — downloads automatically from the UW HVF repository
    • 📂 Load My Own CSV — select any CSV file from disk
  2. A Dataset Summary popup shows which blocks (sensitivity, TD, PD, TDP, PDP) and global indices (MD, PSD, GHT, VFI, etc.) are present or missing
  3. Missing blocks are computed automatically
  4. Enter an index (row number) to view VF plots and classifier predictions
  5. Click 💾 Save Results to export all outputs

Input Format

Any CSV is accepted. Column names are automatically standardized. The following aliases are recognized:

Canonical name Accepted aliases
patientid id, patient_id, mrn, subjectid, pid
eyeid eye, eye_id, laterality
date examdate, testdate, vfdate
l1l54 s1s54, sens1sens54, sensitivity1sensitivity54
td1td54 td1td54
pdp1pdp54 pdp1pdp54
md mtd
ght ght

Eye values (OD/OS) are also normalized from right/left, R/L, 1/0.


Classifiers

Classifier Input Criterion Output columns
HAP2 Part 1 PD probabilities Cluster of 3 PDP points < 5% with ≥1 < 1%; or GHT outside; or PSD p < 5% HAP2_clf, HAP2_reason
HAP2 Part 2 Sensitivity + PDP + MD Early / Moderate / Severe per HAP2 reference criteria (applied to all rows; Non-GL rows receive a severity based on their field characteristics) severity(HAP2_part2)
UKGTS TD probabilities + TD values ≥2 TDP points < 1%; or ≥3 < 5%; or nasal step ≥10 dB UKGTS_clf, UKGTS_reason
LoGTS TD values Cluster of 2 TD < −10 dB; or 3 TD < −8 dB LoGTS_clf, LoGTS_reason
Foster PD probabilities + GHT GHT outside normal limits AND cluster of 3 PDP < 5% Foster_clf, Foster_reason
Kang's TD values Cluster of 3 TD < −5 dB; or 2 TD < −10 dB Kangs_clf, Kangs_reason

Ensemble Decision

Final GL/Non-GL label uses an AUC-weighted ensemble combining all five classifiers:

Classifier AUC weight
UKGTS 0.815
LoGTS 0.821
Foster 0.675
Kang's 0.815
HAP2 0.735

HAP2 Severity Staging (Part II)

Based on Hodapp-Anderson-Parrish 2 (Clinical Decisions in Glaucoma):

Stage Criteria (all must be met for Early; any for Severe)
Early MD > −6 dB AND no central 5° point < 15 dB AND ≤12 PDP points < 5% AND ≤4 PDP points < 1%
Severe MD < −12 dB OR any central 5° point = 0 dB OR central < 15 dB in both hemifields OR ≥27 PDP points < 5% OR ≥14 PDP points < 1%
Moderate Neither Early nor Severe

Central 5° points: locations 23, 24, 32, 33 (1-based 24-2 HFA grid).


Progression Analysis

Method Function Min visits Required columns
CIGTS progression_cigts() 5 tdp1tdp54, eyeid
PLR Nouri 2012 progression_plrnouri2012() 3 td1td54, eyeid
VFI progression_vfi() 5 vfi, eyeid
Schell 2014 progression_schell2014() 5 td1td54, eyeid
AGIS progression_agis() 5 l1l54, eyeid
Global Linear Regression visualFields.glr() 2 global indices
Pointwise Linear Regression visualFields.plr() 2 l1l54 or td*/pd*

Data is automatically sorted by date/age within each patient before progression analysis.


Function Reference

Data Utilities (PyVisualFields.utils)

Function Description
canonicalize_vf_df(df) Standardize column names to canonical format
canonicalize_vf_df(df, sort_byDateAge=True) Standardize and sort by date/age within patient
compute_missing_blocks(df) Compute missing TD, PD, TDP, PDP blocks
vf_blocks(df) Return dict of which blocks are present
missing_blocks(df) Return list of missing block names
investigate_vf_df(df) Return full summary dict of available data
print_vf_summary(df) Print human-readable data summary

Glaucoma Classifiers (from PyVisualFields import PyGlaucoMetrics)

Function Description
Fn_HAP2(df) HAP2 Part 1: GL/Non-GL with reason
Fn_HAP2_part2(df) HAP2 Part 2: Early/Moderate/Severe severity
Fn_UKGTS(df) UKGTS criterion: GL/Non-GL with reason
Fn_LoGTS(df) LoGTS criterion: GL/Non-GL with reason
Fn_Foster(df) Foster criterion: GL/Non-GL with reason (needs GHT)
Fn_Kangs(df) Kang's criterion: GL/Non-GL with reason

Deviation Analysis (PyVisualFields.visualFields)

Function Description
gettd(df) Compute total deviation
gettdp(df) Compute TD probability
getpd(df) Compute pattern deviation
getpdp(df) Compute PD probability
getgl(df) Compute global indices (MD, PSD, VFI, GH, etc.)
getglp(df) Compute global index p-values
glr(df, type, testSlope) Global linear regression
plr(df, type, testSlope) Pointwise linear regression
poplr(df, type, testSlope) PoPLR permutation regression

Visualization

Function Description
visualFields.vfplot(df, type='s') Sensitivity plot
visualFields.vfplot_tds(df) TD probability plot
visualFields.vfplot_pds(df) PD probability plot
vfprogression.plotValues(arr) Plot sensitivity/TD/PD values
vfprogression.plotProbabilities(arr) Plot TDP/PDP probability maps

Built-in Datasets

Function Description
visualFields.data_vfpwgRetest24d2() 24-2 retest dataset (30 glaucoma patients)
visualFields.data_vfctrSunyiu24d2() SUNY-IU 24-2 control dataset
visualFields.data_vfpwgSunyiu24d2() SUNY-IU 24-2 glaucoma dataset
vfprogression.data_vfseries() Longitudinal VF series
vfprogression.data_cigts() CIGTS study dataset
vfprogression.data_vfi() VFI dataset
vfprogression.data_schell2014() Schell 2014 dataset

Requirements

Core (all platforms):

numpy
pandas
matplotlib
scipy
PyQt5>=5.15
Pillow
seaborn
pingouin
requests
PyVisualFields

Windows only (installed automatically with [windows] extra):

pywin32

Citation

If you use PyGlaucoMetrics in your research, please cite:

  1. Moradi et al. (2025) — PyGlaucoMetrics paper: Moradi, M., Hashemabad, S.K., Vu, D.M., Soneru, A.R., Fujita, A., Wang, M., Elze, T., Eslami, M. and Zebardast, N. PyGlaucoMetrics: A Stacked Weight-Based Machine Learning Approach for Glaucoma Detection Using Visual Field Data. Medicina, 61(3), 541. https://doi.org/10.3390/medicina61030541

  2. Eslami et al. (2023) — PyVisualFields: Eslami, M., Kazeminasab, S., Sharma, V., Li, Y., Fazli, M., Wang, M., Zebardast, N. and Elze, T. PyVisualFields: A Python Package for Visual Field Analysis. Trans. Vis. Sci. Tech., 12(2), 6. https://doi.org/10.1167/tvst.12.2.6

  3. Moradi et al. (2024) — ARVO abstract: Moradi, M. et al. PyGlaucoMetrics: An Open-Source Multi-Criteria Glaucoma Defect Evaluation. Investigative Ophthalmology & Visual Science, 65(7), OD38. https://iovs.arvojournals.org/article.aspx?articleid=2800368


Links


License

MIT License — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyglaucometrics-1.0.4.tar.gz (531.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyglaucometrics-1.0.4-py3-none-any.whl (534.7 kB view details)

Uploaded Python 3

File details

Details for the file pyglaucometrics-1.0.4.tar.gz.

File metadata

  • Download URL: pyglaucometrics-1.0.4.tar.gz
  • Upload date:
  • Size: 531.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for pyglaucometrics-1.0.4.tar.gz
Algorithm Hash digest
SHA256 d8506f31e6bb795faa7807bfb2d2be2f78a6ea1777069f58dccb88f0d2bb2816
MD5 7a2f654831639710fa318668a7589d89
BLAKE2b-256 d244afc880c75cb776ad8af4c1b698286887476d1dceba02f35807f732674f86

See more details on using hashes here.

File details

Details for the file pyglaucometrics-1.0.4-py3-none-any.whl.

File metadata

  • Download URL: pyglaucometrics-1.0.4-py3-none-any.whl
  • Upload date:
  • Size: 534.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for pyglaucometrics-1.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 83ec7e39410b72368b01c7646d7bd29c1dce15ddfb350c7e7115787361d6ac3a
MD5 708c2a12f15684d85f5335d9c3fbee39
BLAKE2b-256 8710b60a2ef1c8815f538120beeec152a6d0f5005d1742a9bb0b3bb4e5f3b42b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page