Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dependencies/extraction/processAllTrials_Async.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ function plotE(E, Y,B,selPix) %debugging helper only
E.F0 = F0;
E.SNR = SNR;
catch ME
fprintf(2, 'processResult ERROR: %s\n', ME.message);
B = [];
end
end
Expand Down
10 changes: 8 additions & 2 deletions dependencies/io/saveStructToH5.m
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,14 @@ function writeValue(filename, path, val)
if isempty(val)
return;
end
h5create(filename, path, size(val), 'Datatype', class(val));
h5write(filename, path, val);
dtype = class(val);
val = gather(val); % collect gpuArray / codistributed
sz = size(val);
% Round-trip through cast to materialize a plain array of the declared
% class without applying per-element arithmetic.
plainVal = cast(val, dtype);
h5create(filename, path, sz, 'Datatype', dtype);
h5write(filename, path, plainVal);
return;
end

Expand Down
69 changes: 63 additions & 6 deletions source_extraction/SILo.m
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@
selPix = selPix & repmat(pxAlwaysValid, 1, 1, k); %ADJUST SELECTED PIXELS NOT TO INCLUDE POORLY MEASURED PIXELS

%prune any sources that got clipped by pixel selection process
keepSources = sum(selPix, [1 2])>5;
centerValid = pxAlwaysValid(sub2ind(size(pxAlwaysValid), sources.R, sources.C));
keepSources = squeeze(sum(selPix, [1 2]))>5 & centerValid(:);
if k > 0
sources.R = sources.R(keepSources);
sources.C = sources.C(keepSources);
Expand Down Expand Up @@ -362,20 +363,76 @@
clear meanAligned meanIM actAligned F0selDS E
end

% Shut down the parallel pool explicitly here so all thread-pool arrays are
% fully materialised into regular MATLAB memory before the HDF5 saves.
% The pause gives the pool time to fully release shared memory before h5write.
delete(gcp('nocreate'));
pause(5);
Comment thread
j-friedrich marked this conversation as resolved.

params.endTime = char(datetime('now','TimeZone','local','Format','yyyy-MM-dd''T''HH:mm:ss.SSSZZZZZ'));

trialTable.source_extraction.analysis_params = params;
saveStructToH5(trialTable, [dr filesep trialTablefn]);


%prepare file for saving
exptSummary.params = params;
exptSummary.trialTable = trialTable;
exptSummary.dr = dr;

%save
saveExperimentSummaryH5(fullfile(savedr, 'experiment_summary.h5'), exptSummary, trialTable);
savePerTrialSummaryH5(fullfile(savedr, 'per_trial_summary.h5'), exptSummary, trialTable);
%save (with retry so a transient HDF5 error does not discard all results)
trySave(@() saveStructToH5(trialTable, [dr filesep trialTablefn]), 'trial_table');
trySave(@() saveExperimentSummaryH5(fullfile(savedr, 'experiment_summary.h5'), exptSummary, trialTable), 'experiment_summary');
trySave(@() savePerTrialSummaryH5( fullfile(savedr, 'per_trial_summary.h5'), exptSummary, trialTable), 'per_trial_summary');

%verify the saved file is readable and non-empty
expSumFn = fullfile(savedr, 'experiment_summary.h5');
d = dir(expSumFn);
if isempty(d) || d.bytes == 0
fprintf(2, 'WARNING: experiment_summary.h5 is missing or empty after save.\n');
else
fprintf('experiment_summary.h5 written (%d MB)\n', round(d.bytes/1e6));
% if sources were found, spot-check that each trace dataset is readable
for DMDix = 1:numel(exptSummary.sources)
if isempty(exptSummary.sources{DMDix}) || ~isfield(exptSummary.sources{DMDix}, 'R') ...
|| isempty(exptSummary.sources{DMDix}.R)
continue
end
datasetPath = sprintf('/Path%d/sources/temporal/dF_denoised', DMDix);
try
info = h5info(expSumFn, datasetPath);
fprintf(' %s shape: %s\n', datasetPath, mat2str(info.Dataspace.Size));
catch
fprintf(' %s not found.\n', datasetPath);
end
end
end
Comment thread
j-friedrich marked this conversation as resolved.


disp('Done summarize_LoCo')
end

function trySave(saveFcn, label, maxAttempts)
%TRYSAVE Call saveFcn up to maxAttempts times, pausing between failures.
% Note: retries only help with transient I/O errors. Failures caused by
% stale thread-pool state in the current process will not recover across
% retries.
if nargin < 3 || isempty(maxAttempts)
maxAttempts = 3;
end
for attempt = 1:maxAttempts
try
saveFcn();
return;
catch ME
fprintf(2, 'WARNING: Attempt %d/%d to save "%s" failed: %s\n', ...
attempt, maxAttempts, label, ME.message);
if attempt < maxAttempts
% Long pause to allow the thread pool to fully release shared
% memory asynchronously — the taint clears once shutdown completes.
fprintf(2, 'Waiting 30s before retry...\n');
pause(30);
else
rethrow(ME);
end
end
end
end