zareenz741's picture
download
raw
8.07 kB
#!/usr/bin/env python3
"""Generate statistical overview of all downloaded MRI datasets."""
import os, re, glob, csv, json
from collections import Counter
import pandas as pd
ROOT = "/home/MRI-DataSet"
def banner(s):
print()
print("=" * 78)
print(s)
print("=" * 78)
def describe_ages(label, ages_years, extra=""):
if not ages_years:
print(f" {label}: no age data")
return None
s = pd.Series(ages_years)
print(f" {label}: n={len(s)} mean={s.mean():.2f}y median={s.median():.2f}y "
f"std={s.std():.2f} range={s.min():.2f}{s.max():.2f}y {extra}")
return s
def age_histogram(title, ages_years, bins=None):
if bins is None:
bins = [(0, 3), (3, 6), (6, 10), (10, 14), (14, 18), (18, 99)]
counts = []
for lo, hi in bins:
n = sum(1 for a in ages_years if lo <= a < hi)
counts.append(n)
print(f"\n Age histogram ({title}):")
total = len(ages_years) or 1
for (lo, hi), n in zip(bins, counts):
bar = "#" * int(50 * n / total)
label = f"{lo}{hi}y" if hi < 99 else f"{lo}+"
print(f" {label:>6} {n:>4} {bar}")
return counts
def analyse_bcp():
banner("DataSet-1 — Baby Connectome Project (BCP)")
meta_csv = os.path.join(ROOT, "DataSet-1", "meta.csv")
df = pd.read_csv(meta_csv, sep=";")
t1_dir = os.path.join(ROOT, "DataSet-1", "T1_only")
on_disk = {p.rstrip("/").split("/")[-1]
for p in glob.glob(os.path.join(t1_dir, "s*/"))}
df["on_disk"] = df["image_id"].isin(on_disk)
print(f" Metadata rows: {len(df)} | on-disk T1 scans: {df['on_disk'].sum()} "
f"| missing: {len(df) - df['on_disk'].sum()}")
print(f" Age unit: months (converted to years below)")
print(f" Group split: {dict(Counter(df['group']))}")
print(f" Myelinisation: {dict(Counter(df['myelinisation']))}")
ages_y = (df.loc[df["on_disk"], "age"] / 12).tolist()
describe_ages("AGE (on-disk scans)", ages_y)
# age in months histogram
ages_m = df.loc[df["on_disk"], "age"].tolist()
counts = {}
for lo, hi, label in [(0, 6, "0–6m"), (6, 12, "6–12m"), (12, 18, "12–18m"),
(18, 24, "18–24m"), (24, 36, "24–36m"), (36, 999, "36m+")]:
counts[label] = sum(1 for a in ages_m if lo <= a < hi)
print("\n Age histogram (months):")
total = len(ages_m) or 1
for k, v in counts.items():
bar = "#" * int(50 * v / total)
print(f" {k:>7} {v:>4} {bar}")
# diagnosis counts
diag_counts = Counter()
for d in df.loc[df["on_disk"], "diagnosis"].dropna():
for tok in re.split(r"[;,]", str(d)):
tok = tok.strip()
if tok:
diag_counts[tok] += 1
top = diag_counts.most_common(8)
print(f"\n Top diagnoses: {top}")
return ages_y, "0–3y (0–36 months)"
def analyse_calgary():
banner("DataSet-2 — Calgary Preschool")
xlsx = os.path.join(ROOT, "DataSet-2", "metadata",
"Calgary_Preschool_Dataset_Updated_20200213.xlsx")
df = pd.read_excel(xlsx)
age_col = "Age (Years)"
sex_col = "Biological Sex (Female = 0; Male = 1)"
# On-disk scan IDs come from directory names:
t1_dir = os.path.join(ROOT, "DataSet-2", "T1_Dataset")
on_disk_scans = set()
for subj in os.listdir(t1_dir):
sd = os.path.join(t1_dir, subj)
if os.path.isdir(sd):
for scan in os.listdir(sd):
if os.path.isdir(os.path.join(sd, scan)):
on_disk_scans.add(scan)
df["on_disk"] = df["ScanID"].astype(str).isin(on_disk_scans)
print(f" Metadata rows: {len(df)} | on-disk scans: {df['on_disk'].sum()} "
f"| unique children: {df.loc[df['on_disk'],'PreschoolID'].nunique()}")
print(f" Sex split (on-disk): M={(df.loc[df['on_disk'],sex_col]==1).sum()} "
f"F={(df.loc[df['on_disk'],sex_col]==0).sum()}")
ages = df.loc[df["on_disk"], age_col].dropna().tolist()
describe_ages("AGE (years, on-disk scans)", ages)
age_histogram("years", ages)
return ages, "~2–8y"
def analyse_ds002726():
banner("DataSet-3 — OpenNeuro ds002726 (Gifted Children Study)")
# No participants.tsv downloaded - only what's in BIDS description
sub_dirs = sorted(glob.glob(os.path.join(ROOT, "DataSet-3", "sub-*/")))
print(f" On-disk subjects: {len(sub_dirs)} (01–15 gifted, 16–29 controls per README)")
print(" Ages: NOT PROVIDED in dataset (no participants.tsv in this OpenNeuro release)")
print(" Per PDF reference: middle childhood ~6–10y; paper: ranged 7.29–12.39y (mean ~9.4)")
return [], "~6–12y (per paper, not verified from files)"
def analyse_ds000248():
banner("DataSet-4 — OpenNeuro ds000248 (MNE-Sample-Data, NOT ADHD-200)")
print(" Subjects: 1 (MEG/EEG tutorial sample; adult researcher)")
print(" Age: not specified (n/a in participants.tsv)")
print(" PDF expected: 585 healthy controls 7–18y — wrong dataset, see note")
return [], "n/a"
def analyse_ptbp():
banner("DataSet-5 — PTBP (Independent Test Set)")
csvp = os.path.join(ROOT, "DataSet-5", "ptbp_summary_demographics.csv")
df = pd.read_csv(csvp)
cols = df.columns.tolist()[:15]
# On-disk scans: T1_Anatomy/PEDS###/YYYYMMDD/Anatomy/*_t1.nii.gz
t1_root = os.path.join(ROOT, "DataSet-5", "T1_Anatomy")
on_disk = set()
for subj in os.listdir(t1_root):
sd = os.path.join(t1_root, subj)
if os.path.isdir(sd):
for sess in os.listdir(sd):
if os.path.isdir(os.path.join(sd, sess)):
on_disk.add((subj, str(sess)))
df = df[["SubID", "ScanDate", "AgeAtScan", "Sex", "FullScaleIQ"]].copy()
df["ScanDateStr"] = df["ScanDate"].astype(str)
df["on_disk"] = df.apply(lambda r: (r["SubID"], r["ScanDateStr"]) in on_disk, axis=1)
print(f" Metadata rows: {len(df)} | on-disk T1 scans: {df['on_disk'].sum()} "
f"| unique children: {df.loc[df['on_disk'],'SubID'].nunique()}")
m = (df.loc[df["on_disk"], "Sex"] == "M").sum()
f = (df.loc[df["on_disk"], "Sex"] == "F").sum()
print(f" Sex split (on-disk): M={m} F={f}")
ages = df.loc[df["on_disk"], "AgeAtScan"].dropna().tolist()
describe_ages("AGE (years, on-disk scans)", ages)
age_histogram("years", ages)
iq = df.loc[df["on_disk"] & df["FullScaleIQ"].notna(), "FullScaleIQ"].tolist()
if iq:
s = pd.Series(iq)
print(f"\n Full-Scale IQ: n={len(s)} mean={s.mean():.1f} std={s.std():.1f} "
f"range={s.min()}{s.max()}")
return ages, "7–18y"
def combined_summary(by_ds):
banner("COMBINED AGE COVERAGE (0–18+ yrs)")
bins = [(0, 3), (3, 6), (6, 10), (10, 14), (14, 18), (18, 99)]
labels = [f"{lo}{hi}y" if hi < 99 else f"{lo}+" for lo, hi in bins]
header = ["Dataset", "N"] + labels
rows = []
grand_total = [0] * len(bins)
for name, (ages, _range) in by_ds.items():
if not ages:
row = [name, "0"] + ["–"] * len(bins)
else:
counts = [sum(1 for a in ages if lo <= a < hi) for lo, hi in bins]
row = [name, str(len(ages))] + [str(c) for c in counts]
for i, c in enumerate(counts):
grand_total[i] += c
rows.append(row)
rows.append(["COMBINED", str(sum(grand_total))] + [str(c) for c in grand_total])
widths = [max(len(r[i]) for r in [header] + rows) for i in range(len(header))]
def fmt(r):
return " ".join(v.ljust(widths[i]) for i, v in enumerate(r))
print(fmt(header))
print(fmt(["-" * w for w in widths]))
for r in rows:
print(fmt(r))
def main():
by_ds = {}
by_ds["DataSet-1 BCP"] = analyse_bcp()
by_ds["DataSet-2 Calgary"] = analyse_calgary()
by_ds["DataSet-3 ds002726"] = analyse_ds002726()
by_ds["DataSet-4 ds000248"] = analyse_ds000248()
by_ds["DataSet-5 PTBP"] = analyse_ptbp()
combined_summary(by_ds)
if __name__ == "__main__":
main()

Xet Storage Details

Size:
8.07 kB
·
Xet hash:
b064fd9a08c59e90316572b99224dc7e3e58cdc47f0f5ee4bd320f95fc4055a0

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.