File size: 6,179 Bytes
7536b30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""

prepare_cross_session_data.py

Prepare Aug16 session data for cross-session evaluation (Phase 2, Step 1).



The WILD dataset has 5 Jacobs Hall sessions. Our models trained on sessions 1+2

(July28). To test cross-session generalization, we need sessions 3-5 (Aug16).



STEP 1 — Download raw feature files from WILD (password-protected):

  https://wcsng.ucsd.edu/wild/

  Place these in ./data/:

    features_jacobs_Aug16_1.mat

    features_jacobs_Aug16_3.mat

    features_jacobs_Aug16_4_ref.mat



STEP 2 — Run this script:

  python prepare_cross_session_data.py



OUTPUT — Creates in ./data/:

  dataset_train_jacobs_Aug16_1.mat     (all train samples from session 3)

  dataset_train_jacobs_Aug16_3.mat     (all train samples from session 4)

  dataset_train_jacobs_Aug16_4_ref.mat (all train samples from session 5)



These are the files that eval_cross_session.py and train_and_test.py expect.

"""
import os
import sys
import h5py
import numpy as np

# Paths
DATA_DIR = './data'
SPLIT_DIR = '../data_split_idx'
CHUNK = 300


def load_indices(split_file, key):
    """Load MATLAB 1-based index array, return 0-based numpy int array."""
    import scipy.io
    if not os.path.exists(split_file):
        raise FileNotFoundError(f'Split file not found: {split_file}')
    try:
        with h5py.File(split_file, 'r') as f:
            idx = np.array(f[key]).flatten().astype(np.int64) - 1
    except Exception:
        mat = scipy.io.loadmat(split_file)
        idx = mat[key].flatten().astype(np.int64) - 1
    return idx


def get_var_names(h5_file):
    """Handle both naming conventions."""
    keys = list(h5_file.keys())
    w_key  = 'features_w_offset'  if 'features_w_offset'  in keys else 'features_with_offset'
    wo_key = 'features_wo_offset' if 'features_wo_offset' in keys else 'features_without_offset'
    return w_key, wo_key


def extract_and_save(src_path, dst_path, indices):
    """Read samples at indices from source HDF5, write to dest in dataset_* format."""
    sorted_idx = np.sort(indices)
    n = len(sorted_idx)
    print(f'  Writing {n} samples -> {os.path.basename(dst_path)}')

    with h5py.File(src_path, 'r') as src, h5py.File(dst_path, 'w') as dst:
        w_key, wo_key = get_var_names(src)

        src_shape_w   = src[w_key].shape
        src_shape_lbl = src['labels_gaussian_2d'].shape

        out_shape_w   = src_shape_w[:-1]   + (n,)
        out_shape_lbl = src_shape_lbl[:-1] + (n,)

        # Always write with standard names (features_w_offset, etc.)
        ds_w   = dst.create_dataset('features_w_offset',  shape=out_shape_w,   dtype='float32',
                                    compression='gzip', chunks=True)
        ds_wo  = dst.create_dataset('features_wo_offset', shape=out_shape_w,   dtype='float32',
                                    compression='gzip', chunks=True)
        ds_lbl = dst.create_dataset('labels_gaussian_2d', shape=out_shape_lbl, dtype='float32',
                                    compression='gzip', chunks=True)

        written = 0
        for start in range(0, n, CHUNK):
            end = min(start + CHUNK, n)
            chunk_idx = sorted_idx[start:end].tolist()

            ds_w  [..., written:written + (end - start)] = np.array(src[w_key ][..., chunk_idx], dtype=np.float32)
            ds_wo [..., written:written + (end - start)] = np.array(src[wo_key][..., chunk_idx], dtype=np.float32)
            ds_lbl[..., written:written + (end - start)] = np.array(src['labels_gaussian_2d'][..., chunk_idx], dtype=np.float32)

            written += (end - start)
            print(f'    {written}/{n}', end='\r', flush=True)
        print()
    print(f'  Saved: {dst_path}')


def prepare_aug16_session(session_name, features_filename, split_filename):
    """Prepare one Aug16 session's data."""
    src = os.path.join(DATA_DIR, features_filename)
    split_file = os.path.join(SPLIT_DIR, split_filename)

    if not os.path.exists(src):
        print(f'  MISSING: {src}')
        print(f'  -> Download {features_filename} from WILD website')
        return False

    if not os.path.exists(split_file):
        print(f'  MISSING: {split_file}')
        return False

    print(f'\n  Processing {session_name}...')
    print(f'  Source: {src}')
    print(f'  Split:  {split_file}')

    # Combine fov_train + non_fov_train for all training samples
    # (For cross-session eval, these are used as test data)
    fov_train = load_indices(split_file, 'fov_train_idx')
    non_fov_train = load_indices(split_file, 'non_fov_train_idx')
    all_train = np.concatenate([fov_train, non_fov_train])
    print(f'  Samples: {len(fov_train)} fov_train + {len(non_fov_train)} non_fov_train = {len(all_train)} total')

    dst = os.path.join(DATA_DIR, f'dataset_train_jacobs_{session_name}.mat')
    extract_and_save(src, dst, all_train)
    return True


def main():
    os.makedirs(DATA_DIR, exist_ok=True)

    print('='*60)
    print('Preparing Aug16 cross-session data')
    print('='*60)

    sessions = [
        ('Aug16_1',     'features_jacobs_Aug16_1.mat',     'data_split_ids_jacobs_Aug16_1.mat'),
        ('Aug16_3',     'features_jacobs_Aug16_3.mat',     'data_split_ids_jacobs_Aug16_3.mat'),
        ('Aug16_4_ref', 'features_jacobs_Aug16_4_ref.mat', 'data_split_ids_jacobs_Aug16_4_ref.mat'),
    ]

    results = {}
    for session_name, feat_file, split_file in sessions:
        results[session_name] = prepare_aug16_session(session_name, feat_file, split_file)

    print('\n' + '='*60)
    print('SUMMARY')
    print('='*60)
    for name, ok in results.items():
        status = 'READY' if ok else 'MISSING (download features file from WILD)'
        print(f'  {name}: {status}')

    all_ok = all(results.values())
    if all_ok:
        print('\nAll Aug16 data prepared. Run:')
        print('  python eval_cross_session.py')
    else:
        print('\nSome files missing. Download from: https://wcsng.ucsd.edu/wild/')
        print('Place features_jacobs_Aug16_*.mat files in ./data/')


if __name__ == '__main__':
    main()