-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun_position_processing_batch.m
More file actions
126 lines (113 loc) · 5.41 KB
/
Copy pathrun_position_processing_batch.m
File metadata and controls
126 lines (113 loc) · 5.41 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
%% Batch Position Processing -- WHOLE SESSION
% Processes EVERY C3D trial in one session (one batID + one date) in a single
% run, instead of picking one trial interactively like run_position_processing.m.
%
% What it does ONCE per session:
% (1) mic positions -- mic_landmarks + extract_mic_location (per date)
% (2) maze structure -- extract_maze_structure
% (3) session perch templates -- resolve_session_perches (cached per session)
% then LOOPS over every *.c3d in the session's Vicon_data folder:
% (4) extract_bat_pos -> (5) save_bat_pos -> (6) plot_bat_trajectory
%
% Each trial is wrapped in try/catch, so one bad trial does not stop the session;
% an OK / FAILED / skipped summary prints at the end. Outputs are identical to
% run_position_processing.m (one <batID>_<date>_<NN>_bat_pos.mat per trial in
% Bat_Position\, PNGs in plot\) -- this is just the whole-session sibling with no
% per-trial uigetfile.
%
% NOTE: the FIRST time a date has no mic-landmark CSV yet, mic_landmarks() opens
% a one-time folder picker up front (step 1). Answer it once; the trial loop then
% runs unattended. If the CSV already exists, step 1 loads silently.
%
% Written 2026-07-18 as the batch sibling of run_position_processing.m.
%% Clear everything
clear; clc; close all;
%% ============================ CONFIG (EDIT ME) ============================
date_data = '20260709'; % session date (YYYYMMDD)
batID = 'batA125'; % subject
Mic_marker_distance = 35;
% Mic numbers that are physically floating/movable units (see run_position_processing.m).
floating_mic_ids = [5 8 10 11 13 16];
% Root paths (same as run_position_processing.m)
base_data_folder = 'Z:\Rie\Data\Raw_Data';
base_analysis_folder = 'Z:\Rie\Analysis\Position_processing';
maze_json_file = fullfile(base_analysis_folder, 'y-maze_layout.json');
% Batch behaviour
make_plots = true; % save per-trial trajectory PNGs (figures closed after saving)
overwrite_existing = true; % false -> skip trials whose bat_pos .mat already exists
%% =========================================================================
%% (1) Mic positions -- ONCE for the whole session
mic_fullpath = mic_landmarks(date_data, base_analysis_folder, floating_mic_ids);
savepath_mic_pos = extract_mic_location(date_data, mic_fullpath, Mic_marker_distance);
mic_data = load(savepath_mic_pos);
fprintf('Mic data loaded: %d mics\n', size(mic_data.mic_pos, 1));
%% (2) Maze structure -- ONCE
if isfile(maze_json_file)
maze_structure = extract_maze_structure(maze_json_file);
else
warning('Maze JSON file not found: %s', maze_json_file);
[maze_filename, maze_filepath] = uigetfile('*.json', 'Select maze layout JSON file', base_analysis_folder);
if isequal(maze_filename, 0)
warning('No maze file selected. Continuing without maze.');
maze_structure = [];
maze_json_file = '';
else
maze_json_file = fullfile(maze_filepath, maze_filename);
maze_structure = extract_maze_structure(maze_json_file);
end
end
%% (3) Session perch templates -- ONCE (cached per session)
bat_data_folder = fullfile(base_data_folder, batID, date_data, 'Vicon_data');
if ~exist(bat_data_folder, 'dir')
error('Session Vicon_data folder not found: %s', bat_data_folder);
end
session_perch_cache = fullfile(base_analysis_folder, 'session_perch', ...
sprintf('%s_%s_perch.mat', batID, date_data));
session_perch = resolve_session_perches(bat_data_folder, session_perch_cache);
%% (4-6) LOOP over every C3D trial in the session
c3d_files = dir(fullfile(bat_data_folder, '*.c3d'));
if isempty(c3d_files)
error('No .c3d files found in %s', bat_data_folder);
end
fprintf('\n==== Batch: %s %s -- %d C3D trial(s) ====\n', batID, date_data, numel(c3d_files));
n_ok = 0; n_fail = 0; n_skip = 0;
failed = {};
for k = 1:numel(c3d_files)
bat_fullpath = fullfile(c3d_files(k).folder, c3d_files(k).name);
fprintf('\n---- [%d/%d] %s ----\n', k, numel(c3d_files), c3d_files(k).name);
% Optional skip when the trial's bat_pos file already exists. Strip the .c3d
% extension FIRST (else the '3' in "c3d" is parsed) then take the LAST number
% -- exactly how save_bat_pos names the output.
if ~overwrite_existing
[~, c3d_stem] = fileparts(c3d_files(k).name);
tok = regexp(c3d_stem, '(\d+)', 'tokens');
if ~isempty(tok)
trial_num = tok{end}{1};
outfile = fullfile(base_analysis_folder, 'Bat_Position', ...
sprintf('%s_%s_%s_bat_pos.mat', batID, date_data, trial_num));
if isfile(outfile)
fprintf(' already processed (%s) -- skipping\n', outfile);
n_skip = n_skip + 1;
continue;
end
end
end
try
bat_trajectory = extract_bat_pos(bat_fullpath, maze_json_file, session_perch);
save_bat_pos(bat_trajectory, batID, date_data);
if make_plots
plot_bat_trajectory(bat_trajectory, mic_data, batID, date_data);
close all; % keep figures from piling up across a whole session
end
n_ok = n_ok + 1;
catch ME
fprintf(2, ' TRIAL FAILED (%s): %s\n', c3d_files(k).name, ME.message);
failed{end+1} = c3d_files(k).name; %#ok<SAGROW>
n_fail = n_fail + 1;
end
end
fprintf('\n==== Batch done: %d OK, %d failed, %d skipped ====\n', n_ok, n_fail, n_skip);
if ~isempty(failed)
fprintf('Failed trials:\n');
fprintf(' %s\n', failed{:});
end