From 37110308d95e13c845f685aeae2712abc80df5d6 Mon Sep 17 00:00:00 2001 From: Jon Clayden Date: Tue, 26 Jun 2018 18:23:29 +0000 Subject: [PATCH] version 0.8.0 --- DESCRIPTION | 10 +- MD5 | 164 +- NAMESPACE | 1 + NEWS | 20 + R/nifti.R | 77 +- README.md | 12 +- inst/doxygen/html/_nifti_image_8h_source.html | 128 ++ inst/doxygen/html/annotated.html | 84 + inst/doxygen/html/bc_s.png | Bin 0 -> 676 bytes inst/doxygen/html/bdwn.png | Bin 0 -> 147 bytes .../html/class_nifti_image-members.html | 117 ++ inst/doxygen/html/class_nifti_image.html | 1399 +++++++++++++++ ...class_r_nifti_1_1_nifti_image-members.html | 132 ++ .../html/class_r_nifti_1_1_nifti_image.html | 1496 +++++++++++++++ inst/doxygen/html/classes.html | 87 + inst/doxygen/html/closed.png | Bin 0 -> 132 bytes .../dir_2b5d1a398a9eec011391d543f21db223.html | 85 + .../dir_920884c6b3b2f0be94e27d51660adee5.html | 81 + .../dir_98a44f28b9ced65c076c4e168f5923c6.html | 81 + inst/doxygen/html/doc.png | Bin 0 -> 746 bytes inst/doxygen/html/doxygen.css | 1596 +++++++++++++++++ inst/doxygen/html/doxygen.png | Bin 0 -> 3779 bytes inst/doxygen/html/dynsections.js | 120 ++ inst/doxygen/html/files.html | 85 + inst/doxygen/html/folderclosed.png | Bin 0 -> 616 bytes inst/doxygen/html/folderopen.png | Bin 0 -> 597 bytes inst/doxygen/html/functions.html | 248 +++ inst/doxygen/html/functions_func.html | 235 +++ inst/doxygen/html/functions_vars.html | 88 + inst/doxygen/html/index.html | 78 + inst/doxygen/html/jquery.js | 115 ++ inst/doxygen/html/menu.js | 50 + inst/doxygen/html/menudata.js | 66 + inst/doxygen/html/nav_f.png | Bin 0 -> 153 bytes inst/doxygen/html/nav_g.png | Bin 0 -> 95 bytes inst/doxygen/html/nav_h.png | Bin 0 -> 98 bytes inst/doxygen/html/open.png | Bin 0 -> 123 bytes inst/doxygen/html/search/all_0.html | 30 + inst/doxygen/html/search/all_0.js | 4 + inst/doxygen/html/search/all_1.html | 30 + inst/doxygen/html/search/all_1.js | 5 + inst/doxygen/html/search/all_2.html | 30 + inst/doxygen/html/search/all_2.js | 7 + inst/doxygen/html/search/all_3.html | 30 + inst/doxygen/html/search/all_3.js | 4 + inst/doxygen/html/search/all_4.html | 30 + inst/doxygen/html/search/all_4.js | 4 + inst/doxygen/html/search/all_5.html | 30 + inst/doxygen/html/search/all_5.js | 8 + inst/doxygen/html/search/all_6.html | 30 + inst/doxygen/html/search/all_6.js | 6 + inst/doxygen/html/search/all_7.html | 30 + inst/doxygen/html/search/all_7.js | 7 + inst/doxygen/html/search/all_8.html | 30 + inst/doxygen/html/search/all_8.js | 5 + inst/doxygen/html/search/all_9.html | 30 + inst/doxygen/html/search/all_9.js | 7 + inst/doxygen/html/search/all_a.html | 30 + inst/doxygen/html/search/all_a.js | 6 + inst/doxygen/html/search/all_b.html | 30 + inst/doxygen/html/search/all_b.js | 4 + inst/doxygen/html/search/all_c.html | 30 + inst/doxygen/html/search/all_c.js | 4 + inst/doxygen/html/search/all_d.html | 30 + inst/doxygen/html/search/all_d.js | 4 + inst/doxygen/html/search/all_e.html | 30 + inst/doxygen/html/search/all_e.js | 5 + inst/doxygen/html/search/all_f.html | 30 + inst/doxygen/html/search/all_f.js | 4 + inst/doxygen/html/search/classes_0.html | 30 + inst/doxygen/html/search/classes_0.js | 4 + inst/doxygen/html/search/classes_1.html | 30 + inst/doxygen/html/search/classes_1.js | 4 + inst/doxygen/html/search/close.png | Bin 0 -> 273 bytes inst/doxygen/html/search/functions_0.html | 30 + inst/doxygen/html/search/functions_0.js | 4 + inst/doxygen/html/search/functions_1.html | 30 + inst/doxygen/html/search/functions_1.js | 5 + inst/doxygen/html/search/functions_2.html | 30 + inst/doxygen/html/search/functions_2.js | 6 + inst/doxygen/html/search/functions_3.html | 30 + inst/doxygen/html/search/functions_3.js | 4 + inst/doxygen/html/search/functions_4.html | 30 + inst/doxygen/html/search/functions_4.js | 4 + inst/doxygen/html/search/functions_5.html | 30 + inst/doxygen/html/search/functions_5.js | 6 + inst/doxygen/html/search/functions_6.html | 30 + inst/doxygen/html/search/functions_6.js | 6 + inst/doxygen/html/search/functions_7.html | 30 + inst/doxygen/html/search/functions_7.js | 7 + inst/doxygen/html/search/functions_8.html | 30 + inst/doxygen/html/search/functions_8.js | 4 + inst/doxygen/html/search/functions_9.html | 30 + inst/doxygen/html/search/functions_9.js | 6 + inst/doxygen/html/search/functions_a.html | 30 + inst/doxygen/html/search/functions_a.js | 6 + inst/doxygen/html/search/functions_b.html | 30 + inst/doxygen/html/search/functions_b.js | 4 + inst/doxygen/html/search/functions_c.html | 30 + inst/doxygen/html/search/functions_c.js | 4 + inst/doxygen/html/search/functions_d.html | 30 + inst/doxygen/html/search/functions_d.js | 4 + inst/doxygen/html/search/functions_e.html | 30 + inst/doxygen/html/search/functions_e.js | 5 + inst/doxygen/html/search/functions_f.html | 30 + inst/doxygen/html/search/functions_f.js | 4 + inst/doxygen/html/search/mag_sel.png | Bin 0 -> 563 bytes inst/doxygen/html/search/nomatches.html | 12 + inst/doxygen/html/search/pages_0.html | 30 + inst/doxygen/html/search/pages_0.js | 4 + inst/doxygen/html/search/search.css | 271 +++ inst/doxygen/html/search/search.js | 814 +++++++++ inst/doxygen/html/search/search_l.png | Bin 0 -> 604 bytes inst/doxygen/html/search/search_m.png | Bin 0 -> 158 bytes inst/doxygen/html/search/search_r.png | Bin 0 -> 612 bytes inst/doxygen/html/search/searchdata.js | 27 + inst/doxygen/html/search/variables_0.html | 30 + inst/doxygen/html/search/variables_0.js | 4 + inst/doxygen/html/search/variables_1.html | 30 + inst/doxygen/html/search/variables_1.js | 5 + inst/doxygen/html/search/variables_2.html | 30 + inst/doxygen/html/search/variables_2.js | 4 + inst/doxygen/html/splitbar.png | Bin 0 -> 314 bytes .../struct_nifti_image_1_1_block-members.html | 86 + .../html/struct_nifti_image_1_1_block.html | 219 +++ ...fti_1_1_nifti_image_1_1_block-members.html | 90 + ...uct_r_nifti_1_1_nifti_image_1_1_block.html | 227 +++ inst/doxygen/html/sync_off.png | Bin 0 -> 853 bytes inst/doxygen/html/sync_on.png | Bin 0 -> 845 bytes inst/doxygen/html/tab_a.png | Bin 0 -> 142 bytes inst/doxygen/html/tab_b.png | Bin 0 -> 169 bytes inst/doxygen/html/tab_h.png | Bin 0 -> 177 bytes inst/doxygen/html/tab_s.png | Bin 0 -> 184 bytes inst/doxygen/html/tabs.css | 1 + inst/extdata/example_4d.nii.gz | Bin 0 -> 1853 bytes inst/include/RNifti.h | 5 + inst/include/lib/NiftiImage.h | 284 +-- inst/include/lib/NiftiImage_internal.h | 96 +- inst/include/lib/print.h | 7 +- inst/include/niftilib/nifti1_io.h | 5 + man/niftiVersion.Rd | 37 + man/readNifti.Rd | 12 +- man/updateNifti.Rd | 34 +- src/Makevars | 2 +- src/main.cpp | 67 +- tests/testthat/test-05-nifti.R | 73 +- tests/testthat/test-10-xform.R | 29 +- tests/testthat/test-15-foreign.R | 42 +- 148 files changed, 10170 insertions(+), 253 deletions(-) create mode 100644 inst/doxygen/html/_nifti_image_8h_source.html create mode 100644 inst/doxygen/html/annotated.html create mode 100644 inst/doxygen/html/bc_s.png create mode 100644 inst/doxygen/html/bdwn.png create mode 100644 inst/doxygen/html/class_nifti_image-members.html create mode 100644 inst/doxygen/html/class_nifti_image.html create mode 100644 inst/doxygen/html/class_r_nifti_1_1_nifti_image-members.html create mode 100644 inst/doxygen/html/class_r_nifti_1_1_nifti_image.html create mode 100644 inst/doxygen/html/classes.html create mode 100644 inst/doxygen/html/closed.png create mode 100644 inst/doxygen/html/dir_2b5d1a398a9eec011391d543f21db223.html create mode 100644 inst/doxygen/html/dir_920884c6b3b2f0be94e27d51660adee5.html create mode 100644 inst/doxygen/html/dir_98a44f28b9ced65c076c4e168f5923c6.html create mode 100644 inst/doxygen/html/doc.png create mode 100644 inst/doxygen/html/doxygen.css create mode 100644 inst/doxygen/html/doxygen.png create mode 100644 inst/doxygen/html/dynsections.js create mode 100644 inst/doxygen/html/files.html create mode 100644 inst/doxygen/html/folderclosed.png create mode 100644 inst/doxygen/html/folderopen.png create mode 100644 inst/doxygen/html/functions.html create mode 100644 inst/doxygen/html/functions_func.html create mode 100644 inst/doxygen/html/functions_vars.html create mode 100644 inst/doxygen/html/index.html create mode 100644 inst/doxygen/html/jquery.js create mode 100644 inst/doxygen/html/menu.js create mode 100644 inst/doxygen/html/menudata.js create mode 100644 inst/doxygen/html/nav_f.png create mode 100644 inst/doxygen/html/nav_g.png create mode 100644 inst/doxygen/html/nav_h.png create mode 100644 inst/doxygen/html/open.png create mode 100644 inst/doxygen/html/search/all_0.html create mode 100644 inst/doxygen/html/search/all_0.js create mode 100644 inst/doxygen/html/search/all_1.html create mode 100644 inst/doxygen/html/search/all_1.js create mode 100644 inst/doxygen/html/search/all_2.html create mode 100644 inst/doxygen/html/search/all_2.js create mode 100644 inst/doxygen/html/search/all_3.html create mode 100644 inst/doxygen/html/search/all_3.js create mode 100644 inst/doxygen/html/search/all_4.html create mode 100644 inst/doxygen/html/search/all_4.js create mode 100644 inst/doxygen/html/search/all_5.html create mode 100644 inst/doxygen/html/search/all_5.js create mode 100644 inst/doxygen/html/search/all_6.html create mode 100644 inst/doxygen/html/search/all_6.js create mode 100644 inst/doxygen/html/search/all_7.html create mode 100644 inst/doxygen/html/search/all_7.js create mode 100644 inst/doxygen/html/search/all_8.html create mode 100644 inst/doxygen/html/search/all_8.js create mode 100644 inst/doxygen/html/search/all_9.html create mode 100644 inst/doxygen/html/search/all_9.js create mode 100644 inst/doxygen/html/search/all_a.html create mode 100644 inst/doxygen/html/search/all_a.js create mode 100644 inst/doxygen/html/search/all_b.html create mode 100644 inst/doxygen/html/search/all_b.js create mode 100644 inst/doxygen/html/search/all_c.html create mode 100644 inst/doxygen/html/search/all_c.js create mode 100644 inst/doxygen/html/search/all_d.html create mode 100644 inst/doxygen/html/search/all_d.js create mode 100644 inst/doxygen/html/search/all_e.html create mode 100644 inst/doxygen/html/search/all_e.js create mode 100644 inst/doxygen/html/search/all_f.html create mode 100644 inst/doxygen/html/search/all_f.js create mode 100644 inst/doxygen/html/search/classes_0.html create mode 100644 inst/doxygen/html/search/classes_0.js create mode 100644 inst/doxygen/html/search/classes_1.html create mode 100644 inst/doxygen/html/search/classes_1.js create mode 100644 inst/doxygen/html/search/close.png create mode 100644 inst/doxygen/html/search/functions_0.html create mode 100644 inst/doxygen/html/search/functions_0.js create mode 100644 inst/doxygen/html/search/functions_1.html create mode 100644 inst/doxygen/html/search/functions_1.js create mode 100644 inst/doxygen/html/search/functions_2.html create mode 100644 inst/doxygen/html/search/functions_2.js create mode 100644 inst/doxygen/html/search/functions_3.html create mode 100644 inst/doxygen/html/search/functions_3.js create mode 100644 inst/doxygen/html/search/functions_4.html create mode 100644 inst/doxygen/html/search/functions_4.js create mode 100644 inst/doxygen/html/search/functions_5.html create mode 100644 inst/doxygen/html/search/functions_5.js create mode 100644 inst/doxygen/html/search/functions_6.html create mode 100644 inst/doxygen/html/search/functions_6.js create mode 100644 inst/doxygen/html/search/functions_7.html create mode 100644 inst/doxygen/html/search/functions_7.js create mode 100644 inst/doxygen/html/search/functions_8.html create mode 100644 inst/doxygen/html/search/functions_8.js create mode 100644 inst/doxygen/html/search/functions_9.html create mode 100644 inst/doxygen/html/search/functions_9.js create mode 100644 inst/doxygen/html/search/functions_a.html create mode 100644 inst/doxygen/html/search/functions_a.js create mode 100644 inst/doxygen/html/search/functions_b.html create mode 100644 inst/doxygen/html/search/functions_b.js create mode 100644 inst/doxygen/html/search/functions_c.html create mode 100644 inst/doxygen/html/search/functions_c.js create mode 100644 inst/doxygen/html/search/functions_d.html create mode 100644 inst/doxygen/html/search/functions_d.js create mode 100644 inst/doxygen/html/search/functions_e.html create mode 100644 inst/doxygen/html/search/functions_e.js create mode 100644 inst/doxygen/html/search/functions_f.html create mode 100644 inst/doxygen/html/search/functions_f.js create mode 100644 inst/doxygen/html/search/mag_sel.png create mode 100644 inst/doxygen/html/search/nomatches.html create mode 100644 inst/doxygen/html/search/pages_0.html create mode 100644 inst/doxygen/html/search/pages_0.js create mode 100644 inst/doxygen/html/search/search.css create mode 100644 inst/doxygen/html/search/search.js create mode 100644 inst/doxygen/html/search/search_l.png create mode 100644 inst/doxygen/html/search/search_m.png create mode 100644 inst/doxygen/html/search/search_r.png create mode 100644 inst/doxygen/html/search/searchdata.js create mode 100644 inst/doxygen/html/search/variables_0.html create mode 100644 inst/doxygen/html/search/variables_0.js create mode 100644 inst/doxygen/html/search/variables_1.html create mode 100644 inst/doxygen/html/search/variables_1.js create mode 100644 inst/doxygen/html/search/variables_2.html create mode 100644 inst/doxygen/html/search/variables_2.js create mode 100644 inst/doxygen/html/splitbar.png create mode 100644 inst/doxygen/html/struct_nifti_image_1_1_block-members.html create mode 100644 inst/doxygen/html/struct_nifti_image_1_1_block.html create mode 100644 inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block-members.html create mode 100644 inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block.html create mode 100644 inst/doxygen/html/sync_off.png create mode 100644 inst/doxygen/html/sync_on.png create mode 100644 inst/doxygen/html/tab_a.png create mode 100644 inst/doxygen/html/tab_b.png create mode 100644 inst/doxygen/html/tab_h.png create mode 100644 inst/doxygen/html/tab_s.png create mode 100644 inst/doxygen/html/tabs.css create mode 100644 inst/extdata/example_4d.nii.gz create mode 100644 man/niftiVersion.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 03ecf89..86c11fa 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RNifti -Version: 0.7.1 -Date: 2017-09-13 +Version: 0.8.0 +Date: 2018-06-26 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"), @@ -11,7 +11,7 @@ Authors@R: c(person("Jon","Clayden",role=c("cre","aut"),email="code@clayden.org" person("Jean-loup","Gailly",role="cph"), person("Mark","Adler",role="cph")) Imports: Rcpp (>= 0.11.0) -Suggests: testthat (>= 0.11.0) +Suggests: testthat (>= 0.11.0), reportr Enhances: oro.nifti, tractor.base LinkingTo: Rcpp Description: Provides very fast access to images stored in the NIfTI-1 file @@ -24,7 +24,7 @@ BugReports: https://github.com/jonclayden/RNifti/issues Encoding: UTF-8 RoxygenNote: 6.0.1 NeedsCompilation: yes -Packaged: 2017-09-13 20:20:56 UTC; jon +Packaged: 2018-06-26 15:22:19 UTC; jon Author: Jon Clayden [cre, aut], Bob Cox [aut], Mark Jenkinson [aut], @@ -35,4 +35,4 @@ Author: Jon Clayden [cre, aut], Mark Adler [cph] Maintainer: Jon Clayden Repository: CRAN -Date/Publication: 2017-09-14 15:44:33 UTC +Date/Publication: 2018-06-26 19:23:29 UTC diff --git a/MD5 b/MD5 index cf2ddd1..b8d02ed 100644 --- a/MD5 +++ b/MD5 @@ -1,38 +1,168 @@ -b716048d461151faaa2cc0b3208b7696 *DESCRIPTION -a40af01a5a7fcf21b523ed2b01d0f4c3 *NAMESPACE -c107ffa4542b554aed6ea432420bbd03 *NEWS +0afe362a4ab979170d3ee937b15d6ad4 *DESCRIPTION +acae6be5ad74132cebcd524a391b0be9 *NAMESPACE +38c31f2aec7d66450fd88c14cf8c385e *NEWS 522e649998b6ae37eb5a27660a23ef49 *R/image.R -43090b78f30369ea4df5dd6072a47054 *R/nifti.R +9c1a3732df6e29ecbe42f15f7902a821 *R/nifti.R 96e0d65c5ddfefa5f8dfc67779f879ea *R/xform.R 33e5b97691485f83c60e3d5c3f3a2cdc *R/zzz.R -ac7e8c7c99aa904b1a3b760611e3644b *README.md +d738c8025ab950db4383b6fb234c81b0 *README.md ccc527aa65600337ed5e3f832c0eb443 *cleanup e1101581081b97d9032639597016d3d8 *cleanup.win fb6ea71c285b8fc5d86bf53c4e104348 *inst/COPYRIGHTS +fcf021f6dd32db1077e201417dd49809 *inst/doxygen/html/_nifti_image_8h_source.html +b7cd62b7a7ffe22daf4a3016c559f6c7 *inst/doxygen/html/annotated.html +ceaaae73746596a7519cfe782d8aa065 *inst/doxygen/html/bc_s.png +6249334b2e7fc28090f26abeb328eb78 *inst/doxygen/html/bdwn.png +c212613a84218981b4f6ddf2957c50d6 *inst/doxygen/html/class_nifti_image-members.html +67ad110ad58d315791893d1174fcc7d7 *inst/doxygen/html/class_nifti_image.html +fcfc25b04074d31b0799705d7f4f9d02 *inst/doxygen/html/class_r_nifti_1_1_nifti_image-members.html +cc1a57701176ed8053c00b3d05db0869 *inst/doxygen/html/class_r_nifti_1_1_nifti_image.html +2b3ee461fe586f038393a6b951f84eec *inst/doxygen/html/classes.html +3fa180a1c853204ee64235708fb8e162 *inst/doxygen/html/closed.png +c61c2ea1a021ce83fb780b30d5af6804 *inst/doxygen/html/dir_2b5d1a398a9eec011391d543f21db223.html +665de3539c0faab40d1f3767052578a0 *inst/doxygen/html/dir_920884c6b3b2f0be94e27d51660adee5.html +440b50910d864fd7fb52b6f06caa8d3a *inst/doxygen/html/dir_98a44f28b9ced65c076c4e168f5923c6.html +31ed05886f30a2be256e9df86a25586f *inst/doxygen/html/doc.png +ec4deb6eb4c826b427a90f3ab5ea839b *inst/doxygen/html/doxygen.css +4d8b8c8f1a68a4f320da8294a085f251 *inst/doxygen/html/doxygen.png +78d0ca705e540d5caf939ae1e73923d2 *inst/doxygen/html/dynsections.js +ad62d88369d9a687a49a1b515defa20b *inst/doxygen/html/files.html +0b7046d86103299b2a0306ddf33ec004 *inst/doxygen/html/folderclosed.png +9ff4412a8e93e25320b9e260951c6a04 *inst/doxygen/html/folderopen.png +e12073c5675376b8ae89fa2c845c512c *inst/doxygen/html/functions.html +c417f05eba052698aeefcda898e62e25 *inst/doxygen/html/functions_func.html +6c9175d1e9faaf2f3c71c5ad04a1954a *inst/doxygen/html/functions_vars.html +3d9a495904098753e6a700c3801b5332 *inst/doxygen/html/index.html +6e2b29334385c06816c0df7b9680e54f *inst/doxygen/html/jquery.js +b3cacc16864e59588290feef722b9bc3 *inst/doxygen/html/menu.js +3fcb6b4c0de4332c65b0e8b1fe1598fe *inst/doxygen/html/menudata.js +4e4d8be23c6d6bbe0184fd891ff59e00 *inst/doxygen/html/nav_f.png +6cf157aabeb91ae637a6d770b07c1011 *inst/doxygen/html/nav_g.png +935f050f10b7fe425509491f207f574f *inst/doxygen/html/nav_h.png +468c228548b4a85dd54d544810bd0edd *inst/doxygen/html/open.png +9309624fda98272bfb49b60594df0068 *inst/doxygen/html/search/all_0.html +ee7a1da8d613fb8d6668182bfb8cffb1 *inst/doxygen/html/search/all_0.js +f17cbe80ca19fab6f2349bc3638b07f5 *inst/doxygen/html/search/all_1.html +9d50f031c7788a84ccec64347e0ac5c3 *inst/doxygen/html/search/all_1.js +0b10862a60e1fba1937d193076a7dacb *inst/doxygen/html/search/all_2.html +ea0ab92ada53af4c78503c5bd0a113c3 *inst/doxygen/html/search/all_2.js +750f27a91a5e141713489c29988bf321 *inst/doxygen/html/search/all_3.html +ef84a0112190546eb2603ee7e64f0967 *inst/doxygen/html/search/all_3.js +b8d4882a4787865fe4a574e5a098a876 *inst/doxygen/html/search/all_4.html +ee61ef08404dd553b76098413c1f06f0 *inst/doxygen/html/search/all_4.js +150e161dce38801bf185c4fe0d701052 *inst/doxygen/html/search/all_5.html +b9dedb06bc5da4cc7c8740b9d7fe1828 *inst/doxygen/html/search/all_5.js +6a24f0a31348224d62b9c255faa531e0 *inst/doxygen/html/search/all_6.html +0db48aaacac643c4641fe74b0e20f9f5 *inst/doxygen/html/search/all_6.js +d4acf451ab1146dea245a18e8bd01c74 *inst/doxygen/html/search/all_7.html +d8a536053481471e4755de0fb697f569 *inst/doxygen/html/search/all_7.js +2b02acb9c8acb01ff875b4e51bc7c2dc *inst/doxygen/html/search/all_8.html +98763f7adcc66a5b8976d56935f8029e *inst/doxygen/html/search/all_8.js +e4beb4a91a5ba8eb286cd8355004dfc0 *inst/doxygen/html/search/all_9.html +304451ea906a35fd636421b2dff5a9cc *inst/doxygen/html/search/all_9.js +45ba2e45e4418acbc7ff14952a10ec76 *inst/doxygen/html/search/all_a.html +72005947b417c907fd5bee362bb7ae03 *inst/doxygen/html/search/all_a.js +6208f93e4386c5db3757f8f1063b54eb *inst/doxygen/html/search/all_b.html +30c0a4ba4c280d0b2617cd001f1945c4 *inst/doxygen/html/search/all_b.js +a5fb8a117331e55dcf27b51a8a9bf72d *inst/doxygen/html/search/all_c.html +dcfcc6acc24c9cf971287de64b600feb *inst/doxygen/html/search/all_c.js +01ad28045986ba96aa96ab091d642776 *inst/doxygen/html/search/all_d.html +c44402acad6da8ff6c37e61f7cd0ef5d *inst/doxygen/html/search/all_d.js +347784fab10f616759738e38e698aa5c *inst/doxygen/html/search/all_e.html +695134965c92ef9cb674a078b2d2fde3 *inst/doxygen/html/search/all_e.js +2cf0439cdac8c394d3cb607c9d7a9bea *inst/doxygen/html/search/all_f.html +783e50b7f37cdb0a864dd2026e417917 *inst/doxygen/html/search/all_f.js +2a9ad1439d18eaa008ff79be8f52ae4c *inst/doxygen/html/search/classes_0.html +d424561b48c7ef19a6de739b1615c26a *inst/doxygen/html/search/classes_0.js +8a13c61534b131a98661938bbcf34db8 *inst/doxygen/html/search/classes_1.html +8cc5b79614b64195afb8ed7cecf135fb *inst/doxygen/html/search/classes_1.js +f466a7fdf1edfb1aa52ffab60f819119 *inst/doxygen/html/search/close.png +1c8d88dedfc00e9539ca4f54fe42038a *inst/doxygen/html/search/functions_0.html +cad1fc5dc0c360cc6b9b07970d759504 *inst/doxygen/html/search/functions_0.js +e1c2cf4cbcaf4cbd5168500f99d794e1 *inst/doxygen/html/search/functions_1.html +9d50f031c7788a84ccec64347e0ac5c3 *inst/doxygen/html/search/functions_1.js +1480c6eb90420ee5e81b543a8d0e890a *inst/doxygen/html/search/functions_2.html +6257b2f03f3ca7731eef414b512da337 *inst/doxygen/html/search/functions_2.js +516837ced8730f78c7cb752c2879ca45 *inst/doxygen/html/search/functions_3.html +ef84a0112190546eb2603ee7e64f0967 *inst/doxygen/html/search/functions_3.js +e5041a2606df300935b732da66944a94 *inst/doxygen/html/search/functions_4.html +ee61ef08404dd553b76098413c1f06f0 *inst/doxygen/html/search/functions_4.js +f71c08733e620ef2f596ad7ebc9e759d *inst/doxygen/html/search/functions_5.html +bdc25556a6ac7b673c7446f75c737bf4 *inst/doxygen/html/search/functions_5.js +b9defd7eb6e642d8313f1ecf90ccf04d *inst/doxygen/html/search/functions_6.html +889f13c03d695f3c39a77dd070f4214a *inst/doxygen/html/search/functions_6.js +3e05ca2478fbece4454f631eb6003456 *inst/doxygen/html/search/functions_7.html +d8a536053481471e4755de0fb697f569 *inst/doxygen/html/search/functions_7.js +e43985d41654bcb53e87cc352042b2d6 *inst/doxygen/html/search/functions_8.html +98c0947668e71d59fae961c715a6483e *inst/doxygen/html/search/functions_8.js +ee61c95487e81c0091f30d6acc3ed01d *inst/doxygen/html/search/functions_9.html +9b2e54a4125530f443759537341c6cea *inst/doxygen/html/search/functions_9.js +e639f1e14dc49e8bee90ba4b2cff9a8f *inst/doxygen/html/search/functions_a.html +72005947b417c907fd5bee362bb7ae03 *inst/doxygen/html/search/functions_a.js +d632dad263f6aa86349d26092396f0d5 *inst/doxygen/html/search/functions_b.html +30c0a4ba4c280d0b2617cd001f1945c4 *inst/doxygen/html/search/functions_b.js +ac7ff866c7f21f4d66db771232fad336 *inst/doxygen/html/search/functions_c.html +dcfcc6acc24c9cf971287de64b600feb *inst/doxygen/html/search/functions_c.js +7b7408140b335860b5ac5ea7d714024f *inst/doxygen/html/search/functions_d.html +c44402acad6da8ff6c37e61f7cd0ef5d *inst/doxygen/html/search/functions_d.js +53c5f107417b7c565d6f8681855f3f7b *inst/doxygen/html/search/functions_e.html +695134965c92ef9cb674a078b2d2fde3 *inst/doxygen/html/search/functions_e.js +8f2d4e83bc3f7de0771a6a841830a7ee *inst/doxygen/html/search/functions_f.html +783e50b7f37cdb0a864dd2026e417917 *inst/doxygen/html/search/functions_f.js +be03e63d7379983b28a2c092867a1d67 *inst/doxygen/html/search/mag_sel.png +2414ad3cc0ed34da17bdc0d12c6d8ed6 *inst/doxygen/html/search/nomatches.html +3d858135660433cd6b79789ce4d4a48a *inst/doxygen/html/search/pages_0.html +2db60c12e44f17409196d694ffe0352f *inst/doxygen/html/search/pages_0.js +62c88f58334ead8314afc96a8170411e *inst/doxygen/html/search/search.css +45ecb6807f17457d9557a058b774773d *inst/doxygen/html/search/search.js +496450f84d51c69db49f756b2d0acc20 *inst/doxygen/html/search/search_l.png +20910c4cfe0e8efc8211bc9f7e58b7ff *inst/doxygen/html/search/search_m.png +03ee24f1971c0e31ffb6246882e18edd *inst/doxygen/html/search/search_r.png +9942e1b0822b454d7015209965dae5f5 *inst/doxygen/html/search/searchdata.js +c69d317122acedf700152303c736696b *inst/doxygen/html/search/variables_0.html +1eaa9837643fc8b83fa0d32eea852592 *inst/doxygen/html/search/variables_0.js +d642a01ea0113af5fa01775b9661c965 *inst/doxygen/html/search/variables_1.html +f3dba5507f98561ad230926e5bb7afb0 *inst/doxygen/html/search/variables_1.js +0131d70922bbb1b6da55a9093d5f0bd0 *inst/doxygen/html/search/variables_2.html +04efd618eae955aa49a24f78ed797b97 *inst/doxygen/html/search/variables_2.js +8d590f70c25a81e71b99f6c8246b067e *inst/doxygen/html/splitbar.png +017b479dfa3fa6fce8537e63f4cd926d *inst/doxygen/html/struct_nifti_image_1_1_block-members.html +b05b53f15e9d65190760760587e97121 *inst/doxygen/html/struct_nifti_image_1_1_block.html +2e0b1602977ff731cb0843e7cd0eb4ec *inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block-members.html +ca4ed20f7e002fa18afc3bc520d9666a *inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block.html +12a5e283812e092b5a74b0d47e95e9a9 *inst/doxygen/html/sync_off.png +b1cc394ed471b4ab97be14f1e1a7cefa *inst/doxygen/html/sync_on.png +2a5327b5dfc494fd8688fd887991cdab *inst/doxygen/html/tab_a.png +c7cd16cfabe8a14b9848f813df53fc2e *inst/doxygen/html/tab_b.png +38c6c507f0ab91770a0ed9a668a03551 *inst/doxygen/html/tab_h.png +d5a3e094c590d5113232b74cd902f58f *inst/doxygen/html/tab_s.png +5e5f3c33293bfd03386e623b17ef5e7b *inst/doxygen/html/tabs.css bad67894bda1a1b3b135369d6c07df6a *inst/extdata/example.nii.gz +e8547f4bc7609814adfbab6fe9c1c288 *inst/extdata/example_4d.nii.gz 46972fdde383b57ff6b126544241f3df *inst/extdata/example_compressed.nii.gz -4e83f54fdd3cb670823753e6f49859c3 *inst/include/RNifti.h +dde1deee32aabaf283846e913dbe7ebf *inst/include/RNifti.h 24006ded0251406f93de4cd953f1f46b *inst/include/RNiftiAPI.h -7db7a915427faf7a6204ffe1b6739f49 *inst/include/lib/NiftiImage.h -c7a2f62db9ac9ddd06327565c85c2f10 *inst/include/lib/NiftiImage_internal.h -f03e0b1700657944680f1a47a54bf654 *inst/include/lib/print.h +64b787c9cabc1284fa5d2f9870c08378 *inst/include/lib/NiftiImage.h +0d9a178d4269d502e920e9e21ee58520 *inst/include/lib/NiftiImage_internal.h +e70cfd0317477b6a0f03fcd1264b4a50 *inst/include/lib/print.h a34af6ec4b25ecc1a68459bbb5dc76c9 *inst/include/niftilib/nifti1.h -f7137f566bbb76b092b1274e4ab599fe *inst/include/niftilib/nifti1_io.h +c04802572389eb06064486812e6563ac *inst/include/niftilib/nifti1_io.h 5407d4c937d8f925665f71aad35c12fa *inst/include/zlib/zconf.h 1c128a3b0a0fd84c1224754170ee7756 *inst/include/zlib/zlib.h 6f799f7df2f427678edd3abcc5897ad6 *inst/include/znzlib/znzlib.h bf620bb7e9ac965f397f69cd2fe273de *man/dumpNifti.Rd b73690f99036b7a2941636fa3901e1c5 *man/internalImage.Rd 42120833f7c250a1d4e56c649ef40ed4 *man/ndim.Rd +e5d783e2a4e386e0f3dd2e3b07c95a94 *man/niftiVersion.Rd 20c181da31a24521475e83eff3927f90 *man/pixdim.Rd -1b1b3a86f75e5ee372559822a509e513 *man/readNifti.Rd +34cdb072e6fe1781770712b8b44a4706 *man/readNifti.Rd 2a38dee909e6162648704fe8d5ab846c *man/retrieveNifti.Rd -5e85207c736e3a63e08421567f97cae3 *man/updateNifti.Rd +8b5e8b6e6492d64bf074c84e12cc00a4 *man/updateNifti.Rd d0157fa027c54471e124f07c512283ec *man/voxelToWorld.Rd 7abc3deb7077c2b30d9ff1716b3310e5 *man/writeNifti.Rd 3bcd7f7e4ba7afe740bbc111a2a532cd *man/xform.Rd -2deb2188a91964bdb9bcb32fde0c1752 *src/Makevars -383b2f0124280c4bdc5bc517d23d0c30 *src/main.cpp +4d422a95d90a714e2e100ff63c76ee1f *src/Makevars +b8ccbbaf958d76d31985f1a8451512a6 *src/main.cpp 0914eaaf0fca8668ad668d855c23036c *src/niftilib/nifti1_io.c ae3bbb54820e1d49fb90cbba222e973f *src/zlib/adler32.c 7a734598f9792fee943b70b6da8d932f *src/zlib/compress.c @@ -60,6 +190,6 @@ fff257bc1656eb60fc585a7dc35f963d *src/zlib/zutil.c de91a463004fd5b944c3d37eab0c1794 *src/zlib/zutil.h db1082070d31f780ebd9c051b74adc17 *src/znzlib/znzlib.c d4a2abbb6217055b8900c8d86ac6aa53 *tests/testthat.R -6e33415014a093811ff7efe7978236b0 *tests/testthat/test-05-nifti.R -335c27208d42142e57e497a1ad377b04 *tests/testthat/test-10-xform.R -934d2a677b2cc72e54788cfc7dfcadf4 *tests/testthat/test-15-foreign.R +bddc785f9d73227aa87d79ba5618e5b7 *tests/testthat/test-05-nifti.R +88c4645aeded119b6027c7280aad2b11 *tests/testthat/test-10-xform.R +7b55076655f51ffecc4a9425ed94f668 *tests/testthat/test-15-foreign.R diff --git a/NAMESPACE b/NAMESPACE index c2fa0fe..a63cddf 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -16,6 +16,7 @@ export("qform<-") export("sform<-") export(dumpNifti) export(ndim) +export(niftiVersion) export(orientation) export(origin) export(pixdim) diff --git a/NEWS b/NEWS index a20579a..43e6a53 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,26 @@ Significant changes to the RNifti package are laid out below for each release. =============================================================================== +VERSION 0.8.0 + +- The new niftiVersion() function identifies the NIfTI format variant used by + files on disk. +- The readNifti() function gains an option which allows only certain volumes + to be read from disk. +- The updateNifti() function gains an option to set the internal datatype, for + advanced usage only (issue #8). +- Calling updateNifti() with a list containing only a few fields could + previously reset the remaining metadata to the defaults. This has been + corrected. +- It is now possible to change the cal_min and cal_max fields with the + updateNifti() function (issue #9). The scl_slope and scl_inter fields cannot + be changed, but this is now documented. +- R packages using the RNifti API must now ensure that the USING_R symbol is + defined (which it is by the main R header, R.h). Conversely, standalone use + of RNifti as a C++ library no longer requires _NO_R__ to be defined. + +=============================================================================== + VERSION 0.7.1 - The package is now more careful about handling NaNs when converting to diff --git a/R/nifti.R b/R/nifti.R index 6540e26..b6d7b25 100644 --- a/R/nifti.R +++ b/R/nifti.R @@ -10,8 +10,13 @@ #' class \code{"internalImage"}, which contains only minimal metadata about #' the image. Either way, the return value has an attribute which points to a #' C data structure containing the full image. -#' @return An array or internal image, with class \code{"niftiImage"}, and -#' possibly also \code{"internalImage"}. +#' @param volumes An integer vector giving the volumes to read (counting along +#' all dimensions beyond the third jointly), or \code{NULL}, the default, in +#' which case every volume is read. This cannot currently be set differently +#' for each file read. +#' @return An array or internal image, with class \code{"niftiImage"} (and +#' possibly also \code{"internalImage"}), or a list of such objects if +#' \code{file} has length greater than one. #' #' @note If the \code{internal} argument is \code{FALSE} (the default), the #' data type of the image pointer will be set to match one of R's native @@ -30,16 +35,16 @@ #' @seealso \code{\link{writeNifti}} #' @references The NIfTI-1 standard (\url{http://www.nitrc.org/docman/view.php/26/64/nifti1.h}). #' @export -readNifti <- function (file, internal = FALSE) +readNifti <- function (file, internal = FALSE, volumes = NULL) { if (!is.character(file)) stop("File name(s) must be specified in a character vector") if (length(file) == 0) stop("File name vector is empty") else if (length(file) > 1) - lapply(file, function(f) .Call("readNifti", path.expand(f), internal, PACKAGE="RNifti")) + lapply(file, function(f) .Call("readNifti", path.expand(f), internal, volumes, PACKAGE="RNifti")) else - .Call("readNifti", path.expand(file), internal, PACKAGE="RNifti") + .Call("readNifti", path.expand(file), internal, volumes, PACKAGE="RNifti") } #' Write a NIfTI-1 format file @@ -94,7 +99,7 @@ writeNifti <- function (image, file, template = NULL, datatype = "auto") #' @export retrieveNifti <- function (object) { - .Call("readNifti", object, TRUE, PACKAGE="RNifti") + .Call("readNifti", object, TRUE, NULL, PACKAGE="RNifti") } #' Update an internal NIfTI-1 object using a template @@ -103,19 +108,46 @@ retrieveNifti <- function (object) #' using metadata from the template. The dimensions and, if available, pixel #' dimensions, from the \code{image} will replace those from the template. #' +#' If \code{template} is a complete list of NIfTI-1 header fields, like that +#' produced by \code{\link{dumpNifti}}, or an image, then it will be used to +#' create the internal object, and then the data and metadata associated with +#' the \code{image} will overwrite the appropriate parts. If \code{template} +#' is an incomplete list, the \code{image} will be used to create the internal +#' object, and then the specified fields will be overwritten from the list. +#' This allows users to selectively update certain fields while leaving others +#' alone (but see the note below). +#' +#' Datatype information in a list \code{template} is ignored. The datatype can +#' only be changed using the \code{datatype} argument, but in this case the +#' internal object gets out of sync with the R array, so an internal image is +#' returned to avoid the mismatch. Changing the internal datatype in this way +#' is for advanced usage only. +#' #' @param image A numeric array. #' @param template An image, in any acceptable form (see #' \code{\link{retrieveNifti}}), or a named list of NIfTI-1 properties like #' that produced by \code{\link{dumpNifti}}. The default of \code{NULL} will #' have no effect. +#' @param datatype The NIfTI datatype to use within the internal image. The +#' default, \code{"auto"} uses the R type. Other possibilities are +#' \code{"float"}, \code{"int16"}, etc., which may be preferred to reduce +#' object size. However, no checks are done to ensure that the coercion +#' maintains precision, and this option is for advanced usage only. #' @return A copy of the original \code{image}, with its internal image -#' attribute set or updated appropriately. +#' attribute set or updated appropriately. If \code{datatype} is not +#' \code{"auto"} then the result is an internal image. +#' +#' @note The \code{scl_slope} and \code{scl_inter} fields affect the numerical +#' interpretation of the pixel data, so it is impossible in general to change +#' them without also changing the array values on both the C and the R side. +#' Therefore, to avoid unexpected side-effects, these fields are not affected +#' by this function. #' #' @author Jon Clayden #' @export -updateNifti <- function (image, template = NULL) +updateNifti <- function (image, template = NULL, datatype = "auto") { - .Call("updateNifti", image, template, PACKAGE="RNifti") + .Call("updateNifti", image, template, datatype, PACKAGE="RNifti") } #' Dump the contents of an internal NIfTI-1 object @@ -156,6 +188,33 @@ print.niftiHeader <- function (x, ...) cat(paste0(paste(rep(" ",maxWidth-widths[i]),collapse=""), names(x)[i], ": ", paste(format(x[[i]],trim=TRUE),collapse=" "), "\n")) } +#' Check the format version of a file +#' +#' This function identifies the likely NIfTI format variant used by one or more +#' files on disk. +#' +#' @param file A character vector of file names. +#' @return A vector of integers, of the same length as \code{file}. Each +#' element will be 0 for ANALYZE format (the precursor to NIfTI-1), 1 for +#' NIfTI-1 (which is now most common), 2 for NIfTI-2, or -1 if the file +#' doesn't exist or doesn't look plausible in any of these formats. +#' +#' @note NIfTI-2 format, mostly a variant of NIfTI-1 with wider datatypes used +#' for many fields, is not currently supported for reading, but it is +#' detected by this function. +#' +#' @examples +#' path <- system.file("extdata", "example.nii.gz", package="RNifti") +#' niftiVersion(path) # 1 +#' +#' @author Jon Clayden +#' @seealso \code{\link{readNifti}} +#' @export +niftiVersion <- function (file) +{ + sapply(file, function(f) .Call("niftiVersion", path.expand(f), PACKAGE="RNifti")) +} + rescaleNifti <- function (image, scales) { .Call("rescaleImage", image, scales, PACKAGE="RNifti") diff --git a/README.md b/README.md index 4f17654..7bcaa89 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ The [NIfTI-1 format](http://www.nitrc.org/docman/view.php/26/64/nifti1.h) is a p There are several packages available for reading and writing NIfTI-1 files in R, and these are summarised in the [Medical Imaging task view](https://cran.r-project.org/view=MedicalImaging). However, `RNifti` is distinguished by its - [extremely strong performance](#performance), in terms of speed; -- [C/C++ API](#api), allowing access to NIfTI images even in compiled code in other packages; and +- [C/C++ API](#api), allowing access to NIfTI images in compiled code in other R packages, or even in [standalone C++ code](#use-in-pure-c-projects); and - modest dependencies, consisting of only R itself and the very widely-used [Rcpp](https://cran.r-project.org/package=Rcpp) C++ wrapper library. The latest development version of the package can always be installed from GitHub using the `devtools` package. @@ -186,7 +186,7 @@ void myfunction (SEXP image_) ## Use in pure C++ projects -Thanks to contributions from @soolijoo, it is possible (as of package version 0.7.0) to use the `NiftiImage` C++ class in standalone C++ projects. You will need the following files: +Thanks to contributions from [@soolijoo](https://github.com/soolijoo), it is possible (as of package version 0.7.0) to use the `NiftiImage` C++ class in standalone C++ projects. You will need the following files: | Path | Purpose | | ------------------------------- | --------------------------------------------------------------------------------------------------- | @@ -198,4 +198,10 @@ Thanks to contributions from @soolijoo, it is possible (as of package version 0. | `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 constant `_NO_R__` should be defined, and `print.h` included, before including `NiftiImage.h`, so that the R API is not used. +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. + +## The NIfTI-2 format + +The [NIfTI-2 format](https://nifti.nimh.nih.gov/nifti-2) is a evolution of the far more widely-used NIfTI-1. It primarily [uses wider types for various fields](https://www.nitrc.org/forum/forum.php?thread_id=2148&forum_id=1941), to support large datasets and improve precision. + +Unfortunately, the NIfTI-1 version of the reference library is not forwards-compatible with NIfTI-2, and does not recognise NIfTI-2 files as valid, while the NIfTI-2 version changes the definition of the `nifti_image` data structure, and hence the return type of several core functions, rendering it potentially incompatible with software written for the original library. As a result, adding full NIfTI-2 support to `RNifti` without breaking existing code is not straightforward. Nevertheless, as of `RNifti` version 0.8.0, R function `niftiVersion()` and C++ static method `NiftiImage::fileVersion()` offer a forwards-compatible way to determine the version of the format used by a particular file, so that calling functions can take action accordingly. diff --git a/inst/doxygen/html/_nifti_image_8h_source.html b/inst/doxygen/html/_nifti_image_8h_source.html new file mode 100644 index 0000000..1eb30a2 --- /dev/null +++ b/inst/doxygen/html/_nifti_image_8h_source.html @@ -0,0 +1,128 @@ + + + + + + + +RNifti: inst/include/lib/NiftiImage.h Source File + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
NiftiImage.h
+
+
+
1 #ifndef _NIFTI_IMAGE_H_
2 #define _NIFTI_IMAGE_H_
3 
4 
5 #ifdef USING_R
6 
7 #include <Rcpp.h>
8 
9 #else
10 
11 #define R_NegInf -INFINITY
12 #define ISNAN(x) (x != x)
13 
14 #include <stdint.h>
15 #include <cstddef>
16 #include <cmath>
17 #include <string>
18 #include <sstream>
19 #include <vector>
20 #include <stdexcept>
21 #include <algorithm>
22 #include <map>
23 #include <locale>
24 #include <limits>
25 
26 #endif
27 
28 
29 #include "niftilib/nifti1_io.h"
30 
39 namespace RNifti {
40 
46 {
47 public:
52  struct Block
53  {
54  const NiftiImage &image;
55  const int dimension;
56  const int index;
65  Block (const NiftiImage &image, const int dimension, const int index)
67  {
68  if (dimension != image->ndim)
69  throw std::runtime_error("Blocks must be along the last dimension in the image");
70  }
71 
80  Block & operator= (const NiftiImage &source)
81  {
82  if (source->datatype != image->datatype)
83  throw std::runtime_error("New data does not have the same datatype as the target block");
84  if (source->scl_slope != image->scl_slope || source->scl_inter != image->scl_inter)
85  throw std::runtime_error("New data does not have the same scale parameters as the target block");
86 
87  size_t blockSize = 1;
88  for (int i=1; i<dimension; i++)
89  blockSize *= image->dim[i];
90 
91  if (blockSize != source->nvox)
92  throw std::runtime_error("New data does not have the same size as the target block");
93 
94  blockSize *= image->nbyper;
95  memcpy(static_cast<char*>(image->data) + blockSize*index, source->data, blockSize);
96  return *this;
97  }
98 
102  template <typename TargetType>
103  std::vector<TargetType> getData () const;
104  };
105 
106 #ifdef USING_R
107 
113  static short sexpTypeToNiftiType (const int sexpType)
114  {
115  if (sexpType == INTSXP || sexpType == LGLSXP)
116  return DT_INT32;
117  else if (sexpType == REALSXP)
118  return DT_FLOAT64;
119  else
120  throw std::runtime_error("Array elements must be numeric");
121  }
122 #endif
123 
129  static std::string xformToString (const mat44 matrix)
130  {
131  int icode, jcode, kcode;
132  nifti_mat44_to_orientation(matrix, &icode, &jcode, &kcode);
133 
134  int codes[3] = { icode, jcode, kcode };
135  std::string result("---");
136  for (int i=0; i<3; i++)
137  {
138  switch (codes[i])
139  {
140  case NIFTI_L2R: result[i] = 'R'; break;
141  case NIFTI_R2L: result[i] = 'L'; break;
142  case NIFTI_P2A: result[i] = 'A'; break;
143  case NIFTI_A2P: result[i] = 'P'; break;
144  case NIFTI_I2S: result[i] = 'S'; break;
145  case NIFTI_S2I: result[i] = 'I'; break;
146  }
147  }
148  return result;
149  }
150 
157  static int fileVersion (const std::string &path)
158  {
159  nifti_1_header *header = nifti_read_header(path.c_str(), NULL, false);
160  if (header == NULL)
161  return -1;
162  else
163  {
164  int version = NIFTI_VERSION(*header);
165  if (version == 0)
166  {
167  // NIfTI-2 has a 540-byte header - check for this or its byte-swapped equivalent
168  if (header->sizeof_hdr == 540 || header->sizeof_hdr == 469893120)
169  {
170  // The magic number has moved in NIfTI-2, so find it by byte offset
171  const char *magic = (char *) header + 4;
172  if (strncmp(magic,"ni2",3) == 0 || strncmp(magic,"n+2",3) == 0)
173  version = 2;
174  }
175  else if (!nifti_hdr_looks_good(header))
176  {
177  // Not plausible as ANALYZE, so return -1
178  version = -1;
179  }
180  }
181  return version;
182  }
183  }
184 
185 
186 protected:
187  nifti_image *image;
188  bool persistent;
194  void copy (const nifti_image *source);
195 
200  void copy (const NiftiImage &source);
201 
206  void copy (const Block &source);
207 
208 
209 #ifdef USING_R
210 
216  void initFromNiftiS4 (const Rcpp::RObject &object, const bool copyData = true);
217 
223  void initFromMriImage (const Rcpp::RObject &object, const bool copyData = true);
224 
229  void initFromList (const Rcpp::RObject &object);
230 
236  void initFromArray (const Rcpp::RObject &object, const bool copyData = true);
237 
238 #endif
239 
244  void updatePixdim (const std::vector<float> &pixdim);
245 
250  void setPixunits (const std::vector<std::string> &pixunits);
251 
252 public:
257  : image(NULL), persistent(false) {}
258 
263  NiftiImage (const NiftiImage &source)
264  : image(NULL), persistent(false)
265  {
266  this->copy(source);
267 #ifndef NDEBUG
268  Rprintf("Creating NiftiImage with pointer %p (from NiftiImage)\n", this->image);
269 #endif
270  }
271 
276  NiftiImage (const Block &source)
277  : image(NULL), persistent(false)
278  {
279  this->copy(source);
280 #ifndef NDEBUG
281  Rprintf("Creating NiftiImage with pointer %p (from Block)\n", this->image);
282 #endif
283  }
284 
291  NiftiImage (nifti_image * const image, const bool copy = false)
292  : image(NULL), persistent(false)
293  {
294  if (copy)
295  this->copy(image);
296  else
297  this->image = image;
298 #ifndef NDEBUG
299  Rprintf("Creating NiftiImage with pointer %p (from pointer)\n", this->image);
300 #endif
301  }
302 
309  NiftiImage (const std::string &path, const bool readData = true)
310  : persistent(false)
311  {
312  this->image = nifti_image_read(path.c_str(), readData);
313  if (this->image == NULL)
314  throw std::runtime_error("Failed to read image from path " + path);
315 #ifndef NDEBUG
316  Rprintf("Creating NiftiImage with pointer %p (from string)\n", this->image);
317 #endif
318  }
319 
326  NiftiImage (const std::string &path, const std::vector<int> &volumes);
327 
328 #ifdef USING_R
329 
334  NiftiImage (const SEXP object, const bool readData = true);
335 #endif
336 
340  virtual ~NiftiImage ()
341  {
342  if (!persistent)
343  {
344 #ifndef NDEBUG
345  Rprintf("Freeing NiftiImage with pointer %p\n", this->image);
346 #endif
347  nifti_image_free(image);
348  }
349  }
350 
354  operator const nifti_image* () const { return image; }
355 
359  operator nifti_image* () { return image; }
360 
364  const nifti_image * operator-> () const { return image; }
365 
369  nifti_image * operator-> () { return image; }
370 
376  {
377  copy(source);
378 #ifndef NDEBUG
379  Rprintf("Creating NiftiImage with pointer %p (from NiftiImage)\n", this->image);
380 #endif
381  return *this;
382  }
383 
389  NiftiImage & operator= (const Block &source)
390  {
391  copy(source);
392 #ifndef NDEBUG
393  Rprintf("Creating NiftiImage with pointer %p (from Block)\n", this->image);
394 #endif
395  return *this;
396  }
397 
403  {
404  this->persistent = persistent;
405 #ifndef NDEBUG
406  if (persistent)
407  Rprintf("Setting NiftiImage with pointer %p to be persistent\n", this->image);
408 #endif
409  return *this;
410  }
411 
415  bool isNull () const { return (image == NULL); }
416 
420  bool isPersistent () const { return persistent; }
421 
425  bool isDataScaled () const { return (image != NULL && image->scl_slope != 0.0 && (image->scl_slope != 1.0 || image->scl_inter != 0.0)); }
426 
430  int nDims () const
431  {
432  if (image == NULL)
433  return 0;
434  else
435  return image->ndim;
436  }
437 
442  std::vector<int> dim () const
443  {
444  if (image == NULL)
445  return std::vector<int>();
446  else
447  return std::vector<int>(image->dim+1, image->dim+image->ndim+1);
448  }
449 
454  std::vector<float> pixdim () const
455  {
456  if (image == NULL)
457  return std::vector<float>();
458  else
459  return std::vector<float>(image->pixdim+1, image->pixdim+image->ndim+1);
460  }
461 
469  {
470  int ndim = image->ndim;
471  while (image->dim[ndim] < 2)
472  ndim--;
473  image->dim[0] = image->ndim = ndim;
474 
475  return *this;
476  }
477 
481  template <typename TargetType>
482  std::vector<TargetType> getData () const;
483 
488  NiftiImage & changeDatatype (const short datatype);
489 
494  NiftiImage & changeDatatype (const std::string &datatype);
495 
503  template <typename SourceType>
504  NiftiImage & replaceData (const std::vector<SourceType> &data, const short datatype = DT_NONE);
505 
510  {
511  nifti_image_unload(image);
512  return *this;
513  }
514 
520  NiftiImage & rescale (const std::vector<float> &scales);
521 
529  NiftiImage & reorient (const int i, const int j, const int k);
530 
538  NiftiImage & reorient (const std::string &orientation);
539 
540 #ifdef USING_R
541 
545  NiftiImage & update (const Rcpp::RObject &object);
546 #endif
547 
553  mat44 xform (const bool preferQuaternion = true) const;
554 
558  int nBlocks () const
559  {
560  if (image == NULL)
561  return 0;
562  else
563  return image->dim[image->ndim];
564  }
565 
573  const Block block (const int i) const { return Block(*this, nDims(), i); }
574 
582  Block block (const int i) { return Block(*this, nDims(), i); }
583 
589  const Block slice (const int i) const { return Block(*this, 3, i); }
590 
596  Block slice (const int i) { return Block(*this, 3, i); }
597 
603  const Block volume (const int i) const { return Block(*this, 4, i); }
604 
610  Block volume (const int i) { return Block(*this, 4, i); }
611 
617  void toFile (const std::string fileName, const short datatype = DT_NONE) const;
618 
624  void toFile (const std::string fileName, const std::string &datatype) const;
625 
626 #ifdef USING_R
627 
632  Rcpp::RObject toArray () const;
633 
639  Rcpp::RObject toPointer (const std::string label) const;
640 
647  Rcpp::RObject toArrayOrPointer (const bool internal, const std::string label) const;
648 
653  Rcpp::RObject headerToList () const;
654 
655 #endif
656 
657 };
658 
659 // Include helper functions
660 #include "lib/NiftiImage_internal.h"
661 
662 inline void NiftiImage::copy (const nifti_image *source)
663 {
664  if (image != NULL && !persistent)
665  nifti_image_free(image);
666 
667  if (source == NULL)
668  image = NULL;
669  else
670  {
671  image = nifti_copy_nim_info(source);
672  if (source->data != NULL)
673  {
674  size_t dataSize = nifti_get_volsize(source);
675  image->data = calloc(1, dataSize);
676  memcpy(image->data, source->data, dataSize);
677  }
678  }
679 
680  persistent = false;
681 }
682 
683 inline void NiftiImage::copy (const NiftiImage &source)
684 {
685  const nifti_image *sourceStruct = source;
686  copy(sourceStruct);
687 }
688 
689 inline void NiftiImage::copy (const Block &source)
690 {
691  if (image != NULL && !persistent)
692  nifti_image_free(image);
693 
694  const nifti_image *sourceStruct = source.image;
695  if (sourceStruct == NULL)
696  image = NULL;
697  else
698  {
699  image = nifti_copy_nim_info(sourceStruct);
700  image->dim[0] = source.image->dim[0] - 1;
701  image->dim[source.dimension] = 1;
702  image->pixdim[source.dimension] = 1.0;
703  nifti_update_dims_from_array(image);
704 
705  if (sourceStruct->data != NULL)
706  {
707  size_t blockSize = nifti_get_volsize(image);
708  image->data = calloc(1, blockSize);
709  memcpy(image->data, static_cast<char*>(source.image->data) + blockSize*source.index, blockSize);
710  }
711  }
712 
713  persistent = false;
714 }
715 
716 #ifdef USING_R
717 
718 // Convert an S4 "nifti" object, as defined in the oro.nifti package, to a "nifti_image" struct
719 inline void NiftiImage::initFromNiftiS4 (const Rcpp::RObject &object, const bool copyData)
720 {
721  nifti_1_header header;
722  header.sizeof_hdr = 348;
723 
724  const std::vector<short> dims = object.slot("dim_");
725  for (int i=0; i<8; i++)
726  header.dim[i] = dims[i];
727 
728  header.intent_p1 = object.slot("intent_p1");
729  header.intent_p2 = object.slot("intent_p2");
730  header.intent_p3 = object.slot("intent_p3");
731  header.intent_code = object.slot("intent_code");
732 
733  header.datatype = object.slot("datatype");
734  header.bitpix = object.slot("bitpix");
735 
736  header.slice_start = object.slot("slice_start");
737  header.slice_end = object.slot("slice_end");
738  header.slice_code = Rcpp::as<int>(object.slot("slice_code"));
739  header.slice_duration = object.slot("slice_duration");
740 
741  const std::vector<float> pixdims = object.slot("pixdim");
742  for (int i=0; i<8; i++)
743  header.pixdim[i] = pixdims[i];
744  header.xyzt_units = Rcpp::as<int>(object.slot("xyzt_units"));
745 
746  header.vox_offset = object.slot("vox_offset");
747 
748  header.scl_slope = object.slot("scl_slope");
749  header.scl_inter = object.slot("scl_inter");
750  header.toffset = object.slot("toffset");
751 
752  header.cal_max = object.slot("cal_max");
753  header.cal_min = object.slot("cal_min");
754  header.glmax = header.glmin = 0;
755 
756  strncpy(header.descrip, Rcpp::as<std::string>(object.slot("descrip")).c_str(), 79);
757  header.descrip[79] = '\0';
758  strncpy(header.aux_file, Rcpp::as<std::string>(object.slot("aux_file")).c_str(), 23);
759  header.aux_file[23] = '\0';
760  strncpy(header.intent_name, Rcpp::as<std::string>(object.slot("intent_name")).c_str(), 15);
761  header.intent_name[15] = '\0';
762  strncpy(header.magic, Rcpp::as<std::string>(object.slot("magic")).c_str(), 3);
763  header.magic[3] = '\0';
764 
765  header.qform_code = object.slot("qform_code");
766  header.sform_code = object.slot("sform_code");
767 
768  header.quatern_b = object.slot("quatern_b");
769  header.quatern_c = object.slot("quatern_c");
770  header.quatern_d = object.slot("quatern_d");
771  header.qoffset_x = object.slot("qoffset_x");
772  header.qoffset_y = object.slot("qoffset_y");
773  header.qoffset_z = object.slot("qoffset_z");
774 
775  const std::vector<float> srow_x = object.slot("srow_x");
776  const std::vector<float> srow_y = object.slot("srow_y");
777  const std::vector<float> srow_z = object.slot("srow_z");
778  for (int i=0; i<4; i++)
779  {
780  header.srow_x[i] = srow_x[i];
781  header.srow_y[i] = srow_y[i];
782  header.srow_z[i] = srow_z[i];
783  }
784 
785  if (header.datatype == DT_UINT8 || header.datatype == DT_INT16 || header.datatype == DT_INT32 || header.datatype == DT_INT8 || header.datatype == DT_UINT16 || header.datatype == DT_UINT32)
786  header.datatype = DT_INT32;
787  else if (header.datatype == DT_FLOAT32 || header.datatype == DT_FLOAT64)
788  header.datatype = DT_FLOAT64; // This assumes that sizeof(double) == 8
789  else
790  throw std::runtime_error("Data type is not supported");
791 
792  this->image = nifti_convert_nhdr2nim(header, NULL);
793 
794  const SEXP data = PROTECT(object.slot(".Data"));
795  if (!copyData || Rf_length(data) <= 1)
796  this->image->data = NULL;
797  else
798  {
799  const size_t dataSize = nifti_get_volsize(this->image);
800  this->image->data = calloc(1, dataSize);
801  if (header.datatype == DT_INT32)
802  {
803  Rcpp::IntegerVector intData(data);
804  std::copy(intData.begin(), intData.end(), static_cast<int32_t*>(this->image->data));
805  }
806  else
807  {
808  Rcpp::DoubleVector doubleData(data);
809  std::copy(doubleData.begin(), doubleData.end(), static_cast<double*>(this->image->data));
810  }
811  }
812  UNPROTECT(1);
813 }
814 
815 inline void NiftiImage::initFromMriImage (const Rcpp::RObject &object, const bool copyData)
816 {
817  Rcpp::Reference mriImage(object);
818  Rcpp::Function getXform = mriImage.field("getXform");
819  Rcpp::NumericMatrix xform = getXform();
820 
821  this->image = NULL;
822 
823  if (Rf_length(mriImage.field("tags")) > 0)
824  initFromList(mriImage.field("tags"));
825 
826  Rcpp::RObject data = mriImage.field("data");
827  if (data.inherits("SparseArray"))
828  {
829  Rcpp::Language call("as.array", data);
830  data = call.eval();
831  }
832 
833  const short datatype = (Rf_isNull(data) ? DT_INT32 : sexpTypeToNiftiType(data.sexp_type()));
834 
835  int dims[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
836  const std::vector<int> dimVector = mriImage.field("imageDims");
837  const int nDims = std::min(7, int(dimVector.size()));
838  dims[0] = nDims;
839  size_t nVoxels = 1;
840  for (int i=0; i<nDims; i++)
841  {
842  dims[i+1] = dimVector[i];
843  nVoxels *= dimVector[i];
844  }
845 
846  if (this->image == NULL)
847  this->image = nifti_make_new_nim(dims, datatype, FALSE);
848  else
849  {
850  std::copy(dims, dims+8, this->image->dim);
851  this->image->datatype = datatype;
852  nifti_datatype_sizes(image->datatype, &image->nbyper, NULL);
853  }
854 
855  if (copyData && !Rf_isNull(data))
856  {
857  // NB: nifti_get_volsize() will not be right here if there were tags
858  const size_t dataSize = nVoxels * image->nbyper;
859  this->image->data = calloc(1, dataSize);
860  if (datatype == DT_INT32)
861  memcpy(this->image->data, INTEGER(data), dataSize);
862  else
863  memcpy(this->image->data, REAL(data), dataSize);
864  }
865  else
866  this->image->data = NULL;
867 
868  const std::vector<float> pixdimVector = mriImage.field("voxelDims");
869  const int pixdimLength = pixdimVector.size();
870  for (int i=0; i<std::min(pixdimLength,nDims); i++)
871  this->image->pixdim[i+1] = std::abs(pixdimVector[i]);
872 
873  const std::vector<std::string> pixunitsVector = mriImage.field("voxelDimUnits");
874  setPixunits(pixunitsVector);
875 
876  if (xform.rows() != 4 || xform.cols() != 4)
877  this->image->qform_code = this->image->sform_code = 0;
878  else
879  {
880  mat44 matrix;
881  for (int i=0; i<4; i++)
882  {
883  for (int j=0; j<4; j++)
884  matrix.m[i][j] = static_cast<float>(xform(i,j));
885  }
886 
887  this->image->qto_xyz = matrix;
888  this->image->qto_ijk = nifti_mat44_inverse(image->qto_xyz);
889  nifti_mat44_to_quatern(image->qto_xyz, &image->quatern_b, &image->quatern_c, &image->quatern_d, &image->qoffset_x, &image->qoffset_y, &image->qoffset_z, NULL, NULL, NULL, &image->qfac);
890 
891  this->image->sto_xyz = matrix;
892  this->image->sto_ijk = nifti_mat44_inverse(image->sto_xyz);
893 
894  this->image->qform_code = this->image->sform_code = 2;
895  }
896 }
897 
898 inline void NiftiImage::initFromList (const Rcpp::RObject &object)
899 {
900  Rcpp::List list(object);
901  nifti_1_header *header = nifti_make_new_header(NULL, DT_FLOAT64);
902 
903  internal::updateHeader(header, list);
904 
905  this->image = nifti_convert_nhdr2nim(*header, NULL);
906  this->image->data = NULL;
907  free(header);
908 }
909 
910 inline void NiftiImage::initFromArray (const Rcpp::RObject &object, const bool copyData)
911 {
912  int dims[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
913  const std::vector<int> dimVector = object.attr("dim");
914 
915  const int nDims = std::min(7, int(dimVector.size()));
916  dims[0] = nDims;
917  for (int i=0; i<nDims; i++)
918  dims[i+1] = dimVector[i];
919 
920  const short datatype = sexpTypeToNiftiType(object.sexp_type());
921  this->image = nifti_make_new_nim(dims, datatype, int(copyData));
922 
923  if (copyData)
924  {
925  const size_t dataSize = nifti_get_volsize(image);
926  if (datatype == DT_INT32)
927  memcpy(this->image->data, INTEGER(object), dataSize);
928  else
929  memcpy(this->image->data, REAL(object), dataSize);
930  }
931  else
932  this->image->data = NULL;
933 
934  if (object.hasAttribute("pixdim"))
935  {
936  const std::vector<float> pixdimVector = object.attr("pixdim");
937  const int pixdimLength = pixdimVector.size();
938  for (int i=0; i<std::min(pixdimLength,nDims); i++)
939  this->image->pixdim[i+1] = pixdimVector[i];
940  }
941 
942  if (object.hasAttribute("pixunits"))
943  {
944  const std::vector<std::string> pixunitsVector = object.attr("pixunits");
945  setPixunits(pixunitsVector);
946  }
947 }
948 
949 inline NiftiImage::NiftiImage (const SEXP object, const bool readData)
950  : persistent(false)
951 {
952  Rcpp::RObject imageObject(object);
953  bool resolved = false;
954 
955  if (imageObject.hasAttribute(".nifti_image_ptr"))
956  {
957  Rcpp::XPtr<NiftiImage> imagePtr(SEXP(imageObject.attr(".nifti_image_ptr")));
958  NiftiImage *ptr = imagePtr;
959  if (ptr != NULL)
960  {
961  this->image = ptr->image;
962  this->persistent = true;
963  resolved = true;
964 
965  if (imageObject.hasAttribute("dim"))
966  update(imageObject);
967  }
968  else if (Rf_isString(object))
969  throw std::runtime_error("Internal image is not valid");
970  else
971  Rf_warning("Ignoring invalid internal pointer");
972  }
973 
974  if (!resolved)
975  {
976  if (Rf_isNull(object))
977  this->image = NULL;
978  else if (Rf_isString(object))
979  {
980  const std::string path = Rcpp::as<std::string>(object);
981  this->image = nifti_image_read(path.c_str(), readData);
982  if (this->image == NULL)
983  throw std::runtime_error("Failed to read image from path " + path);
984  }
985  else if (imageObject.inherits("nifti"))
986  initFromNiftiS4(imageObject, readData);
987  else if (imageObject.inherits("anlz"))
988  throw std::runtime_error("Cannot currently convert objects of class \"anlz\"");
989  else if (imageObject.inherits("MriImage"))
990  initFromMriImage(imageObject, readData);
991  else if (Rf_isVectorList(object))
992  initFromList(imageObject);
993  else if (imageObject.hasAttribute("dim"))
994  initFromArray(imageObject, readData);
995  else
996  throw std::runtime_error("Cannot convert object of class \"" + Rcpp::as<std::string>(imageObject.attr("class")) + "\" to a nifti_image");
997  }
998 
999  if (this->image != NULL)
1000  nifti_update_dims_from_array(this->image);
1001 
1002 #ifndef NDEBUG
1003  Rprintf("Creating NiftiImage with pointer %p (from SEXP)\n", this->image);
1004 #endif
1005 }
1006 
1007 #endif // USING_R
1008 
1009 inline NiftiImage::NiftiImage (const std::string &path, const std::vector<int> &volumes)
1010  : persistent(false)
1011 {
1012  if (volumes.empty())
1013  throw std::runtime_error("The vector of volumes is empty");
1014 
1015  nifti_brick_list brickList;
1016  this->image = nifti_image_read_bricks(path.c_str(), volumes.size(), &volumes[0], &brickList);
1017  if (this->image == NULL)
1018  throw std::runtime_error("Failed to read image from path " + path);
1019 
1020  size_t brickSize = image->nbyper * image->nx * image->ny * image->nz;
1021  image->data = calloc(1, nifti_get_volsize(image));
1022  for (int i=0; i<brickList.nbricks; i++)
1023  memcpy((char *) image->data + i * brickSize, brickList.bricks[i], brickSize);
1024  nifti_free_NBL(&brickList);
1025 
1026 #ifndef NDEBUG
1027  Rprintf("Creating NiftiImage with pointer %p (from string and volume vector)\n", this->image);
1028 #endif
1029 }
1030 
1031 inline void NiftiImage::updatePixdim (const std::vector<float> &pixdim)
1032 {
1033  const int nDims = image->dim[0];
1034  const std::vector<float> origPixdim(image->pixdim+1, image->pixdim+4);
1035 
1036  for (int i=1; i<8; i++)
1037  image->pixdim[i] = 0.0;
1038 
1039  const int pixdimLength = pixdim.size();
1040  for (int i=0; i<std::min(pixdimLength,nDims); i++)
1041  image->pixdim[i+1] = pixdim[i];
1042 
1043  if (!std::equal(origPixdim.begin(), origPixdim.begin() + std::min(3,nDims), pixdim.begin()))
1044  {
1045  mat33 scaleMatrix;
1046  for (int i=0; i<3; i++)
1047  {
1048  for (int j=0; j<3; j++)
1049  {
1050  if (i != j)
1051  scaleMatrix.m[i][j] = 0.0;
1052  else if (i >= nDims)
1053  scaleMatrix.m[i][j] = 1.0;
1054  else
1055  scaleMatrix.m[i][j] = pixdim[i] / origPixdim[i];
1056  }
1057  }
1058 
1059  if (image->qform_code > 0)
1060  {
1061  mat33 prod = nifti_mat33_mul(scaleMatrix, internal::topLeftCorner(image->qto_xyz));
1062  for (int i=0; i<3; i++)
1063  {
1064  for (int j=0; j<3; j++)
1065  image->qto_xyz.m[i][j] = prod.m[i][j];
1066  }
1067  image->qto_ijk = nifti_mat44_inverse(image->qto_xyz);
1068  nifti_mat44_to_quatern(image->qto_xyz, &image->quatern_b, &image->quatern_c, &image->quatern_d, &image->qoffset_x, &image->qoffset_y, &image->qoffset_z, NULL, NULL, NULL, &image->qfac);
1069  }
1070 
1071  if (image->sform_code > 0)
1072  {
1073  mat33 prod = nifti_mat33_mul(scaleMatrix, internal::topLeftCorner(image->sto_xyz));
1074  for (int i=0; i<3; i++)
1075  {
1076  for (int j=0; j<3; j++)
1077  image->sto_xyz.m[i][j] = prod.m[i][j];
1078  }
1079  image->sto_ijk = nifti_mat44_inverse(image->sto_xyz);
1080  }
1081  }
1082 }
1083 
1084 inline void NiftiImage::setPixunits (const std::vector<std::string> &pixunits)
1085 {
1086  for (size_t i=0; i<pixunits.size(); i++)
1087  {
1088  if (pixunits[i] == "m")
1089  image->xyz_units = NIFTI_UNITS_METER;
1090  else if (pixunits[i] == "mm")
1091  image->xyz_units = NIFTI_UNITS_MM;
1092  else if (pixunits[i] == "um")
1093  image->xyz_units = NIFTI_UNITS_MICRON;
1094  else if (pixunits[i] == "s")
1095  image->time_units = NIFTI_UNITS_SEC;
1096  else if (pixunits[i] == "ms")
1097  image->time_units = NIFTI_UNITS_MSEC;
1098  else if (pixunits[i] == "us")
1099  image->time_units = NIFTI_UNITS_USEC;
1100  else if (pixunits[i] == "Hz")
1101  image->time_units = NIFTI_UNITS_HZ;
1102  else if (pixunits[i] == "ppm")
1103  image->time_units = NIFTI_UNITS_PPM;
1104  else if (pixunits[i] == "rad/s")
1105  image->time_units = NIFTI_UNITS_RADS;
1106  }
1107 }
1108 
1109 inline NiftiImage & NiftiImage::rescale (const std::vector<float> &scales)
1110 {
1111  std::vector<float> pixdim(image->pixdim+1, image->pixdim+4);
1112 
1113  for (int i=0; i<std::min(3, int(scales.size())); i++)
1114  {
1115  if (scales[i] != 1.0)
1116  {
1117  pixdim[i] /= scales[i];
1118  image->dim[i+1] = static_cast<int>(std::floor(image->dim[i+1] * scales[i]));
1119  }
1120  }
1121 
1123  nifti_update_dims_from_array(image);
1124 
1125  // Data vector is now the wrong size, so drop it
1126  if (!persistent)
1127  nifti_image_unload(image);
1128 
1129  image->scl_slope = 0.0;
1130  image->scl_inter = 0.0;
1131 
1132  return *this;
1133 }
1134 
1135 inline NiftiImage & NiftiImage::reorient (const int icode, const int jcode, const int kcode)
1136 {
1137  if (this->isNull())
1138  return *this;
1139  if (image->qform_code == 0 && image->sform_code == 0)
1140  {
1141  Rf_warning("Image qform and sform codes are both zero, so it cannot be reoriented");
1142  return *this;
1143  }
1144 
1145  int used[6] = { 0, 0, 0, 0, 0, 0 };
1146  used[icode-1] = 1;
1147  used[jcode-1] = 1;
1148  used[kcode-1] = 1;
1149  if (used[0]+used[1] != 1 || used[2]+used[3] != 1 || used[4]+used[5] != 1)
1150  throw std::runtime_error("Each canonical axis should be used exactly once");
1151 
1152  const int codes[3] = { icode, jcode, kcode };
1153  const mat44 native = this->xform();
1154 
1155  // Create a target xform (rotation matrix only)
1156  mat33 target;
1157  for (int j=0; j<3; j++)
1158  {
1159  for (int i=0; i<3; i++)
1160  target.m[i][j] = 0.0;
1161 
1162  switch (codes[j])
1163  {
1164  case NIFTI_L2R: target.m[0][j] = 1.0; break;
1165  case NIFTI_R2L: target.m[0][j] = -1.0; break;
1166  case NIFTI_P2A: target.m[1][j] = 1.0; break;
1167  case NIFTI_A2P: target.m[1][j] = -1.0; break;
1168  case NIFTI_I2S: target.m[2][j] = 1.0; break;
1169  case NIFTI_S2I: target.m[2][j] = -1.0; break;
1170  }
1171  }
1172 
1173  // Extract (inverse of) canonical axis matrix from native xform
1174  int nicode, njcode, nkcode;
1175  nifti_mat44_to_orientation(native, &nicode, &njcode, &nkcode);
1176  int ncodes[3] = { nicode, njcode, nkcode };
1177  mat33 nativeAxesTransposed;
1178  for (int i=0; i<3; i++)
1179  {
1180  for (int j=0; j<3; j++)
1181  nativeAxesTransposed.m[i][j] = 0.0;
1182 
1183  switch (ncodes[i])
1184  {
1185  case NIFTI_L2R: nativeAxesTransposed.m[i][0] = 1.0; break;
1186  case NIFTI_R2L: nativeAxesTransposed.m[i][0] = -1.0; break;
1187  case NIFTI_P2A: nativeAxesTransposed.m[i][1] = 1.0; break;
1188  case NIFTI_A2P: nativeAxesTransposed.m[i][1] = -1.0; break;
1189  case NIFTI_I2S: nativeAxesTransposed.m[i][2] = 1.0; break;
1190  case NIFTI_S2I: nativeAxesTransposed.m[i][2] = -1.0; break;
1191  }
1192  }
1193 
1194  // Check for no-op case
1195  if (icode == nicode && jcode == njcode && kcode == nkcode)
1196  return *this;
1197 
1198  // The transform is t(approx_old_xform) %*% target_xform
1199  // The new xform is old_xform %*% transform
1200  // NB: "transform" is really 4x4, but the last row and column are filled implicitly during the multiplication loop
1201  mat33 transform = nifti_mat33_mul(nativeAxesTransposed, target);
1202  mat44 result;
1203  for (int i=0; i<4; i++)
1204  {
1205  for (int j=0; j<3; j++)
1206  result.m[i][j] = native.m[i][0] * transform.m[0][j] + native.m[i][1] * transform.m[1][j] + native.m[i][2] * transform.m[2][j];
1207 
1208  result.m[i][3] = native.m[i][3];
1209  }
1210 
1211  // Update the xforms with nonzero codes
1212  if (image->qform_code > 0)
1213  {
1214  image->qto_xyz = result;
1215  image->qto_ijk = nifti_mat44_inverse(image->qto_xyz);
1216  nifti_mat44_to_quatern(image->qto_xyz, &image->quatern_b, &image->quatern_c, &image->quatern_d, &image->qoffset_x, &image->qoffset_y, &image->qoffset_z, NULL, NULL, NULL, &image->qfac);
1217  }
1218  if (image->sform_code > 0)
1219  {
1220  image->sto_xyz = result;
1221  image->sto_ijk = nifti_mat44_inverse(image->sto_xyz);
1222  }
1223 
1224  // Extract the mapping between dimensions and the signs
1225  int locs[3], signs[3], newdim[3];
1226  float newpixdim[3];
1227  double maxes[3] = { R_NegInf, R_NegInf, R_NegInf };
1228  for (int j=0; j<3; j++)
1229  {
1230  for (int i=0; i<3; i++)
1231  {
1232  const double value = static_cast<double>(transform.m[i][j]);
1233  if (fabs(value) > maxes[j])
1234  {
1235  maxes[j] = fabs(value);
1236  signs[j] = value > 0.0 ? 1 : -1;
1237  locs[j] = i;
1238  }
1239  }
1240 
1241  // Permute dim and pixdim
1242  newdim[j] = image->dim[locs[j]+1];
1243  newpixdim[j] = image->pixdim[locs[j]+1];
1244  }
1245 
1246  // Calculate strides in target space
1247  ptrdiff_t strides[3];
1248  strides[locs[0]] = 1;
1249  for (int n=1; n<3; n++)
1250  strides[locs[n]] = strides[locs[n-1]] * image->dim[locs[n-1]+1];
1251 
1252  if (image->data != NULL)
1253  {
1254  size_t volSize = size_t(image->nx * image->ny * image->nz);
1255  size_t nVolumes = std::max(size_t(1), image->nvox / volSize);
1256 
1257  const std::vector<double> oldData = this->getData<double>();
1258  std::vector<double> newData(image->nvox);
1259 
1260  // Where the sign is negative we need to start at the end of the dimension
1261  size_t volStart = 0;
1262  for (int i=0; i<3; i++)
1263  {
1264  if (signs[i] < 0)
1265  volStart += (image->dim[i+1] - 1) * strides[i];
1266  }
1267 
1268  // Iterate over the data and place it into a new vector
1269  std::vector<double>::const_iterator it = oldData.begin();
1270  for (size_t v=0; v<nVolumes; v++)
1271  {
1272  for (int k=0; k<image->nz; k++)
1273  {
1274  ptrdiff_t offset = k * strides[2] * signs[2];
1275  for (int j=0; j<image->ny; j++)
1276  {
1277  for (int i=0; i<image->nx; i++)
1278  {
1279  newData[volStart + offset] = *it++;
1280  offset += strides[0] * signs[0];
1281  }
1282  offset += strides[1] * signs[1] - image->nx * strides[0] * signs[0];
1283  }
1284  }
1285  volStart += volSize;
1286  }
1287 
1288  // Replace the existing data in the image
1289  this->replaceData(newData);
1290  }
1291 
1292  // Copy new dims and pixdims in
1293  // NB: Old dims are used above, so this must happen last
1294  std::copy(newdim, newdim+3, image->dim+1);
1295  std::copy(newpixdim, newpixdim+3, image->pixdim+1);
1296  nifti_update_dims_from_array(image);
1297 
1298  return *this;
1299 }
1300 
1301 inline NiftiImage & NiftiImage::reorient (const std::string &orientation)
1302 {
1303  if (orientation.length() != 3)
1304  throw std::runtime_error("Orientation string should have exactly three characters");
1305 
1306  int codes[3];
1307  for (int i=0; i<3; i++)
1308  {
1309  switch(orientation[i])
1310  {
1311  case 'r': case 'R': codes[i] = NIFTI_L2R; break;
1312  case 'l': case 'L': codes[i] = NIFTI_R2L; break;
1313  case 'a': case 'A': codes[i] = NIFTI_P2A; break;
1314  case 'p': case 'P': codes[i] = NIFTI_A2P; break;
1315  case 's': case 'S': codes[i] = NIFTI_I2S; break;
1316  case 'i': case 'I': codes[i] = NIFTI_S2I; break;
1317 
1318  default:
1319  throw std::runtime_error("Orientation string is invalid");
1320  }
1321  }
1322 
1323  return reorient(codes[0], codes[1], codes[2]);
1324 }
1325 
1326 #ifdef USING_R
1327 
1328 inline NiftiImage & NiftiImage::update (const Rcpp::RObject &object)
1329 {
1330  if (Rf_isVectorList(object))
1331  {
1332  Rcpp::List list(object);
1333  nifti_1_header *header = NULL;
1334  if (this->isNull())
1335  {
1336  header = nifti_make_new_header(NULL, DT_FLOAT64);
1337  internal::updateHeader(header, list, true);
1338  }
1339  else
1340  {
1341  header = (nifti_1_header *) calloc(1, sizeof(nifti_1_header));
1342  *header = nifti_convert_nim2nhdr(image);
1343  internal::updateHeader(header, list, true);
1344  }
1345 
1346  if (header != NULL)
1347  {
1348  nifti_image *newImage = nifti_convert_nhdr2nim(*header, NULL);
1349  if (this->image->data != NULL)
1350  {
1351  size_t dataSize = nifti_get_volsize(image);
1352  newImage->data = calloc(1, dataSize);
1353  memcpy(newImage->data, image->data, dataSize);
1354  }
1355  if (!persistent)
1356  nifti_image_free(image);
1357  this->image = newImage;
1358  }
1359  }
1360  else if (object.hasAttribute("dim"))
1361  {
1362  for (int i=0; i<8; i++)
1363  image->dim[i] = 0;
1364  const std::vector<int> dimVector = object.attr("dim");
1365 
1366  const int nDims = std::min(7, int(dimVector.size()));
1367  image->dim[0] = nDims;
1368  for (int i=0; i<nDims; i++)
1369  image->dim[i+1] = dimVector[i];
1370 
1371  if (object.hasAttribute("pixdim"))
1372  {
1373  const std::vector<float> pixdimVector = object.attr("pixdim");
1374  updatePixdim(pixdimVector);
1375  }
1376 
1377  if (object.hasAttribute("pixunits"))
1378  {
1379  const std::vector<std::string> pixunitsVector = object.attr("pixunits");
1380  setPixunits(pixunitsVector);
1381  }
1382 
1383  // This NIfTI-1 library function clobbers dim[0] if the last dimension is unitary; we undo that here
1384  nifti_update_dims_from_array(image);
1385  image->dim[0] = image->ndim = nDims;
1386 
1387  image->datatype = NiftiImage::sexpTypeToNiftiType(object.sexp_type());
1388  nifti_datatype_sizes(image->datatype, &image->nbyper, NULL);
1389 
1390  if (!persistent)
1391  nifti_image_unload(image);
1392 
1393  const size_t dataSize = nifti_get_volsize(image);
1394  image->data = calloc(1, dataSize);
1395  if (image->datatype == DT_INT32)
1396  memcpy(image->data, INTEGER(object), dataSize);
1397  else
1398  memcpy(image->data, REAL(object), dataSize);
1399 
1400  image->scl_slope = 0.0;
1401  image->scl_inter = 0.0;
1402  }
1403 
1404  return *this;
1405 }
1406 
1407 #endif // USING_R
1408 
1409 inline mat44 NiftiImage::xform (const bool preferQuaternion) const
1410 {
1411  if (image == NULL)
1412  {
1413  mat44 matrix;
1414  for (int i=0; i<4; i++)
1415  {
1416  for (int j=0; j<4; j++)
1417  matrix.m[i][j] = 0.0;
1418  }
1419  return matrix;
1420  }
1421  else if (image->qform_code <= 0 && image->sform_code <= 0)
1422  {
1423  // No qform or sform so use pixdim (NB: other software may assume differently)
1424  mat44 matrix;
1425  for (int i=0; i<4; i++)
1426  {
1427  for (int j=0; j<4; j++)
1428  {
1429  if (i != j)
1430  matrix.m[i][j] = 0.0;
1431  else if (i == 3)
1432  matrix.m[3][3] = 1.0;
1433  else
1434  matrix.m[i][j] = (image->pixdim[i+1]==0.0 ? 1.0 : image->pixdim[i+1]);
1435  }
1436  }
1437  return matrix;
1438  }
1439  else if ((preferQuaternion && image->qform_code > 0) || image->sform_code <= 0)
1440  return image->qto_xyz;
1441  else
1442  return image->sto_xyz;
1443 }
1444 
1445 template <typename TargetType>
1446 inline std::vector<TargetType> NiftiImage::Block::getData () const
1447 {
1448  if (image.isNull())
1449  return std::vector<TargetType>();
1450 
1451  size_t blockSize = 1;
1452  for (int i=1; i<dimension; i++)
1453  blockSize *= image->dim[i];
1454 
1455  std::vector<TargetType> data(blockSize);
1456  internal::convertData<TargetType>(image->data, image->datatype, blockSize, data.begin(), blockSize*index);
1457 
1458  if (image.isDataScaled())
1459  std::transform(data.begin(), data.end(), data.begin(), internal::DataRescaler<TargetType>(image->scl_slope,image->scl_inter));
1460 
1461  return data;
1462 }
1463 
1464 template <typename TargetType>
1465 inline std::vector<TargetType> NiftiImage::getData () const
1466 {
1467  if (this->isNull())
1468  return std::vector<TargetType>();
1469 
1470  std::vector<TargetType> data(image->nvox);
1471  internal::convertData<TargetType>(image->data, image->datatype, image->nvox, data.begin());
1472 
1473  if (this->isDataScaled())
1474  std::transform(data.begin(), data.end(), data.begin(), internal::DataRescaler<TargetType>(image->scl_slope,image->scl_inter));
1475 
1476  return data;
1477 }
1478 
1479 inline NiftiImage & NiftiImage::changeDatatype (const short datatype)
1480 {
1481  if (this->isNull() || image->datatype == datatype)
1482  return *this;
1483 
1484  if (image->data != NULL)
1485  {
1486  int bytesPerPixel;
1487  nifti_datatype_sizes(datatype, &bytesPerPixel, NULL);
1488  void *data = calloc(image->nvox, bytesPerPixel);
1489 
1490  switch (datatype)
1491  {
1492  case DT_UINT8:
1493  internal::convertData<uint8_t>(image->data, image->datatype, image->nvox, static_cast<uint8_t *>(data));
1494  break;
1495 
1496  case DT_INT16:
1497  internal::convertData<int16_t>(image->data, image->datatype, image->nvox, static_cast<int16_t *>(data));
1498  break;
1499 
1500  case DT_INT32:
1501  internal::convertData<int32_t>(image->data, image->datatype, image->nvox, static_cast<int32_t *>(data));
1502  break;
1503 
1504  case DT_FLOAT32:
1505  internal::convertData<float>(image->data, image->datatype, image->nvox, static_cast<float *>(data));
1506  break;
1507 
1508  case DT_FLOAT64:
1509  internal::convertData<double>(image->data, image->datatype, image->nvox, static_cast<double *>(data));
1510  break;
1511 
1512  case DT_INT8:
1513  internal::convertData<int8_t>(image->data, image->datatype, image->nvox, static_cast<int8_t *>(data));
1514  break;
1515 
1516  case DT_UINT16:
1517  internal::convertData<uint16_t>(image->data, image->datatype, image->nvox, static_cast<uint16_t *>(data));
1518  break;
1519 
1520  case DT_UINT32:
1521  internal::convertData<uint32_t>(image->data, image->datatype, image->nvox, static_cast<uint32_t *>(data));
1522  break;
1523 
1524  case DT_INT64:
1525  internal::convertData<int64_t>(image->data, image->datatype, image->nvox, static_cast<int64_t *>(data));
1526  break;
1527 
1528  case DT_UINT64:
1529  internal::convertData<uint64_t>(image->data, image->datatype, image->nvox, static_cast<uint64_t *>(data));
1530  break;
1531 
1532  default:
1533  throw std::runtime_error("Unsupported data type (" + std::string(nifti_datatype_string(datatype)) + ")");
1534  }
1535 
1536  nifti_image_unload(image);
1537  image->data = data;
1538  }
1539 
1540  image->datatype = datatype;
1541  nifti_datatype_sizes(datatype, &image->nbyper, &image->swapsize);
1542 
1543  return *this;
1544 }
1545 
1546 inline NiftiImage & NiftiImage::changeDatatype (const std::string &datatype)
1547 {
1548  return changeDatatype(internal::stringToDatatype(datatype));
1549 }
1550 
1551 template <typename SourceType>
1552 inline NiftiImage & NiftiImage::replaceData (const std::vector<SourceType> &data, const short datatype)
1553 {
1554  if (this->isNull())
1555  return *this;
1556  else if (data.size() != image->nvox)
1557  throw std::runtime_error("New data length does not match the number of voxels in the image");
1558 
1559  if (datatype != DT_NONE)
1560  {
1561  nifti_image_unload(image);
1562  image->datatype = datatype;
1563  nifti_datatype_sizes(datatype, &image->nbyper, &image->swapsize);
1564  }
1565 
1566  if (image->data == NULL)
1567  image->data = calloc(image->nvox, image->nbyper);
1568  internal::replaceData<SourceType>(data.begin(), data.end(), image->data, image->datatype);
1569 
1570  image->scl_slope = 0.0;
1571  image->scl_inter = 0.0;
1572  image->cal_min = static_cast<float>(*std::min_element(data.begin(), data.end()));
1573  image->cal_max = static_cast<float>(*std::max_element(data.begin(), data.end()));
1574 
1575  return *this;
1576 }
1577 
1578 inline void NiftiImage::toFile (const std::string fileName, const short datatype) const
1579 {
1580  // Copy the source image only if the datatype will be changed
1581  NiftiImage imageToWrite(image, datatype != DT_NONE);
1582 
1583  if (datatype == DT_NONE)
1584  imageToWrite.setPersistence(true);
1585  else
1586  imageToWrite.changeDatatype(datatype);
1587 
1588  const int status = nifti_set_filenames(imageToWrite, fileName.c_str(), false, true);
1589  if (status != 0)
1590  throw std::runtime_error("Failed to set filenames for NIfTI object");
1591  nifti_image_write(imageToWrite);
1592 }
1593 
1594 inline void NiftiImage::toFile (const std::string fileName, const std::string &datatype) const
1595 {
1596  toFile(fileName, internal::stringToDatatype(datatype));
1597 }
1598 
1599 #ifdef USING_R
1600 
1601 inline Rcpp::RObject NiftiImage::toArray () const
1602 {
1603  Rcpp::RObject array;
1604 
1605  if (this->isNull())
1606  return array;
1607  else if (this->isDataScaled())
1608  {
1609  array = internal::imageDataToArray<REALSXP>(image);
1610  std::transform(REAL(array), REAL(array)+Rf_length(array), REAL(array), internal::DataRescaler<double>(image->scl_slope,image->scl_inter));
1611  }
1612  else
1613  {
1614  switch (image->datatype)
1615  {
1616  case DT_UINT8:
1617  case DT_INT16:
1618  case DT_INT32:
1619  case DT_INT8:
1620  case DT_UINT16:
1621  case DT_UINT32:
1622  case DT_INT64:
1623  case DT_UINT64:
1624  array = internal::imageDataToArray<INTSXP>(image);
1625  break;
1626 
1627  case DT_FLOAT32:
1628  case DT_FLOAT64:
1629  array = internal::imageDataToArray<REALSXP>(image);
1630  break;
1631 
1632  default:
1633  throw std::runtime_error("Unsupported data type (" + std::string(nifti_datatype_string(image->datatype)) + ")");
1634  }
1635  }
1636 
1637  internal::addAttributes(array, image);
1638  array.attr("class") = Rcpp::CharacterVector::create("niftiImage", "array");
1639  return array;
1640 }
1641 
1642 inline Rcpp::RObject NiftiImage::toPointer (const std::string label) const
1643 {
1644  if (this->isNull())
1645  return Rcpp::RObject();
1646  else
1647  {
1648  Rcpp::RObject string = Rcpp::wrap(label);
1649  internal::addAttributes(string, image, false);
1650  string.attr("class") = Rcpp::CharacterVector::create("internalImage", "niftiImage");
1651  return string;
1652  }
1653 }
1654 
1655 inline Rcpp::RObject NiftiImage::toArrayOrPointer (const bool internal, const std::string label) const
1656 {
1657  return (internal ? toPointer(label) : toArray());
1658 }
1659 
1660 inline Rcpp::RObject NiftiImage::headerToList () const
1661 {
1662  if (this->image == NULL)
1663  return Rcpp::RObject();
1664 
1665  nifti_1_header header = nifti_convert_nim2nhdr(this->image);
1666  Rcpp::List result;
1667 
1668  result["sizeof_hdr"] = header.sizeof_hdr;
1669 
1670  result["dim_info"] = int(header.dim_info);
1671  result["dim"] = std::vector<short>(header.dim, header.dim+8);
1672 
1673  result["intent_p1"] = header.intent_p1;
1674  result["intent_p2"] = header.intent_p2;
1675  result["intent_p3"] = header.intent_p3;
1676  result["intent_code"] = header.intent_code;
1677 
1678  result["datatype"] = header.datatype;
1679  result["bitpix"] = header.bitpix;
1680 
1681  result["slice_start"] = header.slice_start;
1682  result["pixdim"] = std::vector<float>(header.pixdim, header.pixdim+8);
1683  result["vox_offset"] = header.vox_offset;
1684  result["scl_slope"] = header.scl_slope;
1685  result["scl_inter"] = header.scl_inter;
1686  result["slice_end"] = header.slice_end;
1687  result["slice_code"] = int(header.slice_code);
1688  result["xyzt_units"] = int(header.xyzt_units);
1689  result["cal_max"] = header.cal_max;
1690  result["cal_min"] = header.cal_min;
1691  result["slice_duration"] = header.slice_duration;
1692  result["toffset"] = header.toffset;
1693  result["descrip"] = std::string(header.descrip, 80);
1694  result["aux_file"] = std::string(header.aux_file, 24);
1695 
1696  result["qform_code"] = header.qform_code;
1697  result["sform_code"] = header.sform_code;
1698  result["quatern_b"] = header.quatern_b;
1699  result["quatern_c"] = header.quatern_c;
1700  result["quatern_d"] = header.quatern_d;
1701  result["qoffset_x"] = header.qoffset_x;
1702  result["qoffset_y"] = header.qoffset_y;
1703  result["qoffset_z"] = header.qoffset_z;
1704  result["srow_x"] = std::vector<float>(header.srow_x, header.srow_x+4);
1705  result["srow_y"] = std::vector<float>(header.srow_y, header.srow_y+4);
1706  result["srow_z"] = std::vector<float>(header.srow_z, header.srow_z+4);
1707 
1708  result["intent_name"] = std::string(header.intent_name, 16);
1709  result["magic"] = std::string(header.magic, 4);
1710 
1711  result.attr("class") = Rcpp::CharacterVector::create("niftiHeader");
1712 
1713  return result;
1714 }
1715 
1716 #endif // USING_R
1717 
1718 } // namespace
1719 
1720 #endif
NiftiImage & reorient(const int i, const int j, const int k)
Reorient the image by permuting dimensions and potentially reversing some.
Definition: NiftiImage.h:1135
+
NiftiImage()
Default constructor.
Definition: NiftiImage.h:256
+
const int index
The location along dimension.
Definition: NiftiImage.h:56
+
static std::string xformToString(const mat44 matrix)
Convert a 4x4 xform matrix to a string describing its canonical axes.
Definition: NiftiImage.h:129
+
std::vector< int > dim() const
Return the dimensions of the image.
Definition: NiftiImage.h:442
+
const nifti_image * operator->() const
Allows a NiftiImage object to be treated as a pointer to a const nifti_image.
Definition: NiftiImage.h:364
+
bool persistent
Marker of persistence, which determines whether the nifti_image should be freed on destruction...
Definition: NiftiImage.h:188
+
std::vector< float > pixdim() const
Return the dimensions of the pixels or voxels in the image.
Definition: NiftiImage.h:454
+
NiftiImage(const std::string &path, const bool readData=true)
Initialise using a path string.
Definition: NiftiImage.h:309
+
NiftiImage & rescale(const std::vector< float > &scales)
Rescale the image, changing its image dimensions and pixel dimensions.
Definition: NiftiImage.h:1109
+
NiftiImage(nifti_image *const image, const bool copy=false)
Initialise using an existing nifti_image pointer.
Definition: NiftiImage.h:291
+
Definition: NiftiImage.h:39
+
Block & operator=(const NiftiImage &source)
Copy assignment operator, which allows a block in one image to be replaced with the contents of anoth...
Definition: NiftiImage.h:80
+
bool isNull() const
Determine whether or not the internal pointer is NULL.
Definition: NiftiImage.h:415
+
Inner class referring to a subset of an image.
Definition: NiftiImage.h:52
+
Block slice(const int i)
Extract a slice block from a 3D image.
Definition: NiftiImage.h:596
+
NiftiImage & replaceData(const std::vector< SourceType > &data, const short datatype=DT_NONE)
Replace the pixel data in the image with the contents of a vector.
Definition: NiftiImage.h:1552
+
std::vector< TargetType > getData() const
Extract a vector of data from the image, casting it to any required element type. ...
Definition: NiftiImage.h:1465
+
bool isDataScaled() const
Determine whether nontrivial scale and slope parameters are set.
Definition: NiftiImage.h:425
+
const Block slice(const int i) const
Extract a slice block from a 3D image.
Definition: NiftiImage.h:589
+
const Block volume(const int i) const
Extract a volume block from a 4D image.
Definition: NiftiImage.h:603
+
bool isPersistent() const
Determine whether or not the image is marked as persistent.
Definition: NiftiImage.h:420
+
void setPixunits(const std::vector< std::string > &pixunits)
Modify the pixel dimension units.
Definition: NiftiImage.h:1084
+
NiftiImage(const Block &source)
Initialise from a block, copying in the data.
Definition: NiftiImage.h:276
+
virtual ~NiftiImage()
Destructor which frees the wrapped pointer, unless the object is marked as persistent.
Definition: NiftiImage.h:340
+
Thin wrapper around a C-style nifti_image struct that allows C++-style destruction.
Definition: NiftiImage.h:45
+
NiftiImage(const NiftiImage &source)
Copy constructor.
Definition: NiftiImage.h:263
+
int nBlocks() const
Return the number of blocks in the image.
Definition: NiftiImage.h:558
+
const int dimension
The dimension along which the block applies (which should be the last)
Definition: NiftiImage.h:55
+
const NiftiImage & image
The parent image.
Definition: NiftiImage.h:54
+
NiftiImage & operator=(const NiftiImage &source)
Copy assignment operator, which copies from its argument.
Definition: NiftiImage.h:375
+
static int fileVersion(const std::string &path)
Get the NIfTI format version used by the file at the specified path.
Definition: NiftiImage.h:157
+
void toFile(const std::string fileName, const short datatype=DT_NONE) const
Write the image to a NIfTI-1 file.
Definition: NiftiImage.h:1578
+
void updatePixdim(const std::vector< float > &pixdim)
Modify the pixel dimensions, and potentially the xform matrices to match.
Definition: NiftiImage.h:1031
+
const Block block(const int i) const
Extract a block from the image.
Definition: NiftiImage.h:573
+
NiftiImage & setPersistence(const bool persistent)
Marked the image as persistent, so that it can be passed back to R.
Definition: NiftiImage.h:402
+
void copy(const nifti_image *source)
Copy the contents of a nifti_image to create a new image.
Definition: NiftiImage.h:662
+
mat44 xform(const bool preferQuaternion=true) const
Obtain an xform matrix, indicating the orientation of the image.
Definition: NiftiImage.h:1409
+
nifti_image * image
The wrapped nifti_image pointer.
Definition: NiftiImage.h:187
+
NiftiImage & changeDatatype(const short datatype)
Change the datatype of the image, casting the pixel data if present.
Definition: NiftiImage.h:1479
+
std::vector< TargetType > getData() const
Extract a vector of data from a block, casting it to any required element type.
Definition: NiftiImage.h:1446
+
int nDims() const
Return the number of dimensions in the image.
Definition: NiftiImage.h:430
+
Block volume(const int i)
Extract a volume block from a 4D image.
Definition: NiftiImage.h:610
+
NiftiImage & drop()
Drop unitary dimensions.
Definition: NiftiImage.h:468
+
Block(const NiftiImage &image, const int dimension, const int index)
Standard constructor for this class.
Definition: NiftiImage.h:65
+
NiftiImage & dropData()
Drop the data from the image, retaining only the metadata.
Definition: NiftiImage.h:509
+
Block block(const int i)
Extract a block from the image.
Definition: NiftiImage.h:582
+
+ + + + diff --git a/inst/doxygen/html/annotated.html b/inst/doxygen/html/annotated.html new file mode 100644 index 0000000..7d2a4e8 --- /dev/null +++ b/inst/doxygen/html/annotated.html @@ -0,0 +1,84 @@ + + + + + + + +RNifti: Class List + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
[detail level 123]
+ + + +
 NRNifti
 CNiftiImageThin wrapper around a C-style nifti_image struct that allows C++-style destruction
 CBlockInner class referring to a subset of an image
+
+
+ + + + diff --git a/inst/doxygen/html/bc_s.png b/inst/doxygen/html/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/inst/doxygen/html/bdwn.png b/inst/doxygen/html/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T + + + + + + +RNifti: Member List + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
NiftiImage Member List
+
+
+ +

This is the complete list of members for NiftiImage, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
copy(nifti_image *const source)NiftiImageinlineprotected
copy(const NiftiImage &source)NiftiImageinlineprotected
copy(const Block &source)NiftiImageinlineprotected
drop()NiftiImageinline
headerToList() constNiftiImageinline
imageNiftiImageprotected
initFromArray(const Rcpp::RObject &object, const bool copyData=true)NiftiImageinlineprotected
initFromList(const Rcpp::RObject &object)NiftiImageinlineprotected
initFromMriImage(const Rcpp::RObject &object, const bool copyData=true)NiftiImageinlineprotected
initFromNiftiS4(const Rcpp::RObject &object, const bool copyData=true)NiftiImageinlineprotected
isNull() constNiftiImageinline
isPersistent() constNiftiImageinline
nDims() constNiftiImageinline
NiftiImage()NiftiImageinline
NiftiImage(const NiftiImage &source)NiftiImageinline
NiftiImage(nifti_image *const image, const bool copy=false)NiftiImageinline
NiftiImage(const std::string &path, const bool readData=true)NiftiImageinline
NiftiImage(const SEXP object, const bool readData=true)NiftiImageinline
operator nifti_image *() constNiftiImageinline
operator->() constNiftiImageinline
operator=(const NiftiImage &source)NiftiImageinline
operator=(const Block &source)NiftiImageinline
persistentNiftiImageprotected
rescale(const std::vector< float > &scales)NiftiImageinline
setPersistence(const bool persistent)NiftiImageinline
setPixunits(const std::vector< std::string > &pixunits)NiftiImageinlineprotected
sexpTypeToNiftiType(const int sexpType)NiftiImageinlinestatic
slice(const int i) constNiftiImageinline
slice(const int i)NiftiImageinline
toArray() constNiftiImageinline
toArrayOrPointer(const bool internal, const std::string label) constNiftiImageinline
toFile(const std::string fileName, const short datatype) constNiftiImageinline
toFile(const std::string fileName, const std::string &datatype) constNiftiImageinline
toPointer(const std::string label) constNiftiImageinline
update(const SEXP array)NiftiImageinline
updatePixdim(const std::vector< float > &pixdim)NiftiImageinlineprotected
volume(const int i) constNiftiImageinline
volume(const int i)NiftiImageinline
xform(const bool preferQuaternion=true) constNiftiImageinline
~NiftiImage()NiftiImageinline
+ + + + diff --git a/inst/doxygen/html/class_nifti_image.html b/inst/doxygen/html/class_nifti_image.html new file mode 100644 index 0000000..9adaf4d --- /dev/null +++ b/inst/doxygen/html/class_nifti_image.html @@ -0,0 +1,1399 @@ + + + + + + + +RNifti: NiftiImage Class Reference + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Thin wrapper around a C-style nifti_image struct that allows C++-style destruction. + More...

+ +

#include <NiftiImage.h>

+ + + + + +

+Classes

struct  Block
 Inner class referring to a subset of an image. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

NiftiImage ()
 Default constructor.
 
 NiftiImage (const NiftiImage &source)
 Copy constructor. More...
 
 NiftiImage (nifti_image *const image, const bool copy=false)
 Initialise using an existing nifti_image pointer. More...
 
 NiftiImage (const std::string &path, const bool readData=true)
 Initialise using a path string. More...
 
 NiftiImage (const SEXP object, const bool readData=true)
 Initialise from an R object. More...
 
~NiftiImage ()
 Destructor which frees the wrapped pointer, unless the object is marked as persistent.
 
operator nifti_image * () const
 Allows a NiftiImage object to be treated as a pointer to a nifti_image.
 
+nifti_image * operator-> () const
 Allows a NiftiImage object to be treated as a pointer to a nifti_image.
 
NiftiImageoperator= (const NiftiImage &source)
 Copy assignment operator, which copies from its argument. More...
 
NiftiImageoperator= (const Block &source)
 Copy assignment operator, which allows a block to be used to replace the contents of a suitably sized image. More...
 
void setPersistence (const bool persistent)
 Allows the image to be marked as persistent, so that it can be passed back to R. More...
 
+bool isNull () const
 Determines whether or not the internal pointer is NULL.
 
+bool isPersistent () const
 Determines whether or not the image is marked as persistent.
 
+int nDims () const
 Returns the number of dimensions in the image.
 
NiftiImagedrop ()
 Drop unitary dimensions. More...
 
void rescale (const std::vector< float > &scales)
 Rescales the image, changing its image dimensions and pixel dimensions. More...
 
void update (const SEXP array)
 Update the image from an R array. More...
 
mat44 xform (const bool preferQuaternion=true) const
 Obtain an xform matrix, indicating the orientation of the image. More...
 
const Block slice (const int i) const
 Extract a slice block from a 3D image. More...
 
Block slice (const int i)
 Extract a slice block from a 3D image. More...
 
const Block volume (const int i) const
 Extract a volume block from a 4D image. More...
 
Block volume (const int i)
 Extract a volume block from a 4D image. More...
 
void toFile (const std::string fileName, const short datatype) const
 Write the image to a NIfTI-1 file. More...
 
void toFile (const std::string fileName, const std::string &datatype) const
 Write the image to a NIfTI-1 file. More...
 
Rcpp::RObject toArray () const
 Create an R array from the image. More...
 
Rcpp::RObject toPointer (const std::string label) const
 Create an internal image to pass back to R. More...
 
Rcpp::RObject toArrayOrPointer (const bool internal, const std::string label) const
 A conditional method that calls either toArray or toPointer. More...
 
Rcpp::RObject headerToList () const
 Create an R list containing raw image metadata. More...
 
+ + + + +

+Static Public Member Functions

static short sexpTypeToNiftiType (const int sexpType)
 Convert between R SEXP object type and nifti_image datatype codes. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Protected Member Functions

void copy (nifti_image *const source)
 Copy the contents of a nifti_image to create a new image. More...
 
void copy (const NiftiImage &source)
 Copy the contents of another NiftiImage to create a new image. More...
 
void copy (const Block &source)
 Copy the contents of a Block to create a new image. More...
 
void initFromNiftiS4 (const Rcpp::RObject &object, const bool copyData=true)
 Initialise the object from an S4 object of class "nifti". More...
 
void initFromMriImage (const Rcpp::RObject &object, const bool copyData=true)
 Initialise the object from a reference object of class "MriImage". More...
 
void initFromList (const Rcpp::RObject &object)
 Initialise the object from an R list with named elements, which can only contain metadata. More...
 
void initFromArray (const Rcpp::RObject &object, const bool copyData=true)
 Initialise the object from an R array. More...
 
void updatePixdim (const std::vector< float > &pixdim)
 Modify the pixel dimensions, and potentially the xform matrices to match. More...
 
void setPixunits (const std::vector< std::string > &pixunits)
 Modify the pixel dimension units. More...
 
+ + + + + + + +

+Protected Attributes

+nifti_image * image
 The wrapped nifti_image pointer.
 
+bool persistent
 Marker of persistence, which determines whether the nifti_image should be freed on destruction.
 
+

Detailed Description

+

Thin wrapper around a C-style nifti_image struct that allows C++-style destruction.

+
Author
Jon Clayden
+

Constructor & Destructor Documentation

+ +

§ NiftiImage() [1/4]

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage::NiftiImage (const NiftiImagesource)
+
+inline
+
+ +

Copy constructor.

+
Parameters
+ + +
sourceAnother NiftiImage object
+
+
+ +
+
+ +

§ NiftiImage() [2/4]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
NiftiImage::NiftiImage (nifti_image *const image,
const bool copy = false 
)
+
+inline
+
+ +

Initialise using an existing nifti_image pointer.

+
Parameters
+ + + +
imageAn existing nifti_image pointer, possibly NULL
copyIf true, the image data will be copied; otherwise this object just wraps the pointer passed to it
+
+
+ +
+
+ +

§ NiftiImage() [3/4]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
NiftiImage::NiftiImage (const std::string & path,
const bool readData = true 
)
+
+inline
+
+ +

Initialise using a path string.

+
Parameters
+ + + +
pathA string specifying a path to a valid NIfTI-1 file, possibly gzipped
readDataIf true, the data will be read as well as the metadata
+
+
+
Exceptions
+ + +
runtime_errorIf reading from the file fails
+
+
+ +
+
+ +

§ NiftiImage() [4/4]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
NiftiImage::NiftiImage (const SEXP object,
const bool readData = true 
)
+
+inline
+
+ +

Initialise from an R object.

+
Parameters
+ + + +
objectThe source object
readDataIf true, the data will be copied as well as the metadata
+
+
+ +
+
+

Member Function Documentation

+ +

§ copy() [1/3]

+ +
+
+ + + + + +
+ + + + + + + + +
void NiftiImage::copy (nifti_image *const source)
+
+inlineprotected
+
+ +

Copy the contents of a nifti_image to create a new image.

+
Parameters
+ + +
sourceA pointer to a nifti_image
+
+
+ +
+
+ +

§ copy() [2/3]

+ +
+
+ + + + + +
+ + + + + + + + +
void NiftiImage::copy (const NiftiImagesource)
+
+inlineprotected
+
+ +

Copy the contents of another NiftiImage to create a new image.

+
Parameters
+ + +
sourceA reference to a NiftiImage
+
+
+ +
+
+ +

§ copy() [3/3]

+ +
+
+ + + + + +
+ + + + + + + + +
void NiftiImage::copy (const Blocksource)
+
+inlineprotected
+
+ +

Copy the contents of a Block to create a new image.

+
Parameters
+ + +
sourceA reference to a Block
+
+
+ +
+
+ +

§ drop()

+ +
+
+ + + + + +
+ + + + + + + +
NiftiImage& NiftiImage::drop ()
+
+inline
+
+ +

Drop unitary dimensions.

+
Returns
Self, after possibly reducing the dimensionality of the image
+
Note
This function differs from its R equivalent in only dropping unitary dimensions after the last nonunitary one
+ +
+
+ +

§ headerToList()

+ +
+
+ + + + + +
+ + + + + + + +
Rcpp::RObject NiftiImage::headerToList () const
+
+inline
+
+ +

Create an R list containing raw image metadata.

+
Returns
An R list
+ +
+
+ +

§ initFromArray()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void NiftiImage::initFromArray (const Rcpp::RObject & object,
const bool copyData = true 
)
+
+inlineprotected
+
+ +

Initialise the object from an R array.

+
Parameters
+ + + +
objectThe source object
copyDataIf true, the data are copied in; otherwise just the metadata is extracted
+
+
+ +
+
+ +

§ initFromList()

+ +
+
+ + + + + +
+ + + + + + + + +
void NiftiImage::initFromList (const Rcpp::RObject & object)
+
+inlineprotected
+
+ +

Initialise the object from an R list with named elements, which can only contain metadata.

+
Parameters
+ + +
objectThe source object
+
+
+ +
+
+ +

§ initFromMriImage()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void NiftiImage::initFromMriImage (const Rcpp::RObject & object,
const bool copyData = true 
)
+
+inlineprotected
+
+ +

Initialise the object from a reference object of class "MriImage".

+
Parameters
+ + + +
objectThe source object
copyDataIf true, the data are copied in; otherwise just the metadata is extracted
+
+
+ +
+
+ +

§ initFromNiftiS4()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void NiftiImage::initFromNiftiS4 (const Rcpp::RObject & object,
const bool copyData = true 
)
+
+inlineprotected
+
+ +

Initialise the object from an S4 object of class "nifti".

+
Parameters
+ + + +
objectThe source object
copyDataIf true, the data are copied in; otherwise just the metadata is extracted
+
+
+ +
+
+ +

§ operator=() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage& NiftiImage::operator= (const NiftiImagesource)
+
+inline
+
+ +

Copy assignment operator, which copies from its argument.

+
Parameters
+ + +
sourceAnother NiftiImage
+
+
+ +
+
+ +

§ operator=() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage& NiftiImage::operator= (const Blocksource)
+
+inline
+
+ +

Copy assignment operator, which allows a block to be used to replace the contents of a suitably sized image.

+
Parameters
+ + +
sourceA reference to a suitable Block object
+
+
+ +
+
+ +

§ rescale()

+ +
+
+ + + + + +
+ + + + + + + + +
void NiftiImage::rescale (const std::vector< float > & scales)
+
+inline
+
+ +

Rescales the image, changing its image dimensions and pixel dimensions.

+
Parameters
+ + +
scalesVector of scale factors along each dimension
+
+
+
Note
No interpolation is performed on the pixel data, which is simply dropped
+ +
+
+ +

§ setPersistence()

+ +
+
+ + + + + +
+ + + + + + + + +
void NiftiImage::setPersistence (const bool persistent)
+
+inline
+
+ +

Allows the image to be marked as persistent, so that it can be passed back to R.

+
Parameters
+ + +
persistentThe new persistence state of the object
+
+
+ +
+
+ +

§ setPixunits()

+ +
+
+ + + + + +
+ + + + + + + + +
void NiftiImage::setPixunits (const std::vector< std::string > & pixunits)
+
+inlineprotected
+
+ +

Modify the pixel dimension units.

+
Parameters
+ + +
pixunitsVector of new pixel units, specified using their standard abbreviations
+
+
+ +
+
+ +

§ sexpTypeToNiftiType()

+ +
+
+ + + + + +
+ + + + + + + + +
static short NiftiImage::sexpTypeToNiftiType (const int sexpType)
+
+inlinestatic
+
+ +

Convert between R SEXP object type and nifti_image datatype codes.

+
Parameters
+ + +
sexpTypeA numeric R SEXP type code
+
+
+
Returns
A nifti_image datatype code
+
Exceptions
+ + +
runtime_errorIf a non-numeric type is passed
+
+
+ +
+
+ +

§ slice() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const Block NiftiImage::slice (const int i) const
+
+inline
+
+ +

Extract a slice block from a 3D image.

+
Parameters
+ + +
iThe slice number required
+
+
+
Returns
A Block object
+ +
+
+ +

§ slice() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
Block NiftiImage::slice (const int i)
+
+inline
+
+ +

Extract a slice block from a 3D image.

+
Parameters
+ + +
iThe slice number required
+
+
+
Returns
A Block object
+ +
+
+ +

§ toArray()

+ +
+
+ + + + + +
+ + + + + + + +
Rcpp::RObject NiftiImage::toArray () const
+
+inline
+
+ +

Create an R array from the image.

+
Returns
A numeric array object with an external pointer attribute
+ +
+
+ +

§ toArrayOrPointer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
Rcpp::RObject NiftiImage::toArrayOrPointer (const bool internal,
const std::string label 
) const
+
+inline
+
+ +

A conditional method that calls either toArray or toPointer.

+
Parameters
+ + + +
internalIf true, toPointer will be called; otherwise toArray
labelA string labelling the image
+
+
+
Returns
An R object
+ +
+
+ +

§ toFile() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void NiftiImage::toFile (const std::string fileName,
const short datatype 
) const
+
+inline
+
+ +

Write the image to a NIfTI-1 file.

+
Parameters
+ + + +
fileNameThe file name to write to, with appropriate suffix (e.g. ".nii.gz")
datatypeThe datatype to use when writing the file
+
+
+ +
+
+ +

§ toFile() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void NiftiImage::toFile (const std::string fileName,
const std::string & datatype 
) const
+
+inline
+
+ +

Write the image to a NIfTI-1 file.

+
Parameters
+ + + +
fileNameThe file name to write to, with appropriate suffix (e.g. ".nii.gz")
datatypeThe datatype to use when writing the file, or "auto"
+
+
+ +
+
+ +

§ toPointer()

+ +
+
+ + + + + +
+ + + + + + + + +
Rcpp::RObject NiftiImage::toPointer (const std::string label) const
+
+inline
+
+ +

Create an internal image to pass back to R.

+
Parameters
+ + +
labelA string labelling the image
+
+
+
Returns
An R character string with additional attributes
+ +
+
+ +

§ update()

+ +
+
+ + + + + +
+ + + + + + + + +
void NiftiImage::update (const SEXP array)
+
+inline
+
+ +

Update the image from an R array.

+
Parameters
+ + +
arrayAn R array object
+
+
+ +
+
+ +

§ updatePixdim()

+ +
+
+ + + + + +
+ + + + + + + + +
void NiftiImage::updatePixdim (const std::vector< float > & pixdim)
+
+inlineprotected
+
+ +

Modify the pixel dimensions, and potentially the xform matrices to match.

+
Parameters
+ + +
pixdimVector of new pixel dimensions
+
+
+ +
+
+ +

§ volume() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const Block NiftiImage::volume (const int i) const
+
+inline
+
+ +

Extract a volume block from a 4D image.

+
Parameters
+ + +
iThe volume number required
+
+
+
Returns
A Block object
+ +
+
+ +

§ volume() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
Block NiftiImage::volume (const int i)
+
+inline
+
+ +

Extract a volume block from a 4D image.

+
Parameters
+ + +
iThe volume number required
+
+
+
Returns
A Block object
+ +
+
+ +

§ xform()

+ +
+
+ + + + + +
+ + + + + + + + +
mat44 NiftiImage::xform (const bool preferQuaternion = true) const
+
+inline
+
+ +

Obtain an xform matrix, indicating the orientation of the image.

+
Parameters
+ + +
preferQuaternionIf true, use the qform matrix in preference to the sform
+
+
+
Returns
A 4x4 matrix
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/inst/doxygen/html/class_r_nifti_1_1_nifti_image-members.html b/inst/doxygen/html/class_r_nifti_1_1_nifti_image-members.html new file mode 100644 index 0000000..397b961 --- /dev/null +++ b/inst/doxygen/html/class_r_nifti_1_1_nifti_image-members.html @@ -0,0 +1,132 @@ + + + + + + + +RNifti: Member List + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
RNifti::NiftiImage Member List
+
+
+ +

This is the complete list of members for RNifti::NiftiImage, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
block(const int i) constRNifti::NiftiImageinline
block(const int i)RNifti::NiftiImageinline
changeDatatype(const short datatype)RNifti::NiftiImageinline
changeDatatype(const std::string &datatype)RNifti::NiftiImageinline
copy(const nifti_image *source)RNifti::NiftiImageinlineprotected
copy(const NiftiImage &source)RNifti::NiftiImageinlineprotected
copy(const Block &source)RNifti::NiftiImageinlineprotected
dim() constRNifti::NiftiImageinline
drop()RNifti::NiftiImageinline
dropData()RNifti::NiftiImageinline
fileVersion(const std::string &path)RNifti::NiftiImageinlinestatic
getData() constRNifti::NiftiImageinline
imageRNifti::NiftiImageprotected
isDataScaled() constRNifti::NiftiImageinline
isNull() constRNifti::NiftiImageinline
isPersistent() constRNifti::NiftiImageinline
nBlocks() constRNifti::NiftiImageinline
nDims() constRNifti::NiftiImageinline
NiftiImage()RNifti::NiftiImageinline
NiftiImage(const NiftiImage &source)RNifti::NiftiImageinline
NiftiImage(const Block &source)RNifti::NiftiImageinline
NiftiImage(nifti_image *const image, const bool copy=false)RNifti::NiftiImageinline
NiftiImage(const std::string &path, const bool readData=true)RNifti::NiftiImageinline
NiftiImage(const std::string &path, const std::vector< int > &volumes)RNifti::NiftiImageinline
operator const nifti_image *() constRNifti::NiftiImageinline
operator nifti_image *()RNifti::NiftiImageinline
operator->() constRNifti::NiftiImageinline
operator->()RNifti::NiftiImageinline
operator=(const NiftiImage &source)RNifti::NiftiImageinline
operator=(const Block &source)RNifti::NiftiImageinline
persistentRNifti::NiftiImageprotected
pixdim() constRNifti::NiftiImageinline
reorient(const int i, const int j, const int k)RNifti::NiftiImageinline
reorient(const std::string &orientation)RNifti::NiftiImageinline
replaceData(const std::vector< SourceType > &data, const short datatype=DT_NONE)RNifti::NiftiImageinline
rescale(const std::vector< float > &scales)RNifti::NiftiImageinline
setPersistence(const bool persistent)RNifti::NiftiImageinline
setPixunits(const std::vector< std::string > &pixunits)RNifti::NiftiImageinlineprotected
slice(const int i) constRNifti::NiftiImageinline
slice(const int i)RNifti::NiftiImageinline
toFile(const std::string fileName, const short datatype=DT_NONE) constRNifti::NiftiImageinline
toFile(const std::string fileName, const std::string &datatype) constRNifti::NiftiImageinline
updatePixdim(const std::vector< float > &pixdim)RNifti::NiftiImageinlineprotected
volume(const int i) constRNifti::NiftiImageinline
volume(const int i)RNifti::NiftiImageinline
xform(const bool preferQuaternion=true) constRNifti::NiftiImageinline
xformToString(const mat44 matrix)RNifti::NiftiImageinlinestatic
~NiftiImage()RNifti::NiftiImageinlinevirtual
+ + + + diff --git a/inst/doxygen/html/class_r_nifti_1_1_nifti_image.html b/inst/doxygen/html/class_r_nifti_1_1_nifti_image.html new file mode 100644 index 0000000..e1ae3df --- /dev/null +++ b/inst/doxygen/html/class_r_nifti_1_1_nifti_image.html @@ -0,0 +1,1496 @@ + + + + + + + +RNifti: RNifti::NiftiImage Class Reference + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+ +
+ +

Thin wrapper around a C-style nifti_image struct that allows C++-style destruction. + More...

+ +

#include <NiftiImage.h>

+ + + + + +

+Classes

struct  Block
 Inner class referring to a subset of an image. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

NiftiImage ()
 Default constructor.
 
 NiftiImage (const NiftiImage &source)
 Copy constructor. More...
 
 NiftiImage (const Block &source)
 Initialise from a block, copying in the data. More...
 
 NiftiImage (nifti_image *const image, const bool copy=false)
 Initialise using an existing nifti_image pointer. More...
 
 NiftiImage (const std::string &path, const bool readData=true)
 Initialise using a path string. More...
 
 NiftiImage (const std::string &path, const std::vector< int > &volumes)
 Initialise using a path string and sequence of required volumes. More...
 
+virtual ~NiftiImage ()
 Destructor which frees the wrapped pointer, unless the object is marked as persistent.
 
operator const nifti_image * () const
 Allows a NiftiImage object to be treated as a pointer to a const nifti_image.
 
operator nifti_image * ()
 Allows a NiftiImage object to be treated as a pointer to a nifti_image.
 
+const nifti_image * operator-> () const
 Allows a NiftiImage object to be treated as a pointer to a const nifti_image.
 
+nifti_image * operator-> ()
 Allows a NiftiImage object to be treated as a pointer to a nifti_image.
 
NiftiImageoperator= (const NiftiImage &source)
 Copy assignment operator, which copies from its argument. More...
 
NiftiImageoperator= (const Block &source)
 Copy assignment operator, which allows a block to be used to replace the contents of a suitably sized image. More...
 
NiftiImagesetPersistence (const bool persistent)
 Marked the image as persistent, so that it can be passed back to R. More...
 
+bool isNull () const
 Determine whether or not the internal pointer is NULL.
 
+bool isPersistent () const
 Determine whether or not the image is marked as persistent.
 
+bool isDataScaled () const
 Determine whether nontrivial scale and slope parameters are set.
 
+int nDims () const
 Return the number of dimensions in the image.
 
std::vector< int > dim () const
 Return the dimensions of the image. More...
 
std::vector< float > pixdim () const
 Return the dimensions of the pixels or voxels in the image. More...
 
NiftiImagedrop ()
 Drop unitary dimensions. More...
 
+template<typename TargetType >
std::vector< TargetType > getData () const
 Extract a vector of data from the image, casting it to any required element type.
 
NiftiImagechangeDatatype (const short datatype)
 Change the datatype of the image, casting the pixel data if present. More...
 
NiftiImagechangeDatatype (const std::string &datatype)
 Change the datatype of the image, casting the pixel data if present. More...
 
template<typename SourceType >
NiftiImagereplaceData (const std::vector< SourceType > &data, const short datatype=DT_NONE)
 Replace the pixel data in the image with the contents of a vector. More...
 
+NiftiImagedropData ()
 Drop the data from the image, retaining only the metadata.
 
NiftiImagerescale (const std::vector< float > &scales)
 Rescale the image, changing its image dimensions and pixel dimensions. More...
 
NiftiImagereorient (const int i, const int j, const int k)
 Reorient the image by permuting dimensions and potentially reversing some. More...
 
NiftiImagereorient (const std::string &orientation)
 Reorient the image by permuting dimensions and potentially reversing some. More...
 
mat44 xform (const bool preferQuaternion=true) const
 Obtain an xform matrix, indicating the orientation of the image. More...
 
+int nBlocks () const
 Return the number of blocks in the image.
 
const Block block (const int i) const
 Extract a block from the image. More...
 
Block block (const int i)
 Extract a block from the image. More...
 
const Block slice (const int i) const
 Extract a slice block from a 3D image. More...
 
Block slice (const int i)
 Extract a slice block from a 3D image. More...
 
const Block volume (const int i) const
 Extract a volume block from a 4D image. More...
 
Block volume (const int i)
 Extract a volume block from a 4D image. More...
 
void toFile (const std::string fileName, const short datatype=DT_NONE) const
 Write the image to a NIfTI-1 file. More...
 
void toFile (const std::string fileName, const std::string &datatype) const
 Write the image to a NIfTI-1 file. More...
 
+ + + + + + + +

+Static Public Member Functions

static std::string xformToString (const mat44 matrix)
 Convert a 4x4 xform matrix to a string describing its canonical axes. More...
 
static int fileVersion (const std::string &path)
 Get the NIfTI format version used by the file at the specified path. More...
 
+ + + + + + + + + + + + + + + + +

+Protected Member Functions

void copy (const nifti_image *source)
 Copy the contents of a nifti_image to create a new image. More...
 
void copy (const NiftiImage &source)
 Copy the contents of another NiftiImage to create a new image. More...
 
void copy (const Block &source)
 Copy the contents of a Block to create a new image. More...
 
void updatePixdim (const std::vector< float > &pixdim)
 Modify the pixel dimensions, and potentially the xform matrices to match. More...
 
void setPixunits (const std::vector< std::string > &pixunits)
 Modify the pixel dimension units. More...
 
+ + + + + + + +

+Protected Attributes

+nifti_image * image
 The wrapped nifti_image pointer.
 
+bool persistent
 Marker of persistence, which determines whether the nifti_image should be freed on destruction.
 
+

Detailed Description

+

Thin wrapper around a C-style nifti_image struct that allows C++-style destruction.

+
Author
Jon Clayden
+

Constructor & Destructor Documentation

+ +

◆ NiftiImage() [1/5]

+ +
+
+ + + + + +
+ + + + + + + + +
RNifti::NiftiImage::NiftiImage (const NiftiImagesource)
+
+inline
+
+ +

Copy constructor.

+
Parameters
+ + +
sourceAnother NiftiImage object
+
+
+ +
+
+ +

◆ NiftiImage() [2/5]

+ +
+
+ + + + + +
+ + + + + + + + +
RNifti::NiftiImage::NiftiImage (const Blocksource)
+
+inline
+
+ +

Initialise from a block, copying in the data.

+
Parameters
+ + +
sourceA Block object, referring to part of another NiftiImage
+
+
+ +
+
+ +

◆ NiftiImage() [3/5]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
RNifti::NiftiImage::NiftiImage (nifti_image *const image,
const bool copy = false 
)
+
+inline
+
+ +

Initialise using an existing nifti_image pointer.

+
Parameters
+ + + +
imageAn existing nifti_image pointer, possibly NULL
copyIf true, the image data will be copied; otherwise this object just wraps the pointer passed to it
+
+
+ +
+
+ +

◆ NiftiImage() [4/5]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
RNifti::NiftiImage::NiftiImage (const std::string & path,
const bool readData = true 
)
+
+inline
+
+ +

Initialise using a path string.

+
Parameters
+ + + +
pathA string specifying a path to a valid NIfTI-1 file, possibly gzipped
readDataIf true, the data will be read as well as the metadata
+
+
+
Exceptions
+ + +
runtime_errorIf reading from the file fails
+
+
+ +
+
+ +

◆ NiftiImage() [5/5]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
RNifti::NiftiImage::NiftiImage (const std::string & path,
const std::vector< int > & volumes 
)
+
+inline
+
+ +

Initialise using a path string and sequence of required volumes.

+
Parameters
+ + + +
pathA string specifying a path to a valid NIfTI-1 file, possibly gzipped
volumesThe volumes to read in (squashing all dimensions above the third together)
+
+
+
Exceptions
+ + +
runtime_errorIf reading from the file fails, or volumes is empty
+
+
+ +
+
+

Member Function Documentation

+ +

◆ block() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const Block RNifti::NiftiImage::block (const int i) const
+
+inline
+
+ +

Extract a block from the image.

+
Parameters
+ + +
iThe block number required
+
+
+
Returns
A Block object
+
Note
slice and volume are variants of this function specific to 3D and 4D images, respectively, which may be preferred in some cases for clarity
+ +
+
+ +

◆ block() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
Block RNifti::NiftiImage::block (const int i)
+
+inline
+
+ +

Extract a block from the image.

+
Parameters
+ + +
iThe block number required
+
+
+
Returns
A Block object
+
Note
slice and volume are variants of this function specific to 3D and 4D images, respectively, which may be preferred in some cases for clarity
+ +
+
+ +

◆ changeDatatype() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage & RNifti::NiftiImage::changeDatatype (const short datatype)
+
+inline
+
+ +

Change the datatype of the image, casting the pixel data if present.

+
Parameters
+ + +
datatypeA NIfTI datatype code
+
+
+ +
+
+ +

◆ changeDatatype() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage & RNifti::NiftiImage::changeDatatype (const std::string & datatype)
+
+inline
+
+ +

Change the datatype of the image, casting the pixel data if present.

+
Parameters
+ + +
datatypeA string specifying the new datatype
+
+
+ +
+
+ +

◆ copy() [1/3]

+ +
+
+ + + + + +
+ + + + + + + + +
void RNifti::NiftiImage::copy (const nifti_image * source)
+
+inlineprotected
+
+ +

Copy the contents of a nifti_image to create a new image.

+
Parameters
+ + +
sourceA pointer to a nifti_image
+
+
+ +
+
+ +

◆ copy() [2/3]

+ +
+
+ + + + + +
+ + + + + + + + +
void RNifti::NiftiImage::copy (const NiftiImagesource)
+
+inlineprotected
+
+ +

Copy the contents of another NiftiImage to create a new image.

+
Parameters
+ + +
sourceA reference to a NiftiImage
+
+
+ +
+
+ +

◆ copy() [3/3]

+ +
+
+ + + + + +
+ + + + + + + + +
void RNifti::NiftiImage::copy (const Blocksource)
+
+inlineprotected
+
+ +

Copy the contents of a Block to create a new image.

+
Parameters
+ + +
sourceA reference to a Block
+
+
+ +
+
+ +

◆ dim()

+ +
+
+ + + + + +
+ + + + + + + +
std::vector<int> RNifti::NiftiImage::dim () const
+
+inline
+
+ +

Return the dimensions of the image.

+
Returns
A vector of integers giving the width in each dimension
+ +
+
+ +

◆ drop()

+ +
+
+ + + + + +
+ + + + + + + +
NiftiImage& RNifti::NiftiImage::drop ()
+
+inline
+
+ +

Drop unitary dimensions.

+
Returns
Self, after possibly reducing the dimensionality of the image
+
Note
This function differs from its R equivalent in only dropping unitary dimensions after the last nonunitary one
+ +
+
+ +

◆ fileVersion()

+ +
+
+ + + + + +
+ + + + + + + + +
static int RNifti::NiftiImage::fileVersion (const std::string & path)
+
+inlinestatic
+
+ +

Get the NIfTI format version used by the file at the specified path.

+
Parameters
+ + +
pathA string specifying a file path
+
+
+
Returns
An integer: -1 if the file is not present or not valid, 0 for ANALYZE-7.5, or a value greater than 0 for NIfTI
+ +
+
+ +

◆ operator=() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage& RNifti::NiftiImage::operator= (const NiftiImagesource)
+
+inline
+
+ +

Copy assignment operator, which copies from its argument.

+
Parameters
+ + +
sourceAnother NiftiImage
+
+
+ +
+
+ +

◆ operator=() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage& RNifti::NiftiImage::operator= (const Blocksource)
+
+inline
+
+ +

Copy assignment operator, which allows a block to be used to replace the contents of a suitably sized image.

+
Parameters
+ + +
sourceA reference to a suitable Block object
+
+
+ +
+
+ +

◆ pixdim()

+ +
+
+ + + + + +
+ + + + + + + +
std::vector<float> RNifti::NiftiImage::pixdim () const
+
+inline
+
+ +

Return the dimensions of the pixels or voxels in the image.

+
Returns
A vector of floating-point values giving the pixel width in each dimension
+ +
+
+ +

◆ reorient() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
NiftiImage & RNifti::NiftiImage::reorient (const int i,
const int j,
const int k 
)
+
+inline
+
+ +

Reorient the image by permuting dimensions and potentially reversing some.

+
Parameters
+ + +
i,j,kConstants such as NIFTI_L2R, NIFTI_P2A and NIFTI_I2S, giving the canonical axes to reorient to
+
+
+
Note
The pixel data is reordered, but not resampled. The xform matrices will also be adjusted in line with the transformation
+ +
+
+ +

◆ reorient() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage & RNifti::NiftiImage::reorient (const std::string & orientation)
+
+inline
+
+ +

Reorient the image by permuting dimensions and potentially reversing some.

+
Parameters
+ + +
orientationA string containing some permutation of the letters L or R, P or A, I or S, giving the canonical axes to reorient to
+
+
+
Note
The pixel data is reordered, but not resampled. The xform matrices will also be adjusted in line with the transformation
+ +
+
+ +

◆ replaceData()

+ +
+
+
+template<typename SourceType >
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
NiftiImage & RNifti::NiftiImage::replaceData (const std::vector< SourceType > & data,
const short datatype = DT_NONE 
)
+
+inline
+
+ +

Replace the pixel data in the image with the contents of a vector.

+
Parameters
+ + + +
dataA data vector, whose elements will be cast to match the datatype of the image. An exception will be raised if this does not have a length matching the image
datatypeThe final datatype required. By default the existing datatype of the image is used
+
+
+ +
+
+ +

◆ rescale()

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage & RNifti::NiftiImage::rescale (const std::vector< float > & scales)
+
+inline
+
+ +

Rescale the image, changing its image dimensions and pixel dimensions.

+
Parameters
+ + +
scalesVector of scale factors along each dimension
+
+
+
Note
No interpolation is performed on the pixel data, which is simply dropped
+ +
+
+ +

◆ setPersistence()

+ +
+
+ + + + + +
+ + + + + + + + +
NiftiImage& RNifti::NiftiImage::setPersistence (const bool persistent)
+
+inline
+
+ +

Marked the image as persistent, so that it can be passed back to R.

+
Parameters
+ + +
persistentThe new persistence state of the object
+
+
+ +
+
+ +

◆ setPixunits()

+ +
+
+ + + + + +
+ + + + + + + + +
void RNifti::NiftiImage::setPixunits (const std::vector< std::string > & pixunits)
+
+inlineprotected
+
+ +

Modify the pixel dimension units.

+
Parameters
+ + +
pixunitsVector of new pixel units, specified using their standard abbreviations
+
+
+ +
+
+ +

◆ slice() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const Block RNifti::NiftiImage::slice (const int i) const
+
+inline
+
+ +

Extract a slice block from a 3D image.

+
Parameters
+ + +
iThe slice number required
+
+
+
Returns
A Block object
+ +
+
+ +

◆ slice() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
Block RNifti::NiftiImage::slice (const int i)
+
+inline
+
+ +

Extract a slice block from a 3D image.

+
Parameters
+ + +
iThe slice number required
+
+
+
Returns
A Block object
+ +
+
+ +

◆ toFile() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void RNifti::NiftiImage::toFile (const std::string fileName,
const short datatype = DT_NONE 
) const
+
+inline
+
+ +

Write the image to a NIfTI-1 file.

+
Parameters
+ + + +
fileNameThe file name to write to, with appropriate suffix (e.g. ".nii.gz")
datatypeThe datatype to use when writing the file
+
+
+ +
+
+ +

◆ toFile() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void RNifti::NiftiImage::toFile (const std::string fileName,
const std::string & datatype 
) const
+
+inline
+
+ +

Write the image to a NIfTI-1 file.

+
Parameters
+ + + +
fileNameThe file name to write to, with appropriate suffix (e.g. ".nii.gz")
datatypeThe datatype to use when writing the file, or "auto"
+
+
+ +
+
+ +

◆ updatePixdim()

+ +
+
+ + + + + +
+ + + + + + + + +
void RNifti::NiftiImage::updatePixdim (const std::vector< float > & pixdim)
+
+inlineprotected
+
+ +

Modify the pixel dimensions, and potentially the xform matrices to match.

+
Parameters
+ + +
pixdimVector of new pixel dimensions
+
+
+ +
+
+ +

◆ volume() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
const Block RNifti::NiftiImage::volume (const int i) const
+
+inline
+
+ +

Extract a volume block from a 4D image.

+
Parameters
+ + +
iThe volume number required
+
+
+
Returns
A Block object
+ +
+
+ +

◆ volume() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + +
Block RNifti::NiftiImage::volume (const int i)
+
+inline
+
+ +

Extract a volume block from a 4D image.

+
Parameters
+ + +
iThe volume number required
+
+
+
Returns
A Block object
+ +
+
+ +

◆ xform()

+ +
+
+ + + + + +
+ + + + + + + + +
mat44 RNifti::NiftiImage::xform (const bool preferQuaternion = true) const
+
+inline
+
+ +

Obtain an xform matrix, indicating the orientation of the image.

+
Parameters
+ + +
preferQuaternionIf true, use the qform matrix in preference to the sform
+
+
+
Returns
A 4x4 matrix
+ +
+
+ +

◆ xformToString()

+ +
+
+ + + + + +
+ + + + + + + + +
static std::string RNifti::NiftiImage::xformToString (const mat44 matrix)
+
+inlinestatic
+
+ +

Convert a 4x4 xform matrix to a string describing its canonical axes.

+
Parameters
+ + +
matrixAn xform matrix
+
+
+
Returns
A string containing three characters
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/inst/doxygen/html/classes.html b/inst/doxygen/html/classes.html new file mode 100644 index 0000000..20cbc18 --- /dev/null +++ b/inst/doxygen/html/classes.html @@ -0,0 +1,87 @@ + + + + + + + +RNifti: Class Index + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Index
+
+
+
b | n
+ + + + + +
  b  
+
  n  
+
NiftiImage::Block (RNifti)   NiftiImage (RNifti)   
+
b | n
+
+ + + + diff --git a/inst/doxygen/html/closed.png b/inst/doxygen/html/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/inst/doxygen/html/dir_2b5d1a398a9eec011391d543f21db223.html b/inst/doxygen/html/dir_2b5d1a398a9eec011391d543f21db223.html new file mode 100644 index 0000000..ab7fa07 --- /dev/null +++ b/inst/doxygen/html/dir_2b5d1a398a9eec011391d543f21db223.html @@ -0,0 +1,85 @@ + + + + + + + +RNifti: inst/include Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
include Directory Reference
+
+
+ + +

+Directories

+
+ + + + diff --git a/inst/doxygen/html/dir_920884c6b3b2f0be94e27d51660adee5.html b/inst/doxygen/html/dir_920884c6b3b2f0be94e27d51660adee5.html new file mode 100644 index 0000000..dc6ddcf --- /dev/null +++ b/inst/doxygen/html/dir_920884c6b3b2f0be94e27d51660adee5.html @@ -0,0 +1,81 @@ + + + + + + + +RNifti: inst Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
inst Directory Reference
+
+
+
+ + + + diff --git a/inst/doxygen/html/dir_98a44f28b9ced65c076c4e168f5923c6.html b/inst/doxygen/html/dir_98a44f28b9ced65c076c4e168f5923c6.html new file mode 100644 index 0000000..b928e7b --- /dev/null +++ b/inst/doxygen/html/dir_98a44f28b9ced65c076c4e168f5923c6.html @@ -0,0 +1,81 @@ + + + + + + + +RNifti: inst/include/lib Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
lib Directory Reference
+
+
+
+ + + + diff --git a/inst/doxygen/html/doc.png b/inst/doxygen/html/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/inst/doxygen/html/doxygen.css b/inst/doxygen/html/doxygen.css new file mode 100644 index 0000000..266c8b3 --- /dev/null +++ b/inst/doxygen/html/doxygen.css @@ -0,0 +1,1596 @@ +/* The standard CSS for doxygen 1.8.14 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +p.reference, p.definition { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: url('nav_f.png'); + background-repeat: repeat-x; + background-color: #E2E8F2; + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-color: #DFE5F1; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + +} + +.overload { + font-family: "courier new",courier,monospace; + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +/* +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTableHead tr { +} + +table.markdownTableBodyLeft td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft { + text-align: left +} + +th.markdownTableHeadRight { + text-align: right +} + +th.markdownTableHeadCenter { + text-align: center +} +*/ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + + +/* @end */ diff --git a/inst/doxygen/html/doxygen.png b/inst/doxygen/html/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff17d807fd8aa003bed8bb2a69e8f0909592fd1 GIT binary patch literal 3779 zcmV;!4m|ORP)tMIv#Q0*~7*`IBSO7_x;@a8#Zk6_PeKR_s92J&)(m+);m9Iz3blw)z#Gi zP!9lj4$%+*>Hz@HCmM9L9|8c+0u=!H$O3?R0Kgx|#WP<6fKfC8fM-CQZT|_r@`>VO zX^Hgb|9cJqpdJA5$MCEK`F_2@2Y@s>^+;pF`~jdI0Pvr|vl4`=C)EH@1IFe7pdJ8F zH(qGi004~QnF)Ggga~8v08kGAs2hKTATxr7pwfNk|4#_AaT>w8P6TV+R2kbS$v==} zAjf`s0g#V8lB+b3)5oEI*q+{Yt$MZDruD2^;$+(_%Qn+%v0X-bJO=;@kiJ^ygLBnC z?1OVv_%aex1M@jKU|Z~$eI?PoF4Vj>fDzyo zAiLfpXY*a^Sj-S5D0S3@#V$sRW)g)_1e#$%8xdM>Jm7?!h zu0P2X=xoN>^!4DoPRgph2(2va07yfpXF+WH7EOg1GY%Zn z7~1A<(z7Q$ktEXhW_?GMpHp9l_UL18F3KOsxu81pqoBiNbFSGsof-W z6~eloMoz=4?OOnl2J268x5rOY`dCk0us(uS#Ud4yqOr@?=Q57a}tit|BhY>}~frH1sP`ScHS_d)oqH^lYy zZ%VP`#10MlE~P?cE(%(#(AUSv_T{+;t@$U}El}(1ig`vZo`Rm;+5&(AYzJ^Ae=h2X z@Re%vHwZU>|f0NI&%$*4eJweC5OROQrpPMA@*w|o z()A==l}(@bv^&>H1Ob3C=<^|hob?0+xJ?QQ3-ueQC}zy&JQNib!OqSO@-=>XzxlSF zAZ^U*1l6EEmg3r};_HY>&Jo_{dOPEFTWPmt=U&F#+0(O59^UIlHbNX+eF8UzyDR*T z(=5X$VF3!gm@RooS-&iiUYGG^`hMR(07zr_xP`d!^BH?uD>Phl8Rdifx3Af^Zr`Ku ztL+~HkVeL#bJ)7;`=>;{KNRvjmc}1}c58Sr#Treq=4{xo!ATy|c>iRSp4`dzMMVd@ zL8?uwXDY}Wqgh4mH`|$BTXpUIu6A1-cSq%hJw;@^Zr8TP=GMh*p(m(tN7@!^D~sl$ zz^tf4II4|};+irE$Fnm4NTc5%p{PRA`%}Zk`CE5?#h3|xcyQsS#iONZ z6H(@^i9td!$z~bZiJLTax$o>r(p}3o@< zyD7%(>ZYvy=6$U3e!F{Z`uSaYy`xQyl?b{}eg|G3&fz*`QH@mDUn)1%#5u`0m$%D} z?;tZ0u(mWeMV0QtzjgN!lT*pNRj;6510Wwx?Yi_=tYw|J#7@(Xe7ifDzXuK;JB;QO z#bg~K$cgm$@{QiL_3yr}y&~wuv=P=#O&Tj=Sr)aCUlYmZMcw?)T?c%0rUe1cS+o!qs_ zQ6Gp)-{)V!;=q}llyK3|^WeLKyjf%y;xHku;9(vM!j|~<7w1c*Mk-;P{T&yG) z@C-8E?QPynNQ<8f01D`2qexcVEIOU?y}MG)TAE6&VT5`rK8s(4PE;uQ92LTXUQ<>^ ztyQ@=@kRdh@ebUG^Z6NWWIL;_IGJ2ST>$t!$m$qvtj0Qmw8moN6GUV^!QKNK zHBXCtUH8)RY9++gH_TUV4^=-j$t}dD3qsN7GclJ^Zc&(j6&a_!$jCf}%c5ey`pm~1)@{yI3 zTdWyB+*X{JFw#z;PwRr5evb2!ueWF;v`B0HoUu4-(~aL=z;OXUUEtG`_$)Oxw6FKg zEzY`CyKaSBK3xt#8gA|r_|Kehn_HYVBMpEwbn9-fI*!u*eTA1ef8Mkl1=!jV4oYwWYM}i`A>_F4nhmlCIC6WLa zY%;4&@AlnaG11ejl61Jev21|r*m+?Kru3;1tFDl}#!OzUp6c>go4{C|^erwpG*&h6bspUPJag}oOkN2912Y3I?(eRc@U9>z#HPBHC?nps7H5!zP``90!Q1n80jo+B3TWXp!8Pe zwuKuLLI6l3Gv@+QH*Y}2wPLPQ1^EZhT#+Ed8q8Wo z1pTmIBxv14-{l&QVKxAyQF#8Q@NeJwWdKk>?cpiJLkJr+aZ!Me+Cfp!?FWSRf^j2k z73BRR{WSKaMkJ>1Nbx5dan5hg^_}O{Tj6u%iV%#QGz0Q@j{R^Ik)Z*+(YvY2ziBG)?AmJa|JV%4UT$k`hcOg5r9R?5>?o~JzK zJCrj&{i#hG>N7!B4kNX(%igb%kDj0fOQThC-8mtfap82PNRXr1D>lbgg)dYTQ(kbx z`Ee5kXG~Bh+BHQBf|kJEy6(ga%WfhvdQNDuOfQoe377l#ht&DrMGeIsI5C<&ai zWG$|hop2@@q5YDa)_-A?B02W;#fH!%k`daQLEItaJJ8Yf1L%8x;kg?)k)00P-lH+w z)5$QNV6r2$YtnV(4o=0^3{kmaXn*Dm0F*fU(@o)yVVjk|ln8ea6BMy%vZAhW9|wvA z8RoDkVoMEz1d>|5(k0Nw>22ZT){V<3$^C-cN+|~hKt2)){+l-?3m@-$c?-dlzQ)q- zZ)j%n^gerV{|+t}9m1_&&Ly!9$rtG4XX|WQ8`xYzGC~U@nYh~g(z9)bdAl#xH)xd5a=@|qql z|FzEil{P5(@gy!4ek05i$>`E^G~{;pnf6ftpLh$h#W?^#4UkPfa;;?bsIe&kz!+40 zI|6`F2n020)-r`pFaZ38F!S-lJM-o&inOw|66=GMeP@xQU5ghQH{~5Uh~TMTd;I9` z>YhVB`e^EVj*S7JF39ZgNf}A-0DwOcTT63ydN$I3b?yBQtUI*_fae~kPvzoD$zjX3 zoqBe#>12im4WzZ=f^4+u=!lA|#r%1`WB0-6*3BL#at`47#ebPpR|D1b)3BjT34nYY z%Ds%d?5$|{LgOIaRO{{oC&RK`O91$fqwM0(C_TALcozu*fWHb%%q&p-q{_8*2Zsi^ zh1ZCnr^UYa;4vQEtHk{~zi>wwMC5o{S=$P0X681y`SXwFH?Ewn{x-MOZynmc)JT5v zuHLwh;tLfxRrr%|k370}GofLl7thg>ACWWY&msqaVu&ry+`7+Ss>NL^%T1|z{IGMA zW-SKl=V-^{(f!Kf^#3(|T2W47d(%JVCI4JgRrT1pNz>+ietmFToNv^`gzC@&O-)+i zPQ~RwK8%C_vf%;%e>NyTp~dM5;!C|N0Q^6|CEb7Bw=Vz~$1#FA;Z*?mKSC)Hl-20s t8QyHj(g6VK0RYbl8UjE)0O0w=e*@m04r>stuEhWV002ovPDHLkV1hl;dM*F} literal 0 HcmV?d00001 diff --git a/inst/doxygen/html/dynsections.js b/inst/doxygen/html/dynsections.js new file mode 100644 index 0000000..c1ce122 --- /dev/null +++ b/inst/doxygen/html/dynsections.js @@ -0,0 +1,120 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +RNifti: File List + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+
[detail level 1234]
+ + + + +
  inst
  include
  lib
 NiftiImage.h
+
+
+ + + + diff --git a/inst/doxygen/html/folderclosed.png b/inst/doxygen/html/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/inst/doxygen/html/functions.html b/inst/doxygen/html/functions.html new file mode 100644 index 0000000..828a5a9 --- /dev/null +++ b/inst/doxygen/html/functions.html @@ -0,0 +1,248 @@ + + + + + + + +RNifti: Class Members + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all documented class members with links to the class documentation for each member:
+ +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+ + +

- x -

+ + +

- ~ -

+
+ + + + diff --git a/inst/doxygen/html/functions_func.html b/inst/doxygen/html/functions_func.html new file mode 100644 index 0000000..2aa2015 --- /dev/null +++ b/inst/doxygen/html/functions_func.html @@ -0,0 +1,235 @@ + + + + + + + +RNifti: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+ + +

- x -

+ + +

- ~ -

+
+ + + + diff --git a/inst/doxygen/html/functions_vars.html b/inst/doxygen/html/functions_vars.html new file mode 100644 index 0000000..9010ed1 --- /dev/null +++ b/inst/doxygen/html/functions_vars.html @@ -0,0 +1,88 @@ + + + + + + + +RNifti: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/inst/doxygen/html/index.html b/inst/doxygen/html/index.html new file mode 100644 index 0000000..70b0bbb --- /dev/null +++ b/inst/doxygen/html/index.html @@ -0,0 +1,78 @@ + + + + + + + +RNifti: RNifti: Fast R and C++ Access to NIfTI Images + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
RNifti: Fast R and C++ Access to NIfTI Images
+
+
+

A more extensive overview of the RNifti package, and its usage from R, is provided on the package's GitHub page at https://github.com/jonclayden/RNifti. The primary role of these pages is to document the RNifti::NiftiImage C++ class for package developers linking to RNifti.

+
+ + + + diff --git a/inst/doxygen/html/jquery.js b/inst/doxygen/html/jquery.js new file mode 100644 index 0000000..2771c74 --- /dev/null +++ b/inst/doxygen/html/jquery.js @@ -0,0 +1,115 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +/*! + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*! + * jQuery UI 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! + * jQuery UI Widget 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Widget + */ +(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! + * jQuery UI Mouse 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$(' + + + + +
+
+
NiftiImage::Block Member List
+
+
+ +

This is the complete list of members for NiftiImage::Block, including all inherited members.

+
+ + + + + +
Block(const NiftiImage &image, const int dimension, const int index)NiftiImage::Blockinline
dimensionNiftiImage::Block
imageNiftiImage::Block
indexNiftiImage::Block
operator=(const NiftiImage &source)NiftiImage::Blockinline
+ + + + diff --git a/inst/doxygen/html/struct_nifti_image_1_1_block.html b/inst/doxygen/html/struct_nifti_image_1_1_block.html new file mode 100644 index 0000000..f0ebf03 --- /dev/null +++ b/inst/doxygen/html/struct_nifti_image_1_1_block.html @@ -0,0 +1,219 @@ + + + + + + + +RNifti: NiftiImage::Block Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
NiftiImage::Block Struct Reference
+
+
+ +

Inner class referring to a subset of an image. + More...

+ +

#include <NiftiImage.h>

+ + + + + + + + +

+Public Member Functions

 Block (const NiftiImage &image, const int dimension, const int index)
 Standard constructor for this class. More...
 
Blockoperator= (const NiftiImage &source)
 Copy assignment operator, which allows a block in one image to be replaced with the contents of another image. More...
 
+ + + + + + + + + + +

+Public Attributes

+const NiftiImageimage
 The parent image.
 
+const int dimension
 The dimension along which the block applies (which should be the last)
 
+const int index
 The location along dimension.
 
+

Detailed Description

+

Inner class referring to a subset of an image.

+

Currently must refer to the last dimension in the image, i.e., a volume in a 4D parent image, or a slice in a 3D image

+

Constructor & Destructor Documentation

+ +

§ Block()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
NiftiImage::Block::Block (const NiftiImageimage,
const int dimension,
const int index 
)
+
+inline
+
+ +

Standard constructor for this class.

+
Parameters
+ + + + +
imageThe parent image
dimensionThe dimension along which the block applies (which should be the last)
indexThe location along dimension
+
+
+
Exceptions
+ + +
runtime_errorIf dimension is not the last dimension in the image
+
+
+ +
+
+

Member Function Documentation

+ +

§ operator=()

+ +
+
+ + + + + +
+ + + + + + + + +
Block& NiftiImage::Block::operator= (const NiftiImagesource)
+
+inline
+
+ +

Copy assignment operator, which allows a block in one image to be replaced with the contents of another image.

+
Parameters
+ + +
sourceA NiftiImage, containing the data to replace the block with
+
+
+
Returns
A reference to the block
+
Exceptions
+ + +
runtime_errorIf the source is incompatible with the block in size or datatype
+
+
+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block-members.html b/inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block-members.html new file mode 100644 index 0000000..a0e6581 --- /dev/null +++ b/inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block-members.html @@ -0,0 +1,90 @@ + + + + + + + +RNifti: Member List + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
RNifti::NiftiImage::Block Member List
+
+
+ +

This is the complete list of members for RNifti::NiftiImage::Block, including all inherited members.

+ + + + + + + +
Block(const NiftiImage &image, const int dimension, const int index)RNifti::NiftiImage::Blockinline
dimensionRNifti::NiftiImage::Block
getData() constRNifti::NiftiImage::Blockinline
imageRNifti::NiftiImage::Block
indexRNifti::NiftiImage::Block
operator=(const NiftiImage &source)RNifti::NiftiImage::Blockinline
+ + + + diff --git a/inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block.html b/inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block.html new file mode 100644 index 0000000..9d0df4f --- /dev/null +++ b/inst/doxygen/html/struct_r_nifti_1_1_nifti_image_1_1_block.html @@ -0,0 +1,227 @@ + + + + + + + +RNifti: RNifti::NiftiImage::Block Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
RNifti +
+
Fast R and C++ Access to NIfTI Images
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
RNifti::NiftiImage::Block Struct Reference
+
+
+ +

Inner class referring to a subset of an image. + More...

+ +

#include <NiftiImage.h>

+ + + + + + + + + + + + +

+Public Member Functions

 Block (const NiftiImage &image, const int dimension, const int index)
 Standard constructor for this class. More...
 
Blockoperator= (const NiftiImage &source)
 Copy assignment operator, which allows a block in one image to be replaced with the contents of another image. More...
 
+template<typename TargetType >
std::vector< TargetType > getData () const
 Extract a vector of data from a block, casting it to any required element type.
 
+ + + + + + + + + + +

+Public Attributes

+const NiftiImageimage
 The parent image.
 
+const int dimension
 The dimension along which the block applies (which should be the last)
 
+const int index
 The location along dimension.
 
+

Detailed Description

+

Inner class referring to a subset of an image.

+

Currently must refer to the last dimension in the image, i.e., a volume in a 4D parent image, or a slice in a 3D image

+

Constructor & Destructor Documentation

+ +

◆ Block()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
RNifti::NiftiImage::Block::Block (const NiftiImageimage,
const int dimension,
const int index 
)
+
+inline
+
+ +

Standard constructor for this class.

+
Parameters
+ + + + +
imageThe parent image
dimensionThe dimension along which the block applies (which should be the last)
indexThe location along dimension
+
+
+
Exceptions
+ + +
runtime_errorIf dimension is not the last dimension in the image
+
+
+ +
+
+

Member Function Documentation

+ +

◆ operator=()

+ +
+
+ + + + + +
+ + + + + + + + +
Block& RNifti::NiftiImage::Block::operator= (const NiftiImagesource)
+
+inline
+
+ +

Copy assignment operator, which allows a block in one image to be replaced with the contents of another image.

+
Parameters
+ + +
sourceA NiftiImage, containing the data to replace the block with
+
+
+
Returns
A reference to the block
+
Exceptions
+ + +
runtime_errorIf the source is incompatible with the block in size or datatype
+
+
+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/inst/doxygen/html/sync_off.png b/inst/doxygen/html/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/inst/doxygen/html/sync_on.png b/inst/doxygen/html/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/inst/doxygen/html/tab_a.png b/inst/doxygen/html/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/inst/doxygen/html/tab_b.png b/inst/doxygen/html/tab_b.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b4a8638cb3496a016eaed9e16ffc12846dea18 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QU#tajv*C{Z}0l@H7kg?K0Lnr z!j&C6_(~HV9oQ0Pa6x{-v0AGV_E?vLn=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/inst/doxygen/html/tabs.css b/inst/doxygen/html/tabs.css new file mode 100644 index 0000000..a28614b --- /dev/null +++ b/inst/doxygen/html/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#doc-content{overflow:auto;display:block;padding:0;margin:0;-webkit-overflow-scrolling:touch}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace!important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0!important;-webkit-border-radius:0;border-radius:0!important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px!important;-webkit-border-radius:5px;border-radius:5px!important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0!important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px!important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} \ No newline at end of file diff --git a/inst/extdata/example_4d.nii.gz b/inst/extdata/example_4d.nii.gz new file mode 100644 index 0000000000000000000000000000000000000000..6937cbb9ca3e03e9b77e58c3144d101f609d57ab GIT binary patch literal 1853 zcmb2|=3oE==C`*tdL0fBVS6z9h$9Pod3z3@)5;xOVn-KtH>iXOfMDLG-1suP2Sn7i$BUa*+s>7 zKTf;<`sMoewI8-rf4hEN?dY4de-#tw_rF(r{AcNo`S-A+arT+tw{>qV_(2 zdhYtk=T~nRRp;;0`TqaM%hmU;mtVDS4fwid`IE)F_P3pl{`@;|8j?$wcK>ZN7FxABOEIZWP29Klj&QJUg%Q*|qC!K$O k;y?8*9W`+@1mGbMdvep6;Zy{E_`i=)w))$?gg{9K0Dkw2jsO4v literal 0 HcmV?d00001 diff --git a/inst/include/RNifti.h b/inst/include/RNifti.h index 3138e66..eef2bc0 100644 --- a/inst/include/RNifti.h +++ b/inst/include/RNifti.h @@ -1,6 +1,11 @@ #ifndef _RNIFTI_H_ #define _RNIFTI_H_ +// RNiftyReg and divest have used HAVE_R, so accept this variant for compatibility +#if !defined(USING_R) && defined(HAVE_R) +#define USING_R +#endif + #include "niftilib/nifti1_io.h" #ifdef __cplusplus diff --git a/inst/include/lib/NiftiImage.h b/inst/include/lib/NiftiImage.h index d2ee60b..cfd1112 100644 --- a/inst/include/lib/NiftiImage.h +++ b/inst/include/lib/NiftiImage.h @@ -2,13 +2,14 @@ #define _NIFTI_IMAGE_H_ -#ifndef _NO_R__ +#ifdef USING_R #include #else #define R_NegInf -INFINITY +#define ISNAN(x) (x != x) #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #endif @@ -101,7 +103,7 @@ class NiftiImage std::vector getData () const; }; -#ifndef _NO_R__ +#ifdef USING_R /** * Convert between R \c SEXP object type and \c nifti_image datatype codes * @param sexpType A numeric R \c SEXP type code @@ -146,6 +148,40 @@ class NiftiImage return result; } + /** + * Get the NIfTI format version used by the file at the specified path + * @param path A string specifying a file path + * @return An integer: -1 if the file is not present or not valid, 0 for ANALYZE-7.5, or + * a value greater than 0 for NIfTI + **/ + static int fileVersion (const std::string &path) + { + nifti_1_header *header = nifti_read_header(path.c_str(), NULL, false); + if (header == NULL) + return -1; + else + { + int version = NIFTI_VERSION(*header); + if (version == 0) + { + // NIfTI-2 has a 540-byte header - check for this or its byte-swapped equivalent + if (header->sizeof_hdr == 540 || header->sizeof_hdr == 469893120) + { + // The magic number has moved in NIfTI-2, so find it by byte offset + const char *magic = (char *) header + 4; + if (strncmp(magic,"ni2",3) == 0 || strncmp(magic,"n+2",3) == 0) + version = 2; + } + else if (!nifti_hdr_looks_good(header)) + { + // Not plausible as ANALYZE, so return -1 + version = -1; + } + } + return version; + } + } + protected: nifti_image *image; /**< The wrapped \c nifti_image pointer */ @@ -170,7 +206,7 @@ class NiftiImage void copy (const Block &source); -#ifndef _NO_R__ +#ifdef USING_R /** * Initialise the object from an S4 object of class \c "nifti" @@ -281,7 +317,15 @@ class NiftiImage #endif } -#ifndef _NO_R__ + /** + * Initialise using a path string and sequence of required volumes + * @param path A string specifying a path to a valid NIfTI-1 file, possibly gzipped + * @param volumes The volumes to read in (squashing all dimensions above the third together) + * @exception runtime_error If reading from the file fails, or \c volumes is empty + **/ + NiftiImage (const std::string &path, const std::vector &volumes); + +#ifdef USING_R /** * Initialise from an R object * @param object The source object @@ -493,12 +537,12 @@ class NiftiImage **/ NiftiImage & reorient (const std::string &orientation); -#ifndef _NO_R__ +#ifdef USING_R /** * Update the image from an R array - * @param array An R array object + * @param array An R array or list object **/ - NiftiImage & update (const SEXP array); + NiftiImage & update (const Rcpp::RObject &object); #endif /** @@ -579,7 +623,7 @@ class NiftiImage **/ void toFile (const std::string fileName, const std::string &datatype) const; -#ifndef _NO_R__ +#ifdef USING_R /** * Create an R array from the image @@ -669,7 +713,7 @@ inline void NiftiImage::copy (const Block &source) persistent = false; } -#ifndef _NO_R__ +#ifdef USING_R // Convert an S4 "nifti" object, as defined in the oro.nifti package, to a "nifti_image" struct inline void NiftiImage::initFromNiftiS4 (const Rcpp::RObject &object, const bool copyData) @@ -856,84 +900,7 @@ inline void NiftiImage::initFromList (const Rcpp::RObject &object) Rcpp::List list(object); nifti_1_header *header = nifti_make_new_header(NULL, DT_FLOAT64); - const Rcpp::CharacterVector _names = list.names(); - std::set names; - for (Rcpp::CharacterVector::const_iterator it=_names.begin(); it!=_names.end(); it++) - names.insert(Rcpp::as(*it)); - - internal::copyIfPresent(list, names, "sizeof_hdr", header->sizeof_hdr); - - internal::copyIfPresent(list, names, "dim_info", header->dim_info); - if (names.count("dim") == 1) - { - std::vector dim = list["dim"]; - for (size_t i=0; idim[i] = dim[i]; - } - - internal::copyIfPresent(list, names, "intent_p1", header->intent_p1); - internal::copyIfPresent(list, names, "intent_p2", header->intent_p2); - internal::copyIfPresent(list, names, "intent_p3", header->intent_p3); - internal::copyIfPresent(list, names, "intent_code", header->intent_code); - - internal::copyIfPresent(list, names, "datatype", header->datatype); - internal::copyIfPresent(list, names, "bitpix", header->bitpix); - - internal::copyIfPresent(list, names, "slice_start", header->slice_start); - if (names.count("pixdim") == 1) - { - std::vector pixdim = list["pixdim"]; - for (size_t i=0; ipixdim[i] = pixdim[i]; - } - internal::copyIfPresent(list, names, "vox_offset", header->vox_offset); - internal::copyIfPresent(list, names, "scl_slope", header->scl_slope); - internal::copyIfPresent(list, names, "scl_inter", header->scl_inter); - internal::copyIfPresent(list, names, "slice_end", header->slice_end); - internal::copyIfPresent(list, names, "slice_code", header->slice_code); - internal::copyIfPresent(list, names, "xyzt_units", header->xyzt_units); - internal::copyIfPresent(list, names, "cal_max", header->cal_max); - internal::copyIfPresent(list, names, "cal_min", header->cal_min); - internal::copyIfPresent(list, names, "slice_duration", header->slice_duration); - internal::copyIfPresent(list, names, "toffset", header->toffset); - - if (names.count("descrip") == 1) - strcpy(header->descrip, Rcpp::as(list["descrip"]).substr(0,79).c_str()); - if (names.count("aux_file") == 1) - strcpy(header->aux_file, Rcpp::as(list["aux_file"]).substr(0,23).c_str()); - - internal::copyIfPresent(list, names, "qform_code", header->qform_code); - internal::copyIfPresent(list, names, "sform_code", header->sform_code); - internal::copyIfPresent(list, names, "quatern_b", header->quatern_b); - internal::copyIfPresent(list, names, "quatern_c", header->quatern_c); - internal::copyIfPresent(list, names, "quatern_d", header->quatern_d); - internal::copyIfPresent(list, names, "qoffset_x", header->qoffset_x); - internal::copyIfPresent(list, names, "qoffset_y", header->qoffset_y); - internal::copyIfPresent(list, names, "qoffset_z", header->qoffset_z); - - if (names.count("srow_x") == 1) - { - std::vector srow_x = list["srow_x"]; - for (size_t i=0; isrow_x[i] = srow_x[i]; - } - if (names.count("srow_y") == 1) - { - std::vector srow_y = list["srow_y"]; - for (size_t i=0; isrow_y[i] = srow_y[i]; - } - if (names.count("srow_z") == 1) - { - std::vector srow_z = list["srow_z"]; - for (size_t i=0; isrow_z[i] = srow_z[i]; - } - - if (names.count("intent_name") == 1) - strcpy(header->intent_name, Rcpp::as(list["intent_name"]).substr(0,15).c_str()); - if (names.count("magic") == 1) - strcpy(header->magic, Rcpp::as(list["magic"]).substr(0,3).c_str()); + internal::updateHeader(header, list); this->image = nifti_convert_nhdr2nim(*header, NULL); this->image->data = NULL; @@ -996,7 +963,7 @@ inline NiftiImage::NiftiImage (const SEXP object, const bool readData) resolved = true; if (imageObject.hasAttribute("dim")) - update(object); + update(imageObject); } else if (Rf_isString(object)) throw std::runtime_error("Internal image is not valid"); @@ -1037,7 +1004,29 @@ inline NiftiImage::NiftiImage (const SEXP object, const bool readData) #endif } -#endif // _NO_R__ +#endif // USING_R + +inline NiftiImage::NiftiImage (const std::string &path, const std::vector &volumes) + : persistent(false) +{ + if (volumes.empty()) + throw std::runtime_error("The vector of volumes is empty"); + + nifti_brick_list brickList; + this->image = nifti_image_read_bricks(path.c_str(), volumes.size(), &volumes[0], &brickList); + if (this->image == NULL) + throw std::runtime_error("Failed to read image from path " + path); + + size_t brickSize = image->nbyper * image->nx * image->ny * image->nz; + image->data = calloc(1, nifti_get_volsize(image)); + for (int i=0; idata + i * brickSize, brickList.bricks[i], brickSize); + nifti_free_NBL(&brickList); + +#ifndef NDEBUG + Rprintf("Creating NiftiImage with pointer %p (from string and volume vector)\n", this->image); +#endif +} inline void NiftiImage::updatePixdim (const std::vector &pixdim) { @@ -1334,67 +1323,88 @@ inline NiftiImage & NiftiImage::reorient (const std::string &orientation) return reorient(codes[0], codes[1], codes[2]); } -#ifndef _NO_R__ +#ifdef USING_R -inline NiftiImage & NiftiImage::update (const SEXP array) +inline NiftiImage & NiftiImage::update (const Rcpp::RObject &object) { - Rcpp::RObject object(array); - if (!object.hasAttribute("dim")) - return *this; + if (Rf_isVectorList(object)) + { + Rcpp::List list(object); + nifti_1_header *header = NULL; + if (this->isNull()) + { + header = nifti_make_new_header(NULL, DT_FLOAT64); + internal::updateHeader(header, list, true); + } + else + { + header = (nifti_1_header *) calloc(1, sizeof(nifti_1_header)); + *header = nifti_convert_nim2nhdr(image); + internal::updateHeader(header, list, true); + } + + if (header != NULL) + { + nifti_image *newImage = nifti_convert_nhdr2nim(*header, NULL); + if (this->image->data != NULL) + { + size_t dataSize = nifti_get_volsize(image); + newImage->data = calloc(1, dataSize); + memcpy(newImage->data, image->data, dataSize); + } + if (!persistent) + nifti_image_free(image); + this->image = newImage; + } + } + else if (object.hasAttribute("dim")) + { + for (int i=0; i<8; i++) + image->dim[i] = 0; + const std::vector dimVector = object.attr("dim"); - for (int i=0; i<8; i++) - image->dim[i] = 0; - const std::vector dimVector = object.attr("dim"); + const int nDims = std::min(7, int(dimVector.size())); + image->dim[0] = nDims; + for (int i=0; idim[i+1] = dimVector[i]; - const int nDims = std::min(7, int(dimVector.size())); - image->dim[0] = nDims; - for (int i=0; idim[i+1] = dimVector[i]; + if (object.hasAttribute("pixdim")) + { + const std::vector pixdimVector = object.attr("pixdim"); + updatePixdim(pixdimVector); + } - if (object.hasAttribute("pixdim")) - { - const std::vector pixdimVector = object.attr("pixdim"); - updatePixdim(pixdimVector); - } + if (object.hasAttribute("pixunits")) + { + const std::vector pixunitsVector = object.attr("pixunits"); + setPixunits(pixunitsVector); + } - if (object.hasAttribute("pixunits")) - { - const std::vector pixunitsVector = object.attr("pixunits"); - setPixunits(pixunitsVector); - } + // This NIfTI-1 library function clobbers dim[0] if the last dimension is unitary; we undo that here + nifti_update_dims_from_array(image); + image->dim[0] = image->ndim = nDims; - // This NIfTI-1 library function clobbers dim[0] if the last dimension is unitary; we undo that here - nifti_update_dims_from_array(image); - image->dim[0] = image->ndim = nDims; + image->datatype = NiftiImage::sexpTypeToNiftiType(object.sexp_type()); + nifti_datatype_sizes(image->datatype, &image->nbyper, NULL); - image->datatype = NiftiImage::sexpTypeToNiftiType(object.sexp_type()); - nifti_datatype_sizes(image->datatype, &image->nbyper, NULL); + if (!persistent) + nifti_image_unload(image); - if (!persistent) - nifti_image_unload(image); + const size_t dataSize = nifti_get_volsize(image); + image->data = calloc(1, dataSize); + if (image->datatype == DT_INT32) + memcpy(image->data, INTEGER(object), dataSize); + else + memcpy(image->data, REAL(object), dataSize); - const size_t dataSize = nifti_get_volsize(image); - image->data = calloc(1, dataSize); - if (image->datatype == DT_INT32) - { - memcpy(image->data, INTEGER(object), dataSize); - image->cal_min = static_cast(*std::min_element(INTEGER(object), INTEGER(object)+image->nvox)); - image->cal_max = static_cast(*std::max_element(INTEGER(object), INTEGER(object)+image->nvox)); + image->scl_slope = 0.0; + image->scl_inter = 0.0; } - else - { - memcpy(image->data, REAL(object), dataSize); - image->cal_min = static_cast(*std::min_element(REAL(object), REAL(object)+image->nvox)); - image->cal_max = static_cast(*std::max_element(REAL(object), REAL(object)+image->nvox)); - } - - image->scl_slope = 0.0; - image->scl_inter = 0.0; return *this; } -#endif// _NO_R__ +#endif // USING_R inline mat44 NiftiImage::xform (const bool preferQuaternion) const { @@ -1586,7 +1596,7 @@ inline void NiftiImage::toFile (const std::string fileName, const std::string &d toFile(fileName, internal::stringToDatatype(datatype)); } -#ifndef _NO_R__ +#ifdef USING_R inline Rcpp::RObject NiftiImage::toArray () const { @@ -1703,7 +1713,7 @@ inline Rcpp::RObject NiftiImage::headerToList () const return result; } -#endif // _NO_R__ +#endif // USING_R } // namespace diff --git a/inst/include/lib/NiftiImage_internal.h b/inst/include/lib/NiftiImage_internal.h index ac20767..f2478d2 100644 --- a/inst/include/lib/NiftiImage_internal.h +++ b/inst/include/lib/NiftiImage_internal.h @@ -203,7 +203,7 @@ inline short stringToDatatype (const std::string &datatype) return datatypeCodes[lowerCaseDatatype]; } -#ifndef _NO_R__ +#ifdef USING_R template inline void copyIfPresent (const Rcpp::List &list, const std::set names, const std::string &name, TargetType &target) @@ -220,7 +220,95 @@ inline void copyIfPresent (const Rcpp::List &list, const std::set n target = static_cast(Rcpp::as(list[name])); } -#endif // _NO_R__ +inline void updateHeader (nifti_1_header *header, const Rcpp::List &list, const bool ignoreDatatype = false) +{ + if (header == NULL) + return; + + const Rcpp::CharacterVector _names = list.names(); + std::set names; + for (Rcpp::CharacterVector::const_iterator it=_names.begin(); it!=_names.end(); it++) + names.insert(Rcpp::as(*it)); + + copyIfPresent(list, names, "sizeof_hdr", header->sizeof_hdr); + + copyIfPresent(list, names, "dim_info", header->dim_info); + if (names.count("dim") == 1) + { + std::vector dim = list["dim"]; + for (size_t i=0; idim[i] = dim[i]; + } + + copyIfPresent(list, names, "intent_p1", header->intent_p1); + copyIfPresent(list, names, "intent_p2", header->intent_p2); + copyIfPresent(list, names, "intent_p3", header->intent_p3); + copyIfPresent(list, names, "intent_code", header->intent_code); + + if (!ignoreDatatype) + { + copyIfPresent(list, names, "datatype", header->datatype); + copyIfPresent(list, names, "bitpix", header->bitpix); + } + + copyIfPresent(list, names, "slice_start", header->slice_start); + if (names.count("pixdim") == 1) + { + std::vector pixdim = list["pixdim"]; + for (size_t i=0; ipixdim[i] = pixdim[i]; + } + copyIfPresent(list, names, "vox_offset", header->vox_offset); + copyIfPresent(list, names, "scl_slope", header->scl_slope); + copyIfPresent(list, names, "scl_inter", header->scl_inter); + copyIfPresent(list, names, "slice_end", header->slice_end); + copyIfPresent(list, names, "slice_code", header->slice_code); + copyIfPresent(list, names, "xyzt_units", header->xyzt_units); + copyIfPresent(list, names, "cal_max", header->cal_max); + copyIfPresent(list, names, "cal_min", header->cal_min); + copyIfPresent(list, names, "slice_duration", header->slice_duration); + copyIfPresent(list, names, "toffset", header->toffset); + + if (names.count("descrip") == 1) + strcpy(header->descrip, Rcpp::as(list["descrip"]).substr(0,79).c_str()); + if (names.count("aux_file") == 1) + strcpy(header->aux_file, Rcpp::as(list["aux_file"]).substr(0,23).c_str()); + + copyIfPresent(list, names, "qform_code", header->qform_code); + copyIfPresent(list, names, "sform_code", header->sform_code); + copyIfPresent(list, names, "quatern_b", header->quatern_b); + copyIfPresent(list, names, "quatern_c", header->quatern_c); + copyIfPresent(list, names, "quatern_d", header->quatern_d); + copyIfPresent(list, names, "qoffset_x", header->qoffset_x); + copyIfPresent(list, names, "qoffset_y", header->qoffset_y); + copyIfPresent(list, names, "qoffset_z", header->qoffset_z); + + if (names.count("srow_x") == 1) + { + std::vector srow_x = list["srow_x"]; + for (size_t i=0; isrow_x[i] = srow_x[i]; + } + if (names.count("srow_y") == 1) + { + std::vector srow_y = list["srow_y"]; + for (size_t i=0; isrow_y[i] = srow_y[i]; + } + if (names.count("srow_z") == 1) + { + std::vector srow_z = list["srow_z"]; + for (size_t i=0; isrow_z[i] = srow_z[i]; + } + + if (names.count("intent_name") == 1) + strcpy(header->intent_name, Rcpp::as(list["intent_name"]).substr(0,15).c_str()); + if (names.count("magic") == 1) + strcpy(header->magic, Rcpp::as(list["magic"]).substr(0,3).c_str()); +} + +#endif // USING_R inline mat33 topLeftCorner (const mat44 &matrix) { @@ -234,7 +322,7 @@ inline mat33 topLeftCorner (const mat44 &matrix) return newMatrix; } -#ifndef _NO_R__ +#ifdef USING_R template inline Rcpp::RObject imageDataToArray (const nifti_image *source) @@ -304,7 +392,7 @@ inline void addAttributes (Rcpp::RObject &object, nifti_image *source, const boo object.attr(".nifti_image_ptr") = xptr; } -#endif // _NO_R__ +#endif // USING_R } // namespace diff --git a/inst/include/lib/print.h b/inst/include/lib/print.h index 6b4456b..7e49100 100644 --- a/inst/include/lib/print.h +++ b/inst/include/lib/print.h @@ -1,11 +1,12 @@ #ifndef _PRINT_H_ #define _PRINT_H_ -#ifndef _NO_R__ +#ifdef USING_R #define R_USE_C99_IN_CXX #include +#include #define Rc_printf Rprintf #define Rc_fprintf_stdout(...) Rprintf(__VA_ARGS__) @@ -27,6 +28,6 @@ #define Rf_warning(str) fprintf(stderr, "%s\n", str) #define Rprintf(...) fprintf(stderr, __VA_ARGS__) -#endif// _NO_R__ +#endif // USING_R -#endif// _PRINT_H_ +#endif // _PRINT_H_ diff --git a/inst/include/niftilib/nifti1_io.h b/inst/include/niftilib/nifti1_io.h index ebb22b7..900f048 100644 --- a/inst/include/niftilib/nifti1_io.h +++ b/inst/include/niftilib/nifti1_io.h @@ -510,8 +510,13 @@ typedef struct { } nifti_type_ele; #undef LNI_FERR /* local nifti file error, to be compact and repetative */ +#ifdef USING_R +#define LNI_FERR(func,msg,file) \ + Rf_warning("%s: %s '%s'\n",func,msg,file) +#else #define LNI_FERR(func,msg,file) \ Rc_fprintf_stderr("** ERROR (%s): %s '%s'\n",func,msg,file) +#endif #undef swap_2 #undef swap_4 diff --git a/man/niftiVersion.Rd b/man/niftiVersion.Rd new file mode 100644 index 0000000..0bf0988 --- /dev/null +++ b/man/niftiVersion.Rd @@ -0,0 +1,37 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/nifti.R +\name{niftiVersion} +\alias{niftiVersion} +\title{Check the format version of a file} +\usage{ +niftiVersion(file) +} +\arguments{ +\item{file}{A character vector of file names.} +} +\value{ +A vector of integers, of the same length as \code{file}. Each + element will be 0 for ANALYZE format (the precursor to NIfTI-1), 1 for + NIfTI-1 (which is now most common), 2 for NIfTI-2, or -1 if the file + doesn't exist or doesn't look plausible in any of these formats. +} +\description{ +This function identifies the likely NIfTI format variant used by one or more +files on disk. +} +\note{ +NIfTI-2 format, mostly a variant of NIfTI-1 with wider datatypes used + for many fields, is not currently supported for reading, but it is + detected by this function. +} +\examples{ +path <- system.file("extdata", "example.nii.gz", package="RNifti") +niftiVersion(path) # 1 + +} +\seealso{ +\code{\link{readNifti}} +} +\author{ +Jon Clayden +} diff --git a/man/readNifti.Rd b/man/readNifti.Rd index da5b487..ffb286d 100644 --- a/man/readNifti.Rd +++ b/man/readNifti.Rd @@ -4,7 +4,7 @@ \alias{readNifti} \title{Read a NIfTI-1 format file} \usage{ -readNifti(file, internal = FALSE) +readNifti(file, internal = FALSE, volumes = NULL) } \arguments{ \item{file}{A character vector of file names.} @@ -15,10 +15,16 @@ will be returned. If \code{TRUE}, the return value will be an object of class \code{"internalImage"}, which contains only minimal metadata about the image. Either way, the return value has an attribute which points to a C data structure containing the full image.} + +\item{volumes}{An integer vector giving the volumes to read (counting along +all dimensions beyond the third jointly), or \code{NULL}, the default, in +which case every volume is read. This cannot currently be set differently +for each file read.} } \value{ -An array or internal image, with class \code{"niftiImage"}, and - possibly also \code{"internalImage"}. +An array or internal image, with class \code{"niftiImage"} (and + possibly also \code{"internalImage"}), or a list of such objects if + \code{file} has length greater than one. } \description{ This function reads one or more NIfTI-1 files into R, using the standard diff --git a/man/updateNifti.Rd b/man/updateNifti.Rd index e2bb28c..a681378 100644 --- a/man/updateNifti.Rd +++ b/man/updateNifti.Rd @@ -4,7 +4,7 @@ \alias{updateNifti} \title{Update an internal NIfTI-1 object using a template} \usage{ -updateNifti(image, template = NULL) +updateNifti(image, template = NULL, datatype = "auto") } \arguments{ \item{image}{A numeric array.} @@ -13,16 +13,46 @@ updateNifti(image, template = NULL) \code{\link{retrieveNifti}}), or a named list of NIfTI-1 properties like that produced by \code{\link{dumpNifti}}. The default of \code{NULL} will have no effect.} + +\item{datatype}{The NIfTI datatype to use within the internal image. The +default, \code{"auto"} uses the R type. Other possibilities are +\code{"float"}, \code{"int16"}, etc., which may be preferred to reduce +object size. However, no checks are done to ensure that the coercion +maintains precision, and this option is for advanced usage only.} } \value{ A copy of the original \code{image}, with its internal image - attribute set or updated appropriately. + attribute set or updated appropriately. If \code{datatype} is not + \code{"auto"} then the result is an internal image. } \description{ This function adds or updates the internal NIfTI-1 object for an array, using metadata from the template. The dimensions and, if available, pixel dimensions, from the \code{image} will replace those from the template. } +\details{ +If \code{template} is a complete list of NIfTI-1 header fields, like that +produced by \code{\link{dumpNifti}}, or an image, then it will be used to +create the internal object, and then the data and metadata associated with +the \code{image} will overwrite the appropriate parts. If \code{template} +is an incomplete list, the \code{image} will be used to create the internal +object, and then the specified fields will be overwritten from the list. +This allows users to selectively update certain fields while leaving others +alone (but see the note below). + +Datatype information in a list \code{template} is ignored. The datatype can +only be changed using the \code{datatype} argument, but in this case the +internal object gets out of sync with the R array, so an internal image is +returned to avoid the mismatch. Changing the internal datatype in this way +is for advanced usage only. +} +\note{ +The \code{scl_slope} and \code{scl_inter} fields affect the numerical + interpretation of the pixel data, so it is impossible in general to change + them without also changing the array values on both the C and the R side. + Therefore, to avoid unexpected side-effects, these fields are not affected + by this function. +} \author{ Jon Clayden } diff --git a/src/Makevars b/src/Makevars index 8ec6ed2..e2375e1 100644 --- a/src/Makevars +++ b/src/Makevars @@ -1,4 +1,4 @@ -PKG_CPPFLAGS = -DNDEBUG -DHAVE_ZLIB -I../inst/include -Izlib +PKG_CPPFLAGS = -DNDEBUG -DHAVE_ZLIB -DUSING_R -I../inst/include -Izlib OBJECTS_ZLIB = zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/deflate.o zlib/gzclose.o zlib/gzlib.o zlib/gzread.o zlib/gzwrite.o zlib/infback.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o zlib/uncompr.o zlib/zutil.o diff --git a/src/main.cpp b/src/main.cpp index 3f35c7c..48c742a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,11 +25,31 @@ bool isInternal (RObject object) return false; } -RcppExport SEXP readNifti (SEXP _object, SEXP _internal) +RcppExport SEXP niftiVersion (SEXP _path) { BEGIN_RCPP - NiftiImage image(_object); - return image.toArrayOrPointer(as(_internal), "NIfTI image"); + int version = NiftiImage::fileVersion(as(_path)); + return wrap(version); +END_RCPP +} + +RcppExport SEXP readNifti (SEXP _object, SEXP _internal, SEXP _volumes) +{ +BEGIN_RCPP + if (Rf_isNull(_volumes)) + { + NiftiImage image(_object); + return image.toArrayOrPointer(as(_internal), "NIfTI image"); + } + else + { + std::vector volumes; + IntegerVector volumesR(_volumes); + for (int i=0; i(_object), volumes); + return image.toArrayOrPointer(as(_internal), "NIfTI image"); + } END_RCPP } @@ -42,20 +62,40 @@ BEGIN_RCPP END_RCPP } -RcppExport SEXP updateNifti (SEXP _image, SEXP _reference) +RcppExport SEXP updateNifti (SEXP _image, SEXP _reference, SEXP _datatype) { BEGIN_RCPP - const NiftiImage reference(_reference); - RObject image(_image); + const std::string datatype = as(_datatype); + const bool willChangeDatatype = (datatype != "auto"); - if (!reference.isNull()) + if (Rf_isVectorList(_reference) && Rf_length(_reference) < 36) { - NiftiImage updatedImage = reference; - updatedImage.update(image); - return updatedImage.toArray(); + NiftiImage image(_image); + image.update(_reference); + if (willChangeDatatype) + image.changeDatatype(datatype); + return image.toArrayOrPointer(willChangeDatatype, "NIfTI image"); } else - return image; + { + const NiftiImage reference(_reference); + if (reference.isNull() && willChangeDatatype) + { + NiftiImage image(_image); + image.changeDatatype(datatype); + return image.toPointer("NIfTI image"); + } + else if (reference.isNull() && !willChangeDatatype) + return _image; + else + { + NiftiImage image = reference; + image.update(_image); + if (willChangeDatatype) + image.changeDatatype(datatype); + return image.toArrayOrPointer(willChangeDatatype, "NIfTI image"); + } + } END_RCPP } @@ -179,9 +219,10 @@ END_RCPP extern "C" { static R_CallMethodDef callMethods[] = { - { "readNifti", (DL_FUNC) &readNifti, 2 }, + { "niftiVersion", (DL_FUNC) &niftiVersion, 1 }, + { "readNifti", (DL_FUNC) &readNifti, 3 }, { "writeNifti", (DL_FUNC) &writeNifti, 3 }, - { "updateNifti", (DL_FUNC) &updateNifti, 2 }, + { "updateNifti", (DL_FUNC) &updateNifti, 3 }, { "dumpNifti", (DL_FUNC) &dumpNifti, 1 }, { "getXform", (DL_FUNC) &getXform, 2 }, { "setXform", (DL_FUNC) &setXform, 3 }, diff --git a/tests/testthat/test-05-nifti.R b/tests/testthat/test-05-nifti.R index a1c58f0..8f377f1 100644 --- a/tests/testthat/test-05-nifti.R +++ b/tests/testthat/test-05-nifti.R @@ -1,43 +1,76 @@ -context("Reading and writing NIfTI files") +context("Reading, writing and manipulating NIfTI objects") + +test_that("NIfTI objects can be created from data", { + data <- array(rnorm(24), dim=c(3L,2L,4L)) + image <- retrieveNifti(data) + + expect_equal(ndim(data), 3L) + expect_is(image, "internalImage") + expect_equal(dim(image), c(3L,2L,4L)) + expect_equal(pixdim(data), c(1,1,1)) + expect_equal(pixdim(image), c(1,1,1)) + expect_equal(pixunits(data), "Unknown") + expect_equal(pixunits(image), "Unknown") + expect_equal(dumpNifti(image)$datatype, 64L) +}) test_that("NIfTI files can be read and written", { imagePath <- system.file("extdata", "example.nii.gz", package="RNifti") + volumeImagePath <- system.file("extdata", "example_4d.nii.gz", package="RNifti") compressedImagePath <- system.file("extdata", "example_compressed.nii.gz", package="RNifti") tempPath <- paste(tempfile(), "nii.gz", sep=".") - expect_that(dim(readNifti(imagePath,internal=FALSE)), equals(c(96L,96L,60L))) - expect_that(dim(readNifti(imagePath,internal=TRUE)), equals(c(96L,96L,60L))) - expect_that(print(readNifti(imagePath,internal=TRUE)), prints_text("2.5 mm per voxel",fixed=TRUE)) + expect_equal(niftiVersion(imagePath), structure(1L,names=imagePath)) + expect_equal(dim(readNifti(imagePath,internal=FALSE)), c(96L,96L,60L)) + expect_equal(dim(readNifti(imagePath,internal=TRUE)), c(96L,96L,60L)) + expect_output(print(readNifti(imagePath,internal=TRUE)), "2.5 mm per voxel") image <- readNifti(imagePath) - expect_that(pixunits(image), equals(c("mm","s"))) + expect_equal(image[40,40,30], 368) + expect_equal(pixunits(image), c("mm","s")) writeNifti(image, tempPath) - expect_that(pixdim(readNifti(tempPath)), equals(c(2.5,2.5,2.5))) + expect_equal(pixdim(readNifti(tempPath)), c(2.5,2.5,2.5)) unlink(tempPath) + expect_output(print(dumpNifti(image)), "NIfTI-1 header") + expect_equal(dumpNifti(image)$bitpix, 32L) writeNifti(image, tempPath, datatype="short") - expect_that(dumpNifti(tempPath)$bitpix, equals(16L)) + expect_equal(dumpNifti(tempPath)$bitpix, 16L) unlink(tempPath) - expect_that(dumpNifti(image)$dim, equals(c(3L,96L,96L,60L,1L,1L,1L,1L))) + expect_equal(dumpNifti(compressedImagePath)$datatype, 2L) + compressedImage <- readNifti(compressedImagePath) + expect_equal(dumpNifti(compressedImage)$datatype, 64L) + expect_equal(round(compressedImage[40,40,30]), 363) + + image <- readNifti(imagePath, internal=TRUE) + expect_equal(as.array(image)[40,40,30], 368) + expect_error(dim(image) <- c(60L,96L,96L)) + + image <- readNifti(volumeImagePath, volumes=1:2) + expect_equal(dim(image), c(96L,96L,60L,2L)) + expect_equal(max(image), 2) + expect_output(print(image), "x 1 s") # time units only appear for 4D+ images +}) + +test_that("image objects can be manipulated", { + imagePath <- system.file("extdata", "example.nii.gz", package="RNifti") + image <- readNifti(imagePath) + + expect_equal(dumpNifti(image)$dim, c(3L,96L,96L,60L,1L,1L,1L,1L)) pixdim(image) <- c(5,5,5) - expect_that(dumpNifti(image)$pixdim, equals(c(-1,5,5,5,0,0,0,0))) + expect_equal(dumpNifti(image)$pixdim, c(-1,5,5,5,0,0,0,0)) pixunits(image) <- c("m","ms") - expect_that(dumpNifti(image)$xyzt_units, equals(17L)) + expect_equal(dumpNifti(image)$xyzt_units, 17L) image <- updateNifti(image, list(intent_code=1000L)) - expect_that(dumpNifti(image)$intent_code, equals(1000L)) + expect_equal(dumpNifti(image)$intent_code, 1000L) + image <- updateNifti(image, datatype="float") + expect_equal(dumpNifti(image)$datatype, 16L) - expect_that(image[40,40,30], equals(368)) image <- readNifti(imagePath, internal=TRUE) - expect_that(as.array(image)[40,40,30], equals(368)) image <- RNifti:::rescaleNifti(image, c(0.5,0.5,0.5)) - expect_that(pixdim(image), equals(c(5,5,5))) - expect_that(as.array(image), gives_warning("no data")) - - expect_that(dumpNifti(compressedImagePath)$datatype, equals(2L)) - compressedImage <- readNifti(compressedImagePath) - expect_that(dumpNifti(compressedImage)$datatype, equals(64L)) - expect_that(round(compressedImage[40,40,30]), equals(363)) + expect_equal(pixdim(image), c(5,5,5)) + expect_warning(as.array(image), "no data") }) diff --git a/tests/testthat/test-10-xform.R b/tests/testthat/test-10-xform.R index d36e116..d55317d 100644 --- a/tests/testthat/test-10-xform.R +++ b/tests/testthat/test-10-xform.R @@ -4,32 +4,33 @@ test_that("NIfTI sform/qform operations work", { imagePath <- system.file("extdata", "example.nii.gz", package="RNifti") image <- readNifti(imagePath) - expect_that(diag(xform(image)), equals(c(-2.5,2.5,2.5,1))) - expect_that(diag(xform(image,useQuaternionFirst=FALSE)), equals(c(-2.5,2.5,2.5,1))) + expect_equal(diag(xform(image)), c(-2.5,2.5,2.5,1)) + expect_equal(diag(xform(image,useQuaternionFirst=FALSE)), c(-2.5,2.5,2.5,1)) + expect_equal(round(origin(image)), c(50,39,23)) point <- c(40, 40, 20) - expect_that(round(voxelToWorld(point,image)), equals(c(25,2,-8))) - expect_that(voxelToWorld(point,image,simple=TRUE), equals(c(97.5,97.5,47.5))) - expect_that(worldToVoxel(voxelToWorld(point,image),image), equals(point)) - expect_that(worldToVoxel(voxelToWorld(point,image,simple=TRUE),image,simple=TRUE), equals(point)) + expect_equal(round(voxelToWorld(point,image)), c(25,2,-8)) + expect_equal(voxelToWorld(point,image,simple=TRUE), c(97.5,97.5,47.5)) + expect_equal(worldToVoxel(voxelToWorld(point,image),image), point) + expect_equal(worldToVoxel(voxelToWorld(point,image,simple=TRUE),image,simple=TRUE), point) # NB: indexing into the image currently discards the metadata, including the xforms - expect_that(voxelToWorld(point[1:2],image[,,20L]), equals(c(39,39))) + expect_equal(voxelToWorld(point[1:2],image[,,20L]), c(39,39)) # Copy image object to check copy semantics originalImage <- image xform <- structure(round(xform(image)), code=4) qform(image) <- xform sform(image) <- xform - expect_that(dumpNifti(image)$qform_code, equals(4L)) - expect_that(dumpNifti(image)$sform_code, equals(4L)) - expect_that(dumpNifti(image)$srow_x, equals(c(-2,0,0,122))) - expect_that(dumpNifti(originalImage)$qform_code, equals(2L)) + expect_equal(dumpNifti(image)$qform_code, 4L) + expect_equal(dumpNifti(image)$sform_code, 4L) + expect_equal(dumpNifti(image)$srow_x, c(-2,0,0,122)) + expect_equal(dumpNifti(originalImage)$qform_code, 2L) image <- readNifti(imagePath, internal=FALSE) reorientedImage <- image orientation(reorientedImage) <- "PIR" - expect_that(orientation(image), equals("LAS")) - expect_that(orientation(reorientedImage), equals("PIR")) - expect_that(image[40,40,30], equals(reorientedImage[57,31,57])) + expect_equal(orientation(image), "LAS") + expect_equal(orientation(reorientedImage), "PIR") + expect_equal(image[40,40,30], reorientedImage[57,31,57]) }) diff --git a/tests/testthat/test-15-foreign.R b/tests/testthat/test-15-foreign.R index b9ef140..48bcb16 100644 --- a/tests/testthat/test-15-foreign.R +++ b/tests/testthat/test-15-foreign.R @@ -1,27 +1,25 @@ context("Working with objects from other packages") -test_that("image objects from other packages can be read", { +test_that("image objects from oro.nifti can be read", { imagePath <- system.file("extdata", "example.nii.gz", package="RNifti") - if (system.file(package="oro.nifti") == "") - skip("The \"oro.nifti\" package is not available") - else - { - # The oro.nifti package warns about nonzero slope, which is nothing to worry about - image <- suppressWarnings(oro.nifti::readNIfTI(imagePath)) - expect_that(dumpNifti(image)$bitpix, equals(32L)) - } + skip_if_not_installed("oro.nifti") - if (system.file(package="tractor.base") == "") - skip("The \"tractor.base\" package is not available") - else - { - reportr::setOutputLevel(reportr::OL$Warning) - - image <- tractor.base::readImageFile(imagePath) - expect_that(dumpNifti(image)$bitpix, equals(32L)) - - image <- tractor.base::readImageFile(imagePath, sparse=TRUE) - expect_that(dumpNifti(image)$bitpix, equals(32L)) - } -}) \ No newline at end of file + # The oro.nifti package warns about nonzero slope, which is nothing to worry about + image <- suppressWarnings(oro.nifti::readNIfTI(imagePath)) + expect_equal(dumpNifti(image)$bitpix, 32L) +}) + +test_that("image objects from tractor.base can be read", { + imagePath <- system.file("extdata", "example.nii.gz", package="RNifti") + + skip_if_not_installed("tractor.base") + + reportr::setOutputLevel(reportr::OL$Warning) + + image <- tractor.base::readImageFile(imagePath) + expect_equal(dumpNifti(image)$bitpix, 32L) + + image <- tractor.base::readImageFile(imagePath, sparse=TRUE) + expect_equal(dumpNifti(image)$bitpix, 32L) +})