Closed avalcarcel9 closed 4 years ago
I believe this is due to oro.nifti::writeNifTI
.
binary_mask = MNITemplate::readMNI()
binary_mask[binary_mask > 0] = 1
any(is.na(binary_mask))
#> [1] FALSE
# [1] FALSE
na_mask = binary_mask
na_mask[1,1,1] = NA
any(is.na(na_mask))
#> [1] TRUE
na_filepath = tempfile(fileext = "na_mask")
oro.nifti::writeNIfTI(na_mask, na_filepath)
na_mask1 = oro.nifti::readNIfTI(paste0(na_filepath, ".nii.gz"), reorient = FALSE)
na_mask1[1,1,1]
#> [1] 0
any(is.na(na_mask1))
#> [1] FALSE
Created on 2020-05-28 by the reprex package (v0.3.0.9001)
What does dtype = TRUE or FALSE in writenii and readnii control then? Documentation is a little confusing.
So it's an issue with how readBin
works with NA and size = 4
from what I can see. I think it's fixed.
Should be fixed with oro.nifti 0.10.3 version.
Yup code for attempt 2 now behaves as expected! Thanks so much!
Bugs still present related to this issue even in updated package. Using neurobase::writenii
with dtype = FALSE
where data is numeric and contains no missing (no NA) then image is saved as strange integers. You can manually compare the maps or use summary in R to see that values have been changed drastically.
> set.seed(5)
> dims = rep(10, 3)
> arr = array(rnorm(prod(dims)), dim = dims)
> nim = oro.nifti::nifti(arr)
> summary(nim)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-3.4981 -0.6556 0.0223 0.0174 0.6919 3.4019
> # Use default dtype (dtype = TRUE)
> neurobase::writenii(nim, '~/Desktop/test_dtype_default.nii.gz')
> # Set dtype = FALSE
> neurobase::writenii(nim, '~/Desktop/test_dtype_false.nii.gz', dtype = FALSE)
> ## Can manually inspect or compare these images in a viewer or read them back in to compare
> nim_default = neurobase::readnii('~/Desktop/test_dtype_default.nii.gz', dtype = FALSE)
> summary(nim_default)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-3.4981 -0.6556 0.0223 0.0174 0.6919 3.4019
> nim_dtype_false = neurobase::readnii('~/Desktop/test_dtype_false.nii.gz', dtype = FALSE)
> summary(nim_dtype_false)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 0.00 0.00 38.41 1.00 255.00
Session info below for reference:
> sessioninfo::session_info()
─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────
setting value
version R version 3.6.1 (2019-07-05)
os macOS Catalina 10.15.6
system x86_64, darwin15.6.0
ui RStudio
language (EN)
collate en_US.UTF-8
ctype en_US.UTF-8
tz America/New_York
date 2020-09-10
─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────
! package * version date lib source
abind 1.4-5 2016-07-21 [2] CRAN (R 3.6.0)
aliviateR 0.0.3 2020-07-09 [1] local
animation 2.6 2018-12-11 [2] CRAN (R 3.6.0)
ANTsR 0.4.9 2019-07-22 [2] Github (stnava/ANTsR@69d65b6)
ANTsRCore 0.7.0 2019-07-22 [2] Github (ANTsX/ANTsRCore@8f99c58)
assertthat 0.2.1 2019-03-21 [2] CRAN (R 3.6.0)
backports 1.1.6 2020-04-05 [2] CRAN (R 3.6.1)
badgecreatr 0.2.0 2019-01-07 [2] CRAN (R 3.6.0)
BiocGenerics 0.32.0 2019-10-29 [2] Bioconductor
BiocParallel 1.20.1 2019-12-21 [2] Bioconductor
bitops 1.0-6 2013-08-17 [2] CRAN (R 3.6.0)
boot 1.3-24 2019-12-20 [2] CRAN (R 3.6.0)
broom 0.5.5 2020-02-29 [2] CRAN (R 3.6.0)
broom.mixed 0.2.4 2019-02-21 [2] CRAN (R 3.6.0)
cli 2.0.2 2020-02-28 [2] CRAN (R 3.6.0)
coda 0.19-3 2019-07-05 [2] CRAN (R 3.6.0)
colorspace 1.4-1 2019-03-18 [2] CRAN (R 3.6.0)
crayon 1.3.4 2017-09-16 [2] CRAN (R 3.6.0)
crosstalk 1.0.0 2016-12-21 [2] CRAN (R 3.6.0)
data.table 1.12.8 2019-12-09 [2] CRAN (R 3.6.0)
DelayedArray 0.12.3 2020-04-09 [1] Bioconductor
DelayedMatrixStats 1.8.0 2019-10-29 [2] Bioconductor
digest 0.6.25 2020-02-23 [2] CRAN (R 3.6.0)
dplyr 1.0.0 2020-05-29 [1] CRAN (R 3.6.2)
ellipsis 0.3.0 2019-09-20 [2] CRAN (R 3.6.0)
evaluate 0.14 2019-05-28 [2] CRAN (R 3.6.0)
extrantsr 3.9.11 2019-09-04 [2] local
fansi 0.4.1 2020-01-08 [2] CRAN (R 3.6.0)
fastmap 1.0.1 2019-10-08 [2] CRAN (R 3.6.0)
forcats 0.5.0 2020-03-01 [2] CRAN (R 3.6.0)
fs 1.3.1 2019-05-06 [2] CRAN (R 3.6.0)
fslr 2.24.1 2019-08-05 [1] CRAN (R 3.6.0)
geepack 1.3-1 2019-12-13 [2] CRAN (R 3.6.0)
generics 0.0.2 2018-11-29 [2] CRAN (R 3.6.0)
ggplot2 3.3.0 2020-03-05 [1] CRAN (R 3.6.0)
git2r 0.27.1 2020-05-03 [1] CRAN (R 3.6.2)
glue 1.4.1 2020-05-13 [1] CRAN (R 3.6.2)
gridExtra 2.3 2017-09-09 [2] CRAN (R 3.6.0)
gtable 0.3.0 2019-03-25 [2] CRAN (R 3.6.0)
hash 2.2.6.1 2019-03-04 [2] CRAN (R 3.6.0)
HDF5Array 1.14.4 2020-04-13 [1] Bioconductor
hms 0.5.3 2020-01-08 [2] CRAN (R 3.6.0)
htmltools 0.5.0 2020-06-16 [1] CRAN (R 3.6.2)
htmlwidgets 1.5.1 2019-10-08 [2] CRAN (R 3.6.0)
httpuv 1.5.2 2019-09-11 [2] CRAN (R 3.6.0)
imcoext 0.1.4 2020-09-10 [1] local
imcolegacy 1.7.0 2020-05-27 [1] local
IRanges 2.20.2 2020-01-13 [2] Bioconductor
iterators 1.0.12 2019-07-26 [2] CRAN (R 3.6.0)
ITKR 0.5.0 2019-07-22 [2] Github (stnava/ITKR@5e76b7e)
jsonlite 1.7.0 2020-06-25 [1] CRAN (R 3.6.2)
knitr 1.29 2020-06-23 [1] CRAN (R 3.6.2)
later 1.0.0 2019-10-04 [2] CRAN (R 3.6.0)
lattice 0.20-38 2018-11-04 [2] CRAN (R 3.6.1)
lifecycle 0.2.0 2020-03-06 [2] CRAN (R 3.6.0)
lme4 1.1-23 2020-04-07 [2] CRAN (R 3.6.1)
lmerTest 3.1-1 2019-12-13 [2] CRAN (R 3.6.0)
lubridate * 1.7.9 2020-06-08 [1] CRAN (R 3.6.2)
magrittr * 1.5 2014-11-22 [2] CRAN (R 3.6.0)
manipulateWidget 0.10.0 2018-06-11 [2] CRAN (R 3.6.0)
MASS 7.3-51.5 2019-12-20 [2] CRAN (R 3.6.0)
Matrix 1.2-18 2019-11-27 [2] CRAN (R 3.6.0)
matrixStats 0.56.0 2020-03-13 [1] CRAN (R 3.6.0)
mgcv 1.8-31 2019-11-09 [2] CRAN (R 3.6.0)
mime 0.9 2020-02-04 [2] CRAN (R 3.6.1)
miniUI 0.1.1.1 2018-05-18 [2] CRAN (R 3.6.0)
minqa 1.2.4 2014-10-09 [2] CRAN (R 3.6.0)
munsell 0.5.0 2018-06-12 [2] CRAN (R 3.6.0)
V neurobase 1.30.1 2020-09-10 [1] Github (muschellij2/neurobase@6946b27)
neuroim 0.0.6 2016-01-07 [2] CRAN (R 3.6.0)
NiftiArray 0.99.6.1 2020-05-03 [1] Neuroconductor-Devel-Releases (R 3.6.3)
nlme 3.1-143 2019-12-10 [2] CRAN (R 3.6.0)
nloptr 1.2.2.1 2020-03-11 [2] CRAN (R 3.6.0)
numDeriv 2016.8-1.1 2019-06-06 [2] CRAN (R 3.6.0)
oro.nifti 0.11.0 2020-09-08 [1] CRAN (R 3.6.2)
pbapply 1.4-2 2019-08-31 [2] CRAN (R 3.6.0)
pillar 1.4.3 2019-12-20 [2] CRAN (R 3.6.1)
pkgconfig 2.0.3 2019-09-22 [2] CRAN (R 3.6.0)
plyr 1.8.6 2020-03-03 [2] CRAN (R 3.6.0)
promises 1.1.0 2019-10-04 [2] CRAN (R 3.6.0)
purrr 0.3.3 2019-10-18 [2] CRAN (R 3.6.0)
R.matlab 3.6.2 2018-09-27 [2] CRAN (R 3.6.0)
R.methodsS3 1.8.0 2020-02-14 [1] CRAN (R 3.6.0)
R.oo 1.23.0 2019-11-03 [2] CRAN (R 3.6.0)
R.utils 2.9.2 2019-12-08 [2] CRAN (R 3.6.0)
R6 2.4.1 2019-11-12 [2] CRAN (R 3.6.0)
Rcpp 1.0.4 2020-03-17 [1] CRAN (R 3.6.0)
RcppEigen 0.3.3.7.0 2019-11-16 [2] CRAN (R 3.6.0)
readr 1.3.1 2018-12-21 [2] CRAN (R 3.6.0)
reshape2 1.4.3 2017-12-11 [2] CRAN (R 3.6.0)
rgl 0.100.30 2019-08-19 [2] CRAN (R 3.6.1)
rhdf5 2.30.1 2019-11-26 [2] Bioconductor
Rhdf5lib 1.8.0 2019-10-29 [2] Bioconductor
rlang 0.4.7 2020-07-09 [1] CRAN (R 3.6.2)
rlist 0.4.6.1 2016-04-04 [2] CRAN (R 3.6.0)
rmarkdown 2.3 2020-06-18 [1] CRAN (R 3.6.2)
RNifti 1.1.0 2020-01-31 [2] CRAN (R 3.6.0)
rstudioapi 0.11 2020-02-07 [1] CRAN (R 3.6.0)
S4Vectors 0.24.4 2020-04-09 [1] Bioconductor
scales 1.1.0 2019-11-18 [2] CRAN (R 3.6.0)
sessioninfo 1.1.1 2018-11-05 [2] CRAN (R 3.6.0)
shiny 1.4.0.2 2020-03-13 [1] CRAN (R 3.6.0)
stapler 0.7.1 2020-01-09 [2] CRAN (R 3.6.0)
statmod 1.4.34 2020-02-17 [2] CRAN (R 3.6.0)
stringi 1.4.6 2020-02-17 [2] CRAN (R 3.6.0)
stringr 1.4.0 2019-02-10 [2] CRAN (R 3.6.0)
tibble 3.0.0 2020-03-30 [2] CRAN (R 3.6.2)
tidyr 1.0.2 2020-01-24 [2] CRAN (R 3.6.0)
tidyselect 1.1.0 2020-05-11 [1] CRAN (R 3.6.2)
TMB 1.7.16 2020-01-15 [2] CRAN (R 3.6.0)
usethis 1.6.0 2020-04-09 [1] CRAN (R 3.6.1)
vctrs 0.3.1 2020-06-05 [1] CRAN (R 3.6.2)
voxel 1.3.5 2019-12-06 [2] Neuroconductor-Releases (R 3.6.1)
webshot 0.5.2 2019-11-22 [2] CRAN (R 3.6.0)
WhiteStripe 2.3.2 2019-10-01 [2] CRAN (R 3.6.0)
withr 2.1.2 2018-03-15 [2] CRAN (R 3.6.0)
xfun 0.15 2020-06-21 [1] CRAN (R 3.6.2)
xtable 1.8-4 2019-04-21 [2] CRAN (R 3.6.0)
yaImpute 1.0-31 2019-01-09 [2] CRAN (R 3.6.0)
yaml 2.2.1 2020-02-01 [2] CRAN (R 3.6.0)
Also is it concerning that local images are not all equal to read in images?
> all.equal(nim_default, nim)
[1] "Attributes: < Component “bitpix”: Mean relative difference: 0.75 >"
[2] "Attributes: < Component “cal_max”: Mean relative difference: 3.293414e-08 >"
[3] "Attributes: < Component “datatype”: Mean relative difference: 0.875 >"
[4] "Attributes: < Component “glmax”: Mean relative difference: 1 >"
[5] "Attributes: < Component “glmin”: Mean relative difference: 1 >"
[6] "Mean relative difference: 2.208861e-08"
I know the difference is small but this is a little worrisome to me.
In the future, can you use reprex
: https://github.com/tidyverse/reprex, makes things a lot easier - looking into it
This is due to the way you're using oro.nifti::nifti
. If you look at oro.nifti::nifti
, the datatype=2
by default.
Trying with the default oro.nifti::nifti
set.seed(5)
dims = rep(10, 3)
arr = array(rnorm(prod(dims)), dim = dims)
nim = oro.nifti::nifti(arr)
summary(nim)
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> -3.4981 -0.6556 0.0223 0.0174 0.6919 3.4019
nim@datatype
#> [1] 2
Writing using writenii
(which has dtype = TRUE
)
tfile = tempfile(fileext = ".nii.gz")
neurobase::writenii(nim, tfile)
nim_default = neurobase::readnii(tfile)
summary(nim_default)
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> -3.4981 -0.6556 0.0223 0.0174 0.6919 3.4019
Writing using writenii
(which has dtype = TRUE
)
bad = abs(nim - nim_default)
max(bad) < 1e-06
#> [1] TRUE
hist(bad)
nim_default = neurobase::readnii(tfile, dtype = FALSE)
summary(nim_default)
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> -3.4981 -0.6556 0.0223 0.0174 0.6919 3.4019
bad = abs(nim - nim_default)
max(bad)
#> [1] 1.190171e-07
hist(bad)
This is the issue -
nim@datatype
#> [1] 2
So we’re not surprised this doesnt work
tfile_false = tempfile(fileext = ".nii.gz")
neurobase::writenii(nim, tfile_false, dtype = FALSE)
nim_dtype_false = neurobase::readnii(tfile_false, dtype = FALSE)
summary(nim_dtype_false)
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> 0.00 0.00 0.00 38.41 1.00 255.00
Now if we use nifti
correctly
nim = oro.nifti::nifti(arr, datatype = oro.nifti::convert.datatype()[["FLOAT32"]])
nim@datatype
#> [1] 16
nim
#> NIfTI-1 format
#> Type : nifti
#> Data Type : 16 (FLOAT32)
#> Bits per Pixel : 32
#> Slice Code : 0 (Unknown)
#> Intent Code : 0 (None)
#> Qform Code : 0 (Unknown)
#> Sform Code : 0 (Unknown)
#> Dimension : 10 x 10 x 10
#> Pixel Dimension : 1 x 1 x 1
#> Voxel Units : Unknown
#> Time Units : Unknown
summary(nim)
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> -3.4981 -0.6556 0.0223 0.0174 0.6919 3.4019
tfile = tempfile(fileext = ".nii.gz")
neurobase::writenii(nim, tfile)
nim_default = neurobase::readnii(tfile)
summary(nim_default)
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> -3.4981 -0.6556 0.0223 0.0174 0.6919 3.4019
bad = abs(nim - nim_default)
max(bad)
#> [1] 1.190171e-07
hist(bad)
nim_default = neurobase::readnii(tfile, dtype = FALSE)
summary(nim_default)
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> -3.4981 -0.6556 0.0223 0.0174 0.6919 3.4019
bad = abs(nim - nim_default)
max(bad)
#> [1] 1.190171e-07
hist(bad)
tfile_false = tempfile(fileext = ".nii.gz")
neurobase::writenii(nim, tfile_false, dtype = FALSE)
nim_dtype_false = neurobase::readnii(tfile_false, dtype = FALSE)
summary(nim_dtype_false)
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> -3.4981 -0.6556 0.0223 0.0174 0.6919 3.4019
Created on 2020-09-10 by the reprex package (v0.3.0)
Good to know that the default from oro.nifti::nifti
is datatype = 2
or binary data. In the code where I encountered this problem I created the image using the old school approach of setting a mask to a new image and then filling with the numeric values.
map = mask
# Fill the map with vector values where the mask is 1
map[mask == 1] = vec
So the header transferred with the following:
NIfTI-1 format
Type : nifti
Data Type : 2 (UINT8)
Bits per Pixel : 8
When writing with dtype = FALSE
then neurobase::datatyper
was not run and neurobase::writenii
simply used the header information (which the incorrect data type as binary).
Future me will rely more heavily on the new school neurobase::remake_img
which runs neurobase::datatyper
to assign the correct header info rather than copying the masks binary header info. If other users encounter this or similar warnings:
Warning message:
In datatyper(average_maps$voxel_data[[1]]) :
Need to change bitpix and datatype to FLOAT64 due to NAs
They should check that their header Data Type
and Bits per Pixel
slot values match the image voxel value types.
I have an image that is filled with 0/1/NA. Writing and reading using neurobase::writenii and neurobase::readnii fills the NA values with 0. Default function has dtype = TRUE so this is as expected but even after setting dtype to FALSE image is stripped of NA values. See example below: