diff --git a/b0realsim/label_to_chi.py b/b0realsim/label_to_chi.py index 6137ad8..f1499d1 100644 --- a/b0realsim/label_to_chi.py +++ b/b0realsim/label_to_chi.py @@ -6,36 +6,13 @@ import json import datetime import git - +from utils.tissue2MR import run_tissue2MR def label_to_chi(bids_subject_dir): bids_subject_dir = Path(bids_subject_dir) subject = str(bids_subject_dir.stem) - merged_labels_path = bids_subject_dir / ".." / 'derivatives' / 'labels' / subject / 'anat' / (subject + '_T1w_label-all.nii.gz') - - - vol = nib.load(merged_labels_path.resolve()) - - vol_data = vol.get_fdata() - - vol_data.astype(np.float64) - - vol_data[vol_data==0] = 0.35 - vol_data[vol_data==1] = -9.05 - vol_data[vol_data==2] = -2 - vol_data[vol_data==3] = -2 - vol_data[vol_data==4] = -4.2 - vol_data[vol_data==5] = -4.2 - vol_data[vol_data==6] = -4.2 - vol_data[vol_data==56] = -9.04 - vol_data[vol_data==60] = -9.05 - vol_data[vol_data==91] = -11 - vol_data[vol_data==92] = -11 - vol_data[vol_data==93] = -9.055 - vol_data[vol_data==100] = -9.055 - - new_volume = nib.Nifti1Image(vol_data, vol.affine, vol.header, dtype=np.float64) + merged_labels_path = bids_subject_dir / ".." / 'derivatives' /'labels' / subject / 'anat' / (subject + '_T1w_label-all.nii.gz') # Check if the directory bids_subject_dir / ".." / 'derivatives' / subject / exists and if no, create it @@ -47,9 +24,16 @@ def label_to_chi(bids_subject_dir): if not os.path.exists(bids_subject_dir / ".." / 'derivatives' / subject / 'anat' ): os.makedirs(bids_subject_dir / ".." / 'derivatives' / subject / 'anat' ) - chi_file = bids_subject_dir / ".." / 'derivatives' / subject / 'anat' / (subject + '_T1w-chi.nii.gz') + chi_file = bids_subject_dir / ".." / 'derivatives' / 'b0sim' /subject / 'anat' / (subject + '_T1w-chi.nii.gz') - nib.save(new_volume, chi_file) + vol = nib.load(merged_labels_path.resolve()) + run_tissue2MR( + in_file = str(merged_labels_path.resolve()), + seg_tool = "compare_fm", + version = "ds005616", + tissue_prop = "sus", + out_file = str(chi_file) + ) # Save json @@ -65,48 +49,8 @@ def label_to_chi(bids_subject_dir): bids_sidecar['input file'] = str(merged_labels_path.resolve()) bids_sidecar['command'] = 'python label_to_chi.py -s ' + str(bids_subject_dir) - bids_sidecar['anatomy'] = {} - bids_sidecar['anatomy']['background'] = {} - bids_sidecar['anatomy']['background']['label'] = 0 - bids_sidecar['anatomy']['background']['chi'] = 0.35 - bids_sidecar['anatomy']['body'] = {} - bids_sidecar['anatomy']['body']['label'] = '1' - bids_sidecar['anatomy']['body']['chi'] = -9.05 - bids_sidecar['anatomy']['sinus'] = {} - bids_sidecar['anatomy']['sinus'] ['label'] = 2 - bids_sidecar['anatomy']['sinus'] ['chi'] = -2 - bids_sidecar['anatomy']['earcanal'] = {} - bids_sidecar['anatomy']['earcanal'] ['label'] = 3 - bids_sidecar['anatomy']['earcanal']['chi'] = -2 - bids_sidecar['anatomy']['trachea'] = {} - bids_sidecar['anatomy']['trachea']['label'] = 4 - bids_sidecar['anatomy']['trachea']['chi'] = -4.2 - bids_sidecar['anatomy']['rightlung'] = {} - bids_sidecar['anatomy']['rightlung']['label'] = 5 - bids_sidecar['anatomy']['rightlung']['chi'] = -4.2 - bids_sidecar['anatomy']['leftlung'] = {} - bids_sidecar['anatomy']['leftlung']['label'] = 6 - bids_sidecar['anatomy']['leftlung']['chi'] = -4.2 - bids_sidecar['anatomy']['brain'] = {} - bids_sidecar['anatomy']['brain']['label'] = 56 - bids_sidecar['anatomy']['brain']['chi'] = -9.04 - bids_sidecar['anatomy']['eyes'] = {} - bids_sidecar['anatomy']['eyes']['label'] = 60 - bids_sidecar['anatomy']['eyes']['chi'] = -9.05 - bids_sidecar['anatomy']['skull'] = {} - bids_sidecar['anatomy']['skull']['label'] = 91 - bids_sidecar['anatomy']['skull']['chi'] = -11 - bids_sidecar['anatomy']['verterbae'] = {} - bids_sidecar['anatomy']['verterbae']['label'] = 92 - bids_sidecar['anatomy']['verterbae']['chi'] = -11 - bids_sidecar['anatomy']['disks'] = {} - bids_sidecar['anatomy']['disks']['label'] = 93 - bids_sidecar['anatomy']['disks']['chi'] = -9.055 - bids_sidecar['anatomy']['canal'] = {} - bids_sidecar['anatomy']['canal']['label'] = 100 - bids_sidecar['anatomy']['canal']['chi'] = -9.055 - - json_file = bids_subject_dir / ".." / 'derivatives' / subject / 'anat' / (subject + '_T1w-chi.json') + + json_file = bids_subject_dir / ".." / 'derivatives' / 'b0sim' /subject / 'anat' / (subject + '_T1w-chi.json') if os.path.exists(json_file): os.remove(json_file) diff --git a/b0realsim/label_to_perm_cond.py b/b0realsim/label_to_perm_cond.py new file mode 100644 index 0000000..3a8fdc8 --- /dev/null +++ b/b0realsim/label_to_perm_cond.py @@ -0,0 +1,90 @@ +import nibabel as nib +import numpy as np +import argparse +from pathlib import Path +import os +import json +import datetime +import git +from utils.tissue2MR import run_tissue2MR + + +def label_to_perm_cond(bids_subject_dir): + + bids_subject_dir = Path(bids_subject_dir) + subject = str(bids_subject_dir.stem) + merged_labels_path = bids_subject_dir / ".." / 'derivatives' / 'labels' / subject / 'anat' / (subject + '_T1w_label-all.nii.gz') + + # Check if the directory bids_subject_dir / ".." / 'derivatives' / subject / exists and if no, create it + + if not os.path.exists(bids_subject_dir / ".." / 'derivatives' / subject ): + os.makedirs(bids_subject_dir / ".." / 'derivatives' / subject ) + + # Check if the directory bids_subject_dir / ".." / 'derivatives' / subject / 'anat' exists and if no, create it + + if not os.path.exists(bids_subject_dir / ".." / 'derivatives' / subject / 'anat' ): + os.makedirs(bids_subject_dir / ".." / 'derivatives' / subject / 'anat' ) + + elecsim_anat_dir = bids_subject_dir / ".." / 'derivatives' / 'elecsim' / subject / 'anat' + os.makedirs(elecsim_anat_dir, exist_ok=True) + + perm7t_file = bids_subject_dir / ".." / 'derivatives' / 'elecsim' / subject / 'anat' / (subject + '_T1w-perm7T.nii.gz') + chi7t_file = bids_subject_dir / ".." / 'derivatives' / 'elecsim' / subject / 'anat' / (subject + '_T1w-cond7T.nii.gz') + + run_tissue2MR( + in_file = str(merged_labels_path.resolve()), + seg_tool = "compare_fm", + version = "ds005616", + tissue_prop = "perm7T", + out_file = str(perm7t_file) + ) + + run_tissue2MR( + in_file = str(merged_labels_path.resolve()), + seg_tool = "compare_fm", + version = "ds005616", + tissue_prop = "cond7T", + out_file = str(chi7t_file) + ) + # Save json + + repo = git.Repo(search_parent_directories=True) + + + bids_sidecar = {} + bids_sidecar['author'] = os.getenv('USERNAME') + bids_sidecar['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + bids_sidecar['script'] = str(Path(os.path.abspath(__file__)).resolve()) + bids_sidecar['script source'] = repo.remotes.origin.url + bids_sidecar['script commit hash'] = repo.head.object.hexsha + bids_sidecar['input file'] = str(merged_labels_path.resolve()) + bids_sidecar['command'] = 'python label_to_perm_cond.py -s ' + str(bids_subject_dir) + + json_perm7t_file = bids_subject_dir / ".." / 'derivatives' / subject / 'anat' / (subject + '_T1w-perm7T.json') + json_cond7t_file = bids_subject_dir / ".." / 'derivatives' / subject / 'anat' / (subject + '_T1w-cond7T.json') + if os.path.exists(json_perm7t_file): + os.remove(json_perm7t_file) + + with open(json_perm7t_file, 'w', encoding='utf-8') as f: + json.dump(bids_sidecar, f, ensure_ascii=False, indent=4) + + if os.path.exists(json_cond7t_file): + os.remove(json_cond7t_file) + + with open(json_cond7t_file, 'w', encoding='utf-8') as f: + json.dump(bids_sidecar, f, ensure_ascii=False, indent=4) + + +if __name__ == "__main__": + + current_directory = os.path.dirname(os.path.abspath(__file__)) + + # Create an argument parser + parser = argparse.ArgumentParser(description="Process subject directory path and other arguments.") + + # Add the -s argument to the parser + parser.add_argument("-s", "--bids_subject_dir", required=True, help="Path to the subject directory in BIDS format") + + # Parse the arguments + args = parser.parse_args() + label_to_perm_cond(args.bids_subject_dir) diff --git a/b0realsim/step_2_1_generate_perm_cond.sh b/b0realsim/step_2_1_generate_perm_cond.sh new file mode 100755 index 0000000..e2d9517 --- /dev/null +++ b/b0realsim/step_2_1_generate_perm_cond.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# Find all the subjects in the bids directory and create a list of them +# This is useful for the batch processing of subjects + +# Parse the command line arguments -b --bids_dir +while getopts ":b:" opt; do + case ${opt} in + b ) + BIDS_DIR=$OPTARG + ;; + \? ) + echo "Usage: cmd [-b] bids_dir" + exit 1 + ;; + esac +done + +# Handle Windows-style paths like E:/... or C:/... +if [[ "$BIDS_DIR" =~ ^[A-Z]:/ ]]; then + drive=$(echo $BIDS_DIR | cut -c1 | tr 'A-Z' 'a-z') + path=$(echo $BIDS_DIR | cut -c3-) + BIDS_DIR="/cygdrive/$drive/$path" +fi + +# Print the bids directory to the screen +echo "BIDS directory: $BIDS_DIR" + +# Check if BIDS_DIR exists +if [ ! -d "$BIDS_DIR" ]; then + echo "[ERROR] BIDS directory not found: $BIDS_DIR" + exit 1 +fi + +# If subjects.txt exists, remove it and create a new one +if [ -f subjects.txt ]; then + rm subjects.txt + touch subjects.txt +fi + +# Find all the subjects in the bids directory +SUBJECTS=$(ls $BIDS_DIR | grep sub-) + +# Remove sub-unfErssm001 and sub-unfErssm021 from the list of subjects +SUBJECTS=$(echo $SUBJECTS | sed 's/sub-unfErssm001//g' | sed 's/sub-unfErssm021//g') + +echo "Subjects found:" +echo $SUBJECTS + +# Create a list of the subjects +echo $SUBJECTS > subjects.txt + +# Get script directory +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +# Convert DIR to Windows path for Windows Python +WIN_DIR=$(echo "$DIR" | sed 's|/cygdrive/\([a-z]\)/|\U\1:/|') + +for subject in $SUBJECTS +do + # Skip empty entries from excluded subjects + if [ -z "$subject" ]; then + continue + fi + + echo "[INFO] Processing $subject" + + # Convert BIDS_DIR to Windows path + WIN_BIDS_DIR=$(echo "$BIDS_DIR" | sed 's|/cygdrive/\([a-z]\)/|\U\1:/|') + + # Check if subject folder exists + if [ ! -d "$WIN_BIDS_DIR/$subject" ]; then + echo "[WARNING] Subject folder not found: $WIN_BIDS_DIR/$subject, skipping..." + continue + fi + + # Check if Python script exists + if [ ! -f "$WIN_DIR/label_to_perm_cond.py" ]; then + echo "[ERROR] Python script not found: $WIN_DIR/label_to_perm_cond.py" + exit 1 + fi + + # Run Python to generate perm/cond maps + "C:/Users/Admin/Miniconda3/python.exe" "$WIN_DIR/label_to_perm_cond.py" -s "$WIN_BIDS_DIR/$subject" +done + +echo "[INFO] All subjects processed." + + diff --git a/b0realsim/utils/__init__.py b/b0realsim/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/b0realsim/utils/tissue2MR.py b/b0realsim/utils/tissue2MR.py new file mode 100644 index 0000000..0cee772 --- /dev/null +++ b/b0realsim/utils/tissue2MR.py @@ -0,0 +1,46 @@ +import subprocess +from pathlib import Path + +def run_tissue2MR( + in_file: str, + seg_tool: str, + version: str, + tissue_prop: str, + out_file: str, +): + """ + Run tissue_to_MR from command line inside Python. + + Parameters + ---------- + in_file : str + Path to input NIfTI file (.nii.gz). + seg_tool : str + The tool used to segmented the input file (argument to -s). + version : str + Version of the tool used to select approriate dictionary (argument to -v). + tissue_prop : str + Tissue type desired (argument to -t). + out_file : str + Path to output NIfTI file (.nii.gz). + """ + + # Ensure paths are safe + in_file = Path(in_file).resolve() + out_file = Path(out_file).resolve() + + cmd = [ + "tissue_to_MR", + "-i", str(in_file), + "-s", seg_tool, + "-v", version, + "-t", tissue_prop, + "-o", str(out_file) + ] + + try: + subprocess.run(cmd, check=True) + print(f"[INFO] tissue_to_MR finished successfully. Output: {out_file}") + except subprocess.CalledProcessError as e: + print("[ERROR] tissue_to_MR failed!") + print(e)