Releasing pyAFQ 0.1
Just as the year started, and after several years of slow development, we finally released a version 0.1 of pyAFQ. The core functionality of this software is to segment tractography solutions into bundles of streamlines that represent major brain tracts, such as the corticospinal tract, which connects the primary motor cortex with the spinal cord, or the arcuate fasciculus, which connects the temporal lobe with the frontal lobe and plays an important role in language functions. The algorithm for bundle segmentation is based on previous work by Jason Yeatman that was published a while ago. A large part of the motivation for reimplementing these ideas in Python is that this allows us to take advantage of the developments we are making in DIPY. For example, it should allow us to use the large collection of diffusion MRI reconstruction algorithms implemented in DIPY. The core segmentation algorithm, using a strategy that combines waypoint ROIs through which each streamline in a bundle must cross and a probabilistic atlas, was implemented over a rather long period of time, and tested on some sample datasets, as well as on the Human Connectome Project dataset. We had initially implemented a command-line interface that used argparser to parse input arguments, but there are many options that can be used in modeling the diffusion in each voxel, using these models in tractography and in creating scalar values, and in the manner in which segmentation is executed (e.g., whether or not and how to clean a bundle after segmentation, to produce a more compact and coherent bundle that conforms with our idea of a tract). This made the CLI rather clunky. To deal with this, we now use an additional configuration file that customizes each one of these steps. This is a TOML file that follows a particular division into sections, based on stages of the analysis with a set of key-word arguments in each section. One nice thing is that introspection allows us to set defaults once in the executing function (for example, in a tracking function) and then use a simple introspection pattern (thank you, SO!) to read out these values and replace them only if they are defined in the configuration file. This should hopefully make a rather complicated API, with multiple steps of analysis and lots of knobs to twiddle, rather straightforward to control and run.