# QSM-CI end-to-end pipeline — auto-generated by `qsm-ci interface snakemake --pipeline`.
# Put phase/mask in the working dir (magnitude/params too if your methods read them),
# then:  snakemake -c1 chimap.nii.gz
# The rules chain by filename (totalfield -> localfield -> chimap).

import os

def optional(**artifacts):
    """`--flag path` for each optional artifact that is actually present.

    The stage contract names these (so the rule works with any method slug), but they are not
    required: `magnitude` only some methods weight with, and `params.json` a caller may replace
    with acquisition flags. Listing them under `input:` would make Snakemake refuse to run the
    rule until the files exist.
    """
    return " ".join(f"--{flag} {path}" for flag, path in artifacts.items() if os.path.exists(path))

rule field_mapping:
    input:
        phase="phase.nii.gz",
        mask="mask.nii.gz",
    output:
        totalfield="totalfield.nii.gz",
    params:
        slug="romeo-qsmrs",
        optional=lambda wildcards: optional(magnitude="magnitude.nii.gz", params="params.json"),
    shell:
        "qsm-ci run {params.slug} --phase {input.phase} --mask {input.mask} {params.optional} -o {output.totalfield}"

rule bfr:
    input:
        totalfield="totalfield.nii.gz",
        mask="mask.nii.gz",
    output:
        localfield="localfield.nii.gz",
    params:
        slug="vsharp-qsmrs",
        optional=lambda wildcards: optional(params="params.json"),
    shell:
        "qsm-ci run {params.slug} --totalfield {input.totalfield} --mask {input.mask} {params.optional} -o {output.localfield}"

rule dipole:
    input:
        localfield="localfield.nii.gz",
        mask="mask.nii.gz",
    output:
        chimap="chimap.nii.gz",
    params:
        slug="rts-qsmrs",
        optional=lambda wildcards: optional(params="params.json"),
    shell:
        "qsm-ci run {params.slug} --localfield {input.localfield} --mask {input.mask} {params.optional} -o {output.chimap}"
