Skip to main content

Reference-table-based visual acuity conversion for ophthalmic research data harmonization.

Project description

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:

pip install visual-acuity-conversion

Then import the module in Python:

from visual_acuity_conversion import convert_visual_acuity, get_va_chart

Dependencies

The package requires:

numpy
pandas

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


Quick start

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:

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

Main functions

convert_visual_acuity()

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:

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:

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.

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.

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

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

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

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

print(converted)

Snellen visual acuity

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

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

print(converted)

Off-chart descriptors

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:

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:

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:

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.

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

visual_acuity_conversion-0.9.1.tar.gz (10.2 kB view details)

Uploaded Source

Built Distribution

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

visual_acuity_conversion-0.9.1-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file visual_acuity_conversion-0.9.1.tar.gz.

File metadata

  • Download URL: visual_acuity_conversion-0.9.1.tar.gz
  • Upload date:
  • Size: 10.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for visual_acuity_conversion-0.9.1.tar.gz
Algorithm Hash digest
SHA256 8fe449c5ce5d0035d2c9196dff7a9011aab8e16cf4439f111a68bb4c254ee284
MD5 1d96500a03fe269b8f0ffeae3269ec94
BLAKE2b-256 88c72ed23d4c0f86cdbae964e61ca0b33794e0568f58307c4fc0bd315f08e185

See more details on using hashes here.

File details

Details for the file visual_acuity_conversion-0.9.1-py3-none-any.whl.

File metadata

File hashes

Hashes for visual_acuity_conversion-0.9.1-py3-none-any.whl
Algorithm Hash digest
SHA256 fd93718b5fda99021b013149e5b769b6d22f6e463db060369152261f9189b06a
MD5 9c2f53b532681f6b012d592ae187885a
BLAKE2b-256 a173d35ddc8b5714a6992d88cc184b0f1007cd9dee461a0d05b3daf6c05ea273

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