generated from snakemake-workflows/snakemake-workflow-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add general madym_T1 wrapper (set to IR_E by default)
- Loading branch information
1 parent
2d65fcf
commit 5098ddc
Showing
5 changed files
with
263 additions
and
5 deletions.
There are no files selected for viewing
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,16 @@ | ||
# madym_T1 | ||
# version = v4.23.0 | ||
|
||
method: IR_E | ||
|
||
T1_dir: IR | ||
T1_vols: [OE_400, OE_800, OE_1000, OE_1500, OE_2000, OE_2500] | ||
B1_name: null | ||
|
||
output_dir: T1_IR | ||
log_file: logs/madym_T1_IR.log | ||
config_out: logs/madym_T1_IR.conf | ||
|
||
T1_noise: 0.1 | ||
B1_scaling: 1000 | ||
B1_values: [] |
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
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,36 @@ | ||
''' | ||
Wrapper for madym_T1 | ||
''' | ||
import os | ||
from snakemake.utils import validate | ||
|
||
configfile: workflow.source_path("../../config/madym_T1.config.yaml") | ||
validate(config, workflow.source_path("../schemas/madym_T1.schema.yaml")) | ||
|
||
envvars: | ||
"MADYM_ROOT" | ||
|
||
rule madym_T1: | ||
container: | ||
"docker://registry.gitlab.com/manchester_qbi/manchester_qbi_public/madym_cxx/madym_release_no_gui:u22.04" | ||
# "preclinicalmri_depends_no_gui:latest" | ||
input: | ||
# TODO: adjust for other formats, see img_fmt_r in madym_T1.schema.yaml | ||
expand("{T1_dir}/{vols}{ext}", | ||
T1_dir = config["T1_dir"], | ||
vols = config["T1_vols"], | ||
ext = [".nii.gz", ".json"]) | ||
output: | ||
# TODO: adjust for other formats, see img_fmt_w in madym_T1.schema.yaml | ||
expand("{output_dir}/{key}{ext}", | ||
output_dir = config["output_dir"], | ||
key = ["T1", "M0","efficiency"], | ||
ext = [".xtr", ".nii.gz"]), | ||
os.path.join(config["output_dir"], "error_tracker.nii.gz") | ||
# touch(os.path.join(config["output_dir"], "madym_T1.done")) | ||
log: | ||
log = config["log_file"], | ||
cfg = config["config_out"], | ||
audit = os.path.join(config["audit_dir"], config["audit_name"]) | ||
script: | ||
"../scripts/madym_T1.py" |
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,121 @@ | ||
$schema: "https://json-schema.org/draft/2020-12/schema" | ||
|
||
|
||
# The following options are overriden by snakemake's functionality: | ||
# working_directory: set to workdir | ||
# config_file: disabled (replaced by rule's configfile) | ||
|
||
# roi_name | ||
|
||
properties: | ||
|
||
# Inputs | ||
T1_vols: | ||
type: [array, "null"] | ||
default: null | ||
description: Variable flip angle file names, comma separated (no spaces). | ||
T1_dir: | ||
type: [string, "null"] | ||
default: null | ||
description: Folder containing T1 input volumes, can be left empty if already included in option --T1_vols | ||
img_fmt_r: | ||
type: string | ||
default: NIFTI_GZ | ||
# enum: [ANALYZE, ANALYZE_SPARSE, NIFTI, NIFTI_GZ, DICOM] # TODO: adjust madym_T1.smk inputs for other formats | ||
const: NIFTI_GZ | ||
description: Image format for reading input. | ||
error_name: | ||
type: [string, "null"] | ||
default: null | ||
description: Error codes image file name. | ||
|
||
# Outputs | ||
output_dir: | ||
type: [string, "null"] | ||
default: null | ||
description: Output path, will use a temporary directory if empty. | ||
img_fmt_w: | ||
type: string | ||
default: NIFTI_GZ | ||
# enum: [ANALYZE, ANALYZE_SPARSE, NIFTI, NIFTI_GZ, DICOM] # TODO: adjust madym_T1.smk outputs for other formats | ||
const: NIFTI_GZ | ||
description: Image format for writing output. | ||
log_file: | ||
type: string | ||
default: logs/madym_T1.log | ||
description: Folder in which audit output is saved. | ||
config_out: | ||
type: [string, "null"] | ||
default: logs/madym_T1.conf | ||
description: Filename of the output config file. | ||
no_log: | ||
type: boolean | ||
default: false | ||
description: Switch off program logging. | ||
no_audit: | ||
type: boolean | ||
default: true | ||
description: Switch off audit logging. | ||
audit_dir: | ||
type: string | ||
default: audit_logs | ||
description: Folder in which audit output is saved. | ||
audit_name: | ||
type: string | ||
default: madym_T1.audit | ||
description: Audit file name. | ||
quiet: | ||
type: boolean | ||
default: false | ||
description: Do not display logging messages in cout. | ||
|
||
# Params | ||
method: | ||
type: ["null","string"] | ||
default: null | ||
enum: [VFA, VFA_B1, IR, IR_E] | ||
description: T1 method to use to fit, Variable Flip-Angle [B1 corrected], Inversion Recovery [with efficiency weighting] | ||
B1_name: | ||
type: [string, "null"] | ||
default: null | ||
description: Path to the B1 correction map. | ||
B1_scaling: | ||
type: ["number", "null"] | ||
default: null | ||
description: Value applied to scaled values in the B1 correction map. | ||
B1_values: | ||
type: [array, "null"] | ||
default: null | ||
description: B1 correction values, 1D array of length n_samples. | ||
T1_noise: | ||
type: ["number", "null"] | ||
default: null | ||
description: PD noise threshold. | ||
|
||
# Other | ||
nifti_scaling: | ||
type: boolean | ||
default: false | ||
description: If set, applies intensity scaling and offset when reading/writing NIFTI images. | ||
nifti_4D: | ||
type: boolean | ||
default: false | ||
description: If set, reads NIFTI 4D images for T1 mapping and dynamic inputs. | ||
use_BIDS: | ||
type: boolean | ||
default: false | ||
description: If set, writes images using BIDS JSON meta info. | ||
voxel_size_warn_only: | ||
type: boolean | ||
default: false | ||
description: Warn if voxel sizes don't match for subsequent images. | ||
overwrite: | ||
type: boolean | ||
default: true | ||
description: Set overwrite existing analysis in the output directory ON. | ||
|
||
required: | ||
- method | ||
- T1_vols | ||
|
||
# additionalProperties: false |
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,87 @@ | ||
import os | ||
import re | ||
|
||
from QbiMadym import madym_T1 | ||
from QbiMadym.utils import local_madym_root | ||
|
||
import subprocess | ||
command = 'madym_T1.exe' | ||
try: | ||
command = os.path.join(local_madym_root(),'madym_T1') | ||
subprocess.run([command, "--version"], stdout = subprocess.PIPE, stderr = subprocess.PIPE, check=True) | ||
except subprocess.CalledProcessError: | ||
raise NameError(f"{command} is not available.") | ||
|
||
madym_T1.run( | ||
# | ||
working_directory = os.getcwd(), | ||
config_file = None, | ||
# cmd_exe = command, | ||
# | ||
output_dir = snakemake.config["output_dir"], | ||
img_fmt_w = "NIFTI_GZ", | ||
|
||
# Input | ||
# T1_dir = snakemake.config["T1_dir"], | ||
T1_vols = [os.path.join(snakemake.config["T1_dir"], vol) for vol in snakemake.config["T1_vols"]], | ||
img_fmt_r = "NIFTI_GZ", | ||
roi_name = snakemake.config["roi_path"], | ||
error_name = snakemake.config["error_name"], | ||
|
||
# Params | ||
method = snakemake.config["method"], | ||
B1_name = snakemake.config["B1_name"], | ||
B1_scaling = snakemake.config["B1_scaling"], | ||
noise_thresh = snakemake.config["T1_noise"], | ||
nifti_scaling = snakemake.config["nifti_scaling"], | ||
nifti_4D = snakemake.config["nifti_4D"], | ||
use_BIDS = snakemake.config["use_BIDS"], | ||
voxel_size_warn_only = snakemake.config["voxel_size_warn_only"], | ||
# | ||
no_log = False, | ||
quiet = False, | ||
overwrite = True, | ||
return_maps = False, | ||
dummy_run = False, | ||
|
||
no_audit = snakemake.config["no_audit"], | ||
audit_dir = snakemake.config["audit_dir"], | ||
|
||
program_log_name = "smk.log", # see below (*) | ||
config_out = "smk.cfg", | ||
audit_name = "smk.audit" | ||
|
||
# madym_T1_lite options (not exposed) | ||
# ScannerParams = None, | ||
# signals = None, | ||
# TR = None, | ||
# B1_values = None, | ||
# output_name = 'madym_analysis.dat', | ||
) | ||
|
||
# (*) Logs are time-stamped and auto-renamed by madym: | ||
# | ||
# {output_dir}/madym_T1_{date}_{time}_smk.log | ||
# {output_dir}/madym_T1_{date}_{time}_smk.cfg | ||
# {output_dir}/madym_T1_{date}_{time}_override_smk.cfg | ||
# {audit_dir}/madym_T1_{date}_{time}_smk.audit | ||
# | ||
# Rename to consistent snakemake.log entries | ||
for item in snakemake.log.keys(): | ||
|
||
if item == "log" or item == "cfg": | ||
dir = snakemake.config["output_dir"] | ||
elif item == "audit": | ||
dir = snakemake.config["audit_dir"] | ||
else: | ||
raise NameError("Unexpected log key: " + item) | ||
|
||
for filename in os.listdir(dir): | ||
match = re.match(r'madym_T1_(\d+)_(\d+)(_\w)?_smk\.' + item, filename) | ||
if match: | ||
if match.group(3) is None: | ||
logname = snakemake.log[item] | ||
else: | ||
# Modify log.ext to e.g. log_override.ext | ||
logname = re.sub(r'(\.\w+)$', match.group(3) + r'\1', snakemake.log[item]) | ||
os.rename(os.path.join(dir, filename), logname) |