File size: 54,910 Bytes
0079804
 
 
 
 
 
 
 
 
 
 
c0a7163
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
 
 
 
 
 
 
 
 
 
 
 
 
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
3acc658
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
0079804
 
 
c0a7163
0079804
 
 
 
 
 
 
 
 
c0a7163
 
0079804
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
 
 
0079804
 
 
 
 
 
 
 
 
 
 
 
c0a7163
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3acc658
0079804
 
 
3acc658
 
 
 
 
 
 
 
 
0079804
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
 
0079804
 
 
c0a7163
 
 
 
 
 
 
 
0079804
 
 
 
 
 
c0a7163
0079804
 
 
 
 
 
 
 
c0a7163
0079804
c0a7163
 
 
 
 
 
 
 
 
 
 
 
 
 
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
0079804
c0a7163
0079804
 
 
 
 
 
c0a7163
 
 
0079804
c0a7163
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
0079804
 
c0a7163
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3acc658
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
 
0079804
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c0a7163
 
0079804
c0a7163
 
 
0079804
 
 
 
 
c0a7163
 
0079804
 
 
c0a7163
 
 
 
 
 
 
0079804
 
c0a7163
0079804
 
c0a7163
 
0079804
 
 
 
 
 
 
 
c0a7163
0079804
 
 
 
 
 
0673175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3acc658
0673175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0079804
c0a7163
0079804
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
# NeuroBridge Enterprise — Sıfırdan Tam Anlatı

> Bu döküman, projeye hiç bakmamış birine her şeyi sırayla anlatır: probleme neden el attık, hangi parçaları neden kullandık, ne nasıl çalışıyor, jüriye ne göstereceğiz. Türkçe.

**Canlı demo:** https://huggingface.co/spaces/mekosotto/hackathon
**Embed (temiz Streamlit):** https://mekosotto-hackathon.hf.space

---

## 1. Tek Cümleyle Ne Yaptık?

Üç farklı klinik veri tipini (molekül / EEG sinyali / MRI görüntüsü) tek bir API + tek bir web arayüzü arkasında işleyen, her tahmin için **etiket + güven skoru + kalibrasyon + drift sinyali + MLflow izlenebilirlik bilgisi + doğal-dilde AI açıklaması** döndüren, MRI tarafında dışarıda eğitilecek volumetrik deep-learning modelini ONNX üzerinden `POST /predict/mri` ile sisteme bağlayan, RAG destekli agent yüzeyiyle pipeline araçlarını orkestre eden ve jüri demosu için olası çökme noktalarını "kill-switch" ile koruyan bir B2B "Living Decision System" inşa ettik.

Hackathon teması: **"Building AI Systems for Neurotechnology & Health"** — ve jüri 6 boyutta puanlıyor (Problem Depth, System Quality, Robustness, Interaction, Execution, Creativity). Her boyutu spesifik feature'larla cevapladık. Detayları aşağıda.

---

## 2. Hangi Problemi Çözüyoruz?

Hackathon spec'i (Slayt 3-4) şunu söylüyor: gerçek dünyadaki klinik ML pipeline'ları üç temel sorundan kırılıyor:

1. **Veri Drift'i** — Aynı modelin farklı hastanelerin MRI cihazlarında tahmin doğruluğu çok değişiyor (cihaz/site bias'ı).
2. **Eksik Modaliteler** — Bir hastanın MRI'ı var ama EEG'si yok, ya da tam tersi. Pipeline'lar bunlara uyamıyor.
3. **Artefaktlar** — Ham EEG sinyali göz kırpma, kas hareketi, line noise gibi "kirlilikler" içeriyor; ham hâliyle ML'e besleyemezsin.

Üstüne hackathon'un "What's Actually Broken" slaytı 3 myth daha söylüyor:
- *Dashboards ≠ Understanding* — sadece tablo/grafik göstermek anlamak değil
- *Clean Data ≠ Reality* — sadece curated test setinde çalışan model gerçeği temsil etmiyor
- *Black-Box AI ≠ Trust* — açıklayamadığın bir model klinikte güvenilemez

Yani jüri 3 teknik problem + 3 felsefik myth bekliyor. NeuroBridge **6'sını birden** ele alıyor:

| Problem | Bizim çözümümüz |
|---|---|
| Data Drift | MRI ComBat harmonization (3290× site-gap reduction sayısal kanıt) + runtime drift z-score |
| Missing Modalities | Üç pipeline bağımsız çalışır, biri olmasa diğerleri çalışmaya devam eder |
| Artifacts | EEG için MNE + ICA artefakt temizleme, BBB için invalid SMILES drop+log |
| Dashboards ≠ Understanding | Her grafik bir hikâye anlatıyor (KDE convergence "neden ComBat şart?"i tek bakışta gösterir) |
| Clean Data ≠ Reality | "Test Edge Cases" dropdown'da invalid + boş + OOD molekül probe'ları, sistem çökmüyor |
| Black-Box ≠ Trust | SHAP attribution + calibration bin + drift z-score + MLflow provenance + LLM rationale = 5 katmanlı şeffaflık |

---

## 3. Üç Modalitenin Detayı

Hackathon "Example Domains to Explore" slaytında **"Complex Biological Systems — modeling systems like the blood-brain barrier where biology and AI meet"** diyor. Tam bunu hedefledik, üstüne EEG ve MRI ekledik.

### 3.1 Molecule (BBB — Blood-Brain Barrier Permeability)

**Ne yapıyor?** Bir molekülün SMILES (Simplified Molecular Input Line Entry System) string'ini veriyorsun, sistem o molekülün kan-beyin bariyerinden geçip geçemeyeceğini tahmin ediyor. İlaç keşfinde MSS (merkezi sinir sistemi) ilaçları için kritik bir filtreleme adımı.

**Pipeline:**
1. **SMILES validation** — RDKit ile parse edilebilir mi? Edilemezse drop + WARNING log.
2. **Morgan fingerprint** — 2048-bit fingerprint vektörü çıkarıyoruz (RDKit `AllChem.GetMorganFingerprintAsBitVect`, radius=2). Yapısal "barkod" gibi düşün.
3. **Random Forest classifier** — sklearn 1.5.1, 100 ağaç, deterministik (random_state=42, n_jobs=1).
4. **80/20 stratified split** — train sırasında calibration ve train-time stats için ayrı bir test set ayrılıyor.
5. **Calibration bins hesaplama** — 6 confidence threshold (0.50, 0.60, 0.70, 0.75, 0.80, 0.90) için held-out test set'inde precision + support kaydediliyor.
6. **Train-time stats** — model'in kendi predict_proba çıktısının median + std değeri kaydediliyor (drift detection için referans).
7. **Joblib persist** — model `data/processed/bbb_model.joblib` olarak diske yazılıyor; `_neurobridge_fp_cols`, `_neurobridge_calibration`, `_neurobridge_train_stats` öznitelikleriyle birlikte.

**Inference (POST /predict/bbb):**
- SMILES → fingerprint → predict_proba → label + confidence
- SHAP TreeExplainer ile top-k feature attribution (hangi fingerprint bit'leri kararı pushladı?)
- Calibration bin lookup (bu confidence aralığında precision ne?)
- Drift z-score hesaplama (deque'a confidence ekle, trailing-100 median'ı train-time median'a göre z-score)
- Response: `{label, label_text, confidence, top_features, calibration, drift_z, rolling_n, provenance}`

**Neden Random Forest, neden derin öğrenme değil?**
- BBB veri seti küçük (yaklaşık 2000 örnek), RF bu boyutta deep learning'i yener
- SHAP TreeExplainer **exact** — sampling yok, deterministik, jüri "neden bu cevap?" sorusuna kesin cevap alabiliyor
- Hackathon süresi içinde train + retrain hızlı

### 3.2 Signal (EEG)

**Ne yapıyor?** Ham EEG kaydını (FIF veya EDF formatı) alıyor, göz kırpma artefaktlarını temizliyor, sabit-süreli epoch'lara bölüyor, her epoch için PSD (Power Spectral Density) + istatistiksel feature'lar üretiyor.

**Pipeline:**
1. **Read** — MNE-Python (`mne.io.read_raw_fif/edf`)
2. **Bandpass filter** — 0.5-40 Hz arası, line noise ve DC drift'i temizler
3. **ICA decomposition** — `mne.preprocessing.ICA(n_components=15)`, sinyali bağımsız bileşenlere ayırır
4. **EOG artifact rejection** — EOG kanalıyla |correlation| ≥ 0.5 olan ICA bileşenlerini drop et (göz kırpmaları)
5. **Reconstruct** — temizlenmiş bileşenlerden sinyali geri inşa et
6. **Epoching** — 2 saniyelik fixed-duration window'lara böl
7. **Feature extraction** — her epoch × her kanal için: 5 frekans bandının (delta, theta, alpha, beta, gamma) power'ı + 4 istatistik (mean, std, skew, kurtosis)

**Neden MNE? Neden ICA?**
- MNE-Python EEG/MEG işlemenin de facto bilimsel standardı (Brain Imaging Data Structure / BIDS uyumlu)
- ICA artefakt temizleme klinik çalışmalarda kanıtlanmış yöntem (PCA göz kırpmasını yakalayamaz çünkü orthogonal değil, ICA bağımsızlık varsayımıyla göz hareketini bağımsız kaynak olarak izole eder)

### 3.3 Image (MRI — ComBat Harmonization)

**Ne yapıyor?** Çoklu hastanenin MRI taramalarını alıp her ROI (Region of Interest) için intensity istatistikleri çıkarıyor, sonra **ComBat** algoritmasıyla site/cihaz bias'ını kaldırıyor.

**Pipeline:**
1. **Read** — nibabel ile NIfTI (.nii.gz) yükleme
2. **Brain masking** — basit intensity threshold, kafatası ve hava bölgelerini ayırma
3. **ROI feature extraction** — N×N×N ROI grid'i, her ROI için mean / std / median / skew / kurtosis
4. **Variance-aware ComBat split** — std ≤ `_MIN_VAR_THRESHOLD` olan feature'ları zero-var fallback'e ayır (ComBat onları işleyemez)
5. **ComBat harmonization**`neuroHarmonize` library'siyle her feature'ın site-bağımlı mean/std'ini referans dağıtıma çek
6. **Site-gap KPI** — ilk feature'ın per-site mean'lerinin range'i (max − min). Pre-ComBat ~5.0, Post-ComBat ~0.0015 → **3290× collapse**.

**Diagnostics endpoint (POST /pipeline/mri/diagnostics):**
Pipeline iki kez çalışır (pre + post ComBat) ve long-format DataFrame döner:
- `subject_id`, `site`, `feature`, `feature_value`, `harmonization_state` (Pre-ComBat / Post-ComBat)
- Streamlit UI altair faceted KDE plot'unda her site farklı renkte. Pre paneli'nde renkli bölgeler ayrışık, Post paneli'nde üst üste binerler — **harmonizasyonun görsel kanıtı**.

**Neden ComBat?** ComBat orijinal olarak gen ekspresyon batch effect'leri için icat edildi (Johnson et al. 2007), neuroimaging'e (Fortin et al. 2017, 2018) uyarlandı. Empirical Bayes yaklaşımıyla site-bağımlı location + scale parametrelerini öğreniyor, **biological signal'i koruyarak** site bias'ını kaldırıyor. Tek başına z-score normalization farkı tam kapatamaz; ComBat hem mean hem variance'ı düzeltir.

### 3.4 MRI Image Deep Learning Modeli (External Training → ONNX)

MRI için eğiteceğimiz deep-learning model bu repoda train edilmiyor. Eğitim ayrı GPU ortamında yapılacak, export edilen ONNX artifact'i NeuroBridge runtime'a takılacak:

- Artifact yolu: `data/processed/mri_model.onnx`
- Override: `MRI_MODEL_PATH=/path/to/model.onnx`
- Input: `.nii` / `.nii.gz` NIfTI volume
- Preprocess: 3D finite-volume validation → trilinear resize (`64×64×64` default) → non-zero voxel z-score normalization → `[1, 1, D, H, W]` float32 tensor
- Output: `[1, C]` class vector; logits veya probability kabul edilir
- API: `POST /predict/mri`

Bu ayrım önemli: `src/pipelines/mri_pipeline.py` çok-merkezli MRI verisini temizleyip ComBat ile harmonize eder; `src/models/mri_model.py` ise klinik sınıflandırma için dışarıda eğitilmiş volumetrik modeli inference aşamasında çalıştırır. Artifact yoksa endpoint HTTP 503 döner ve operatöre ONNX export yolunu söyler.

---

## 4. "Living Decision System" — Yedi Şeffaflık Katmanı

Bir BBB tahmini yaptığında karar kartında 7 ayrı sinyal görüyorsun. Her biri bir "neden inanayım sana?" sorusunu cevaplar:

| # | Sinyal | Ne diyor? | Nasıl üretildi? |
|---|---|---|---|
| 1 | **MLflow Provenance Badge** | Bu tahmin v1 modelinden, run_id `abc123`, n=4 örnekle eğitilmiş, tarih şu | `mlflow.search_runs(experiments=["bbb_pipeline"])` cache'lenir |
| 2 | **Verdict (label)** | permeable / non-permeable | `argmax(predict_proba)` |
| 3 | **Confidence** | %82 | `max(predict_proba)` |
| 4 | **Calibration caption** | "≥75% güven üreten tahminler hold-out test'te %92 precision (n=18)" | Train sırasında 80/20 split, 6 threshold bin'i, lookup |
| 5 | **Drift caption** | "trailing-100 confidence median +0.42σ from train (within range)" | Module-level `deque(maxlen=100)` + train-time median/std |
| 6 | **Top SHAP attributions bar chart** | Hangi fingerprint bit'leri kararı pushladı? | `shap.TreeExplainer(model).shap_values(X)` exact, 3-branch dispatch (sklearn version compat) |
| 7 | **AI Assistant rationale** (opsiyonel) | "Predicted **permeable** with 82% confidence. Top SHAP attributions toward this label..." | OpenRouter free-tier fallback chain (10 model, head: `inclusionai/ling-2.6-1t:free`) — `user_question` diline matchler; key yoksa / chain tükenmişse deterministik template |

Bu yedi katman birlikte "Black-Box AI ≠ Trust" mit'ini çürütür: kara kutu değil, **camdan kutu**.

---

## 5. Mimari — "Tek API Surface, Üç Pipeline"

### 5.1 Bileşenler

```
┌──────────────────────────────────────────────────────────┐
│  Streamlit Dashboard  (port 7860, public)                │
│  5 tab: Molecule / Signal / Image / AI Assistant /       │
│         Experiments                                      │
└────────────────────┬─────────────────────────────────────┘
                     │ httpx (in-container 127.0.0.1:8000)

┌──────────────────────────────────────────────────────────┐
│  FastAPI  (port 8000, internal)                          │
│                                                          │
│  /pipeline/{bbb,eeg,mri}        → batch processing       │
│  /pipeline/mri/diagnostics      → pre/post ComBat KPIs   │
│  /predict/bbb                   → single-molecule infer  │
│  /predict/mri                   → volumetric ONNX infer  │
│  /explain/{bbb,eeg,mri}         → LLM/template rationale │
│  /experiments/runs              → MLflow run list        │
│  /experiments/diff              → side-by-side run diff  │
│  /agent/run                     → pipeline tools + RAG   │
│  /health                        → liveness check         │
└─┬────────────┬────────────┬────────────┬─────────────────┘
  │            │            │            │
  ▼            ▼            ▼            ▼
bbb_pipeline eeg_pipeline mri_pipeline llm.explainer
+ bbb_model  + MNE/ICA    + neuroHarm   + OpenRouter SDK
+ shap                                  + template fallback
```

Agent yüzeyi (`src/agents/orchestrator.py`) LLM function-calling'i dener; model tool çağrısını atlar veya yanlış sıraya girerse guarded workflow devreye girer. Deterministik router (`src/agents/routing.py`) bir pipeline seçer, ilgili tool'u çalıştırır, `retrieve_context` ile FAISS/RAG bağlamını alır ve son sentezi yine aynı API kontratıyla döndürür.

### 5.2 Process Modeli

Tek Docker container'da supervisord iki process çalıştırıyor:
- **uvicorn** → FastAPI :8000 (internal)
- **streamlit run** → :7860 (public, HF Spaces routes here)

Streamlit, container içinde `httpx.post("http://127.0.0.1:8000/...")` ile FastAPI'a konuşuyor. Dışarıya yalnızca 7860 açık. Bu sade ama production-aware mimari (FastAPI doğrudan dışarı açık değil; Streamlit bir BFF/proxy katmanı).

### 5.3 Persistence

| Veri | Yer | Yaşam süresi |
|---|---|---|
| Trained BBB model (joblib) | `data/processed/bbb_model.joblib` | Container build-time'da train, image içinde gömülü |
| MRI DL model (ONNX) | `data/processed/mri_model.onnx` veya `MRI_MODEL_PATH` | Dış eğitim ortamından export edilir; runtime yalnızca load + inference yapar |
| RAG FAISS index | `data/processed/faiss_index/` | Build-time ingest + container startup guard ile eksikse yeniden oluşturulur |
| MLflow runs | `mlruns/` (default backend: SQLite) | Runtime ortamına bağlı; `NEUROBRIDGE_DISABLE_MLFLOW=1` ile kapatılabilir |
| Worker drift deque | In-memory (`collections.deque(maxlen=100)`) | Container restart'a kadar; Worker restart = state reset |
| Streamlit session state | Browser sekmesi | Sekme kapanana kadar |

---

## 6. Neden Bu Stack? (Karar Gerekçeleri)

### 6.1 Backend: FastAPI

- **Type-safe schemas:** Pydantic v2 ile request/response Pydantic modelleri otomatik validation + 422 errors
- **OpenAPI auto-generation:** `/docs` endpoint'i jüri'ye Swagger UI sunar, integration documentation ücretsiz
- **Async-ready:** Bizim use case sync ama gerekirse async pipeline kolayca eklenebilir
- **Test-friendly:** `fastapi.testclient.TestClient` API testlerinin çoğunu gerçek network olmadan çalıştırıyor
- **Alternatif neden değil:** Flask çok ham (her şeyi elden yazarsın), Django overkill (admin + ORM gereksiz)

### 6.2 Frontend: Streamlit

- **Python-only:** React/Vue öğrenme yükü yok, hackathon hızı kritik
- **Built-in widgets:** st.tabs, st.selectbox, st.metric, st.altair_chart — her şey hazır
- **Session state:** Multi-tab persistence için doğrudan API
- **Native Python data integration:** pandas DataFrame, altair Chart object'leri direkt render
- **Alternatif neden değil:** Gradio daha çok ML demo'larına yönelik (tek input/output odaklı), bizim 5-tab dashboard ihtiyacımıza Streamlit daha uygun

### 6.3 Model: scikit-learn Random Forest

- **Veri seti boyutu:** ~2000 örnek, deep learning aşırı kapasite
- **Determinism:** `n_jobs=1, random_state=42` ile bit-identical reproducibility
- **SHAP exact:** TreeExplainer sampling yok, jüri "bu sayı tam olarak nereden?" sorusunda kesin cevap
- **Joblib persistence:** custom attribute'lar (`_neurobridge_*`) save/load roundtrip-safe
- **Alternatif neden değil:** XGBoost biraz daha iyi olabilirdi ama dependency yükü +50MB, ROI yok

### 6.4 Explainability: SHAP

- **Game-theoretic foundation:** Shapley values fairness axioms'a uyar (Lloyd Shapley 1953, Nobel 2012)
- **Local + global:** Hem tek tahmin hem feature importance dağılımı için kullanılabilir
- **TreeExplainer exact:** RF için kapalı-form çözüm var, milyonlarca SHAP value'da bile tutarlı
- **Alternatif neden değil:** LIME approximation, tree ensemble'larda exact'ten daha az güvenilir

### 6.5 Multi-site Harmonization: ComBat (neuroHarmonize)

- **Domain-validated:** ENIGMA Consortium ve birçok multi-site neuroimaging study tarafından kullanılır
- **Empirical Bayes:** Hierarchical model, az veriyle bile robust
- **Biology-preserving:** Covariate'lere koşullu (age, sex, diagnosis), site bias'ı kaldırırken biological variance'ı tutar
- **Alternatif neden değil:** Z-score normalization sadece location düzeltir, scale farkı kalır; CycleGAN denemeleri var ama train zamanı ve hyperparameter complexity hackathon'a uygun değil

### 6.6 LLM Provider: OpenRouter (free-tier fallback chain, 10 model)

- **Free tier:** Hackathon süresince ücret yok, jüri demosunda da maliyet riski yok
- **OpenAI-compatible:** `openai==1.51.0` SDK doğrudan çalışır, custom HTTP client yok
- **Smartest → smallest fallback chain:** `src/llm/explainer.py` içindeki `_DEFAULT_FREE_MODEL_CHAIN` 10 free-tier id tutar (head: `inclusionai/ling-2.6-1t:free` ~1T flagship → tail: `poolside/laguna-xs.2:free`). Status-code classification:
  - `429 / 402 / 403 / 404 / 5xx` → bir sonraki modele geç
  - `400` → o modelin prompt-shape mismatch'i, sonrakine geç
  - `401` → key bozuk, tüm chain için anlamsız, **template'e düş + actionable WARNING** (key rotate at https://openrouter.ai/keys)
  - Network/timeout → switching models won't help → template
- **Runtime override:** `OPENROUTER_FREE_MODELS="modelA,modelB"` env variable ile chain'i değiştirebilirsin (model availability OpenRouter'da haftalık değişiyor; verify with `python scripts/diagnose_openrouter.py`).
- **Hybrid contract:** API key yoksa, kill-switch açıksa veya tüm chain tükenirse **deterministik template path**'e düşer — demo gününde **asla çökmez**
- **Prompt design (intent-split):** Caller `user_question` verirse model'a "soru diliyle cevap ver, doğrudan soruyu cevapla, off-topic ise kısa-conversational kal" denir; vermezse default 2-4 cümle paper-style rationale fallback'i devreye girer.
- **Diagnostics:** `GET /diag/openrouter` (FastAPI) key presence (length + 12-char prefix only), kill-switch state, chain head, ve 8-token probe sonucunu döner. Streamlit'te sidebar "🔧 Diagnose LLM" butonu olarak surface'lenir.
- **Alternatif neden değil:** OpenAI direct API ücretli, Anthropic API key yoktu, lokal Ollama demo gününde 1B model indirme/load riski

### 6.7 Tracking: MLflow

- **Industry standard:** Databricks ekosistemi, çoğu MLOps tool'u MLflow runs'ı okuyabilir
- **Auto-logging integration:** sklearn modelleri için minimal ek kod
- **Two-run diff:** API endpoint'imiz (`/experiments/diff`) MLflow `get_run` üzerine basit bir wrapper
- **Alternatif neden değil:** Weights & Biases güzel ama cloud-only / paid, hackathon'da self-host edebilen MLflow daha uygun

### 6.8 Container: Docker (HF Spaces Docker SDK)

- **Self-contained:** Tüm dependencies + kod + data tek image'da
- **Portable:** Aynı image local'de, HF'de, ileride Railway/AWS'de çalışır
- **Build-time artifacts:** BBB model train edilir, RAG index ingest edilir; cold start'ta ana demo artifact'leri hazır gelir
- **Runtime guard:** `docker-entrypoint.sh`, host volume boş geldiyse fixture data'dan BBB modeli ve FAISS index'i yeniden üretir
- **Supervisord:** İki process tek container'da minimal overhead
- **Alternatif neden değil:** docker-compose multi-container çözüm güzel ama HF Spaces tek container istiyor

### 6.9 Agent + RAG

- **Tool-first orchestration:** Agent'ın kullanabildiği tool'lar pipeline surface'in aynısı: BBB predict, EEG pipeline, MRI pipeline ve RAG retrieval.
- **Guarded workflow:** LLM function-calling başarısız olursa API deterministik router ile pipeline → retrieval → synthesis sırasını zorlar; demo sırasında "agent tool çağırmadı" riski kalmaz.
- **RAG stack:** `fastembed` (`BAAI/bge-small-en-v1.5`, 384 dim) + `faiss-cpu` (`IndexFlatIP`, L2 normalize edilmiş cosine search). Torch bağımlılığı yok.
- **Knowledge base:** `data/knowledge_base/` altındaki `.md`, `.txt`, `.pdf` dosyaları `python -m src.rag.ingest` ile `data/processed/faiss_index/` altına yazılır.
- **Default agent model:** `NEUROBRIDGE_AGENT_MODEL` override edilebilir; `OPENROUTER_API_KEY` yoksa `/agent/run` HTTP 503 döner.

---

## 7. Test Disiplini: TDD + Subagent-Driven Development

### 7.1 Sayılar

- **242 passed, 2 skipped** (Windows / Python 3.11 doğrulaması)
- 8 günlük sprint, ~50 atomik commit
- Her test-bearing task **RED → GREEN → REFACTOR** disipliniyle yazıldı
- Her task ayrı bir Subagent (Claude Code) tarafından implementasyon edildi, ana ajan koordine + review

### 7.2 Test Dağılımı

```
tests/
├── core/                         logger, storage, tracking, determinism
├── pipelines/
│   ├── test_bbb_pipeline.py      SMILES validation, FP, drop+log, idempotence
│   ├── test_eeg_pipeline.py      filter, ICA, epoching, feature extraction
│   └── test_mri_pipeline.py      volume validation, masking, ComBat split, diagnostics
├── models/
│   ├── test_bbb_model.py         train, save/load, predict, SHAP, calibration, train_stats
│   └── test_mri_model.py         NIfTI preprocess + ONNX inference contract
├── api/                          route contracts, error mapping, drift/calibration/provenance
├── llm/                          template determinism, modality dispatch, kill-switch
├── rag/                          ingest, empty-index behavior, retrieval
├── agents/                       tool schemas, guarded orchestration, agent route
├── frontend/                     Streamlit module import smoke
└── deploy/                       Dockerfile.hf / startup contract

Total: 242 passed, 2 skipped
```

### 7.3 UserWarning Gate

Sklearn / Pydantic warnings sessizce kalmasın diye:
```bash
pytest -W error::UserWarning tests/
```
0 escalation. Day-7'de Pydantic'in `model_*` protected-namespace warning'ini yakaladık (ModelProvenance schema'sı `model_version` field'ı yüzünden); inline ConfigDict patch'iyle kapattık.

### 7.4 TDD Disiplini Neden?

- Her feature'ın **kabul kriteri** test koduyla yazılıyor → spec ambigüitesi sıfır
- Implementation-first yapsak refactor cesareti olmaz
- Subagent dispatch yaparken her task'ın **net bitiş koşulu** var: "tests pass + lint clean"
- 242 passed / 2 skipped demosu jüri için "production-aware" sinyali

---

## 8. Robustness ("Real Conditions" altında ne yapar?)

Hackathon "Tested Under Real Conditions" diyor (Slayt 13: "Show performance with noisy, incomplete, or edge-case inputs — not only happy paths").

### 8.1 Edge-case dropdown (BBB tab, T1 of Day 6)

Streamlit'te 5 curated probe:
1. **Custom input (CCO)** — ethanol, baseline, "happy path"
2. **Invalid SMILES**`this_is_not_a_valid_molecule_at_all_!!` → API HTTP 400 → UI `st.warning` (recoverable, **çökme yok**)
3. **Empty string** — boundary condition, Pydantic kabul eder, RDKit reject eder
4. **Cyclosporine-like macrocycle** (~1.2 kDa, 11 residue) — OOD; eğitim setinde böyle bir şey görmedi, model **düşük confidence** ile hedge eder
5. **Decafluorobiphenyl** — extreme halogen density, rare scaffold

### 8.2 Graceful failure pattern

```python
try:
    result = _post("/predict/bbb", {...})
except httpx.HTTPStatusError as e:
    if e.response.status_code == 503:
        st.error("Model not loaded yet. Run trainer.")
    elif e.response.status_code == 400:
        # Robustness story: WARNING, not ERROR
        st.warning(f"API rejected input with HTTP 400 (no crash). Detail: ...")
    else:
        st.error(f"...")
```

400 → `st.warning` ayrımı önemli: jüri "sistem reject etti ama çökmedi" hikâyesini görsün, kırmızı ERROR yerine sarı WARNING.

### 8.3 Demo Lifelines (kill-switches + artifact overrides)

Demo gününde her şey ters gidebilir. Bu env variable'lar kritik senaryoları kontrollü hale getirir:

| Env | Etkisi |
|---|---|
| `NEUROBRIDGE_DISABLE_LLM=1` | OpenRouter çağrısı yapılmaz, deterministic template path'i her zaman cevap verir |
| `NEUROBRIDGE_DISABLE_MLFLOW=1` | MLflow lookup yapılmaz, provenance badge "—" gösterir, sistem çalışmaya devam eder |
| `BBB_MODEL_PATH=...` | Default `data/processed/bbb_model.joblib` yerine farklı yol |
| `MRI_MODEL_PATH=...` | Default `data/processed/mri_model.onnx` yerine dışarıda eğitilen ONNX artifact yolu |
| `OPENROUTER_API_KEY=...` | LLM explainer ve orchestrator agent'ı gerçek OpenRouter çağrılarıyla açar |
| `NEUROBRIDGE_AGENT_MODEL=...` | Agent'ın OpenRouter modelini override eder |

Docker image artık `NEUROBRIDGE_DISABLE_MLFLOW=1` değerini hard-code etmez; operatör ortamına göre açar/kapatır. LLM **default ON**`Dockerfile` ve `Dockerfile.hf` `NEUROBRIDGE_DISABLE_LLM`'i hard-code etmiyor; deployed Space `OPENROUTER_API_KEY` Secret'ı varsa free-tier chain'i kullanır, yoksa template'e düşer. LLM'i jüri demosunda %100 deterministik istersen Space → Settings → Variables → `NEUROBRIDGE_DISABLE_LLM=1` ekle. LLM'in hangi state'te olduğunu canlı görmek için sidebar'daki "🔧 Diagnose LLM" butonu (`GET /diag/openrouter`'a vurur) key presence + chain head + 8-token probe döner.

### 8.4 Drift detection

Predict her seferinde:
1. Confidence değeri `WORKER_CONFIDENCE_DEQUE: deque(maxlen=100)`'a append edilir
2. Eğer `len(deque) >= 10` ve model'de `_neurobridge_train_stats` varsa:
   ```
   drift_z = (rolling_median - train_median) / max(train_std, 1e-9)
   ```
3. UI'da:
   - `|z| < 1` → "within expected range"
   - `1 ≤ |z| < 2` → "mild distribution shift"
   - `|z| ≥ 2` → "significant shift, retrain recommended"

Bu "Adapt Over Time" katmanı (Living Systems pillar). Sistem **kendi tahminlerinin trainingden ne kadar saptığını bilir**.

---

## 9. UI: Editorial Dark + Cream Paper (Day 8)

### 9.1 Renk Sistemi

**Dark theme (default, Netflix-inspired):**
- Surfaces: `#0e0e10``#161618``#1e1e21``#2a2a2e` (4-step elevation)
- Accent: `#D2C4B1` (sand) — CTA, key data, brand mark
- Text: `#F5F2ED` primary, `#A8A29A` secondary, `#6B6660` tertiary
- Borders: `#2a2a2e`, strong `#3a3a3e`

**Light theme (Apple HIG editorial):**
- Surfaces: `#FAF7F2` paper bg, `#FFFFFF` cards, `#F5F0E8` inputs, `#EDE5D5` hover
- Accent: `#1e1e21` (charcoal) — high contrast against cream
- Sand `#D2C4B1` strong borders / dividers (ortada bir yerde, decorative warm contour)

**Theme toggle:** Sidebar'da `st.toggle("Dark mode")`. Session state'e yazar, CSS bloğu rebuilt edilir, altair theme re-register edilir, Streamlit otomatik rerun.

### 9.2 Tipografi

- **Display + Body:** Inter (Google Fonts, Apple SF benzeri, açık kaynak)
- **Monospace:** JetBrains Mono (run_id'ler, SMILES, SHAP feature isimleri, kod)
- **Scale:** 12 / 14 / 16 / 18 / 24 / 32 / 48 / 64
- **Tabular numerals:** KPI metrics ve confidence yüzdeleri için (`font-feature-settings: "tnum" on`) — sayılar her zaman sabit genişlikte hizalanır

### 9.3 Component Hierarchy

5 ana redesign:
1. **Hero strip** — büyük word-mark "Neuro**Bridge**" (Bridge sand renk), tagline, 3 status dot (api/mlflow/explainer)
2. **Tabs** — left-aligned, sand underline indicator (no boxes, Apple Music tarzı)
3. **Decision card** — provenance line (mono, küçük, gri) → big lowercase verdict (sand, 48px) → signals grid (calibration / drift) → SHAP frame
4. **KPI metrics** — 64px tabular numerals, mono uppercase eyebrows
5. **Altair charts** — registered "neurobridge" theme, sand-led category palette, transparent view, Inter typography

---

## 10. Hackathon 6-Boyut Jüri Skoru (Projeksiyon: ~96.8%)

| Boyut | Puan | Kanıt |
|---|---|---|
| **Problem Depth** | 9.5/10 | 3 zor real-world problem (BBB drug-discovery, EEG artifact, MRI multi-site domain shift); slayt 11'in "blood-brain barrier" örneğine doğrudan referans |
| **System Quality** | 9.7/10 | 242 passed / 2 skipped, TDD, 50+ atomik commit, FastAPI+Streamlit+MLflow+Docker, error mapping (400/404/422/503), lifeline gates |
| **Robustness** | 9.5/10 | Edge-case dropdown (5 probe), HTTP 400 → graceful warning, fallback chains everywhere |
| **Interaction** | 9.8/10 | 5 tab + edge-case probes + calibration caption + drift caption + AI Assistant chat (3 modalite × inline expander + standalone tab) |
| **Execution** | 9.8/10 | 8-day disciplined sprint + post-Day-8 hardening, atomic commits, AGENTS.md contract, README executive summary + demo recipe, all DoD checks green |
| **Creativity** | 9.7/10 | LLM hybrid (template fallback) + drift z-score + ComBat KDE faceted + "Living Decision System" framing + Track-1 multi-modal AI agents + Track-5 Experiments tab |
| **TOPLAM** | **58.0/60 (~96.8%)** | |

### "Living Systems — Your Edge" (Slayt 12, 4 Edge)

| Edge | Karşılığımız |
|---|---|
| **Adapt Over Time** | `WORKER_CONFIDENCE_DEQUE` + drift z-score + UI uyarıları (warming-up / numeric / mild / significant) |
| **Handle Uncertainty** | predict_proba confidence + 6-bin calibration + drift signal |
| **Interact With Users** | 5 tab + edge-case dropdown + AI Assistant 3-modalite |
| **Explain Decisions** | SHAP top-k + ComBat KDE viz + LLM/template rationale + provenance badge |

**4/4 pillar full** — Day 6'daki tek zayıflık (Adapt Over Time) Day 7'de kapatıldı.

### "What You Must Deliver" (Slayt 13)

- ✅ Working Prototype (FastAPI + Streamlit + Docker, end-to-end functional)
- ✅ Interactive System (5 tab, real-time predictions, custom SMILES, AI Assistant chat)
- ✅ Explanation of Behavior (7-layer transparency stack)
- ✅ Tested Under Real Conditions (242 passed / 2 skipped + edge-case dropdown probes)
- ❌ No slides-only — gerçek çalışan sistem
- ❌ No perfect-data-only — edge-case dropdown bunun kanıtı

---

## 11. 8 Günlük Sprint Özeti

| Gün | Ana Çıktı | Test Sayısı |
|---|---|---|
| Day 1 | Project scaffold + AGENTS.md contract + BBB pipeline (RDKit Morgan FP) + structured logger | 22 |
| Day 2 | EEG pipeline (MNE + ICA + epoching + feature extraction) | 36 |
| Day 3 | MRI pipeline (NIfTI + masking + ROI + ComBat harmonization) | 78 |
| Day 4 | FastAPI surface (`/pipeline/{bbb,eeg,mri}`) + MLflow tracking + Docker compose + Streamlit B2B dashboard | 142 |
| Day 5 | RandomForest BBB classifier + SHAP explainer + `/predict/bbb` endpoint + interactive Streamlit BBB tab | 158 |
| Day 6 | Edge-case dropdown + calibration metadata + ComBat diagnostics endpoint + altair faceted KDE | 165 |
| Day 7 | Drift detection (deque + z-score) + MLflow provenance badge + LLM explainer (OpenRouter hybrid) + AI Assistant tab | 175 |
| Day 8 | Multi-modal explain (`/explain/{eeg,mri}`) + Experiments tab (MLflow runs + diff) + HF Spaces deploy (Dockerfile.hf + supervisord) + README pitch craft | 184 |
| Day 9 | Agent/RAG hardening + guarded orchestration + Docker startup guard + Windows-safe MLflow tests + MRI ONNX decision layer (`/predict/mri`) | 242 passed, 2 skipped |

Her gün için ayrı plan ve spec dosyası: `docs/superpowers/plans/` ve `docs/superpowers/specs/`.

---

## 12. Demo Akışı (Jüri'ye 90 Saniye)

**Hazırlık:** Tarayıcıda https://mekosotto-hackathon.hf.space açık. Soldaki sidebar'da Dark mode toggle'ı dark'ta.

| t | Tab | Aksiyon | Söyleyeceğin |
|---|---|---|---|
| 0:00 | (giriş) | Hero strip'i göster | "NeuroBridge Enterprise — three modalities behind one decision system." |
| 0:05 | **Molecule** | "Custom input" → `CCO` → Predict | Decision card'ı göster, label + 82% confidence. |
| 0:15 | (aynı) | Calibration caption oku | "Predictions ≥80% confident are correct 92% of the time on held-out data — n=18." |
| 0:22 | (aynı) | Drift caption oku | "Trailing-100 confidence median is +0.42σ from train — within expected range." |
| 0:30 | (aynı) | Provenance badge oku | "MLflow run abc123, Model v1, n=4 — full audit trail." |
| 0:35 | (aynı) | "Massive OOD: cyclosporine-like macrocycle" → Predict | "Cyclosporine has 11 residues, ~1.2 kDa — way outside training distribution." |
| 0:45 | (aynı) | "Invalid SMILES" → Predict | "API rejects with HTTP 400, UI shows warning. **System never crashes.**" |
| 0:55 | **AI Assistant** | Preset "Why was this molecule predicted as permeable?" → Ask | "LLM rationale uses SHAP attributions + drift context — auditable source label." |
| 1:10 | **Image** | "Run ComBat diagnostics" | 3-metric strip: Pre 5.0 → Post 0.0015 → **3290× reduction**. |
| 1:20 | (aynı) | Faceted KDE'yi göster | "Each color is a hospital. Pre-ComBat panels diverge; Post panels converge." |
| 1:30 | **Experiments** | Tab'a geç, MLflow runs tablosunu göster | "Every train run is logged; pick any two for a metric/param diff." |

### 30-Saniyelik Drift Show (Standalone)

| t | Aksiyon | Jüri ne görür |
|---|---|---|
| 0:00 | Molecule tab. Drift caption: "warming up (0/10 buffered)" | Sistem henüz yeterli sample toplamadı |
| 0:05 | Hızlıca 10 kez `CCO` predict | 10. tahminden sonra drift z-score numeric değere döner |
| 0:18 | Cyclosporine OOD → 3 kez predict | Drift z-score büyür, "mild" veya "significant" tag'i çıkar |
| 0:30 | Sonuç | "System is online-aware — predicts AND knows when its predictions drift." |

---

## 13. Sıkça Sorulabilecek Sorular

### "Neden tek bir model değil de üç pipeline?"
Çünkü hackathon spec'i (Slayt 9-10, Tracks 2 + 3 + 4) **multi-modality** istiyor: "fuse EEG, imaging, behavioral, and clinical data". Tek modaliteli demo "Data Systems" track'inden zayıf puan alır. Üç bağımsız pipeline + tek API surface → "Missing modalities" probleminin de cevabı (biri olmadan diğerleri çalışır).

### "Neden ComBat? Z-score yetmez mi?"
Z-score sadece **mean**'i sıfıra çeker. ComBat hem mean hem **scale**'i (variance) düzeltir, üstüne empirical Bayes shrinkage'ı ile az veri durumunda overfit etmez. ENIGMA Consortium ve birçok multi-site MRI study tarafından kullanılan altın standart.

### "SHAP yerine LIME olamaz mıydı?"
Olabilirdi ama **Random Forest gibi tree ensemble**'larda SHAP TreeExplainer'ın **exact** çözümü var (Lundberg & Lee 2018). LIME local linear approximation, tree boundary'larında hatalı extrapolation yapabiliyor. Hackathon jürisi sayısal kesinliği seviyor.

### "Neden OpenRouter, neden ChatGPT API değil?"
OpenAI API ücretli + key yok. OpenRouter free tier'da 1T flagship'ten (`inclusionai/ling-2.6-1t:free`) 30B reasoning'e (`nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free`) kadar 10 model'lik bir **smartest → smallest fallback chain** sunuyor; biri 429 / 4xx / 5xx dönerse otomatik bir sonrakine geçeriz. **Hybrid template fallback** sayesinde key olmasa, chain tükenmiş olsa veya API ölse bile sistem çalışmaya devam eder — demo gününde kritik.

### "Neden Streamlit, neden React/Next.js değil?"
Hackathon süresi 8 gün. Python-only stack 4 günü implement'a, 2 günü test'e, 1 günü polish'e, 1 günü deploy'a verdi. React öğrenirken hackathon biterdi. Streamlit'in "fast iteration" değer önerisi tam bizim için.

### "Neden HF Spaces, AWS değil?"
HF Spaces:
- Free tier 16GB RAM, 50GB disk (yetiyor)
- ML community hub (jüri "huggingface.co/spaces/..." linkini güvenli görür)
- Docker SDK'sı sade
- AWS ECS/Fargate kurulum 4-6 saat alır, hackathon süresi yetmez

### "Production'da bu sistem ne kadar ölçeklenir?"
HF free tier'da değil. Production'da:
- FastAPI'yi gunicorn + 4 worker arkasında → 100 req/s rahat
- BBB modeli RAM'de 50MB, MRI features dosya sisteminden lazy-load
- Drift deque per-worker olduğu için 4 worker = 4 bağımsız buffer (production'da Redis sentinel'a çekilir)
- ComBat batch (~500 subject/dakika single-thread, vectorize edilmiş)

### "Test sayısı 242 passed / 2 skipped ama nasıl?"
TDD disipliniyle her feature'a 2-4 test yazıldı. Pipeline'lar fixture-driven (synthetic NIfTI, sample SMILES CSV, sample EEG FIF). API testleri `fastapi.testclient.TestClient` üzerinden (no real network). LLM ve agent testleri env-gated; RAG testleri fixture knowledge base ile çalışır; MRI ONNX kontratı dummy ONNX artifact ile doğrulanır.

---

## 14. Tek-Komut Demo

```bash
# Lokal
git clone https://github.com/mert-gng-99/hackathondemo.git
cd hackathondemo
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
NEUROBRIDGE_DISABLE_MLFLOW=1 NEUROBRIDGE_DISABLE_LLM=1 \
  uvicorn src.api.main:app --port 8000 &
streamlit run src/frontend/app.py
```

**Public deploy:** https://mekosotto-hackathon.hf.space

---

## 15. Repository Yapısı

```
hackathon/
├── src/
│   ├── api/                    # FastAPI app + routes + schemas
│   │   ├── main.py
│   │   ├── routes.py           # pipeline, predict, explain, experiments, agent routers
│   │   └── schemas.py          # Pydantic request/response contracts
│   ├── core/
│   │   ├── logger.py           # Structured logging (no print())
│   │   ├── storage.py          # Deterministic Parquet helpers
│   │   └── tracking.py         # MLflow tracking context
│   ├── pipelines/
│   │   ├── bbb_pipeline.py     # SMILES → Morgan FP → Parquet
│   │   ├── eeg_pipeline.py     # FIF/EDF → ICA → epochs → features
│   │   └── mri_pipeline.py     # NIfTI → ROI → ComBat → diagnostics
│   ├── models/
│   │   ├── bbb_model.py        # RF train + SHAP + calibration + train_stats
│   │   └── mri_model.py        # External ONNX MRI inference surface
│   ├── llm/
│   │   ├── __init__.py
│   │   └── explainer.py        # OpenRouter + deterministic template fallback
│   ├── rag/
│   │   ├── ingest.py           # KB → chunks + FAISS index
│   │   └── retrieve.py         # Top-k retrieval API
│   ├── agents/
│   │   ├── orchestrator.py     # OpenRouter function-calling + guarded workflow
│   │   ├── routing.py          # Deterministic pipeline/query routing fallback
│   │   └── tools.py            # Pipeline/RAG tool registry
│   └── frontend/
│       └── app.py              # Streamlit 5-tab dashboard (editorial redesign)
├── tests/                      # 242 passed, 2 skipped across core/api/pipelines/models/rag/agents
├── data/
│   ├── raw/                    # Input data (gitignored)
│   ├── knowledge_base/         # User-supplied RAG docs (gitignored)
│   └── processed/              # Pipeline outputs + model artifacts + FAISS index
├── docs/
│   └── superpowers/
│       ├── plans/              # 8 day-by-day implementation plans
│       └── specs/              # Architectural specs (Day 7 sealed)
├── Dockerfile.hf               # HF Spaces deploy image
├── Dockerfile                  # Alias for HF (auto-discovery)
├── supervisord.conf            # Two-process launcher
├── requirements.txt            # Pinned deps (fastapi==0.115, sklearn==1.5.1, openai==1.51, ...)
├── AGENTS.md                   # Team contract
├── README.md                   # Public-facing overview + Demo Recipe
└── PROJECT_OVERVIEW.md         # This file
```

---

## 16. Terimler Sözlüğü

Yukarıdaki bölümlerde geçen teknik terimlerin sade Türkçe karşılıkları. Hiç tanımadığın bir alan için kısa "neden önemli?" notlarıyla.

### 16.1 Klinik / Biyomedikal

- **BBB (Blood-Brain Barrier / Kan-Beyin Bariyeri):** Beyne giden damarlardaki özel hücre tabakası. Vücudun beyni zararlı maddelerden koruyan filtre. Bir ilacın etki etmesi için (eğer beyinde çalışacaksa) buradan geçmesi gerekir; geçmemesi gerekiyorsa (yan etki istemiyoruz) buraya takılması gerekir. İlaç keşfinde kritik bir filtre.
- **MSS (Merkezi Sinir Sistemi):** Beyin + omurilik. CNS olarak da geçer.
- **MRI (Magnetic Resonance Imaging):** Manyetik rezonans görüntüleme; beynin/dokunun kesit görüntüsü.
- **NIfTI (`.nii.gz`):** Beyin görüntüleme veri formatı; MRI taramaları bu formatta saklanır.
- **ROI (Region of Interest / İlgi Bölgesi):** Görüntüde ölçüm aldığımız bölge (örn. hipokampus). Bizde N×N×N grid hücreleri.
- **EEG (Electroencephalography):** Kafa derisindeki elektrotlarla beynin elektriksel aktivitesini ölçen yöntem.
- **EOG (Electrooculography):** Göz hareketlerinin elektriksel kaydı. EEG'de göz kırpma artefaktını ayıklamak için referans olarak kullanılır.
- **MNE-Python:** EEG/MEG işlemenin de facto bilimsel kütüphanesi (klinik standart).
- **ICA (Independent Component Analysis):** Karışık bir sinyali bağımsız kaynaklarına ayıran algoritma. Örn. EEG kaydında göz kırpma + beyin aktivitesi karışmıştır; ICA bunları ayrı "kaynak"lara böler, sonra göz kırpma kaynağını silip temiz sinyali yeniden inşa edersin.
- **PSD (Power Spectral Density / Güç Spektral Yoğunluğu):** Sinyalin gücünün frekanslara dağılımı. EEG'de **delta** (0.5–4 Hz, derin uyku), **theta** (4–8 Hz, uyku-uyanıklık geçişi), **alpha** (8–13 Hz, gevşek uyanıklık), **beta** (13–30 Hz, aktif düşünme), **gamma** (30+ Hz, yüksek bilişsel aktivite) bantları.
- **Bandpass Filter (0.5–40 Hz):** Sadece bu aralıktaki frekansları geçiren filtre. 0.5 Hz altı = DC drift (yavaş baseline kayması), 50/60 Hz = elektrik şebekesi gürültüsü → ikisini de keser.
- **Epoch:** EEG kaydını sabit süreli (örn. 2 saniyelik) eşit parçalara bölme. Her parça bir "örnek".
- **SMILES (Simplified Molecular Input Line Entry System):** Molekül yapısının kısa metin gösterimi. Örnekler: `CCO` → ethanol, `CN1C=NC2=C1C(=O)N(C(=O)N2C)C` → kafein. ML modeli SMILES'i değil onu vektöre çeviren fingerprint'i öğrenir.
- **Morgan Fingerprint:** Molekülün yapısal "barkod"u. 2048 bit'lik 0/1 vektör; her bit "molekülde şu alt yapı var mı?" sorusuna cevap. RDKit `GetMorganFingerprintAsBitVect`, radius=2 (her atomun 2 komşuluk uzağına kadar bakar).
- **RDKit:** Kimya/cheminformatics açık kaynak Python kütüphanesi. SMILES parse, validation, fingerprint hep RDKit ile.
- **Cyclosporine / Macrocycle:** ~1.2 kDa, 11-residue (peptit zinciri) makrosiklik (halkasal) immünosüpresan ilaç. BBB eğitim setindeki tipik küçük moleküllere göre devasa ve sıra dışı; OOD probe için kullanıyoruz.

### 16.2 Site Bias & Harmonizasyon

- **Site / Cihaz Bias'ı (Site Effect):** Aynı hastanın farklı hastane MRI cihazlarında farklı sayısal sonuç vermesi. Cihaz markası, manyetik alan gücü, yazılım sürümü, çekim protokolü hepsi sistematik kayma yaratır. Tedavi etkisi gibi görünebilir aslında sadece "cihaz farkı"dır.
- **Site-Gap (Site Boşluğu):** Aynı feature'ın siteler-arası ortalama farkının büyüklüğü. `max(per_site_means) - min(per_site_means)`. Sıfıra yakın olması iyidir (cihaz farkı gözükmüyor demektir).
- **Site-Gap Reduction (Site Boşluğu Azalması):** Harmonizasyon öncesi vs. sonrası site-gap oranı. Bizde **3290× reduction**: ComBat öncesi siteler-arası ortalama farkı 5.0, sonrası 0.0015 — fark 3290 kat çöktü. Yani MRI'ın hangi hastanede çekildiğinin tahmine etkisi neredeyse sıfırlandı.
- **ComBat Harmonization:** Çok-merkezli verilerde site bias'ı düzelten istatistiksel algoritma. Her sitenin ortalama (location) + varyans (scale) farkını referans dağılıma çeker, biyolojik sinyali korur. Empirical Bayes shrinkage'ı sayesinde az veri durumunda bile robust. Aslen gen ekspresyonu için icat edildi (Johnson 2007), MRI'a uyarlandı (Fortin 2017–2018).
- **Empirical Bayes:** Klasik Bayes'in pratik versiyonu — prior'u veriden tahmin eder, az örnekli grupları "ortalamaya çeker" (shrinkage). Az veriyle overfit'i önler.
- **Z-score Normalization:** `(x - mean) / std`. Sadece **mean**'i sıfıra çeker, scale farkını çözmez. ComBat hem mean hem scale'i düzelttiği için z-score'dan üstün.
- **KDE (Kernel Density Estimation):** Histogram'ın yumuşak versiyonu. Veri dağılımını düzgün eğri olarak çizer. Bizde her site bir renk; Pre-ComBat panelde renkler ayrışık tepeler oluşturur (cihaz farkı), Post-ComBat panelde üst üste biner (cihaz farkı kalktı) — harmonizasyonun **görsel kanıtı**.
- **Faceted Plot (Yüzlü Grafik):** Aynı grafik tipinin küçük çoklu versiyonları yan yana. Bizde Pre-ComBat ve Post-ComBat iki ayrı panel, ama aynı eksen.
- **Long-format DataFrame:** Her satırda tek `(subject, site, feature, value, state)` tuple'ı. Faceted plot ve `groupby` için ideal; "wide" tablonun melt edilmiş hâli.

### 16.3 Makine Öğrenmesi

- **Random Forest (RF):** Onlarca-yüzlerce karar ağacının bağımsız oy vermesi üzerine kurulu klasik ML algoritması. Küçük-orta veri setlerinde (≤10K örnek) derin öğrenmeyi yener çünkü deep learning bu boyutta overfit eder.
- **Stratified Split (Tabakalı Bölme):** Train/test ayırırken her sınıfın oranını koruma. Veride %30 pozitif varsa hem train hem test'te %30 olur. Class imbalance'da kritik.
- **`predict_proba`:** sklearn modellerinin "ham olasılık" çıktısı. Örn. `[0.18, 0.82]` = %82 olasılıkla pozitif sınıf. `argmax`'ı alırsak label, `max`'ı alırsak confidence.
- **Confidence (Güven Skoru):** Modelin tahminine verdiği olasılık (`max(predict_proba)`). %50 = bilmiyor, %99 = çok emin.
- **Calibration (Kalibrasyon):** "Model %80 derse, gerçekten %80 doğruluk gösteriyor mu?" sorusu. Kalibre olmayan model "çok eminim" der ama yanılır; kalibre model güveni ile gerçek precision'ı uyuşur.
- **Calibration Bin:** Confidence aralıkları (0.50, 0.60, 0.70, 0.75, 0.80, 0.90). Her aralık için held-out test'te precision ölçülür → kullanıcıya "≥%75 confident olduğumda gerçek precision %92" deme imkânı.
- **Precision (Kesinlik):** Model "pozitif" dediklerinin kaçı gerçekten pozitif? `TP / (TP + FP)`.
- **Support:** O bin'de kaç örnek var. n=18 demek "bu istatistik 18 örnekten hesaplandı".
- **Held-out Test Set:** Train'de hiç görmediği veri. Modelin gerçek genelleme performansını ölçen tek dürüst veri.
- **OOD (Out-of-Distribution):** Eğitim verisinde olmayan, "tanımadığım" tipte örnek. Cyclosporine örneği gibi. Sağlam model OOD'de düşük confidence ile **hedge eder** (kararsız kalır).
- **Drift (Veri Sapması):** Modelin gerçek dünyada gördüğü verinin zamanla eğitim dağılımından uzaklaşması. "Hasta profili değişti, model eskidi" sinyali.
- **Drift z-score:** Son 100 tahminin median'ı, eğitim sırasındaki median'dan kaç standart sapma uzakta? Formül: `(rolling_median - train_median) / max(train_std, 1e-9)`. Yorum: `|z|<1` normal, `1≤|z|<2` hafif kayma, `|z|≥2` ciddi kayma — retrain önerilir.
- **Trailing-100 / Rolling-100 Window:** Son 100 tahmin penceresi. Python `collections.deque(maxlen=100)` ile tutulur.
- **deque (Double-Ended Queue):** Python'da iki uçtan ekleme/çıkarma yapılabilen sabit-boyutlu kuyruk. `maxlen=100` = en yeni 100 eleman tutulur, eski olan otomatik düşer.
- **SHAP (SHapley Additive exPlanations):** Bir tahmindeki katkıyı feature'lar arasında "adil" şekilde paylaştıran yöntem. Oyun teorisinden Shapley value (Lloyd Shapley, 1953 — Nobel 2012) kullanır. "Bit #532 kararı +0.18 ittirdi, bit #1024 −0.05 ittirdi" der.
- **TreeExplainer:** SHAP'in karar ağacı modelleri için kapalı-form **exact** çözümü. Sampling yok, deterministik, tam aynı feature için tam aynı katkıyı verir (Lundberg & Lee 2018).
- **LIME:** SHAP'a alternatif "local linear approximation". Tree boundary'larında SHAP kadar kesin değil; biz SHAP tercih ediyoruz.
- **Feature Attribution (Öznitelik Atfı):** Her feature'ın tahmindeki katkısı (yön + büyüklük).
- **Feature Importance:** Tüm dataset üzerinde bir feature'ın model kararındaki ortalama önem ağırlığı (global). Attribution ise bireysel tahmindekidir (local).
- **MLflow:** ML deneylerini (run'ları) izleyen açık kaynak araç. "Hangi veri, hangi parametre, hangi metrik?" — hepsi otomatik loglanır.
- **Run / Run ID:** MLflow'da bir eğitim çalışmasının kaydı. Her train invocation yeni bir `run_id` (örn. `abc123...`) alır.
- **Provenance (Kanıt İzi / Veri Kökenli):** "Bu tahmin tam olarak hangi modelden, hangi run'dan, hangi veriyle çıktı?" sorusunun audit-trail cevabı. Tıbbi/regülatif sistemlerde zorunlu.
- **Joblib:** sklearn modellerini diske yazmak/okumak için kullanılan serileştirme kütüphanesi. `pickle`'ın numpy-aware versiyonu.
- **TDD (Test-Driven Development):** Önce test yaz (kabul kriteri), sonra kodu yaz. Döngü: **RED** (test fail) → **GREEN** (test pass) → **REFACTOR** (temizle, test hâlâ pass).

### 16.4 Backend & Mimari

- **FastAPI:** Python'da modern HTTP API framework (Pydantic schema'lar + async + auto-generated `/docs` Swagger UI).
- **Pydantic:** Python data validation kütüphanesi. Request/response schema'larını type-safe yapar; yanlış formatta input gelirse otomatik HTTP 422 döner.
- **Uvicorn:** Python ASGI sunucusu, FastAPI'yi çalıştırır.
- **Streamlit:** Python-only web dashboard framework. React/HTML yazmadan multi-tab interactive UI.
- **httpx:** Modern Python HTTP istemcisi (`requests`'in async-aware halefi). Streamlit container içinde FastAPI'ya bununla konuşur.
- **Supervisord:** Tek container içinde birden fazla process'i (uvicorn + streamlit) yöneten süreç yöneticisi. Biri ölünce yeniden başlatır.
- **BFF (Backend For Frontend) / Proxy Pattern:** UI ile gerçek API arasındaki ara katman. Bizde Streamlit container içinden FastAPI'yi çağırır; dışarı sadece Streamlit (port 7860) açıktır, FastAPI (port 8000) doğrudan internet'e açık değildir.
- **Endpoint:** API'nin URL yolu. Örn. `POST /predict/bbb`.
- **HTTP Status Codes:** `200` OK, `400` Bad Request (input geçersiz), `404` Not Found, `422` Unprocessable Entity (Pydantic validation fail), `503` Service Unavailable (model yüklenmedi).
- **Env Variable (Çevre Değişkeni):** Container'a dışarıdan verilen ayar. Örn. `NEUROBRIDGE_DISABLE_LLM=1`.
- **Kill-Switch:** Bir özelliği tek değişkenle devre dışı bırakma anahtarı. Demo gününde LLM ölürse `NEUROBRIDGE_DISABLE_LLM=1` ile sistem template path'e düşer ve hayatta kalır.
- **Graceful Failure / Graceful Degradation:** Bir bileşen hata verince **çökmek yerine** sistemin daha basit modda çalışmaya devam etmesi. Bizde: API HTTP 400 dönerse UI'da kırmızı ERROR yerine sarı WARNING; LLM ölürse template path; MLflow ölürse provenance "—" gösterir.
- **Fallback Chain:** Bir hata zincirinde sırayla denenen yedekler. LLM Provider A → Provider B → deterministic template gibi.
- **Hybrid Path:** İki yollu sistem; LLM çalışırsa LLM cevap verir, çalışmazsa template path. Source label ile hangi path'in döndüğü işaretlenir.
- **Deterministic Template:** Aynı input'a her zaman tıpatıp aynı cevabı veren string template. (LLM ise rastgelelik içerir.)
- **Idempotence (Idempotency):** Aynı işlemi 1 kez de 100 kez de çalıştırsan sonuç aynı kalır. Pipeline'larımız idempotent → re-run güvenli.
- **HF Spaces (Hugging Face Spaces):** ML demolarını host etmek için ücretsiz public platform. ML community hub.
- **Docker / Container:** Uygulama + tüm dependencies'in tek izole paket olarak çalıştırılması. "Bende çalışıyor" sorununu öldürür.
- **Dockerfile:** Container'ın nasıl build edileceğine dair talimat dosyası.
- **Cold Start:** Container'ın ilk ayağa kalkış süresi. Bizde build-time train sayesinde model image'a gömülü → cold start'ta train beklemeyiz.
- **Worker:** Web sunucusu işlem birimi. Her worker bağımsız bellek alanına sahip → drift deque'i her worker'da ayrıdır (production'da Redis'e taşınır).

### 16.5 LLM / Açıklanabilirlik

- **LLM (Large Language Model):** GPT, Llama, Gemini, Claude gibi büyük dil modelleri.
- **OpenRouter:** Birçok LLM provider'ı tek API arkasında toplayan servis. Free tier'da `inclusionai/ling-2.6-1t`, `nvidia/nemotron-3-super-120b`, `google/gemma-4-31b`, `qwen3-next-80b` gibi seçenekler — biz smartest → smallest 10-model fallback chain (`_DEFAULT_FREE_MODEL_CHAIN`) ile her birini sırayla deniyoruz.
- **API Key:** Bir servise erişim için kişisel jeton. Asla repo'ya commit edilmez (HF Spaces "Variables and Secrets"'a girilir).
- **Rationale (Gerekçe):** Modelin tahminine dair doğal-dil açıklama (örn. "Predicted permeable with 82% confidence; SHAP attributions toward this label include bits 532 and 1024…").
- **Source Label:** Cevabın hangi kaynaktan geldiğini gösteren etiket. Bizde `source: "llm"` veya `source: "template"` — auditability için.

### 16.6 Veri Yapıları & Format

- **Parquet:** Sıkıştırılmış kolonlu veri formatı. CSV'den çok daha verimli (boyut + okuma hızı).
- **DataFrame:** pandas'ın tablo veri yapısı. SQL-benzeri operasyonlar Python içinde.
- **JSON:** API request/response'larının metin formatı.
- **`.fif` / `.edf`:** EEG kayıt formatları (FIF = MNE'nin native format'ı, EDF = European Data Format, daha yaygın).
- **Joblib `.joblib`:** sklearn modeli + custom attribute'lar serialized hâli.

---

## 17. Kapanış

NeuroBridge Enterprise hackathon'un sloganına ("**Stop Building Ideas. Start Building Systems.**") en doğrudan cevap. 8 günlük sprint sonrası agent/RAG hardening ve MRI ONNX decision layer ile sistemi daha ileri taşıdık. Public deploy'lu, jüri tarayıcıdan tıklayıp dokunabiliyor. 242 passed / 2 skipped, 96.8% jüri skoru projeksiyonu, 5/5 hackathon track strong, 4/4 Living Systems pillar full.

Şampiyonluğa oynuyoruz.

— *Mert Gungor + Claude Code (Subagent-Driven Development)*