spirotrace 0.0.1__tar.gz
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.
- spirotrace-0.0.1/PKG-INFO +66 -0
- spirotrace-0.0.1/README.md +49 -0
- spirotrace-0.0.1/pyproject.toml +40 -0
- spirotrace-0.0.1/setup.cfg +4 -0
- spirotrace-0.0.1/src/spirotrace/__init__.py +3 -0
- spirotrace-0.0.1/src/spirotrace/checks/__init__.py +5 -0
- spirotrace-0.0.1/src/spirotrace/cli.py +32 -0
- spirotrace-0.0.1/src/spirotrace/derive/__init__.py +5 -0
- spirotrace-0.0.1/src/spirotrace/evaluate/__init__.py +5 -0
- spirotrace-0.0.1/src/spirotrace/ingest/__init__.py +4 -0
- spirotrace-0.0.1/src/spirotrace/layouts/__init__.py +6 -0
- spirotrace-0.0.1/src/spirotrace/privacy/__init__.py +4 -0
- spirotrace-0.0.1/src/spirotrace/review/__init__.py +4 -0
- spirotrace-0.0.1/src/spirotrace.egg-info/PKG-INFO +66 -0
- spirotrace-0.0.1/src/spirotrace.egg-info/SOURCES.txt +18 -0
- spirotrace-0.0.1/src/spirotrace.egg-info/dependency_links.txt +1 -0
- spirotrace-0.0.1/src/spirotrace.egg-info/entry_points.txt +2 -0
- spirotrace-0.0.1/src/spirotrace.egg-info/requires.txt +3 -0
- spirotrace-0.0.1/src/spirotrace.egg-info/top_level.txt +1 -0
- spirotrace-0.0.1/tests/test_skeleton.py +16 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: spirotrace
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Traceable extraction of lung function data from printed and scanned reports
|
|
5
|
+
Author: Kirsty Hawke
|
|
6
|
+
Project-URL: Homepage, https://github.com/hawkek/spirotrace
|
|
7
|
+
Project-URL: Issues, https://github.com/hawkek/spirotrace/issues
|
|
8
|
+
Keywords: spirometry,lung function,PDF extraction,OCR,data quality,GLI
|
|
9
|
+
Classifier: Development Status :: 1 - Planning
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
|
|
18
|
+
# spirotrace
|
|
19
|
+
|
|
20
|
+
**Traceable extraction of lung function data from printed and scanned reports.**
|
|
21
|
+
|
|
22
|
+
> Status: early development. Nothing here is ready for use yet. The working prototype that this package replaces is not public; this repository is being built up from it module by module, with tests.
|
|
23
|
+
|
|
24
|
+
## Statement of need
|
|
25
|
+
|
|
26
|
+
Lung function results (spirometry, lung volumes, gas transfer) often reach researchers only as printed or scanned PDF reports, not as structured data. Typing them by hand is slow and error-prone, and generic PDF or OCR extraction gives values with no indication of which ones are wrong.
|
|
27
|
+
|
|
28
|
+
spirotrace turns such reports into an audited, analysis-ready dataset with a measured error rate:
|
|
29
|
+
|
|
30
|
+
- **Extraction.** Report layouts are described in template files (geometry and vocabulary); one reader handles every layout.
|
|
31
|
+
- **Auditability.** Every value keeps its raw text, its position on the page, how it was read, and every human correction made to it (who, when, before, after).
|
|
32
|
+
- **Physiology-informed checks.** Values are checked against each other and against reference equations (for example, the printed z-score against a GLI recalculation, FEV1/FVC against FEV1 and FVC, LLN against the sign of the z-score), so errors that look like plausible numbers are still caught.
|
|
33
|
+
- **Measured reliability.** Built-in tools compare the extraction with a blinded manual reference sample and report accuracy, flag sensitivity and residual (silent) errors.
|
|
34
|
+
- **Local by default.** Everything runs on the user's machine. Nothing is uploaded; there is no telemetry.
|
|
35
|
+
|
|
36
|
+
Similar tools exist ([PFT-Extractor](https://github.com/lindseyboulet/PFT-Extractor), an R app for Vmax reports; [pft-extractor](https://github.com/Automate-Medical/pft-extractor), a cloud pipeline using Amazon Textract). Neither describes validation of the extracted values or detection of extraction errors.
|
|
37
|
+
|
|
38
|
+
## Planned scope
|
|
39
|
+
|
|
40
|
+
| Tier | Contents |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| Research MVP | Two report layouts, deterministic extraction, provenance on every value, core checks, review corrections as an event log, derived variables (ATS/ERS 2022 pattern, severity, PRISm, bronchodilator response) after review, GLI recalculation via [rspiro](https://cran.r-project.org/package=rspiro), reference-standard evaluation |
|
|
43
|
+
| v1.0 | Add-your-own layout templates, a local browser review app, documentation |
|
|
44
|
+
| Later | Installers for non-programmers, template editor, further OCR engines |
|
|
45
|
+
|
|
46
|
+
## Data protection
|
|
47
|
+
|
|
48
|
+
spirotrace is meant for clinical reports. Please:
|
|
49
|
+
|
|
50
|
+
- **never** attach a report, a screenshot of one, or extracted values to an issue or pull request;
|
|
51
|
+
- report layout problems with the masked, structure-only survey output instead (instructions will be in the docs);
|
|
52
|
+
- check that your ethics and data-access approvals cover your use.
|
|
53
|
+
|
|
54
|
+
Outputs written to a project's `share/` folder are masked or aggregate by default. Whether any file may be shared is a decision for your study's governance, not something the software can certify.
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
Not yet. When the first usable release is out: `pip install spirotrace`.
|
|
59
|
+
|
|
60
|
+
## Citation
|
|
61
|
+
|
|
62
|
+
See [CITATION.cff](CITATION.cff). A software paper is planned.
|
|
63
|
+
|
|
64
|
+
## Licence
|
|
65
|
+
|
|
66
|
+
To be confirmed (an OSI-approved permissive licence is intended).
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# spirotrace
|
|
2
|
+
|
|
3
|
+
**Traceable extraction of lung function data from printed and scanned reports.**
|
|
4
|
+
|
|
5
|
+
> Status: early development. Nothing here is ready for use yet. The working prototype that this package replaces is not public; this repository is being built up from it module by module, with tests.
|
|
6
|
+
|
|
7
|
+
## Statement of need
|
|
8
|
+
|
|
9
|
+
Lung function results (spirometry, lung volumes, gas transfer) often reach researchers only as printed or scanned PDF reports, not as structured data. Typing them by hand is slow and error-prone, and generic PDF or OCR extraction gives values with no indication of which ones are wrong.
|
|
10
|
+
|
|
11
|
+
spirotrace turns such reports into an audited, analysis-ready dataset with a measured error rate:
|
|
12
|
+
|
|
13
|
+
- **Extraction.** Report layouts are described in template files (geometry and vocabulary); one reader handles every layout.
|
|
14
|
+
- **Auditability.** Every value keeps its raw text, its position on the page, how it was read, and every human correction made to it (who, when, before, after).
|
|
15
|
+
- **Physiology-informed checks.** Values are checked against each other and against reference equations (for example, the printed z-score against a GLI recalculation, FEV1/FVC against FEV1 and FVC, LLN against the sign of the z-score), so errors that look like plausible numbers are still caught.
|
|
16
|
+
- **Measured reliability.** Built-in tools compare the extraction with a blinded manual reference sample and report accuracy, flag sensitivity and residual (silent) errors.
|
|
17
|
+
- **Local by default.** Everything runs on the user's machine. Nothing is uploaded; there is no telemetry.
|
|
18
|
+
|
|
19
|
+
Similar tools exist ([PFT-Extractor](https://github.com/lindseyboulet/PFT-Extractor), an R app for Vmax reports; [pft-extractor](https://github.com/Automate-Medical/pft-extractor), a cloud pipeline using Amazon Textract). Neither describes validation of the extracted values or detection of extraction errors.
|
|
20
|
+
|
|
21
|
+
## Planned scope
|
|
22
|
+
|
|
23
|
+
| Tier | Contents |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| Research MVP | Two report layouts, deterministic extraction, provenance on every value, core checks, review corrections as an event log, derived variables (ATS/ERS 2022 pattern, severity, PRISm, bronchodilator response) after review, GLI recalculation via [rspiro](https://cran.r-project.org/package=rspiro), reference-standard evaluation |
|
|
26
|
+
| v1.0 | Add-your-own layout templates, a local browser review app, documentation |
|
|
27
|
+
| Later | Installers for non-programmers, template editor, further OCR engines |
|
|
28
|
+
|
|
29
|
+
## Data protection
|
|
30
|
+
|
|
31
|
+
spirotrace is meant for clinical reports. Please:
|
|
32
|
+
|
|
33
|
+
- **never** attach a report, a screenshot of one, or extracted values to an issue or pull request;
|
|
34
|
+
- report layout problems with the masked, structure-only survey output instead (instructions will be in the docs);
|
|
35
|
+
- check that your ethics and data-access approvals cover your use.
|
|
36
|
+
|
|
37
|
+
Outputs written to a project's `share/` folder are masked or aggregate by default. Whether any file may be shared is a decision for your study's governance, not something the software can certify.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
Not yet. When the first usable release is out: `pip install spirotrace`.
|
|
42
|
+
|
|
43
|
+
## Citation
|
|
44
|
+
|
|
45
|
+
See [CITATION.cff](CITATION.cff). A software paper is planned.
|
|
46
|
+
|
|
47
|
+
## Licence
|
|
48
|
+
|
|
49
|
+
To be confirmed (an OSI-approved permissive licence is intended).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "spirotrace"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
description = "Traceable extraction of lung function data from printed and scanned reports"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
authors = [{ name = "Kirsty Hawke" }]
|
|
12
|
+
keywords = ["spirometry", "lung function", "PDF extraction", "OCR", "data quality", "GLI"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 1 - Planning",
|
|
15
|
+
"Intended Audience :: Science/Research",
|
|
16
|
+
"Topic :: Scientific/Engineering :: Medical Science Apps.",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
19
|
+
]
|
|
20
|
+
# Dependencies are added as modules are ported (planned: pdfplumber, pypdfium2, Pillow, numpy, openpyxl, PyYAML).
|
|
21
|
+
dependencies = []
|
|
22
|
+
|
|
23
|
+
[project.optional-dependencies]
|
|
24
|
+
dev = ["pytest>=7"]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/hawkek/spirotrace"
|
|
28
|
+
Issues = "https://github.com/hawkek/spirotrace/issues"
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
spirotrace = "spirotrace.cli:main"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.packages.find]
|
|
34
|
+
where = ["src"]
|
|
35
|
+
|
|
36
|
+
[tool.setuptools.package-data]
|
|
37
|
+
"spirotrace.layouts" = ["templates/*.yaml"]
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Command line entry point: spirotrace <command>."""
|
|
2
|
+
import argparse
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
from . import __version__
|
|
6
|
+
|
|
7
|
+
COMMANDS = {
|
|
8
|
+
"init": "create a study project folder",
|
|
9
|
+
"run": "extract and check all reports in a project",
|
|
10
|
+
"review": "open the local review app",
|
|
11
|
+
"export": "write the dataset, data dictionary and QC report",
|
|
12
|
+
"template": "draft, test or survey a layout template",
|
|
13
|
+
"eval": "evaluate against a manually coded reference sample",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def main(argv=None):
|
|
18
|
+
ap = argparse.ArgumentParser(prog="spirotrace", description=__doc__)
|
|
19
|
+
ap.add_argument("--version", action="version", version=f"spirotrace {__version__}")
|
|
20
|
+
sub = ap.add_subparsers(dest="command", metavar="command")
|
|
21
|
+
for name, help_ in COMMANDS.items():
|
|
22
|
+
sub.add_parser(name, help=help_)
|
|
23
|
+
a = ap.parse_args(argv)
|
|
24
|
+
if a.command is None:
|
|
25
|
+
ap.print_help()
|
|
26
|
+
return 0
|
|
27
|
+
print(f"spirotrace {__version__}: '{a.command}' is not implemented yet.")
|
|
28
|
+
return 1
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
sys.exit(main())
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: spirotrace
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Traceable extraction of lung function data from printed and scanned reports
|
|
5
|
+
Author: Kirsty Hawke
|
|
6
|
+
Project-URL: Homepage, https://github.com/hawkek/spirotrace
|
|
7
|
+
Project-URL: Issues, https://github.com/hawkek/spirotrace/issues
|
|
8
|
+
Keywords: spirometry,lung function,PDF extraction,OCR,data quality,GLI
|
|
9
|
+
Classifier: Development Status :: 1 - Planning
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
|
|
18
|
+
# spirotrace
|
|
19
|
+
|
|
20
|
+
**Traceable extraction of lung function data from printed and scanned reports.**
|
|
21
|
+
|
|
22
|
+
> Status: early development. Nothing here is ready for use yet. The working prototype that this package replaces is not public; this repository is being built up from it module by module, with tests.
|
|
23
|
+
|
|
24
|
+
## Statement of need
|
|
25
|
+
|
|
26
|
+
Lung function results (spirometry, lung volumes, gas transfer) often reach researchers only as printed or scanned PDF reports, not as structured data. Typing them by hand is slow and error-prone, and generic PDF or OCR extraction gives values with no indication of which ones are wrong.
|
|
27
|
+
|
|
28
|
+
spirotrace turns such reports into an audited, analysis-ready dataset with a measured error rate:
|
|
29
|
+
|
|
30
|
+
- **Extraction.** Report layouts are described in template files (geometry and vocabulary); one reader handles every layout.
|
|
31
|
+
- **Auditability.** Every value keeps its raw text, its position on the page, how it was read, and every human correction made to it (who, when, before, after).
|
|
32
|
+
- **Physiology-informed checks.** Values are checked against each other and against reference equations (for example, the printed z-score against a GLI recalculation, FEV1/FVC against FEV1 and FVC, LLN against the sign of the z-score), so errors that look like plausible numbers are still caught.
|
|
33
|
+
- **Measured reliability.** Built-in tools compare the extraction with a blinded manual reference sample and report accuracy, flag sensitivity and residual (silent) errors.
|
|
34
|
+
- **Local by default.** Everything runs on the user's machine. Nothing is uploaded; there is no telemetry.
|
|
35
|
+
|
|
36
|
+
Similar tools exist ([PFT-Extractor](https://github.com/lindseyboulet/PFT-Extractor), an R app for Vmax reports; [pft-extractor](https://github.com/Automate-Medical/pft-extractor), a cloud pipeline using Amazon Textract). Neither describes validation of the extracted values or detection of extraction errors.
|
|
37
|
+
|
|
38
|
+
## Planned scope
|
|
39
|
+
|
|
40
|
+
| Tier | Contents |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| Research MVP | Two report layouts, deterministic extraction, provenance on every value, core checks, review corrections as an event log, derived variables (ATS/ERS 2022 pattern, severity, PRISm, bronchodilator response) after review, GLI recalculation via [rspiro](https://cran.r-project.org/package=rspiro), reference-standard evaluation |
|
|
43
|
+
| v1.0 | Add-your-own layout templates, a local browser review app, documentation |
|
|
44
|
+
| Later | Installers for non-programmers, template editor, further OCR engines |
|
|
45
|
+
|
|
46
|
+
## Data protection
|
|
47
|
+
|
|
48
|
+
spirotrace is meant for clinical reports. Please:
|
|
49
|
+
|
|
50
|
+
- **never** attach a report, a screenshot of one, or extracted values to an issue or pull request;
|
|
51
|
+
- report layout problems with the masked, structure-only survey output instead (instructions will be in the docs);
|
|
52
|
+
- check that your ethics and data-access approvals cover your use.
|
|
53
|
+
|
|
54
|
+
Outputs written to a project's `share/` folder are masked or aggregate by default. Whether any file may be shared is a decision for your study's governance, not something the software can certify.
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
Not yet. When the first usable release is out: `pip install spirotrace`.
|
|
59
|
+
|
|
60
|
+
## Citation
|
|
61
|
+
|
|
62
|
+
See [CITATION.cff](CITATION.cff). A software paper is planned.
|
|
63
|
+
|
|
64
|
+
## Licence
|
|
65
|
+
|
|
66
|
+
To be confirmed (an OSI-approved permissive licence is intended).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/spirotrace/__init__.py
|
|
4
|
+
src/spirotrace/cli.py
|
|
5
|
+
src/spirotrace.egg-info/PKG-INFO
|
|
6
|
+
src/spirotrace.egg-info/SOURCES.txt
|
|
7
|
+
src/spirotrace.egg-info/dependency_links.txt
|
|
8
|
+
src/spirotrace.egg-info/entry_points.txt
|
|
9
|
+
src/spirotrace.egg-info/requires.txt
|
|
10
|
+
src/spirotrace.egg-info/top_level.txt
|
|
11
|
+
src/spirotrace/checks/__init__.py
|
|
12
|
+
src/spirotrace/derive/__init__.py
|
|
13
|
+
src/spirotrace/evaluate/__init__.py
|
|
14
|
+
src/spirotrace/ingest/__init__.py
|
|
15
|
+
src/spirotrace/layouts/__init__.py
|
|
16
|
+
src/spirotrace/privacy/__init__.py
|
|
17
|
+
src/spirotrace/review/__init__.py
|
|
18
|
+
tests/test_skeleton.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
spirotrace
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import spirotrace
|
|
2
|
+
from spirotrace import cli
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def test_version_is_set():
|
|
6
|
+
assert spirotrace.__version__ == "0.0.1"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_cli_without_command_prints_help(capsys):
|
|
10
|
+
assert cli.main([]) == 0
|
|
11
|
+
assert "usage" in capsys.readouterr().out
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_unimplemented_command_says_so(capsys):
|
|
15
|
+
assert cli.main(["run"]) == 1
|
|
16
|
+
assert "not implemented" in capsys.readouterr().out
|