-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added functions move_betas_to_secondlvl()
- Loading branch information
1 parent
ab264f9
commit 07248c8
Showing
2 changed files
with
219 additions
and
0 deletions.
There are no files selected for viewing
145 changes: 145 additions & 0 deletions
145
Second_level_analysis_template_scripts/move_betas_to_secondlvl.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
function move_betas_to_secondlvl(firstlvl_dir, datadir, operation, varargin) | ||
% MOVE_BETAS_TO_SECONDLVL Move beta images to a second-level analysis directory. | ||
% | ||
% This function moves or creates symbolic links to beta images from a first-level | ||
% analysis directory to a second-level analysis directory. It is designed to be | ||
% used with BIDS-formatted datasets and supports operations to either copy the | ||
% beta images or create symbolic links. | ||
% | ||
% Inputs: | ||
% firstlvl_dir - String. Path to the first-level analysis directory. | ||
% datadir - String. Path to the destination directory for the second-level analysis. | ||
% operation - String. Specify 'copy' to copy the files, or 'symlink' to create symbolic links. | ||
% varargin - (Optional) Cell array. Specific conditions to process, | ||
% passed in as a cell-array of char-strings e.g., {'hot', 'warm', 'imagine'}. | ||
% | ||
% Outputs: | ||
% None. This function operates by side effects (file operations). | ||
% | ||
% Example usage: | ||
% move_betas_to_secondlvl('/CANlab/labdata/data/WASABI/derivatives/canlab_firstlvl/sub-SID00XXXX/ses-0X/func/firstlvl/bodymap', ... | ||
% '/CANlab/labdata/projects/WASABI/WASABI_N_of_Few/analysis/WASABI-NofFew_BodyMap/data', 'symlink'); | ||
% | ||
% Notes: | ||
% - This function is intended to be used as part of a SLURM job script. | ||
% - Requires appropriate permissions to read from the source and write to the destination directories. | ||
% - Symbolic link creation is platform dependent and may require administrative privileges. | ||
% | ||
% Author: Michael Sun, Ph.D. | ||
% Created: 12/1/2023 | ||
% Last Modified: 12/1/2023 | ||
|
||
% Extract sub, ses, and task using fileparts | ||
[path, task, ~] = fileparts(firstlvl_dir); | ||
|
||
% Extract sub, ses, and task from name_parts | ||
% sub = char(strcat('sub-', extractBetween(path, 'sub-', [filesep, 'ses']))); % Assuming sub-SID* | ||
% ses = char(strcat('ses-', extractBetween(path, 'ses-', [filesep, 'func']))); % Assuming ses-* | ||
|
||
% Creating a pattern that matches either '/' or '\' | ||
slashPattern = '[/\\]'; | ||
|
||
% Extracting the subject ID | ||
subPattern = strcat('sub-', '.*?(?=', slashPattern, 'ses)'); | ||
subMatch = regexp(path, subPattern, 'match'); | ||
if ~isempty(subMatch) | ||
sub = subMatch{1}; | ||
else | ||
sub = ''; | ||
end | ||
|
||
% Extracting the session ID | ||
sesPattern = strcat('ses-', '.*?(?=', slashPattern, 'func)'); | ||
sesMatch = regexp(path, sesPattern, 'match'); | ||
if ~isempty(sesMatch) | ||
ses = sesMatch{1}; | ||
else | ||
ses = ''; | ||
end | ||
|
||
% Extracting task | ||
task=['task-', task]; | ||
|
||
load(fullfile(firstlvl_dir, sub, 'SPM.mat')); | ||
if ~exist('varargin', 'var') | ||
conditions=varargin; | ||
end | ||
|
||
if ~exist('conditions', 'var') | ||
conditions={}; | ||
end | ||
|
||
if isempty(conditions) | ||
% If no conditions are passed in, generate a list of conditions | ||
% from SPM.xX.name that don't include constants or noise (R) | ||
% regressors. | ||
|
||
% Regular expression pattern | ||
% Pattern for 'R' followed by one or more digits, or 'constant' | ||
pattern = '(R\d+|constant)$'; | ||
|
||
% Finding indices of cells that do not match the pattern | ||
idx = cellfun(@isempty, regexp(SPM.xX.name, pattern)); | ||
|
||
% The cells that do not contain 'R' followed by numbers or 'constant' | ||
conditions = SPM.xX.name(idx); | ||
|
||
% Remove 'Sn(*) ' prefix | ||
pattern = 'Sn\(\d+\) '; | ||
% Stripping the pattern from each string in result using | ||
% regex-replace | ||
conditions = regexprep(conditions, pattern, ''); | ||
% Remove '* *bf(*)' suffix | ||
pattern = ' \*bf\(\d+\)'; | ||
conditions = regexprep(conditions, pattern, ''); | ||
|
||
% Extract only the unique conditions | ||
conditions=unique(conditions); | ||
end | ||
|
||
for k = 1:numel(conditions) | ||
% Search for the beta number that corresponds to the condition in | ||
% question. | ||
betanum=find(contains(SPM.xX.name, conditions{k})); | ||
if ~isempty(betanum) | ||
% | ||
for i = 1:numel(betanum) | ||
betafile=fullfile(firstlvl_dir, sub, ['beta_', sprintf('%04d',betanum(i)),'.nii']); | ||
if ~isempty(sub) | ||
bidsname=[sub,'_']; | ||
end | ||
if ~isempty(ses) | ||
bidsname=[bidsname, ses,'_']; | ||
end | ||
run=['run-',char(extractBetween(SPM.xX.name(betanum(i)), 'Sn(', ')'))]; | ||
bidsname=sprintf('%s%s_%s.nii', bidsname, task, run); | ||
|
||
destination_folder=fullfile(datadir,sub,conditions{k}); | ||
|
||
% Check if the destination folder exists, and create it if it does not | ||
if ~exist(destination_folder, 'dir') | ||
mkdir(destination_folder); | ||
end | ||
|
||
if strcmp(operation, 'copy') | ||
copyfile(betafile, destination_folder); | ||
new_betafile=fullfile(datadir,sub,conditions{k}, ['beta_', sprintf('%04d',betanum(i)),'.nii']); | ||
renamed_betafile=fullfile(datadir,sub,conditions{k}, bidsname); | ||
movefile(new_betafile, renamed_betafile); | ||
elseif strcmp(operation, 'symlink') | ||
% Create symlink using system command | ||
% Rename the file into BIDS-format | ||
dest_link_path = fullfile(destination_folder, bidsname); | ||
if ispc % Check if the system is Windows | ||
cmd = ['cmd.exe /C mklink "' dest_link_path '" "' betafile '"']; | ||
else | ||
cmd = sprintf('ln -s %s %s', betafile, dest_link_path); | ||
end | ||
system(cmd); | ||
else | ||
error('Invalid operation. Choose either "copy" or "symlink".') | ||
end | ||
end | ||
end | ||
end | ||
end |
74 changes: 74 additions & 0 deletions
74
Second_level_analysis_template_scripts/move_betas_to_secondlvl.sbatch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#!/bin/bash | ||
#SBATCH --job-name=movebetas_bodymap # Job name | ||
#SBATCH --output=log/movebetas/movebetas_bodymap_%a.out # Output file name, %a is replaced by the array index | ||
#SBATCH --error=log/movebetas/movebetas_bodymap_%a.err # Error output file name | ||
#SBATCH --ntasks=1 # Number of MPI ranks | ||
#SBATCH --cpus-per-task=1 # Number of cores per task | ||
#SBATCH --time=24:00:00 # Wall time | ||
#SBATCH --partition=normal # Partition name | ||
#SBATCH --array=0-108 # Array indices, replace with the number of first-level directories you have -1 | ||
#SBATCH --account=DBIC | ||
#SBATCH --partition=standard | ||
# Email notifications (comma-separated options: BEGIN,END,FAIL) | ||
#SBATCH --mail-type=FAIL | ||
#SBATCH --mail-type=END | ||
|
||
# Output and error log directories | ||
output_log_dir="log/movebetas" | ||
error_log_dir="log/movebetas" | ||
|
||
# Create the directories if they don't exist | ||
mkdir -p "$output_log_dir" | ||
mkdir -p "$error_log_dir" | ||
|
||
hostname | ||
|
||
# Enable extended globbing | ||
shopt -s extglob | ||
|
||
# FOR DEBUGGING | ||
# SLURM_ARRAY_TASK_ID=0 | ||
|
||
# Set the directory paths | ||
firstlvl_dir="/dartfs-hpc/rc/lab/C/CANlab/labdata/data/WASABI/derivatives/canlab_firstlvl" | ||
# Second-level batch analysis directory | ||
data_dir="/dartfs-hpc/rc/lab/C/CANlab/labdata/projects/WASABI/WASABI_N_of_Few/analysis/WASABI-NofFew_BodyMap/data" | ||
|
||
# Set your conditions | ||
# Define the conditions array in Bash | ||
# conditions=("hot_leftface" "warm_leftface" "imagine_leftface" | ||
# "hot_rightface" "warm_rightface" "imagine_rightface" | ||
# "hot_leftarm" "warm_leftarm" "imagine_leftarm" | ||
# "hot_rightarm" "warm_rightarm" "imagine_rightarm" | ||
# "hot_leftleg" "warm_leftleg" "imagine_leftleg" | ||
# "hot_rightleg" "warm_rightleg" "imagine_rightleg" | ||
# "hot_chest" "warm_chest" "imagine_chest" | ||
# "hot_abdomen" "warm_abdomen" "imagine_abdomen") | ||
|
||
# Initialize an empty array to store the quoted strings | ||
# quoted_conditions=() | ||
# for condition in "${conditions[@]}"; do | ||
# quoted_conditions+=("'$condition'") | ||
# done | ||
|
||
# Convert the quoted_conditions array into a comma-separated string | ||
# conditions_str=$(IFS=,; echo "{${quoted_conditions[*]}}") | ||
|
||
# If you ran many first-level GLMs, e.g., by subject or by session, you may have to do this: | ||
# Find all the directories matching the pattern 'firstlvl/bodymapST+([1-2])' | ||
# map_dirs=("$firstlvl_dir"/sub-*/ses-*/func/firstlvl/bodymapST+([1-2])) | ||
map_dirs=("$firstlvl_dir"/sub-*/ses-*/func/firstlvl/bodymap) | ||
|
||
sub=$(basename "$(dirname "$(dirname "$(dirname "$(dirname "${map_dirs[SLURM_ARRAY_TASK_ID]}")")")")") | ||
ses=$(basename "$(dirname "$(dirname "$(dirname "${map_dirs[SLURM_ARRAY_TASK_ID]}")")")") | ||
task=$(basename "${map_dirs[SLURM_ARRAY_TASK_ID]}") | ||
|
||
# Print the extracted components for each 'map_dir' | ||
echo "sub: $sub, ses: $ses, task: $task" | ||
echo "conditions: '${conditions_str}'" | ||
|
||
module load matlab | ||
|
||
# Run the MATLAB function | ||
# srun matlab -nodisplay -r "addpath(genpath('//dartfs-hpc/rc/lab/C/CANlab/modules/spm12')); addpath(genpath('//dartfs-hpc/rc/lab/C/CANlab/labdata/projects/WASABI/software')); move_betas_to_secondlvl('${map_dirs[${SLURM_ARRAY_TASK_ID}]}', '${data_dir}', 'symlink', ${conditions_str})" | ||
srun matlab -nodisplay -r "addpath(genpath('//dartfs-hpc/rc/lab/C/CANlab/modules/spm12')); addpath(genpath('//dartfs-hpc/rc/lab/C/CANlab/labdata/projects/WASABI/software')); move_betas_to_secondlvl('${map_dirs[${SLURM_ARRAY_TASK_ID}]}', '${data_dir}', 'symlink')" |