medical image analysis using s4 classes and methods · medical image analysis using s4 classes and...
TRANSCRIPT
7/1/2011
1
Medical Image Analysis
Using S4 Classes and
Methods
Brandon Whitcher
Mango Imaging Group
Mango Solutions UK
2
Acknowledgements
• S4 Classes and Methods
– Slides by F. Leisch and P. Murrell
– Software for Data Analysis by J. Chambers
– R Programming for Bioinformatics by R. Gentlemen
– R packages• nlme• kernlab• EBImage
7/1/2011
2
3
OOP and Classes in R
• One identifies real objects, and the operations on them, that are interesting.– These operations can be systematically implemented.
• A basic principle (hope) is that by faithfully representing the objects we get easier-to-implement functions.
• A class is an abstract definition of a concrete real-world object.
• A class system is a software infrastructure that is designed to help construct classes and to provide programmatic support for dealing with classes.
4
Why (S4) Classes for Medical
Imaging Data?
• Context of imaging data
• Interface with data standards and third-party
software
• Numerous processing steps involved
– Multiple information sources
• Audit trail (internal and external agencies)
• Too easy to make mistakes!
7/1/2011
3
5
Data Analysis Pipeline
Pre-processingMathematical
Modelling
Statistical
Analysis
Data
Results
Motion correction
Warping
Co-registration
Model building
Parameter
estimation
Test statistics
p-values
Multiple
comparisons
6
Medical Imaging Data
Slice Thickness; e.g. 5mm
Spatial Resolution
Size = X × Y; e.g. 256×256
X
Y
e.g. 0.4mm
Chosen parameters depend
on many factors: application,
scanner, local practice,
radiologist preferences, etc.
X
Z
7/1/2011
4
7
Composition of Structural Data
convert
DICOM
X
Y
Z
NIfTI 3D
8
Composition of Dynamic Data
XY
Z
t = 1
XY
Z
t = T
•••
•••
•••
NIfTI 4D
7/1/2011
5
9
The niftiniftiniftinifti Class
• Inherits from class arrayarrayarrayarray• Contains 44 “slots” (not counting .Data)
– both numeric and character strings [348 bytes]
• Also created function nifti() for user-defined slots.• Similar class has been defined for ANALYZE data.
setClass(“nifti”, representation(“sizeof_hdr”=“numeric”, “data_type”=“character”, ...),
prototype(“sizeof_hdr”=348,“data_type”=“”,...),
contains=“array”)
10
Method “show” for niftiniftiniftinifti Class
setMethod(“show”, “nifti”, function(object) {cat(“NIfTI-1 file format”, fill=TRUE)cat(...)cat(...)
})
> ffdNIfTI-1 formatType : niftiData Type : 4 (INT16)Bits per Pixel : 16Slice Code : 0 (Unknown)Intent Code : 0 (None)Qform Code : 1 (Scanner_Anat)Sform Code : 0 (Unknown)Dimension : 64 x 64 x 21 x 180Pixel Dimension : 4 x 4 x 6 x 3Voxel Units : mmTime Units : sec
7/1/2011
6
11
Validity Checking for niftiniftiniftinifti Class
setValidity(“nifti”, function(object) {retval <- NULL...if (object@”sizeof_hdr” != 348)
retval <- c(retval, “sizeof_hdr != 348”)if (!object@datatype %in% c(2^(1:11),768,1280,1536,1792))
retval <- c(retval, “datatype not recognized”)...if (!all(object@”dim_”[indices] == dim([email protected])))
retval <- c(retval, “dim/img mismatch”)...if (is.null(retval))
return(TRUE)else
return(retval)})
12
Manipulation of Slots
• The nifti header allows limited text information
– descrip (80 characters) and aux_file (24 characters)
– Replacement functions
Acessor functions
> aux.file(mniLR)[1] "none "> descrip(mniLR)[1] "FSL3.2beta"
SlotsSlotsSlotsSlots
> mniLR@”aux_file”[1] "none "> mni@”descrip”[1] "FSL3.2beta"
setMethod(“descrip”, “nifti”, function(object) { object@descrip })setGeneric(“descrip<-”, function(x, value) { standardGeneric(“descrip<-”) })setReplaceMethod(“descrip”, “nifti”,
function(x, value) {x@descrip <- valuex
})
7/1/2011
7
13
Additional Methods
• readNIfTI() and writeNIfTI()– IO functions for NIfTI data (100% R)
– Affine transformations
• image()– Forces S3 method into proper generic method
– Equivalent to a “lightbox” representation
• overlay()– Essentially, the image function for two input arrays
• orthographic()– 2×2 matrix of plots: coronal, sagittal, axial
– Utilizes “pixel dimension” slot
14
ffd <- readNIfTI(“filtered_func_data.nii.gz”)image(ffd, zlim=range(ffd)) # Figure 1zstat1 <- readNIfti(“zstat1.nii.gz”)overlay(ffd, ifelse(abs(zstat1) > 5, zstat1, NA), zlim.x=range(ffd)) # Figure 2
7/1/2011
8
15
mni <- readNIfTI(“avg152T1_LT_nifti.nii.gz”)orthographic(mni, zlim=range(mni))> mniLRNIfTI-1 formatType : niftiData Type : 2 (UINT8)Bits per Pixel : 8Slice Code : 0 (Unknown)Intent Code : 0 (None)Qform Code : 0 (Unknown)Sform Code : 4 (MNI_152)Dimension : 91 x 109 x 91Pixel Dimension : 2 x 2 x 2Voxel Units : mmTime Units : sec
16
Coercion and Extensions
•• Coercion Coercion
–– Implicit since Implicit since niftinifti class is built on the class is built on the arrayarray class.class.
–– But... it will fail But... it will fail validObjectvalidObject()()..
•• Allow extensions via the NIfTIAllow extensions via the NIfTI--1.1 mechanism.1.1 mechanism.
–– Define new class Define new class ““niftiExtensionniftiExtension””–– Implement full audit trailImplement full audit trail
•• XML document XML document –– library(“XML”)library(“XML”)
> A <- array(1:8^3, rep(8,3))> B <- as(A, “nifti”)> dim(B)[1] 8 8 8> B@”dim_”[1] 0 0 0 0 0 0 0 0
7/1/2011
9
17
Conclusions
• S4 classes are powerful
– Robust framework
– Generics and methods
– Validity checking
– Inheritance
• ... and difficult
– Documentation (lack thereof)
– Examples (lack thereof)
– Slower than S3 (?)
18
Todo List
• Integrate S4 class into image analysis functions.
– Modification of .Data causes modification of slot(s)
• Use cniftilib to be 100% NIfTI compliant
– Rniftilib by Oliver Granert <[email protected]>
• Medical_Imaging task view
– Seven packages in current version.
7/1/2011
10
19
Extra Slides
20
Data Formats
• Digital Imaging and Communications in Medicine (DICOM); 1992.– Binary file with a dynamic header description.
• ANALYZE™ 7.5 File Format; 199?.– An image (.img) file
– A header (.hdr) file [348 bytes]
• Neuroimaging Informatics Technology Initiative (NIfTI); 2004.– Adapted from ANALYZE 7.5
– Dual file (.hdr & .img)
– Single file (.nii) [348+ bytes]