raylim Claude commited on
Commit
0506a57
·
unverified ·
1 Parent(s): a2b6947

Add Aeon model test suite and reproducibility scripts

Browse files

- Add comprehensive test summary (AEON_TEST_SUMMARY.md)
- Add test results for 3 validation slides (100% accuracy, avg 99.10% confidence)
- Add reproducibility scripts:
- export_aeon_checkpoint.py: Convert PyTorch Lightning checkpoints to pickle
- run_aeon_tests.sh: Automated test runner with validation
- verify_aeon_results.py: Result verification against ground truth
- Update analysis.py to use standard aeon_model.pkl path
- Update .gitignore to exclude slide images and masks

Test Results:
- Slide 881837 (BLCA): 98.19% confidence ✓
- Slide 744547 (HCC): 99.49% confidence ✓
- Slide 755246 (HCC): 99.61% confidence ✓

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

.gitignore CHANGED
@@ -17,3 +17,5 @@ data/
17
  htmlcov/
18
  flagged/
19
  gradio_cached_examples/
 
 
 
17
  htmlcov/
18
  flagged/
19
  gradio_cached_examples/
20
+ *.svs
21
+ *.png
scripts/README.md ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Mosaic Scripts
2
+
3
+ This directory contains utility scripts for working with the Mosaic pipeline, particularly for Aeon model testing and deployment.
4
+
5
+ ## Aeon Model Scripts
6
+
7
+ ### 1. export_aeon_checkpoint.py
8
+
9
+ Export PyTorch Lightning checkpoint to pickle format for inference.
10
+
11
+ **Usage:**
12
+ ```bash
13
+ python scripts/export_aeon_checkpoint.py \
14
+ --checkpoint data/checkpoint.ckpt \
15
+ --output data/aeon_model.pkl \
16
+ --metadata-dir data/metadata
17
+ ```
18
+
19
+ **Arguments:**
20
+ - `--checkpoint`: Path to PyTorch Lightning checkpoint (.ckpt file)
21
+ - `--output`: Path to save exported model (.pkl file)
22
+ - `--metadata-dir`: Directory containing metadata files (default: data/metadata)
23
+
24
+ **Requirements:**
25
+ - paladin package from git repo (must have AeonLightningModule)
26
+ - PyTorch Lightning
27
+ - Metadata files: n_classes.txt, ontology_embedding_dim.txt, target_dict.tsv
28
+
29
+ **Example:**
30
+ ```bash
31
+ # Export the checkpoint
32
+ uv run python scripts/export_aeon_checkpoint.py \
33
+ --checkpoint data/checkpoint.ckpt \
34
+ --output data/aeon_model.pkl
35
+
36
+ # Output:
37
+ # Loading metadata from data/metadata...
38
+ # Loading checkpoint from data/checkpoint.ckpt...
39
+ # Saving model to data/aeon_model.pkl...
40
+ # ✓ Successfully exported checkpoint to data/aeon_model.pkl
41
+ # Model size: 118.0 MB
42
+ # Model class: AeonLateAggregator
43
+ # Number of classes: 160
44
+ # Ontology embedding dim: 20
45
+ # Number of histologies: 160
46
+ ```
47
+
48
+ ### 2. run_aeon_tests.sh
49
+
50
+ Run the Aeon model on test slides and validate predictions.
51
+
52
+ **Usage:**
53
+ ```bash
54
+ ./scripts/run_aeon_tests.sh
55
+ ```
56
+
57
+ **Configuration:**
58
+ The script reads test samples from `test_slides/test_samples.json` and processes each slide through the full Mosaic pipeline with:
59
+ - Cancer subtype: Unknown (triggers Aeon inference)
60
+ - Segmentation config: Biopsy
61
+ - Number of workers: 4
62
+
63
+ **Output:**
64
+ - Results saved to `test_slides/results/{slide_id}/`
65
+ - Logs saved to `test_slides/logs/`
66
+ - Summary showing passed/failed tests
67
+
68
+ **Example Output:**
69
+ ```
70
+ =========================================
71
+ Aeon Model Test Suite
72
+ =========================================
73
+
74
+ Found 3 test slides
75
+
76
+ =========================================
77
+ Processing slide 1/3: 881837
78
+ =========================================
79
+ Ground Truth:
80
+ Cancer Subtype: BLCA
81
+ Site Type: Primary
82
+ Sex: Male
83
+ Tissue Site: Bladder
84
+
85
+ Running Mosaic pipeline...
86
+
87
+ Aeon Prediction:
88
+ Predicted: BLCA
89
+ Confidence: 0.9819
90
+
91
+ ✓ PASS: Prediction matches ground truth
92
+
93
+ [... continues for all slides ...]
94
+
95
+ =========================================
96
+ Test Summary
97
+ =========================================
98
+ Total slides: 3
99
+ Passed: 3
100
+ Failed: 0
101
+
102
+ All tests passed!
103
+ ```
104
+
105
+ ### 3. verify_aeon_results.py
106
+
107
+ Verify Aeon test results against expected ground truth.
108
+
109
+ **Usage:**
110
+ ```bash
111
+ python scripts/verify_aeon_results.py \
112
+ --test-samples test_slides/test_samples.json \
113
+ --results-dir test_slides/results \
114
+ --output test_slides/verification_report.json
115
+ ```
116
+
117
+ **Arguments:**
118
+ - `--test-samples`: Path to test samples JSON file (default: test_slides/test_samples.json)
119
+ - `--results-dir`: Directory containing results (default: test_slides/results)
120
+ - `--output`: Optional path to save verification report as JSON
121
+
122
+ **Example:**
123
+ ```bash
124
+ # Verify results and save report
125
+ uv run python scripts/verify_aeon_results.py \
126
+ --output test_slides/verification_report.json
127
+
128
+ # Output:
129
+ # ================================================================================
130
+ # Aeon Model Verification Report
131
+ # ================================================================================
132
+ #
133
+ # Slide: 881837
134
+ # Ground Truth: BLCA
135
+ # Site Type: Primary
136
+ # Sex: Male
137
+ # Tissue Site: Bladder
138
+ # Predicted: BLCA
139
+ # Confidence: 0.9819 (98.19%)
140
+ # Status: ✓ PASS
141
+ #
142
+ # [... continues for all slides ...]
143
+ #
144
+ # ================================================================================
145
+ # Summary
146
+ # ================================================================================
147
+ # Total slides: 3
148
+ # Passed: 3 (100.0%)
149
+ # Failed: 0 (0.0%)
150
+ #
151
+ # ✓ All tests passed!
152
+ #
153
+ # Confidence Statistics (for passed tests):
154
+ # Average: 0.9910 (99.10%)
155
+ # Minimum: 0.9819 (98.19%)
156
+ # Maximum: 0.9961 (99.61%)
157
+ ```
158
+
159
+ ## Workflow
160
+
161
+ ### Complete Testing Workflow
162
+
163
+ 1. **Export checkpoint** (if needed):
164
+ ```bash
165
+ uv run python scripts/export_aeon_checkpoint.py \
166
+ --checkpoint data/checkpoint.ckpt \
167
+ --output data/aeon_model.pkl
168
+ ```
169
+
170
+ 2. **Run tests**:
171
+ ```bash
172
+ ./scripts/run_aeon_tests.sh
173
+ ```
174
+
175
+ 3. **Verify results**:
176
+ ```bash
177
+ uv run python scripts/verify_aeon_results.py \
178
+ --output test_slides/verification_report.json
179
+ ```
180
+
181
+ ### Quick Verification
182
+
183
+ If you already have test results and just want to verify them:
184
+
185
+ ```bash
186
+ uv run python scripts/verify_aeon_results.py
187
+ ```
188
+
189
+ ## Test Samples Format
190
+
191
+ The test samples JSON file should have this format:
192
+
193
+ ```json
194
+ [
195
+ {
196
+ "slide_id": "881837",
197
+ "cancer_subtype": "BLCA",
198
+ "site_type": "Primary",
199
+ "sex": "Male",
200
+ "tissue_site": "Bladder"
201
+ },
202
+ {
203
+ "slide_id": "744547",
204
+ "cancer_subtype": "HCC",
205
+ "site_type": "Metastatic",
206
+ "sex": "Male",
207
+ "tissue_site": "Liver"
208
+ }
209
+ ]
210
+ ```
211
+
212
+ ## Dependencies
213
+
214
+ All scripts require:
215
+ - Python 3.10+
216
+ - uv package manager
217
+ - Mosaic package with dependencies
218
+
219
+ Additional requirements for checkpoint export:
220
+ - paladin from git repository (dev branch)
221
+ - PyTorch Lightning
222
+
223
+ ## Exit Codes
224
+
225
+ - `0`: Success (all tests passed)
226
+ - `1`: Failure (one or more tests failed)
227
+
228
+ ## Troubleshooting
229
+
230
+ ### "AeonLightningModule not found"
231
+ ```bash
232
+ uv sync --upgrade-package paladin
233
+ ```
234
+
235
+ ### "Metadata files not found"
236
+ Make sure you have:
237
+ - `data/metadata/n_classes.txt`
238
+ - `data/metadata/ontology_embedding_dim.txt`
239
+ - `data/metadata/target_dict.tsv`
240
+
241
+ ### "Test slides not found"
242
+ Place your test slides in `test_slides/` directory and update `test_samples.json` with correct paths.
243
+
244
+ ## See Also
245
+
246
+ - [AEON_TEST_SUMMARY.md](../test_slides/AEON_TEST_SUMMARY.md) - Detailed test results and validation
247
+ - [README.md](../README.md) - Main Mosaic documentation
scripts/export_aeon_checkpoint.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ """
3
+ Export Aeon PyTorch Lightning checkpoint to pickle format for inference.
4
+
5
+ This script converts a PyTorch Lightning checkpoint (.ckpt) file to a pickle
6
+ (.pkl) file that can be used with the Mosaic inference pipeline.
7
+
8
+ Usage:
9
+ python export_aeon_checkpoint.py \
10
+ --checkpoint data/checkpoint.ckpt \
11
+ --output data/aeon_model.pkl \
12
+ --metadata-dir data/metadata
13
+
14
+ Requirements:
15
+ - paladin package from git repo (must have AeonLightningModule)
16
+ - PyTorch Lightning
17
+ - Access to metadata files (n_classes.txt, ontology_embedding_dim.txt, target_dict.tsv)
18
+ """
19
+
20
+ import argparse
21
+ import json
22
+ import pickle
23
+ from pathlib import Path
24
+
25
+
26
+ def load_metadata(metadata_dir: Path):
27
+ """Load metadata required for model initialization.
28
+
29
+ Args:
30
+ metadata_dir: Directory containing metadata files
31
+
32
+ Returns:
33
+ SimpleMetadata object with n_classes, ontology_embedding_dim, and target_dicts
34
+ """
35
+ # Read n_classes
36
+ with open(metadata_dir / "n_classes.txt") as f:
37
+ n_classes = int(f.read().strip())
38
+
39
+ # Read ontology_embedding_dim
40
+ with open(metadata_dir / "ontology_embedding_dim.txt") as f:
41
+ ontology_embedding_dim = int(f.read().strip())
42
+
43
+ # Read target_dict (JSON format with single quotes)
44
+ with open(metadata_dir / "target_dict.tsv") as f:
45
+ target_dict_str = f.read().strip().replace("'", '"')
46
+ target_dict = json.loads(target_dict_str)
47
+
48
+ # Create simple metadata object
49
+ class SimpleMetadata:
50
+ def __init__(self, n_classes, ontology_embedding_dim, target_dict):
51
+ self.n_classes = n_classes
52
+ self.ontology_embedding_dim = ontology_embedding_dim
53
+ self.target_dicts = [target_dict]
54
+
55
+ return SimpleMetadata(n_classes, ontology_embedding_dim, target_dict)
56
+
57
+
58
+ def export_checkpoint(checkpoint_path: Path, output_path: Path, metadata_dir: Path):
59
+ """Export PyTorch Lightning checkpoint to pickle format.
60
+
61
+ Args:
62
+ checkpoint_path: Path to .ckpt file
63
+ output_path: Path to save .pkl file
64
+ metadata_dir: Directory containing metadata files
65
+ """
66
+ try:
67
+ from paladin.pl_modules.aeon import AeonLightningModule
68
+ except ImportError:
69
+ raise ImportError(
70
+ "Failed to import AeonLightningModule. "
71
+ "Make sure paladin is installed from the git repository:\n"
72
+ " uv sync --upgrade-package paladin"
73
+ )
74
+
75
+ print(f"Loading metadata from {metadata_dir}...")
76
+ metadata = load_metadata(metadata_dir)
77
+
78
+ print(f"Loading checkpoint from {checkpoint_path}...")
79
+ pl_module = AeonLightningModule.load_from_checkpoint(
80
+ str(checkpoint_path),
81
+ metadata=metadata
82
+ )
83
+
84
+ # Extract the model
85
+ model = pl_module.model
86
+
87
+ print(f"Saving model to {output_path}...")
88
+ with open(output_path, "wb") as f:
89
+ pickle.dump(model, f)
90
+
91
+ print(f"✓ Successfully exported checkpoint to {output_path}")
92
+
93
+ # Print model info
94
+ file_size = output_path.stat().st_size / (1024 * 1024) # MB
95
+ print(f" Model size: {file_size:.1f} MB")
96
+ print(f" Model class: {type(model).__name__}")
97
+ print(f" Number of classes: {metadata.n_classes}")
98
+ print(f" Ontology embedding dim: {metadata.ontology_embedding_dim}")
99
+ print(f" Number of histologies: {len(metadata.target_dicts[0]['histologies'])}")
100
+
101
+
102
+ def main():
103
+ parser = argparse.ArgumentParser(
104
+ description="Export Aeon PyTorch Lightning checkpoint to pickle format"
105
+ )
106
+ parser.add_argument(
107
+ "--checkpoint",
108
+ type=Path,
109
+ required=True,
110
+ help="Path to PyTorch Lightning checkpoint (.ckpt)"
111
+ )
112
+ parser.add_argument(
113
+ "--output",
114
+ type=Path,
115
+ required=True,
116
+ help="Path to save exported model (.pkl)"
117
+ )
118
+ parser.add_argument(
119
+ "--metadata-dir",
120
+ type=Path,
121
+ default=Path("data/metadata"),
122
+ help="Directory containing metadata files (default: data/metadata)"
123
+ )
124
+
125
+ args = parser.parse_args()
126
+
127
+ # Validate inputs
128
+ if not args.checkpoint.exists():
129
+ raise FileNotFoundError(f"Checkpoint not found: {args.checkpoint}")
130
+
131
+ if not args.metadata_dir.exists():
132
+ raise FileNotFoundError(f"Metadata directory not found: {args.metadata_dir}")
133
+
134
+ # Create output directory if needed
135
+ args.output.parent.mkdir(parents=True, exist_ok=True)
136
+
137
+ # Export checkpoint
138
+ export_checkpoint(args.checkpoint, args.output, args.metadata_dir)
139
+
140
+
141
+ if __name__ == "__main__":
142
+ main()
scripts/run_aeon_tests.sh ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Aeon Model Test Script
3
+ # This script runs the Aeon cancer subtype prediction model on test slides
4
+ # for reproducibility and validation.
5
+
6
+ set -e # Exit on error
7
+
8
+ # Configuration
9
+ TEST_SAMPLES_FILE="test_slides/test_samples.json"
10
+ RESULTS_DIR="test_slides/results"
11
+ LOG_DIR="test_slides/logs"
12
+ SEGMENTATION_CONFIG="Biopsy"
13
+ NUM_WORKERS=4
14
+
15
+ # Colors for output
16
+ GREEN='\033[0;32m'
17
+ YELLOW='\033[1;33m'
18
+ RED='\033[0;31m'
19
+ NC='\033[0m' # No Color
20
+
21
+ echo "========================================="
22
+ echo "Aeon Model Test Suite"
23
+ echo "========================================="
24
+ echo ""
25
+
26
+ # Create directories
27
+ mkdir -p "${RESULTS_DIR}"
28
+ mkdir -p "${LOG_DIR}"
29
+
30
+ # Check if test samples file exists
31
+ if [ ! -f "${TEST_SAMPLES_FILE}" ]; then
32
+ echo -e "${RED}Error: Test samples file not found: ${TEST_SAMPLES_FILE}${NC}"
33
+ exit 1
34
+ fi
35
+
36
+ # Read test samples
37
+ echo "Reading test samples from ${TEST_SAMPLES_FILE}..."
38
+ SLIDE_IDS=$(python3 -c "
39
+ import json
40
+ with open('${TEST_SAMPLES_FILE}') as f:
41
+ samples = json.load(f)
42
+ for sample in samples:
43
+ slide_id = sample.get('slide_id') or sample.get('image_id')
44
+ print(slide_id)
45
+ ")
46
+
47
+ # Count slides
48
+ NUM_SLIDES=$(echo "${SLIDE_IDS}" | wc -l)
49
+ echo -e "${GREEN}Found ${NUM_SLIDES} test slides${NC}"
50
+ echo ""
51
+
52
+ # Process each slide
53
+ CURRENT=0
54
+ PASSED=0
55
+ FAILED=0
56
+
57
+ for SLIDE_ID in ${SLIDE_IDS}; do
58
+ CURRENT=$((CURRENT + 1))
59
+
60
+ echo "========================================="
61
+ echo -e "${YELLOW}Processing slide ${CURRENT}/${NUM_SLIDES}: ${SLIDE_ID}${NC}"
62
+ echo "========================================="
63
+
64
+ # Get slide metadata
65
+ METADATA=$(python3 -c "
66
+ import json
67
+ with open('${TEST_SAMPLES_FILE}') as f:
68
+ samples = json.load(f)
69
+ for sample in samples:
70
+ slide_id = sample.get('slide_id') or sample.get('image_id')
71
+ if slide_id == '${SLIDE_ID}':
72
+ cancer_subtype = sample.get('cancer_subtype') or sample.get('cancer_type')
73
+ print(f\"{cancer_subtype}|{sample['site_type']}|{sample['sex']}|{sample['tissue_site']}\")
74
+ break
75
+ ")
76
+
77
+ IFS='|' read -r CANCER_SUBTYPE SITE_TYPE SEX TISSUE_SITE <<< "${METADATA}"
78
+
79
+ echo "Ground Truth:"
80
+ echo " Cancer Subtype: ${CANCER_SUBTYPE}"
81
+ echo " Site Type: ${SITE_TYPE}"
82
+ echo " Sex: ${SEX}"
83
+ echo " Tissue Site: ${TISSUE_SITE}"
84
+ echo ""
85
+
86
+ # Find slide file
87
+ SLIDE_FILE=$(find test_slides -name "${SLIDE_ID}.svs" -o -name "${SLIDE_ID}.tiff" -o -name "${SLIDE_ID}.ndpi" 2>/dev/null | head -1)
88
+
89
+ if [ -z "${SLIDE_FILE}" ]; then
90
+ echo -e "${RED}Error: Slide file not found for ${SLIDE_ID}${NC}"
91
+ FAILED=$((FAILED + 1))
92
+ continue
93
+ fi
94
+
95
+ echo "Slide file: ${SLIDE_FILE}"
96
+ echo ""
97
+
98
+ # Run Mosaic pipeline with Aeon inference
99
+ LOG_FILE="${LOG_DIR}/${SLIDE_ID}_aeon_test.log"
100
+
101
+ echo "Running Mosaic pipeline..."
102
+ if uv run python -m mosaic.cli \
103
+ --input-slide "${SLIDE_FILE}" \
104
+ --output-dir "${RESULTS_DIR}/${SLIDE_ID}" \
105
+ --cancer-subtype "Unknown" \
106
+ --site-type "${SITE_TYPE}" \
107
+ --sex "${SEX}" \
108
+ --tissue-site "${TISSUE_SITE}" \
109
+ --segmentation-config "${SEGMENTATION_CONFIG}" \
110
+ --num-workers "${NUM_WORKERS}" \
111
+ > "${LOG_FILE}" 2>&1; then
112
+
113
+ # Check if results exist
114
+ AEON_RESULTS="${RESULTS_DIR}/${SLIDE_ID}/${SLIDE_ID}_aeon_results.csv"
115
+
116
+ if [ -f "${AEON_RESULTS}" ]; then
117
+ # Extract prediction
118
+ PREDICTION=$(python3 -c "
119
+ import pandas as pd
120
+ df = pd.read_csv('${AEON_RESULTS}')
121
+ if not df.empty:
122
+ print(f\"{df.iloc[0]['Cancer Subtype']}|{df.iloc[0]['Confidence']:.4f}\")
123
+ ")
124
+
125
+ IFS='|' read -r PRED_SUBTYPE CONFIDENCE <<< "${PREDICTION}"
126
+
127
+ echo ""
128
+ echo "Aeon Prediction:"
129
+ echo " Predicted: ${PRED_SUBTYPE}"
130
+ echo " Confidence: ${CONFIDENCE}"
131
+ echo ""
132
+
133
+ # Check if prediction matches ground truth
134
+ if [ "${PRED_SUBTYPE}" == "${CANCER_SUBTYPE}" ]; then
135
+ echo -e "${GREEN}✓ PASS: Prediction matches ground truth${NC}"
136
+ PASSED=$((PASSED + 1))
137
+ else
138
+ echo -e "${RED}✗ FAIL: Prediction does not match ground truth${NC}"
139
+ echo " Expected: ${CANCER_SUBTYPE}"
140
+ echo " Got: ${PRED_SUBTYPE}"
141
+ FAILED=$((FAILED + 1))
142
+ fi
143
+ else
144
+ echo -e "${RED}✗ FAIL: Aeon results file not found${NC}"
145
+ FAILED=$((FAILED + 1))
146
+ fi
147
+ else
148
+ echo -e "${RED}✗ FAIL: Mosaic pipeline failed${NC}"
149
+ echo "Check log file: ${LOG_FILE}"
150
+ FAILED=$((FAILED + 1))
151
+ fi
152
+
153
+ echo ""
154
+ done
155
+
156
+ # Summary
157
+ echo "========================================="
158
+ echo "Test Summary"
159
+ echo "========================================="
160
+ echo "Total slides: ${NUM_SLIDES}"
161
+ echo -e "${GREEN}Passed: ${PASSED}${NC}"
162
+ if [ ${FAILED} -gt 0 ]; then
163
+ echo -e "${RED}Failed: ${FAILED}${NC}"
164
+ else
165
+ echo "Failed: ${FAILED}"
166
+ fi
167
+ echo ""
168
+
169
+ if [ ${FAILED} -eq 0 ]; then
170
+ echo -e "${GREEN}All tests passed!${NC}"
171
+ exit 0
172
+ else
173
+ echo -e "${RED}Some tests failed. Check logs in ${LOG_DIR}${NC}"
174
+ exit 1
175
+ fi
scripts/verify_aeon_results.py ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ """
3
+ Verify Aeon test results against expected ground truth.
4
+
5
+ This script reads the test results and compares them against the ground truth
6
+ values in test_samples.json to validate the Aeon model predictions.
7
+
8
+ Usage:
9
+ python verify_aeon_results.py \
10
+ --test-samples test_slides/test_samples.json \
11
+ --results-dir test_slides/results
12
+ """
13
+
14
+ import argparse
15
+ import json
16
+ from pathlib import Path
17
+ import pandas as pd
18
+ from typing import Dict, List, Tuple
19
+
20
+
21
+ def load_test_samples(test_samples_file: Path) -> List[Dict]:
22
+ """Load test samples from JSON file.
23
+
24
+ Args:
25
+ test_samples_file: Path to test_samples.json
26
+
27
+ Returns:
28
+ List of test sample dictionaries
29
+ """
30
+ with open(test_samples_file) as f:
31
+ return json.load(f)
32
+
33
+
34
+ def load_aeon_results(slide_id: str, results_dir: Path) -> Tuple[str, float]:
35
+ """Load Aeon prediction results for a slide.
36
+
37
+ Args:
38
+ slide_id: Slide identifier
39
+ results_dir: Directory containing results
40
+
41
+ Returns:
42
+ Tuple of (predicted_subtype, confidence)
43
+ """
44
+ results_file = results_dir / slide_id / f"{slide_id}_aeon_results.csv"
45
+
46
+ if not results_file.exists():
47
+ raise FileNotFoundError(f"Results file not found: {results_file}")
48
+
49
+ df = pd.read_csv(results_file)
50
+
51
+ if df.empty:
52
+ raise ValueError(f"Empty results file: {results_file}")
53
+
54
+ # Get top prediction
55
+ top_prediction = df.iloc[0]
56
+ return top_prediction["Cancer Subtype"], top_prediction["Confidence"]
57
+
58
+
59
+ def verify_results(test_samples: List[Dict], results_dir: Path) -> Dict:
60
+ """Verify all test results against ground truth.
61
+
62
+ Args:
63
+ test_samples: List of test sample dictionaries
64
+ results_dir: Directory containing results
65
+
66
+ Returns:
67
+ Dictionary with verification statistics
68
+ """
69
+ total = len(test_samples)
70
+ passed = 0
71
+ failed = 0
72
+ results = []
73
+
74
+ print("=" * 80)
75
+ print("Aeon Model Verification Report")
76
+ print("=" * 80)
77
+ print()
78
+
79
+ for sample in test_samples:
80
+ slide_id = sample.get("slide_id") or sample.get("image_id")
81
+ ground_truth = sample.get("cancer_subtype") or sample.get("cancer_type")
82
+ site_type = sample["site_type"]
83
+ sex = sample["sex"]
84
+ tissue_site = sample["tissue_site"]
85
+
86
+ print(f"Slide: {slide_id}")
87
+ print(f" Ground Truth: {ground_truth}")
88
+ print(f" Site Type: {site_type}")
89
+ print(f" Sex: {sex}")
90
+ print(f" Tissue Site: {tissue_site}")
91
+
92
+ try:
93
+ predicted, confidence = load_aeon_results(slide_id, results_dir)
94
+
95
+ print(f" Predicted: {predicted}")
96
+ print(f" Confidence: {confidence:.4f} ({confidence * 100:.2f}%)")
97
+
98
+ # Check if prediction matches
99
+ if predicted == ground_truth:
100
+ print(" Status: ✓ PASS")
101
+ passed += 1
102
+ status = "PASS"
103
+ else:
104
+ print(f" Status: ✗ FAIL (expected {ground_truth}, got {predicted})")
105
+ failed += 1
106
+ status = "FAIL"
107
+
108
+ results.append({
109
+ "slide_id": slide_id,
110
+ "ground_truth": ground_truth,
111
+ "predicted": predicted,
112
+ "confidence": confidence,
113
+ "site_type": site_type,
114
+ "sex": sex,
115
+ "tissue_site": tissue_site,
116
+ "status": status
117
+ })
118
+
119
+ except Exception as e:
120
+ print(f" Status: ✗ ERROR - {e}")
121
+ failed += 1
122
+ results.append({
123
+ "slide_id": slide_id,
124
+ "ground_truth": ground_truth,
125
+ "predicted": None,
126
+ "confidence": None,
127
+ "site_type": site_type,
128
+ "sex": sex,
129
+ "tissue_site": tissue_site,
130
+ "status": "ERROR",
131
+ "error": str(e)
132
+ })
133
+
134
+ print()
135
+
136
+ # Print summary
137
+ print("=" * 80)
138
+ print("Summary")
139
+ print("=" * 80)
140
+ print(f"Total slides: {total}")
141
+ print(f"Passed: {passed} ({passed / total * 100:.1f}%)")
142
+ print(f"Failed: {failed} ({failed / total * 100:.1f}%)")
143
+ print()
144
+
145
+ if passed == total:
146
+ print("✓ All tests passed!")
147
+ else:
148
+ print(f"✗ {failed} test(s) failed")
149
+
150
+ # Calculate statistics for passed tests
151
+ if passed > 0:
152
+ confidences = [r["confidence"] for r in results if r["status"] == "PASS"]
153
+ avg_confidence = sum(confidences) / len(confidences)
154
+ min_confidence = min(confidences)
155
+ max_confidence = max(confidences)
156
+
157
+ print()
158
+ print("Confidence Statistics (for passed tests):")
159
+ print(f" Average: {avg_confidence:.4f} ({avg_confidence * 100:.2f}%)")
160
+ print(f" Minimum: {min_confidence:.4f} ({min_confidence * 100:.2f}%)")
161
+ print(f" Maximum: {max_confidence:.4f} ({max_confidence * 100:.2f}%)")
162
+
163
+ return {
164
+ "total": total,
165
+ "passed": passed,
166
+ "failed": failed,
167
+ "accuracy": passed / total if total > 0 else 0,
168
+ "results": results
169
+ }
170
+
171
+
172
+ def main():
173
+ parser = argparse.ArgumentParser(
174
+ description="Verify Aeon test results against ground truth"
175
+ )
176
+ parser.add_argument(
177
+ "--test-samples",
178
+ type=Path,
179
+ default=Path("test_slides/test_samples.json"),
180
+ help="Path to test_samples.json (default: test_slides/test_samples.json)"
181
+ )
182
+ parser.add_argument(
183
+ "--results-dir",
184
+ type=Path,
185
+ default=Path("test_slides/results"),
186
+ help="Directory containing results (default: test_slides/results)"
187
+ )
188
+ parser.add_argument(
189
+ "--output",
190
+ type=Path,
191
+ help="Optional path to save verification report as JSON"
192
+ )
193
+
194
+ args = parser.parse_args()
195
+
196
+ # Validate inputs
197
+ if not args.test_samples.exists():
198
+ raise FileNotFoundError(f"Test samples file not found: {args.test_samples}")
199
+
200
+ if not args.results_dir.exists():
201
+ raise FileNotFoundError(f"Results directory not found: {args.results_dir}")
202
+
203
+ # Load test samples
204
+ test_samples = load_test_samples(args.test_samples)
205
+
206
+ # Verify results
207
+ verification_report = verify_results(test_samples, args.results_dir)
208
+
209
+ # Save report if requested
210
+ if args.output:
211
+ with open(args.output, "w") as f:
212
+ json.dump(verification_report, f, indent=2)
213
+ print()
214
+ print(f"Verification report saved to: {args.output}")
215
+
216
+ # Exit with appropriate code
217
+ if verification_report["failed"] > 0:
218
+ exit(1)
219
+ else:
220
+ exit(0)
221
+
222
+
223
+ if __name__ == "__main__":
224
+ main()
src/mosaic/analysis.py CHANGED
@@ -181,7 +181,7 @@ def _run_aeon_inference(features, site_type, num_workers, sex=None, tissue_site_
181
  logger.info("Running Aeon for cancer subtype inference")
182
  aeon_results, _ = run_aeon(
183
  features=features,
184
- model_path="data/aeon_model_new.pkl",
185
  metastatic=(site_type == "Metastatic"),
186
  batch_size=8,
187
  num_workers=num_workers,
 
181
  logger.info("Running Aeon for cancer subtype inference")
182
  aeon_results, _ = run_aeon(
183
  features=features,
184
+ model_path="data/aeon_model.pkl",
185
  metastatic=(site_type == "Metastatic"),
186
  batch_size=8,
187
  num_workers=num_workers,
test_slides/AEON_TEST_SUMMARY.md ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Aeon Model Test Summary
2
+
3
+ ## Overview
4
+
5
+ This document summarizes the Aeon cancer subtype prediction model testing performed on January 7, 2026.
6
+
7
+ ## Model Information
8
+
9
+ - **Model File**: `aeon_model.pkl` (118MB)
10
+ - **Source**: Exported from `checkpoint.ckpt` (469MB, Nov 29, 2024)
11
+ - **Architecture**: AeonLateAggregator with late fusion
12
+ - **Output Classes**: 160 cancer subtypes
13
+ - **Input Features**:
14
+ - Tile embeddings from Optimus model
15
+ - Sex (one-hot encoded, 3 classes)
16
+ - Tissue site (one-hot encoded, 57 classes)
17
+ - Site type (Primary/Metastatic)
18
+
19
+ ## Test Slides
20
+
21
+ Three test slides were processed using the full Mosaic pipeline with Aeon inference:
22
+
23
+ ### Slide 1: 881837
24
+ - **File**: `881837.svs`
25
+ - **Ground Truth**: BLCA (Bladder Urothelial Carcinoma)
26
+ - **Site Type**: Primary
27
+ - **Sex**: Male
28
+ - **Tissue Site**: Bladder
29
+ - **Prediction**: BLCA
30
+ - **Confidence**: 98.19%
31
+ - **Status**: ✓ PASS
32
+
33
+ ### Slide 2: 744547
34
+ - **File**: `744547.svs`
35
+ - **Ground Truth**: HCC (Hepatocellular Carcinoma)
36
+ - **Site Type**: Metastatic
37
+ - **Sex**: Male
38
+ - **Tissue Site**: Liver
39
+ - **Prediction**: HCC
40
+ - **Confidence**: 99.49%
41
+ - **Status**: ✓ PASS
42
+
43
+ ### Slide 3: 755246
44
+ - **File**: `755246.svs`
45
+ - **Ground Truth**: HCC (Hepatocellular Carcinoma)
46
+ - **Site Type**: Primary
47
+ - **Sex**: Male
48
+ - **Tissue Site**: Liver
49
+ - **Prediction**: HCC
50
+ - **Confidence**: 99.61%
51
+ - **Status**: ✓ PASS
52
+
53
+ ## Test Results
54
+
55
+ | Slide ID | Ground Truth | Prediction | Confidence | Next Highest | Status |
56
+ |----------|--------------|------------|------------|--------------|--------|
57
+ | 881837 | BLCA | BLCA | 98.19% | UTUC (0.87%) | ✓ PASS |
58
+ | 744547 | HCC | HCC | 99.49% | IHCH (0.18%) | ✓ PASS |
59
+ | 755246 | HCC | HCC | 99.61% | IHCH (0.29%) | ✓ PASS |
60
+
61
+ **Overall Accuracy**: 3/3 (100%)
62
+
63
+ ## Pipeline Configuration
64
+
65
+ ### Segmentation
66
+ - **Config**: Biopsy (`SegmentationConfig.BIOPSY`)
67
+ - **Tissue Detection**: Automated segmentation of tissue regions
68
+ - **Tile Size**: 224x224 pixels at 20x magnification
69
+
70
+ ### Feature Extraction
71
+ - **CTransPath**: Pretrained histopathology foundation model
72
+ - **Optimus**: Multi-task feature aggregator
73
+ - **Marker Classifier**: Tissue marker prediction
74
+
75
+ ### Aeon Inference
76
+ - **Model Path**: `data/aeon_model.pkl`
77
+ - **Batch Size**: 8
78
+ - **Workers**: 4
79
+ - **Sex Encoding**: Male=0 (one-hot: [1,0,0])
80
+ - **Tissue Site Encoding**:
81
+ - Bladder=11 (one-hot vector, 57 dims)
82
+ - Liver=26 (one-hot vector, 57 dims)
83
+
84
+ ## Key Implementation Details
85
+
86
+ ### Cancer Type Mapping
87
+ - Mappings loaded from `data/metadata/target_dict.tsv`
88
+ - 160 histologies supported
89
+ - 5 cancer types excluded from predictions: UDMN, ADNOS, CUP, CUPNOS, NOT
90
+
91
+ ### Model Architecture
92
+ ```python
93
+ AeonLateAggregator(
94
+ tile_emb_dim=768,
95
+ num_targets=160,
96
+ sex_embedding_dim=mini_latent_dim (latent_dim // 4),
97
+ tissue_site_embedding_dim=mini_latent_dim,
98
+ site_embedding_dim=mini_latent_dim
99
+ )
100
+ ```
101
+
102
+ ### Encoding Functions
103
+ - **Sex**: `encode_sex(sex_str)` → index (0-2) → one-hot (3 classes)
104
+ - **Tissue Site**: `encode_tissue_site(tissue_site_str)` → index (0-56) → one-hot (57 classes)
105
+
106
+ ## Critical Fixes Applied
107
+
108
+ ### Issue 1: Model-Metadata Mismatch
109
+ - **Problem**: Model outputs 160 classes but code used 183-entry mapping
110
+ - **Solution**: Load mappings from `metadata/target_dict.tsv` instead of global constants
111
+ - **Files Modified**: `src/mosaic/inference/aeon.py` (lines 87-102, 127, 130-147)
112
+
113
+ ### Issue 2: Checkpoint Format
114
+ - **Problem**: Inference code expects `.pkl` files, not PyTorch Lightning `.ckpt` files
115
+ - **Solution**: Exported checkpoint using paladin's `AeonLightningModule.load_from_checkpoint()`
116
+ - **Export Command**: See `scripts/export_aeon_checkpoint.py`
117
+
118
+ ### Issue 3: Missing AeonLateAggregator
119
+ - **Problem**: PyPI paladin package had `AeonAggregator`, not `AeonLateAggregator`
120
+ - **Solution**: Installed paladin from git repo dev branch
121
+ - **Command**: `uv sync --upgrade-package paladin`
122
+
123
+ ## Dependencies
124
+
125
+ ### Critical Packages
126
+ - `paladin` (from git: ssh://git@github.com/pathology-data-mining/paladin.git@dev)
127
+ - `torch>=2.0`
128
+ - `pytorch-lightning`
129
+ - `pandas`
130
+ - `numpy`
131
+
132
+ ### Model Files Required
133
+ - `aeon_model.pkl` (118MB)
134
+ - `metadata/target_dict.tsv`
135
+ - `metadata/n_classes.txt`
136
+ - `metadata/ontology_embedding_dim.txt`
137
+ - `sex_original_to_idx.csv`
138
+ - `tissue_site_original_to_idx.csv`
139
+
140
+ ## Reproducibility
141
+
142
+ All test results are fully reproducible using:
143
+ 1. The test samples defined in `test_samples.json`
144
+ 2. The run script: `scripts/run_aeon_tests.sh`
145
+ 3. The model and metadata uploaded to `PDM-Group/paladin-aeon-models` on Hugging Face
146
+
147
+ ## Output Files
148
+
149
+ For each slide, the following files are generated in `test_slides/results/{slide_id}/`:
150
+ - `{slide_id}_aeon_results.csv` - Full confidence scores for all 160 cancer subtypes
151
+ - `{slide_id}_paladin_results.csv` - Biomarker predictions
152
+ - `{slide_id}_mask.png` - Tissue segmentation mask
153
+ - `{slide_id}_features.h5` - Extracted tile features
154
+
155
+ ## Validation Metrics
156
+
157
+ - **Prediction Accuracy**: 100% (3/3)
158
+ - **Average Confidence**: 99.10%
159
+ - **Minimum Confidence**: 98.19%
160
+ - **Maximum Confidence**: 99.61%
161
+
162
+ ## Hugging Face Repository
163
+
164
+ All model files and metadata have been uploaded to:
165
+ - **Repository**: `PDM-Group/paladin-aeon-models`
166
+ - **URL**: https://huggingface.co/PDM-Group/paladin-aeon-models
167
+
168
+ ### Uploaded Files (Jan 7, 2026)
169
+ - `aeon_model.pkl` (118MB)
170
+ - `metadata/` (5 files)
171
+ - `sex_original_to_idx.csv`
172
+ - `tissue_site_original_to_idx.csv`
173
+
174
+ ## Test Date
175
+
176
+ - **Date**: January 7, 2026
177
+ - **Git Commit**: 49fbf68 (Complete implementation of sex and tissue site parameters)
178
+ - **Tester**: Ray Lim
test_slides/results/744547/744547_aeon_results.csv ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Cancer Subtype,Confidence
2
+ HCC,0.9949353337287903
3
+ IHCH,0.0018046980258077383
4
+ ACC,0.000752770050894469
5
+ OPHSC,0.00036126983468420804
6
+ PAAC,0.0003446016926318407
7
+ THHC,0.0001074946703738533
8
+ NPC,9.898660937324166e-05
9
+ HNSC,8.415944466833025e-05
10
+ STAD,8.021725079743192e-05
11
+ HGNEC,7.314849062822759e-05
12
+ WT,6.0233636759221554e-05
13
+ ANSC,5.0760227168211713e-05
14
+ NSGCT,4.1861039790092036e-05
15
+ CHRCC,3.653292151284404e-05
16
+ EHCH,3.409649070817977e-05
17
+ PEMESO,3.360131086083129e-05
18
+ SFT,3.2356434530811384e-05
19
+ PANET,3.2246403861790895e-05
20
+ ANGS,3.0679162591695786e-05
21
+ PAAD,2.974703056679573e-05
22
+ EGC,2.666616092028562e-05
23
+ UM,2.5927740352926776e-05
24
+ MCC,2.5807627025642432e-05
25
+ SKCM,2.2870222892379388e-05
26
+ ODG,2.1314301193342544e-05
27
+ COAD,2.0228028006386012e-05
28
+ SCLC,2.006701470236294e-05
29
+ PTAD,1.9878523744409904e-05
30
+ SSRCC,1.9336708646733314e-05
31
+ PECOMA,1.8762702893582173e-05
32
+ SBOV,1.75385684997309e-05
33
+ PRCC,1.7517071682959795e-05
34
+ EMPD,1.742972199281212e-05
35
+ LMS,1.7376194591633976e-05
36
+ ES,1.7088817912735976e-05
37
+ SBWDNET,1.6885298464330845e-05
38
+ READ,1.6691648852429353e-05
39
+ ASTR,1.5237395928124897e-05
40
+ MACR,1.468232130719116e-05
41
+ ARMM,1.4290351828094572e-05
42
+ CSCC,1.4241238204704132e-05
43
+ LUSC,1.3981271877128165e-05
44
+ THPA,1.3920045603299513e-05
45
+ CCOV,1.389113640470896e-05
46
+ PRAD,1.3490677702066023e-05
47
+ BLCA,1.2866928955190815e-05
48
+ GIST,1.2835040251957253e-05
49
+ BCC,1.2371066986816004e-05
50
+ THPD,1.229105419042753e-05
51
+ BMGCT,1.1911726687685587e-05
52
+ DES,1.1774703125411179e-05
53
+ LGSOC,1.158510258392198e-05
54
+ UTUC,1.1252666809014045e-05
55
+ PAMPCA,1.1209620424779132e-05
56
+ ACYC,1.0676962119759992e-05
57
+ THYC,1.063129002432106e-05
58
+ ULMS,1.0360988198954146e-05
59
+ WDLS,9.846420653047971e-06
60
+ DA,9.834530828811694e-06
61
+ MPNST,9.739153028931469e-06
62
+ HNMUCM,9.407535799255129e-06
63
+ THAP,9.405741366208531e-06
64
+ OCS,9.383109500049613e-06
65
+ GBAD,9.255892109649722e-06
66
+ GCCAP,9.183406291413121e-06
67
+ SDCA,9.130208127317019e-06
68
+ EPIS,8.989960406324826e-06
69
+ PHC,8.885029274097178e-06
70
+ EHAE,8.772132787271403e-06
71
+ PLMESO,8.688036359671969e-06
72
+ ESCC,8.65026049723383e-06
73
+ TAC,8.619595064374153e-06
74
+ GRCT,8.587684533267748e-06
75
+ BLAD,8.564702511648647e-06
76
+ DSRCT,8.161241566995159e-06
77
+ EPM,7.880689736339264e-06
78
+ MFH,7.607672614540206e-06
79
+ SCBC,7.4185886660416145e-06
80
+ SEM,7.19011586625129e-06
81
+ SYNS,7.085985998855904e-06
82
+ UCP,6.969770311116008e-06
83
+ UEC,6.914885034348117e-06
84
+ LUCA,6.88146519678412e-06
85
+ GEJ,6.397517154255183e-06
86
+ ALUCA,6.210095307324082e-06
87
+ CHDM,6.182817287481157e-06
88
+ OS,6.126435437181499e-06
89
+ MAAP,6.075235432945192e-06
90
+ LUPC,6.040307198418304e-06
91
+ ESCA,5.798766324005555e-06
92
+ ERMS,5.519645128515549e-06
93
+ RBL,5.355142548069125e-06
94
+ VSC,5.320628133631544e-06
95
+ DDLS,5.237710411165608e-06
96
+ CCRCC,4.890111540589714e-06
97
+ ARMS,4.8574038373772055e-06
98
+ MNG,4.79665777675109e-06
99
+ HGSOC,4.588881893141661e-06
100
+ THYM,4.543203431239817e-06
101
+ BA,4.302230991015676e-06
102
+ NBL,4.251941845723195e-06
103
+ UCCC,4.113941486139083e-06
104
+ GBM,3.829367415164597e-06
105
+ EOV,3.7675256407965207e-06
106
+ CHS,3.7070362850499805e-06
107
+ IDC,2.831375240930356e-06
108
+ MBC,2.820524969138205e-06
109
+ DASTR,2.7697560653905384e-06
110
+ UCS,2.7230109935771907e-06
111
+ CESC,2.5985430056607584e-06
112
+ VMM,2.466509386067628e-06
113
+ ILC,2.451496357025462e-06
114
+ LUNE,2.4507951366103953e-06
115
+ ATM,2.3741329187032534e-06
116
+ MRLS,2.351298462599516e-06
117
+ THME,2.2384033400157932e-06
118
+ MOV,2.2177562186698196e-06
119
+ ECAD,2.15100362765952e-06
120
+ LUAD,1.7751663108356297e-06
121
+ ACRM,1.5891558859948418e-06
122
+ MFS,1.58587818077649e-06
123
+ PAST,1.1561178325791843e-06
124
+ USC,9.618892136131763e-07
125
+ SCHW,9.386900501340278e-07
126
+ NECNOS,6.424317007258651e-07
127
+ BRCANOS,4.31851503890357e-07
128
+ MDLC,4.30085862035412e-07
129
+ SCCNOS,3.5081365012956667e-07
130
+ SBC,3.1285472346098686e-07
131
+ NSCLC,2.687320375116542e-07
132
+ MXOV,2.395507863184321e-07
133
+ SARCNOS,2.364027835710658e-07
134
+ MEL,2.3354837708211562e-07
135
+ CHOL,2.3344369992628344e-07
136
+ PAASC,2.256272324530073e-07
137
+ MUP,2.2071883165608597e-07
138
+ BRCA,2.1710592079671187e-07
139
+ NVRINT,2.1676953565474832e-07
140
+ AMPCA,2.1609788802834373e-07
141
+ LUAS,2.136845722588987e-07
142
+ URCC,2.0894131580462272e-07
143
+ BRCNOS,2.067983615461344e-07
144
+ GINET,2.0037792580751557e-07
145
+ PDC,1.7432496690616972e-07
146
+ GNOS,1.6309185468799114e-07
147
+ NETNOS,1.6066735497588525e-07
148
+ APAD,1.5840650746667961e-07
149
+ DIFG,1.5840393530197616e-07
150
+ COADREAD,1.5738932290787488e-07
151
+ CSCLC,1.4587288887923933e-07
152
+ RCC,1.3664508458077762e-07
153
+ UMEC,1.1690717371948267e-07
154
+ GBC,8.854171795746879e-08
155
+ NSCLCPD,7.288439718422524e-08
156
+ UCEC,7.106321220362588e-08
157
+ ADNOS,0.0
158
+ CUP,0.0
159
+ CUPNOS,0.0
160
+ NOT,0.0
161
+ UDMN,0.0
test_slides/results/744547/744547_paladin_results.csv ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Cancer Subtype,Biomarker,Score
2
+ HCC,Del_8p,0.2197096198797226
test_slides/results/755246/755246_aeon_results.csv ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Cancer Subtype,Confidence
2
+ HCC,0.9960950016975403
3
+ IHCH,0.0028622548561543226
4
+ PAAC,0.0002748313418123871
5
+ OPHSC,4.615329817170277e-05
6
+ ACC,3.686468699015677e-05
7
+ NPC,3.5695637052413076e-05
8
+ HGNEC,2.805266558425501e-05
9
+ PAMPCA,2.4401044356636703e-05
10
+ HNSC,2.1414962247945368e-05
11
+ WT,2.062890780507587e-05
12
+ STAD,1.9500384951243177e-05
13
+ ANSC,1.9137134586344473e-05
14
+ NSGCT,1.8425340385874733e-05
15
+ ACYC,1.6153164324350655e-05
16
+ SFT,1.4236396054911893e-05
17
+ PAAD,1.385363702866016e-05
18
+ ANGS,1.3724854397878516e-05
19
+ CSCC,1.1247223483223934e-05
20
+ CHRCC,1.1185951734660193e-05
21
+ MCC,1.1107679711130913e-05
22
+ PEMESO,1.0368969924456906e-05
23
+ LUSC,1.0365045454818755e-05
24
+ BMGCT,1.0343398571421858e-05
25
+ LGSOC,1.0238399227091577e-05
26
+ COAD,1.0101895895786583e-05
27
+ PECOMA,9.616783245292027e-06
28
+ ODG,9.323048288933933e-06
29
+ READ,8.963126674643718e-06
30
+ GBAD,8.933258868637495e-06
31
+ ASTR,8.659791092213709e-06
32
+ EMPD,8.184463695215527e-06
33
+ CCOV,7.98109067545738e-06
34
+ SSRCC,7.932881999295205e-06
35
+ LMS,7.707203621976078e-06
36
+ SDCA,7.481134616682539e-06
37
+ EGC,7.304894097615033e-06
38
+ EHCH,7.18998262527748e-06
39
+ DA,7.112325420166599e-06
40
+ GRCT,7.074557743180776e-06
41
+ THYC,6.8966392063885e-06
42
+ ES,6.499152732430957e-06
43
+ TAC,6.04554270466906e-06
44
+ LUPC,5.894301011721836e-06
45
+ UM,5.811031769553665e-06
46
+ HNMUCM,5.70150587009266e-06
47
+ MPNST,5.589005922956858e-06
48
+ PTAD,5.411789061326999e-06
49
+ THHC,5.279471679386916e-06
50
+ SBOV,5.134588718647137e-06
51
+ EHAE,5.056334430264542e-06
52
+ UCP,4.79583195556188e-06
53
+ PANET,4.769396582560148e-06
54
+ UEC,4.691957201430341e-06
55
+ MFH,4.5436950131261256e-06
56
+ DES,4.397928478283575e-06
57
+ MACR,4.386647560750134e-06
58
+ DSRCT,4.259570687281666e-06
59
+ BCC,4.2207666410831735e-06
60
+ THYM,4.200107468932401e-06
61
+ SKCM,4.163767698628362e-06
62
+ SCLC,4.137152245675679e-06
63
+ SBWDNET,4.107126642338699e-06
64
+ BLCA,4.042853561259108e-06
65
+ THPA,3.967577868024819e-06
66
+ CHDM,3.964094503317028e-06
67
+ EPIS,3.7835466173419263e-06
68
+ UTUC,3.6972760426579043e-06
69
+ PRCC,3.5816708532365737e-06
70
+ RBL,3.18466845783405e-06
71
+ PHC,3.1321446840593126e-06
72
+ ARMS,3.073702600886463e-06
73
+ WDLS,2.967372893181164e-06
74
+ HGSOC,2.9246689337014686e-06
75
+ EOV,2.842233243427472e-06
76
+ PLMESO,2.8313088478171267e-06
77
+ LUCA,2.7812454845843604e-06
78
+ ERMS,2.6738305223261705e-06
79
+ ARMM,2.653551291587064e-06
80
+ ESCC,2.534464101699996e-06
81
+ GIST,2.4675975964782992e-06
82
+ OS,2.3962300019775284e-06
83
+ SEM,2.267454874527175e-06
84
+ UCCC,2.2549797904503066e-06
85
+ GEJ,2.228342964372132e-06
86
+ ALUCA,2.21250593313016e-06
87
+ CCRCC,2.1547989490500186e-06
88
+ GCCAP,2.145640792150516e-06
89
+ CHS,2.1370740341808414e-06
90
+ EPM,2.113296659445041e-06
91
+ LUNE,1.8964744867844274e-06
92
+ THAP,1.8861140915760188e-06
93
+ MNG,1.883976551653177e-06
94
+ SCBC,1.8645082491275389e-06
95
+ GBM,1.8083156874126871e-06
96
+ THME,1.7755396584107075e-06
97
+ SYNS,1.749014700180851e-06
98
+ VSC,1.7275091295232414e-06
99
+ PRAD,1.7234281131095486e-06
100
+ THPD,1.5961649069140549e-06
101
+ OCS,1.574517796143482e-06
102
+ ULMS,1.5738452248115209e-06
103
+ ESCA,1.5239124877552968e-06
104
+ LUAD,1.5225077731884085e-06
105
+ ATM,1.4334439129015664e-06
106
+ DASTR,1.3374641412156052e-06
107
+ BLAD,1.3204950164436013e-06
108
+ MRLS,1.2621910627785837e-06
109
+ PAST,1.214046847053396e-06
110
+ DDLS,1.207565446748049e-06
111
+ BA,1.193913703900762e-06
112
+ USC,1.1651327440631576e-06
113
+ UCS,1.127504333453544e-06
114
+ IDC,1.1131320434287773e-06
115
+ MBC,1.073736029866268e-06
116
+ CESC,1.0562247325651697e-06
117
+ ECAD,1.0221086768069654e-06
118
+ MOV,1.0173221198783722e-06
119
+ MFS,8.068860779530951e-07
120
+ ILC,7.115056064321834e-07
121
+ NBL,7.080777209012012e-07
122
+ MAAP,7.038765375000366e-07
123
+ SCHW,6.599229323001055e-07
124
+ VMM,6.425576088986418e-07
125
+ ACRM,5.137104039931728e-07
126
+ SCCNOS,2.88556179839361e-07
127
+ NECNOS,2.860723498088191e-07
128
+ MDLC,1.5423735533204308e-07
129
+ SBC,1.473414386055083e-07
130
+ LUAS,1.313886741627357e-07
131
+ AMPCA,1.1514853781591228e-07
132
+ BRCANOS,1.100927349284575e-07
133
+ COADREAD,1.0235498848487623e-07
134
+ BRCNOS,1.0230521496623624e-07
135
+ NSCLC,9.84467831699476e-08
136
+ URCC,9.794707978016959e-08
137
+ SARCNOS,9.708332271429754e-08
138
+ MEL,9.660030997338254e-08
139
+ MXOV,9.167136028054301e-08
140
+ BRCA,9.164460124111429e-08
141
+ GINET,9.150922863909727e-08
142
+ MUP,8.768505921352698e-08
143
+ GNOS,8.663077721848822e-08
144
+ CSCLC,8.40352782915943e-08
145
+ PAASC,8.390650663159249e-08
146
+ CHOL,8.387851124780354e-08
147
+ NVRINT,7.996587214620376e-08
148
+ PDC,7.627340892213397e-08
149
+ APAD,7.168080173869384e-08
150
+ NETNOS,5.965442539945798e-08
151
+ RCC,5.8925582635538376e-08
152
+ DIFG,5.8173132089223145e-08
153
+ UMEC,4.262162889290266e-08
154
+ GBC,3.4216750322002554e-08
155
+ NSCLCPD,2.902431717188847e-08
156
+ UCEC,2.4343131954651653e-08
157
+ ADNOS,0.0
158
+ CUP,0.0
159
+ CUPNOS,0.0
160
+ NOT,0.0
161
+ UDMN,0.0
test_slides/results/755246/755246_paladin_results.csv ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Cancer Subtype,Biomarker,Score
2
+ HCC,Del_8p,0.5229867100715637
test_slides/results/881837/881837_aeon_results.csv ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Cancer Subtype,Confidence
2
+ BLCA,0.9819191694259644
3
+ UTUC,0.008712546899914742
4
+ ESCC,0.0018056846456602216
5
+ HNSC,0.0012019714340567589
6
+ SCBC,0.0011546163586899638
7
+ CSCC,0.0009968428639695048
8
+ BLAD,0.000923480314668268
9
+ VSC,0.0003943268384318799
10
+ LUSC,0.0002285304362885654
11
+ MFH,0.0002151085063815117
12
+ CESC,0.00016243607387878
13
+ ANSC,0.00014434086915571243
14
+ OPHSC,0.00010440379264764488
15
+ ERMS,9.818207036005333e-05
16
+ ESCA,8.05684321676381e-05
17
+ THME,7.75650842115283e-05
18
+ DDLS,7.418631867039949e-05
19
+ EMPD,6.874153041280806e-05
20
+ SKCM,6.219839997356758e-05
21
+ STAD,5.7987392210634425e-05
22
+ ARMM,5.323389996192418e-05
23
+ VMM,4.82685245515313e-05
24
+ ANGS,4.764321420225315e-05
25
+ HNMUCM,4.300122964195907e-05
26
+ MPNST,4.062237712787464e-05
27
+ THAP,3.992616620962508e-05
28
+ CCOV,3.978966560680419e-05
29
+ EGC,3.804164953180589e-05
30
+ PECOMA,3.58297438651789e-05
31
+ GEJ,3.361854032846168e-05
32
+ LMS,3.190735151292756e-05
33
+ GIST,3.053894397453405e-05
34
+ UCP,2.6960187824442983e-05
35
+ BCC,2.6275198251823895e-05
36
+ WDLS,2.504539406800177e-05
37
+ COAD,2.4500428480678238e-05
38
+ READ,2.3131282432586886e-05
39
+ PLMESO,2.2688231183565222e-05
40
+ PHC,2.2610343876294792e-05
41
+ HGSOC,2.2057527530705556e-05
42
+ EHCH,2.0888484868919477e-05
43
+ SFT,2.061663690255955e-05
44
+ LUPC,2.0348075850051828e-05
45
+ ARMS,2.0138555555604398e-05
46
+ NPC,2.0069532183697447e-05
47
+ SDCA,1.9388126020203345e-05
48
+ PRAD,1.885020174086094e-05
49
+ PAMPCA,1.8754808479570784e-05
50
+ HGNEC,1.862645149230957e-05
51
+ DA,1.7162436051876284e-05
52
+ EPM,1.6749159840401262e-05
53
+ PTAD,1.6459982361993752e-05
54
+ NSGCT,1.5192160390142817e-05
55
+ UM,1.4609363461204339e-05
56
+ SSRCC,1.4532034583680797e-05
57
+ SEM,1.3767842574452516e-05
58
+ GCCAP,1.3716285138798412e-05
59
+ OS,1.3539702194975689e-05
60
+ LUCA,1.3414683053269982e-05
61
+ BA,1.340845392405754e-05
62
+ ODG,1.3301939361554105e-05
63
+ ULMS,1.3188847333367448e-05
64
+ ILC,1.3158909496269189e-05
65
+ GBAD,1.3059830052952748e-05
66
+ HCC,1.2799720934708603e-05
67
+ THYC,1.2515503840404563e-05
68
+ ACC,1.2373102435958572e-05
69
+ EHAE,1.2079371117579285e-05
70
+ THPD,1.2004609743598849e-05
71
+ LUAD,1.1745101801352575e-05
72
+ IHCH,1.1457958862592932e-05
73
+ BMGCT,1.14437843876658e-05
74
+ DSRCT,1.1421912859077565e-05
75
+ ASTR,1.1173871826031245e-05
76
+ THPA,1.0899780136242043e-05
77
+ DES,1.0811750144057442e-05
78
+ MNG,1.0468449545442127e-05
79
+ PEMESO,1.0408997695776634e-05
80
+ ES,1.0323257811251096e-05
81
+ SCHW,1.024130961013725e-05
82
+ ACRM,9.928556210070383e-06
83
+ RBL,9.5573650469305e-06
84
+ UCS,9.554930329613853e-06
85
+ CHDM,9.308922926720697e-06
86
+ NBL,9.223444067174569e-06
87
+ OCS,9.14371048565954e-06
88
+ MBC,8.864662049745675e-06
89
+ EPIS,8.839479050948285e-06
90
+ LUNE,7.987197932379786e-06
91
+ MFS,7.876495146774687e-06
92
+ GRCT,7.63608932174975e-06
93
+ UCCC,7.5786451816384215e-06
94
+ SBOV,7.530676612077514e-06
95
+ LGSOC,7.442437436111504e-06
96
+ IDC,7.195951184257865e-06
97
+ ATM,7.1556032708031125e-06
98
+ CCRCC,6.893693353049457e-06
99
+ PAAC,6.823243893450126e-06
100
+ TAC,6.447641681006644e-06
101
+ PRCC,6.3316215346276294e-06
102
+ THHC,6.0560396377695724e-06
103
+ ACYC,5.6987450989254285e-06
104
+ SYNS,5.622236585622886e-06
105
+ EOV,5.584717200690648e-06
106
+ PAAD,5.3922740335110575e-06
107
+ ALUCA,5.391060767578892e-06
108
+ SBWDNET,5.067640813649632e-06
109
+ CHRCC,5.057868747826433e-06
110
+ MOV,5.055631390860071e-06
111
+ MACR,4.9109949031844735e-06
112
+ USC,4.86157659906894e-06
113
+ THYM,4.622621872840682e-06
114
+ MRLS,3.963573362852912e-06
115
+ MCC,3.7632978546753293e-06
116
+ GBM,3.364578788023209e-06
117
+ DASTR,3.190721145074349e-06
118
+ WT,3.0390583560802042e-06
119
+ PAST,3.0256139780249214e-06
120
+ ECAD,2.9308980629139114e-06
121
+ UEC,2.8302536065893946e-06
122
+ SCLC,2.7639291602099547e-06
123
+ CHS,2.524923047531047e-06
124
+ PANET,1.8923717561847297e-06
125
+ MAAP,1.4423669654206606e-06
126
+ COADREAD,4.742931878354284e-07
127
+ NECNOS,3.882300347868295e-07
128
+ SCCNOS,3.831314643321093e-07
129
+ SARCNOS,3.6490285992840654e-07
130
+ CSCLC,3.121313341125642e-07
131
+ AMPCA,3.0839311193631147e-07
132
+ BRCANOS,3.0359336733454256e-07
133
+ MDLC,3.011147668985359e-07
134
+ LUAS,2.772100344827777e-07
135
+ MXOV,2.492066641934798e-07
136
+ UCEC,2.3689378281233076e-07
137
+ BRCA,2.2784350051097135e-07
138
+ PDC,2.1551392137553194e-07
139
+ PAASC,2.1430530239285872e-07
140
+ NETNOS,2.1316037646101904e-07
141
+ SBC,2.033053903005566e-07
142
+ NVRINT,1.984174957669893e-07
143
+ URCC,1.8473356533377228e-07
144
+ BRCNOS,1.7265826102175197e-07
145
+ NSCLC,1.700868494936003e-07
146
+ GBC,1.6887882736682513e-07
147
+ GINET,1.6104266364891373e-07
148
+ APAD,1.5570284972454829e-07
149
+ GNOS,1.547322483475e-07
150
+ CHOL,1.4654114011136699e-07
151
+ DIFG,1.4512880852635135e-07
152
+ MUP,1.4281692983786343e-07
153
+ MEL,1.391822195273562e-07
154
+ NSCLCPD,1.0773995029467187e-07
155
+ RCC,9.598431205404268e-08
156
+ UMEC,6.501737459529977e-08
157
+ ADNOS,0.0
158
+ CUP,0.0
159
+ CUPNOS,0.0
160
+ NOT,0.0
161
+ UDMN,0.0
test_slides/results/881837/881837_paladin_results.csv ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ Cancer Subtype,Biomarker,Score
2
+ BLCA,Del_6q,0.14185988903045654
3
+ BLCA,FGFR3_ONCOGENIC,0.08551423251628876
4
+ BLCA,RB1_ONCOGENIC,0.10338973999023438
5
+ BLCA,RB1_TRUNC,0.08562182635068893
6
+ BLCA,TP53_PATHWAY,0.8390844464302063
test_slides/test_samples.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "sample_id": "P-0000034-T01-IM3",
4
+ "image_id": "881837",
5
+ "sex": "MALE",
6
+ "tissue_site": "Bladder",
7
+ "site_type": "Primary",
8
+ "cancer_type": "BLCA",
9
+ "confidence": 0.9412469863891602
10
+ },
11
+ {
12
+ "sample_id": "P-0000037-T01-IM3",
13
+ "image_id": "744547",
14
+ "sex": "Male",
15
+ "tissue_site": "Liver",
16
+ "site_type": "Metastasis",
17
+ "cancer_type": "HCC",
18
+ "confidence": 0.9471913576126099
19
+ },
20
+ {
21
+ "sample_id": "P-0000037-T02-IM3",
22
+ "image_id": "755246",
23
+ "sex": "Male",
24
+ "tissue_site": "Liver",
25
+ "site_type": "Primary",
26
+ "cancer_type": "HCC",
27
+ "confidence": 0.9306515455245972
28
+ }
29
+ ]
test_slides/verification_report.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "total": 3,
3
+ "passed": 3,
4
+ "failed": 0,
5
+ "accuracy": 1.0,
6
+ "results": [
7
+ {
8
+ "slide_id": "881837",
9
+ "ground_truth": "BLCA",
10
+ "predicted": "BLCA",
11
+ "confidence": 0.9819191694259644,
12
+ "site_type": "Primary",
13
+ "sex": "MALE",
14
+ "tissue_site": "Bladder",
15
+ "status": "PASS"
16
+ },
17
+ {
18
+ "slide_id": "744547",
19
+ "ground_truth": "HCC",
20
+ "predicted": "HCC",
21
+ "confidence": 0.9949353337287904,
22
+ "site_type": "Metastasis",
23
+ "sex": "Male",
24
+ "tissue_site": "Liver",
25
+ "status": "PASS"
26
+ },
27
+ {
28
+ "slide_id": "755246",
29
+ "ground_truth": "HCC",
30
+ "predicted": "HCC",
31
+ "confidence": 0.9960950016975404,
32
+ "site_type": "Primary",
33
+ "sex": "Male",
34
+ "tissue_site": "Liver",
35
+ "status": "PASS"
36
+ }
37
+ ]
38
+ }