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

Skeletons and foldlabels for the whole brain #75

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
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
5 changes: 5 additions & 0 deletions deep_folding/brainvisa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ def inner_function(*args, **kwargs):
if exc.code != 0:
reraise(*exc_info())
return inner_function


class DeepFoldingError(BaseException):
pass

69 changes: 55 additions & 14 deletions deep_folding/brainvisa/generate_ICBM2009c_transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@
import glob
import sys
import re
from os.path import abspath
from os.path import abspath, basename, join, dirname
from os.path import basename

from deep_folding.brainvisa import exception_handler
from deep_folding.brainvisa import exception_handler, DeepFoldingError
from deep_folding.brainvisa.utils.folder import create_folder
from deep_folding.brainvisa.utils.subjects import get_number_subjects,\
is_it_a_subject
Expand Down Expand Up @@ -129,10 +129,11 @@ def parse_args(argv):

args = parser.parse_args(argv)

suffix = {"R": "right", "L": "left", "F": "full"}
setup_log(args,
log_dir=f"{args.output_dir}",
prog_name=basename(__file__),
suffix='right' if args.side == 'R' else 'left')
suffix=suffix[args.side])

params = vars(args)

Expand Down Expand Up @@ -166,26 +167,49 @@ def __init__(self, src_dir, transform_dir,
def generate_one_transform(self, subject: str):
"""Generates and writes ICBM2009c transform for one subject.
"""
graph_path = f"{self.src_dir}/{subject}*/" +\
f"{self.path_to_graph}/{self.side}*.arg"
if self.side == "F":
graph_path = f"{self.src_dir}/{subject}*/" + \
f"{self.path_to_graph}/?{subject}*.arg"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est normal qu'il y ait un {subject] en plus dans le path ?

else:
graph_path = f"{self.src_dir}/{subject}*/" + \
f"{self.path_to_graph}/{self.side}{subject}*.arg"
log.debug(graph_path)
list_graph_file = glob.glob(graph_path)
log.debug(f"list_graph_file = {list_graph_file}")
if len(list_graph_file) == 0:
raise RuntimeError(f"No graph file! "
f"{graph_path} doesn't exist")
for graph_file in list_graph_file:
transform_file = self.get_transform_filename(subject, graph_file)
graph = aims.read(graph_file)
g_to_icbm_template = aims.GraphManip.getICBM2009cTemplateTransform(
graph)
aims.write(g_to_icbm_template, transform_file)
if not self.bids:
break
try:
transform_file = self.get_transform_filename(subject, graph_file)
if self.side == "F":
graph_file_left, graph_file_right, graph_to_remove = \
self.get_left_and_right_graph_files(graph_file, list_graph_file)
list_graph_file.remove(graph_to_remove)
graph_left = aims.read(graph_file_left)
graph_right = aims.read(graph_file_right)
g_to_icbm_template_left = aims.GraphManip.getICBM2009cTemplateTransform(
graph_left)
g_to_icbm_template_right = aims.GraphManip.getICBM2009cTemplateTransform(
graph_right)
if g_to_icbm_template_left != g_to_icbm_template_right:
raise DeepFoldingError(f"Left and right transformations files are not the same: "
f"{g_to_icbm_template_left} and {g_to_icbm_template_right}")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mais du coup, vu que la DeepFoldingError fait que pass, ça arrête le sujet en cours ?

aims.write(g_to_icbm_template_left, transform_file)
else:
graph = aims.read(graph_file)
g_to_icbm_template = aims.GraphManip.getICBM2009cTemplateTransform(
graph)
aims.write(g_to_icbm_template, transform_file)
if not self.bids:
break
except DeepFoldingError as e:
log.error(f"Graph file {graph_file} : {e}")
continue

def get_transform_filename(self, subject, graph_file):
transform_file = (
f"{self.transform_dir}/"
transform_file = join(
f"{self.transform_dir}",
f"{self.side}transform_to_ICBM2009c_{subject}")
if self.bids:
session = re.search("ses-([^_/]+)", graph_file)
Expand All @@ -200,6 +224,23 @@ def get_transform_filename(self, subject, graph_file):
transform_file += ".trm"
return transform_file

@staticmethod
def get_left_and_right_graph_files(graph_file, list_graph_file):
graph_name = basename(graph_file)
if graph_name.startswith("L"):
graph_file_left = graph_file
graph_file_right = join(dirname(graph_file), f"R{graph_name[1:]}")
if graph_file_right not in list_graph_file:
raise DeepFoldingError(f"Right graph is missing : {graph_file_right}")
graph_to_remove = graph_file_right
else:
graph_file_right = graph_file
graph_file_left = join(dirname(graph_file), f"L{graph_name[1:]}")
if graph_file_left not in list_graph_file:
raise DeepFoldingError(f"Left graph is missing : {graph_file_left}")
graph_to_remove = graph_file_left
return graph_file_left, graph_file_right, graph_to_remove

def compute(self, number_subjects):
"""Loops over subjects to generate transforms to ICBM2009c from graphs.
"""
Expand Down
69 changes: 52 additions & 17 deletions deep_folding/brainvisa/generate_foldlabels.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
Typical usage
-------------
You can use this program by first entering in the brainvisa environment
(here brainvisa 5.0.0 installed with singurity) and launching the script
(here brainvisa 5.0.0 installed with singularity) and launching the script
from the terminal:
>>> bv bash
>>> python generate_foldlabels.py
Expand All @@ -50,11 +50,9 @@
import glob
import re
import sys
from os.path import abspath
from os.path import exists
from os.path import basename
from os.path import abspath, exists, basename, dirname, join

from deep_folding.brainvisa import exception_handler
from deep_folding.brainvisa import exception_handler, DeepFoldingError
from deep_folding.brainvisa.utils.folder import create_folder
from deep_folding.brainvisa.utils.subjects import get_number_subjects,\
is_it_a_subject
Expand All @@ -63,7 +61,7 @@
from deep_folding.brainvisa.utils.logs import setup_log
from deep_folding.brainvisa.utils.parallel import define_njobs
from deep_folding.brainvisa.utils.foldlabel import \
generate_foldlabel_from_graph_file
generate_foldlabel_from_graph_file, generate_full_foldlabel
from deep_folding.brainvisa.utils.quality_checks import \
compare_number_aims_files_with_expected, \
compare_number_aims_files_with_number_in_source, \
Expand Down Expand Up @@ -144,10 +142,11 @@ def parse_args(argv):

args = parser.parse_args(argv)

suffix = {"R": "right", "L": "left", "F": "full"}
setup_log(args,
log_dir=f"{args.output_dir}",
prog_name=basename(__file__),
suffix='right' if args.side == 'R' else 'left')
suffix=suffix[args.side])

params = {}

Expand All @@ -157,6 +156,8 @@ def parse_args(argv):
params['side'] = args.side
params['junction'] = args.junction
params['parallel'] = args.parallel
params['bids'] = args.bids
params['parallel'] = args.parallel
# Checks if nb_subjects is either the string "all" or a positive integer
params['nb_subjects'] = get_number_subjects(args.nb_subjects)

Expand Down Expand Up @@ -205,20 +206,54 @@ def generate_one_foldlabel(self, subject: str):
"""Generates and writes skeleton for one subject.
"""
# Gets graph file path
graph_path = f"{self.src_dir}/{subject}*/" +\
f"{self.path_to_graph}/{self.side}*.arg"
if self.side == "F":
graph_path = f"{self.src_dir}/{subject}*/" + \
f"{self.path_to_graph}/?{subject}*.arg"
else:
graph_path = f"{self.src_dir}/{subject}*/" +\
f"{self.path_to_graph}/{self.side}*.arg"
list_graph_file = glob.glob(graph_path)
log.debug(f"list_graph_file = {list_graph_file}")
if len(list_graph_file) == 0:
raise RuntimeError(f"No graph file! "
f"{graph_path} doesn't exist")

raise FileNotFoundError(f"No graph file! "
f"{graph_path} doesn't exist")
for graph_file in list_graph_file:
foldlabel_file = self.get_foldlabel_filename(subject, graph_file)
generate_foldlabel_from_graph_file(
graph_file, foldlabel_file, self.junction)
if not self.bids:
break
try:
foldlabel_file = self.get_foldlabel_filename(subject, graph_file)
if self.side == "F":
graph_file_left, graph_file_right, graph_to_remove = \
self.get_left_and_right_graph_files(graph_file, list_graph_file)
if graph_to_remove:
list_graph_file.remove(graph_to_remove)
generate_full_foldlabel(graph_file_left, graph_file_right,
foldlabel_file, self.junction)
else:
generate_foldlabel_from_graph_file(
graph_file, foldlabel_file, self.junction)
if not self.bids:
break
except DeepFoldingError as e:
log.error(f"Graph file {graph_file} : {e}")
continue

@staticmethod
def get_left_and_right_graph_files(graph_file, list_graph_file):
graph_name = basename(graph_file)
if graph_name[0] == "L":
graph_file_left = graph_file
graph_file_right = join(dirname(graph_file), f"R{graph_name[1:]}")
if graph_file_right not in list_graph_file:
raise DeepFoldingError(f"Right graph is missing ({graph_file_right})")
else:
graph_to_remove = graph_file_right
else:
graph_file_right = graph_file
graph_file_left = join(dirname(graph_file), f"L{graph_name[1:]}")
if graph_file_left not in list_graph_file:
raise DeepFoldingError(f"Left graph is missing ({graph_file_left})")
else:
graph_to_remove = graph_file_left
return graph_file_left, graph_file_right, graph_to_remove

def compute(self, number_subjects):
"""Loops over subjects and converts graphs into skeletons.
Expand Down
78 changes: 59 additions & 19 deletions deep_folding/brainvisa/generate_skeletons.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
Typical usage
-------------
You can use this program by first entering in the brainvisa environment
(here brainvisa 5.0.0 installed with singurity) and launching the script
(here brainvisa 5.0.0 installed with singularity) and launching the script
from the terminal:
>>> bv bash
>>> python generate_skeletons.py
Expand All @@ -50,10 +50,9 @@
import glob
import re
import sys
from os.path import abspath
from os.path import basename
from os.path import abspath, basename, join, dirname

from deep_folding.brainvisa import exception_handler
from deep_folding.brainvisa import exception_handler, DeepFoldingError
from deep_folding.brainvisa.utils.folder import create_folder
from deep_folding.brainvisa.utils.subjects import \
get_number_subjects, is_it_a_subject
Expand All @@ -62,7 +61,7 @@
from deep_folding.brainvisa.utils.logs import setup_log
from deep_folding.brainvisa.utils.parallel import define_njobs
from deep_folding.brainvisa.utils.skeleton import \
generate_skeleton_from_graph_file
generate_skeleton_from_graph_file, generate_full_skeleton
from deep_folding.brainvisa.utils.quality_checks import \
compare_number_aims_files_with_expected, \
get_not_processed_subjects
Expand Down Expand Up @@ -141,10 +140,11 @@ def parse_args(argv):

args = parser.parse_args(argv)

suffix = {"R": "right", "L": "left", "F": "full"}
setup_log(args,
log_dir=f"{args.output_dir}",
prog_name=basename(__file__),
suffix='right' if args.side == 'R' else 'left')
suffix=suffix[args.side])

params = vars(args)

Expand Down Expand Up @@ -196,20 +196,60 @@ def get_skeleton_filename(self, subject, graph_file):
def generate_one_skeleton(self, subject: str):
"""Generates and writes skeleton for one subject.
"""
graph_path = f"{self.src_dir}/{subject}*/" +\
f"{self.path_to_graph}/{self.side}*.arg"
if self.side == "F":
graph_path = f"{self.src_dir}/{subject}*/" + \
f"{self.path_to_graph}/?{subject}*.arg"
else:
graph_path = f"{self.src_dir}/{subject}*/" + \
f"{self.path_to_graph}/{self.side}{subject}*.arg"
list_graph_file = glob.glob(graph_path)
log.debug(f"list_graph_file = {list_graph_file}")
if len(list_graph_file) == 0:
raise RuntimeError(f"No graph file! "
f"{graph_path} does not exist")
try:
if len(list_graph_file) == 0:
raise FileNotFoundError(f"No graph file! "
f"{graph_path} doesn't exist")
except FileNotFoundError as e:
log.error(f"Subject {subject} : {e}")
for graph_file in list_graph_file:
skeleton_file = self.get_skeleton_filename(subject, graph_file)
generate_skeleton_from_graph_file(graph_file,
skeleton_file,
self.junction)
if not self.bids:
break
try:
skeleton_file = self.get_skeleton_filename(subject, graph_file)
if self.side == "F":
graph_file_left, graph_file_right, graph_to_remove = \
self.get_left_and_right_graph_files(graph_file, list_graph_file)
if graph_to_remove:
list_graph_file.remove(graph_to_remove)
generate_full_skeleton(graph_file_left,
graph_file_right,
skeleton_file,
self.junction)
else:
generate_skeleton_from_graph_file(graph_file,
skeleton_file,
self.junction)
if not self.bids:
break
except DeepFoldingError as e:
log.error(f"Graph file {graph_file} : {e}")
continue

@staticmethod
def get_left_and_right_graph_files(graph_file, list_graph_file):
graph_name = basename(graph_file)
if graph_name[0] == "L":
graph_file_left = graph_file
graph_file_right = join(dirname(graph_file), f"R{graph_name[1:]}")
if graph_file_right not in list_graph_file:
raise DeepFoldingError(f"Right graph is missing ({graph_file_right})")
else:
graph_to_remove = graph_file_right
else:
graph_file_right = graph_file
graph_file_left = join(dirname(graph_file), f"L{graph_name[1:]}")
if graph_file_left not in list_graph_file:
raise DeepFoldingError(f"Left graph is missing ({graph_file_left})")
else:
graph_to_remove = graph_file_left
return graph_file_left, graph_file_right, graph_to_remove

def compute(self, number_subjects):
"""Loops over subjects and converts graphs into skeletons.
Expand All @@ -226,8 +266,8 @@ def compute(self, number_subjects):
list_subjects = select_subjects_int(list_subjects, number_subjects)

log.info(f"Expected number of subjects = {len(list_subjects)}")
log.info(f"list_subjects[:5] = {list_subjects[:5]}")
log.debug(f"list_subjects = {list_subjects}")
log.info(f"list_subjects[:5] = {list_subjects[:5]}")
log.debug(f"list_subjects = {list_subjects}")

# Performs computation on all subjects either serially or in parallel
if self.parallel:
Expand Down
Loading