gliostitch
Reproducible cohort selection over four public glioma MRI datasets — stitched into one manifest of facts, with a study definition layered on top.
Assembling a multi-cohort GBM study means reconciling four different directory layouts, four clinical CSV conventions, three ID formats, two segmentation label schemes, and an unknown number of patients who appear in more than one dataset. Most of that work gets done once, in a notebook, and is difficult to reproduce six months later.
This project does it as a pipeline. It emits one manifest of facts about every imaging session, and a separate layer that turns those facts into a cohort according to a named, versioned study definition. The split matters: the manifest never changes when the research question does.
1661 imaging sessions → study definition → 502 sessions (377 training / 125 external)
with a reason attached to all 1159 exclusions
Datasets: BraTS-2020 · UCSF-PDGM · UPENN-GBM · RHUH-GBM (not redistributed — you supply the data and configure its location)
Install
pip install gliostitch # selection + path resolution
pip install "gliostitch[pipeline]" # + build the manifest yourself
pip install "gliostitch[load]" # + read NIfTI volumes
pip install "gliostitch[monai]" # + framework backends: monai / torchio / torch
The core is pandas, numpy and pydantic only. If you just want to query a manifest
someone else built, you never install the pipeline.
Quickstart
Build the manifest
Point config/pipeline.yaml at your dataset roots, then:
gliostitch verify-layout # check the directories before doing any work
gliostitch build # → output/master_manifest.csv
Select a cohort
from gbm_os import Cohort
from gbm_os.studies import GBM_OS_STUDY
cohort = Cohort.from_manifest(
"output/master_manifest.csv",
data_roots={"brats2020": "/data/BraTS-2020", ...},
)
view = GBM_OS_STUDY.apply(cohort)
print(len(view)) # 502
for spec in view: # SampleSpec: resolved paths + clinical metadata
print(spec.paths["t1ce"], spec.os_days, spec.os_class)
Or express criteria directly — all optional, all composable:
view = cohort.select(
datasets=["ucsf_pdgm", "rhuh_gbm"],
baseline_only=True,
require_complete=True,
filters={"eor": "GTR", "who_grade": [4, None]},
where=lambda r: r["age"] is not None and r["age"] >= 18,
resolve_duplicates="drop",
)
Load it
ds = view.to_monai() # or .to_torchio() / .to_torch()
folds = view.split(k=5, seed=42) # stratified, patient-grouped, deterministic
train = folds.fold(0, "train")
Why it is built this way
The manifest records facts, not decisions. One row per imaging session, 31 columns,
covering identity, paths, modality presence, and normalised clinical values. It does not
store os_class, is_baseline or partition — those are modelling choices, derived at
load time. A fact discarded at ingest is unrecoverable; a derivation recomputed on load
costs milliseconds.
A study is a separate, versioned object. Eligibility criteria, survival thresholds and
the held-out cohort live in gbm_os.studies, declaratively — no lambdas, so a definition
can be printed, diffed and pasted into a methods section.
$ gliostitch studies gbm-os
gbm-os v2
Overall-survival classification over baseline preoperative GBM MRI, held out on UPENN-GBM.
Eligibility:
- baseline session only (session_index == 0)
- all four structural modalities present
- eor == 'GTR'
- who_grade in [4, None]
- has_os == True
Changing the study cannot change the manifest — building under a different one produces a byte-identical CSV. That property is enforced by a test.
Every exclusion is accounted for. Selection records what each criterion removed, so a cohort table is derivable rather than asserted:
>>> print(view.provenance())
input 1661
baseline_only 1661 → 1521 (−140)
require_complete 1521 → 1126 (−395)
filter:eor 1126 → 526 (−600)
filter:who_grade 526 → 509 (−17)
filter:has_os 509 → 503 (−6)
resolve_duplicates 503 → 502 (−1)
selected 502
>>> view.exclusions() # every dropped session, tagged with its reason
len(view) + len(view.exclusions()) always equals the input.
Duplicates are annotated, never deleted. Patients appearing in more than one dataset are flagged with a group id and a confidence level. Which copy to keep is a selection policy, not a manifest edit.
Documentation
| Architecture | How the two packages relate and which one a change belongs in |
| Extending | Adding a dataset, column, study, criterion or backend |
| Design decisions | Why it is shaped this way, and what breaks if reversed |
| Versioning | Release process, and which number to bump |
| Usage notebook | Worked end-to-end walkthrough |
Development
source activate.sh
pytest # 246 tests
pytest tests/manifest # pipeline only — runs against a synthetic dataset tree,
# no real data needed, ~1 s
The pipeline suite builds a miniature four-dataset tree on the fly and runs the real adapters against it, so join contracts are testable without access to the MRI data. Tests that need a built manifest skip themselves with a reason.
Status
Beta. The cohort figures above are current as of the latest entry in CHANGELOG.md, which records data-affecting changes separately from code changes — a fix that moves a cohort count is breaking for anyone who published against the old one.
Citation
If you use this in published work, please cite it. GitHub's Cite this repository button
reads CITATION.cff and will produce BibTeX or APA for you.
Lim, Wei Xin (Davian). gliostitch: reproducible cohort selection over public glioma MRI datasets, version 0.1.0, 2026. https://github.com/realdavian/gliostitch
ORCID: 0009-0005-2683-1528
Please also cite the source datasets — BraTS-2020, UCSF-PDGM, UPENN-GBM and RHUH-GBM each have their own citation requirements, and this project redistributes none of them.
Licence
GNU General Public License v3.0 or later.
You may use, modify and redistribute this software, including commercially. If you distribute a modified version, or software that incorporates this one, that work must also be released under the GPL. Running it to produce research results places no obligation on your results — only on distributed software.
Metadata
Release files for gliostitch 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| gliostitch-0.1.0.tar.gz | 59.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gliostitch-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 136.5 kB
Release files / gliostitch-0.1.0.tar.gz
| Download URL | gliostitch-0.1.0.tar.gz |
|---|---|
| Size | 59.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
92944156d8c526664cbfcc705df5b69df000e6794075ef0d33f402139288eb16
|
|
BLAKE2b-256 checksum How to use checksums |
0be55d01f3a641fba06da1a14f5610c08dc9fc2dcdc491dc5e2191eed94e521d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency logRelease files / gliostitch-0.1.0-py3-none-any.whl
| Download URL | gliostitch-0.1.0-py3-none-any.whl |
|---|---|
| Size | 77.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b616d50a246449e24e887f03444bacf48c6563fcde742a23ee1e6bfad46c9ed0
|
|
BLAKE2b-256 checksum How to use checksums |
cc2c2e8d7ecf30d0a10ac6254326fe0c6fdf798b827be642b6900cdba5eeb4ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency logSecurity for gliostitch 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for gliostitch-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.