Skip to content

Programming: Moving away from sct.run and run_proc

Joshua Newton edited this page Jun 15, 2022 · 1 revision

Most file OS commands can be found here (shutils) and here (os)

Basic sytem call replacement:

  • When copying a file:

    -sct.run('cp src dst')
    +sct.copy(src, dst)

    Rationale:

    • Avoids to run a subprocess
    • ... which may not exist on Windows
    • shutil.copy() pops an exception if src is actually the same file as dst (which can happen)
  • To delete a file:

    -sct.run('rm path_to_file')
    +os.remove(path_to_file, ignore_errors=True)

    Rationale: same as above

  • Delete a folder (only) recursively:

    -sct.run('rm -rf path_to_folder')
    +shutil.rmtree(path, ignore_errors=True)

    Rationale: same as above

  • Get environment variable:

    -status, path_sct = commands.getstatusoutput('echo $THE_VARIABLE')
    +default_value = "something_that_makes_sense"
    +the_variable = os.environ.get('THE_VARIABLE', default_value)

    Rationale: same as above

    Note: for ${SCT_DIR}, try to get the default value from the path of __file__. See how scripts do (git grep SCT_DIR).

  • Rename a file:

    -sct.run('mv src dst')
    +shutil.move(src, dst)

Calling another SCT function

You may see the pattern below:

sct_register_multimodal.main(args=['-i', 'template2anat.nii.gz',
                                   '-d', t2star_fname ,
                                   '-iseg', './label/template/PAM50_levels.nii.gz'
                                   '-dseg', t2star_sc_seg_fname,
                                   '-param', 'step=1,type=seg,algo=syn,metric=MeanSquares,iter=5:step=2,type=im,algo=slicereg,metric=MeanSquares,iter=5'])
sct_concat_transfo.main(args=['-w', 'warp_template2anat.nii.gz,{0}'.format(multimodal_warp_name),
                              '-d', t2star_fname,
                              '-o', total_warp_name])

This is better than the subprocess call, but is not ideal.

Avoid this and instead import the functionality the proper way:

  • If a script provides a useful core functionality, this means it should be moved to the API so that it can be used by other consumers.

  • I a script provides a useful high-level functionality not relevant to the API, import that specific functionality instead of calling script.main().

Clone this wiki locally