Metadata-Version: 2.4
Name: visual-acuity-conversion
Version: 0.9.1
Summary: Reference-table-based visual acuity conversion for ophthalmic research data harmonization.
Author: Broder Poschkamp
License-Expression: MIT
Keywords: ophthalmology,visual acuity,logMAR,Snellen,ETDRS,vision impairment
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Healthcare Industry
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.23
Requires-Dist: pandas>=1.5

# Visual Acuity Conversion Toolkit

**Version:** 0.9.1  
**Status:** pre-release / manuscript submission version  
**License:** MIT License

A lightweight Python module for harmonizing visual acuity values across commonly used ophthalmic notation systems, including decimal acuity, Snellen notation, logMAR, approximate ETDRS letters, WHO vision impairment categories, and selected low-vision descriptors.

The toolkit was developed to support reproducible ophthalmic research, retrospective dataset cleaning, registry preprocessing, and transparent reporting of visual acuity conversion assumptions.

---

## Purpose

Visual acuity is frequently documented in heterogeneous formats across clinical records, registries, retrospective datasets, and research studies. Common formats include decimal visual acuity, Snellen notation, logMAR, ETDRS letters, and low-vision descriptors such as counting fingers, hand movements, light perception, and no light perception.

These formats are related but not fully interchangeable. This package provides a transparent reference-table-based approach for harmonizing routinely documented visual acuity values while keeping conversion assumptions explicit and reproducible.

The package is intended for ophthalmic research, dataset cleaning, registry preprocessing, and transparent reporting of visual acuity conversion assumptions. It is not intended for clinical visual acuity measurement.

---

## Installation

Install from PyPI:

```bash
pip install visual-acuity-conversion
```

Then import the module in Python:

```python
from visual_acuity_conversion import convert_visual_acuity, get_va_chart
```

---

## Dependencies

The package requires:

```text
numpy
pandas
```

These dependencies are installed automatically when installing the package from PyPI.

---

## Quick start

```python
import pandas as pd
from visual_acuity_conversion import convert_visual_acuity

values = pd.Series(["6/6", "6/12", "6/60", "counting fingers"])

converted = convert_visual_acuity(
    values,
    input_format="Snellen_6m",
    mode="exact"
)

print(converted)
```

Example output columns:

```text
Decimal VA
logMAR
Snellen 6 m
Snellen 20 ft
Approx ETDRS letters
WHO class
```

---

## Main functions

### `convert_visual_acuity()`

```python
convert_visual_acuity(series, input_format, mode="exact", return_columns=None)
```

Converts a `pandas.Series` of visual acuity values using the embedded reference conversion table.

### Parameters

| Parameter | Description |
|---|---|
| `series` | A `pandas.Series` containing visual acuity values. |
| `input_format` | Input format of the visual acuity values. |
| `mode` | Conversion mode. Default is `"exact"`. |
| `return_columns` | Optional subset of output columns to return. |

---

## Supported input formats

Accepted values for `input_format` are:

| Input format | Description | Example values |
|---|---|---|
| `Decimal` | Decimal visual acuity | `1.0`, `0.5`, `0.32`, `0,32` |
| `logMAR` | logMAR visual acuity | `0.0`, `0.3`, `1.0` |
| `Snellen_6m` | Snellen notation at 6 m | `6/6`, `6/12`, `3/60` |
| `Snellen_20ft` | Snellen notation at 20 ft | `20/20`, `20/40`, `20/200` |
| `ETDRS_letters` | Approximate ETDRS letters | `85`, `70`, `35` |
| `Off_chart` | Low-vision descriptors | `counting fingers`, `hand movements`, `light perception`, `no light perception` |

---

## Output columns

By default, the package returns the following columns:

| Output column | Description |
|---|---|
| `Decimal VA` | Decimal visual acuity. |
| `logMAR` | logMAR visual acuity. |
| `Snellen 6 m` | Snellen notation at 6 m. |
| `Snellen 20 ft` | Snellen notation at 20 ft. |
| `Approx ETDRS letters` | Approximate ETDRS letter score. |
| `WHO class` | WHO visual impairment category. |

You can request a subset of columns:

```python
converted = convert_visual_acuity(
    values,
    input_format="Snellen_6m",
    return_columns=["Decimal VA", "logMAR", "WHO class"]
)
```

---

## Inspecting the reference table

The embedded conversion table can be inspected directly:

```python
from visual_acuity_conversion import get_va_chart

chart = get_va_chart()
print(chart.head())
```

This makes the conversion assumptions transparent and allows users to inspect the reference values used internally by the package.

---

## Exact and nearest-neighbour conversion

### Exact mode

Exact mode is the recommended default. It converts values only if they match an entry in the embedded reference table.

```python
converted = convert_visual_acuity(
    values,
    input_format="Decimal",
    mode="exact"
)
```

If no exact match is found, the output for that value is returned as missing.

### Nearest-neighbour mode

Nearest-neighbour mode maps an input value to the closest predefined table entry.

```python
converted = convert_visual_acuity(
    values,
    input_format="Decimal",
    mode="near"
)
```

The aliases `"close"` and `"closest"` are also accepted.

Nearest-neighbour mode does not calculate a new continuous visual acuity value. It only selects the closest existing row from the embedded conversion table. This mode should be used cautiously and reported explicitly in analyses, reports, and manuscripts.

---

## Low-vision descriptors

The toolkit includes approximate mappings for selected off-chart descriptors:

| Descriptor | Accepted aliases |
|---|---|
| Counting fingers | `counting fingers`, `CF` |
| Hand movements | `hand movements`, `hand movement`, `hand motion`, `HM` |
| Light perception | `light perception`, `LP`, `follows light` |
| No light perception | `no light perception`, `NLP`, `nulla lux` |

These mappings should be interpreted with caution because low-vision descriptors are not equivalent to standardized chart-based visual acuity measurements. Ambiguous or clinically important values should be reviewed manually.

---

## Examples

### Decimal visual acuity

```python
import pandas as pd
from visual_acuity_conversion import convert_visual_acuity

values = pd.Series([1.0, 0.5, 0.1])

converted = convert_visual_acuity(
    values,
    input_format="Decimal"
)

print(converted)
```

### logMAR visual acuity

```python
values = pd.Series([0.0, 0.3, 1.0])

converted = convert_visual_acuity(
    values,
    input_format="logMAR"
)

print(converted)
```

### Snellen visual acuity

```python
values = pd.Series(["6/6", "6/12", "6/60"])

converted = convert_visual_acuity(
    values,
    input_format="Snellen_6m"
)

print(converted)
```

### Off-chart descriptors

```python
values = pd.Series(["counting fingers", "hand movements", "light perception", "no light perception"])

converted = convert_visual_acuity(
    values,
    input_format="Off_chart"
)

print(converted)
```

---

## Recommended reporting in manuscripts

Suggested wording:

```text
Visual acuity values were harmonized using the Visual Acuity Conversion Toolkit, version 0.9.1. Conversion was performed using exact lookup against the embedded reference table. Low-vision descriptors were mapped using predefined approximate values and interpreted cautiously.
```

If nearest-neighbour mode was used, this should be stated explicitly:

```text
For values without an exact table match, nearest-neighbour lookup was used to map the input value to the closest predefined entry in the embedded conversion table. This approach did not interpolate new visual acuity values.
```

---

## Limitations

This package is intended for transparent research data harmonization, not for clinical visual acuity measurement.

Important limitations:

- Snellen, decimal, logMAR, and ETDRS values are related but not fully interchangeable.
- Approximate ETDRS letters should not be interpreted as equivalent to standardized ETDRS chart testing.
- Low-vision descriptors do not have universally accepted numeric equivalents.
- Nearest-neighbour mode may introduce threshold-related misclassification.
- The package does not account for testing distance deviations, refraction status, pinhole testing, monocular versus binocular testing, or best-corrected versus presenting acuity.
- The package does not distinguish between monocular and binocular recordings.
- The current implementation does not automatically infer all input formats in a fully mixed-format column.

Users should retain original visual acuity values where possible and report conversion assumptions transparently.

---

## Citation

This toolkit is currently released as a pre-publication software package. Until a journal article or archived DOI is available, please cite the PyPI package or software repository directly:

```text
Poschkamp B, Jonas RA, Grün M, Kim H, Stahl A, Keane PA.
Visual Acuity Conversion Toolkit. Version 0.9.1.
Python Package Index: visual-acuity-conversion.
Accessed: [insert access date].
```

---

## License

MIT License.

Copyright (c) 2026 Broder Poschkamp

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files to deal in the software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, subject to the conditions of the MIT License.

---

## Disclaimer

This toolkit is provided for research and data-harmonization purposes. It is not a medical device and should not be used as a substitute for clinical visual acuity testing, clinical judgment, or standardized trial measurement protocols.

Low-vision descriptor mappings and approximate ETDRS conversions should be interpreted cautiously and reported transparently.
