Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Add options for sub-folder and for func sesssions" #94

Merged
merged 1 commit into from
May 30, 2024
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
126 changes: 0 additions & 126 deletions manual_correction.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,6 @@ def get_parser():
type=str,
default=None
)
parser.add_argument( #TODO
'-add-subfolder',
help="Add a subfolder to find labels or segmentation to correct",
type=str,
default=None
)
parser.add_argument(
'-qc-only',
help="Only output QC report based on the manually-corrected files already present in the 'derivatives' folder. "
Expand Down Expand Up @@ -590,8 +584,6 @@ def ask_if_modify(fname_out, fname_label, do_labeling_always=False):
create_empty_mask = False

# If the output file does not exist, copy it from label folder
print(os.path.isfile(fname_label))
print('fname_label', fname_label)
elif not os.path.isfile(fname_out) and os.path.isfile(fname_label):
do_labeling = True
copy = True
Expand Down Expand Up @@ -788,123 +780,6 @@ def main():
# TODO: address "none" issue if no file present under a key
# Perform manual corrections
for task, files in dict_yml.items():
# Get the list of segmentation files to add to derivatives, excluding the manually corrected files in -config.
# TODO: probably extend also for other tasks (such as FILES_GMSEG)
if args.add_seg_only and task == 'FILES_SEG':
# Remove the files in the -config list
for file in files:
# Remove the file suffix (e.g., '_RPI_r') to match the list of files in -path-img
file = utils.remove_suffix(file, args.suffix_files_in)
if file in file_list:
file_list.remove(file)
files = file_list # Rename to use those files instead of the ones to exclude
if len(files) > 0:
# Handle regex (i.e., iterate over all subjects)
if '*' in files[0] and len(files) == 1:
subject, ses, filename, contrast = utils.fetch_subject_and_session(files[0])
# Get list of files recursively
files = sorted(glob.glob(os.path.join(path_img, '**', filename),
recursive=True))
# Loop across files
for file in tqdm.tqdm(files, desc="{}".format(task), unit="file"):
# Print empty line to not overlay with tqdm progress bar
time.sleep(0.1)
print("")
# build file names
subject, ses, filename, contrast = utils.fetch_subject_and_session(file)
if args.add_subfolder:
subfolder = args.add_subfolder
else:
subfolder = False
# Construct absolute path to the input file
# For example: '/Users/user/dataset/data_processed/sub-001/anat/sub-001_T2w.nii.gz'
if subfolder:
fname = os.path.join(path_img, subject, ses, contrast, subfolder, filename)
else:
fname = os.path.join(path_img, subject, ses, contrast, filename)
# Construct absolute path to the other contrast file
if args.load_other_contrast:
# Do not include session in the filename
if ses == '':
other_contrast_filename = subject + '_' + args.load_other_contrast + '.nii.gz'
# Include session in the filename
else:
other_contrast_filename = subject + '_' + ses + '_' + args.load_other_contrast + '.nii.gz'
fname_other_contrast = os.path.join(path_img, subject, ses, contrast, other_contrast_filename)
else:
fname_other_contrast = None
# Construct absolute path to the input label (segmentation, labeling etc.) file
# For example: '/Users/user/dataset/data_processed/sub-001/anat/sub-001_T2w_seg.nii.gz'
if subfolder:
fname_label = utils.add_suffix(os.path.join(path_label, subject, ses, contrast, subfolder, filename), suffix_dict[task])
else:
fname_label = utils.add_suffix(os.path.join(path_label, subject, ses, contrast, filename), suffix_dict[task])
# Construct absolute path to the output file (i.e., path where manually corrected file will be saved)
# For example: '/Users/user/dataset/derivatives/labels/sub-001/anat/sub-001_T2w_seg.nii.gz'
# The information regarding the modified data will be stored within the sidecar .json file
fname_out = utils.add_suffix(os.path.join(path_out, subject, ses, contrast, filename), suffix_dict[task])

# Create subject folder in output if they do not exist
os.makedirs(os.path.join(path_out, subject, ses, contrast), exist_ok=True)
if not args.qc_only:
# Check if the output file already exists. If so, asks user if they want to modify it.
do_labeling, copy, create_empty_mask, do_labeling_always = \
ask_if_modify(fname_out=fname_out,
fname_label=fname_label,
do_labeling_always=do_labeling_always)
# Perform labeling (i.e., segmentation correction, labeling correction etc.) for the specific task
if do_labeling:
if args.denoise:
# Denoise the input file
fname = denoise_image(fname)
# Copy file to derivatives folder
if copy:
shutil.copyfile(fname_label, fname_out)
print(f'Copying: {fname_label} to {fname_out}')
# Create empty mask in derivatives folder
elif create_empty_mask:
utils.create_empty_mask(fname, fname_out)

if task in ['FILES_SEG', 'FILES_GMSEG']:
if not args.add_seg_only:
time_one = get_modification_time(fname_out)
correct_segmentation(fname, fname_out, fname_other_contrast, args.viewer, param_fsleyes)
time_two = get_modification_time(fname_out)
elif task == 'FILES_LESION':
time_one = get_modification_time(fname_out)
correct_segmentation(fname, fname_out, fname_other_contrast, args.viewer, param_fsleyes)
time_two = get_modification_time(fname_out)
elif task == 'FILES_LABEL':
time_one = get_modification_time(fname_out)
correct_vertebral_labeling(fname, fname_out, args.label_disc_list)
time_two = get_modification_time(fname_out)
elif task == 'FILES_COMPRESSION':
time_one = get_modification_time(fname_out)
# Note: be aware of possibility to create compression labels also using
# 'sct_label_utils -create-viewer'
# Context: https://github.com/spinalcordtoolbox/spinalcordtoolbox/issues/3984
correct_segmentation(fname, fname_out, fname_other_contrast, 'fsleyes', param_fsleyes)
time_two = get_modification_time(fname_out)
elif task == 'FILES_PMJ':
time_one = get_modification_time(fname_out)
correct_pmj_label(fname, fname_out)
time_two = get_modification_time(fname_out)
elif task == 'FILES_CENTERLINE':
time_one = get_modification_time(fname_out)
correct_centerline(fname, fname_out)
time_two = get_modification_time(fname_out)
else:
sys.exit('Task not recognized from the YAML file: {}'.format(task))
if args.denoise:
# Remove the denoised file (we do not need it anymore)
remove_denoised_file(fname)

# Add segmentation only (skip generating QC report)
if args.add_seg_only:
# We are passing modified=True because we are adding a new segmentation and we want
# to create a JSON file
update_json(fname_out, name_rater, modified=True)
# Generate QC report
if task.startswith('FILES'):
# Check if task is in suffix_dict.keys(), if not, skip it
# Note that this check is done after the task.startswith('FILES') check because the manual-correction
Expand Down Expand Up @@ -1022,7 +897,6 @@ def main():
# a JSON file
update_json(fname_out, name_rater, json_metadata)
# Generate QC report
#generate_qc(fname, fname_out, task, fname_qc, subject, args.config, args.qc_lesion_plane, suffix_dict)
else:
update_json(fname_out, name_rater, json_metadata)
# Generate QC report
Expand Down
12 changes: 3 additions & 9 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,16 @@ def fetch_subject_and_session(filename_path):
_, filename = os.path.split(filename_path) # Get just the filename (i.e., remove the path)
subject = re.search('sub-(.*?)[_/]', filename_path) # [_/] means either underscore or slash
subjectID = subject.group(0)[:-1] if subject else "" # [:-1] removes the last underscore or slash
session = re.findall(r'ses-.*', filename_path)
sessionID = session[0].split('_')[0] if session else "" # Return None if there is no session
if 'dwi' in filename_path:
contrast = 'dwi'
elif 'bold' in filename_path:
contrast = 'func'
else:
contrast = 'anat'


session = re.search('ses-(.*?)[_/]', filename_path) # [_/] means either underscore or slash
sessionID = session.group(0)[:-1] if session else "" # [:-1] removes the last underscore or slash
# REGEX explanation
# . - match any character (except newline)
# *? - match the previous element as few times as possible (zero or more times)

# TODO - add support for func (fMRI)
contrast = 'dwi' if 'dwi' in filename_path else 'anat' # Return contrast (dwi or anat)

return subjectID, sessionID, filename, contrast


Expand Down
Loading