Files
kg-scr/README.md
aman bf968affaa
Some checks failed
tests / core (macos-latest, py3.11) (push) Has been cancelled
tests / core (macos-latest, py3.12) (push) Has been cancelled
tests / core (macos-latest, py3.13) (push) Has been cancelled
tests / core (ubuntu-latest, py3.11) (push) Has been cancelled
tests / core (ubuntu-latest, py3.12) (push) Has been cancelled
tests / core (ubuntu-latest, py3.13) (push) Has been cancelled
tests / doctor CLI smoke test (push) Has been cancelled
update readme
2026-07-20 17:53:52 +00:00

243 lines
6.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OCR Pipeline for Life Science Screenshots
Turns scientific screenshots into RAG-ready Markdown, with metadata attached.
- OCR via PaddleOCR, falls back to Tesseract
- Preprocessing: deskew, denoise, CLAHE, line removal
- Figure/table detection
- Entity extraction with scispaCy
- Citation matching (DOI, PMID, arXiv, ISBN)
- Chunking for embedding
- Knowledge graph over the output (`kg` commands)
## Quick start
```bash
uv sync
uv run ocr-pipeline setup # installs Tesseract if missing
uv run ocr-pipeline init # write a config
uv run ocr-pipeline demo # check it works
uv run ocr-pipeline run # process your screenshots
```
Default install is small: Tesseract only, no multi-GB ML downloads.
## Commands
- `run` / `watch` — process a directory, or watch for new screenshots
- `status` / `stats` — what's been processed
- `doctor` — check engines, models, config
- `kg build|stats|query|export` — knowledge graph over the output
- `setup [basic|full]` — install dependencies step by step
Use `--force` to reprocess. `--exclude "*.photoslibrary/*"` keeps recursive
scans out of macOS photo bundles.
<details>
<summary><b>Optional extras</b></summary>
Heavy ML features are opt-in and degrade gracefully when missing (logged, step
skipped, run continues):
| Extra | Provides |
|-------|----------|
| `paddle` | PaddleOCR engine |
| `scientific` | spaCy/scispaCy NER |
| `tables` | Table Transformer detection |
| `figures` | LayoutParser figure/caption detection |
| `full` | All of the above |
| `kg` | Knowledge graph (networkx, txtai, litellm) |
| `neo4j` | Neo4j export driver |
```bash
uv sync --extra full
# or guided:
uv run ocr-pipeline setup full
```
`en_core_sci_lg` is distributed separately from scispaCy and needs spaCy 3.7.x.
If the model install conflicts, use a dedicated Python 3.11 venv and enable
`entities` only there.
</details>
<details>
<summary><b>Knowledge graph</b></summary>
Build a graph from pipeline output: documents, chunks, entities, citations,
entity co-occurrence.
```bash
uv sync --extra kg
uv run ocr-pipeline kg build -d data/ocr_output
uv run ocr-pipeline kg stats data/ocr_output/kg_graph.json
# retrieval
uv run ocr-pipeline kg query data/ocr_output/kg_graph.json --entity BRCA1
uv run ocr-pipeline kg query data/ocr_output/kg_graph.json --entity BRCA1 --expand
uv run ocr-pipeline kg query data/ocr_output/kg_graph.json --citation 10.1038/nature12345
# export
uv run ocr-pipeline kg export data/ocr_output/kg_graph.json -f graphml
uv run ocr-pipeline kg export data/ocr_output/kg_graph.json -f neo4j
```
Anomaly detection flags low-confidence documents, empty chunks, and entity
hubs. Neo4j export needs `uv sync --extra neo4j` plus `NEO4J_URI`,
`NEO4J_USER`, `NEO4J_PASSWORD` env vars (or `--uri/--user/--password`).
</details>
<details>
<summary><b>Docker</b></summary>
The image ships the Tesseract-only core. It reads `/data/screenshots` and
writes `/data/output`:
```bash
docker build -t ocr-pipeline .
docker run -v ~/Pictures:/data/screenshots -v "$PWD/ocr-output:/data/output" ocr-pipeline run
docker run -v ~/Pictures:/data/screenshots -v "$PWD/ocr-output:/data/output" ocr-pipeline watch
# with ML extras:
docker build --build-arg EXTRAS="--extra full" -t ocr-pipeline:full .
```
</details>
<details>
<summary><b>Config</b></summary>
`ocr-pipeline init` writes a minimal config. Lookup order:
`$OCR_PIPELINE_CONFIG``./config.yaml` → per-user config dir.
Every knob, for reference:
```yaml
input:
paths: ["~/Pictures", "/mnt/storage3/aman/screenshots"]
patterns: ["SCR-*.png", "*.jpg", "*.jpeg", "*.tiff"]
recursive: true
exclude_patterns: ["*.photoslibrary/*"]
ocr:
engine: "paddleocr" # paddleocr | tesseract | auto
languages: ["en", "latin"]
use_gpu: false
preprocess:
deskew: true
denoise: true
clahe: true
adaptive_threshold: true
remove_lines: true
processing:
workers: 4
batch_size: 10
retry_attempts: 2
detectors:
figures:
enabled: true
confidence_threshold: 0.7
tables:
enabled: true
confidence_threshold: 0.7
entities:
enabled: true
model: "en_core_sci_lg"
citations:
regex_enabled: true
grobid_enabled: false # set true if you're running a GROBID server
chunking:
chunk_size: 1000
chunk_overlap: 200
output:
base_directory: "./data/ocr_output"
organize_by: "date_run" # date_run | source_dir | flat
write_consolidated: true
consolidated_filename: "all_ocr.md"
watch:
enabled: true
debounce_seconds: 5
db_path: "./data/processed_files.db"
```
</details>
<details>
<summary><b>Output example</b></summary>
Each chunk is a Markdown file with YAML frontmatter:
```markdown
---
source_path: "/Users/Aman/Pictures/SCR-20250115-gel.png"
source_hash: "a1b2c3d4e5f6..."
timestamp: "2025-01-15T10:30:00Z"
ocr_engine: "paddleocr"
ocr_confidence_mean: 0.91
language: "en"
detected_entities: ["GENE", "PROTEIN", "CHEMICAL"]
has_figures: true
has_tables: false
citations_found: ["doi:10.1038/nature12345", "pmid:PMID:12345678"]
chunk_index: 0
total_chunks: 2
---
# Screenshot: SCR-20250115-gel.png
## Extracted Text
**Western Blot Analysis of BRCA1 Expression**
Lane 1: WT control
Lane 2: BRCA1 KO (CRISPR)
...
```
Files land in `<output>/<date>/run_NNN/`. Chunk files are kept for RAG
indexing. `output.write_consolidated: true` also writes `all_ocr.md` with one
frontmatter block and all source text grouped by image.
</details>
<details>
<summary><b>Models and dependencies</b></summary>
Weights download on first use, cached in `~/.cache/ocr_pipeline/`:
- PaddleOCR models (~200MB)
- scispaCy `en_core_sci_lg` (~800MB)
- Table Transformer (~500MB)
- LayoutParser PubLayNet (~300MB)
Notes per capability:
- **PaddleOCR:** pinned to the legacy 2.x API. Falls back to Tesseract when it
can't initialize; the fallback is logged and recorded in frontmatter.
- **Scientific NER:** without scispaCy + `en_core_sci_lg`, a conservative
regex extractor runs instead and the backend is marked accordingly.
- **Figures:** needs a Detectron2 build matching your Torch/Python. No
universal wheel exists, so it's never installed automatically.
- **Tables:** downloaded by Transformers on first use; needs `timm`.
`ocr-pipeline doctor` checks all of the above and prints remediation hints.
</details>
## Life science specifics
Gene/protein names go through scispaCy's `en_core_sci_lg`. Chemical formulas
and units (µM, ng/mL, kb/Mb/Gb, °C, ×g) get normalized, scientific notation
gets cleaned up (`1.5×10⁻³``1.5×10^-3`), and gel/blot figures get their
captions pulled out separately.