Metadata-Version: 2.4
Name: fyron
Version: 0.3.0
Summary: Fyron is an open-source Python toolkit for interoperable healthcare data and AI workflows. It provides unified access to FHIR data via REST APIs and relational (SQL-backed) FHIR servers, integrates DICOM imaging sources, and enables semantic exploration of clinical narratives using modern language models.
Project-URL: Homepage, https://github.com/bitsandflames/fyron
Project-URL: Repository, https://github.com/bitsandflames/fyron
Project-URL: Documentation, https://bitsandflames.github.io/fyron/
Author-email: Bits & Flames <hello@bitsandflames.ai>
License-Expression: MIT
License-File: LICENSE
Keywords: DICOM,FHIR,LLM,NLP,clinical,healthcare
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: dicomweb-client<0.60.0,>=0.59.1
Requires-Dist: fhirpathpy<3.0.0,>=2.1.0
Requires-Dist: pandas<3.0.0,>=2.2.0
Requires-Dist: psycopg<4.0.0,>=3.1.19
Requires-Dist: pydicom<3.0.0,>=2.4.4
Requires-Dist: pyjwt<3.0.0,>=2.9.0
Requires-Dist: python-dotenv<2.0.0,>=1.0.1
Requires-Dist: requests<3.0.0,>=2.32.0
Requires-Dist: retrying<2.0.0,>=1.3.3
Requires-Dist: simpleitk<3.0.0,>=2.3.1
Requires-Dist: tqdm<5.0.0,>=4.66.0
Provides-Extra: all
Requires-Dist: boruta<0.4.0,>=0.3.0; extra == 'all'
Requires-Dist: boto3<2.0.0,>=1.34.0; extra == 'all'
Requires-Dist: highdicom<0.23,>=0.22; extra == 'all'
Requires-Dist: joblib<2.0.0,>=1.3.0; extra == 'all'
Requires-Dist: lifelines<1.0.0,>=0.30.0; extra == 'all'
Requires-Dist: matplotlib<4.0.0,>=3.8.0; extra == 'all'
Requires-Dist: numpy<2.0.0,>=1.26.0; extra == 'all'
Requires-Dist: opencv-python-headless<5.0.0,>=4.8.0; extra == 'all'
Requires-Dist: openpyxl<4.0.0,>=3.1.0; extra == 'all'
Requires-Dist: pyradiomics<3.1.0,>=3.0.1; extra == 'all'
Requires-Dist: scikit-learn<2.0.0,>=1.4.0; extra == 'all'
Requires-Dist: scikit-survival<1.0.0,>=0.23.0; extra == 'all'
Requires-Dist: scipy<2.0.0,>=1.11.0; extra == 'all'
Requires-Dist: shap<1.0.0,>=0.45.0; extra == 'all'
Requires-Dist: xgboost<3.0.0,>=2.0.0; extra == 'all'
Provides-Extra: audit
Provides-Extra: boruta
Requires-Dist: boruta<0.4.0,>=0.3.0; extra == 'boruta'
Provides-Extra: curate
Provides-Extra: descriptive
Requires-Dist: numpy<2.0.0,>=1.26.0; extra == 'descriptive'
Requires-Dist: scipy<2.0.0,>=1.11.0; extra == 'descriptive'
Provides-Extra: dicom-seg
Requires-Dist: highdicom<0.23,>=0.22; extra == 'dicom-seg'
Provides-Extra: excel
Requires-Dist: openpyxl<4.0.0,>=3.1.0; extra == 'excel'
Provides-Extra: explainability
Requires-Dist: numpy<2.0.0,>=1.26.0; extra == 'explainability'
Requires-Dist: scikit-learn<2.0.0,>=1.4.0; extra == 'explainability'
Requires-Dist: shap<1.0.0,>=0.45.0; extra == 'explainability'
Provides-Extra: feature-selection
Requires-Dist: boruta<0.4.0,>=0.3.0; extra == 'feature-selection'
Requires-Dist: numpy<2.0.0,>=1.26.0; extra == 'feature-selection'
Requires-Dist: scikit-learn<2.0.0,>=1.4.0; extra == 'feature-selection'
Requires-Dist: scipy<2.0.0,>=1.11.0; extra == 'feature-selection'
Provides-Extra: ml
Requires-Dist: joblib<2.0.0,>=1.3.0; extra == 'ml'
Requires-Dist: matplotlib<4.0.0,>=3.8.0; extra == 'ml'
Requires-Dist: numpy<2.0.0,>=1.26.0; extra == 'ml'
Requires-Dist: scikit-learn<2.0.0,>=1.4.0; extra == 'ml'
Requires-Dist: xgboost<3.0.0,>=2.0.0; extra == 'ml'
Provides-Extra: radiomics
Requires-Dist: pyradiomics<3.1.0,>=3.0.1; extra == 'radiomics'
Provides-Extra: reporting
Provides-Extra: s3
Requires-Dist: boto3<2.0.0,>=1.34.0; extra == 's3'
Provides-Extra: statistics
Requires-Dist: numpy<2.0.0,>=1.26.0; extra == 'statistics'
Requires-Dist: scipy<2.0.0,>=1.11.0; extra == 'statistics'
Provides-Extra: survival
Requires-Dist: lifelines<1.0.0,>=0.30.0; extra == 'survival'
Requires-Dist: matplotlib<4.0.0,>=3.8.0; extra == 'survival'
Requires-Dist: scipy<2.0.0,>=1.11.0; extra == 'survival'
Provides-Extra: survival-ml
Requires-Dist: lifelines<1.0.0,>=0.30.0; extra == 'survival-ml'
Requires-Dist: matplotlib<4.0.0,>=3.8.0; extra == 'survival-ml'
Requires-Dist: scikit-survival<1.0.0,>=0.23.0; extra == 'survival-ml'
Requires-Dist: scipy<2.0.0,>=1.11.0; extra == 'survival-ml'
Provides-Extra: validation
Requires-Dist: numpy<2.0.0,>=1.26.0; extra == 'validation'
Requires-Dist: scikit-learn<2.0.0,>=1.4.0; extra == 'validation'
Provides-Extra: visualization
Requires-Dist: opencv-python-headless<5.0.0,>=4.8.0; extra == 'visualization'
Description-Content-Type: text/markdown

![Fyron Banner](images/FYRON-Banner.png)

<div align="center">
  <a href="https://pypi.org/project/fyron/"><img alt="PyPI" src="https://img.shields.io/pypi/v/fyron?color=0B0B0C" /></a>
  <a href="https://github.com/bitsandflames/fyron/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/bitsandflames/fyron/actions/workflows/ci.yml/badge.svg" /></a>
  <img alt="Python" src="https://img.shields.io/pypi/pyversions/fyron?color=0B0B0C" />
  <a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-MIT-0B0B0C" /></a>
  <img alt="FHIR" src="https://img.shields.io/badge/FHIR-enabled-FF6A1A" />
  <img alt="DICOM" src="https://img.shields.io/badge/DICOM-supported-FF6A1A" />
  <img alt="Survival ML" src="https://img.shields.io/badge/survival%20ML-supported-FF6A1A" />
  <a href="https://bitsandflames.github.io/fyron/"><img alt="Docs" src="https://img.shields.io/badge/docs-GitHub%20Pages-0B0B0C" /></a>
</div>

# Fyron

**Clinical data science, from source systems to evidence artifacts.**

Fyron is an open Python toolkit for healthcare researchers, imaging AI teams, and clinical data scientists who need research workflows to be inspectable, reproducible, and ready for scientific review. It connects the practical pieces around clinical evidence generation: FHIR and DICOM acquisition, local imaging and BOA outputs, cohort construction, manuscript statistics, survival analysis, tabular machine learning, validation, explainability, paper-ready figures, and provenance manifests.

We developed Fyron from years of hands-on clinical data science work, where the hard part is rarely one isolated model or one isolated table. Real studies often span hospital systems, registries, PACS exports, segmentation folders, spreadsheets, notebooks, statistical scripts, figures, and reviewer questions. Fyron gives those steps a shared, explicit shape so assumptions are visible and outputs can be checked, saved, repeated, and cited.

Fyron is not a replacement for pandas, scikit-learn, lifelines, highdicom, MONAI, or FHIR/DICOM libraries. It is the pragmatic research layer around them: small APIs, explicit parameters, DataFrame-first outputs, Matplotlib figures, clinical workflow defaults, and audit artifacts that help a team move from raw clinical data to defensible scientific results.

[Documentation](https://bitsandflames.github.io/fyron/) · [API Design](https://bitsandflames.github.io/fyron/api-design/) · [Example Gallery](https://bitsandflames.github.io/fyron/example-gallery/) · [Curate](https://bitsandflames.github.io/fyron/applications/curate/) · [Using Fyron In Research](https://bitsandflames.github.io/fyron/repository-trust/)

## What Fyron Enables

| Research need | Fyron support |
| --- | --- |
| Acquire clinical data | FHIR REST/SQL workflows, FHIRPath extraction presets, DICOMweb downloads, document downloads |
| Build cohorts | patient joins, endpoint construction, cohort profiles, filter-flow explainability |
| Work with imaging AI outputs | DICOM/NIfTI utilities, BOA feature extraction, radiomics, DICOM SEG export, segmentation collages, Curate preview folders, CT/MR difference heatmaps |
| Prepare training datasets | nnU-Net v2 segmentation folders, YOLO classification folders, YOLO detection labels |
| Produce manuscript statistics | Table 1, missingness/QC tables, FDR correction, regression tables, model-comparison tests |
| Run survival and ML studies | Kaplan-Meier, Cox, RMST, Schoenfeld diagnostics, classification pipelines, calibration, thresholds, subgroup metrics |
| Explain and review results | feature importance, SHAP-ready summaries, patient-level prediction drivers, cohort flow charts, paper-ready plots |
| Preserve provenance | analysis run manifests, file hashes, parameters, output paths, package/version metadata |

## Why We Built Fyron

Clinical research is full of valuable but fragmented work: a FHIR query in one place, an imaging export in another, a cohort spreadsheet, a survival notebook, a model validation script, and figures assembled late in the manuscript process. That fragmentation makes it difficult to answer simple but essential questions: Which patients entered the study? Which endpoint definition was used? Which features were excluded? Which parameters produced this figure?

Fyron is built for that middle layer. It makes the common clinical data science steps explicit, composable, and reviewable without turning them into a black box. The goal is not AutoML and not regulatory compliance software; the goal is practical scientific discipline: clear inputs, clear assumptions, clear outputs, and artifacts that can travel from notebook to manuscript to supplement.

## From Clinical Data To Evidence

```text
FHIR / DICOM / files
        -> cohort and endpoints
        -> feature tables and imaging measurements
        -> statistics, survival, and ML
        -> validation and explainability
        -> figures, reports, and provenance manifests
```

```python
from fyron import FHIRRestClient
from fyron.fhir import get_fhir_path_preset
from fyron.cohort import build_time_to_event_endpoint, cohort_profile
from fyron.flow import FlowTracker
from fyron.audit import analysis_run_manifest, write_manifest

client = FHIRRestClient("https://hapi.fhir.org/baseR4")
observations = client.search_df(
    "Observation",
    params={"_count": 50, "code": "http://loinc.org|718-7"},
    fhir_paths=get_fhir_path_preset("Observation"),
    max_pages=1,
)

cohort = build_time_to_event_endpoint(
    cohort,
    index_date_col="diagnosis_date",
    event_date_col="death_date",
    censor_date_col="last_followup_date",
)

profile = cohort_profile(cohort, id_col="patient_id", endpoint_cols=["time", "event"])

flow = FlowTracker("NSCLC CT cohort")
flow.add_step("Reviewed export", cohort, reason="source cohort")

manifest = analysis_run_manifest(
    title="nsclc_ct_survival_model",
    inputs=["cohort.csv", "features.csv"],
    outputs=["table1.csv", "km.png", "model_metrics.csv"],
    parameters={"seed": 42, "endpoint": "overall_survival"},
)
write_manifest(manifest, "analysis_manifest.json")
```

The [Example Gallery](https://bitsandflames.github.io/fyron/example-gallery/) contains full synthetic workflows for FHIR-to-cohort, BOA/imaging validation, cohort-flow explainability, manuscript statistics, plotting, DICOM SEG export, and CT/MR difference heatmaps.

## Built For Responsible Research

- **Local-first by default.** Fyron sends no telemetry on import; external calls happen only when you configure a client or CLI command.
- **Inspectable outputs.** Core helpers return DataFrames, dictionaries, named objects, Matplotlib figures, and JSON-compatible manifests.
- **Explicit clinical assumptions.** Endpoints, censoring, event coding, FHIR paths, imaging geometry, p-value correction, and model validation choices are parameterized.
- **Synthetic examples.** Documentation examples are designed to be runnable without PHI.
- **Research, not clinical deployment.** Fyron is not a medical device, treatment recommendation system, or compliance platform.

For citation, security, and research-use expectations, see [CITATION.cff](CITATION.cff), [SECURITY.md](SECURITY.md), and [Using Fyron In Research](https://bitsandflames.github.io/fyron/repository-trust/).

## Install

```bash
uv add fyron
```

With pip:

```bash
pip install fyron
```

Useful extras:

| Extra | Install | Adds |
| --- | --- | --- |
| All features | `uv add "fyron[all]"` | Full local research environment with every optional dependency |
| Excel | `uv add "fyron[excel]"` | Excel read/write via `openpyxl` |
| Survival | `uv add "fyron[survival]"` | KM, RMST, Cox, Weibull AFT |
| Survival ML | `uv add "fyron[survival-ml]"` | Gradient survival boosting via `scikit-survival` |
| ML | `uv add "fyron[ml]"` | Random Forest, XGBoost, metrics, plots |
| Statistics | `uv add "fyron[statistics]"` | FDR correction, regression tables, QC tests |
| Feature selection | `uv add "fyron[feature-selection]"` | Univariate, model, permutation, Boruta, stability selection |
| Validation | `uv add "fyron[validation]"` | Thresholds, calibration, subgroups, decision curves |
| Explainability | `uv add "fyron[explainability]"` | Permutation importance, partial dependence, SHAP tables |
| Radiomics | `uv add "fyron[radiomics]"` | BOA radiomics via PyRadiomics |
| Visualization | `uv add "fyron[visualization]"` | BOA collages, Curate previews, and CT/MR difference heatmaps |
| S3 | `uv add "fyron[s3]"` | S3 and S3-compatible table/object storage |
| Curate | `uv add "fyron[curate]"` | Local Docker Compose image cohort review app |

For a broad local analysis environment:

```bash
uv add "fyron[all]"
```

Start the local cohort curation app after installing Docker Desktop:

```bash
fyron curate
```

Prepare CT/MRI folders for Curate review by rendering PNG previews first:

```bash
uv add "fyron[visualization,curate]"
fyron dataset-curate-previews --input-dir ct_exports/ --output-dir curate_previews/
fyron curate
```

Drop `curate_previews/` into the Curate **Add cohort** dialog. Three-dimensional volumes and DICOM series produce middle axial, coronal, and sagittal PNGs; 2D images such as X-rays or topograms produce one PNG.

## Modules

| Module | Purpose |
| --- | --- |
| `fyron.fhir` | FHIR REST/SQL access, FHIRPath extraction, resource building, mapping, write-back |
| `fyron.dicom` | DICOMweb downloads, study/series manifests, NIfTI conversion, DICOM SEG |
| `fyron.boa_extraction` | BOA cohort feature tables from measurement JSON and NIfTI masks |
| `fyron.boa_radiomics` | Radiomics extraction from BOA segmentations |
| `fyron.datasets` | Synthetic demo data plus nnU-Net v2 and YOLO dataset preparation |
| `fyron.cohort` | Patient joins, endpoint construction, cohort profiles, survival columns |
| `fyron.flow` | Filter-flow tracking, Markdown flow charts, cohort inclusion explainability |
| `fyron.statistics` | FDR correction, regression tables, model-comparison tests, QC tables |
| `fyron.survival` | KM, RMST, Cox, Weibull AFT, PH checks, Schoenfeld residual diagnostics |
| `fyron.ml` | Tabular classification pipelines, metrics, model plots |
| `fyron.validation` | Bootstrap metrics, calibration, thresholding, subgroup and survival validation |
| `fyron.explainability` | Feature importance, SHAP summaries, patient-level prediction explanations |
| `fyron.reporting` | Table 1, metric tables, cohort-flow tables, Markdown report tables |
| `fyron.audit` | Provenance manifests, file hashes, analysis run records |
| `fyron.plotting` | Clinical and paper-ready plots across survival, ML, QC, and flow workflows |

Beta desktop tooling:

- `fyron curate` starts the local image cohort review app.

See the [module documentation](https://bitsandflames.github.io/fyron/modules/) for workflow guides, tutorials, and the generated complete function reference.

## Example Gallery

Start with the [Example Gallery](https://bitsandflames.github.io/fyron/example-gallery/) for runnable synthetic workflows. It includes FHIR-to-cohort, BOA/imaging validation, cohort-flow explainability, manuscript statistics, plotting, DICOM SEG export, synthetic GAN volume export, and CT/MR difference heatmaps.

Several plotting examples render manuscript-style figures:

<p align="center">
  <img alt="Risk score distribution" src="docs/assets/dummy-risk-score-distribution.png" width="42%" />
  <img alt="Forest estimates" src="docs/assets/dummy-forest-estimates.png" width="42%" />
</p>

## Public Beta

Fyron is in public beta. The main workflows are intended to be useful and reproducible, but some APIs may still evolve as researchers try the package on real projects. We try to make changes additive, document migration paths, and avoid surprising notebook breakage.

## Privacy And Security

Fyron is local-first and sends no telemetry on import. External calls happen only when you configure a client or CLI command for systems such as FHIR, DICOMweb, S3, Teable, or document downloads. See [SECURITY.md](SECURITY.md) and [Using Fyron In Research](https://bitsandflames.github.io/fyron/repository-trust/) for healthcare data cautions.

## Contributing

```bash
uv sync --all-extras --dev
uv run pytest
```

Preview the docs locally:

```bash
uv run python scripts/build_docs.py
uv run python -m http.server 8001 --directory site
```

For public support expectations and the `0.x` compatibility policy, see [SUPPORT.md](SUPPORT.md). For research-use privacy notes, see [Using Fyron In Research](https://bitsandflames.github.io/fyron/repository-trust/).

## License

MIT. See [LICENSE](LICENSE).
