[Python] How to create a Docker file that iterates over files in a folder and executes a...

Discussão em 'Python' iniciado por Stack, Abril 6, 2025.

  1. Stack

    Stack Membro Participativo

    There is this program mri_synthstrip which inputs a brain MRI file and outputs the same brain MRI file excluding the skull. This is a basic initial step for preprocessing brain MRIs for research.

    The program is wonderful and the syntax to skull strip a single MRI is simple if you install the program in your computer:

    mri_synthstrip -i input.nii.gz -o stripped.nii.gz


    The authors are very nice and they even created a Docker image that you can pull from Dockerhub with docker pull freesurfer/synthstrip

    in which case the syntax to skull strip a brain MRI is

    docker run -v C:/Users/ch134560/Desktop/MRI_files://data freesurfer/synthstrip -i //data/input.nii.gz -o //data/stripped.nii.gz


    What I am trying to do is to create a Docker image that runs through all the MRI files in a directory and skull strips them with synthstrip. I thought this would be easy.

    My multistage Dockerfile looks like this, but it does not work because it does not recognize the command in the loop

    freesurfer/synthstrip -i "$file" -o "$file"


    or

    mri_synthstrip -i "$file" -o "$file"


    I guess that I do not know how to call a particular command within a unix loop.

    #########STAGE 1: CREATE THE MOUNT AND COPY THE MRIs TO BE SKULL-STRIPPED#########

    # Use ubuntu as base image
    FROM ubuntu AS prepare

    # Set working directory
    WORKDIR /app

    # Copy all MRIs
    COPY . .

    #########STAGE 2: USE SYNTHSTRIP#########
    FROM freesurfer/synthstrip

    # Set working directory
    WORKDIR /app

    # Copy all MRIs
    COPY --from=prepare . .

    # Create a loop that runs through the MRIs
    RUN for file in .; do freesurfer/synthstrip -i "$file" -o "$file"; done

    ENTRYPOINT ["ls"]


    Other option I thought about is to create a multistage build in which first I import the synthstrip program and then I loop through the MRI files and call synthstrip, but again I do not know exactly how to call the command to run synthstrip from python.

    Dockerfile

    #########STAGE 1: CREATE THE SYNTHSTRIP CONTAINER###########

    # Use synthstrip AS base image
    FROM freesurfer/synthstrip as builder

    # Set working directory
    WORKDIR /app

    #########STAGE 2: CREATE THE ANACONDA CONTAINER###########

    # Use miniconda as base image
    FROM continuumio/miniconda3

    # Set working directory
    WORKDIR /app

    # Copy the initial image
    COPY --from=builder . .

    # Create the environment
    COPY environment.yml .
    RUN conda env create -f environment.yml

    # Make run commands use the new environment
    SHELL ["conda", "run", "-n", "app", "bin/bash", "-c"]

    # Code to run when the container is started
    COPY main.py .
    ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "app", "python", "main.py"]


    main.py file

    import os
    import subprocess

    for MRI in os.listdir('./file_with_MRIs'):
    print(MRI)
    proc = subprocess.Popen(['docker run freesurfer/synthstrip -i ', MRI, ' -o', MRI],
    stdin = subprocess.PIPE,
    stdout = subprocess.PIPE,
    stderr = subprocess.PIPE
    )

    (out, err) = proc.communicate()
    print (out)


    Other option is to create a smaller Docker image that loops through the MRI files and just calls the synthstrip Docker image for each of those and collects the output, but I am not sure how to do that.

    Continue reading...

Compartilhe esta Página