forked from baptistebaquero/ALIDDM
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathvisualize_cache.py
More file actions
205 lines (170 loc) · 7.4 KB
/
Copy pathvisualize_cache.py
File metadata and controls
205 lines (170 loc) · 7.4 KB
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
#!/usr/bin/env python3
"""
Visualize cached inputs and targets from disk.
Shows 5 camera views side by side for a selected patient.
"""
import os
import sys
import torch
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.gridspec import GridSpec
import numpy as np
# Add py folder to path to import GlobVar
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'py'))
import GlobVar as GV
CACHE_BASE_DIR = '/media/luciacev/Data/ALI_IOS cache_mg'
def get_cached_files(cache_dir):
"""List all cached files in a directory."""
if not os.path.exists(cache_dir):
return []
return sorted([f for f in os.listdir(cache_dir) if f.endswith('.pth')])
def load_tensor(filepath):
"""Load a tensor from disk."""
try:
return torch.load(filepath, weights_only=True)
except Exception as e:
print(f"Error loading {filepath}: {e}")
return None
def visualize_patient(patient_name, label, jawtype='L', lm_typ='O', fold_idx=None, cache_type=None):
"""
Visualize inputs and targets for a patient and tooth label.
Automatically finds the correct fold and cache_type if not specified.
Args:
patient_name: e.g., "A10_T1_L_SegOrReg"
label: tooth label, e.g., "18"
jawtype: 'L' or 'U'
lm_typ: 'O' or 'C'
fold_idx: fold index (0-4), auto-detect if None
cache_type: 'train' or 'val', auto-detect if None
"""
# Determine number of cameras based on landmark type
lm_type_dir = GV.PATH_DICT[lm_typ]
n_cameras = 3#len(GV.dic_cam[lm_typ.upper()][jawtype])
# Load input from global cache
input_dir = os.path.join(CACHE_BASE_DIR,lm_type_dir, f'global_inputs_{jawtype}')
input_file = f"input_{patient_name}_{label}.pth"
input_path = os.path.join(input_dir, input_file)
# Check if input exists
if not os.path.exists(input_path):
print(f"❌ Input file not found: {input_path}")
return
# Auto-detect fold and cache_type if not specified
target_path = None
if fold_idx is not None and cache_type is not None:
target_dir = os.path.join(CACHE_BASE_DIR,lm_type_dir, f'fold_{fold_idx}_targets_{cache_type}_{jawtype}_{lm_typ}')
target_file = f"target_{patient_name}_{label}.pth"
target_path = os.path.join(target_dir, target_file)
else:
# Search for target in all folds and cache types
for fi in range(5):
for ct in ['train', 'val']:
target_dir = os.path.join(CACHE_BASE_DIR,lm_type_dir, f'fold_{fi}_targets_{ct}_{jawtype}_{lm_typ}')
target_file = f"target_{patient_name}_{label}.pth"
test_path = os.path.join(target_dir, target_file)
if os.path.exists(test_path):
target_path = test_path
fold_idx = fi
cache_type = ct
break
if target_path is not None:
break
if target_path is None:
print(f"❌ Target file not found in any fold!")
print(f" Searched for: target_{patient_name}_{label}.pth")
return
# Load tensors
input_tensor = load_tensor(input_path)
target_tensor = load_tensor(target_path)
if input_tensor is None or target_tensor is None:
return
print(f"✅ Loaded {patient_name} | Tooth {label} | Mode {lm_typ} | Fold {fold_idx} ({cache_type})")
print(f" Input shape: {input_tensor.shape}")
print(f" Target shape: {target_tensor.shape}")
# input_tensor: [n_cameras, 4, 224, 224] = cameras × (RGB + Z)
# target_tensor: [n_cameras, 4, 224, 224] = cameras × (RGB + Z)
# Extract RGB channels (first 3 channels, drop Z-buffer)
input_rgb = input_tensor[:, :3, :, :] # [n_cameras, 3, 224, 224]
target_rgb = target_tensor[:, :3, :, :] # [n_cameras, 3, 224, 224]
# Create figure with 2 rows × n_cameras columns
fig = plt.figure(figsize=(4*n_cameras, 8))
gs = GridSpec(2, n_cameras, figure=fig, hspace=0.3, wspace=0.1)
# Plot inputs (top row)
for cam_idx in range(n_cameras):
ax = fig.add_subplot(gs[0, cam_idx])
img = input_rgb[cam_idx].permute(1, 2, 0).numpy()
img = np.clip(img, 0, 1)
ax.imshow(img)
ax.set_title(f"Input - Cam {cam_idx}", fontsize=8, fontweight='bold')
ax.axis('off')
# Plot targets (bottom row)
for cam_idx in range(n_cameras):
ax = fig.add_subplot(gs[1, cam_idx])
img = target_rgb[cam_idx].permute(1, 2, 0).numpy()
img = np.clip(img, 0, 1)
ax.imshow(img)
# Add color legend based on mode
if lm_typ.upper() == 'O':
legend_text = "🔴 O, 🟢 MB, 🔵 DB"
elif lm_typ.upper() == 'C':
legend_text = "🟣 CL, 🟠 CB"
else:
legend_text = "🟣 MG"
ax.set_title(f"Target ({lm_typ}) - Cam {cam_idx}\n{legend_text}", fontsize=7, fontweight='bold')
ax.axis('off')
fig.suptitle(f"Patient: {patient_name} | Tooth: {label} | Jaw: {jawtype} | Mode: {lm_typ} ({n_cameras} cams) | Fold: {fold_idx} ({cache_type})",
fontsize=14, fontweight='bold')
plt.tight_layout()
plt.show()
def list_available_patients(jawtype='L',region = 'O'):
"""List all available patients in the global input cache."""
lm_type_dir = GV.PATH_DICT[region]
input_dir = os.path.join(CACHE_BASE_DIR,lm_type_dir, f'global_inputs_{jawtype}')
files = get_cached_files(input_dir)
# Extract unique patient names
patients = set()
for f in files:
# Extract patient name from "input_PATIENT_LABEL.pth"
parts = f.replace('input_', '').replace('.pth', '').rsplit('_', 1)
if len(parts) == 2:
patient_name = parts[0]
patients.add(patient_name)
return sorted(list(patients))
def main():
print("\n" + "="*80)
print(" CACHE VISUALIZATION TOOL")
print("="*80)
# Configuration
jawtype = 'L' # 'L' for Lower, 'U' for Upper
lm_typ = 'MG' # 'O' for Occlusal, 'C' for Cervical
fold_idx = 0
cache_type = 'train'
# List available patients
patients = list_available_patients(jawtype,lm_typ)
print(f"\n✅ Found {len(patients)} unique patients in {jawtype} jaw cache")
print(f" First 5 patients: {patients[:5]}")
if len(patients) == 0:
print("❌ No patients found. Make sure pre-rendering is complete.")
return
# Select first patient and all teeth
patient_name = patients[0]
print(f"\n📋 Visualizing patient: {patient_name}")
# List available teeth for this patient
input_dir = os.path.join(CACHE_BASE_DIR,"Mucogingival", f'global_inputs_{jawtype}')
files = get_cached_files(input_dir)
teeth = set()
for f in files:
if patient_name in f:
# Extract tooth label from "input_PATIENT_LABEL.pth"
label = f.replace('input_', '').replace('.pth', '').replace(patient_name + '_', '')
teeth.add(label)
teeth = sorted(list(teeth))
print(f" Available teeth: {teeth}")
# Visualize first few teeth
for tooth_idx, label in enumerate(teeth[:15]):
print(f"\n▶️ Visualizing tooth {label}...")
visualize_patient(patient_name, label, jawtype=jawtype, lm_typ=lm_typ) # Auto-detect fold
if tooth_idx >= 10: # Show max 3 teeth
break
if __name__ == '__main__':
main()