From cb21059fab9f363273e7dff38eca20d41a1adbf4 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 18 Sep 2026 12:38:28 +0200 Subject: [PATCH 1/2] fix(flowreg): label motion correction offsets with the right axis The displacement field of FlowRegistration holds the displacement in x in its first channel and the displacement in y in its second, which is the order imwarp takes a displacement field in. updateCorrectionStats read the channels the other way round, so offsetX and offsetY in the saved MotionCorrectionStats were swapped. The image data was never affected, because the correction applies the field itself and not these values. Co-Authored-By: Claude Opus 5 --- .../+wrapper/+flowreg/@Processor/Processor.m | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/code/wrappers/+nansen/+wrapper/+flowreg/@Processor/Processor.m b/code/wrappers/+nansen/+wrapper/+flowreg/@Processor/Processor.m index d85904b55..6434f5e52 100644 --- a/code/wrappers/+nansen/+wrapper/+flowreg/@Processor/Processor.m +++ b/code/wrappers/+nansen/+wrapper/+flowreg/@Processor/Processor.m @@ -178,9 +178,12 @@ function updateCorrectionStats(obj, IND) meanDivergence = get_mean_divergence(W); meanTranslation = get_mean_translation(W); - % Compute quantities - xOffset = squeeze(mean(mean(W(:,:,2,:), 1), 2)); %Todo: Is 2nd x-offsets? - yOffset = squeeze(mean(mean(W(:,:,1,:), 1), 2)); %Todo: Is 1st y-offsets? + % Compute quantities. The displacement field of flowreg holds + % the displacement in x in its first channel and the + % displacement in y in its second, which is the order that + % imwarp takes a displacement field in. + xOffset = squeeze(mean(mean(W(:,:,1,:), 1), 2)); + yOffset = squeeze(mean(mean(W(:,:,2,:), 1), 2)); rmsmov = sqrt(mean( W(:).^2) ); % Add results to struct @@ -375,7 +378,12 @@ function onInitialization(obj) end function shifts = addShifts(shifts, offset) - % Add rigid shifts to struct of normcorre nonrigid shifts. + % Add a rigid offset to the displacement fields of flowreg. + % + % The offset is [dx, dy], as it comes from correctDrift, and + % the field holds the displacement in x in its first channel + % and the displacement in y in its second, so the two are in + % the same order. for k = 1:numel(shifts) shifts{k}(:, :, 1, :) = shifts{k}(:, :, 1, :) + offset(1); shifts{k}(:, :, 2, :) = shifts{k}(:, :, 2, :) + offset(2); From 5b07c60422a46c2d00273497827f939f15170115 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 18 Sep 2026 12:38:28 +0200 Subject: [PATCH 2/2] fix(normcorre): add drift to the right axis of the saved shifts correctDrift returns the drift as [dx, dy], while normcorre follows the MATLAB array convention and holds the shift in y in the first plane of its shifts and the shift in x in the second. addShifts added dx to the y plane and dy to the x plane, so the drift ended up on the wrong axis of the shifts that are saved as NormcorreShifts. The image data was never affected, because correctDrift translates the frames before the drift is added to the shifts. Co-Authored-By: Claude Opus 5 --- .../+wrapper/+normcorre/@Processor/Processor.m | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/code/wrappers/+nansen/+wrapper/+normcorre/@Processor/Processor.m b/code/wrappers/+nansen/+wrapper/+normcorre/@Processor/Processor.m index d6d442042..9e3b5d288 100644 --- a/code/wrappers/+nansen/+wrapper/+normcorre/@Processor/Processor.m +++ b/code/wrappers/+nansen/+wrapper/+normcorre/@Processor/Processor.m @@ -286,12 +286,17 @@ function onCompletion(obj) methods (Static) function ncShifts = addShifts(ncShifts, offset) - % Add rigid shifts to struct of normcorre nonrigid shifts. + % Add a rigid offset to a struct of normcorre shifts. + % + % The offset is [dx, dy], as it comes from correctDrift, while + % normcorre follows the MATLAB array convention and holds the + % shift in y in the first plane of its shifts and the shift in + % x in the second, so the two are in opposite order. for k = 1:numel(ncShifts) - ncShifts(k).shifts(:,:,:,1) = ncShifts(k).shifts(:,:,:,1) + offset(1); - ncShifts(k).shifts(:,:,:,2) = ncShifts(k).shifts(:,:,:,2) + offset(2); - ncShifts(k).shifts_up(:,:,:,1) = ncShifts(k).shifts_up(:,:,:,1) + offset(1); - ncShifts(k).shifts_up(:,:,:,2) = ncShifts(k).shifts_up(:,:,:,2) + offset(2); + ncShifts(k).shifts(:,:,:,1) = ncShifts(k).shifts(:,:,:,1) + offset(2); + ncShifts(k).shifts(:,:,:,2) = ncShifts(k).shifts(:,:,:,2) + offset(1); + ncShifts(k).shifts_up(:,:,:,1) = ncShifts(k).shifts_up(:,:,:,1) + offset(2); + ncShifts(k).shifts_up(:,:,:,2) = ncShifts(k).shifts_up(:,:,:,2) + offset(1); end end end