Join/Login

Business Software

Open Source Software

For Vendors

Blog

About

More

Articles

Create

SourceForge Podcast

Site Documentation

Subscribe to our Newsletter

Support Request

For Vendors Help Create Join Login

Business Software

Open Source Software

SourceForge Podcast

Resources

Articles

Case Studies

Blog

Menu

Help

Create

Join

Login

Home

Browse

Iris

Calliope

Iris Calliope

2-photon scanning software

Brought to you by: heinmatt, kellgeor

Summary

Reviews

Support

Wiki

Tickets ▾

Bugs

Tasks

Feature Requests

SVN ▾

Iris Main

Auxiliary Code

Calliope

Discussion

Menu ▾ ▴

Browse Commits

Browse Files

[r1211]: / 12_Widefield / register_widefield_exp.m  Maximize  Restore  History

Download this file

335 lines (289 with data), 18.0 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
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

function register_widefield_exp(ExpID, ExpLog, varargin)

%REGISTER_WIDEFIELD_EXP Processes and registers widefield imaging data.

%

% This function processes widefield imaging data for a given experiment

% ID, generates analysis data, and registers images to a site template.

% It handles both single and batch processing of experiment IDs.

% It supports overwriting existing data and handles both raw (.wid) and trace (.roi) data files.

%

% Parameters:

% ExpID - Single or array of experiment IDs to process.

% adata_dir - Directory where analysis data will be saved.

% ExpLog - Experiment log database containing metadata for experiments.

% varargin - Optional parameters including 'overwrite_flag'.

%

% The function supports overwriting existing data with the 'overwrite_flag'.

%

% Example usage:

% register_widefield_exp(12345, '/path/to/adata', ExpLog, 'overwrite_flag', 1); will overwrite all processes

% register_widefield_exp(12345, '/path/to/adata', ExpLog, 'overwrite_flag', [0, 0, 1]); will overwrite only registration

% Parse optional input arguments

p=inputParser;

addParameter(p, 'overwrite_flag', 0, @isnumeric) % Flag to determine whether to overwrite existing data

parse(p,varargin{:})

overwrite_flag = p.Results.overwrite_flag;

adata_dir = set_lab_paths;

% Begin processing for a single experiment ID

fprintf('\n[0] Initiating registration for stack %u\n', ExpID)

% Attempt to read experiment info and file types

[ExpIDinfo, data_dir] = read_info_from_ExpLog(ExpID,1,ExpLog);

ftypes=list_file_types(ExpID,data_dir,ExpIDinfo.userID,ExpIDinfo.mouse_id);

% Check for necessary file types before proceeding

if any(contains(ftypes, 'lvd')) && any(contains(ftypes, 'ach')) && any(contains(ftypes, 'wii')) && any(contains(ftypes, 'wid'))

% Extract relevant information from ExpInfo

[data_path,ExpIDinfo]=get_data_path(ExpID,ExpIDinfo,ExpLog);

wid_fname = fullfile(data_path,ExpIDinfo.userID,ExpIDinfo.mouse_id,['\S1-T' num2str(ExpID) '.wid']);

roi_fname = fullfile(data_path,ExpIDinfo.userID,ExpIDinfo.mouse_id,['\S1-T' num2str(ExpID) '.roi']);

adata_fname = [adata_dir ExpIDinfo.userID '\' ExpIDinfo.mouse_id '\Adata-S1-T' num2str(ExpID) '.mat'];

has_wid = isfile(wid_fname);

has_roi = isfile(roi_fname);

% Proceed if adata file doesn't exist or overwrite is enabled

if (exist(adata_fname,'file') == 0) || overwrite_flag(1)

fprintf('[1] Generating widefield adata for stack %u\n', ExpID)

% Make directory if it doesn't exist

if ~isfolder([adata_dir ExpIDinfo.userID '\' ExpIDinfo.mouse_id])

mkdir([adata_dir ExpIDinfo.userID], ExpIDinfo.mouse_id);

end

% original logic was load only roi if it has both???

if has_roi

[trace_data, trace_meta_info] = load_widefield_data_trace_NEW(roi_fname, 'load_data', 1);

end

if has_wid

[wid_data, ~, wid_meta_info] = load_widefield_data_raw_NEW(wid_fname, 'load_data', 0);

end

% Additional processing and setting adata fields based on loaded data

% Logic to populate adata fields from idata and imeta_info

% adata.img_mean = []; % - meant to contain (array, single) � average across timepoints of the full movie

% adata.img_median = []; % - meant to contain (array, single) � median across timepoints of the full movie

% adata.img_std = []; % - meant to contain (array, single) � standard deviation across timepoints of the full movie

% adata.img_max = []; % - meant to contain (array, uint16) � Max projection of the full res movie

% adata.ROIs = {}; %- (cell array of structs) � array containing multiple structs. Each structs has info and fluorescence traces for ROIs of different type (e.g., raw, trace, or grid) or channels (e.g., green, or red).

% % Each struct in ROIs is a multidimensional struct (s(n)) that contains data for each of the n ROIs.

% adata.ROI_params = struct; % - (cell array of structs) � Contains info about type and channels of ROI data in each element of the ROIs cell array.

% adata.rm = struct; % - "Response Movies" struct containing full resolution average responses across all triggers for a given event.

% adata.ROI_trans = []; %

if has_wid

adata.timestamp = [wid_meta_info.timestamp]';

else

adata.timestamp = [roi_meta_info.timestamp]';

end

% Load meta info and data based on file type (.wid or .roi)

if has_roi

adata.trace_img_mean = trace_meta_info(1).img_mean;

tmp_indices = cast(roi_meta_info(1).ROIs_coordinates, 'like', zeros(size(roi_meta_info(1).ROIs_coordinates,1), size(roi_meta_info(1).ROIs_coordinates,2), "uint32"));

tmp_names = imeta_info(1).ROIs_names;

tmp_acronyms = imeta_info(1).ROIs_acronyms;

tmp_ids = cellfun(@(x) uint32(str2double(x)), imeta_info(1).ROIs_id);

tmp_colors = imeta_info(1).ROIs_colors;

for j = 1:length(tmp_indices)

adata.ROIs{i}(j).activity = single(squeeze(idata(j, 1, :)));

[pixels_in_ROI] = find_pixels_in_ROIs(tmp_indices(j, :), imeta_info(1).ROIs_size);

% for k = 1:length(pixels_in_ROI)

adata.ROIs{i}(j).indices = uint32(pixels_in_ROI);

% end

adata.ROIs{i}(j).region_name = tmp_names{j};

adata.ROIs{i}(j).region_acronym = tmp_acronyms{j};

adata.ROIs{i}(j).region_id = tmp_ids(j);

% from here fields are not mandatory

adata.ROIs{i}(j).regions_color = tmp_colors{j};

adata.ROIs{i}(j).ind_ml = [];

adata.ROIs{i}(j).ind_ap = [];

end

adata.ROI_params(i).type = 'trace';

adata.ROI_params(i).channel = roi_meta_info(1).channel;

adata.ROI_params(i).bl_coord = uint32(roi_meta_info(1).BL_coordinates);

adata.ROI_params(i).shape = roi_meta_info(1).ROIs_shape;

adata.ROI_params(i).size = roi_meta_info(1).ROIs_size;

adata.ROI_params(i).indices_loc = roi_meta_info(1).ROIs_indices_loc;

end

if has_wid

adata.ROI_params(i).type = 'raw';

adata.ROI_params(i).channel = wid_meta_info(1).channel;

end

elseif isa(wid_fname, 'char') % case in which we have only .wid or only .roi file

if endsWith(wid_fname, '.roi')

adata.img_mean = imeta_info(1).img_mean;

tmp_indices = cast(imeta_info(1).ROIs_coordinates, 'like', zeros(size(imeta_info(1).ROIs_coordinates,1), size(imeta_info(1).ROIs_coordinates,2), "uint32"));

tmp_names = imeta_info(1).ROIs_names;

tmp_acronyms = imeta_info(1).ROIs_acronyms;

tmp_ids = cellfun(@(x) uint32(str2double(x)), imeta_info(1).ROIs_id);

tmp_colors = imeta_info(1).ROIs_colors;

for j = 1:length(tmp_indices)

adata.ROIs{1}(j).activity = single(idata(j, 1, :));

adata.ROIs{1}(j).indices = uint32(tmp_indices(j, :));

adata.ROIs{1}(j).ind_ml = [];

adata.ROIs{1}(j).ind_ap = [];

adata.ROIs{1}(j).region_name = tmp_names{j};

adata.ROIs{1}(j).region_acronym = tmp_acronyms{j};

adata.ROIs{1}(j).region_id = tmp_ids(j);

% from here fields are not mandatory

adata.ROIs{1}(j).regions_color = tmp_colors{j};

end

adata.ROI_params(1).type = 'trace';

adata.ROI_params(1).channel = imeta_info(1).channel;

adata.ROI_params(1).bl_coord = imeta_info(1).BL_coordinates;

adata.ROI_params(1).shape = imeta_info(1).ROIs_shape;

adata.ROI_params(1).size = imeta_info(1).ROIs_size;

adata.ROI_params(1).indices_loc = imeta_info(1).ROIs_indices_loc;

elseif endsWith(wid_fname, '.wid')

adata.ROIs{1}(1).activity = [];

adata.ROIs{1}(1).indices = [];

adata.ROIs{1}(1).ind_ml = [];

adata.ROIs{1}(1).ind_ap = [];

adata.ROIs{1}(1).region_name = {};

adata.ROIs{1}(1).region_acronym = {};

adata.ROIs{1}(1).region_id = [];

adata.ROIs{1}(1).region_color = {};

adata.ROI_params(1).type = 'raw';

adata.ROI_params(1).channel = '';

adata.ROI_params(1).bl_coord = [];

adata.ROI_params(1).shape = '';

adata.ROI_params(1).size = '';

adata.ROI_params(1).indices_loc = '';

else

disp(' File has wrong extension. Need to be either .wid either .roi. Aborting.')

return

end

else

disp([' Adata file for stack ' num2str(ExpID) ' already exist and thus won''t be created.'])

adata = load([adata_dir ExpIDinfo.userID '\' ExpIDinfo.mouse_id '\Adata-S1-T' num2str(ExpID) '.mat'], 'img_max', 'img_mean', 'img_std', 'img_median', 'timestamp', 'ROI_trans');

end

disp('--- Adata backbone generated.')

fprintf('[2] Computing widefield templates for stack %u\n', ExpID)

warning off

% check if data were already analyzed by trying to load the

% template mean_proj

warning off

x = rmfield(adata, 'timestamp');

was_processed = ~any(structfun(@isempty, x));

% only_trace = isempty(find_file_NEW(ExpID, userID, mouseID, 'file_extension', '.wid')) && ~isempty(find_file_NEW(stackID, userID, mouseID, 'file_extension', '.roi'));

only_trace = ~any(contains(ftypes, 'wid')) && any(contains(ftypes, 'roi'));

if (~sum([overwrite_flag(2) was_processed]) || overwrite_flag(2)) && ~only_trace

file_name_local = find_file_NEW(ExpID, ExpIDinfo.userID, ExpIDinfo.mouse_id, 'file_extension', '.wid');

ach = parse_ach([file_name_local(1:end-3) 'ach']);

% load adata to get frame_ids

disp(' Now processing associated aux_data...')

% conditions for dual and 470 LED only illumination

% result in different frame rates

if exist([file_name_local(1:end-3) 'wii'], 'file') == 2

if length(adata.img_mean)==799% checking if data was acquired on platform

[wii_config, ~] = extract_wii_file_platform(strrep(file_name_local, '.wid', '.wii'));

im_rate = wii_config.Camera_FrameRate;

else

im_rate = extract_imaging_settings([file_name_local(1:end-3) 'wii']);

end

else

im_rate = 50;

end

[~, frame_ids, ~] = align_aux_to_frame_times_NEW(adata.timestamp, im_rate, ach.auxrec.scanrate, file_name_local);

if im_rate == 50

disp(' Dual-color illumination detected')

nbr_LEDs = 2;

% frame_ids(find(diff(frame_ids)==0)) = NaN;

frame_ids((diff(frame_ids)==0)) = NaN;

gcamp_frames = find(frame_ids == 0);

% hr_frames = find(frame_ids == 1);

elseif im_rate == 100

disp(' Single 470 nm LED illumination detected.')

nbr_LEDs = 1;

% win = [-50 200];

gcamp_frames = find(frame_ids == 0);

end

% load all subset of data as the noise level is low enough

% to allow for only minor averaging

if nbr_LEDs == 1

disp(' Now loading every 100th frame of the full data.')

[data{1},~,~] = load_widefield_data_raw_NEW(file_name_local, 'load_data', 1, 'trigs', gcamp_frames(100:100:end));

if isempty(adata.img_mean)

disp(' Computing mean template...')

adata.img_mean = uint16(squeeze(mean(single(data{1}),4)));

else

disp(' Mean template already computed through trace imaging')

end

disp(' Computing median template...')

adata.img_median = uint16(squeeze(median(single(data{1}),4)));

disp(' Computing std template...')

adata.img_std = uint16(squeeze(std(single(data{1}), 0, 4)));

disp(' Computing max template...')

adata.img_max = uint16(squeeze(max(single(data{1}),[], 4)));

elseif nbr_LEDs == 2

disp(' Now loading every 100th frame of the full GCaMP data.')

[data{1},~,~] = load_widefield_data_raw_NEW(file_name_local, 'load_data', 1, 'trigs', gcamp_frames(100:100:end));

disp(' Computing mean template...')

adata.img_mean = uint16(squeeze(mean(single(data{1}),4)));

disp(' Computing median template...')

adata.img_median = uint16(squeeze(median(single(data{1}),4)));

disp(' Computing std template...')

adata.img_std = uint16(squeeze(std(single(data{1}), 0, 4)));

disp(' Computing max template...')

adata.img_max = uint16(squeeze(max(single(data{1}),[],4)));

else

disp(' Could not determine imaging mode. ABORTING.')

return

end

fprintf(['--- Done extracting templates from stack ' num2str(ExpID) '\n'])

else

if only_trace

disp("--- Can't compute std, max, nor median template since only ROI traces were acquired.")

else

disp('--- Data already analyzed and will not be overwritten.')

end

end

fprintf('[3] Registration of stack %u\n', ExpID)

if isempty(adata.ROI_trans) || overwrite_flag(3) || strcmp(adata.ROI_trans, 'failed')

tmp = load([adata_dir ExpIDinfo.userID '\' ExpIDinfo.mouse_id '\Adata-S1-T' num2str(ExpIDinfo.site_id) '.mat'], 'img_mean');

site_template = tmp.img_mean;

data = adata.img_mean;

fprintf([' Registering stack ' num2str(ExpID) ' to site_template ' num2str(ExpIDinfo.site_id) ', please wait...\n'])

[tformEstimate, peakcorr] = imregcorr(data, site_template, 'rigid');

% [optimizer,metric] = imregconfig("multimodal");

% optimizer.InitialRadius = 0.009; % InitialRadius 0.009: Sets the initial step size for the optimization algorithm. A smaller value makes the optimizer take smaller steps. This is crucial for fine-tuning the alignment, especially in the final stages of optimization.

% optimizer.Epsilon = 1.5e-4; % Epsilon 1.5e-4: This is a convergence criterion threshold. The optimizer stops when the change in the metric value is less than this threshold, indicating that further optimization will not significantly improve the metric.

% optimizer.GrowthFactor = 1.01; % GrowthFactor 1.01: Determines the rate at which the step size grows during optimization. A value greater than 1.0 means the step size increases after each iteration. A small growth factor (close to 1.0) leads to a more cautious search, which can be beneficial for fine convergence but might slow down the overall process.

% optimizer.MaximumIterations = 300; % MaximumIterations: Sets the maximum number of iterations for the optimization process. The optimizer will stop if this number of iterations is reached, even if it has not yet converged according to Epsilon.

optimizer = registration.optimizer.OnePlusOneEvolutionary();

optimizer.MaximumIterations = 300;

optimizer.InitialRadius = 0.009; % Adjust based on preliminary tests

optimizer.Epsilon = 1.5e-4; % Make convergence criteria more strict

metric = registration.metric.MattesMutualInformation();

if peakcorr>0.1

[~, tform] = imregister2(data, site_template, 'rigid', optimizer, metric, 'InitialTransformation', tformEstimate);

else

[~, tform] = imregister2(data, site_template, 'rigid', optimizer, metric);

end

Rfixed = imref2d(size(site_template));

data_reg = imwarp(data, tform, 'OutputView', Rfixed); % apply transformation to check for similarity with original template

% m = tform.T';

% tx = m(1,3);

% ty = m(2,3);

% theta = rad2deg(atan2(m(2,1), m(1,1))); % correspond to the clockwise rotation needed to align with site_template

% % To reconstruct the data registered to site template

% data_reg = imtranslate(imrotate(data, -theta, 'bilinear', 'crop'), [tx, ty]);

similarity = corr2(data_reg, site_template);

if similarity < 0.50

fprintf(' [FAILED] Similarity = %.2f, registration algorithm didn''t converge...\n', similarity)

adata.ROI_trans = 'failed';

else

fprintf(' [SUCCESS] Similarity = %.2f, registration completed.\n', similarity)

adata.ROI_trans = tform;

end

fprintf(' Now saving adata to tungsten\n')

if exist(adata_fname, 'file') && ~(all(overwrite_flag))

img_mean = adata.img_mean;

img_std = adata.img_std;

img_median = adata.img_median;

img_max = adata.img_max;

ROI_trans = adata.ROI_trans;

save(adata_fname,'img_mean', 'img_std', 'img_median', 'img_max', 'ROI_trans','-append','-v7.3');

else

save(adata_fname, '-struct','adata','-v7.3');

end

disp([' Saved Adata (' adata_fname ')'])

fprintf('--- Registration completed.\n')

else

disp(['--- Stack [' num2str(ExpID) '] already registered.'])

end

else

fprintf('\n--- Stack %u will not be registered since some files are missing. Either .lvd, .ach, .lvd and/or .wid\n', ExpID)

end

end

SourceForge

Create a Project

Open Source Software

Business Software

Top Downloaded Projects

Company

About

Team

SourceForge Headquarters
225 Broadway Suite 1600
San Diego, CA 92101
+1 (858) 422-6466

Resources

Support

Site Documentation

Site Status

SourceForge Reviews

© 2025 Slashdot Media. All Rights Reserved.

Terms Privacy Opt Out Advertise

×
Want the latest updates on software, tech news, and AI?

Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.

Submit