Skip to content

Commit

Permalink
updated all of it
Browse files Browse the repository at this point in the history
  • Loading branch information
muschellij2 committed Jun 21, 2019
2 parents ac24599 + 75265c0 commit d59ef32
Show file tree
Hide file tree
Showing 22 changed files with 2,254 additions and 1,807 deletions.
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
^.*\.Rproj$
^\.Rproj\.user$
^appveyor.yml$
^\.covrignore$
^standalone$
^revdep$
2 changes: 2 additions & 0 deletions .covrignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
src/zlib
src/znzlib
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ script:
- cd standalone && make clean && make CC="$(R CMD config CC)" CXX="$(R CMD config CXX)" && ./nii_info ../inst/extdata/example.nii.gz

after_success:
- Rscript -e 'covr::coveralls(line_exclusions=as.list(list.files(file.path("src",c("zlib","znzlib")), full.names=TRUE)))'
- Rscript -e 'covr::coveralls()'
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: RNifti
Version: 0.10.0
Date: 2018-10-19
Version: 0.11.0
Date: 2019-06-17
Title: Fast R and C++ Access to NIfTI Images
Authors@R: c(person("Jon","Clayden",role=c("cre","aut"),email="code@clayden.org"),
person("Bob","Cox",role="aut"),
Expand All @@ -23,4 +23,4 @@ License: GPL-2
URL: https://github.com/jonclayden/RNifti
BugReports: https://github.com/jonclayden/RNifti/issues
Encoding: UTF-8
RoxygenNote: 6.1.1
RoxygenNote: 6.1.0
1 change: 1 addition & 0 deletions Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ FILE_PATTERNS = "NiftiImage.h"
RECURSIVE = NO
GENERATE_LATEX = NO
JAVADOC_AUTOBRIEF = YES
EXCLUDE_SYMBOLS = internal
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

S3method("$",niftiImage)
S3method("$<-",niftiImage)
S3method("[",internalImage)
S3method("[<-",internalImage)
S3method("dim<-",internalImage)
S3method("pixdim<-",default)
S3method("pixunits<-",default)
Expand Down
27 changes: 27 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,33 @@ Significant changes to the RNifti package are laid out below for each release.

===============================================================================

VERSION 0.11.0

R interface

- It is now possible to index directly into objects of class `internalImage`,
meaning that individual elements or arbitrary blocks may be converted to R
vectors or arrays, without needing to convert everything. This can save
significant amounts of memory for large images.

API changes

- This release introduces the `NiftiImageData` C++ class as the main way to
encapsulate the data in a NIfTI image. This class handles datatypes and data
scaling, and provides indexing, iterators and other niceties. The doxygen
documentation has full details.
- As a result of this new introduction, the templated `getData()` method within
`NiftiImage` is deprecated in favour of `data()`, which returns a (constant
or mutable) object of class `NiftiImageData` rather than a standard `vector`.

Bug fixes

- The slope and intercept fields in `nifti` objects (from the `oro.nifti`
package) are now ignored, since that package does its own scaling. (Reported
by John Muschelli, issue #13.)

===============================================================================

VERSION 0.10.0

R interface
Expand Down
79 changes: 76 additions & 3 deletions R/image.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@
#' not be changed.
#'
#' @param x An \code{"internalImage"} object.
#' @param value Not used. Changing the dimensions of an internal image is
#' invalid, and will produce an error.
#' @param ... Additional parameters to methods. Currently unused.
#' @param value Not used. Changing the dimensions of (or data in) an internal
#' image is invalid, and will produce an error. Convert to an array first.
#' @param i,j Index vectors. May be missing, which indicates that the whole of
#' the relevant dimension should be obtained.
#' @param ... Additional parameters to methods. Only used for additional
#' indices.
#' @param drop If \code{TRUE} (the default), unitary indices in the result will
#' be dropped. This mirrors the behaviour of standard array indexing.
#'
#' @author Jon Clayden <code@@clayden.org>
#' @rdname internalImage
Expand All @@ -34,6 +39,74 @@ as.array.internalImage <- function (x, ...)
return (.Call("pointerToArray", x, PACKAGE="RNifti"))
}

#' @rdname internalImage
#' @export
"[.internalImage" <- function (x, i, j, ..., drop = TRUE)
{
nArgs <- nargs() - as.integer(!missing(drop))
if (nArgs < 2)
return (as.array(x))

# Evaluate the indices, replacing missing values with -1
if (nArgs == 2)
indices <- substitute(list(i))
else
indices <- substitute(list(i,j,...))
present <- (sapply(indices, as.character)[-1] != "")
if (any(!present))
indices[which(!present)+1] <- -1
indices <- eval(indices, parent.frame())
lengths <- rep(-1L, nArgs - 1)
lengths[present] <- sapply(indices[present], length)

dims <- dim(x)
data <- NULL

if (all(lengths == -1))
return (as.array(x))
else if (any(lengths == 0))
return (numeric(0))
else if (nArgs == 2 && present[1])
{
if (is.matrix(i))
{
if (ncol(i) != length(dims))
stop("Index matrix should have as many columns as the image has dimensions")
strides <- c(1, cumprod(dims)[-length(dims)])
locs <- apply(i, 1, function(n) sum((n-1)*strides) + 1)
}
else
locs <- as.integer(i)

return (.Call("indexVector", x, locs, PACKAGE="RNifti"))
}
else if (nArgs != length(dims) + 1)
stop("Number of indices (", nArgs-1, ") not equal to the dimensionality of the image (", length(dims), ")")
else
{
data <- .Call("indexList", x, lapply(seq_along(indices), function(l) {
if (length(indices[[l]]) == 1 && indices[[l]] == -1)
seq_len(dims[l])
else if (is.logical(indices[[l]]))
which(indices[[l]])
else
indices[[l]]
}), PACKAGE="RNifti")
dim(data) <- ifelse(present, lengths, dims)
}

if (drop)
data <- drop(data)
return (data)
}

#' @rdname internalImage
#' @export
"[<-.internalImage" <- function (x, i, j, ..., value)
{
stop("The data in an internal image cannot be changed - convert to array first")
}

#' @export
print.niftiImage <- function (x, ...)
{
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,12 @@ This arrangement is efficient and generally works well, but many R operations st

## API

It is possible to use the package's NIfTI-handling code in other R packages' compiled code, thereby obviating the need to duplicate the reference implementation. Moreover, `RNifti` provides a C++ wrapper class, `NiftiImage`, which simplifies memory management, supports the package's internal image pointers and persistence, and provides syntactic sugar. Full doxygen documentation for this class is available at <http://doxygen.flakery.org/RNifti/>, and is also provided with package releases.
It is possible to use the package's NIfTI-handling code in other R packages' compiled code, thereby obviating the need to duplicate the reference implementation. Moreover, `RNifti` provides two key C++ wrapper classes:

- `NiftiImage`, which simplifies memory management and supports the package's internal image pointers and associated reference counting, and
- `NiftiImageData`, which encapsulates the pixel data within an image, and handles datatype multiplexing and data scaling, as well as providing indexing, iterators and other niceties.

Full doxygen documentation for these classes is available at <http://doxygen.flakery.org/RNifti/>, and is also provided with package releases.

A third-party package can use the `NiftiImage` class by including

Expand Down Expand Up @@ -254,7 +259,7 @@ Thanks to contributions from [@soolijoo](https://github.com/soolijoo), it is pos
| `src/znzlib/znzlib.c` | Source for I/O functions from the NIfTI-1 reference implementation |
| `src/zlib/*` | `zlib` source files for reading and writing gzipped files (optional, as above) |
Note that the `NiftiImage` class is header-only, but C code from the NIfTI-1 reference implementation will need to be compiled and linked into the project. The `print.h` header should be included before including `NiftiImage.h`, so that the R API is not used for printing error messages. The [`standalone` directory](https://github.com/jonclayden/RNifti/tree/master/standalone) provides a minimal example.
Note that the `NiftiImage` and `NiftiImageData` classes are header-only, but C code from the NIfTI-1 reference implementation will need to be compiled and linked into the project. The `NiftiImage_print.h` header should be included before including `NiftiImage.h`, so that the R API is not used for printing error messages. The [`standalone` directory](https://github.com/jonclayden/RNifti/tree/master/standalone) provides a minimal example.
## The NIfTI-2 format
Expand Down
2 changes: 1 addition & 1 deletion inst/include/RNifti.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// Defined since RNifti v0.10.0
// Equal to 100 * (major version) + (minor version)
// Does not change with patch level, since the API should not change
#define RNIFTI_VERSION 10
#define RNIFTI_VERSION 11

#include "niftilib/nifti1_io.h"

Expand Down
9 changes: 9 additions & 0 deletions inst/include/RNiftiAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ static int(*_nifti_copy_extensions)(nifti_image*, const nifti_image*) = NULL;
static void(*_nifti_image_unload)(nifti_image*) = NULL;
static void(*_nifti_image_free)(nifti_image*) = NULL;

static int(*_nifti_is_inttype)(int) = NULL;
static void(*_nifti_datatype_sizes)(int, int*, int*) = NULL;
static char const *(*_nifti_datatype_string)(int) = NULL;
static char const *(*_nifti_units_string)(int) = NULL;
Expand Down Expand Up @@ -61,6 +62,7 @@ void niftilib_register_all ()
_nifti_image_unload = (void(*)(nifti_image*)) R_GetCCallable("RNifti","nii_image_unload");
_nifti_image_free = (void(*)(nifti_image*)) R_GetCCallable("RNifti","nii_image_free");

_nifti_is_inttype = (int(*)(int)) R_GetCCallable("RNifti","nii_is_inttype");
_nifti_datatype_sizes = (void(*)(int, int*, int*)) R_GetCCallable("RNifti","nii_datatype_sizes");
_nifti_datatype_string = (char const *(*)(int)) R_GetCCallable("RNifti","nii_datatype_string");
_nifti_units_string = (char const *(*)(int)) R_GetCCallable("RNifti","nii_units_string");
Expand Down Expand Up @@ -146,6 +148,13 @@ void nifti_image_free (nifti_image *nim)
_nifti_image_free(nim);
}

int nifti_is_inttype (int dt)
{
if (_nifti_is_inttype == NULL)
niftilib_register_all();
return _nifti_is_inttype(dt);
}

void nifti_datatype_sizes (int datatype, int *nbyper, int *swapsize)
{
if (_nifti_datatype_sizes == NULL)
Expand Down

0 comments on commit d59ef32

Please sign in to comment.