Skip to content

Commit

Permalink
New motion correction methods, QoL updates, etc.
Browse files Browse the repository at this point in the history
## Main features and changes:
- Increment to CIAtah version `4.11.0`.
- Addition of additional spinal cord motion correction functions and demos. These allow for correction of large motion (LD-MCM), non-rigid motion (displacement fields), and cross-session registration (CS-MCM). See below for details of function or https://bahanonu.github.io/ciatah/pipeline_detailed_spinal.
- Improved DeepLabCut importer function to also allow output of tensors with all tracking data.
- QoL improvements for a number of CIAtah functions and class methods.
- Updated `README` to include additional information on spinal cord imaging, Fiji + N5 viewing of files, and other changes.

## New functions
- `ciapkg.demo.cross_session_motion_correction` - Script to allow multi-step cross-session registration directly on movies. Includes automated registration as well as the ability to perform manual correction to help with large or unusual shifts using a GUI.
- `ciapkg.demo.displacementFields` - Displacement field motion correction example across several images. This is to help validate that motion correction will work on user systems.
- `ciapkg.demo.ldmcm` -
- `ciapkg.motion_correction.ldmcm` - LD-MCM motion correction using deep learning and control point registration. This demo script includes the necessary steps that need to be run after conducting DeepLabCut-based tracking of features in the imaging movie.
- `ciapkg.video.scaleMatrix8bit` - Scales an input matrix to 8-bit (256) range. Can also save video out to an AVI file.
- `ciapkg.view.displacementFieldCompare` -Displays different frames along with the displacement fields.

## Updated `@ciatah`
- `ciatah.computeManualSortSignals` - Update display of information.
- `ciatah.computeMatchObjBtwnTrials` - Added the option to only keep cells within a specific region of the FOV, useful for when want to register cells in a single region and don't want other cells affecting alignment. Add support for normcorre and imregdemons for registration.
- `ciatah.getRegistrationSettings` - Add support for gradient-based filtering for motion correction input. Add displacement field-based motion correction. (Updated 2024.02.29 [18:17:06])
- `ciatah.modelBatchCopyFiles` - Easier user switching between copying or moving files.
- `ciatah.modelExtractSignalsFromMovie` - Allow input of images from one cell extraction method to CELLMax and EXTRACT, e.g. run PCA-ICA quickly then use as input. Update ROI method of calling other algorithm images.
- `ciatah.modelGetSignalsImage` - Added support for registering images (e.g. after cross-day registration) using multiple methods instead of just turboreg.
- `ciatah.modelPreprocessMovieFunction` - Updated NormCorre parameter window to estimate window size from the first frame. Make correlation calculation parallel. Allow detrend movie to use movie subsets to reduce memory overhead. Reduce double calling of mean() for calculation and plotting when conducting detrending. Further eliminate nanmean/nanmin/nanmax usage, use dims instead of (:) [waste memory], and general refactoring. Fix thisMovieMinMask(row,:) = logical(max(isnan(squeeze(thisMovie(row,:,:))),[],2,'omitnan')); as was 3 instead of row. Add support for input of prior motion correction coordinates to be user facing. Empty imagesc() call leading to face appearing. For the curious, see https://blogs.mathworks.com/steve/2006/10/17/the-story-behind-the-matlab-default-image/.
- `ciatah.modelVarsFromFiles` - CELLMax by default uses the estimated dF/F.
- `ciatah.modelVerifyDataIntegrity` -  Updated movieInformation to have additional movie information.
- `ciatah.runPipeline` - Use guiFoldersSelected to remember prior user selected folders on next call of CIAtah GUI.
- `ciatah.viewMatchObjBtwnSessions` - Additional options for choosing which cells to display and additional cellmaps saved out as TIFF files.
- `ciatah.viewMovie` - Fix readHDF5Subset function unable to be found in certain cases.
- `ciatah.viewObjmaps` - Update display of cell overlap.
- `` -

## Updated `+ciapkg`
- `ciapkg.behavior.importDeepLabCutData` -  Added conversion to tensor and cell to the import function from other functions.
- `ciapkg.classification.matchObjBtwnTrials` - Made ability to switch between different motion correction and image alignment methods user visible.
- `ciapkg.download.downloadGithubRepositories` - Automatically convert string inputs to character arrays.
- `ciapkg.download.example_downloadTestData` - Added additional link.
- `ciapkg.hdf5.appendDataToHdf5.m` - Flag to silence command line output.
- `ciapkg.hdf5.downsampleHdf5Movie` - Integrated TIFF support from other functions. options.newFilenameTwo is sufficient to initiate secondary movie downsampling. Option to convert data type during downsampling.
- `ciapkg.image.cropMatrix` - Update to callback. Added support for automatic detection of crop borders from main pre-processing functions. Remove workspace unpacking of options.
- `ciapkg.image.thresholdImages` - fastThresholding respects normalization=0, so threshold functions as absolute value. Also make sure remove unconnected works with fastThresholding at all times.
- `ciapkg.io.getMovieFileType` - Added mp4 support to output.
- `ciapkg.io.loadDependencies` - Update Bio-Formats to 7.3.0.
- `ciapkg.motion_correction.computeManualMotionCorrection` - Better support for adding custom fill values for both translation and rotation.
- `ciapkg.motion_correction.getNoRMCorreParams` - Change default parameters and run final output through NoRMCorre parameter function to reduce chance of errors.
- `ciapkg.motion_correction.turboregMovie` - Changes to GUI display. Correct user options input to normcorre.apply_shifts. Add displacement field-based motion correction. Add back in ability to remove NaNs from each frame before calculating shifts or displacements. Add support for gradient-based filtering for motion correction input. Support loading of prior coordinates from MAT-file in standard of modelPreprocessMovieFunction. Added additional options for displacement field-based motion correction. Update to row assignment for removeInputMovieEdges.
- `ciapkg.movie_processing.detrendMovie` - Fix detrendDegree passing.
- `ciapkg.movie_processing.dfofMovie` - Updated to allow users to adjust movies with negative values.
- `ciapkg.movie_processing.normalizeMovie` - matlabdisk no longer converts to cell array, bad memory usage. Improve other memory usage in function. Change how NaN check before filtering is run. Remove on a per-frame basis so that the NaNs can be added back in at the correct pixel locations. Further eliminate nanmean/nanmin/nanmax usage, use dims instead of (:) [waste memory], and general refactoring. Added movie subset support to reduce memory usage with parfor. Fix detrendDegree passing. Added subfxnFft movie subset support to reduce memory usage with parfor.
- `ciapkg.overloaded.suptitle` - Added font name option.
- `ciapkg.settings.cnmfeSettings` - Updated merge settings to reduce duplicates in output.
- `ciapkg.view.playMovie` - Users can now input a cell array of movies to have the extra movie play instead of the 'extraMovie' option. Added support for additional NWB series.

## Updated `docs`
- `help_spatial_filtering`
- `pipeline_detailed_signal_extraction_validation`
- `pipeline_detailed_signal_sorting_manual`
  • Loading branch information
bahanonu committed Jul 23, 2024
1 parent 4ce5a7a commit 91db13f
Show file tree
Hide file tree
Showing 50 changed files with 2,668 additions and 352 deletions.
58 changes: 45 additions & 13 deletions +ciapkg/+behavior/importDeepLabCutData.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function [mainTbl] = importDeepLabCutData(inputPath,varargin)
function [mainTbl, mainTensor, mainCell] = importDeepLabCutData(inputPath,varargin)
% [outputTable] = importDeepLabCutData(inputPath,varargin)
%
% Loads DeepLabCut processed CSV files and loads into a table or structure for use by other functions.
Expand All @@ -10,14 +10,17 @@
% inputPath - Str: path to DLC file.
%
% Outputs
% mainTbl - Struct with fields named after body parts. Each field is [likelihood x y] matrix with rows equal to frames of the movie.
% mainTbl - Struct: with fields named after body parts. Each field is [likelihood x y] matrix with rows equal to frames of the movie.
% mainTensor - Tensor: format [nFeatures nDlcOutputs nFrames].
% mainCell - Cell: format {1 nFeatures} with each cell containing a [likelihood x y] matrix with rows equal to frames of the movie.
%
% Options (input as Name-Value with Name = options.(Name))
% % DESCRIPTION
% options.exampleOption = '';

% Changelog
% 2022.03.14 [01:47:04] - Added nested and local functions to the example function.
% 2024.02.19 [09:25:58] - Added conversion to tensor and cell to the import function from other functions.
% TODO
%

Expand Down Expand Up @@ -47,26 +50,37 @@
% dlcTablePath = fullfile(rootAnalysisPath,dlcFileCSV{vidNo});
t1 = readtable(inputPath);
t2 = readlines(inputPath);
bodyPartListMain = strsplit(t2{2},',');
bodyPartList = unique(bodyPartListMain);
nBodyParts = length(bodyPartList)-1;
featuresListMain = strsplit(t2{2},',');
featuresList = unique(featuresListMain);
nfeaturess = length(featuresList)-1;

if options.dispPlots==1
figure;
set(gcf,'Color','k')
end

for partX = 1:nBodyParts
partName = bodyPartListMain{(partX-1)*3+4};
if partX==nBodyParts
mainCell = {};
nFrames = length(t1{:,(1-1)*3+2});
mainTensor = NaN([nfeaturess 3 nFrames]);

for partX = 1:nfeaturess
partName = featuresListMain{(partX-1)*3+4};
if partX==nfeaturess
fprintf('%s.\n',partName)
else
fprintf('%s | ',partName)
end
conf1 = t1{:,(partX-1)*3+4};
dlcX = t1{:,(partX-1)*3+2};
dlcY = t1{:,(partX-1)*3+3};
mainTbl.(partName) = [conf1(:) dlcX(:) dlcY(:)];

mainMatrix = [conf1(:) dlcX(:) dlcY(:)];

mainTbl.(partName) = mainMatrix;

mainCell{partX} = mainMatrix;

mainTensor(partX,:,:) = mainMatrix';

if options.dispPlots==1
subplot(3,3,partX)
Expand All @@ -92,7 +106,25 @@
% outputs = ;
end
end
function [outputs] = localfxn_exampleFxn(arg)
% Always start local functions with "localfxn_" prefix.
% outputs = ;
end
% function [outputs] = localfxn_exampleFxn(arg)
% opts.nFrames = size(inputMovie,3);
% featurePts = cell([1 opts.nFrames]);
% opts.nFields = fieldnames(dlcData);
% featurePtsTensor = NaN([length(opts.nFields) 3 opts.nFrames]);

% for i = 1:opts.nFrames
% conf1 = [];
% dlcX = [];
% dlcY = [];
% for partX = 1:length(opts.nFields)
% thisField = opts.nFields{partX};
% dlcDataNew.(thisField) = vertcat(dlcData.(thisField));
% conf1(partX) = dlcDataNew.(thisField)(i,1);
% dlcX(partX) = dlcDataNew.(thisField)(i,2);
% dlcY(partX) = dlcDataNew.(thisField)(i,3);
% end
% featurePts{i} = [conf1(:) dlcX(:) dlcY(:)];
% featurePtsTensor(:,:,i) = featurePts{i};
% end
% disp('Done!')
% end
21 changes: 18 additions & 3 deletions +ciapkg/+classification/matchObjBtwnTrials.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
% 2019.10.29 [13:07:18] - Added support for sparse (ndSparse) array inputs.
% 2019.12.05 [10:37:17] - Fix for cases in which cells are lost when cropping all movies to the same size before starting cross-session alignment.
% 2021.08.08 [19:30:20] - Updated to handle CIAtah v4.0 switch to all functions inside ciapkg package.
% 2023.05.09 [12:33:23] - Made ability to switch between different motion correction and image alignment methods user visible.
% notes
% the cell array of traces allows us to have arbitrary numbers of trials to align automatically,
% TODO
Expand Down Expand Up @@ -70,6 +71,14 @@
options.turboregZeroThres = 1e-6;
% Binary: 1 = check correlation matches visually
options.checkImageCorr = 0;
% Str: Register images using 'imtransform' or 'imwarp' (Matlab) or 'transfturboreg' (C)
options.registrationFxn = 'transfturboreg';
% Str: motion correction algorithm.
% 'turboreg' - TurboReg as developed by Philippe Thevenaz.
% 'normcorre' - NoRMCorre as developed by several authors at Flatiron Institute.
% 'imregdemons' - Displacement field alignment based on imregdemons.
options.mcMethod = 'turboreg';

options = getOptions(options,varargin);
%========================
% obtain trial stats
Expand Down Expand Up @@ -124,6 +133,10 @@
% =======
RegisTypeFinal = options.RegisTypeFinal;
% turboreg options.
ioptions.mcMethod = options.mcMethod;
% ioptions.registrationFxn = 'imtransform';
ioptions.registrationFxn = options.registrationFxn;

ioptions.meanSubtract = 0;
ioptions.complementMatrix = 0;
ioptions.normalizeType = [];
Expand All @@ -141,8 +154,6 @@
ioptions.cropCoords = [];
ioptions.closeMatlabPool = 0;
ioptions.removeEdges = 0;
% ioptions.registrationFxn = 'imtransform';
ioptions.registrationFxn = 'transfturboreg';
% =======
% turboreg all object maps to particular trial's map
if issparse(objectMap{options.trialToAlign})
Expand Down Expand Up @@ -211,10 +222,13 @@
ioptions.closeMatlabPool = 0;
ioptions.meanSubtract = 0;
ioptions.normalizeType = 'divideByLowpass';
ioptions.registrationFxn = 'transfturboreg';
% ioptions.registrationFxn = 'transfturboreg';
ioptions.removeEdges = 0;
ioptions.cropCoords = [];

ioptions.mcMethod = options.mcMethod;
ioptions.registrationFxn = options.registrationFxn;

for switchNo = 1:length(switchStrArray)
switch switchStrArray{switchNo}
case 'optional'
Expand Down Expand Up @@ -352,6 +366,7 @@
OutStruct.registrationCoords = registrationCoords;
OutStruct.coords = coords;
OutStruct.inputImages = inputImages;
% OutStruct.inputOptions = options;
if ~isempty(options.inputSignals)
OutStruct.inputSignals = options.inputSignals;
end
Expand Down
Loading

0 comments on commit 91db13f

Please sign in to comment.