Best Practices

We at DCAN Labs highly value creating code and workflows that are able to be reused and shared with other institutions. This means that we should be following best practices in order to make it easy for someone outside of our lab to use and understand our code. Below is some information about NMIND, which is a great place to start for exposure to best coding practices in the neuroimaging field. Below are some common best practices within DCAN labs.

NMIND Workflow

When code is developed without keeping best practices and standards in mind, challenges can arise when someone who didn't develop the code tries to use it. Some challenges that can come out of this is that the code if not fully developed/bullet-proofed, it has poor documentation, there are hard-coded paths, and it's overall not designed to be reused. To learn more about the NMinD programming recommendations, visit this page.

In an ideal world, code should be:

  • Fully documented

  • Include descriptions and examples

  • Able to run on any platform

  • Modularized, with modular elements able to be reused

  • Containerized at its final stage

In order to try to fit into this ideal world, we try to follow the NMIND coding standard when developing code. When developing or reviewing code, the goal is to have the codebase Bronze certified.

A Bronze certification broadly entails the following:

  • Documentation that is up to date

  • Documentation about usage, installation, dependecies, and expected outputs

  • Version control

  • License and readme

  • Issue tracking (typically through GitHub)

  • Some sort of testing

You can find all three levels of NMIND certifications here.

Logging Codebase Changes

Record Change Dates - The following is an example of how to do this:

author: Audrey Houghton
created on: 11/25/2023
last modified: 11/30/2023
by whom: Audrey Houghton

Commit Often - Make sure that you are regularly pushing your changes to a branch on GitHub with concise but descriptive commit messages.

Error / Out Logging

  • The more descriptive you can make your codebase's logs, the better.

Commenting

  • At the top of each script within a given repository, describe what that script is doing.
  • At the beginning of each function, define the purpose of the function, what its inputs are, and what its outputs are.

Obscuring Filepaths

It's generally considered best practice to not share full filesystem paths on public GitHub repositories. For repositories that have file paths in the code, we therefore recommend using a config.json file when necessary to obscure file paths from your local computer, MSI, etfc:

Within your local repository, create a config.json file that contains, for example, a tier1 path you don’t want to make available on GitHub:

{
"tier1_path": "/your/file/path"
}

Create a file called .gitignore and add config.json so that you or other users don't accidentally publish their local config.json to the public repository (this can of course include other files/folders to ignore, such as logs):

# ignore config.json
config.json

Grab the path within your python script using the json module:

import json

with open("config.json") as json_data_file:
    data = json.load(json_data_file)
tier1_path = data['tier1_path']

This way, instead of having the file path visible in the code, you are pulling it from a config file that isn't public for others to see.