Python library description

A collection of Python programs to process fMRI and PET medical imaging data for research purposes. The programs were written for the Waisman Brain Imaging Lab, University of Wisconsin-Madison.

Descriptions are provided for the following Python libraries:

If you are interested in using this software, contact Terry Oakes at: troakes - at - wisc.edu


--- Library Description for coreg_wrappers.py ---

Full name: /apps/dev/python_apps/coreg_wrappers.py

Purpose:
Scripts to perform basic coregistration using FSL, AIR. The scripts serve as wrappers, choosing standard default options to facilitate incorporation into larger programs.

Library Functions:

  1. air_affine AIR coregistration using an affine body (12 parameter) fit.
  2. air_dir_define Define directory where AIR executables are located.
  3. air_rigid_body AIR coregistration using a rigid body (6 parameter) fit.
  4. air_warp AIR coregistration using a warp (many parameter) fit.
  5. flirt_coreg Use FSL's FLIRT to coregister 3D image files with standard parameters.
  6. mri2mni Skull-strip, segment, bias-correct, and coregister a T1-MRI brain scan into MNI space. T2 and mask images are optional.
Abstract:
The programs currently supported include AIR and FLIRT. For each program, this library contains specific functions for rigid-body (6-parameter), affine (~12 parameter), and (for AIR) warp (many parameter) coregistrations. This set of library routines is meant to codify the most useful, general, and most commonly used options for each of the coregistration programs. This is especially useful for AIR, where the alignment and reslice operations are quite distinct.
If you need to change advanced parameters which are not available through these functions, you can use the corresponding function as the basis for either writing your own new function, or simply calling the coregistration program directly from the command line or from another script.
History:
Written 2006 by Terry Oakes at UW-Madison Waisman Center.


air_affine in coreg_wrappers.py

Purpose:
Use AIR to coregister an image file to a target file using an affine body (12 parameter) fit.
Calling sequence:
air_affine fn_obj fn_tgt [t2 t1 verbose]
Returns:
1 if succesful
0 if unsuccesful
History:
@ Terry Oakes 2006
Written 2006-01-31 by Terry Oakes.


air_dir_define in coreg_wrappers.py

Purpose:
Define directory where AIR executables are located. Consolidate location into one place, accessible by all AIR python wrappers.
Calling sequence:
air_rigid_body fn_obj fn_tgt [t2 t1 verbose]
Returns:
string containing name of AIR directory.
History:
@ Terry Oakes 2006
Written 2006-01-31 by Terry Oakes.


air_rigid_body in coreg_wrappers.py

Purpose:
Use AIR to coregister an image file to a target file using a rigid body (6 parameter) fit.
Calling sequence:
air_rigid_body fn_obj fn_tgt [t2 t1 verbose]
Returns:
1 if succesful
0 if unsuccesful
History:
@ Terry Oakes 2006
Written 2006-01-31 by Terry Oakes.


air_warp in coreg_wrappers.py

Purpose:
Use AIR to coregister an image file to a target file using a warp (many parameter) fit.
Calling sequence:
air_rigid_body fn_obj fn_tgt [t2 t1 m1 m2 verbose]
Returns:
1 if succesful
0 if unsuccesful
History:
@ Terry Oakes 2006
Written 2006-01-31 by Terry Oakes.


flirt_coreg in coreg_wrappers.py

Purpose:
Use FSL's FLIRT to coregister a 3D image file to a target file using one of the following:

Calling sequence:
flirt_coreg fn_obj fn_tgt [dof 6|12 omat 0|1 clean 0|1 verbose 0|1]
Parameters:

Returns:
array with coregistered filename and matrix filename if succesful, 0 if unsuccesful
History:
@ Terry Oakes 2006
Written 2006-01-26 by Terry Oakes.


mri2mni in coreg_wrappers.py

Purpose:
Skull-strip, segment, bias-correct, and coregister a T1-MRI brain scan into MNI space.
Abstract:
The target is a suitable template in MNI space (e.g. avg152T1.img), and an affine (12-parameter) fit is performed. A rough coregistration is first performed, then the brain is skull-stripped and corrected for inhomogeneity artifacts, and a the skull-stripped brain is then coregistered to the template. Finally, the transform is applied to the original brain volume, yielding an unmasked coregistered brain.
If an accurate mask exists, this will usually produce better results than relying on the BET program, which, while accurate, cannot yet do as well as manual whole-brain segmentation.
Calling sequence:
mri2mni fn_obj [fn_mask fn_T2 loptop 0|1 clean 0|1 test 0|1 verbose 0|1]
Parameters:

Example:
fn_bet = coreg_wrappers.mri2mni(fn_mri, fn_mask, verbose=1)
Returns:
array with coregistered filename and matrix filename if succesful.
0 if unsuccesful.
History:
@ Terry Oakes 2006
Written 2006-02-09 by Terry Oakes.


--- Library Description for image_manip.py ---

Full name: /apps/dev/python_apps/image_manip.py

Purpose:
Collection of scripts to perform basic 3D image processing.
Abstract:
This set of library routines is meant to codify the most useful, general, and most commonly used options for basic 3D and 4D image pre-processing. If you need to change advanced parameters which are not available through these functions, you can use the corresponding function as the basis for either writing your own new function, or simply calling the program directly from the command line or from another script. Many of these programs call IDL subroutines. You will need to have IDL installed for those routines to work properly.

Library functions:

  1. convert_to_analyze Converts a 3D or 4D image file to ANALYZE.
  2. fn_add_suffix Add a suffix to a filename before the extension
  3. fsl_name_pbmaps for FSL probability maps, determine which tissue class each represents.
  4. idl_command Process commands for IDL from individual python functions.
  5. is_analyze Returns a 1 if image file is ANALYZE format, 0 otherwise.
  6. is_voi Returns a 1 if image file is Spamalize-VOI format, 0 otherwise.
  7. loptop Sets top 0.5% pixels to value of 99.5% percentile's value for better dynamic range.
  8. rename_anlz Rename an ANALYZE-7.5 file (both .hdr and .img).
  9. spam_dir_define Define base directory where Spamalize IDL program files are located.
  10. sum_3d_files Sum 2 or more same-size 3D image files, write out sum-image.
  11. sum_frames Makes a 3D sum-image by summing a 4D file framewise.
History:
Written 2006 by Terry Oakes, UW-Madison Waisman Center.


convert_to_analyze in image_manip.py

Purpose:
Wrapper for IDL/Spamalize program "spam_convert_format", which converts 3D and 4D image files from a variety of formats to ANALYZE-7.5 format.
Abstract:
This function creates a text file that can be used as an IDL startup file. The IDL commands needed to call spam_convert_format are in this text file. IDL is used in order to take advantage of the Spamalize "EZ_Writer" programs which can read a variety of off-beat image file formats.
Parameters:

Returns:
list of filename(s) of new ANALYZE file if succesful
0 if unsuccesful
History:
@ Terry Oakes 2006. Written 2006-01-31 by Terry Oakes.


fn_add_suffix in image_manip.py

Purpose:
Add a suffix to a filename before the extension.
Abstract:
Example: Indicate a file is a sum-image by changing the name from e.g.:
/dir_name/myfile_dyn.img
to e.g.:
/dir_name/myfile_dym_sum.img
You should include a leading or trailing underscore or dot if desired- the exact string you pass will be added.
Parameters:

fsl_name_pbmaps in image_manip.py

Purpose:
Deterimnes which tissue type (CSF, GM, WM) the tissue probability maps from FSL's MFAST refer to. The naming scheme is not always consistent, so some extra smarts need to be thrown at the problem.

!!!! This program is not fully implemented yet !!!!


idl_command in image_manip.py

Purpose:
Process commands for IDL from individual python functions. Centralizes code for calling IDL into a single program.
Abstract:
This program consolidates chores for calling an IDL program. Most of these IDL programs write a new image file after some manipulation. This program checks to make sure the user can write to the output directory, which is usually the same directory as the input file. Then this program takes care of starting up IDL, calling the desired program, and checking to make sure the desired output was produced.

Parameters:

Returns:
list of filenames produced (corresponding to "fn_markers")
1 if there are no fn_markers.
0 if an error.
Example:
res = image_manip.idl_command(commands, fn_markers)
History:
Written 2006-02-06 by Terry Oakes.


is_analyze in image_manip.py

Purpose:
Checks to see if a string refers to a valid, existing ANALYZE-7.5 formatted image file.
Abstract:
Input filename to test should have full path + filename, including extension (e.g. ".img" or ".hdr"). This program checks for the existence of both the *.img and the *.hdr file.
Returns:
a 1 if image file is ANALYZE format, 0 otherwise.
Example:
res = image_manip.is_analyze(fn)
History:
Written 2006-01-31 by Terry Oakes.


is_voi in image_manip.py

Purpose:
Checks to see if a file is a "voi" file, created by BrainMaker.

Returns:

Example:
res = image_manip.is_voi(fn)
History:
Written 2006-03-10 by Terry Oakes.


loptop in image_manip.py

Purpose:
Lop an image file: set the top 0.5% of pixel values to the 99.5 percentile value.
Abstract:
In many MRI images a small number of pixels have values which occupy most of the dynamic range. For T1 images, these pixles rarely contain brain matter. By "lopping" these values or setting them to a single lower value which is still larger than the highest white matter value, a large improvement in display properties is realized. Also, for processing operations that create or use a histogram of the data (segmentation, mutual information coreg) the brain tissue of intrerest is spread into more of the useful histogram bins.
Parameters:

Returns:
filename of new ANALYZE lopped image file if succesful.
0 if unsuccesful.
History:
@ Terry Oakes 2006
Written 2006-03-10 by Terry Oakes.


rename_anlz in image_manip.py

Purpose:
Rename .hdr and .img files from an ANALYZE-7.5 file using passed string as a basis.
Abstract:
Performs the equivalent of unix "mv" on .img and .hdr files. Bo-coo permission checking. The file to be renamed, "fn_old" must exist and user must have appropriate permissions for all delete, move operations. Consolidates frequently used code.
Parameters:

Returns:
New filename "/fullpath/fn_new.img" if all went as planned,
a string containing zero "0" otherwise.
History:
@ Terry Oakes 2006
Written 2006-03-24 by Terry Oakes.


spam_dir_define in image_manip.py

Purpose:
Define base directory where Spamalize IDL program files are located. Consolidate location into one place.
Returns:
string containing name of Spamalize directory.
History:
@ Terry Oakes 2006
Written 2006-01-31 by Terry Oakes.


sum_3d_files in image_manip.py

Purpose:
Sum 2 or more same-size 3D image files, write out sum-image.
Abstract:
This function creates a text file that can be used as an IDL startup file. The IDL commands needed to call spam_sum_img_file are in this text file. IDL is used in order to take advantage of the Spamalize "EZ_Writer" programs which can read a variety of off-beat image file formats. The IDL sum-program will overwrite an existing sum-file with the same output name.
N.B.: The IDL code could be replaced by e.g. FSL's "avwmaths" -add.
Parameters:

Returns:
filename of new ANALYZE sum-image file if succesful (based on first input filename)
0 if unsuccesful
History:
@ Terry Oakes 2006
Written 2006-01-31 by Terry Oakes.


sum_frames in image_manip.py

Purpose:
Sum a 4D file across frames, write out a new 3D sum-image file.
Abstract:
This function creates a text file that can be used as an IDL startup file. The IDL commands needed to call spam_sum_img_file are in this text file. IDL is used in order to take advantage of the Spamalize "EZ_Writer" programs which can read a variety of off-beat image file formats. The IDL sum-program will overwrite an existing sum-file with the same output name.
N.B.: The IDL code could be replaced by e.g. FSL's "avwmaths" -roi, -mas, -add.
Parameters:

Returns:
filename of new ANALYZE sum-image file if succesful
0 if unsuccesful
History:
@ Terry Oakes 2006
Written 2006-01-31 by Terry Oakes.


--- Library Description for utils_tro.py ---

Full name: /apps/dev/python_apps/utils_tro.py

Purpose:
Collection of utility programs written in Python.

Library Functions:

  1. timestamp Returns a string timestamp formatted like: yyyymmdd_hhmmss
  2. describe_local_python Prints description of local python libraries and their subroutines.
  3. file_list Returns a list of files corresponding to a variety of search criteria. Useful for pipelines.
  4. is_file Determines if an item is a string refering to a valid file (i.e. the file exists on the disk system).
History:
Written by Terry Oakes at UW-Madison Waisman Lab, 2005-present.


timestamp in utils_tro.py

Purpose:
Function that returns a string timestamp formatted like:
yyyymmdd_hhmmss
with zero-padding of each element, if needed, to maintain a consistent format.
Returns:
a string formatted like: yyyymmdd_hhmmss
Example:
ts = utils_tro.timestamp()
-> 20060421_083425
History:
Written 2005-04-12 by Terry Oakes.


describe_local_python in utils_tro.py

Purpose:
Creates a description of local python libraries and their subroutines by extracting comments at the beginning of each function. Can be piped to an HTML generator to include info in a web-page.

[Note- this web-page was created using "utils_tro.describe_local_python". About 10 minutes of extra work was needed to clean up the text, insert a few hyperlinks, etc.]

Abstract:
This program introduces a minimal amount of text formatting. Emphasis is more on quick functionality than pretty results. I got it to where it worked, then stopped.

This program contains a list of known local Python libraries. Information about the libraries and constituent functions can be displayed if that information is contained in the files and if coventions for describing the program are followed. There are three levels of detail:

  1. verbose = 0: (default) Prints a brief top-level description of the library, followed by a 1-line description of each of the constituent functions;
  2. verbose = 1: Prints information for "verbose=0", plus the entire top-level comments for the library.
  3. verbose = 2: Prints information for "verbose=1", plus the initial comment block for each subroutine.

The comments for this program (which you are reading now) serve as a template. The following assumptions are made regarding the initial comment blocks:

  1. Functions are preceded by a block of comments. The first line contains an obvious section seperator, such as '----' or '====' (but usually ~80 characters wide).
  2. The name of each function is listed alone at the beginning of its comment block.
  3. A brief description (1-2 lines) for each function is preceded by a line containing the single word, "Purpose:". The "Purpose" section should come immediately after the name of the function.
  4. The top-level comments for the entire library should be at the top of the file. The initial library comment block should contain a "Purpose" followed by a list of all subroutines. This list should be immediately preceded by a line containing the single phrase, "Library Functions:". Any initial Python statements (e.g. "import") must come after this comment block.

Additional information can be placed into the comment block for both the top-level library as well as for each function. Suggested headings include:

Parameters:

Output:
Prints a list of libraries and their constituent functions to the screen.

Returns:
1 if all goes well, 0 otherwise.
Example:
res=utils_tro.describe_local_python(verbose=0, fn_out=1)
History:
Written 2006-03-16 by Terry Oakes.


file_list in utils_tro.py

Purpose:
Returns a list of files corresponding to a variety of search criteria. Facilitates pipeline construction.
Abstract:
This is a general purpose utility to make it easy to find files. It is meant to consolidate frequently used code. It is aimed at batch-processing programs that need to find one or more files in a directory tree based on a few simple criteria. Three features make this program especially handy for use in data processing pipelines:

  1. It can process a variety of possible filenames in different contexts, e.g. single files, wildcards, or directories.
  2. It has a uniform output which is always a list, even if it is an empty list.
  3. It will not crash if an error is encountered (e.g. a filename does not exist).

Wildcards can be either "*" or "?", with standard unix usage. All filenames (including directory names) should include the full path.
The input to this program can be any of the following:

  1. A directory: All files within the directory will be returned.
  2. A directory+wildcard, e.g. /fullpath/*.img
  3. Single file: verifies that file exists and can be read by user.
  4. List of files: verifies that all files exist and can be read.

If a list is provided, a 0 is inserted in the list for each of the explicitly named files that are not readable files, and the caller should check for this.


Returns:
A list of files that correspond to the criteria, or "0" if none found or the file or directory does not exist. N.B. a list is always returned, even if the input is a single string or invalid.
Example:
files = utils_tro.file_list('/study/mystudy/sub*.img')
History:
Written 2005-09-29 by Terry Oakes.


is_file in utils_tro.py

Purpose:
Function to determine if an object is a string refering to a valid file (i.e. the file exists on the disk system).
Abstract:
This program provides a wrapper for "os.path.exists(fn)", which is quite particular about the types of objects it wants to consider. For instance, a crash results if the possible filename is a list with one or more elements, if it is not a string, (such as the number 0), etc. This routine lets you pass pretty much any ol' object to see if it is a valid filename. If the passed object is a list, all of the elements must be strings to examine any of them. An array of 1's or 0' are returned with each value corresponding to each putative filename. The file (with full directory path) must contain at least 4 characters.
Returns:
1 if the file exists
0 if the file does not exist or the object is not a valid filename.
Example:
file_exists = utils_tro.is_file(fn)
History:
Written 2005-04-12 by Terry Oakes.


--- Library Description for fmri_tools.py ---

Full name: /study/fMRI_tools/software/python/fmri_tools.py

Purpose:
Collection of Python programs for fMRI Software Tools comparisons.

Library Functions:

  1. air_params Reads an AIR .air file, returns translation & rotations.
  2. air_write_mc_series Write motion-correction .air params for a fMRI series.
  3. batch_seg Top-level function to segment anatomic images from all subjects.
  4. coreg_n_seg Pipeline to coregister and segment a T1 MRI brain scan into MNI space.
  5. find_anat_4_seg Returns a list of study files needed to perform segmentation.
History:
@ Terry Oakes 2004
Written 2004-03-30 by Terry Oakes.


air_params in fmri_tools.py

Purpose:
Extract coregistration parameters from an AIR .air-file
Abstract:
This program assumes a rigid-body rotation only!
Returns:
3x2 array of [[translations], [rotations]]. Translations are in mm, rotations are in degrees(?).
Example:
params = fmri_tools.air_params(/fullpath/file.air, print_flag=1)
History:
Written 2004-04-02 by Terry Oakes.
CHANGES 041216 by k.w from lines 88-102, left the old code in but commented out


air_write_mc_series in fmri_tools.py

Purpose:
Write Motion Correction (mc) .air params for a fMRI series.
Returns:
1 if succesful
0 if there was a problem.


batch_seg in fmri_tools.py

Purpose:
Top-level function to segment anatomic images from all subjects in a designated study.

Abstract:
This program calls a subroutine (coreg_n_seg) that performs the segmentation and registration for each subject. Currently the subroutine uses FSL's FLIRT, FAST, and MFAST programs.

Returns:
1 if succesful
0 if there was a problem.
Calling sequence:
import fmri_tools
fmri_tools.batch_seg([verbose])


coreg_n_seg in fmri_tools.py

Purpose:
Pipeline to coregister and segment a T1 MRI brain scan into MNI space.
Abstract:
This is a top-level pipeline script to coregister a single subject's MRI data into MNI space. Once there, it is segmented into CSF, WM, and CSF. The target is a suitable template in MNI space (e.g. avg152T1.img), and an affine (12-parameter) fit is performed. The following steps are performed:
  1. Preprocessing:
    1. loptop of T1 image
    2. if mask file is a VOI file, convert to ANALYZE.
  2. Brain Extraction (skull stripping). If a mask file was passed, the T1 is masked. If not, BET is called. Output: BET brain.
  3. Bias Correction using FAST.
  4. Coregister T2 (if present) to the T1 image (in original space). Default assumes a T2, but some subjects do not have one.
  5. Coregistration to MNI space
    1. 12-parameter affine to skull-stripped T1avg152.
    2. reslice T1, T2 images into MNI space in 1x1x1, 2x2x2 formats.
  6. Segmentation
    1. use MFAST if T2 available
    2. use FAST if no T2.
    3. Output (see below)

A rough coregistration is first performed, then the brain is skull-stripped and corrected for inhomogeneity artifacts, and a the skull-stripped brain is then coregistered to the template. Finally, the transform is applied to the original brain volume, yielding an unmasked coregistered brain.

Parameters:

Example:
fn_bet = coreg_wrappers.mri2mni(fn_mri, fn_mask, -v)

Output: The following data in MNI tempalte space are written to files:

Returns:
array with coregistered filename and matrix filename if succesful
0 if unsuccesful
History:
@ Terry Oakes 2006. Written 2006-02-09 by Terry Oakes.


find_anat_4_seg in fmri_tools.py

Purpose:
Find files needed to perform segmentation on anatomical images.
Abstract:
The segmentation algorithms need a T1 image (FAST) and MFAST can also make use of a T2 image. Both of these programs work better if the brain is closely and accurately masked (cropped) so that only brain tissue is considered. Thus, a mask-file is searched for also, as this is more accurate than an automated mask (e.g. from BET).
If there is no a T2 image, the original data directory for the subject is searched and if the T2 image is found, it is copied into the corresponding "coreg" directory for the subject.
If there are multiple VOI files in a subject's directory, the latest one is assumed to contain the most correct VOI.
Returns:
[6 x n_sub] string array (list) of filenames. Each column corresponds to:
1) Subject number
2) /fullpath/T1High.img
3) /fullpath/T1High.hdr
4) /fullpath/T2.img
5) /fullpath/T2.hdr
6) /fullpath/XXX.voi
Returns a 0 of unsuccesful.
Example:
fn_list = fmri_tools.find_anat_4_seg()
History:
Written 2006-03-20 by Terry Oakes.