From 5f6da2f4f121db4e5befd67726ec2b3a08ac8798 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Mon, 11 Dec 2023 16:10:33 -0500 Subject: [PATCH] Documentation build - no history --- .nojekyll | 0 .../cross_product_error.ipynb | 154 + .../neuro_radio_conventions-2_01.hires.png | Bin 0 -> 70273 bytes .../coordinate_systems-3_01.hires.png | Bin 0 -> 70273 bytes .../neuro_radio_conventions-2_00.png | Bin 0 -> 45578 bytes .../neuro_radio_conventions-2_01.png | Bin 0 -> 58088 bytes .../neuro_radio_conventions-2_00.pdf | Bin 0 -> 27362 bytes .../ata_error.ipynb | 251 + .../neuro_radio_conventions-2_00.hires.png | Bin 0 -> 54907 bytes .../spm_dicom_orient.py | 163 + .../coordinate_systems-2.pdf | Bin 0 -> 27362 bytes .../neuro_radio_conventions-2_01.pdf | Bin 0 -> 33286 bytes .../coordinate_systems-2.png | Bin 0 -> 45578 bytes .../coordinate_systems-2.hires.png | Bin 0 -> 54907 bytes .../someones_anatomy.nii.gz | Bin 0 -> 191449 bytes .../coordinate_systems-3_01.png | Bin 0 -> 58088 bytes .../coordinate_systems-3_00.hires.png | Bin 0 -> 54907 bytes .../coordinate_systems-3_00.pdf | Bin 0 -> 27362 bytes .../coordinate_systems-3_01.pdf | Bin 0 -> 33286 bytes .../coordinate_systems-3_00.png | Bin 0 -> 45578 bytes .../someones_epi.nii.gz | Bin 0 -> 93766 bytes _images/biap_flowchart.png | Bin 0 -> 12925 bytes _images/branch_dropdown.png | Bin 0 -> 16311 bytes _images/coordinate_systems-2.png | Bin 0 -> 45578 bytes _images/coordinate_systems-3_00.png | Bin 0 -> 45578 bytes _images/coordinate_systems-3_01.png | Bin 0 -> 58088 bytes _images/forking_button.png | Bin 0 -> 13092 bytes _images/illustrating_affine.png | Bin 0 -> 136815 bytes _images/localizer.png | Bin 0 -> 187883 bytes _images/mosaic_grid.png | Bin 0 -> 44060 bytes _images/neuro_radio_conventions-2_00.png | Bin 0 -> 45578 bytes _images/neuro_radio_conventions-2_01.png | Bin 0 -> 58088 bytes _images/pull_button.png | Bin 0 -> 12893 bytes _images/rorden_radio_neuro.jpg | Bin 0 -> 102453 bytes _sources/api.rst.txt | 101 + _sources/changelog.rst.txt | 1597 +++++++ _sources/coordinate_systems.rst.txt | 962 ++++ _sources/devel/add_image_format.rst.txt | 159 + _sources/devel/add_test_data.rst.txt | 137 + _sources/devel/advanced_testing.rst.txt | 32 + _sources/devel/biaps/biap_0000.rst.txt | 281 ++ _sources/devel/biaps/biap_0001.rst.txt | 299 ++ _sources/devel/biaps/biap_0002.rst.txt | 176 + _sources/devel/biaps/biap_0003.rst.txt | 751 +++ _sources/devel/biaps/biap_0004.rst.txt | 235 + _sources/devel/biaps/biap_0005.rst.txt | 160 + _sources/devel/biaps/biap_0006.rst.txt | 284 ++ _sources/devel/biaps/biap_0007.rst.txt | 116 + _sources/devel/biaps/biap_0008.rst.txt | 158 + _sources/devel/biaps/biap_0009.rst.txt | 335 ++ _sources/devel/biaps/biap_template.rst.txt | 92 + _sources/devel/biaps/index.rst.txt | 27 + _sources/devel/bv_formats.rst.txt | 98 + _sources/devel/core_developer.rst.txt | 152 + _sources/devel/data_pkg_discuss.rst.txt | 383 ++ _sources/devel/devdiscuss.rst.txt | 25 + _sources/devel/devguide.rst.txt | 211 + _sources/devel/governance.rst.txt | 180 + _sources/devel/image_design.rst.txt | 7 + _sources/devel/index.rst.txt | 21 + _sources/devel/make_release.rst.txt | 315 ++ _sources/devel/modified_images.rst.txt | 121 + _sources/devel/roadmap.rst.txt | 93 + _sources/devel/scaling.rst.txt | 70 + _sources/devel/spm_use.rst.txt | 299 ++ _sources/dicom/dcm2nii_algorithms.rst.txt | 92 + _sources/dicom/dicom.rst.txt | 26 + _sources/dicom/dicom_fields.rst.txt | 74 + _sources/dicom/dicom_info.rst.txt | 51 + _sources/dicom/dicom_intro.rst.txt | 793 ++++ _sources/dicom/dicom_mosaic.rst.txt | 138 + _sources/dicom/dicom_niftiheader.rst.txt | 73 + _sources/dicom/dicom_orientation.rst.txt | 412 ++ _sources/dicom/siemens_csa.rst.txt | 135 + _sources/dicom/spm_dicom.rst.txt | 309 ++ _sources/gettingstarted.rst.txt | 122 + _sources/gitwash/configure_git.rst.txt | 158 + _sources/gitwash/development_workflow.rst.txt | 415 ++ _sources/gitwash/following_latest.rst.txt | 36 + _sources/gitwash/forking_hell.rst.txt | 32 + _sources/gitwash/git_development.rst.txt | 16 + _sources/gitwash/git_install.rst.txt | 26 + _sources/gitwash/git_intro.rst.txt | 18 + _sources/gitwash/git_resources.rst.txt | 59 + _sources/gitwash/index.rst.txt | 16 + _sources/gitwash/maintainer_workflow.rst.txt | 96 + _sources/gitwash/patching.rst.txt | 134 + _sources/gitwash/set_up_fork.rst.txt | 67 + _sources/image_orientation.rst.txt | 91 + _sources/images_and_memory.rst.txt | 225 + _sources/index.rst.txt | 176 + _sources/installation.rst.txt | 139 + _sources/legal.rst.txt | 220 + _sources/manual.rst.txt | 16 + _sources/neuro_radio_conventions.rst.txt | 144 + _sources/nibabel_images.rst.txt | 434 ++ _sources/nifti_images.rst.txt | 494 ++ _sources/notebooks/index.rst.txt | 16 + _sources/old/ioimplementation.rst.txt | 128 + _sources/reference/index.rst.txt | 67 + .../reference/nibabel._compression.rst.txt | 13 + _sources/reference/nibabel.affines.rst.txt | 74 + _sources/reference/nibabel.analyze.rst.txt | 39 + _sources/reference/nibabel.arrayproxy.rst.txt | 57 + .../reference/nibabel.arraywriters.rst.txt | 90 + .../reference/nibabel.batteryrunners.rst.txt | 39 + _sources/reference/nibabel.benchmarks.rst.txt | 133 + _sources/reference/nibabel.brikhead.rst.txt | 84 + _sources/reference/nibabel.caret.rst.txt | 26 + _sources/reference/nibabel.casting.rst.txt | 141 + _sources/reference/nibabel.cifti2.rst.txt | 402 ++ _sources/reference/nibabel.cmdline.rst.txt | 425 ++ _sources/reference/nibabel.data.rst.txt | 102 + .../reference/nibabel.dataobj_images.rst.txt | 26 + _sources/reference/nibabel.deprecated.rst.txt | 58 + _sources/reference/nibabel.deprecator.rst.txt | 39 + _sources/reference/nibabel.dft.rst.txt | 83 + _sources/reference/nibabel.ecat.rst.txt | 89 + .../reference/nibabel.environment.rst.txt | 31 + .../reference/nibabel.eulerangles.rst.txt | 49 + .../reference/nibabel.filebasedimages.rst.txt | 65 + .../reference/nibabel.fileholders.rst.txt | 45 + .../reference/nibabel.filename_parser.rst.txt | 44 + _sources/reference/nibabel.fileslice.rst.txt | 97 + _sources/reference/nibabel.fileutils.rst.txt | 19 + _sources/reference/nibabel.freesurfer.rst.txt | 120 + _sources/reference/nibabel.funcs.rst.txt | 37 + _sources/reference/nibabel.gifti.rst.txt | 175 + .../reference/nibabel.imageclasses.rst.txt | 19 + .../reference/nibabel.imageglobals.rst.txt | 39 + _sources/reference/nibabel.imagestats.rst.txt | 25 + _sources/reference/nibabel.loadsave.rst.txt | 37 + _sources/reference/nibabel.minc1.rst.txt | 91 + _sources/reference/nibabel.minc2.rst.txt | 65 + _sources/reference/nibabel.mriutils.rst.txt | 32 + _sources/reference/nibabel.nicom.rst.txt | 435 ++ _sources/reference/nibabel.nifti1.rst.txt | 116 + _sources/reference/nibabel.nifti2.rst.txt | 77 + _sources/reference/nibabel.onetime.rst.txt | 51 + _sources/reference/nibabel.openers.rst.txt | 65 + _sources/reference/nibabel.optpkg.rst.txt | 19 + .../reference/nibabel.orientations.rst.txt | 74 + _sources/reference/nibabel.parrec.rst.txt | 95 + _sources/reference/nibabel.pointset.rst.txt | 65 + _sources/reference/nibabel.processing.rst.txt | 55 + .../reference/nibabel.pydicom_compat.rst.txt | 19 + .../reference/nibabel.quaternions.rst.txt | 97 + _sources/reference/nibabel.rst.txt | 31 + _sources/reference/nibabel.rstutils.rst.txt | 19 + _sources/reference/nibabel.spaces.rst.txt | 25 + .../reference/nibabel.spatialimages.rst.txt | 123 + .../reference/nibabel.spm2analyze.rst.txt | 39 + .../reference/nibabel.spm99analyze.rst.txt | 52 + .../reference/nibabel.streamlines.rst.txt | 434 ++ _sources/reference/nibabel.tmpdirs.rst.txt | 38 + _sources/reference/nibabel.tripwire.rst.txt | 45 + _sources/reference/nibabel.viewers.rst.txt | 26 + .../reference/nibabel.volumeutils.rst.txt | 129 + _sources/reference/nibabel.wrapstruct.rst.txt | 52 + _sources/reference/nibabel.xmlutils.rst.txt | 52 + _sources/tutorials.rst.txt | 11 + _static/basic.css | 925 ++++ _static/contents.png | Bin 0 -> 107 bytes _static/doctools.js | 156 + _static/documentation_options.js | 13 + _static/file.png | Bin 0 -> 286 bytes _static/graphviz.css | 19 + _static/item.png | Bin 0 -> 378 bytes _static/language_data.js | 199 + _static/minus.png | Bin 0 -> 90 bytes _static/navigation.png | Bin 0 -> 120 bytes _static/nibabel-logo.svg | 91 + _static/nibabel.css | 42 + _static/nipy-logo-bg-138x120.png | Bin 0 -> 29906 bytes _static/nipy.css | 507 ++ _static/plot_directive.css | 16 + _static/plus.png | Bin 0 -> 90 bytes _static/pygments.css | 74 + _static/reggie.png | Bin 0 -> 13454 bytes _static/searchtools.js | 574 +++ _static/sphinx_highlight.js | 154 + _static/sphinxdoc.css | 354 ++ api.html | 362 ++ changelog.html | 2064 +++++++++ coordinate_systems.html | 928 ++++ devel/add_image_format.html | 262 ++ devel/add_test_data.html | 243 + devel/advanced_testing.html | 135 + devel/biaps/biap_0000.html | 368 ++ devel/biaps/biap_0001.html | 412 ++ devel/biaps/biap_0002.html | 281 ++ devel/biaps/biap_0003.html | 840 ++++ devel/biaps/biap_0004.html | 342 ++ devel/biaps/biap_0005.html | 271 ++ devel/biaps/biap_0006.html | 362 ++ devel/biaps/biap_0007.html | 217 + devel/biaps/biap_0008.html | 268 ++ devel/biaps/biap_0009.html | 478 ++ devel/biaps/biap_template.html | 211 + devel/biaps/index.html | 128 + devel/bv_formats.html | 197 + devel/core_developer.html | 256 ++ devel/data_pkg_discuss.html | 466 ++ devel/devdiscuss.html | 133 + devel/devguide.html | 312 ++ devel/governance.html | 298 ++ devel/image_design.html | 92 + devel/index.html | 187 + devel/make_release.html | 425 ++ devel/modified_images.html | 224 + devel/roadmap.html | 208 + devel/scaling.html | 171 + devel/spm_use.html | 391 ++ dicom/dcm2nii_algorithms.html | 202 + dicom/dicom.html | 160 + dicom/dicom_fields.html | 180 + dicom/dicom_info.html | 160 + dicom/dicom_intro.html | 1009 ++++ dicom/dicom_mosaic.html | 232 + dicom/dicom_niftiheader.html | 183 + dicom/dicom_orientation.html | 461 ++ dicom/siemens_csa.html | 248 + dicom/spm_dicom.html | 409 ++ genindex.html | 4080 +++++++++++++++++ gettingstarted.html | 209 + gitwash/configure_git.html | 272 ++ gitwash/development_workflow.html | 506 ++ gitwash/following_latest.html | 149 + gitwash/forking_hell.html | 146 + gitwash/git_development.html | 146 + gitwash/git_install.html | 148 + gitwash/git_intro.html | 121 + gitwash/git_resources.html | 177 + gitwash/index.html | 146 + gitwash/maintainer_workflow.html | 206 + gitwash/patching.html | 252 + gitwash/set_up_fork.html | 182 + image_orientation.html | 188 + images_and_memory.html | 333 ++ index.html | 343 ++ installation.html | 235 + legal.html | 323 ++ manual.html | 395 ++ neuro_radio_conventions.html | 254 + nibabel_images.html | 529 +++ nifti_images.html | 591 +++ notebooks/index.html | 108 + objects.inv | Bin 0 -> 13919 bytes old/ioimplementation.html | 212 + py-modindex.html | 596 +++ reference/index.html | 3323 ++++++++++++++ reference/nibabel._compression.html | 116 + reference/nibabel.affines.html | 554 +++ reference/nibabel.analyze.html | 993 ++++ reference/nibabel.arrayproxy.html | 432 ++ reference/nibabel.arraywriters.html | 790 ++++ reference/nibabel.batteryrunners.html | 449 ++ reference/nibabel.benchmarks.html | 330 ++ reference/nibabel.brikhead.html | 701 +++ reference/nibabel.caret.html | 182 + reference/nibabel.casting.html | 838 ++++ reference/nibabel.cifti2.html | 2785 +++++++++++ reference/nibabel.cmdline.html | 999 ++++ reference/nibabel.data.html | 546 +++ reference/nibabel.dataobj_images.html | 509 ++ reference/nibabel.deprecated.html | 277 ++ reference/nibabel.deprecator.html | 225 + reference/nibabel.dft.html | 269 ++ reference/nibabel.ecat.html | 899 ++++ reference/nibabel.environment.html | 233 + reference/nibabel.eulerangles.html | 519 +++ reference/nibabel.filebasedimages.html | 794 ++++ reference/nibabel.fileholders.html | 290 ++ reference/nibabel.filename_parser.html | 333 ++ reference/nibabel.fileslice.html | 746 +++ reference/nibabel.fileutils.html | 166 + reference/nibabel.freesurfer.html | 1018 ++++ reference/nibabel.funcs.html | 301 ++ reference/nibabel.gifti.html | 1039 +++++ reference/nibabel.html | 306 ++ reference/nibabel.imageclasses.html | 155 + reference/nibabel.imageglobals.html | 184 + reference/nibabel.imagestats.html | 195 + reference/nibabel.loadsave.html | 231 + reference/nibabel.minc1.html | 499 ++ reference/nibabel.minc2.html | 380 ++ reference/nibabel.mriutils.html | 189 + reference/nibabel.nicom.html | 2098 +++++++++ reference/nibabel.nifti1.html | 1912 ++++++++ reference/nibabel.nifti2.html | 556 +++ reference/nibabel.onetime.html | 339 ++ reference/nibabel.openers.html | 449 ++ reference/nibabel.optpkg.html | 202 + reference/nibabel.orientations.html | 466 ++ reference/nibabel.parrec.html | 1032 +++++ reference/nibabel.pointset.html | 360 ++ reference/nibabel.processing.html | 477 ++ reference/nibabel.pydicom_compat.html | 162 + reference/nibabel.quaternions.html | 665 +++ reference/nibabel.rstutils.html | 174 + reference/nibabel.spaces.html | 238 + reference/nibabel.spatialimages.html | 852 ++++ reference/nibabel.spm2analyze.html | 431 ++ reference/nibabel.spm99analyze.html | 745 +++ reference/nibabel.streamlines.html | 2329 ++++++++++ reference/nibabel.tmpdirs.html | 260 ++ reference/nibabel.tripwire.html | 206 + reference/nibabel.viewers.html | 319 ++ reference/nibabel.volumeutils.html | 1123 +++++ reference/nibabel.wrapstruct.html | 721 +++ reference/nibabel.xmlutils.html | 282 ++ search.html | 105 + searchindex.js | 1 + tutorials.html | 174 + 314 files changed, 87267 insertions(+) create mode 100644 .nojekyll create mode 100644 _downloads/01d26ddfe66a9569b4cf79881141dece/cross_product_error.ipynb create mode 100644 _downloads/15ee5f982d34b67854edc69ebd5e3772/neuro_radio_conventions-2_01.hires.png create mode 100644 _downloads/2174665309d4572bf9425c62abdb3e82/coordinate_systems-3_01.hires.png create mode 100644 _downloads/5b2b00af981a01f3cc5e81b34ccc8fdb/neuro_radio_conventions-2_00.png create mode 100644 _downloads/6be0680a63be0340a581f954a2ec30b9/neuro_radio_conventions-2_01.png create mode 100644 _downloads/79cc4a050731c618885fe142bc9dfcaf/neuro_radio_conventions-2_00.pdf create mode 100644 _downloads/83473e2bf68165d7691882d14e07c1fe/ata_error.ipynb create mode 100644 _downloads/9e0340951323f17d19212a1b25b97064/neuro_radio_conventions-2_00.hires.png create mode 100644 _downloads/a0359552c75a1df40c301397f03c7556/spm_dicom_orient.py create mode 100644 _downloads/a8f112aa4c254d4394f4e73b75e10047/coordinate_systems-2.pdf create mode 100644 _downloads/ae8bde362c4868fea3617fb37893ca61/neuro_radio_conventions-2_01.pdf create mode 100644 _downloads/b5b25fc5e75398a75b3dee5d03dee056/coordinate_systems-2.png create mode 100644 _downloads/bb31c24d40cb6a247054fb507ce53e36/coordinate_systems-2.hires.png create mode 100644 _downloads/c16214e490de2a223655d30f4ba78f15/someones_anatomy.nii.gz create mode 100644 _downloads/ce40033060c439c27eb234896af2b1e6/coordinate_systems-3_01.png create mode 100644 _downloads/dc0e6623b8086a1f47ed26af34e7c6ba/coordinate_systems-3_00.hires.png create mode 100644 _downloads/e6b45cf94b78c71339be16615ab48886/coordinate_systems-3_00.pdf create mode 100644 _downloads/ea07875cb182b05530c1caaa47b509a8/coordinate_systems-3_01.pdf create mode 100644 _downloads/f421d045ed7d77d5be5b5aa28544d030/coordinate_systems-3_00.png create mode 100644 _downloads/f76cc5a46e5368e2c779868abc49e497/someones_epi.nii.gz create mode 100644 _images/biap_flowchart.png create mode 100644 _images/branch_dropdown.png create mode 100644 _images/coordinate_systems-2.png create mode 100644 _images/coordinate_systems-3_00.png create mode 100644 _images/coordinate_systems-3_01.png create mode 100644 _images/forking_button.png create mode 100644 _images/illustrating_affine.png create mode 100644 _images/localizer.png create mode 100644 _images/mosaic_grid.png create mode 100644 _images/neuro_radio_conventions-2_00.png create mode 100644 _images/neuro_radio_conventions-2_01.png create mode 100644 _images/pull_button.png create mode 100644 _images/rorden_radio_neuro.jpg create mode 100644 _sources/api.rst.txt create mode 100644 _sources/changelog.rst.txt create mode 100644 _sources/coordinate_systems.rst.txt create mode 100644 _sources/devel/add_image_format.rst.txt create mode 100644 _sources/devel/add_test_data.rst.txt create mode 100644 _sources/devel/advanced_testing.rst.txt create mode 100644 _sources/devel/biaps/biap_0000.rst.txt create mode 100644 _sources/devel/biaps/biap_0001.rst.txt create mode 100644 _sources/devel/biaps/biap_0002.rst.txt create mode 100644 _sources/devel/biaps/biap_0003.rst.txt create mode 100644 _sources/devel/biaps/biap_0004.rst.txt create mode 100644 _sources/devel/biaps/biap_0005.rst.txt create mode 100644 _sources/devel/biaps/biap_0006.rst.txt create mode 100644 _sources/devel/biaps/biap_0007.rst.txt create mode 100644 _sources/devel/biaps/biap_0008.rst.txt create mode 100644 _sources/devel/biaps/biap_0009.rst.txt create mode 100644 _sources/devel/biaps/biap_template.rst.txt create mode 100644 _sources/devel/biaps/index.rst.txt create mode 100644 _sources/devel/bv_formats.rst.txt create mode 100644 _sources/devel/core_developer.rst.txt create mode 100644 _sources/devel/data_pkg_discuss.rst.txt create mode 100644 _sources/devel/devdiscuss.rst.txt create mode 100644 _sources/devel/devguide.rst.txt create mode 100644 _sources/devel/governance.rst.txt create mode 100644 _sources/devel/image_design.rst.txt create mode 100644 _sources/devel/index.rst.txt create mode 100644 _sources/devel/make_release.rst.txt create mode 100644 _sources/devel/modified_images.rst.txt create mode 100644 _sources/devel/roadmap.rst.txt create mode 100644 _sources/devel/scaling.rst.txt create mode 100644 _sources/devel/spm_use.rst.txt create mode 100644 _sources/dicom/dcm2nii_algorithms.rst.txt create mode 100644 _sources/dicom/dicom.rst.txt create mode 100644 _sources/dicom/dicom_fields.rst.txt create mode 100644 _sources/dicom/dicom_info.rst.txt create mode 100644 _sources/dicom/dicom_intro.rst.txt create mode 100644 _sources/dicom/dicom_mosaic.rst.txt create mode 100644 _sources/dicom/dicom_niftiheader.rst.txt create mode 100644 _sources/dicom/dicom_orientation.rst.txt create mode 100644 _sources/dicom/siemens_csa.rst.txt create mode 100644 _sources/dicom/spm_dicom.rst.txt create mode 100644 _sources/gettingstarted.rst.txt create mode 100644 _sources/gitwash/configure_git.rst.txt create mode 100644 _sources/gitwash/development_workflow.rst.txt create mode 100644 _sources/gitwash/following_latest.rst.txt create mode 100644 _sources/gitwash/forking_hell.rst.txt create mode 100644 _sources/gitwash/git_development.rst.txt create mode 100644 _sources/gitwash/git_install.rst.txt create mode 100644 _sources/gitwash/git_intro.rst.txt create mode 100644 _sources/gitwash/git_resources.rst.txt create mode 100644 _sources/gitwash/index.rst.txt create mode 100644 _sources/gitwash/maintainer_workflow.rst.txt create mode 100644 _sources/gitwash/patching.rst.txt create mode 100644 _sources/gitwash/set_up_fork.rst.txt create mode 100644 _sources/image_orientation.rst.txt create mode 100644 _sources/images_and_memory.rst.txt create mode 100644 _sources/index.rst.txt create mode 100644 _sources/installation.rst.txt create mode 100644 _sources/legal.rst.txt create mode 100644 _sources/manual.rst.txt create mode 100644 _sources/neuro_radio_conventions.rst.txt create mode 100644 _sources/nibabel_images.rst.txt create mode 100644 _sources/nifti_images.rst.txt create mode 100644 _sources/notebooks/index.rst.txt create mode 100644 _sources/old/ioimplementation.rst.txt create mode 100644 _sources/reference/index.rst.txt create mode 100644 _sources/reference/nibabel._compression.rst.txt create mode 100644 _sources/reference/nibabel.affines.rst.txt create mode 100644 _sources/reference/nibabel.analyze.rst.txt create mode 100644 _sources/reference/nibabel.arrayproxy.rst.txt create mode 100644 _sources/reference/nibabel.arraywriters.rst.txt create mode 100644 _sources/reference/nibabel.batteryrunners.rst.txt create mode 100644 _sources/reference/nibabel.benchmarks.rst.txt create mode 100644 _sources/reference/nibabel.brikhead.rst.txt create mode 100644 _sources/reference/nibabel.caret.rst.txt create mode 100644 _sources/reference/nibabel.casting.rst.txt create mode 100644 _sources/reference/nibabel.cifti2.rst.txt create mode 100644 _sources/reference/nibabel.cmdline.rst.txt create mode 100644 _sources/reference/nibabel.data.rst.txt create mode 100644 _sources/reference/nibabel.dataobj_images.rst.txt create mode 100644 _sources/reference/nibabel.deprecated.rst.txt create mode 100644 _sources/reference/nibabel.deprecator.rst.txt create mode 100644 _sources/reference/nibabel.dft.rst.txt create mode 100644 _sources/reference/nibabel.ecat.rst.txt create mode 100644 _sources/reference/nibabel.environment.rst.txt create mode 100644 _sources/reference/nibabel.eulerangles.rst.txt create mode 100644 _sources/reference/nibabel.filebasedimages.rst.txt create mode 100644 _sources/reference/nibabel.fileholders.rst.txt create mode 100644 _sources/reference/nibabel.filename_parser.rst.txt create mode 100644 _sources/reference/nibabel.fileslice.rst.txt create mode 100644 _sources/reference/nibabel.fileutils.rst.txt create mode 100644 _sources/reference/nibabel.freesurfer.rst.txt create mode 100644 _sources/reference/nibabel.funcs.rst.txt create mode 100644 _sources/reference/nibabel.gifti.rst.txt create mode 100644 _sources/reference/nibabel.imageclasses.rst.txt create mode 100644 _sources/reference/nibabel.imageglobals.rst.txt create mode 100644 _sources/reference/nibabel.imagestats.rst.txt create mode 100644 _sources/reference/nibabel.loadsave.rst.txt create mode 100644 _sources/reference/nibabel.minc1.rst.txt create mode 100644 _sources/reference/nibabel.minc2.rst.txt create mode 100644 _sources/reference/nibabel.mriutils.rst.txt create mode 100644 _sources/reference/nibabel.nicom.rst.txt create mode 100644 _sources/reference/nibabel.nifti1.rst.txt create mode 100644 _sources/reference/nibabel.nifti2.rst.txt create mode 100644 _sources/reference/nibabel.onetime.rst.txt create mode 100644 _sources/reference/nibabel.openers.rst.txt create mode 100644 _sources/reference/nibabel.optpkg.rst.txt create mode 100644 _sources/reference/nibabel.orientations.rst.txt create mode 100644 _sources/reference/nibabel.parrec.rst.txt create mode 100644 _sources/reference/nibabel.pointset.rst.txt create mode 100644 _sources/reference/nibabel.processing.rst.txt create mode 100644 _sources/reference/nibabel.pydicom_compat.rst.txt create mode 100644 _sources/reference/nibabel.quaternions.rst.txt create mode 100644 _sources/reference/nibabel.rst.txt create mode 100644 _sources/reference/nibabel.rstutils.rst.txt create mode 100644 _sources/reference/nibabel.spaces.rst.txt create mode 100644 _sources/reference/nibabel.spatialimages.rst.txt create mode 100644 _sources/reference/nibabel.spm2analyze.rst.txt create mode 100644 _sources/reference/nibabel.spm99analyze.rst.txt create mode 100644 _sources/reference/nibabel.streamlines.rst.txt create mode 100644 _sources/reference/nibabel.tmpdirs.rst.txt create mode 100644 _sources/reference/nibabel.tripwire.rst.txt create mode 100644 _sources/reference/nibabel.viewers.rst.txt create mode 100644 _sources/reference/nibabel.volumeutils.rst.txt create mode 100644 _sources/reference/nibabel.wrapstruct.rst.txt create mode 100644 _sources/reference/nibabel.xmlutils.rst.txt create mode 100644 _sources/tutorials.rst.txt create mode 100644 _static/basic.css create mode 100644 _static/contents.png create mode 100644 _static/doctools.js create mode 100644 _static/documentation_options.js create mode 100644 _static/file.png create mode 100644 _static/graphviz.css create mode 100644 _static/item.png create mode 100644 _static/language_data.js create mode 100644 _static/minus.png create mode 100644 _static/navigation.png create mode 100644 _static/nibabel-logo.svg create mode 100644 _static/nibabel.css create mode 100644 _static/nipy-logo-bg-138x120.png create mode 100644 _static/nipy.css create mode 100644 _static/plot_directive.css create mode 100644 _static/plus.png create mode 100644 _static/pygments.css create mode 100644 _static/reggie.png create mode 100644 _static/searchtools.js create mode 100644 _static/sphinx_highlight.js create mode 100644 _static/sphinxdoc.css create mode 100644 api.html create mode 100644 changelog.html create mode 100644 coordinate_systems.html create mode 100644 devel/add_image_format.html create mode 100644 devel/add_test_data.html create mode 100644 devel/advanced_testing.html create mode 100644 devel/biaps/biap_0000.html create mode 100644 devel/biaps/biap_0001.html create mode 100644 devel/biaps/biap_0002.html create mode 100644 devel/biaps/biap_0003.html create mode 100644 devel/biaps/biap_0004.html create mode 100644 devel/biaps/biap_0005.html create mode 100644 devel/biaps/biap_0006.html create mode 100644 devel/biaps/biap_0007.html create mode 100644 devel/biaps/biap_0008.html create mode 100644 devel/biaps/biap_0009.html create mode 100644 devel/biaps/biap_template.html create mode 100644 devel/biaps/index.html create mode 100644 devel/bv_formats.html create mode 100644 devel/core_developer.html create mode 100644 devel/data_pkg_discuss.html create mode 100644 devel/devdiscuss.html create mode 100644 devel/devguide.html create mode 100644 devel/governance.html create mode 100644 devel/image_design.html create mode 100644 devel/index.html create mode 100644 devel/make_release.html create mode 100644 devel/modified_images.html create mode 100644 devel/roadmap.html create mode 100644 devel/scaling.html create mode 100644 devel/spm_use.html create mode 100644 dicom/dcm2nii_algorithms.html create mode 100644 dicom/dicom.html create mode 100644 dicom/dicom_fields.html create mode 100644 dicom/dicom_info.html create mode 100644 dicom/dicom_intro.html create mode 100644 dicom/dicom_mosaic.html create mode 100644 dicom/dicom_niftiheader.html create mode 100644 dicom/dicom_orientation.html create mode 100644 dicom/siemens_csa.html create mode 100644 dicom/spm_dicom.html create mode 100644 genindex.html create mode 100644 gettingstarted.html create mode 100644 gitwash/configure_git.html create mode 100644 gitwash/development_workflow.html create mode 100644 gitwash/following_latest.html create mode 100644 gitwash/forking_hell.html create mode 100644 gitwash/git_development.html create mode 100644 gitwash/git_install.html create mode 100644 gitwash/git_intro.html create mode 100644 gitwash/git_resources.html create mode 100644 gitwash/index.html create mode 100644 gitwash/maintainer_workflow.html create mode 100644 gitwash/patching.html create mode 100644 gitwash/set_up_fork.html create mode 100644 image_orientation.html create mode 100644 images_and_memory.html create mode 100644 index.html create mode 100644 installation.html create mode 100644 legal.html create mode 100644 manual.html create mode 100644 neuro_radio_conventions.html create mode 100644 nibabel_images.html create mode 100644 nifti_images.html create mode 100644 notebooks/index.html create mode 100644 objects.inv create mode 100644 old/ioimplementation.html create mode 100644 py-modindex.html create mode 100644 reference/index.html create mode 100644 reference/nibabel._compression.html create mode 100644 reference/nibabel.affines.html create mode 100644 reference/nibabel.analyze.html create mode 100644 reference/nibabel.arrayproxy.html create mode 100644 reference/nibabel.arraywriters.html create mode 100644 reference/nibabel.batteryrunners.html create mode 100644 reference/nibabel.benchmarks.html create mode 100644 reference/nibabel.brikhead.html create mode 100644 reference/nibabel.caret.html create mode 100644 reference/nibabel.casting.html create mode 100644 reference/nibabel.cifti2.html create mode 100644 reference/nibabel.cmdline.html create mode 100644 reference/nibabel.data.html create mode 100644 reference/nibabel.dataobj_images.html create mode 100644 reference/nibabel.deprecated.html create mode 100644 reference/nibabel.deprecator.html create mode 100644 reference/nibabel.dft.html create mode 100644 reference/nibabel.ecat.html create mode 100644 reference/nibabel.environment.html create mode 100644 reference/nibabel.eulerangles.html create mode 100644 reference/nibabel.filebasedimages.html create mode 100644 reference/nibabel.fileholders.html create mode 100644 reference/nibabel.filename_parser.html create mode 100644 reference/nibabel.fileslice.html create mode 100644 reference/nibabel.fileutils.html create mode 100644 reference/nibabel.freesurfer.html create mode 100644 reference/nibabel.funcs.html create mode 100644 reference/nibabel.gifti.html create mode 100644 reference/nibabel.html create mode 100644 reference/nibabel.imageclasses.html create mode 100644 reference/nibabel.imageglobals.html create mode 100644 reference/nibabel.imagestats.html create mode 100644 reference/nibabel.loadsave.html create mode 100644 reference/nibabel.minc1.html create mode 100644 reference/nibabel.minc2.html create mode 100644 reference/nibabel.mriutils.html create mode 100644 reference/nibabel.nicom.html create mode 100644 reference/nibabel.nifti1.html create mode 100644 reference/nibabel.nifti2.html create mode 100644 reference/nibabel.onetime.html create mode 100644 reference/nibabel.openers.html create mode 100644 reference/nibabel.optpkg.html create mode 100644 reference/nibabel.orientations.html create mode 100644 reference/nibabel.parrec.html create mode 100644 reference/nibabel.pointset.html create mode 100644 reference/nibabel.processing.html create mode 100644 reference/nibabel.pydicom_compat.html create mode 100644 reference/nibabel.quaternions.html create mode 100644 reference/nibabel.rstutils.html create mode 100644 reference/nibabel.spaces.html create mode 100644 reference/nibabel.spatialimages.html create mode 100644 reference/nibabel.spm2analyze.html create mode 100644 reference/nibabel.spm99analyze.html create mode 100644 reference/nibabel.streamlines.html create mode 100644 reference/nibabel.tmpdirs.html create mode 100644 reference/nibabel.tripwire.html create mode 100644 reference/nibabel.viewers.html create mode 100644 reference/nibabel.volumeutils.html create mode 100644 reference/nibabel.wrapstruct.html create mode 100644 reference/nibabel.xmlutils.html create mode 100644 search.html create mode 100644 searchindex.js create mode 100644 tutorials.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/_downloads/01d26ddfe66a9569b4cf79881141dece/cross_product_error.ipynb b/_downloads/01d26ddfe66a9569b4cf79881141dece/cross_product_error.ipynb new file mode 100644 index 0000000000..bcf8c23d36 --- /dev/null +++ b/_downloads/01d26ddfe66a9569b4cf79881141dece/cross_product_error.ipynb @@ -0,0 +1,154 @@ +{ + "metadata": { + "name": "cross_product_error" + }, + "nbformat": 3, + "nbformat_minor": 0, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The error in a cross product calculation with (3,) tuples" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "from sympy import Symbol, symarray, Matrix, matrices\n", + "u = Matrix(symarray('u', (3, 1)))\n", + "v = Matrix(symarray('v', (3, 1)))" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 1 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "c = u.cross(v)\n", + "c" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "pyout", + "prompt_number": 2, + "text": [ + "[u_1_0*v_2_0 - u_2_0*v_1_0, -u_0_0*v_2_0 + u_2_0*v_0_0, u_0_0*v_1_0 - u_1_0*v_0_0]" + ] + } + ], + "prompt_number": 2 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Assuming same error $\\delta$ for both vectors:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "d = Symbol('d')\n", + "e = matrices.ones((3,1)) * d" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 3 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Same calculation as above, with error" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "ue = u + e\n", + "ve = v + e\n", + "ce = ue.cross(ve)" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 4 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Calculate absolute error by subtracting true result from result with error" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "cce = ce - c\n", + "cce.simplify()\n", + "cce" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "pyout", + "prompt_number": 5, + "text": [ + "[d*(u_1_0 - u_2_0 - v_1_0 + v_2_0), d*(-u_0_0 + u_2_0 + v_0_0 - v_2_0), d*(u_0_0 - u_1_0 - v_0_0 + v_1_0)]" + ] + } + ], + "prompt_number": 5 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Floating point calculation error given by operations on elements:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "c" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "pyout", + "prompt_number": 6, + "text": [ + "[u_1_0*v_2_0 - u_2_0*v_1_0, -u_0_0*v_2_0 + u_2_0*v_0_0, u_0_0*v_1_0 - u_1_0*v_0_0]" + ] + } + ], + "prompt_number": 6 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Each element has two products and one subtraction; The input values are $\\le 1$. Calculation error per element then $3 \\epsilon / 2$" + ] + } + ], + "metadata": {} + } + ] +} diff --git a/_downloads/15ee5f982d34b67854edc69ebd5e3772/neuro_radio_conventions-2_01.hires.png b/_downloads/15ee5f982d34b67854edc69ebd5e3772/neuro_radio_conventions-2_01.hires.png new file mode 100644 index 0000000000000000000000000000000000000000..e7903b12312bd62ede85d01c0a3e4940880c0756 GIT binary patch literal 70273 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

WhIIupLYe9ZDkcIg0gXqaU1Ynz>lv($vuKcX_w0 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 YBhn->{N(nRTy_mbTYr0!*5Ql)4{2aY3jhEB literal 0 HcmV?d00001 diff --git a/_downloads/2174665309d4572bf9425c62abdb3e82/coordinate_systems-3_01.hires.png b/_downloads/2174665309d4572bf9425c62abdb3e82/coordinate_systems-3_01.hires.png new file mode 100644 index 0000000000000000000000000000000000000000..e7903b12312bd62ede85d01c0a3e4940880c0756 GIT binary patch literal 70273 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

WhIIupLYe9ZDkcIg0gXqaU1Ynz>lv($vuKcX_w0 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 YBhn->{N(nRTy_mbTYr0!*5Ql)4{2aY3jhEB literal 0 HcmV?d00001 diff --git a/_downloads/5b2b00af981a01f3cc5e81b34ccc8fdb/neuro_radio_conventions-2_00.png b/_downloads/5b2b00af981a01f3cc5e81b34ccc8fdb/neuro_radio_conventions-2_00.png new file mode 100644 index 0000000000000000000000000000000000000000..93a56cc54cfaff980ba0986586ac0283f034df04 GIT binary patch literal 45578 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≺48wcGA{D$UR3 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 XR$o}44D6pHAH-_U*Jh7)JO1!rZU;uw literal 0 HcmV?d00001 diff --git a/_downloads/6be0680a63be0340a581f954a2ec30b9/neuro_radio_conventions-2_01.png b/_downloads/6be0680a63be0340a581f954a2ec30b9/neuro_radio_conventions-2_01.png new file mode 100644 index 0000000000000000000000000000000000000000..e7ddf823b323ab17d14ac0a8b2de85ac31d71f8a GIT binary patch literal 58088 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 literal 0 HcmV?d00001 diff --git a/_downloads/79cc4a050731c618885fe142bc9dfcaf/neuro_radio_conventions-2_00.pdf b/_downloads/79cc4a050731c618885fe142bc9dfcaf/neuro_radio_conventions-2_00.pdf new file mode 100644 index 0000000000000000000000000000000000000000..25792dc54dc8d89c22853ed2253e16f8b3aa944a GIT binary patch literal 27362 zcmdSB1z23m(kKeS-7VPQ5`1tAF2N$f-*o*5Yg1m1U!-Zw+AHb?OXuB`w7e%3Px6@#x4M^ z?_b3|TqIRo3|&kC?B6da8oIccI@tj@z+VxWRV)lmEbYtzoImb5*&C~vx&X96+lonm zKr!`j0WeG3f<=`Z~vs8 ztf`&3iv@u7$Bq(~HXwWf%n~*rB8Zt9+nbnz!FG0WGBvbC^hhaIm$RScL~l4&KbR!x zr84Ih9b}bPrV#ub?nCmL1kt=f?yH?(~hbyWJtI zWLnw&C=Xq;N?yi8>t2>V)D|4NJLI=~symN~|%dXY1dBYG$D**4>Xq*0`?_oPjx+;*K^KD;jr{hP18u;*@ zlLPhcjO3_{*a5}miXK_%*^Fov#RBQKkla>M#vaOci$q+w&a>Fa!Nz7CBW~+yNjW4q z(ms@u50$3cVpO%Rv14Yd+<@;S5d(D!>;O#mXLlo0nSWdcHR#)+pv3{sp+=v`H8|=@IXw{)#=8<-D%4!y}JgjQ{!j5 zw{QiTVh_N&_J^YQp>^-I3Ru&yvT(5fRK@q|2z*f+p!@S08(2mCO(n4bIY4^o-{>O_ zC22bdR`|MgoLiyXGMfFQcUze^cOL_ln4zF1Cn@(^Bq#;jBll?4pZ9LD_Z{$Qu5=7N zSzKudM$DmaMYMz)a#8~#rx7MSNB|ycnh7T1^5H7VwL7}4u=@!ITk1&mZL*Bqt>dPrU~8$5?~2U@6NO63R}XhV zzQ(}B8)bL;mM$nRhm4!in=~X-bqKW-gZiZzrAKd?{C+lj{i*QSw+1g^Njqv2`f5c9 z`m`eU&alkOa0}|f{X3tuZw-yN5TbIbHUCOnw%={Y4>ius`tM05H&BPt3_yk+PNU<0 z@bykmDVBVyDI5hOvpn5}CeH>1yxZOpzt zxu#jwFzWM8)+K&@=5di(Q0Y@3t3Ou~=0gK|cPF%O-}1S4XQCr*)D4GIALdlB^haF_ zpsP3!I|oNyQ|LQc8xAL};o&j9Cnz?R9oaE_XTylR6)x=F`)%B_JgvKkeS(6t*nHQ)!6l69HYIg=TrR>x|%c{TmELe)f-AYcyOF@@6z8h zinu8s10FH(Lzv8Njw zaFQY9#tC@q%fbkoPg*Usg5%u9p@jF2Dto;U_Gad-x<9}bCJyq^nU!t3C^OmN1(A_- z9~B&|W=~p+44s!fqB@b93{)cKjdw3a-p+?Z%e*PEAUpnAYWIc7pk9Sn+{i@U zsmL<)sr;ED_E=3@12XzI8*x!O=cvzH`fYwd$3#hH`=oS+5SE4!D_3W1-b4D=eil<%U(TAM@G=;-Gp*4HoOp3)h8+= zV~PjNtmizzv**zq+0-x1oz$-x6apk$i@!=^`y?#tx%u`HcA7p$1(Mb$s14?H#vpf# za|-ZduuW2-^Rm>zx=xx+hcuEcR!}GpNW_m#V4jT9L-(pwEo}N?+P=SZzA8epy_&|7 zck|kkUd0Mtk1uLAUB-#&(0~+InT76LzO8YA#FMVECKNfjX!r{;1oJBPJ>1(@Lm>Tlg(gp?itz`6fgR_+6O5hb z-xEwgkuO4w40)R;fcb#(h{AzH;yt6;{z3^mp zU!Ama7(p!C7D=8P`HLd{?rh!-6S=`6ilnJAg_)#tB8O`IX%qRlE*Fyi^OVX#KOUUg zv*i#@IJxlYjh!H$?tQAAPg@>NZpj;asqdOL3ZgD~kf&Hhwgfq!F z+b9(AAx0#T37hB(HXpd>_=%FP%a*xabEh_?r`HgJHtf=WK;>r|B8p zGj*4^POhSKu3W%mB%&KkIFyNTAdqQ|saf7|$itAG(x+mhA@fB3B3m4ulowLi)m6Ombb?_j|8gAe!&v7DS(Y?^~myC^*< zS_Tt^gi4{lk7BhD!)UfEp*fR@* z=0NjmdRR3je$3r6O8P0?Y!2qLJ5+P($bx4h#;IpW##a>l{|Y7W4=x^%{U5jm;>t31 zVyy5pO)3sPQi}*OYDi?lK5hXaB{SQ5Tap zZqa&U3o1lGK2{}6H^KBCC!Gbv)7nt!*6brsJGU&G?5CR-L=Zq!7N_Q5DsAG%k$H&t z7rGnb;jeEV2`Om`U3Y(WYnf;5k#fLYgN0%1A&gnLu%#MHiAGq@eXOin57&0JRwIax8V~4~H#HB`DGlRYN z*%}K&YDAduq>$Tt!G2pMRf=!0xpyMK7QF+2D^{KqLLf$*0vXl!^$8RN)eLUWAK>|e z56S)yoSHwv6OXROgeS`Y*Z*K7-T{$3ttAc?qQ)GB<`3Kc!GC1q;Qj|^DN4o(8UQbL zmgY<0eZ9gT^Td?3=8h9((1g=1q2R{<2}K?z!#egemKQxo1143Q?mTLIgfQ6Rw23`W zH_9Kp=Tm7$6!%SO?!rwo_Jt&>DdJ?2 zGm*{LUfVW&8i}{Xd#Gn200kNq$&OvX)Bzk#_=~vrj~r5MPDf-|P@!)`uo727g|?A> zItNrvRxo##m)+KV4D6p_NKK)4N0H$Z`?{s-+%0{%Xt;9>~_{-4cEffiz+2tQd`3Jw0l@s_6 zNEyk82}Oo1>Ls5^aZUjxIAq2~$9ZONJZYocJf;EgtHbggpY{#e@C~Y>nuFOdhBi08 z-sH67z+8cL^;XMSwun`JQPW`==W=Ml>HG+(7>n2p)iXAmAOoEjXMQ(p#VK!Z@Iut# zoBp>ZqdA_pAwE65#P9=KDzg`yd|9=%J-0bsvqcjxAMHFfwA7U8L#R%zGZR9XRpFU_ zFYuTYk@xfuxc$XBcNCl4$X?(ryKB4quFz}&>S~ZChzV<>f)4q1Xo;{o+Bxm zj@dPqN>gQ?_j!Cf>a)OAI}=VSdU58MGODv-#KRXMYuIOVpW`b;*%K^yULpbM-w_gz z$#5n+&|}qR%(ek9QEXkH)PhLLwE@F91`|~Pr!F*nF! z-4a$()FKO=hO|2-D@SBDSv%woF|X37O#XpHfAIWRIsd_%nRp}*CdhArc5d*ck<#%! zE9(2$a(Pz>_eC;m^8q_iEv{UzC$@#)X1PRW?XdL*!;@&S7TjoJ#eCynK3XYRDdT9V zDiS}6WQ_{l#3WVv3gyL0%Z}EjDXq`lV&M+q*CCs*s@DozI~ zj8g{ydBz!0Hv@PMx5B^aQtQ!hR}~#2E`e%r!nzt5^5nTDpgQ|Ydv$ofP{3m8`~H9- zshMux;J(PvPtlA4USbR@tnK{mzWeVFNk}e=`g^3(H@4oI{896=u)QC%OQb?TWp$xZ@OI(}?pE~BJ^>e%ptp-Y)Z8u7lC$&D)<*v9zRx$hd zjAqCwYrGJCzua7Ac$lXots!31!sRVieUAT7r@VrEqdIV#j0Xpy&`3+Y#S%No2w?_O zUqwkJ*^}V*>S*tf@8vBdgY$FeKd|KwZYB^EcKY`bCXo9919Crx=spSM9w-bRzk3(j zcx7*m)qo?*Vz5ldtT`&vI8HT_+qR-jdPY?)GXG{bxnH^C47UP%h_O_12&0-25n2gL zKqHA6hkShKWP`WB;YqrWI(#)YVZEO;grC(p97!$^ptvs7S!cwi4CPBX>1^o;AL2wE z@+zl3ZGomZC-X!=GpTPOMkaTdSWbQevZJ>{Izw0bA|omBiCA>P_KR|nlfdR^enCmr z9`7B_5Zf#m>UEM_s{VFt-m>|g*$%&0sk2m8K6QQw&Xf7{zF6 zSM5E+iSpq?oJwv)S!g!Po6|}g91{I3ZF1M>$A0bf%(Kh2#ND}H>gKaT8(-x>vLgHe zn?HDDZ2u&T#;7Fi1SJe#H}vSl-z+gU4J%bn=Z83Qx(h z=txMa`Nj_IoAZa51rM3^LEN!ruYsPUR#k(Jw-a_koS&B#>VucB!b;cIFRr2V4YY&* zK*K+Hk!-C0D6Gtb3i3gA&Ol*h$}naRg)G{E+oplA5jBz)oxsXivZN#Bm;$m@6+zD= zrj***iGC~g_4rCgXYWr{^~}Z5%^_yNel3=XpCFU@Aw?%f3Y0|gNQTFARcOm*p#@)8 z+o8=FfAmSHB3lmu7|{|i2oDsBW8vBk(d2M6fvoX-!tPwRN^WO7z7H&<8aL6z#>7FK zfCBZ13l7`(dyYPQ1T1lK{)>pb&sf`9?4xX$V0yQS;WxU^v6g}Nl8rYk(jBKp_;3Tp`9~W zV>&szh*}srfgWa-HT*GVTK*}>EL4T1YrGPcTgVx@I9c8&L77-sz~={Gf+kr^xM)6gn=^%2u{#ji70>*6vGk+aDi}>25^IB zDG}(9q zNb|6PFahrX{=&!xjyQ=LI!KvXnp?O4SP+>tehxtt0A=DWjfL&ZZA`%uqT*s|s|Fs( z8G77f1YiZSv;Ce7|LGcP12|b&{&zIQ|8yN7=tQuCm<39#1Gs_Q08St$A`giBTp*sZ zad7~EJS_K(0|Y1dK6pNmll6NKPbUmy?oId%XCsOJU|3*6r~Ht;;odm?~)@c#Eq z0}~Jg1BkGQ;5|7&&)gH`Cvf2YUVgwkv4g*`fJp=f8;lyb2eo^?fVcbJ5II07-aiSZ z?_UEDfZvy317Qrl1BMC&`A;$U$*!M0h-HXB0l9~Yor@KW_C5GuIruN2f^oVRCXhgZ zpZc{57$_DN#QS?c7T^IXke>}K2;XG@EC>I!-P0N*7hswAt=-E5SSEh9ds+D*6JUAx zy@BDn{|;IMEE_)?7;{b*4iFDPu!3da4~>T##1pVwfUM~6?Wauq?7>6<@g4EL2akVi z_q_goA3Wz*1Iq=NtKj}uX82x#|I~G&fcr$TGFaE%r$0d>X#gA8%7aFV01zARM}`2l zAN4!N01!*>ubBea?)4}lNDH(5uuJz^obA50=7(YjX}SB^=79TnC1_PkkTiV1W&<`2 z_jheUatj_If>bvMf%|LrpfmD)gww9^77*1;=;nh+}zyE%*@o()WpQZ=g*(V#>PfQMuvul1_lQD`uci$db+y0IyySq z+S*!LTAG@g8X6kv>gsB0YO1TNKYsjJQBhG|US3*ST3lTG{{8#H!ovLg{M_8!?Ck8! z%*^!k^wiYUw{PDjB_$;!B*ewV#l*x!MMb@N^CmnzJTx>kBqSs#C@3Hxz|YUm$H(Wz zix*yAUeBIAb9Z-lb#--ic6M}hw70jnwY9ajwzjmiG&eUlH8nLhHa0Xg)YsS7)z#J3 z*4EV2R99Dj`t+%aii(nwl7fPQoSdADjEuCjw4|h@xVX5esHm{8@Z-mi`S|#_xVV5o zATu-bqeqWuXlN)XC`d_3iHV5`2?+@Z2=MUmaBy(2u&~h3&~%)@A0#9s1Ox;)I5-#> z7$_(xNJz-*>+8$Q%k%T|)6>(Vqoad^gT1}Iot>Snt*woXjkUG4rKP2>U%$@J&(F@z zPESuyPELOL@?~^%ba;4paB#4{zrVM)x4XN$v$M0cwY9mqxv{aazP`S;w)WGfPgPY_ zA3l62D=RB0DJd!{diU;KK|w)YUS3vKRz^lfT3T94N=kBaa$;g)e0+R#baZ57WJE+n zSXkKW*RO+vg98HteSLksy}e()eEIzOa}N&>H#avI7Z(Qy2Rl1E8yg!73kx$dGZPaN z0|Ns+Jw2WKe;OJZYHDh#s;Y{Lit_UEva+&LQc@BU5@KRvLPA1}+goAe+O)#KgeBKu=GvLks>;Q&Uq?Qj(LC0{{RL5)vXJqK6M3;^X6EV`F1t zVxpp=A|oT~*nvOr@bIv(u+Y%Z4<0;#fPkPw1bMe2mM+eUrcR>vwhs1oV0Y}#fku#D zdtbi?Dk-#ezCYxOPN4EZ<9o*(qyp}b3CO#=AGz9sJp22T^oP~Kdg4cBj{W;723`48 z61Y3}?Tqm$ai=3P3oVi=Hj;S9BR6+npO9h=fRW$pfMA5G;P5%0*K?_pbFVKGxc4V? z&4(_TUNvoBm!*^L@tQX}o0&BY=^pRg>jf`YhVqhvE;Gk)_XbUt;S=On^qFY9fNHl?}qkuk0S zInS2D7#7|QZ%yn%u71wohRvDOg1qj*P;F~do_XFYI~S+R33S{$P)(5Ym>$-sKRcP6 z)C_b_)1Ca?(0WeE`rc;eW?IivSAnJ{B|GgWmE-0wqxaql#@QviG4hf(@aO`GYd5Sm zQ8wjzPTja^rd+YU> za7ro*x5-G{*!I}_v6fK1I8Vp21|h`GZ)4igXj4t1IvhOocYO9ETw@2dG)^;(+<0bn zGVAZoG~3^Em_%w3&%I~S`LyUrrhJd;E|1iC*wr_cvE|YAF-hDPR5ikN=6;S#5><85 z^Gu&bs;8_eZMR@wY#4@?L<@bm=@(a*0;I<2y)F4DH9;6QOys2KxhtVgwAF1 zQEqH~Of|bzO6nXW?)Jju$o9@O>h`SHJU=oi@*d4;da2vb3k+iDbhCV{g;$KNEpF;8 zgM;LI>2~qlql=+JOKRuH3$5#}2rY|t2{L4SWA6(lA>p1I>=axsbn6LztZQOzouO=z zO>?^jtoDs#4Z%;P?5x%m+Us~4#g<1S_TDoPYcyWuC@4R_UM3r+uQdV-ce7iD($oDx zmxa2Z66}ZVVrls3&~obiPxzAW9QE+c;DtpFUX!uZd#+|BQ0+H=4V}A`PkYI+wVh**|(c})=}pa`{t-HT`+Q%tiKFmrtB)Y zx=mb3oxDmYOlsPur2FFj*s2Oc-Kq@30My|D1e2O+|pQ{_xt z<9iW^hg+Vh%T<=C{VtzBw&2^1uQTG z<3jm6+`M852@F5&7}^AJpf0j~J>(G$e8jk9CqZvNyYXR@YBN{5Al7s@;fvfXBb48o zx4#Vqrn;exQH;O?Q$=SJHsuRLD^=62*liSLcWE|OiZb&Y;^i2X?_6_^d@khXa3${f zMX*FvS6>xRdp_ets78C$Vy|TlMUH-2Z#9|klUu;iZZ1vGM6{@6i2qF;#x_%(OnMr7 zMP2z!Y2D#;*Pi|9W0pT@Dv0wT0(|MrD+^h75g;sG!ul)6M&}2cBZXu# z8B9VDg{66{mLcOmWK~W0QiJW`CiPuz4!J0q3-I}NufSg32MTv|y8piX+I4Jwv*cgOrs5o%_mlfF{ox6b#vGxY&TjFF|(YD({AU4awfRXQ2%g zIf*D}9^*72RCKkX2iv}Du--v=x96HM+c(k6je=AjFPb-!3h$}=O(wTxOu&o5Xi8UQ zLSP=X(Z4Pi7C$;Oh-%IeT6@u^wdCPi)BSerWVSez1Y9b7Zc!JK?w-~%f|VO>A#kUA zqO(?5p*s(xPg;_Xgu3zPldaVA%wDCF2)KJ`iY{?`&hC1b?0((MbZ6N8oDle4ukuUj zflIR&jeu}3wS8CqZZDNK4Se8NXv&x*A5Vh^CLkpW7T5QnV2S(XJfcUotIam#Mf0DWqaI^-F$DT2*|w z1D7AhQ(AMorI;Hx#J()d76g+{wxnVccvuAt-;DO|Fh;u{#zGsW#|ks`D4qGphmUH? z9SI8O%5(i;F~m-$&AEp}5G%YHg=gz=*`lgI^T2KN0RK`NP z2>S3Hpv64G(LxEKFf7DmI~j}-dNt%e)fJUBU7#7jc#T!OQO4J>t>RAUkOMRDo}x(7 z$YROm@87;8<)B{5nk|NHT!0XHTR%|DKBm_XpF_yN=2&KZPT-8pS*NqOsAkd4#>Ikm{EUIece<+~w_lQ(EG_W@NfMLr=p-<;S&q1BNT#PQFUBbu95SXaj58_!ZYnc2avS#YO&?>1( zDec(GRb2G`(y8OMO>iM_oxDhzoT2X>{FR;s`^TD4Qt}Sf_UZI%I3$tPsp0=M%Lq)*|VHm7MA!2xQIFG2517~e)@+1KrHMbn(l1WR?u%G_MLbbdx2(NtIJ0^P;fv0s-B zjP;zt69WfydC4N=P|6D=b_76P4fy0gjT~=b%_ebXF4o7&>7;=r1|WoJ=%_QeA0o>b zqnnpDv}TM&SM-HFjJH^{GL5s*;nyX<7)DYF8WvFyKaF!pLoL8SHLM(t(oM9oH;(t? z)Czhe6~6FT7>Q6rexcimbcVS0j{Ww^V)cjEM1Q1O@}Z~kNLeUgFt5*U0zL>m6^ED~=RG)vdtQuzteyxQd%< z{t5CjNY|$Qw?&kjB9(8g%d>T#%_-M?vEH0ud0FDUQp*H}>Vp=3-~z9hqbc7HT|LO?;J zWWA1)M$n*JM%C2DJLS;^thC=FaW!?g(`iv=GB^bpSjx>1ui|0<^%aWkKP?w2Whnh?nUo$NRm5aF$+k0jv%`)B zPvXUsm~aWYXBkoc65c)KoNP&V?Ce6i zWw*+dewtQ}5Q?=49g^Q8j*dK_b(Y6Il&c!K?wIpmWN2w3#RMzXjQr`fAr`GMw9IYM zDN7lA5(ZQ$@L2&{4J(X-bNIClGCtM_U4+yZ z7X^Loo@uBRi>H~IFmjvEm^?|~xIVDr=UQ-pq5C#iGxNjyh!__!ecDE-9L0pB4bm89+3hK>T{COe-8u>@|HZ4BOwE|| z^KP#Q>GN~pI>0l)TLS1d%p6~n^YV(y_RwwW^!$k9_OwvF#lJ^7^X>PRAe%?^fS$u_Ec zBVk{~33aq1kdo$R;OPe8HWglql!a<#;t}?Ui<~|F5K8S<1e{X0xJHVOiAvt{=GwVC z-`lnVml@rs-;arZrFi5m9F@7x*MH5r-M>SFLtH>^E+F_eczhod`_JQE+@NI6zmI#d z@cfK>{T}oJMZEs!aM%BLv9AB^fv*27%JnP6^((&hE4YP$f$`r3w{CB5e+9Sx7TNmm z!dn0TMzj9sP}Z+F)_)ho0!6U?=kOISF7EdT7CJim|ItCL@A2pV62wY zk@3y4jeW*i5lh``It#DJd3Vwn+R_!fh1Z@rd1ESOI%A} zxWcnBGHh(&wSnPc)9qHXwZE}CyiJR+^PGa?JsC$%;CST2(Plv0kccP83Hjyo;53?j z6kD7ahN+>4(Xx2Rium1l+0h12d$xUsAD$R&&}_sdip%>Zi zlntYexRO0feRv7Iv^=$OILwTpn-)``C(Nf3pe|}9g;Gcsj-B(l&^|*(WQaWFg1fc% z7(MkRW-2Kg0AtkP1BrPRz^?5Iu6d`Lg@uz5{(=!>r!9CUJ_}0ZEW0=pOYyWKD%gu$ z3-f4(PgG(VC`v<-Ri0-ImFc`xIGliy(-?C53Vt~9p)z`kfqPC5xBW$DRlv|E+TWefqnD2aEc zn*PAY;-3np`s+8vYhrOIK7p2-USe88i$?Dr>;T?8=IS)x|d|wjgv|NbGCR zCcq2@(wMJ&*2W}%ET3mFV)Hu6?-^F4%~|5G*N8A#!plz+E2zzGIucM{qx$2q7pw@X zSy4Z|xQpDt$2=dusBmCE5ZfrVkSzFt4LYXd?q}uz*@0k&l8i!h&Wv>#tfz*n{^vsB4r*2aC6zn%H`~!>?7s0o=S;XK0s2KVBO5K zAM)3*^-Qr&)us$TR`{{U!_i^D4V=$1W%~~CnSf}b36TR?;hRGOsc1R`Z8A|zvy4@9 z+?c&wN9JZz?XUC`DX1t7gyq94EdJK{Dk4*{$q1H~y+|9ATS$OnX`WsK_yd@BTU5q0 zG*;Bfk?-uMfC<6LiEF3-P$jMq^wO`{uLbE8SqY_{Yct^nYcAf*pyG6=B+@bLJtA}5 zn9&pMiNGQoLHZn?*)j%GB-797Z>WZQqOFs#p2JJEe`(X~7?ny3jf3OfUwH6}q3UX8 zSY7G6Jagn^3On&e@APK*hKe*v%6=J;S8{cOs56cb#kXmP4#Gh+F?tvb*TMW)q_Z6n ztsq+4U7>pxMVVA2$B|Ujv;gunx|63m1f{C)BMj!}`Ji3A4{8yFvS`xVDLL291<3X( zIX2*P!;ur^+io+Bb*;}_iX_q`TGaOnjTn=S34QlvSa*p|5VM)FHS0^~TY0o#5mQ%b zqJ4x5cB#r)Y3COkSMYC;^<2mZ$c;A#m=4AYdQOu0T;R>t{P}4gA3=vz3&IkI0fQTy`Y zk{HC>u2{yx(HMR2uHb;PmojY~Zfywl?ZSIz&j?*zjn--s>ma2upD|23T~4LEX+B6$ z8rO|uflUs8NtmNV3c3D`yr&MpEE6SbS9c^Ep{23(bEkrF=Y3VMZf*U zMpRbfa6EkW^$Fr{dME+|KWzs#5gw2JlBXsKydeK}*TyTv zN2x@8{cDt$EXT=sqTMN}KJnS{04IP|hwIm|pnMd^^LATVtY9r=`9%^{Wp7yV zqrpc;4}ILRZuq>qY}-E@_o91S%hZ~FgRu{*N8BZ8y_%aO2gXyNH?8`49!=jC( zR(A7wrsutk8{pRl3Fn8Xuj4G)z5Ld4))xVj8}5hbf@DhL=;iCXp;Q-&IVa}jArW5r zk(s3xZTO1{$Mp=A-U>P0kM9~Lz; z6M7x!5%yLRR|Ln?9v83g9mgA?9d-qtkuBAfLP7-EAKV*dkO#odE=2;{jNVMZlfr6* z88JbX9_@dD@!rF{c}~o>uR}wbelYRIw6L8mnvc1er>}BKU$lMUMwd)ppzeK+89$!m zaF!_+GKar{#@TbiPR6r*{@kD$A_{}Tju}da#=@i*l6PX1AJVAjeyZo5F+Y9TDBNd> zh)*E~CFT-(bs3HQ;pt&fSG0YWlzei0#N<+aVh^L<7pYKWU|OyjR!x!Oc@TP}#8H$G zsBMb4xG+GGCzdWPWpkG;I1D(KbCoQ4``&DR5;~HL{Y&;X6@tI+cVaCS1QB52=)#a! zIJ(R7AgxbFcI`v;_&@?<*6hydD5q0pVRj!WrTeEzN)8ME+?&J z?PBOegTjLdn}kVO#%RG;QlAE}xRdhcTy->mcr}=m@@mf`7-{ZA#UP0D$(+foAYIH1 z>9f0@e;^rv9g24;6w7?j6Gtl;zec+)9L*jgRUm&=_J1Ms`>e zM($z0=L~w-eT;(VRE=O7#|Hc6#aNkXa9P*PM7i5AyWm(@3G~ zLWs@!pvvl2U7FA`JHQP%sSNg1Pvtb0lNO0A% zzt7RNPMnITp!^`~E+1WY`1(UW;k}PmNQQzkS`j?E%hAr5C*FQk7+YtT$l?+mZDo(t z(37a++^Xixpck{GrYZ|uTT1XcB0$04Y1xwj{T%{-5b@qO=FDWmSz=K}EuR%5Jn6(Y zZ*awf@Me@7i^7TdK#W~e3~nOqlm6ik<^bZfy!%F`$Qr2DKgfssLO>AtBL4-)_cLRiGjgXu7Xe1xPSONIQOG{N}Sk<|>il`rY$jAC{T6unGU!5GmXhdfqsbKoU&OL6aIE z!OA#&O$Q0YjV=CCGe;cwCS*1fJ&~;0W|z?OjTQXE5o^l{c$t=RW`;Z&KgQi@e4y># zUAyB{>kzp>T2aFx+@col>BCi?5}OIwl%E0#qQ06&d}nR~Y@Ryy$p$7X9<8qVFX|ps35Q zs-k}_Df-u9qW`#(==UCoTmhW@o^=x-H6|JQ_Ee%1N?RX3Ds zo>=#hb_bHEjX3&t4`Reik4DJ{TVYOW3SE1*0O1HVYoAp9K;_SX?%P^3gs& zp%5wXHe!(E5{uV$L(FAoxONmHmtrJb)Lxhd?FO>Je#3s_I`dWbmxZmdy9pOnw}v^x z1R=y6@K3Ug)VFVeo4a>icw=5iV-y8ZJk}e?F0I3yE(60p7R$qCmFy=f&^aG13^&j# zxm{>^?Kaq5CP1;AHqp~eiI0uM@^rTg7+&~NKG;$|>?)CNW}|LS**G?=%xGC&L6mI< z`0K4tMeQXf%k{|zYl-JrU8rjtP6jje0q44JI8k~|6UmTo;@H!W#T|45Xxx*Qz(%MeQZI9Z1sHT&y?M;e&Q< zH>xt-0Ze>E#QY}KT%eUx$kxd5Sg15ut3C&XOfSfNU$b8%nN34D&+^4)y6DL|QGcu> zTX&K0!RQG~dpbp6_xjBFW-&Zcp6fDO0f}>8WIcB%?OZtxN~*F3%9t+K3K`y4o;26_ z;VqK6EegFf`p5@#;GZ=V<+>c=cV>t)pHsxi*Pqw3U%e)E<>2*{Vw<$a65&F-X%tIw zJgg9XBZ`L>C0u)WAxbK)@X!;7*D83kZ9frH>hPQ_S~cHyFuyIfxd?|ORga29m!hKL zaVYtL#dpYMg|*V&>2fu+x3xMm!-hbQaQL^lw91o?MzDs(H?9}Sr4x9POuKKuZDeIC zWGkRHVB9!tybZQb4}mZ=6kdkOSpW!L5y4+adDL#tW+EwR)}3yA&R*@g)V^O|88ASY zgQMoai)KNi7$y0!XY)9$ZU`>k)7P3+_lUSWOMi@XG5|h9$Sv!|2fWY#rdt`OJJV zfi5aY$WQ&P#Sj%v)Lfl~Qep`I91A_DR7l7Zqt;0(VgE{0LDCBqqmIwp?PRWz>%_Bi zVt5tay6fXYP%LCEVW8||!{dG)jH=FxufSS8e^v=`S#=2c3Bq2{+!0dI6+#eFPup zNJ{cO7L|pBHzg6ze-&O(R(APdVT?zPg5%rQ74)CduH|p}q*sPS=&OS?GUGNw)L{7w z`SXXZqv&!oc%(?m3hmfR@op@*eWH8kSSNFt`I&P;^WGZq6=b1wYZJI03EgyzFPm5ZBvGMiRvjVj4$ z!K%wzF~Hwt+K47oi?K5a-!$BqCJTc9nh#im?*vpMe~iofA}VxEU{RepL1sqqVO97A zjE|pF_}d;~0@aSbm7aNF#tuZT5=Z#&s(?=FMpW3z4;y#JYp7V%#AJ`ZLJYkx=Vjl6 z8;fr4sjfhN$YoPTh$3A<(NA(2vy02Y!zm%u0Af8SeTZZalq?T#>!yKfI5IXRFA6Dw zSJ@HMA0VE~$t-q9)r1ANSRW8p{!}_#QYb^&PpjvMIBl7#xenmz{9cCXsmMi3%JgG< zEAOnw@E<|Hel+_n&(;cx1g?z;@*OEu^v1!#il|{A5bhE>_$JX5zjQ^Xz>e(8CUF|C zm}FyEf~5};lA$*CSi=ylueAyU4J=qAVM|pY7V_AX@K9#T8|_-n^4hRCRtm9gbfObKH1-ScXE7JEtx1<3|=` z^#RvRG4x_KVt^Kkud@2^7=gR)rJkv$i7MPDqUUefY2)*usg%+Ow}TeNrvXM^Kvot}@c`5u8}Xijj2%;Y)c zb2kjdY^m*O{!0Ke!=keyPD`pp$VZ$9s>mCk1eL#=39t-`!ETlY>x625TYk5>P}bNv z$`$K?wQI$KHk-l2Q;$`Jo zIc=>`X)=zL{q!_v6pxp$F@D891{v`7be60_=v+rI+D$)0I>c`(|x z&2_lVq~o_}e7GTbYm%z-zjPdB0~V)N|S?%?$XIX!>4l zm=)5I6pG2YeY{}XI$Gfh?uXAnC$(p+P}bvab$BrpY(Mb-v~}L`RDXXQS5^o~+3JdG zW!=jid=**UGC~sJW^;{e?;YKnT%((jk`+oWnOF86#m(N5kW^L?D)hUzqVJdA`R~5& z`F!r@{XXmcdE9fJ?|I#I$7n7;?!j}xNrdm^N1(15x(q1o$O8MDT$#y%2*37QwfXe5f`Enw2!hPiKmx1?xN=>0cTp08 z1!q(cHM5m0=ksmNFKL;9Sk|8bWxQ$QV-i_Rrt9ql%#`j>+kK9LuyENJb_5`ZebTVBIC$;wMU8RQP$r30mYul|p8=fKnFR6c z_(r$HUT>>J>Dc?3pmG&T4T?{bR;F}UuzsMgs(~GBx<{0c*Lw&Q6uqP2Cu#%H#EJ}Y z>W_l;MB?Jc#xS2Y?^d?JYxvoK5iDjL9(v##rsMClH+!kQ!>F$FBm0<3K;+vr?rZ%^5IVTp93Xxtb*Uh&@LYZ zc<^8^Bt$GqbajtL{=Rwg4Qp4NwuxzIxYtTu5CFwlE4%6xVP&K8gk$!kVwqf&P3Y#q zsth=K;ex4%GMiKZFUh92_!R}o{ zKBjcO@H-S>MGG#HhQewi0;CeZ6^@n8N6+2Yg9rDzI4lkx!%yD`^8sAQ_L|n6S}uVc zj#r%-&C`UQTOUjq{eJR6{kq(FLmOtLR)Rwp>O8^;3mE&`2>!@sp_>tsJ~fO>An!b0 z?*Tb~`mC~S+ozB^+~nxRHwcWyhV$`YX&J66mFr#^@Ku`oMxu)gwqK^?OU3Hf#N!I> z0*Q9MmgoD?sEMS1ZpA!qilJiFM@*%u?*wYa;X-%+>mC1~$+IcHq$B9=jvM<08 z1=pYZnedaL2|42|5W8oY9&&Ao%UX|P{-TcOxbtk?E1xag9t22aU z2dst#Who&nnym&UccRV1_?~|_QlIz6uZ+JlZ&+ z^%Uoxq(j$Yk>7(aG78^M8&bhFzK?+x88vE_uu5KmB#6XIzyBd7HZ+`6cZ5i#@V-WM zaNu_UMLH&wRG>@csx+mzg76%JX}Fi$!egEy`L6V0T-yeHOrExnspOrUHF>kG;+QC! zls)onfVJGju-1WH$+-ZRC?qOS_|K#aw7jU9#Lw&Uyg#*MAv-U2m?XSo0Xsec%~i85 z*y)yswj|RKuoAG z(crm32w|Df!q!hsOYh=4a<~8ZSW*ziD}Uh*oR$jjMExryw`IhazyIlBm^R)vG|Jl< zTK$B1^5^!@m!lk)(!)u!$*+>H!B)MWa_<>h}jds6wB);;^(DK};^RbZ%TTK`++@$Us68tRII@4bZa1G-V1 z_Sd6mQ)h`IXCnjJ8Y+0yTT$~-V1);hy0HcMEpNeQXK|V9EzOYkXiZcuqV(83?6Mvw5b~1+>*DsVCB8cokK&b^%eB|ZnMgFk=|;#FFW&PhoY@y zLsLOs8XV`!RzAQqz6q;cMJ(YIJ*dDQktN?B3kZ57LknKwuB{m_4n zIjR;g{p2~-`}mBcQxkESuivlHeGxrXQk6fcz6VF3ET|G?K*RSjZW5D!xr0hwbv*Ah<6wiNi9TT@KvP2zs_lD zbOF+AprK)2D?o`9fFUkP-NhG~eyYD|s#yWgW=1x=Sd6QDrP@vWTMs)lCOmq$yxJoArRasg&oSlEJ( zKDKzM;Xi9)QwtXo;`khZO?>Onc&79=Yg_kvwW;C^zp`C5p2^fCYDidfTdPxQcc!|& z_9|q#QXxd_Eyo%5E9zf(jm_-2aPRPFw(d;#=eol8pNA*&!NCvhFj z3C4?$0&YEiqBmm-^O|KSO}UHBDv*c^PfD_Q2&5Kc6#xifGW*(@Dqo%d+blRW@Tt58 zQU9^9b}79@B7H%!4wqy(5X1!B60SZWP}a{{qnP!?7^9)n7I~m`+vY3yhBojtv0_j< z-Tn>)1{)m)l+B5zjWJZ(md=(}1H!b?6KxYTI;ZZ@Z1L{cljYHquS!>qK4A%bcV=0( zJZ8(yls;ZYp&;49I7U$PJ<9RXt>a&4jILibiQ(4=XE)Qb+!;F*ViNg)p>9-S{K zYZ(klCvnrta?E?XE)!o&b9ayRP^*5@+Z`QQv49EdUX9o*)m5_xe25DmZcHDoldDOK zp1!EjpjL4Oe@0xD6xX#sU0Ig)1Dl%L7tkSgY*|&AO_J+?=_Ll1zV%_@s%W3= zbD2q`iT0?lfP=(~W6kD5EapB^(lp#3o!%WpKb z!b@e5wa_fEg184?Pma*su}DOy<}Mby9V&W<*iWU%(=49u%Whpdnm%?-o;SmM-DFPR zCn~IiL-iB!K^2Rcp3TVj*!}@|kMs*k&x!o-u>OOw#6h0c^pY!N0=*KjseJI}xY?Ag z=aNHUMM&n??48(T=I0wumI^a&U`Isv+Nq71@_ssVI-O>5N=z$Lnl9hCUO0{0Blk^f_RX1D{Bkj-Vnly&QXuI9AEz#irQ~T7=8O^t8_H^7 z&J8!9*o(<%BkaDb0EHwT+L(1xkACSbxo8NHRg(lsUXJo+;IyB2kr@KN>*~P8^gQ@gKAX)To=QC5C`}jwB+Hl>x1Dg6>NyAYz-wfJGigKB zLG_pGdI>6x&1UVAXcYfD(uk5r8Zx%B!f1(aU zz}Mfa6#hvRSeF$uupynE)s`Gpx8EGd)uql%P0?a@E4TgN1VOll}=}P1b&K3pf6pF!LzbJu+Fsjo!Bt|vEU?;^Od%rcdoE#yWc?uFH11+ zqv~5=INbCRJ$w!R+7Nx?QHCQrvwTpT-`h8D|U7n4|_D`Ymq!>g6JLc z^v4`cH%eTaC1d+%cgD)0+@ROB0FlM0x0iT|gPd+*V#*tQ+XHyC#mZ{*jR@0pcFwBr z%Gke2s;=^%&WhAJ^frQ_&{=EnFn{rl7`dS;wikjyq&|#9P7}>EW=VzI8 z`OkqdKLj>9kzX=v{3ngR_Yq{sc~9*z119%Duq#PFFT^UP`P-|Fwm93{9`Dpg+)B`f zV?~--4~8zAON6H}b0eqEJ-l7$eZO?zr$i2)!QZa*)oYCrdAR~h1?M{q9hQu-Fh9fX zyE=Evk_TX|cHd#XHdnkFx`L?Vo4TRo#(Q;p($7yS03L3KYE#ou6>WhcUZ6<_ox2Dl zTOWo;%cF;^E{E>4tt_JBYmica|D!c-{l&KzCP?c>V4!Q%LE=hj=8f8_t%I)$BMVkA ze4If^hqI^i0Y4-&Msr4%tAm-$4kZuobl-=3?9-cfYS#YUHA`qd zD8=K_5B#64(mVgpK|#>n1OgN)!hd&4|IYa$t%0-xD;3dU{5{>?x7$p?Y#Syl#9Ea7^5_q zD`f3uMb44(@2gy`Z2^`RR*vLf`Ev(y&0n`ixuDf3`D8@Z6u>fISr8aRKF=#dMqo(F z$cf0vh=~1*nBePfW6Ma+>H=dV9~u8s$dnfd87yH7*wrXFAW8wC|7c(`T!ZYV|7bGu za%4KoUJXKV&7OKtN?ISe_W2nM+uugAGW*(`>}Cp1gi`+6D+?hba`$R*GFfJiCMQEd zl~BsxYssjB{q-R7``Uv{yxC_j*)99(LBRX_9~oA(&-V~GnOL;vS)l*N_fQJiXm35} z{^x_j$;hoe^AIzBVUoWYo~^wVv)4C?^~DU%99* xqx{L(Ff#c|-^GP8@%+Y|plw~qM5$jNe(gE8aQFN*)WKx>4VV!KRKKLb_&;ufgcSe) literal 0 HcmV?d00001 diff --git a/_downloads/83473e2bf68165d7691882d14e07c1fe/ata_error.ipynb b/_downloads/83473e2bf68165d7691882d14e07c1fe/ata_error.ipynb new file mode 100644 index 0000000000..5a26ed0f98 --- /dev/null +++ b/_downloads/83473e2bf68165d7691882d14e07c1fe/ata_error.ipynb @@ -0,0 +1,251 @@ +{ + "metadata": { + "name": "ata_error" + }, + "nbformat": 3, + "nbformat_minor": 0, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have a square matrix $R$. We consider the error for $T = R'R$ where $R'$ is the transpose of $R$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The elements of $R$ are $r_{i,j}$, where $i = 1 \\dots N, j = 1 \\dots N$.\n", + "\n", + "$r_{i, *}$ is row $i$ of $R$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let $R$ be a rotation matrix. $T$ at infinite precision will be the identity matrix $I$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Assume the maximum error in the specification of values $r_{i, j}$ is constant, $\\delta$. That is, any floating point value $r_{i, j}$ represents an infinite precision value between $r_{i, j} \\pm \\delta$" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "from sympy import Symbol, symarray, Matrix, matrices, simplify, nsimplify\n", + "R = Matrix(symarray('r', (3,3)))\n", + "R" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "pyout", + "prompt_number": 1, + "text": [ + "[r_0_0, r_0_1, r_0_2]\n", + "[r_1_0, r_1_1, r_1_2]\n", + "[r_2_0, r_2_1, r_2_2]" + ] + } + ], + "prompt_number": 1 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "T = R.T * R\n", + "T" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "pyout", + "prompt_number": 2, + "text": [ + "[ r_0_0**2 + r_1_0**2 + r_2_0**2, r_0_0*r_0_1 + r_1_0*r_1_1 + r_2_0*r_2_1, r_0_0*r_0_2 + r_1_0*r_1_2 + r_2_0*r_2_2]\n", + "[r_0_0*r_0_1 + r_1_0*r_1_1 + r_2_0*r_2_1, r_0_1**2 + r_1_1**2 + r_2_1**2, r_0_1*r_0_2 + r_1_1*r_1_2 + r_2_1*r_2_2]\n", + "[r_0_0*r_0_2 + r_1_0*r_1_2 + r_2_0*r_2_2, r_0_1*r_0_2 + r_1_1*r_1_2 + r_2_1*r_2_2, r_0_2**2 + r_1_2**2 + r_2_2**2]" + ] + } + ], + "prompt_number": 2 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now the same result with error $\\delta$ added to each element" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "d = Symbol('d')\n", + "E = matrices.ones((3,3)) * d\n", + "RE = R + E\n", + "RE" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "pyout", + "prompt_number": 3, + "text": [ + "[d + r_0_0, d + r_0_1, d + r_0_2]\n", + "[d + r_1_0, d + r_1_1, d + r_1_2]\n", + "[d + r_2_0, d + r_2_1, d + r_2_2]" + ] + } + ], + "prompt_number": 3 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Calculate the result $T$ with error" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "TE = RE.T * RE\n", + "TE" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "pyout", + "prompt_number": 4, + "text": [ + "[ (d + r_0_0)**2 + (d + r_1_0)**2 + (d + r_2_0)**2, (d + r_0_0)*(d + r_0_1) + (d + r_1_0)*(d + r_1_1) + (d + r_2_0)*(d + r_2_1), (d + r_0_0)*(d + r_0_2) + (d + r_1_0)*(d + r_1_2) + (d + r_2_0)*(d + r_2_2)]\n", + "[(d + r_0_0)*(d + r_0_1) + (d + r_1_0)*(d + r_1_1) + (d + r_2_0)*(d + r_2_1), (d + r_0_1)**2 + (d + r_1_1)**2 + (d + r_2_1)**2, (d + r_0_1)*(d + r_0_2) + (d + r_1_1)*(d + r_1_2) + (d + r_2_1)*(d + r_2_2)]\n", + "[(d + r_0_0)*(d + r_0_2) + (d + r_1_0)*(d + r_1_2) + (d + r_2_0)*(d + r_2_2), (d + r_0_1)*(d + r_0_2) + (d + r_1_1)*(d + r_1_2) + (d + r_2_1)*(d + r_2_2), (d + r_0_2)**2 + (d + r_1_2)**2 + (d + r_2_2)**2]" + ] + } + ], + "prompt_number": 4 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Subtract the true result to get the absolute error" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "TTE = TE-T\n", + "TTE.simplify()\n", + "TTE" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "pyout", + "prompt_number": 5, + "text": [ + "[ d*(3*d + 2*r_0_0 + 2*r_1_0 + 2*r_2_0), d*(3*d + r_0_0 + r_0_1 + r_1_0 + r_1_1 + r_2_0 + r_2_1), d*(3*d + r_0_0 + r_0_2 + r_1_0 + r_1_2 + r_2_0 + r_2_2)]\n", + "[d*(3*d + r_0_0 + r_0_1 + r_1_0 + r_1_1 + r_2_0 + r_2_1), d*(3*d + 2*r_0_1 + 2*r_1_1 + 2*r_2_1), d*(3*d + r_0_1 + r_0_2 + r_1_1 + r_1_2 + r_2_1 + r_2_2)]\n", + "[d*(3*d + r_0_0 + r_0_2 + r_1_0 + r_1_2 + r_2_0 + r_2_2), d*(3*d + r_0_1 + r_0_2 + r_1_1 + r_1_2 + r_2_1 + r_2_2), d*(3*d + 2*r_0_2 + 2*r_1_2 + 2*r_2_2)]" + ] + } + ], + "prompt_number": 5 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "TTE[0,0], TTE[1,1], TTE[2,2]" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "pyout", + "prompt_number": 6, + "text": [ + "(d*(3*d + 2*r_0_0 + 2*r_1_0 + 2*r_2_0),\n", + " d*(3*d + 2*r_0_1 + 2*r_1_1 + 2*r_2_1),\n", + " d*(3*d + 2*r_0_2 + 2*r_1_2 + 2*r_2_2))" + ] + } + ], + "prompt_number": 6 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Assuming $\\delta$ is small ($\\delta^2$ is near zero) then the diagonal values $TTE_{k, k}$ are approximately $2\\delta \\Sigma_i r_{i, k}$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$\\Sigma_i r_{i, k}$ is the column sum for column $k$ of $R$. We know that the column $L^2$ norms of $R$ are each 1. We know $\\|x\\|_1 \\leq \\sqrt{n}\\|x\\|_2$ - https://en.wikipedia.org/wiki/Lp_space. Therefore the column sums must be $\\le \\sqrt{N}$. Therefore the maximum error for the diagonal of $T$ is $\\sqrt{N} 2\\delta$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More generally, the elements $k, m$ of $TTE$ are approximately $\\delta (\\Sigma_i{r_{i, k}} + \\Sigma_i{r_{i, m}})$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So the error for each of the elements of $TTE$ is also bounded by $\\sqrt{N} 2\\delta$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now consider the floating point calculation error. This depends on the floating point representation we use for the calculations. Let $\\epsilon = x-1$ where $x$ is the smallest number greater than 1 that is representable in our floating point format (see https://matthew-brett.github.io/pydagogue/floating_error.html). The largest error for a calculation resulting in a value near 1 is $\\frac{\\epsilon}{2}$. For the diagonal values, the calculation error will be the error for the $r_{i,*} r_{i, *}'$ dot product. This comprises $N$ scalar products with results each bounded by 1 ($r_{i, j} r_{i, j}$) followed by $N-1$ sums each bounded by 1. Maximum error is therefore $(2N-1) \\frac{\\epsilon}{2}$ = $\\frac{5}{2} \\epsilon$ where $N=3$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the off-diagonal values $T_{k, m}$, we have the $r_{k,*} r_{m, *}'$ dot product. Because $R$ is a rotation matrix, by definition this result must be zero.\n", + "\n", + "Because the column and row $L^2$ norms of $R$ are 1, the values in $R$ cannot be greater than 1. Therefore $r_{k,*} r_{m, *}'$ consists of the $N$ products with results each bounded by 1 ($r_{k, j} r_{m, j}$) followed by $N-2$ sums each bounded by 1 (the last of the sums must be approximately 0). Maximum error is therefore $(2N-2) \\frac{\\epsilon}{2}$ = $2\\epsilon$ where $N=3$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So, assuming an initial error of $\\delta$ per element, and $N=3$, the maximum error for diagonal elements is $\\sqrt{3} 2 \\delta + \\frac{5}{3} \\epsilon$. For the off-diagonal elements it is $\\sqrt{3} 2 \\delta + 2 \\epsilon$." + ] + } + ], + "metadata": {} + } + ] +} diff --git a/_downloads/9e0340951323f17d19212a1b25b97064/neuro_radio_conventions-2_00.hires.png b/_downloads/9e0340951323f17d19212a1b25b97064/neuro_radio_conventions-2_00.hires.png new file mode 100644 index 0000000000000000000000000000000000000000..e1398cd57d4bfdf3d2c88001c7334069f7be3311 GIT binary patch literal 54907 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 literal 0 HcmV?d00001 diff --git a/_downloads/a0359552c75a1df40c301397f03c7556/spm_dicom_orient.py b/_downloads/a0359552c75a1df40c301397f03c7556/spm_dicom_orient.py new file mode 100644 index 0000000000..12b3ee99b6 --- /dev/null +++ b/_downloads/a0359552c75a1df40c301397f03c7556/spm_dicom_orient.py @@ -0,0 +1,163 @@ +"""Symbolic versions of the DICOM orientation mathemeatics. + +Notes on the SPM orientation machinery. + +There are symbolic versions of the code in ``spm_dicom_convert``, +``write_volume`` subfunction, around line 509 in the version I have (SPM8, late +2009 vintage). +""" + +import numpy as np +import sympy +from sympy import Matrix, Symbol, eye, ones, symbols, zeros + + +# The code below is general (independent of SPMs code) +def numbered_matrix(nrows, ncols, symbol_prefix): + return Matrix(nrows, ncols, lambda i, j: Symbol(symbol_prefix + '_{%d%d}' % (i + 1, j + 1))) + + +def numbered_vector(nrows, symbol_prefix): + return Matrix(nrows, 1, lambda i, j: Symbol(symbol_prefix + '_{%d}' % (i + 1))) + + +# premultiplication matrix to go from 0 based to 1 based indexing +one_based = eye(4) +one_based[:3, 3] = (1, 1, 1) +# premult for swapping row and column indices +row_col_swap = eye(4) +row_col_swap[:, 0] = eye(4)[:, 1] +row_col_swap[:, 1] = eye(4)[:, 0] + +# various worming matrices +orient_pat = numbered_matrix(3, 2, 'F') +orient_cross = numbered_vector(3, 'n') +missing_r_col = numbered_vector(3, 'k') +pos_pat_0 = numbered_vector(3, 'T^1') +pos_pat_N = numbered_vector(3, 'T^N') +pixel_spacing = symbols((r'\Delta{r}', r'\Delta{c}')) +NZ = Symbol('N') +slice_spacing = Symbol(r'\Delta{s}') + +R3 = orient_pat * np.diag(pixel_spacing) +R = zeros(4, 2) +R[:3, :] = R3 + +# The following is specific to the SPM algorithm. +x1 = ones(4, 1) +y1 = ones(4, 1) +y1[:3, :] = pos_pat_0 + +to_inv = zeros(4, 4) +to_inv[:, 0] = x1 +to_inv[:, 1] = symbols('a b c d') +to_inv[0, 2] = 1 +to_inv[1, 3] = 1 +inv_lhs = zeros(4, 4) +inv_lhs[:, 0] = y1 +inv_lhs[:, 1] = symbols('e f g h') +inv_lhs[:, 2:] = R + + +def spm_full_matrix(x2, y2): + rhs = to_inv[:, :] + rhs[:, 1] = x2 + lhs = inv_lhs[:, :] + lhs[:, 1] = y2 + return lhs * rhs.inv() + + +# single slice case +orient = zeros(3, 3) +orient[:3, :2] = orient_pat +orient[:, 2] = orient_cross +x2_ss = Matrix((0, 0, 1, 0)) +y2_ss = zeros(4, 1) +y2_ss[:3, :] = orient * Matrix((0, 0, slice_spacing)) +A_ss = spm_full_matrix(x2_ss, y2_ss) + +# many slice case +x2_ms = Matrix((1, 1, NZ, 1)) +y2_ms = ones(4, 1) +y2_ms[:3, :] = pos_pat_N +A_ms = spm_full_matrix(x2_ms, y2_ms) + +# End of SPM algorithm + +# Rather simpler derivation from DICOM affine formulae - see +# dicom_orientation.rst + +# single slice case +single_aff = eye(4) +rot = orient +rot_scale = rot * np.diag(pixel_spacing[:] + (slice_spacing,)) +single_aff[:3, :3] = rot_scale +single_aff[:3, 3] = pos_pat_0 + +# For multi-slice case, we have the start and the end slice position +# patient. This gives us the third column of the affine, because, +# ``pat_pos_N = aff * [[0,0,ZN-1,1]].T +multi_aff = eye(4) +multi_aff[:3, :2] = R3 +trans_z_N = Matrix((0, 0, NZ - 1, 1)) +multi_aff[:3, 2] = missing_r_col +multi_aff[:3, 3] = pos_pat_0 +est_pos_pat_N = multi_aff * trans_z_N +eqns = tuple(est_pos_pat_N[:3, 0] - pos_pat_N) +solved = sympy.solve(eqns, tuple(missing_r_col)) +multi_aff_solved = multi_aff[:, :] +multi_aff_solved[:3, 2] = multi_aff_solved[:3, 2].subs(solved) + +# Check that SPM gave us the same result +A_ms_0based = A_ms * one_based +A_ms_0based.simplify() +A_ss_0based = A_ss * one_based +A_ss_0based.simplify() +assert single_aff == A_ss_0based +assert multi_aff_solved == A_ms_0based + +# Now, trying to work out Z from slice affines +A_i = single_aff +nz_trans = eye(4) +NZT = Symbol('d') +nz_trans[2, 3] = NZT +A_j = A_i * nz_trans +IPP_i = A_i[:3, 3] +IPP_j = A_j[:3, 3] + +# SPM does it with the inner product of the vectors +spm_z = IPP_j.T * orient_cross +spm_z.simplify() + +# We can also do it with a sum and division, but then we'd get undefined +# behavior when orient_cross sums to zero. +ipp_sum_div = sum(IPP_j) / sum(orient_cross) +ipp_sum_div = sympy.simplify(ipp_sum_div) + + +# Dump out the formulae here to latex for the RST docs +def my_latex(expr): + S = sympy.latex(expr) + return S[1:-1] + + +print('Latex stuff') +print(' R = ' + my_latex(to_inv)) +print(' ') +print(' L = ' + my_latex(inv_lhs)) +print() +print(' 0B = ' + my_latex(one_based)) +print() +print(' ' + my_latex(solved)) +print() +print(' A_{multi} = ' + my_latex(multi_aff_solved)) +print(' ') +print(' A_{single} = ' + my_latex(single_aff)) +print() +print(r' \left(\begin{smallmatrix}T^N\\1\end{smallmatrix}\right) = A ' + my_latex(trans_z_N)) +print() +print(' A_j = A_{single} ' + my_latex(nz_trans)) +print() +print(' T^j = ' + my_latex(IPP_j)) +print() +print(r' T^j \cdot \mathbf{c} = ' + my_latex(spm_z)) diff --git a/_downloads/a8f112aa4c254d4394f4e73b75e10047/coordinate_systems-2.pdf b/_downloads/a8f112aa4c254d4394f4e73b75e10047/coordinate_systems-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4d5aa32e9c2c90b6eb5ab89e2b8ea60f133daeba GIT binary patch literal 27362 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 literal 0 HcmV?d00001 diff --git a/_downloads/ae8bde362c4868fea3617fb37893ca61/neuro_radio_conventions-2_01.pdf b/_downloads/ae8bde362c4868fea3617fb37893ca61/neuro_radio_conventions-2_01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ef86954eafcdcfb31af41898127f9e0fd22b4d22 GIT binary patch literal 33286 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≺48wcGA{D$UR3 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 XR$o}44D6pHAH-_U*Jh7)JO1!rZU;uw literal 0 HcmV?d00001 diff --git a/_downloads/bb31c24d40cb6a247054fb507ce53e36/coordinate_systems-2.hires.png b/_downloads/bb31c24d40cb6a247054fb507ce53e36/coordinate_systems-2.hires.png new file mode 100644 index 0000000000000000000000000000000000000000..e1398cd57d4bfdf3d2c88001c7334069f7be3311 GIT binary patch literal 54907 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 literal 0 HcmV?d00001 diff --git a/_downloads/c16214e490de2a223655d30f4ba78f15/someones_anatomy.nii.gz b/_downloads/c16214e490de2a223655d30f4ba78f15/someones_anatomy.nii.gz new file mode 100644 index 0000000000000000000000000000000000000000..b7e917e3f891c74fd99cdf82ec579ee254a195d0 GIT binary patch literal 191449 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%0Akud2bRtMiG8 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 yfFK1CTB#C|4hp}AN2pv`6$9BxT>1WD9A?ZZH`8 zz6|qT)93yD{(Il!J$}dW{`Z|@s%d6Cp69-=`?}8ayw3ZHxUHi~b(-Zg0)e1XS5wwQ zAc)~5QOGGW_-Ewe-+K5*%H!5U4}BLK4{vifYlODBhpUr|hm*a7Yz(L4e)ePJb2udBoAEIFIC{6@o`kuP-jk`V> zOSS&5@(c{vk25p}D<@n$OBT~svJQp25IU^px0O%a5lQ2Id0K?j(&G0uE{&EoPJ`1N z=Fu!s(@MmB5zIvBYd4sSRcKYs!g9h>>mGQH>1G}t{g%QU9^H|3shwCEaDP(BKL5AZ zu(qmt(WuTP*nf4`H+%PsTnt+B^M4OXy*2p}CNuMY59GEvc}OVX(MtE68^QSRp-P*K zc=+$ZdgCGSf8Rus{y%<^FJL1v`*}OM(M%YDsM-GH(&`OKs!ppub#6@+ z)1yICDIuRmiVQ2!1y+Ti(f#fToc8`$C z-+8mC8Y)-o4l{zcVvpk)sKYaN>+we^#*gy!kU=x5K`k9tqB;VM?m8KgQvs7C7hK`j z$gfA}N+M>&@b&mry!%Ssp|h_`^_bWAR=$K3uTF+5oR$01kO(Gl)qg_2YL)lEgrT#u zGX{nAsvMiwKbBg^i+v0t<4 zuCVLAaioB2R#@ul>XPiU`z__W@ow``{r02cQUfC+kMW}w?^rg8&E1U7Ro`C!j7KiD zgXH1OJ!9Sz%SKfm9ljWui3I@x0m%sECf_5h=_)1JvjW-UM~@!$(BK+q2yaVyExmTf zAMMH@GIRr`88*^*A5kze>XK<91hPbRvgMZ%uCN4RWv8(6$Lp~&gab`JIhir#IxoBN zgOf0P|9(2g{j+`D47U*S`t|GoM&=jIQQYQRrdl<5G~v287a!FB-L8z4+j-3pp`1Yo zpq}yZEO%Jc|DrT#`$6zM6Ox9?;{$A_eu0iuZr>04?;|P36GHe6AsM0I{mx9k+Lb63 zPRw*`q>_AA6r$!}u*541kHg5s${)NJV~Nh#-uA?7X5(@H0%{ytL6~ic+6CJz-UJz8`n*l_N}#{7z}CRP)rY{mGLG^FFmEn66YYn8Kbs&6Et9 z!1UW9yhuW$4D@ktM9Hq29ZxSKWD$_3#MeQ;*VFo=|T#=FbW7{Q9`1ZwZ_%sckz&ba$#1UmmJou9?D~)T>^5k zw)F=^^@}xxAYsLr4d8wk$aB}@JL_?pyk|~#;M?g!f{#k@<(nTK)c)KqJ6x@ws9dSS z&fpP7=NBYvX0N&+>t-L-weBC*S z*B^PI9AT`ETgXF|dhEpASZyaHQ&DSo*9dE>N8z{~KeRoD-^xDLM>!HkPBnN-^#Lvl zvTpZ&34Xi&CtjOa7zXS%-wbXc`*^{6HCJzae76ooPD-p(Kany~zmZhpQHQOr>)g(I zD8Q3#DPNZEQa8LWgrBXK%{%mhe0sc!55kQ5uO{JxuaZsR%mszx=d0DO zQ^bhL18hnC^tN1IVDP62O~@zYC}ZzTtZjSj1=WIq8>J6lVK%LHS0$;(5B_|grope# zl$MqfwIhEmd#&Rz3KQGXM*$&6w!iJf5r`y>6ZLzM^)F7c`ylf4$W2O^x@{O_WMm%T z#>d8tJ)|>BcRyEE@#A}K%3i;I?HcHEDc-dfmTYJF>k8MYrnA|1N>I(|<6Atq{cOC{ zx9{Jl)_s0Ce_!WR*x-Cnvr_PMVZk1?J?AF%K<_PkHSc*mbFHO@VaiysN)(h;2Ig~oE;oay9A)m-}!WZRyVh=0qSJdhIh1PKzdqQ zQ|!@DY^D5nlakzFC;0{cYfV$a$LL^Otk2$5IC5oFYVYW{;MHKa_8w#u%V50K?ooM= zkcfgp>?WqSI>-yY@mz^x#!YH}IB^Vr;i&Jz6d?lEAchZz#>Q@y8@B4=w{)9*S$Ln- zuSdJISjNhQ=>{(9zaMmXf4`_=e=glP8!pvowZo?D6xlOL@0C&OU9*Jdl9Nyh9|WlE zj(J}=hAKoHyv`K-L?iF1L;1^;+9hjU?0CJ2?C@T1PY*HT{{8ziat9L)`lf``PD)7a zj6u8J!AuwS8cw>d*6vzZTc3zQzcDF6?*`*{*YhQ6$q{Rt3iwSQC?FBBflHRmlw|PS z+eoR8(hWWs(B1dX&(C*-%X{#6w;q>*r@w%kJh}daCIE31bOA!rwl}LaTmd&#;7JpF zj0ui`lx{A}e36x!^UP`EJD$IO%)0IMT{yafD+=B&S=&R$k|3^2NaW$xJ5~-Ik4&c9 zgO=I}Z=*9;19%UPgLv%_f;szFSdZSVA8NznGd z!7*=BFCN#6UUmtVA=ElcN!GW0c9Z(q2d|90FVZRsrZn4$Hxa;Ek;&Y?6N_@0+cgv5X6V09M=|o@5R5gGCxjFQ7@Hq|9}6QS-@T~| z$L5HJE2jGzgg7J`$IVG_X7|Dq?OEc_=H>03y|G(!yj^ng^XfI8MD>rw#nbz}!SeD4 zeX-MHt3eU~FXB6_)(Dw7#aC4~jDksUGN~khJE4OMJ}RxPjoz)n$muTBt_JN^BYWj` zC#{A2&%N#ABY-iH09~&M)81X;!-O?}xO6x|&Wr2CKz?6m^BL|m3B%*E@tXrxcvRg^ zxlf0t$y2}tfSdd5v#cGqyZ{KUFT!Ifr;7Q!_NT};xL zYKdUj8&EjXM>N#$OW?^iH#Z*|8MSnEQ4-4T6kO%3*v^>l30-R(Bpp0$4B8Bdr0We_ zabG{0z#kz(%!E%NdWQ@@Oa5Jxe4u~$g}_yO{`$=4gs;JLFr7btzBqt{BC_PQ}kIZg5gZ}1W!F5vgtvuCfARV16;{KsY{%wS#m3>KM$J`@O(S*>A! z0l{wuANSfGei0}Zd3d6siSU>{)x`gQ#(oGq>HiZ=`kybFoBzMC$p0Ch{~4bDa}DDE z|LB&^?I|aj@z1`TUwrD{Z2k3 zQpt_SeJbg$nJ8gOOiYBs^v>JLKLSyL@Y~PRqJNN39nZ{gJ#D-=y)OA>Sir54H90vs zuG(pAoIfJ~wvmyM`Q1Z!ZWut-Z8W2WL#pNJz0Sx`zDOI=i)n@< z1;}53!$1)RB0ssgf4gW9a2f!^CwhfkC~;=WU#q+EItB5avvC@E!canQ^F0TAI)Pf< z?Q^F zuKsqoW>n!y1m{LTRG;qO{62E41jV5ArX!>sjXcW6Uk`RZ7D(xobEnxi2>VZ#nlKZN zR=_L30U{#EfxKIl8JszNLIf8X83{u)G(N79r`Nc@iRoMLxc%wA2%Pn@7m?zR=8X-} zOYx_m!~*wvPcr7rl-qZz^dTh!0|Vcg(=SwVPlYP29Uj?Ec53A7+L@hm(Y%00i|qD@)~4ykezM8)!by-`p*_$07eWP9a|Ojj2QotyJUT^6{6hJX8W%krK&@clMLQZmC0y};aFZ`dgD|}w(iRyV)X1F%iNA;jKmGni-^4);FmFT&y z?rw8m-*bg`PY(KS0i2adZb1yw{9lQq$C{5zK^UR2ZEk#jz~*K=MqcwTNE}2 zg{|Bm*>j;MZAa3c4s|`+M&*J~*c3`(S8fQS=@t!3r`Ci9Mgpi0oEJ>s>-6+zDC}8_ zuT@nq0kXrhwpI?52_M<4&JCulB`M=b{*eE!@d2IgU|CH9CR>XqULy}8hb}@{7%mvt zn?>mhx5_9WP@s$W3e~!@9933IwV;u}IYep#jzD1X`CIx>>r4pH*q3=?IdPCRAjv>v z!nDIP;eA0guBC-EtT~7FJddD`j?T}(gwIRM%N&f6>XJ{9R_+-8vEGpEhPSvXQUIasMRmx66=RhuYYp>}t6fUXlEV9r97h+s+P z+*YHkM`4qM75UC2+$Q~8;&i*p_UXkETS?Z_3o!bLyHYXFBAJBV-Y+tL{Fo|Q<>m%E zMD6_t4@$p&eV&?n4n&K;B zLJXsk>$udTo_7ju~VcrJ6L7eHayX(J8w$aqg9lILGY=GC3}^v zzF;~LY4Blwb04wfzX>@6R_Ao)X0^w#g#hC-2!BadG6ak(jL4bDTcFRt7{N%vYX}rA zZEbTmH@!2@RdS!WRSHy|_N&nr^?LQchQ2}aW-fNa^Qd-WH5`s4no5w(A$x%;N=UsO zR$PDTD=Q;lO+-kT@SSnRe)_KAJLxK^Txp~tz<5)fhUUC0_U0xeQYxX&z-NPe2hZLQHJA7xjL`p`MEi5fbKvUpL>7;Lt zRmqj~T4IJZ4rK7}@^zTorm4?Xv)DFyTro&`qBFP^m^)ZFFsku~+Adjo3WKNXCxQ+1 zIgV^CESmCY5wx763m(55%HjFWDP9Ef`swUm-fV`**4z9^2!f7LZm3O9`Tg6sU)b$9 z$nB>?X=B@=hK1`CJcCKGQpFG(6-5O7que0F*1d!jB2hC%wTG=gc7$*St+%)FXm=tO zbhb&5NvVMLLD;O-?bgyrKnp|vK&vdDwL*5KD|_ILO70zqG&qczmlq>QKA;Lg!mjXH zzx3zNAJ=1?ugIF1m>5AafbnpJ>K$>odl7L4Ajq5*8C9K>%8T60LWsqb8(zk##Sc610YY7cNn^9=+xxD;ano z4n+cFRRlueXh0zvRe!wgv+QUZNfWg8?B9!%7XsEU2Nz#HG+ns1Rs5{+B2<+A1#yrY z-eJeu+Qm-6qgqdGuAO^4)3}7hrp93AiujUF3Z$G|RYUc9np#T|_=+0RJUMWFwTlKB( z5(qS8Sm+WdUwY#F{Ynzalq+*?pPJG|(@wENn{YyI)+I4@c^lUgm5FDU_7O1bUKQuhtNKpMJIWO#=LQIAS&4;g*DIAtb`tJx3^tpH0_`AiC zz1dVAFdZ;3!k{+|4->K|fF^>L!z5^=2uhZju%dKk+t!viAi8(jf}Qhvg|B=Tw8qgx zSWK4)7tv&`dzAez&iEIvPE&{9gm~nlCx?{PA|ZzS=M=2KT05m;Bc}wHZ}kRAtBM8B8BxcvpFPG3&j&een3w2 z*u3w*S9guW^KT1Mkv$W%$T?pMr3Vm${m&*pEX)rSA6RPv^07vOykWWbi*oMrbI?az zOz+mvKR0gseIzORD`XT14#Q@>pM#%Fi7M#(w(!Fq@N3B;l$A7of=(pN5>2RY4&|R= z&H+$Df&~rW4P?1oNG|TTo{ATv+5M}tWxS~uJXl-;v5(e4e!Y0+^wd=sUkU(&`2_{7 z&$fMJfj2ZPE-va{Lg-$%-E)!W>`62d40pO7d6z#F25D(&$qe8u0M&kNAy#TjXJ=}V zub^Tzn%$Q5ygpWVzi9eidW&YFK;rWRW>T!X9RD=tMIM!g=)g#?62?8;1g@e}k9 zj?WX?aqbyYak=D=PG)ehn~Dr^=Bzedaa4>Vv*+~0~S&f z8M#1u=Hy^V>KY`>eqWq8i^P7*WX4$KL6Z-DjNJ%8db!zXS#^S~1T*F5FJGRfJ6Dn8 z7Zi?o1J)x=TQp4%^l*cqGwElYC&--8oTw|n`I#_Ku~wtH0pyvR69G`m)H#X8VtsJy z?RNxItc^T^5%Q`r98~WiK>MWv-(~{`V8i9+1;o%~D|C=iiPZYilhP~gQ2e@g!p~$q zjSsykW8ZLiRQHO+;oeiyw8gMGl_M!&H-J-a@+8LZH;N&kc@m|4Jw0?{wS9W}5`af| zBjZ{FjwF*o(J1oeKb)q^pzG!E`Z{hYr|0i-YwN9nVK=4_pUJYAX2(mj`2x?~M*h{gD5CPqeR z9oHzHqQrhHck;*WAz`U6)a-x|cH&v1V$HP=L?CHhI#;$pfe=xaJzG4mVCLpV53<=0 zD^cKQdMF*2L}e}jtFSttiVr(!JY`7=xsv3as$lx?VF(J_T4Z|UfM{^fJ~U#L@uIwP z<;u|L=&M5{>&c>`A_(h>B{7hRO-B7!Ym4{InznH22!KYw7~Lu}y5eCSI)9JM%wz+a zcz>J$s$jHAUMWpPVmq3SzU>g5@oS@whwZ@5Snhg;s$o9rEGgIHE{Vy)r(6geWr9R9 zZHx*hkT6tfV}}0SvtMx~GL)k46mKVS&=Hs==&k?|yu7?1X#fq&djLsIrFtw3=;rU= zXMkqF3PilQU(~@O!_WPMpyboXWK1A zAb~8@U6+x$(rrFOQHR1th&CkfE#F(H;FlBeyD9z)APS&JKq+4u^{MCNpkl=9lRQEE zL7{*O8nI2yLo&J%ALd`16^AIJqijA)>G-*k(y}Q)PV+Y)89q9M5h=P5vd}cQkT3c1 zK?$CP(7{AbHJu<(Rqu&FiIoa8^=L5u=)d9z9YesRhiS9H+83|gp$u;ZI!R!6kR~Nr z8E@YIbf23j_RHbuC@VCpzHa6DHK!c_@B;t?$djD>7oU5Er_Sk;j;_96=xz~Az-(DR zGFY40V=tsFt-mfcRuSDDgut=WBfR+DExu7FCr4z*7ZOFC2f%d zMBL<0O4$1@i0x0$)tT%sDDCd;ZN_d_Szuz&lQA+Yaj%`qhFfmZ$UO%Z2VHuQB=*_; z%w+q^^$IJdrv;L7k!B<;e?s-SIq3X8Sepb2hEVTERbRiF{OJ?$O5>n$Q96FG4- zHqq*6dT2;6mfQkF3?27zTPyZE_jzx0VKx)a(^H4fMjiUq3T9pF9D=l-SD?^&fKba0 zu_=qN6X#C=AVg%0;O{{L{A+$7nJEH4oqnAfUA$oUt!XH)gQxkOAv{othdSaGFPeJxS-k z7}hpY|HH<#2{;yjn_Gyc0Au1i&SZu4+lj#U){nO@KOTKm5dr<3ODUaGd+X>+)r;LP z*LQ5nF01Qp&3LfB9vf9d*mc=|1_%XppNmOPaBkNQ-7E6um1d=UdUw@tVwO@XQRq4o zL=>QM7NtJJL;dePrP&G~!nDyb_ zAg`qWpDN+nam9-vT0GA@q@y7=oUT)}Bf0R;#@64zU-LYWH1!+I;58|E@bg$Q1r{nW zg2ip=5E8UKi?rMh)Fx;QLI#HykjN;%77y?G$hyr_GZ?Bn149R<^i|xZj_eBg*Tz{R zojkpb{VvlfTak}eJlBZha7+nFN;x46ygJai>MRTe4i}@zPDz%qX2^F2WE*bpkcf{c zw|oEcvnj9E(;296mdHS{ez4#T4f6O@PbDRvyUu$2f3NuQm8k1MDS@TE_$G`O9ACL4N?U(ru$(w^%7B?!8I8T1(!~xYvuWXR^;D9`HrX1~=TuCf4_z+=jmLWZQX{mfs*c zAUHs#2lfx;4gL!U($dm`b9v#nrF@SFMI0kb`twls zT4&4$xi(-lSFL=FgX&Ewp9IxObI^uh1$;8af0XufJ4rk*mYR}}sm=J4%IppI zuA^rTOf+df_dyYLI8GT>DQ7~W+10Hdsr@NaYQ>R)3r;t@f7<3_ zYqo2+Z_FS+i?e?m$jZ#T#gljggos*`cIcws`dCtuYb2O!QbJKUEnDTWKo9=8)1kz3 zb8{_{ZD^#A?BQAB=Be8blf$AZZPTe-8M;gXWS}k(WKN#M1f1%ve3KGOcX$0Cl-b-U zW-+|yBO{hwlM+nAZg?{X=#=lgNy^5xS0^Yr2eFY|RxP(ym zpVOvMzhJ*`JTjWDE?wcWeHeHrsv=pEMvB+tn4Yh84^GAY7N0ZG5 z01n@orr*C`{rD2qy(mBa+&Pt;Rjnjr3zxdku{mMWLBqsa_UTC=r$*~jZgH@4^~)8F zIa5>;5nLjq#6(gB8Sh@~D)okFs9jILRW#THz9I;dyjot(2JyaMc?uJD6!BpxDoI%i zkG_0KrK+VrF1*WM;jxe)tGa9rng}d!BkwU!fFK03gw;(9S=Z{o`s3w0_OojKSU$Jpk|FFhwJI`!!XVuhb5Nbpd7ZPzBSe&IP%0WED& zg1=uhE3F!GR=DQ+2Nh6sfmPGv3#y=T!0ju_7@0G$a51q1F_bOQaHA4krp`h`k&H0I znX};}@UH0D(ln5c6Dpduv(jnGl6$iigaWHmYc*n1DY84vLB?J1Fyykz{G2zEExOR= z6!C#Pr1D&Pf8ENvR@CeC>f}SamM2HuV)1HfiD^)eH_l@lPCk3`+fVfp9bl{n7PJxp z^iS^>g#vs7RS)w2x+L?!yPSO$!vORd4tDpSUB2?Veq5l!0Qz<_Bd@)a+}2k_LH4Wy z#OgJ$2&%@o4yM=GKP->Z6eVWeak=|cL^@~_hk zXZE2w@Y~P)tB-Ma2AisnEJ#NdMs`bEmD@GR;7tIR8LZo`-d+md991StGV8L5kr4*n zzPqW#WM5xtzg4()EfoAU>PsI{Sdg?qb$V!O%2WUv>{NcbGa*i`J~^U0St(+wc@SNJ zzdo?G$D;DG$xRcrc&tm{CpJ<&o)RQLUWb#I3(z=p|xdvX4}vBOLbz$yBcty zzO3n3&AH(K-5pY5`ovt-H{`vNPj{T!-K2D!iq1zUKmWDP>P;`sBA7MTMio6yfgN4& zoOP2Le&LbGF!{z*x}=$vq3w}pxP(o{rp!>_?TJ`lmpR+bO?7eccq=ES5L^t`AMxV@ zf6$L_xp}dwQUXd<M_+rlvJL4AVz*sGcfp~ui$s>PEix(iYoP*F!`+8p<$cbgIR`j2JX05mZM_9r+JYyGCF@Im9l%o#W1{G~~9BrRuw{H(Gds)Zq z`2ExF-|}O344TxYo%{~+E#Im`|55L(61w*%sW$80IS*lIBXYgFp054z)2BwvX2f5$ zvx(|uAhSccaZ~d+w;++gu%QKW!TPxuxz5w}t>X4@s#8!9JA9?^uEtFN;NU$dP_nqS zW&m3Kl&x5~`M)aDpc#Vp#*-j2tL@kSs%ySf__D_NU>z?(udC&E=66frJA;s5M#rvi>KFN&=bq(ZN-0X4EqH2!LIiZ-y#RF53?yU(zBh z4B61KljUpYuxn3z0}o8TvUXRButbBdIJxa-9VICwS>j{dr3!)uXyk7VLz~SZ0;u34e5uz zQPx=1OQbWQz&yVny(j$`*Nw?#cv#+EP+~94tafO@^V2x^Xd6Hrp>+VQ2R>zGXw6r; zW2|y_{c7E8WZmxo(gHDxB|0pwv-$bBsahIEC^3++86xDei;D~4>@D!nb%p%}uhY^J zZs)FidgE^8@iZ@p2dvGWltRrX0&24q{MhZA-pV=fYkoXKyhG)l+egbCauWZV{6#+U zkGsWa#e(k?6oRv~9^xvweGgmJW93GaH$(F3@rU*81R(`Fp#Z*oY7af}T}+4&r5ptG zin>2kkQH-3Bz8UF`bG4*u5ViZHA{;@hqKV7`qGDTxMtpNwL0u{UpAPBh?v&kB|BAb z-k)$kBpU3{e&k_IOHePBj)~%hM77@#P(#fr4GpgtOdl&^OjULU?`cleO zWbUBIC@A58zS=$V2keJ0E)0LJq`;y*XPe6m(wYx#Oh~guiln~wjf{@A{QUXyxv|;` z)JZ~iB6x}`HhW}dO?+NQt0O|5J=5Kqv-eX=yXYFT80EAn_jfJvlq+>YlwSPCet@X0 z_`-}Vr#g{fub4=!mYDirhGh+7f^}F1@skj)#(PEgmR454HTlD~RQWRsYYvI6M!y}Y zd;=^8qVf+MZ}Q$LkkxG}7%T_P5EK$@D|-DROSFdXJHfFTTYGNB&Lu$Y{fomHS8%(M z+=}g^QhJ+c1hj;k}NS_0C1)?^+fwpaDjbPcA7Mz^IGt2f>7F4fNeTstR3LUvD zf}@)9M!eCjOLPR!K<}EAvF2w|1X|NaVYnR<~RB!#M>3yGuRaenB7h z40%G0NeM6Jk}&QXlxxBklUX0vZjnt>nJcdv)oI10(5ze$?3l|WC!bG<4{-&8-T=zR z?>3m;4v(%f(6**MH?3}pT~3C4T{o_)v^uU)qJZwty2IdpGWj~_$}`R zAmfAf4yXb4e+<^l8-mZ{w4aDbX#{Bq{Wa^mHU|m^^SS+>NkX`O5C#L1s-GVV)W8Hw zpRh{j&&}#T6&h~Tq$34coSoZnQktI-6$wu(5MPl*)L&XEBQ|YE6`4)N#qus+b}uX7 zEh>wb1I~fV7ey#uH@BJkQq7z=kk-uuhG{DjbA=Pe203y!WAb#gMA0eX(Sxu2PpmE0yFfSO(izk3BboFc5$A`%k3 zdG=fg7>)>KV(6>9Q`Id2g9Ml64y)>7FGZ~cR0*OZUS~x<@a|=b8!gktg3LsvtAhSjrFp`UL3{26?e26)<`k!8S1s#^sm4Gu)8E z1A(xZVA>Wu{@!bA?~ZQE-uRrn(fyE(sZ=lmZPWey@>R5(el0!GuToLx`BAeUuP(2z zvpnQMZ~OJxi9_#AS$%S7p*u3`w2Y&*=(+VCD8)sT;j_=8q}(@uwZ9;a>(1Qxx`GV8 z)*yVM^Tu$)ts(|!PDAkm*hf#Iv+o6FAJ|f+D4(73IgYybv+`HH!pT0>3rUrj&E*Tb zKi4G^DSaQ$l`q!YTP+N`=1$R%yD^{mlj4V8a;ky!bAgGC?VSNM#l)POqD1 z*t5o{SX;_}fFU6I3Y9#QP-oQ-qXjz27_>vk4LjXot%LqwRz$837+j;~eSe+mzwPK5 zvYIO~x9yj=EF$pghpO@$=VCHr$&MWr@CBc$d(z zP2|-z`7;z&YR&#v6s#xh$QgXbDs-^Giy#?Hwp6Si&G}`FV!1Mms{OiMm#N7}?A25*>CV%h$rc(^TcNm1-)&3X zkVNyYISJjcFCH_Wu0da7y82i;BTpt$uhp^yF=vUaA3S7BOemB!Aru^Eng~5ZVP>%1 zsDg|I+=N-8Y-BhuvV%jbN18wPh0Lzizy7+>tVuS}*@?txEV z(NI8b%x<~{QN1Z%r1oTO-#n>M%sC1EKlsf$A~ji4mk^wHo?d)(oaNW*>PWDafb0ZK zRWyxaS``3AL|n7p{0)=n$|hD?KkI|rNg&fo*}Mt^I}jvH!!sOXQK}4rG368W!H8cS ziM({w;RGL+ly?(){l{n@(7)@d+Vo$Me;ylDrn>7maK0;vc$siNddqupsHl+C=rXUO z>4o|f_mJIAcaiza?o=X=9@(Zr7YNLl3p{FhcHrHCEt-ZkqU6HyY85g3@&a)e%c5TM za=T@&E-&Zk6`Fx=-J|j*{3k2joZ_#&^t_ydeTPfq&fo6{FoG5Uwox!+a2b@}=Bsdv zRAXch+`0qDM*6`rvtHWrPIZ5x5xz6jeXRrcny{w`D#rIQuk^bTuk#9}!+KRLStW|S z-A$0}_Ljx>POs#GTnb%q(C89`H1p^YFWP%aUHP>@UiordeD)zRG$b^ebvf%`r=~Qr z3%x!`2+W^9PlIS-wYaEP4^?Nj?st}r|zGs<)sm|wl?TqG6nWZw+s|r!Kjg(Us z*Yerm`>Q93r!VndHh)}vxwn6E)4fpGwGo*+R{<)3`B9Cj#uqLUt+*K*XbQP*c1z?! zs}@{KARH%Y+>$>ec;bMw5I%`y(nkN#PMm08Yc%Ke5Qzc%U+4^Sb8+{OuwM&69IJ4X z`x$`qYo8_#J|$=>xpg3OIL=4!j8x5S`V#tYe2kI*bj1L9ArYs*A&Qa+F2!b63N{rB zw;bm)%GM67gnutL#RrO8h71iAMj2)Gm zenb4=ERLt8yTS{E#6#8cRM-dD*OF2pmdLrURj$`$+bm*MJ!JTaC*7y;t{b<(BBz({ zf)tZcU|+ci(*y{l}c}$Mdr$;h7yE5tBvod%(sfhCs?ZGeh0-KHmGUVA3;M2)YpKC z-M|aZm9xpEZNIrV4h((1Oo5|#jZjE_{OIpbkTmYH{MA-9v8qW!oBTjuj>~>dzGc55 z8;j#lFy=o4E(`$DKy1M>^v4oZvlhMMuGL-6#Eu3eD@e(R3V!q4q7#}3*V{JjD@Fo+ zu$isDado}@Li@r%0fF(GmqeWqGqCmbH8`jT`?tChOSFnxKhrR0ePUEvS5jn1x@_$Q zcAl19(LZh7itT%9>=hMzGCNFW%m~*DU(5xa1{@u~k9--9a}rij@%kvXGyEx1C5->n zJqqV0&}+d7;ifbRq!CI6mnrZQGmxfW1Ko5v;Ngof$`W1vQcGNHHt_{|mluA`felQ6 z5rFWOnG-`2)86C0ykNVE+28k7C$+l#o|>xfl-?cls5H`oVJ8bu&wJBNAC-hHxBjlB zl|Bdxzn}m0r84&$XjeQG&^U*NQtfa;u8xcLm8`=@LcdLLSuuLl59%y@Q4XER2x}Exe1Xgil)}^k7t-*yN-TYHu-k? z=Bk(P>{NPPi+?MjwPq_loH&zk7K-pO=T#Ul9xl_Sd~hi)j7*ml(H0m?${~=syB7=6s&bPMX^MwJT!A5{nB;5e_)k`mWw>#kB{#P1#XkN%QvB_$%`77Idvc%03PP-B zd)mg}T(l3^joj&(NoFoTTN-L50f+kw)<;@54?Gg4>KGy5ANbNraC#}ci=TeDdHej& z;((Zd`&}&zIF=1 zcEXExP)=%3A{IYu(zx9#V$q**pGbYjvpkHtCr95=Z)O}!QC=(_2BSrwwT|yLhrrIIEXA0WCQl zS~eUjSjNeG#THFlKOr=GW$A+M%^RFK&>pGKNg4Ri3?8(oKxZ(7nw~-g7fZ03@XFmY zDdIu+-Qz=QrLO@{My>OJPb_x^woTdf%XEz)H>i1e>S5PqP?GqB&0f+y-X} zoC5&>MwRp=7jTe_V#ct}9)_8qVnF*N;Td>5k#P3`*n2UGY-h80MI%#`o+Ist7he)r z3XqSA9hhGjlA>ZoQA9IQy_RQqKGEUXTEDQKewHM^eOWSwYbamuGKU>B9nYLuu{0{E zx{E@xLMsQECTLV~u{Y`i1skvY1Aavt8uA!6yeq3mF^y?%qTar7*Ix{)&5PT-eT!il zcg;PYinqT$9rKB}qD@gZY}u#)Y_6pgpR)~cp+W&SSOyV?=?2ikgRz3W%o*vQXxws? z6mKf_K6jHs-|M15T-4UBIJY@r_!C8u9+gRXoiVaQ?he}<-rm<@qn17#McKb5XsI?|=SxPY)84i&dj5}v8i*m1V=lA^G zVhKHY1%7T>SM~D-J(bWEP`>kB8z?`*&Cs-9fX*I8d1C&M+e4lR;|z$SzCHB%o}ZX= zZ+F^ebhN|#HZm*GDgNR-k74+USlfDs=MlLFaa$>3JQ5p*kaQCM{$V*2+&0aFwNlm)&s=x-wrw(KD?M?D6# zCE@-X?>(1dn<`~s>k{E!9mN`CJ=`pTVTnHPY1?D0{csA2=AL{}SPcx@e3(5Yk^Q|G z^&im51482V$?11n?^KyZFw(G|%JQiP!9EV$qHs4D@URc^m_0$ws+Snbn@P>~zGS)g+&cZ$KN~Qd8Tg#)t0T)?nDw z-_bk1*CsJtT)ol+o3_nm_a>k1!KUOJU{-6qw<=3*vU=Rt^XmQg@89$M;2ttKhS7URbLS^1@VXjrPo)8yoHJ8x{6B3oNX21!HRlP;#_odFLdIBl$r$k`I-s`^(k z_4bo&?eQ&A$%hMje&FNAC|?Q~nlyP6+c4<(3i~YVrB(f)LqwAbv7!qqpzd$;U~j|+ z*7|I7`At?*Z52D&)cK#=zA*jJfr3sTm~A33Vje$#^#jHs1bd;EdB;?R+{<0FWWn^_ zEQNtj?fbhG6|x;-yJA7v_c@?<%eAo>N4~3(d9(Rw->^BJ7h$p*l)~q?^>Khl%*eoi zuvM(J3_ZmK8nc@sxmZE!`}UxnhDNTr77SO~>({gk-eCL%)dFO5%6H?6oa# z*O1YNxJnA38luTUj5H-#+X%i*!u=V5&w!O_-m6+N_*fQza15JFSVY7TLoawGz(!BF z55PWnEo)XhOPXaS_H|$@f=gUB9&RWk(vu}ef$$-eE?|-Yi~8A3gj+($FJy4s$aQ)@ z!s7ULPBMmh3|XoTMPjpHWVvcFXQ5TJFJheX-kBhph}V^=v7Mp6^78*Of9}7*pc2R=?;2)ixKYKvdXBkW#J)oRr@6im$YI z)3*ibySLmlICVU=ct7Y>zSVC=7Nn(X@ys5;t`(@dMhc0qiPZA?%kL7OdI)#-nm!V9 z)=}v;S&=S`zDH#AI!bf>B6;R3RZcB~gkPx#IHT?W&+AumuzHndJ{m~|$!{l$Bs87l z1WE?hZ#XMTQ+HK-NG`toWV7sC`#>e}Uo|`HC+TrIdSZDplNWWm-bp4K+LRf@Yo`9X z3!4xOw1gf`*B!1j!_9o6VXwJM3Z`66I6gG-^VS!N3eSU z7#a8o=@t^K^Ks2y^?otJUvJRFsE5f<1aUGgS32s3qKn&2KzBV1EUbBh>zxtLvgxob zjE<_io`xj zhxBfHtuI@^_}@o=dKp5*C1pGpUv+kvCFTHygKiu}Bbx}!t>9c*%-dPI?k6+AgoZ<)E4*;w@GvFPPEigarOX|EHC8W?6(%&zOk z{i1vJoF5bOnfov1l2O-4wXLRh>%=}iPd7-(R+1;)v1(z@1wJYowv(vcHf;w<)|Voi z`vKE*{y@V{g<7YAjS&=mg8#m14wjL+nguZfB4EGMwC&$L4-ViSFlm_Kz}>O%!AjKBd?*7r!C_(w@)rl5|BI#bj;H#6-}o^i zGK!ROC>(@rSy|az$tW4wGn=f863NQmdnGHY93d+@)-lpSl0BkiW#@OF&-eFlJw(p? z{d(Qwx}H~%8TVk7Tm+LG>~PGz9^4a|&%q{ytI$3$t;~xIF+_Bm(pG1)*0|H1W#p_G zHIpNg+P?0kXCi@A0T<=Ggva3(UFt8h37z2CaF?W9qOTJLfjA;0TBtK#OKedjZ=|aM zi_YI>@xlmH-=b9vN)f9Tw?MfnKJCj6T?n*9rXNR>m7_B=-w>WInU&zk z%1hO3Uu&(7+@HqTi_+-z1Trl#+?JUSv@DMN?IY<@wTYzeaR*W3uU{nZ1AQKM20%KPeiBjUM%+R=- z)qHp7^Zrj-aj&eym=b&Hg6+?XOVSAZ^%F?#V~cn6CPe&Oa{WhgS-=d+O)kXx`_(4^ z$cj7tbLAfqY!gABt8@lG;RJ>qf993F=>UP>Ab>xR6Zvw`4DciROa7TK0FLI3x$q&K zz%84oJ!N#K4KGqJ(>IwHla%CMEE~4h_a}Fg_Fli-X44hIa%p}W6#-i(1{%6gUP1SQHX~z?y9rvDc=_i1SVb08)Cm!7Jmie& zAhiAF`jHv`b3;EHR^bt27WrEG?#$%;@mP2oD`NV?Uq{KmNsX(kdY>$sje9x^hhIlm z8&X#*_0l^IzsaUL7!q8Qu@ar!IGZ+LyLg_XQZQrT)tErZrZ_EwHpkO#d0H(gQmMTc z>H*DmGK0qIHc#2e-lZ277?gvQ2~C|r@eLW`ijW=^GUY+^^MLEcBY_EP1y($e%x_8M z40elD-yjg=x-r4o;*~v9TFilfD+zJ+2L@9yUt1z=$4M=0cy?Vt;rs7YrZX{8iP2Bn z^PI22LUiOt^f?vR6)E1-9~k;_ux_Gc_47mBk?p4U)+c3=kEa>RFhmiX}p(~63U84wrn z&x4Z@pf7kgebgswy&H^_6UUfAblSvm1WO;7hrist9Hkt&89yshR&Bx`)vtR=v-=#f zexk^ob7JVDRmDpSQvb1LJ4TlvS%zRxd_ELBkB)NAtf_%Fc~QY6B*~1SoQrIZQ`?FP znZz}`Kl;`)e|ysF43T&TlrtW?VBdhj=G) z?gK@G7Ym^%<-|xhw^!|Pphkl+38;ENBP!e*K>)3Zo76vDOlFI+FV=rxWt%|FhyLj( zZtx`sXU!%<3y)3KlF)b1TCAO zP@J0*ow1IQ`is#{>(8_a^{*Qx4$;aums(S*QphTNk+PJ3+v+=iF#Mt=-Psaa9MxGG zP5j6Djk%^*2g0JBvs~mo->AM;!eDY*FccTX{c~nq2x=s%ES)jEYc>^zJ)g@w+@6(Kj7?M2`PkXo zf>#o5p(6&(3NM3jAw2G*QSqZ4HvEfSbks%ZphQG~_Xns;+;`Z-{rXxC0r=V!r zmC*}6nY9H^+k{k3CgXRDB9WggYbAwALo%K7Z@+T-(rp@0w?sdDZ$%#Kd5IrKb9Y=mPlFPih(;RFBI;kHRi9=X;HZna!W9+1|WA(#8PUY}i2CxJ$_Fjv| zrVpOU<--sgV88}Vr=2C>REAIFIyVSRf%nI?GQbNxVDO z>OQ(=r$;00Y@eROL?O=BO|yC-zGzkHri|?2>EXfJ23xvlagYL5gqfU>D(6E`%k*(s z|H|)#!wQVr zMah6#0ra;Kis*q<-_I92pTU&r#W_r)SdRX;YgRx)aF<_k02|w7Rw($Z&POr`k8HUE;-kHt7K~gQbZ+ec)zdX78+GnVJ_FqvaBaWuE>}(tDtW(UYuu4zkF}S_E)+|zB z1)VZ3w`Q`uybK%`z>ryY$n6X%!ZZnfY{bne9F- zToYMi+4~4a#h0keJ8vV3?U^Ts!b48K;zr>D0NcDm{#9Y77AmnN3+Yq?fUjk@4m(iv?Q*Te3|Fu6bEIe(wR)6)|q01B{u?~UmsS@i3zh7KEuTo`K_e2Zje zb_pX1XGQHd_2ZSum9M3?fx|mt4sZKusdtxYZLb0IRtR|*CLP!F41`3OczpbxF6>0UvcynoKYp6->eDsSmCK#&5@eth7HRFmGeyn2mV!PFEfWm!+ zSf3?0Fb$;D1$nE>0J16WeL;K`_A;P_2mgh$E{*PUExVO96P9gj+1_7TPm9Q5fvprj zGE1*b?4`#+c9!|&tlR0^I+y~n(p1P_Jt$s>T_}F-55roORI0?Fzp?X;G!6~tq8mKnSH`7*+M|DSbxM5yq=N0?{p)?642ECm9%Q7M@a~szBCz^ek42?kbB(1> z?Cjj{)37bGYMv533HoULTAYy*2qrHV%Ef&}7<2=s;I;Okkzhb`d))ddLa=Z4geO~P zZtn3Pe{X4n01I1_`+W^bm_|R3_QOEg%~tLW&sz?zDY=TeN~tp|T`EBWa+xFIm&Gx( zij-4=E8Ie~`7$dtv0}3NwDQ?+{|(4qW^|7AhvBiQ>~dOX{tghzeHJ1 zIG*;BB(>$z((*C^0!mH~53W5nnmPBEQ4BmYjjIP0nG6nNFFES^=h<%I?;PK^k4g5< z&s??0WR>Q5U~Eu1<_Nm)1m{B~)|ak^fp=*`?8pm;gA}PaS88~_*^4T`!k;IZrn>Vw z*{~kJjP=raFzOoFHi!|o5tJ`>k2{Mgt8fuKq)4vL&B{s|Nb7#qZ>Bkrfe>WS?g{n# zaVUjoyeAgVbGjV;O!}Rh#|NY@Omro zhgSQ3;#D#woHEOvRzizu5sK+Sz*0~oD zRfoX{h2A$~Z&2(B(m(%@kRfCYWz4j$TJsYaNNB$rfBf|55)Q4daqy(cSdCY=e{7aT zWibx>lFLZ%7tvLYr_C(CGf^3Vt;TdC!XFKzSCrCh8c=f4KN7=^02p&jM(}S=heog=4lybIHA4TTX4{*lX3#=BcXQPPTY@t;K>dpO+g^ zI4ttbF3dViB?^a85_#mzjrDv|+YhpM4Z5>9uDX9^y>Dsc%cCau9SL0r^WC?5cfL4; zrMu?>nTm`pbYZ*KS{RR*N>6VGz9ZB-ARqfOv9__$Q2X($!7Xk22FG@m>)?xAjWjkW zp3K{;2dE19!P~G`^UAe-f+WnGtySM$%ndia@D`1A5o@uOJaKJ9osES1t2@5viMu58 zMK;pWBSk6e4LzT0W%;%Eb^O;e7(C-0Tn3XQ{5?K&NZh*0De-{d3PX7ska z$|1pQ{uNE4#s6iNj0c54#jE#ymP*$wzbZvlWtD8?>AuCNH9-^N+%0`OZ2PGrSqryV zlBGh@!NJmLL%gVsCGFJtvR>)a11#*Gr2qYOJ-q}~9Z=j!|A3$M(m@~#h~4nhfA{$q zaSb*j+1$t3M%8g{Rfgrh>oq-pB6R~5c+}{>f`X@Ut?I+Vg1GGCnXR|PZm*`wf^B;% z{3{Opjyq+USg`-v@6Ed1OG1c6S=<+(4rayJxP~iAoWF)Wu^18yC#4Bhn!38~@WNT{M zBcGgBGI@Q5Sh|~pwTvOL6AfYPx(JYk!$>3R6VQo@g-9P%dn68-O#wj8t6;ucy;cx> z@?6%#--xJwK17dy)<=`sKYOG3eqV%#%mlgqXn<0;{EYQTe;6NF*0ZydtyL1WR(xeH zGauQ3<=wn{X^9hTuQ1UD>y2jjyh?|MdT+vUW_mk{7Ww$m=k(7P$)AI>9~G$ ziiJEW1Wz5fcEw?{Z?+`1O{+DO=Hlu)4;q8V-Y*wKtc8nGTzhUAUAE_VKGX8^b`&Q9 zNz2(j+z8`v*4LAt*M?qkrXMn}sN`PAaRAuK_^pV|G%o0wBo8+0)pQCPJOuaOfYVFyv7P#!%zY#Q~+)We9oZc1krd+b8|H4 zEQC6wFC_6q=ae>^wYp?wd|K|#t*Lz)Zk|Y-jhNWj19}AqMbYwg>`jXo{E3*nVS7;D zYkFKAW6aJ9+y6uPgV^?IjpxJm7BZ=qS4XK zTPx0kaU*JIUXe&_kbUN!dm<^7f1f$!pAYDKVXbywHcvLMEo8tVxMM(N)|D{-W)TNX zJ`W);s_{-lrv=FQnuN>LyXb|7yW%;Fp4yo z3@p7_{1z_6mrf9My8o^F2i$4^%|T1GcrZjC7f{uV|JS<`{8;;^OK`n)Vmnh`7oDM?`&M!vlu_ zriM4OCWqatq8?NYdT+@3`s$Xb#vs#O$+^1GYz?&dnq2=O?or5np8nge{HcjDX%^o> z_RK8#?bo{ny_HddYS8}wF*p-KtIBl%CJ-QbfeOz#<6LxNbayrr6B!`}9ImMvgtmpk zUI?W1gz(?eMgK<^?=ANp?k&q~_`wORK4|>R1x{vh=;q%B%R4aY<^wlrz{O zoZ}Y|f7N?aMRdXf9m?wzEPQv+FGRmWW^)e`tFa^$X&U-zXEeJXpY`bgJ&t9UpBw^Z zIM^*KI@xUW{dVMr6-6p}pTvzb5-WzPNWW`%!zlezfpjazxp7X$9U~8-LS6ln5BSV}hvb3`3 z*Qp0ld@gFh^_g(~Iu`M5e)Gj%Ws5-Xq;zWv4NZ%A+oKoWW)S3Z5SPcgxW~uG2bKo% zGX369ugOHhHJ&L{$7RNgJ+$r+Ez&akf&;-0GpQ^1U(nUiQoybe<5QZTV5nV4Do-<5 zkHWZHoFNv63*NtQB=h-TT%KcoCtn05^Jyt*S5}<0u-`N9P+a1ZH?(7mod1a-~c z**7U!ZRQ}6LSu67@z2H&pgSw9!lUC~T<#jW^FIo^mOYKcci)%0-$4Wk@@zehw)G8I z4{}`v96IX|l56mWOzO&aLmoOK6|_$DeA9>|iXzedAHnZ%d8y+9bt3gtL&BWb6hmD& zPak5<7pjFPB=Vp?@vwoAj%y-d-S&j<;QbfWRR9Z)0X_9 zZ8MHP6^w2QDryq@EPTod#4E%%%v?dMfVZg29RXTP1VqhE^bKOjB=-ipH!|L4)HXIt zWNz$*rIl;AgDI~nBDw7{mtJ$~dU1@?T*Irzm6{>5OEG1!^G-LyvCo+h(D5BQnVa&uKd$k2S=w8e5M z095!6jBBvba*ABm`eWuGAxc&hI&wf@%sN71&Z}ZO*wu*AiP4oMdZMyZXVG|vm(f;) z-z<*d8E#g9kt@NBlQC6;!|2;AOkZFwdQL9$D#1+PNY|MD`JNa$T9ei26~}WkGZUFd z7b8=1*kk8Se6;GyknYoNGArme%*1b8Z9heniT$~$ra!)>Onc9;M|vXgz!pM$%uSP` zzxjMH1=<6sCnnN>KZDA)*Ue1~z29Q}F6%RB|NcW|D)|#3QgN-0aMs;fCKc@S244n# zA`i$){s*`Hw*gBloXT*e(0!TBa)gSSX*Tk{N%QraKv%;nn=VOL19=q)Pu-R8r(c4T z@_)O<_yo*KX=y1iHx?*DeLnED5J(JW>!>y}ho5g0OlKIVnNLHIKIv^Z_DdU@FBK=+ zzW30Kx+m%-jm={kkxF|Q8C}WAq?b9rbU{$OGg@`aa|c-tscp>dsj?mZu=*d`)RmAVugpnA`c5FGMNreg0uiUlG=wMsiNMSb&^Qgkv+J-v+v!U zCS=1r`sMpl|Iahbnz-o>i;kqd2BBd+-kv*l_eN(tn#rcGP%F$WeTs<;(<)aqYBKk4 zX)23sl^ql}UBYM!&{NEvGv6nKs2RSW{dh0H0~hqCv2!74;;Ap(>T5KHly|d-!UmSN z)elg#wrEa20snOgYA?O2*kn(>Va+10&$x`~)v*v3E*im^y!BKxOUX++o~sn@tF6q= zwp~N7%rrAz#rCz&+*mpJ+-$3Tsh+JZ*E2hFR^e{s9QMWq!R*W0B;6NG28G@{Lq$(n z0igycjHXZSyzc$EePuu3$%fR#gJoqm{`7fIz8L^=h+LwQk47=g4jtiWL&>D3_UU_I z2z)*+xrXC=TSP4~Kwsot-$2}ED>&9wx5GOv$`-$#dwDK498jaPumKjuYuP1fO>&9F zfZGSka!A=QtHprw3lD9y_!1|*^#ZA{;Fr=+lk~(Dy?6=w|JC*7Oh41U1eVW^0Oa`Xjpqf>QI>dy{*qA8iD^Zx_)BE91}S; zcG~J$M{-zb1-LjlQGTzc(^#ySGg#Y4!R8eBsKUEB)v56IwaI@jXEBhtxl3$UfQSXDWT7%&c7kF^^WI%WUa@4r248E z{F=ay(75-CL>qgD^4I#GQ`7?~SzXw+cQ9dV=1@k8EJywR_t{&X4dh?Sp(qC10wL;0O^h#x$GSkj6Bb+M zz>vl8ZobwKJ$tA3%f=0>t-xGaYvsP==sqXI@_9p0i;U5HF+qYfA5x3x`AwU`K&)%@ zGzqZ1)Sb)Q7FJe@8eYEgByrX7aI!rX`r0j*R0UE?rGl@dF+*x}aJ^wKPm`Rk9)8zlx7ykDdxOR6W0Sw zO%q8f>7zFNr~LzWdtw@Da8^ZRAv!e0Jp&t~VTxR}895x{kF^o?n=?*m9k0TS_J<)b z?yz!l(j0t@lf0NA;rFoO(Gmj2PjRkRy_WPkNYpoF%IXm z12ON74^qum4MNGb?+Z%0W#x~Z95kp_Z*%VW&mU=Rm|}@!&0A6qWVd(yTeqKN6get~ z4)Meq5*_%{aJ)%H>eAfh6#nT+`>%mn=g)I*n0FS&ZPUzNs1rA;$B0lxP>MW$ zmc9-ByMNs1HtcxjHldkDb zWD9UT@M>_l_>6R;I!Va*B3rA%39k0ynd%^t^*zWyxKH0L<4x@YHfX$1sZ>WD^SUM-=HG2BsfFjwQ zrLHv?412&s;qQr}9EBspvL+4nwl+HB&An=zB0xEfTDRzM_i3ed=ZrfVyv5B)=^x{= z|9w6m`b@cyOFTx1i@L=&Cz=%L>?PWo^%lm)Vi?2nGhn+C<#YL5p@yJ}JsuOjX0Ca^ z4+iXl&K~WyGW}v=x}3bws?1&f_yR~Gk`Y-wbcvJzf?PFI=>&16^(fwn4q{zrN0YbW zQ*J~cUNbZ@DsEQ+F?bhacAF~pxk~O(_rMOP?-g6$nYR`+@vuU+=KU`*rEhIKG&=iJ znsRk!k^M%@7^75_S^3%d-**!UTQE)r?O~kMQwzHRu&p5m*e|QQ)TL@U-2jUW-<2@s zmY~MaQQlFGU@fWQ3*WwfPu?a4?FZo6IS!(?Gc>ZP%x~2z9|Lzf|0QCyn>Rk&z&DHbXSb1ro3xo_+O+8#xt*R3I3MOzj6jKp!O&`Wrs0djg; zUqaSb!f}IWQT}D}7P(vP8Jm!9n~KP%4v?8J~NS6z@CU!6xgiar&rp4#w3>B0f`kJt_ovFenccvQ%8NM zo{=zGP9<%=LfmuI*Ui(mkoDhiLVeJcn01M=l-yFQNsz5(f0SKy7o>mq&sXa}*8uML+yW*MSVk#M zK$OuNEOk2auE?PD1uGez@(TwFrfvB~I^TShs=OQ^&^=!-Ao=h<$@a)3z{Rbbw zv-HwOmVVnVVG9P1@L7Sbnhk^Z)~euv>L9zA6P$fnal1!OvK>$&Fl6l#kmR07WRmz( z??=c&yLPWb7zP-4`68qp;Q_&IFU_t)>cBEKSM}o$RanH)+ricWMu(76mRkVEI#9Y* z9js5_bF^Nax#g-M;*>)7>(?&}PfuF-dcgl%=8YGHVZ?Sy=$G;=)_gwvXA%RD9zMU! zU=ng6H@^cY5o${OU!a60?_FPddEX!A6ngE-x}Un%m#gMq*~Ye6JjI#?bGS1|(+p--I_hvl!H@@& zyQkgJ=1vZC)9IUii@qVR)Muz@MXRzpVIW-=3Bs$Y$Sskc2VCgY^HKk%)KE{M7PF49 z`UOc^N4Un?J1vIwrE-IHxb8p`myp%5xT8WjY*H``Td)g3CzDBi;% zAydo#Jr8O&?qb4j58LTF14PxGmGQ*EFJCuxJPGf>ggpi>IDR*^cPUw+@2^ ztwr{*{YB7&92!D=L3~Nb$w10PXHrC&4$K5VRDDa0MEol-Szx7douB{Z9dX)KuaXle z!9Yc@Chg0g26&VE>m{=`_d?K=$jhzWpss|urlV&=ZATz^+pon}&bK{m4W6SdR)g2* z|5_-zY8~U-#7oPdNM%z!(Oq zWMLIN@*NEpG2puVWr(fJk!vHs%y<)##ylOrrg7z6G1=Qe@gWOB9#RS`hm9Xux^1`o z0O!0f89V=C+Y5Xe5N-kJ16J6lW)8gUq=`}CD1D>PlYj3zWH8L(b56b87ymKG_1FY5 zR6&moc~MCR+9U294QrWnsyT=i?U#vo&;&_Yx}S4zd9o-FP<|kTXwLz;39dVYV zCkg1^_fuRCF5O2)XV(p1LKAv%|sV0$ss%Z3G@ydWVV(VL-wt&$%xY{pp~iR?YT^ z=xD8W!r4p(p?0tO62Z)qH5$u@<_s@CS<<*HjC&3Ws=j!0ek0YYJJ@sG`^b&w=6cC% z>P+Ee_0}I@WvG}BT)(td-oA2ZYv>fEGHwt&wNEIcBM&O2@)it^^fVL~C?G7tk&%V` zcIxo!M(KSY?=>VqURa4Sb-gI%@LVO;qr!z!>wdNe$2K8-sa-)YAj!-0X%t;-hks)2 z0$;``d4b3`rCG)7O8Lb!iLN7t)SXWO;39&Q3bwJ4`Gu#5tF_Vwq@2up2{+~gj;R9o|1SsVKK>frj0|4^jEp-7Kn zN%ga~33)$0{vaD(-p1S$BzQHkbtuy`AQ+Q4_;L1$eS!bItCDsN&tQn~KPwZ`ZonmQ zr`8jVgz5zVh0u!u0*WKBd-wAY`!WVVp`esWDyaPd=we0T^dwHpCO*mKP^zf3pB%Yz zWaI|OAn{~Hn)h0q?52ubTwJCH(#HNcr|-wixfc}eo8sfZehZR0pvU5~-_%e=^E|wK z<9#TAu7j@(4!w(+wwC`=F&EmZA3uA}y4gaiYT_^UUMK@VF7Y~#&INu=IfQG+-V5s(* zxSLtxgqCfV>J7%2u5#;KQkhe~p_hIiMWr*G?FsY9UKo;l1sa{^F#OT)yNA^!oLt)- zTJ);#BC0LL+;ql#WlE*f(2C5Bl%~Vhr}T&xg595lq6Ctec-DJH)-x zeoxY(eUhCQfL}#7ieDbcK%Z}%MYz>C@JnsC?95CALaGT{yc&4kfoqD-?tza6P9PZ6 z;@2ER&sMlWEdvUnRPk{DkRu_&N;CcCZyYF3@nIj(PpScMP9|HY&(fkIIuj+sMH2$5 z%yU>2LaT%PxdPPR3g8bP2pe*DNJxc`l8v6C>GRXS(P=Zqar|GS5@+cWM73|%_dFgS zVxiA%8N|$t*E-*2YIi5Iha#eO3@S>%TWPios|RF79Wt&YgC!%~mdPj)VgEF5xdRFZ z{NMu*E`ns7bgd@;{_Wk#I-DFXw^H2L1st-6{|+b)B#mc>f1YXaX-)BrT6>;Z|2MXb z9gBG5hDYJ3=pX4fjX{VEGoA|1*G}qb0I9Qj0>jqwf1WZxVIhRL|fK)#-cylAk z*gqU0opX{n4ju%2a{&Tfd_F)@+BGh*%RfK|3KKgxa6zH~7&9djIao+Jb-?u=KjKFz zEuP6r{*La<6w@X30qB3etax_vBx?XO5dWD#$_;!hiJu`q<$o-ZUsBfrnt-wMkz#fj zY**H%PHSk1-f*lo=VJZ&7Blv6W$JAs6fx{DorZCi23wv^+Ly?Hk_$^Jg+0&nSz^hy z71jLf#fxnG9*ysW+c4TOZ;Y9}=R}K27!M1!urfOiiG> zQU5`QT^_HUsO0Q+fs_aIc1H9Oo{Hi;g|%&hp$sXOjf%ANiR1Rq731P42~3{ND1F&7 zgsK~I)vlg@72_u%Es>hz?#`TBfK*omKeWxaUVh>Ml#LNN-pa$4N z@E;WVCz{nX0A6QV%}}d1b-ueY_9ayK6NKo1G~;`YqOgEf-A{Hz4EgVN6S=(M=F70vZGH?lM-ZWIG2 z?U>-bIM%nGY8gQ~c1HhJeJIh@qQpo?{kZ*gxW!@Euc6*A#}e1Kr1@M)?%c;88;<0K zEmBJ&0H;a+=s%clQQp}mvDlN;L>4QABgZl3S~M6ZuLt!`2a-%(NxN8qje6*P9>e;v zuUSX?jhD_~V_H!8m;wM28rs6N3~$za4E<--{cYe#tU7YWbID|AmYtcgNVr2uoq0)U zPp8H8l}Uz$E_3(X>Hqe~ZtQu{-+uYvRe@jw!Q%+74*zmOqlZ4^iMPCaM*_JLu(IBK z3a=8(a>30hwTh*lsa-%Co)sMCMN*y1A4-H;W)>p9xgoeA=@5c&&BS6ax2!1B=*%pk z!65;00NT$%SdB6pcDvnc{@_94y$21(%3w0X36@Mi78rcE(6!(lqHJkHa(G5^p~9sVDnOu$-Uf3B4t}a zEk4UxbaN&>r$YTzzxF-5;L&ThwLw3k4D#zywu#m>GX2BJ-4=J}{upMrTrxx(9Ve^b zmysY)V$+M|Ize{G(~4YzWw{p91WlKfV{u$|EN^DEEH#mo(kJ(?TQ|tE($AKbtB;?3 z$$Idc_B!7-qvtYB{B$N?47%1~T*r^>jaGJiHe3kQx@C7uuNHdB(eSKXI zgLWsscE!vSBm0>KgGIjdc9e7Gld zG4F%F`*!JiiAWN6;Rum6I!*^Mw>R{ei-s(|N+Nzj>~aWFtTS(B~YegjTBq@9O?_hrpdlrce5-YwB?5TPDtJ6zGeIDS`h_T*21*I&Wl zl455*N^?rWJSK)!XYUkBXzwGDFv8#v57AEUkI``5YJUiGn&HKGKrO-Mj+G9vz_7-y z*T7Y%D8KVc!biVGD}CDiucnS}mIQ00{$wXE^BNryk2y$ln{^V;r_~D79XK3AEn$s> zmUicEp7?#J5miG{>KmH-0_2fm&nGJq|Nhd&spM$iv z{{sMc;7g%R1>SXP7Y3s6kfs{gmlz{xUhx?)PzIKcx^p8;tnt_em&RF=XqBUg0r1d3 z88;7-pQ_I2{zy4Me?`28TsEi@U~1tEBEE!n%0NK-z=9NhOt1yQK*gh%zMKwbmBq0p zqSD;2w)T>XRAxekMdG7uUhMcE_}2+PbC-tb9Jx-W2ueNyP})L=S)|9!AeV59QJC3v zY-UMauN@n!#0L5=kLspR+~T~k)%U3!dMhXGJv}+xqgbI2uiXfWn8vSe&gdi2HX3<>RJNu7XzBU10pfT|S2hm3{p#K|Z_ zCLzy2ApY|9_q>cZt_%lOBMkBY0!ZeDas^KRv9{jpQ&&dAU-?9BKo+;wy?U^=ccfql z;bOPjI;rKZbM4#-9WGK0I7VLim%E*Vx@&$DM;q*7yC3%4QM+636ix-dQ=zga3;&2$$*%3SKZ zz6z08AUA>*4K{r>5IY~0K21ZNm%mxsgJ{fbcN@Nw(`Q>(TZ3m=jya+gC?KH%coGTC zMYL}k$J3t=1gLW+RyoaIiP$@7u8?1ql2rcB zmY&p1`GC|P@*{o+OCZ^x5JWvn5oh7lvKq|2V4N=`qf^Dqm+dsyBUEsxv>R{n*1b2% z;m_{l*uMN3?C#_nz~47ig7kR1S117SYTk!zA=)vD%E{K;bhXU#hU zgk`+4Y4hZCQ&A)7^J{390jv<&?ideKOU8Z)8$R+AA9u5O3a`}V>CM>32*khrxKnxv zg+GJ%Pkf1w^4=}eoxKUKZ|)zF8|B1QgK4&NbTLBaeI(q{X+_4B8sR5^ygW$vDYai|E?yp8v$=sER4<+*HKS~Fv z4(+1XkpV2R?O2FUvC2w{$g{*<2+zCALLE|M(M&`!XEDT-M8(0~GZJD_=hB0BROGkv z$wIm z(;dE|iW0Z{ZNs$f4^R$i(04TdHj`xg^}84L^lmQ6Y}=W3P6f!gC3`<~RF_f(Q59!)>yR3#)Gh?4!b@0&fw110Eej@g87<%{+7^uD}8upE?4E zGH3}?jg?jc&v3pKvI|*Az*UQT{Neyl4qO4Nlj;Q;9k)6H$A?Jbt;*;wnzj_k=*W;v zKI2LsMiV6cE4#Y7iA;?nKwcx&YFy+_L9#EIzcSfgXor$+^}1uYs25dinb?Xnckg;2 zUyO`qj1{ctL}OJ*Nwd>6!gC7SLQApXw~rNf2Ld^f0-WYf-fgH)V#I$a!``>@*(OK>Wf z9r;myIU!|U3mu26ELN(!csq_D^1|4e*6A*bYbwnGzi$0JT4)$<)8i0|3DIdC*|X{H zZb0=qQX*1gVyZM|Oauci*cTR%G5oO7Xe%MER44AqIsJ-_mlV!go0NCcSqqcN{!@I! z0m{=y)#w^00Rvj=f0c^7Qlbx2+G6{(CADs+3o4p7tI#mSR;RzH$gOU5`4^3;_jk#d z+1r}Py7^c~+GfyT5Mn%{K(tK-6DDE1o%XRf*Ho zvjv(ZkbHh~`9KK->E71L{NVTJpGRe=T(njoTG&B)5GM#alchUF-tKdLpGGyW-adGism-nA0Kz&w)!}j+# z&ixfFF)1%0?8FU^JHFB%`UZ>Bsvi#3*#~;D^AMTGhNPN@Ffw^C$^_te3R&1WtrM?$ z%6*{|_Gfkr8dV?Bxr8}e{XHDfO5pb6$=>YAMz9?IDFENj!GYWX*D3LTxnwEto6k_o z?q9`og|ISv(#6;X;)TxT(}_^c_m>ulzp#jK@VUr_eAuQ#tg31=Bz(kmYm3}w?p)xU z-99)EU^2*}#fdwuHHdaQ73sZ2qq)@`nz8KT$}E%JRN$`7RO1T$bJu01Sr$Jj)lWTI~bR_ip&XswJ3(Fs>_I-b$Q z2FE5k{AuXuIU2#bP8|=kHiBiR&JK%DWdS50x6c%aL=H|IM zsmD)X_z5$EPw|!`Gxqht{Acz^>P+-_jiYyAD+}AAiNbx;sgG#_N+X>zX}JDPSpDLU zeHbE{1QZw`a+L8t8cJ7RB6#06K}q!s@t1OQS$0pd`Q(>tkM41o?hKG2Ab_w70(wuA z<^zC8O?PF1v+wRF27WZXI3v%ly78~3hXrW(01Hn2 zn%y)@hA`rk6Bo*<^~SH#VZdHg0|OGcrBhWkHfo0LXXdY*Hh#Htw{_mO4xV6;8A$`> zdX91$3=NM8V{{fiznzlZgTsTk5sCnaQ|;p=4w zuG8kYRb2bV4>^`Js{(P$LH5?%fnhFBb&M1s`0>IsJZlFM=Mwr9 z3a!P6=S<*ik^qWJ*U!~o4tmDbxaaGR+<_27`>Y)S(ADP(?PHNN2v8V!X?(#>?7Uh< z4+mID#B_~;t}>Q5@|(pop69=j4od`oPMZxyEQUpW=M|imu)Ek0A~rvWOe`}Sv51Fc zCHRHm{c0~%3Tc+UpyY!|t78UfmftbN&Ul-z`ooMAk8wY`=yv-~hs-_fUCM0pw!8P# zlXe^KUU+y=q|;$@?=E%~8W|X|AuZG%lNU0aH=hDsT0`Bf6p7NGJIFTNU zyTz_mK-g%NYMYhDlr#8`tN!A^or&1@=-;)E=cG|2f*A4?iIFb!mJwzUy^!iJYY z1`?g92Bb}9-mv<6C}XT3o=o;nd%|A=*}M7HNE1v2XMQuo*0r}FV9zsd$dAISRu^z8Lpn&E!nE0HaJv^EI2VFD7RExlM(Dw(PF;-$od)tp8Rw*}^&BfAvEjX^$ zv^zL~$KZca*=FUKGSHYtaKX@^>{@jcaneghtJ5asn|psjuP(_k^?2v;=I+!{{b8TX z!T-cZL~00FnhC1Zx^_2@J0=$UG)0Gd(7LtlqzeLa2310~&Qt@@$C0`}m-yRmiBOng zb)OCX+W@hv-hBUt@PnKYz>=^^Z}?#oKON$ErkpntjmNtpqN+eC0fG|PT_@B76@&#G zEOYSICK5d#e;v+r57Z9NNs;vQw(n{ELxpN$G9$R}tevjK==2nLpNWX<)Q`6RjE6C` zvEVnXz2_15?ZDLMMsIlK@101v#{2*sh0T0sZtmkxGHCa^GWikZ;)dN~>hwD$y>E%s zFRH7TjX^Ju)G?e9KZRJ$d)ozfe4X z(e!S~Qhbvr$$9|zg&^Pr+=$owNNg(((@7K&`iEZ5AB-!Z@zb!uHY%x{NE0+t$VE0% z(b`+S-X^iX23cpYlmxw1SK8JxSi?agB9Asn`LViTJBIM&9?!j%C?I1YJO)e*BEk)m>P+9I9X2iW;i%?l3>Kl#$oM|pkzW~xg{)CoVpTvX za?n>FZPE?{a{AAJ9>0(guVy*dX*92}FIL#G?3 zCm-?u4H&#?J>d6$$8NiB=sGScze67SOqluCM0#YLya9q$du=4e%V_~4x*d`%}Pl7*G8;9?YZ|qs7&edUloeq zUmZxQEUNxOHiSIqlWZLq?Y?Mn_#-0>EYjDWhcSlqHLeDHnYZTbi@AFq=ncO!;j94O zPlvD(QPaXJY(~T)KoX2>hz$gu{8;jKJjfrUu$V!(>6(=F zXC$qd)#${D)R)&xsWroyztMS-g#XvxTX;pies7>d2}lYeDTq=^NOy^ZNQojPARW@( zB_%B&B_#r)(%ndhv`E8{64DJ)chC9$?muzYb+J6_oTD%^pEve?_7gL*>@3zk$y(s>#mZQ{=9iRR$X2m2sX{2JceEOE~KbO#(i^=m@|Yv{wY9+JuBQ6 zah>$gJ^^0~!!OW;;>s+PB=WTSABqSB&5H^E znC}m{(?CuF?D~_uAOBdvWgf051)J;J$+U@tN&uiuXgYJ>D{F!~0`h{v!Yq4PCj>d} zr@-9haLH4i)35+VBvh&>hDZc;b-mn`fnSFfT}SIPB>0ag91eO$H(uKNV!S^Qi|*lL zbZYd0bdPEhzn(lkB8Fi`hkxEqv50qfyJ^uENnB2W&x&88(=Ws3l*9)SX`YQMp5WH8 zOYXZ%4%$F)Ln`z(_V&IFpiC~y=MX; z88%R87uWs~-|)zXZwm$ohaNNW?gIh3PW3bPG~mJpUto~|_lg!x=CddK?ms^QM-P~- zWa@)C@<7RM0Tie4Am?Ew#D%Kog{s221LPQ|hIGB^{`@f^v|6u-V+Bh1UKYi1kUbp{ z3APEq(U5}dbmSs<_}ImDGeC(14)N_hm~-3<=Ti}5=-Af2;H(F_PUs4k_TG)}1j>;@ z(nLw9j0VPeBOK=6pFnHq{@G}e0S{v5s{bYl{&Av`@W`jJEYl)vke$18L#3zFPvm|? z!-0~8+7EET4kd4YUT04$_-Fy;W0cA9vvGs>n}DOW@soG%wjj}dTH}^qu{BZ{PbSvS z5UWPsYy6_4(79*c{@77-@VIB^ZZylX`;89^r}-A2oTWZdQVqK^*3S zu52Zl^?lQ*2oo|;H7y*S6Y|d+Ja@<%vWp*I+qwUk6aUO2;Cr0A5YZDoe{VSyYp{@{ z9h6-5f?waiS*^)Sqc3>7=I}C#eE(&2=k7(VL*Pqh5DWu$@9_nU822#!N^g+9DmT8q zVQc!~XU&>j>#y`5{r!AKHi`@TZlW9(;neix#r-F895rYhp z)VMEhjf`<|anWyz%aZ^bfI{0NwYGwZplfL<`-4*HFumi=gSWgUmT#YP8#!9t&En}_ zQ(Y&ayQtB?^SEd5A`Ucv&Yz}-=%3iDwwvP6Nwu;@`$GC)V*JsM{dq{fJIdwIwJpFrGp zYf;gL0qsuBpfX9T3k2-|a}xOAfWpH&+H)x+qj5(Efan>^O$K+R&XM~?kR$`ww?$;P z)$_N#F&(kAHxaw$T15j!&dHAo7kxni@IMwCD%8z>?N?5ZVNOKyZrh`d;I)@~6}2W@ zk=PCRdJic%cw9jDh1x99o$w`d6fT=}H)J=xy5?^-70kScb5#_KJ^_6d`|cXUome)< z^YKr{mX>(1t5KgRul(5Y--O;T)9!qq2(UX}dT!UN*laMo(RSg>qk6*O{xw{k*u4H= zUB0&bSgt6{fMS^E^ZeMg_k+~A3Fh)_PSsrzlDTJCE7Bz zJuR`e9a{P2z7^yOpkdQl^41=??*EI$cPn6yYv0CSL4QSY?x4g zD-r><6AYk1nE4THjW{el#Dnnt&5!eF7sCAnTXc#POaFifzOVtI!B1KW!S`4;Q>2P( zxnC(1KV_x*#nWupmTKNV3Z;t5!lPf%u{R|TnXIU!j%Wn!7chbO1hQP_j(E!A{F1Tc zL5~~ee1_9+hjdGOF*zH)LR$u`D26RFCS!}$@MIUqWK$t1=;UQ|SvY{@6RU?~~ydcHeEFLaqQkX&;ID#tzi z6EPI{j*1W3&dMHG3_8_PbFQ|1KWC4`z>f9gPQIDdzmw^r>~=>B2D_XTPHF6OyBn@m z#@jc8pFZ(ZG*VvZv^4V}zAboB^TlEH&_jkyzl@#MRgt@o_NEup7zqSCe=_*PfUrwO zZwey69%O9KDe{30J`1>BnqlN&YI?2da>24f`#J3`!VnWjV_QUD>irAIzpx;K1OvvI z6-b=6Ix;Sq#2Dpb6I(-bMZZB=r`Pq5>WL4F!SK{*5l^N7%~NktR=)?>)OS?xX1jJV z+~$}D-Uk4$_X!~4LSaVJfp?2?Z#(Z1dim~e1InkHY-QQ!MR`xl?e9^3YBqUgOvUZt z>=8E{yABe%5zr}jn+*kI$qm1$Xxlg9uhh~ri$=whB=!dIkhtMk=A z@l_U1Ho5H#iQy}LvF8of6k~I7k!@|5FhLEp;u%T~esB3aF@gI7E)7j+A7La!qokKH zJ@m-9`)%a8n6L8N{JbKHzvy$%AN9V!Ta^4JkAr=5U2&TrRl-Z+_3ZzAfPm^SCia)< z)qf8_e}P)S+NRdHLea@!BMK>@@Y~5%GF>Tq+Ipf89UrqdEPe+J>~W zpVOHhtz*yHK|%T4Xn@K!Ay-vskkN~#6Kp4sJNYu@aqR4#GiL~?%rFeWo{J?#nFd0R z1vn<5IJi(84Y>C^W@Fs3lRPL2G+Wrf0e{Mg?v;ILVI2P6#ue#&RTX%2di2Vd=d@S! zL_y;5h3^Zkr4v&!wy_tY8Spv2GA=m7ImZ9 z>2rd^F*t97$eGn5EWGE#na{Jx%Uk|1@Co?0&v#KON~~t;5B%| zpCahGmHJ`Ap5w23>#4~?vZx4v1OT$igR|hb`-1&G7IsjtixPgff&Q+=hyiobV$h+2 z$><;*H_i!|9zXdwX}U>N(%m{~Z+Ttwx@6c9RtceRk-kfx8v`~gD9K?*hU`lT1^x#- z^4a2gX`ZxpgS)D(N+yD_PeT?r5^49&(UvDji~UA;5I+!(*r`@vr(;1Q>8+F!;jzgh08Vaw8XVo z6u$Qk40a5vk)AjvOzhGs**<5+{u||3o9Jgccqdgh_3&^Ji4YL?C-;E{5!FfdgOH+5A%%K~bOCzQ808J#H^Mj6 z;#7H@WH1KWI)Hck=3!5^?4~?O>EZlao5&>ndor;oB^zSzf@!p__|a(Q2e87kh9pZg z+ZGlUOpcXfa~)lHPtC@|2gcQ~oRZ#e=2EVV8c>SSPQO0kiKB`Ax>oDEh4)W~NLW<( z^ktDs!$U&Id5CndUQfk|MV}EH#P{7fR-{;NG!&-Am)I3MuLmjz(Cc9FoPtHOcy&)_>rg6qhk8XAz!GPtLAT(6v$1y{f3qe)Ta0|Ehq|tAXNiCNXH6 zp7@!fF9_B+=#*xz`R|og8*tL27=h`{2L8s66{71`02YT%JcJfFA`+K^>HDcG`ZhL% zsHD9nh+}HO`ge}=01rRFF3a#seN-zXiODBifemt-=W=kb`fte9-Qx!`=iKobM0&VB znY~s(WzqUs!1lKG5Yin+OfVh;4}1o7#e1zU#vt3vYYXmZ@WzKJFlwKLc3K)K#s?lh zIZbt}gyE>t2{c}TB7*$T{lMTDRpWs+kW;9}w_ohl^50rJ$Ee#K6F0JkE>EfOTVc?H zA9AMD1nfI7(+`KXQNGKlQ^{jyBec0qelvNP>(fu^$2p;d8MPp!X17mlK`|;qQZk1Cx2oekG-T;Qj`hRENZJI-Vzyw;X21r3w-1 zoWTe3GkEQfv0dyxsBcBh*2 zsw*1LOPQvLDkN1WbD0)uJxFHx!!l#}%CnjGr|9kQ4v6hWj^M~pU)j@RQRUbPMm+x( z2*OnGW)GL{XfG1;*)%Y>-FQkXam9aS9*{}EAb{yz^pD5MDoR$;Q~02CZSB|lJ>gD1 zX<@dcP|bR|WhkMoK7kt#q^GZBiBZ}ls69y{{u)PhitpyDeVX~N&9SGZ1}x=cV%){1 z-SS2rAi8LlT;F?H$jC~_y$G7WaIKr^sb?x%dj>SbH<-Zv{FG_T9ST%O4cV&X`^ujm zqf4G9Ga5v!#XUhgbNr#hVFd6B)aj@$c>HhzTiEu|B4>ZpozrFEtltC0&tO7j7plCm zBxbSD|DN)gkx7EPq-=J(?g2(Qwi1bCXEQ^Qhj@~w|HQ6ZUNm@$e2@Wyl_;GM9jARx zv1mb!4k7Y-{U-kQYZK8R1-!7K~RZCd6zQ8fN1 z3~iFn_?JKPev0(h&iV*nOZ=AJg(ku zQRzQRl0+^@b{q%yIp~GHy~x$Mn5kLge!U1k*QNW*2X#8IE&x3_pljf*^rTM$G3LD* z=|j^EiDho9nIYM>o@EnlD_gLEkn~Lm;UC6G6yAZY&tJ!#B zkI6&;P*lINZBTWUYKvz)V_~=!(dJJ^;lci_Qkf~P6k90jo^fDsIpo9xPFHrPW7mB! zPFay5`A*52lkk&VlzSSAKzDoc+fY1~FwN&<>}4mrBK;_wm)vRh&}jlYo#c5&NN3za zuS}^Ifwl!hBlWx>*axtwyTt&91p_1yZ6qDsMOC5!4(#*b3xP;FKhgVSO5dp%AdZewTFsw zg#8A13f?`SXUy0vw$fd4!X$?xjCt>04G3s`Y0&1jJA%+U`0##lJ!V(=mB;vvdqPYe zM}(Pj{7kx-mvCAVuxy zeeE67JVTwAo<|=Kb3n((W0hoGvp?&><_yQRMHt%wMZ+(7JgkIVg~YX$eiObsm3yrL zX9OpSJa*ZY`!ZezeM*cjD+>4?Ou@Sv2$I%%QD&w*3HYRUPx6iaEln8Dk;t$9+4XcH zQLLLu2>oipy&1Zm#ZpmEC@CtL{@~ii!y~|+;rNT8IF#ZdkG(vOH-2{U(VokL{cwHk z&HX9G{-F!Z1GD6-l?8!}8&~{{e_PQrlI5dVG}a?S9Nz^;+jqg8>wc^DJaW!-<@hWI zi(8^>YV$K>!(m-VXqbxG*-6GI>x~#E1n;4y#&t8m)UVF}lJcvrzh+Lh8fdCu!m0QV z4`CPc#KRRe6AG0uDF1He{in_fTg4Vq98mY8Q^Q6BwrAg@wyrEe4maPh&o-P*dCJ){CDTJ zI7XvhhE6A6C$TnA9xg(RAgVX}23bn9MQdRX>Edp6kE0pR9dKA{$(dT`#_TSmhhqy$ zg24ByWjwlU8cEnOn8wWy|G=Pq=n?NX8Dkkl4u33w{dASzl99IFG=AvoRw${kV6f`8ZYw4ZBn#l&s9j*=x60|NGs^7mMSo z<4mNvKmq!lol+uyJ8VG*H%JOdy})q8wtGg>&LCk^J`K|SN8qwG3sH$7-LX|vsaUC;PD`?B}m)J6+CRzF34ex1)CcvG-Sb0(YT zh)=M?w3MO9e^%yKcWZ&BY*#~@6XrqsXUD=`K4p_QOtlc(a;c61EJB>GF8n8+Vgk+_ zXx$i(>89f*>VozY2cmP^_5K60NlENF%Y-I`l9S?}63MD?&djS&KVu(2!=}yaKlzfm z*dd+Oz1M1g*zhH>KgkIs4gU;u%f16^-1q=}DCRi)0C5PS_3u5d;dWvOkI@G|M=Jwh&u4O~RKp zY7vzS4{la4ynZPrHSl^?WSd%0kc-rB>B$adtmHsnU*^ag+!A9crk?wUW%H>fHVB>* zn5m));cnyiPjlu3qq>&a%)rp0@RCRkQ}a6&4kkl=yIJ%0aN6@zeE*(0D(;7V7cZSe ztaaI&YJN7qJ{C0kEi@$V``c9}n zKd}yicN9#%Ybj!#9ZO=!EN$bBvMDQ=xN2$S#x8%o8q6q|9azuoG<|U0G=bB%kd@!u zu866;WVxef*X;b6=ZP?~uv7KwweOcGOLT0KFHACOStoik=^vAig)tvbRQxwwG5{p&2a1(z~HV`Nw1aGOmI1$oDUy|+I{X(w)fcVRFLFXA~b6-HpZ2=A{&j*iSH1Q+` zc~b7tb~YR+C*iqCzrJM+jn7s}$*acb{b+-GHYXnYOU`S8_Z?MFlK;8yUont)yvWs% z!3rNxVIDxoPN$CKAkr|vcLyGdlpYOTfy2&OuO-h*k$y{BTcw45&r!##H-Tt0W8~4078N_IO9r4|ZAUwqI3zM0t zUTiY9%z_kUYEHc3Q`4_+_mjwE^VJ5^9=Wel$xFi|?eKvRWRF322xE{O;lR+(i)xRB zd3fg-ayG0#uM{tCWZW7D;O_r?H&$TLqFj=Ifz#MuYRHWa8a)68=+#a@VOD9s689q=4_G%Un}6zIh3 z?2lEx-;ha0Q*)@JjtFh^3b#p9J#EwtPvncx`IS{ij^1aJ27UuypktyT3^!Of1ph1m zzUj-^gpBTU8Ld+>p@EFhTf#I++H>Pv98ro?;(IjkGR`Y*$I^YK7g$Lx>0g{w0%qS- zFsKB1vr~|KlKPGt*{HH9Y8SZ$GBBXvf`vljk#O3rdtH&Kco0G} z4>WM@G(}t>?CM8D8Byd} z;o`{|he{t~Vx6d7dP=s6rbup-ys91PO|`(6!7K}vce8}Y=^RN@Kl#4nB$G7}Tp`tL zZnm@f>q}bj*|E4!Nxi~yj7hi9-P|Fut_PH0`(Bqfkh5M}W7(Uvj5W*0K98Pw)`VPP`78YwIxhyb^WLw_CQJsk8YD)~vnynsOm5I1(lz)E4F5dtPCmcRLKAQ~Et+!pZmzr$X^!x7YEzfFV1e`JNq?Z)#@9jAV3~WqR z-~q%9l~Xh1mArZL=9z}ZN#qwNp6`hK=VQ^s4{q#R3+A3r`B`*9fr+LSFk zn`WP#xku&Y<#&j2s(q*-T>;nyhtDz-ZFA>5(e#Z9k#3(NS@)KW&fHa$4+HvNE*e4?YizRZCs?Ib|T;GK=4gB4(ohJR#Aj{;4U)rNhWi4Y3Z+^ zAkFK1JUom2x0&y66FNJo!l6@_cDTVc27iU-gdp5GLyq$CZBaZYnothYtn zyd5AASgxgM8Cwv3-|&s4mso#UBojQhDGM`p zcc18^JFwz1^T%~QJUo;UVr&ckyJ5@vZ_U8aCx!rb_s}X(jpZh^#?xE*l@UYKU&dKf z+Jhwp<$iran~SBh;I!`t_4wDKA~`UeI{t8YbNqR0THrPoqS$mu%a!$6s#V9z_{>N( zXQ^m*VPU_P_xYZi(b4&5PRsa-LK^IXHCR7$gPD(&g@%R8lIKyGVQp>Fs^{YgsuL6q zO3${h@v_}^-_gTJ_pJ@F?tiNkyr+)g zwiu9t%Zy(1eqOA3S4}N{^LZ!kdpuzUN$WT&J&i_RYwLn_?Q8k$df>gr!SN;zUuex? zezBo*yt5{oCJMoo6n zO6o@5UP?-lo{a)NHl+QlZ;=}ek{s&!bQ!?(%6tZ#04ew#gp;0aSmL9f|?&V zlN6bBtvwVJddL>W)=$6Y=R3Izo+CYexGK(Bnwv|Sm@vX-1BSWX(T3KC`1s6%g1-0` zG`qKP<3WS#jOcSM8D3tHZvfVRp}YxVj(Q6hueG#7`}>tqQ&)*4KC0@SvP7)nO6Io& zhtF7eKD0P~>@(%!=U?tnfAuQd`|QX7?CKzzNEW2X5Vj1acRiN_re!jpt(oc3{1&pA z^)JSgE8ZvDq34g3>{pZr3w2|#IJ}&Y2@oiEo_W#i=wDp&>WmhlBcBi%y4PbNgU$TZ zkTf&j^SAcnBRBV6r;_2YPh6H0M+)V7)lD2s>LZ@MueL+`3dR-dM?;P$ z?S6fpL!Yb1aLMJaliZt4#dlY#wzHczmE8kCGv$DC40A5u@>PH>JN?{Gu^ImgLc4P> z?JIuO-evOq#2?K@OC{qBl0M>&&mo&lVes?RRM>k-{fZyg>J}!rHGP<^OeG#`%-fB- zqvboRptY?yroM6>7({1hWqk}zD22LpI^nikWFVl>U42`mrLFC-8M&rZ;!a*~T2G$z z+F(D@Z^5lTZG|G;;7{k^ATeD0Kx{AM#1~{jlJe8N+qS@BUZKA}4z98CNuc?V zU~$LU*?Ft6MDJR^EpKgoijV4tSNAae_9Z#XO$)Ac>s&IweZwUnAlMQuc6>1P@I{3C zzOoCt$Wz3@@$n+WXo78&6az`Kt(kd&HO}s`%Mu62Os zAIKE3HZf@r5<9`leW~ARJL9bQw#*&pD9OLVjW5GeHz16n+COV;lv9*zBa8Yzk$ zMswBmv~1d%5dj|CO16ZE_Kb!f1$K+>OP0y++l|?3-wNG2)1oOOpwzTCZ>6oj+N`NU z7WB1UzfgM+l#|045gl!0Vp7rWs;hfjSVTlsRdxQ~Fb}eq{}+^e*n~880Qe`|e0?wt zbQo8g2du2&KXKi++;kz+w#00JmRCSP#8p5B^GAvzgQ+7o$GhJ9dkI?5jvy>`@h9%x z11CNZ9HyVc^`xt-%K~fR^=mqp&B-7bHN;-k?-w8PK2t2iV@0gkR|sk7G^wNs2WjZJ zx5w8%=X7y)p7-ANq@$vyPFr!ZvciWOM(avcZ=G-I{ss%$PDPP70cdeshqB~$ryU38 zSBJ9PHY>&oPleYf5469#wCr|#D_C#H&+o0UGPz4(E8Q_%;87V~c|pT5$ZydtVjme9 zS(8-ioHo@y5H-Mrqv|}xreAwuJz$e^XkFl>OzS1_&_(np)uD8vE68-QkKdwCn_EY7 z^R1zbU&SqcYVFbpf?ows*V9Jd&9r6L*H4E^*HuqCcC^PQuvNuYblWQKl-ui3D}O#& z!tBQyb@`knv!S$CHqU7}F_hJw`r+e8s+G*S1;aQ=>zBB*84Dd@QaZh*~Y)z(h7 zzpeQ+Y}vdxf6>z(mb{20kxPGlHnZ%$AXQ7YLz@g$791xWiH^HRaM@Qq;fd&4?<44R zsL>e`GZ_$SVDDu$ETcyhF5W3-YP4d3Tl!N;$&krR+0t*1+!JJZZOzx=pDRS2y_`(@ zI4s1gZ&$>m3~u6J4*vcf`1kJ{^1YI47(uCr=A3~R(J61Img!WzBBG)eA_b6kvc!)W zhs=M65_(L4U%-^hN9uc8MSqnIJ8}E~fFFD9J7YcJ4idA)W^B5)rY6ME){N)K*rfab zE5Zu@=epj4aS!#+btbIQ>8#Wy!Q?6GFaZ%VvAFbn&XPYiSy@>W6cl#yChLr6Zi^-S zNK@U0O5>QYw7v){LPUY>b<#$p@+X>bjb{_m(q}rQNcXChS?Z4^g(i(fN)INj_#Iq5 z$VEj=J!i+iJm5b^%a1Rc2#ttG1B6+Ip5)bS1EUKa;?u@+HV!G#T+!F{A=aLn$n|pp za?Mv#W?1;l4y*}lxW%NUhctHFrZgg8$uhH-)NP}nx#_8G8{S7yavXkWr%CiSGSgN@ zacp^cM+BmQRax>~Ftc6RX$XzBkqy8Cg168#J)L@H6CEABID2&|P+M0wG&8fgciT;3 zs9i}RrLzxt-N|`M=eh@PA{=zrgNj|Z^-y^Ue{uWKx{ZHXH}|r6QF_@nwg^8s%!lcB&Y3ovrsK^Pp6I{TUM5jTvNQWae+) zv}8UG8JwC5UtTt4dswtJ2EN;NYrhzQ`&xzfxhi?=zlSzIZ%|%QLB_b_?CNS{Zoc{* zy-9fiNfE89S-{xlJFHz6_uSf=9R_vlCH-QU6g_=^95~K0evWfoi;s_oI>fcmsE)IE zV+X<``wwk(>zlM`k}BHy1CXO?Km@wG9$&~k`c_3nMMTDyTqBr}VzEl9V|}zDoUR0k zsc&6khMuiEXT?-PhNfe@xzI5%d)+Mp5q6|8C*8hpOxjz&5>A?|J6`SPXcz$wZkn2s zuU=7eC*uR>Yo(1S!z>Obv?A(sB2~182xFU1dC4i4TSvxUzX+?RuDW`s)8j^cw_ka_ z8xi+b?}{Uuxs8pBQWQlGAt0V`u8VQF6`uV2^XCuioAXU?nY`cHd82z(^HF_m9_keR z2B&tAf%Nhv+27z50()&9P?&dg@)b>6!zfD?4N|u=z(H{204=4Kdx)=V-IS zhrCx%P#|;hp!x))biiE}Q9*NLcN2570Tu1EH$ncUc$Z_7v|3S8{@1T|?$qZtLoeDq z!}WNsOI_DLn$`CW3JStvrb$dp-*lK$EkJSyX&mdg(jG4HfiK2NHXxWI)S73%lW;xub zu+gi`>0Q~Ep~XG(KyZW(cC=gL-eFetQC-FQB-d1%CX_k6xmmF@CgLip_fUPqEo1wz ze7qg$$+2NMw(nN;yDxHX^wIho8+3DBw{f$!Kb#tg(?cARs^)6WC%95mzgQULDU_ z@Y-gs&DtH-wNB}sV)dX8J%2!Z@-8?y__MwJuBl_XKIiJKIrz;bt(;oSec%3smfwGn zm5S1|^x~n_YKKR`s<*x}$+l|BW0S|Z{5lB(EB2u6g6gb};i>pTl2HBQt(n!oe<9jd z1ZMQp91+ty%yHd{llEG!S^%d$)>Yi!lO;wht zP07F4ySx7Rm}yRxV!Y(lKv*Afl^$iSO2a8Zd1Jm@i)Ezae3eo01uu(f5<)J51<4CT$qD7)UY$9&HxJ$%?v)6$%=;h`UrT}9NA=%vO|M|e$ar- zH~C}0$tNo#g9UC_K+oV37motL8;C6G(yx#@1!-MTHxP)O@Ym<)a?!NyM$uxywY9>j zg7$`WAq*}QddFN1N;+0a?gO}Ccri-1vfDSjX$#nt-}hqShP1+Ka!yBZyw|x2d=BUh z%K9f_et95HPVwm`n3T^q)4D9y_9^PS3v|XGXTG=8=o{yR7dvc2V!~{vPF7x3RX0tN zZicWaLU<77^I61^TCetUXwzKn?M?F6Ap1YQ3Q{s%?05=i0BE$$t*xEMglPy-&lU=M z!1f9)h{3WUBH~khJx!hKw(K2ZyO(lEI|7NgbmBUFM}w>r2K5h<(rWr6mRu0?Mnc?> z$>x);#A)m!#hok-Jv45_!NK@3Vzf31%sW?x?(&m&vm#b?DQRgtfJFiW_vsD=|E4#u zLt)<>932_L6|Zbw`i+?SigUJkOQ_=W0mIQ`^Oexr9BRf26 zK?Xc2u-*`MWRh_8qtF2r6{1_@3{_+RY(g5^)1cn(FFWKF_-`cFtF91(k(YhlMlB zhH|)m)a}cdAA|*lHT{3lZbu$P&IR8=QV12_(x~u-u*}QP zN5$8mK$>rOl0!#7Q#q|a)0VYBfVrh!dxu6u-Y+TBpfECK7ez(3vbcHZGr^i9{2u_- zU*hFlA705uODZUYufNlPp1r%f`*Vku6=7SF_yDfKcq@Oy!Xm%8(sq!ueUU)7Ex!&+ z4Gz!51}X)6zVQ3^>o9SFPqH&z%o8fKX-EH&Gg~h&8rWQdPOHRJR8)h5gL69PicMKN z2Cs1~4-512w*>TMjM;9nzM*R0mvg=N`SXoH3n&qRE_Hmn__%zNTRsL=EM8`rg&)Ug zEUC_+YQ8Uz`6=VWe~2X>P}E->O$maaR#r|9Tta7#L!2)?k2ac{1F&b5V*r6*zl7_D zlMXk}FUT9^Xesqc1lpI+6d#B2&_hBp#S zQhIQA62kVXtfi&#h%_yyrCDcEG}{L%)CFhGt&~mbBuGphUWMCa(beHhO`}bvwA2PR zaQRU4&(9X%O?v8DX%){nHh1Jzy*Mb<9#i7Ho!t@6!i8jNM z&#_9cE-lD$FL$nx(qid(&?}Ag_=PLW$ON&*?txZ<)BH%2VD zpsk}8O)%Wi(6HrYuTG=a#BDIzC!L&}Og-#lc(yf{sK^8Y5=Q8yq4xMxQ$u-nyzPn` z-#avSn%Um#_5RNv6OEDQEcsjC21iHLmzqndk2q)j#!@*;xKjFRk8`Sm2dbfAZ4x?qW%q=XMFE7sQ0l($t=dVq@ z&UCI@?}ndJ9)7qYkyE0q|A<@0~M~IHQD??!V*& z01u@ZNYD_|AjUlD5NIsvyLZjQ!z1ixbR+2H7vVlJl+RePoZqB2@VvDB@W|R|_*R`{ zVWPyG(%hc-7&UfPj;2dyS@HyRdxy}3Hft0fCOdCb^VDFFy%#HDRD^atYGwP-;jUXF zzwkq(V==M@Gpt}EQaoiKOMmjs=sxE7cRyHYl6U4R=PI_g0aW1rttHm9tgC36h1Zyq z)80Ov+(-1OYtO8Pr4^y4+UD5N$?_EFyncKtamSq=IrU?GOmyg$NDA9mZ#Yhl%1+Ng z*bYUYk(E{N$jPvgOwSLvXuwGg?j4ZKfHI;Dm@?3QfFI=Ig;}_h0 z1ibJ0T&%xNRGfVmIo|JcV@%;&gnikWtQBU#7Cic~&@wm!VE_#VN-$!v;rgDJ=Qu+` z4ad*y>~`s&iTRj6m8kImASzk!D)~0yQ6^_Z>0(M>f3+I5QC@g+G0-&R*A_E~gZ>KA0_nRoK_pC+N0w$HUWe zXmTkI3eZrPkEkSsNY5)H8B%<;F+VG-Xv(_tycM1@00-o4bSamL&EwDngj;~rn zh)_X`vmG~PC~`c~T|H)TB6pYlMvDnh!L^_o!VJh$a-+Cq_}K_{1Gw%$X~HQkzD2?? zLHBlH9!hZ3*}Je{7-QDItb(wsK}UfW4m?anAzhW6W;*HgIj|*B`yR?3AV$GSgNs(D zMI7WWaQ_!|jc~UoBgJY$ z>6@Eap-X`aRU;WffC>Z2k?yvDI}OQ0TUXKI|5zH&X0{jRngdRniG2JT8yl@@W~h#l zo)3X0D!vyJJr^QzZXlmwb{I*V<5y8zLx(|%VNp^>015^dT~ebGifh-d=`5zgg;~X7 z#!Xqj(}HJiW!1J>H5&y}5P*`^UcRicZmJ=c%Thgdb9b+qDg{~yFeX047dUGy`Jm+! zW*$Pu+TieT09+^a|NiE!uCF^%<6#9nN@VC_PhX3lYsApmShLozHU!(}|B~x&fs+U- z_3>3TWyc#>zVIpA)NS%_%+!$s@&%Uvg}=9fj6y*})7I66a}66CcwIAu;bU)(EnDx1 z5X@fpO9@3q{bFEXoPZ76b;QZ0t#5c?AqRK|o*(2&w4-=5pt3Mck;AP&S%9Rjtq#Z= zYTQrTo&#*P_4vot#U|}&@K@VF7P3{`;xxz;AL)Bv?YxNsgWoccZ-IRS)KsuE6Yt3N zR6k>>W)hvIFaGl78njb|4y{{+Pw_G;&hvAQkHY7e9xJw_LhdYVKj=yd&86C{qbXa> z#6t;ui>U&_8+A_>cLh<^?Gpx0SeR0@y-GlL{aRQktD!*-ZNlLA_-YF_9K8PvT7xwK z0&%QT{BAr+v0} z!3?;h#9k!iZ@(@S)F|!B#_W%)FG2&`fzR2k%grNl0wQm}?rFDj9W~;=0BqgS==k73 z-@*bH%mbl@?>A^$O2` zXaJG->SKX+cc0v8e7wXC%}E_g)sjdj*xV@b#M)v)@AOduo`;-VNLg2n7^l&Z;@=c_ zraL>uQ?-dN(XA?aOSHmgwby_o8Cd{|?CERLmGY!m1f*itq%fUb*k3)QprQiXU&!V+plgT8!W`VD19Ru%^2F&47Y^ZXlLD-S>RWcPhl&@^z&>i;%6`VxlG zf*uDfzu^C%%{uh3Pl>T1nqcw6Bi5lI(Cm}Enwq@~h5#Xq{r&wy-0g@zu>u89)-?#@A850&+RhW1StS^>c9I(m}XZ+305F5MXJm8yl$U?^gZ3G6YiB z1hxX18TQ)m(b3u+4A;}Fchz2}rFrP!s&W&8(Ke-UHx38vq@nC0q!Zt0AppxXV4%vB z_;5`6g2Pi9c|cCgM#BvpOqioQgGtnX5o)K9MOC}cCoCKW+80;=DBBZ&)`2rvX#Yzj z^wd_`(sDgYUhl8~8^N+kVP|Hx5-czeVPuW%SvCAHVs-;{%;?3d`x$2Rg^9s_+ec7ebs7ek|xJyJz2pJ~9At9*yg5+ow?NhsTimW|8 zC~tui1T#ShNU@3g9u{^T+6WN^FQE2A2P5cvS&w(aF6DK{*?j~c5hS6Q05_h>r z{|+p`o5}$8mURi_bb&YK|UsY^QptulPu>7ySA6c`I=76j>xnk?~jhV*$-c<9>( zfc_iS&+oA@3{3?FV3MiSDBu2voueE;48o|Q1?)MeGT!A^ae z10L^bi7g2f9s`>mVyw|+(0qlOUCb!1!~FxMYVTArM*NJKX` zH-ElW_)12UwzJ6Rkd;Q0;fj?aEZ=EaOs3#$@+A3@hq4mv&`epD--2nH&+r zfmN6q-GE+=OFSDlDky^}I6#%bw2AWGfYL#u2|fo}<2SD%seGfnI$|&mj)11^16(aQgYl5^BwHkNP?zA~S`%Vy9 zILi5V!Yrd5W(kP7qbXZCK!Yyf`OU>;oG&Fr*@LMNs?hS;i_4gck)ySbPW*X-RH!e= zVnF}dbn}n*sBV%6Qq%a@AUWY-$5iY3iet=WF#uc_2S~9 zFqC-lVp`7whV|^((@9+*@JPED&zi0LhovsES3-TKf$=6a&?cHDeMr1~w}QLF{GqT2 zY&C$JV0QCv7k?9YB~skJ-42$PaIwy4q7bsfHjnVDk)Ib(XfSoS81g}1LOk~9z5s7& zv4NU!8tU$ZB|S3>1vDowZ}}f1VV`qBlxN>OD#;`|{?|!i2(|U?3q5u!exo#ZG`4QA zAAJntYq<5MO&?7=h1j^;l(&)8wzs#ly67#Pm5KYnubC1%If;~qO~&H1Wi#9UhD{tD zUK|+%4eUuQ6cDog;za;_Ad{2YuA;CP`$=2c#F-emiS!$SUXNb=dxF3zd0b48rTMyH zCRN;j|VQ{D$DRdq+VG!xVc?bRs@P*n9Ad6NI-D$#LYq=R5-|)|#(`68g+&)AjmU^eO1Xl>-?2)F?0W%3g3Wq+BNR`l!SPEzU zF#{ry*pPH}d%F`AH3|!du4>jt1nITkw@FI^cc0x-*Ny-FE7F4%Ws6#4st8*PHg7Hp zjs|+qSB9qo;MD97y@mvA2gFmy2mv0{4=KSdc0M@WU)e3N^~M7{Z)S@gP1E|eH*oo2 z%U?C?y3PchZU3Na(zaZNdIMlSbQJY^cK_p*Ys<)_T;fj(TNl*JTY%m*>j#7?BjB%# ziHdIIZ*IOV$eOs=-kEQOhzf-ID;{5HU9g``e{>fq-pm4|dwMa4w<8U;wx#MjbqbuF z?yH6sWcjBJiT^W|^oDQR67s=t-CTdAJi3wcJ+>qcJ<`Z(-5kLZ08KEsVD=6~K+v!`DtR(79gQX)O zyjvOJG?#*`D$grFD7T%QoimGyh+zEOq`kfh6_Mvw4K~2ozyfKDQxRXARIp`sMY=Pi zsyNi~Z`|ot2Io#7vD6815WH9^9J>GaUvUxis27j=;eo{B(&+HY19#~E@1e#Z;E&RK sy+gh2|9iIo|6l$8Kc@c=EQvkeLrwB(c4P5h2>2y0qbyx0rT_N-0m2l-+yDRo literal 0 HcmV?d00001 diff --git a/_downloads/dc0e6623b8086a1f47ed26af34e7c6ba/coordinate_systems-3_00.hires.png b/_downloads/dc0e6623b8086a1f47ed26af34e7c6ba/coordinate_systems-3_00.hires.png new file mode 100644 index 0000000000000000000000000000000000000000..e1398cd57d4bfdf3d2c88001c7334069f7be3311 GIT binary patch literal 54907 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 literal 0 HcmV?d00001 diff --git a/_downloads/e6b45cf94b78c71339be16615ab48886/coordinate_systems-3_00.pdf b/_downloads/e6b45cf94b78c71339be16615ab48886/coordinate_systems-3_00.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4d5aa32e9c2c90b6eb5ab89e2b8ea60f133daeba GIT binary patch literal 27362 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 literal 0 HcmV?d00001 diff --git a/_downloads/ea07875cb182b05530c1caaa47b509a8/coordinate_systems-3_01.pdf b/_downloads/ea07875cb182b05530c1caaa47b509a8/coordinate_systems-3_01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b15ac9d2963d8d5a85edf3f15d56cc5084f2221e GIT binary patch literal 33286 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 WySV-JxN>rELOc^SwUm-H;Qs)jL={p1 literal 0 HcmV?d00001 diff --git a/_downloads/f421d045ed7d77d5be5b5aa28544d030/coordinate_systems-3_00.png b/_downloads/f421d045ed7d77d5be5b5aa28544d030/coordinate_systems-3_00.png new file mode 100644 index 0000000000000000000000000000000000000000..93a56cc54cfaff980ba0986586ac0283f034df04 GIT binary patch literal 45578 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≺48wcGA{D$UR3 zM^#Cuw+L%5a|aNMe5}Y#nkw$({2x?ja2#A@R6+l2g3E(SzU1{QwRdRw(fbb{;6pQ; zPWn!PCJVRB#L0=GmL3m2M<6n^)n5=!6bH@Ky&^fGJh^ z7KeR^-z1Voy)4H<4xN%l1H@zHyg=E#nlZ@_p`&vUpZInBRGk~Dp^Vq>(~#C|Dl)k! z5ma1Uw~I|nKtASISLskq4!t@;!Svt7GE#X+E3o_oI;zfXeSZUj)6~>dSB=%-Th)&% zr^&3mz0X0@St@Av;?&q7nHy=NoftVlzh8umG1p8krRCMu-s8UDbLREODZtFH@`=?* zH+^J<;-kBxfR#b@f-DXfq>)P&p$ejdgL&V)BWD;uC7`|EzTFu28q|Y=XJ&3LVVwwt z#G@|OztN@i6VSG?^NbXy=qJn72zC{JMf3iTA*$sJ_-ZX#{`Je(FVgD_=1*yb?h2yi zM*{!|0E&ZW)}LK2ZPAmSc=8Y9{-CEUa(D220iFdY&~tp^KL^~x1gGYh!mgYm2wkc} zPaN#aG4Iv*OfP%azquk@bD94l44#>Vg_K>SHG#_><%^;kWof?IPnkJ6U(#+_M58!E z@KS=bHJ!H(kQx4!nJp}2J48#4&!;=9#m~x95TB?FLAYW-GvWLPdcP>MsOkKPjQ}yg zuIe_lXHr5nD_iu!Kw=S5P>6-%AvN<-`oZuY@sBOU@}2WpGnOSovC_y3Tkf%a2N{R- zU6smy`c%$Zbli$a{wp5FoIM-kVTpc}x~g_r+z3w>C9@^_!gA zK#auNCnO~Br0LA?3Hy;dI6C6ty0o-oY~`E`e{a5q__-Lo836%JP(07?=(twJE|UHG z>ptP#&K%Y=qOs?zc5%TW25p=V)<$Cxp&Lhq(zM7&M6WkoVYQ!&0a6cxtRac7@O}wa z`NSX=Nzqe~gag`bot@=A2Im9^pbrgaI2jInW#Uc(GS<1iUOw8LsQv^?T0L{?zczxh znB7W#WGr7u-&@CfO02^ox{xW-#&UN<< zrimt2Bd##(WAgI2bGLUJG`*+aKO+(sbExd%m)|dn1F~MwhO@$FbQo z@A8APRdsQ!QeIg@{AT9v&ngek497~ds<1w+O7qV;-QxnT0xE-oi@ij18#177g6{-M z6-bj%B}U^jIHbzNzh;LSNQT)5G&p!ek||gDUob4&q~gqbx+TWLahRLh}cHH_#*7hX?IHn?q13yxjSB-9iZ_u&NCh_ z?T|l!4}yvSDH%`o3XOm#cYOVtsQu%e$tANpcf=^A5j;hvFrt^v5{F*}ObN7hWvm9x ztJvLP+L>7N=8ga75A5>ZRMtIAmi^re@E zB9vwS>4$SNnfdve_!kyeRs{1-jxgERK8+%6oSn(zGzuIa+?Fb{#`yy`1zh&6KvVDX z-P^&P`tI8dxZvgum6#50Abj;5RFL;dRRINDu-a7=RkDk7Y07Ki&TlXTM*9(>!+eeRvR#Lm{ zx*+GnE06_KNwfuP#zfuzNr4+|E&K#XBpqO3kn1HR?5geUJ0Ag?k;*=W;Bo%W>Nv}o za2C8mqxKoCFt0F%&@Pz7L(}Z(q`!8(;e@V)?>cXwP>|Vmt@4 z$rg5H;VM7FFBD1j4}oNA@82b+B^p^t&j=8M$hV`&T?rW*&(|O!gO~#9NNikOt2>*W z7&G+62c4c;BB-!78LD&}xtaSH@ZGfiGcBiX{2fo%<;U}WMa73YDWH)Un0r2aNDZ71 z5)IpRDFy99qme4dgpG1surkmk>#negvBt4g?u=f*L6fPekL1`v5MgT9Nl5ARfo1@J z`HvxKL1P!M_I4!a{&EV$o`41nK?OY@qLEZLZ6!coK%;Jt+%h#qAR}0On@lv#o~8FL zfLu7U;R~22?u?DJ0-a!ICrnGh$Ngv#e|G$7trK6eGwZ)HYTH)~!I;}AOaf}GQ+2g8 zJ-dD|)3l2vyBW&GC3`FMc#p1x;rhK*Bwy5$|^#t z6KrkkPoZ4`TZQAtEJSJ!T`XCd_xM-L_PkM(F5_rojNF?CmOjj=*P4tm9kCK}P%2;< zLV{<&&A7|n;DuAX{DPCb*f=pp94K9{z^(eQvg&+6y->Gkcb>_Ki9PFvT&g8 zmmTe&x>6W*CExgV_>_}GpT()z(W)kkUD`z6*yu+&C7V@<%sryJ6(OTL3AT#?S`JGu z$2R=4)+#}dfP1T`5XDK&AT_%nHoyAh|9}<=`1&dFz4T3GCCQU)s8<4{R%#po{@xFP2;+eBQgz zhwZcxr4Lvb-@*oJRHt?(aYXm7?=MrHiNKnEJ1Mdl*HGh zxjIAM(7jC0h^=svEYXLHcSLp#k`YM1^&I-mJH2*Svo3I_$S!GDrJT>do~*-R%>Qn4 z-#m)xFe9Ilj9Awfd~SJ_nxRPXzGZ?I-uVs30E@BC+%*hSUA2y8Ebkkm;>;6KO$RTp zAM=PV%)3z}iwy|^^Zp}_cYUI9rikGuw)6GQ1?>Yo{PI+}Ehv_}W3$ETbZ7U0)eFExK{>8XlAlZ5KsW-I| zTEMtWW5+ouBB<&tz-t7J^@qkKdaBTiNd)l#jY-le)V09(v+gcdk}8y^=?Y+au*7FY z<>+&WBr-u%cq!GOK)|Xy@jqFmRD70`2+3} z5T8FUb-?ZG$=gQ?c;6QTr8nn}M@P3dPp&RMUa^8z1r-PuBX^eW^Z8=DKL~H@ixH;3 zU+Z?=_2=BidFY^K>DoZ`!{huPKN#qupKKi0mG>kw+?FC~5iG6zLKW)w0+HG6GQ9Ua zz_waCq5m4N5N796i?ZxEt&wyuXXoyZX9|5#Tk`<9q{=HQtflrqvoA~PU`L5&=O9Gv z!gUY5`0nAT8gk3Ml)egQ#fW+capw>L8u2Z`w`zt>t0fm6@ORy)Ud%9;;X}?%tsND* zCk72&FEldfY-|+hO%}e(y~tM7r#okrpiOt9SYtb;SSS42qgV^RswsQ(EJ~%bJnxLf z1X1V8comY_?ve4Syo)y3)%tt;Pv`K)bFh7ap2b{niMld~y|B-f^|Ji90A?_&hoA4_ z>uvOX8h@-&dP$KwX-0R3Ag+R9*k zLqt&!lb!zKRF8!KX3e?Gl?KAPTCKXo;jr7|(1NndFxFYrU@;%(W1fEW2be5ZEQhTC z10e#SFSMYH^ZOzWbp6Q2?!{~oSX>y*dg$vrBH_#ojTFiNs02XMJnC||l69ZQsB`0G z#t-+PE`m}H!d4ucVAb2YufK@3efNLhQ>pI$)y?aWJKnClew;{R(YBx3Oa#$ zk27M2jr=bZSENxeZ`v?t=J0qAP^8p+o+!PN4{zAWoV0{pWEVS z8OdN0#`(<#7+ED2d3hu@VHDn~2vXa7o?m<@k`O+2_Ie$=O2VePy=LU+mHsHCCTZwx zX}d0+(kXM#VgyX=Ao0_e43`L@?*WY)jn%^MUnI*o&ouvdNsMS*6<8QB-!=oFEh;V^ z4vY*A(6j{w1*f|&<^_@(MCs(JCDqEO=0w{4iz*oF54?rKj$M{$0 zGI>i^TdI`o8%U3v?0{^Srf*(K>*MYp5v9JTOkSG564IoK5VO#iP9Zf9Mbga)oqM!@Xq=6+>2g_>#(4?=(APoY1*vL#)0 z)eR4skcBpVzAH>rU=@AdKz=dkI%xA+;g@X(O@8d3Y%z-w>Qi6PS%`~HI?A<$jPoW? z0+=VS!r}8Vj-9N5?%nc3_Jrn??Lh&LSTVu6T(MS>)9o>pAB}@Mm-42>na%6GwG;Aj zGH@GM-MSgNG_LfRUk_8U<|!*H>T961Azp+8mBwNRw@9U`3_bs~S7MPD=nG%(^`6QM z2r$sq1t$X;XwBc8K3>S`-2JsMvQp6#VWd;e*34d$@}4C$Yb5Y|VZ-Gr7ke9CMh>w@ zN-{@CF{h;~IT(ycTl<@n8%pbP8(Gk!=AV~URHQ~|49(qX2{08rrIs7b*L^aj0o8V@> zc?|NV8Xc+CgS&Rexp8lx#q9hc5O^B%LZxX5v#Ja<)$sl;d;1Ov_T;*Y4UAOR7q|TI z&IiL4UI79X*Y~Lv-298HlZ|7%%pc0i=3t8h-ee7-PNhAqX6q_91Ks>+b+_pj0%&95 z7tx#JTP!!NN~CN12Nv2dD~if@M^Q#e><6~gS*?rP4U0DAc_{9ETU@p~CWs@F9>Xs< zT#rGXg7fEo(G3ItxYS)Rirf4F0{}0`a#YNCiON?&ajocE66Hul`b=%@x8B#9t&__V zLMzt#Ji6LRuM;1w#0I7Ce%tRxFJo{-cPR_a1q(^h!s&LRTbBM3xY=Wma2Ed1Uon*? zb+Es|hh}%Vn&-X|`E-u;Z-FdbSTrntrs=1W6$~Sid$QTb(wOIPi{GJTuXOM&VYZXi zRU)K*Z!*9gHcHHj=VPhB8zRn&7l;EZ6tIQOV zp`DsM-@EMCu5`<<`5ni^8j;?rmoYBWgm_d z{Nf6}z3u*!F{3F}Xd{fUD)}HWtp85ZB;NbJ?Rh@L@3?PC534jX_>j=E^*x3iDOzhP zt|wldrO++I_myE6kEp2iJJK!_`|&*Y8eYkBRs7}`co|FYeEZHwBG z>u0ZWWW>-n-c7+evHHrp2iptq*a_i z_sr%5$~IJj>({UIYwJhe(K>*yb?cWLegTQcL(9KRO#cC^Zk>QmS@cw45;F&f)M!88 z%9V@4td;AEm5)TX?q!B*o{iy1x@U0-Lyox;{k}n(F8S@RlNyYSEe^~i#U?#DwxGPE z7$`*pD*)1^_F1PedFi@}8sKaHckFf(pB1Y?slab;!0&R~$lGf`9pUKn_le^<6e$q3 z#|O)J{G-Vk#8BoxR5BoA=|py$MTa}3cR@GW7EDKV=8bwLUF2UAS%E;gH7+v_h{?u{=+6G`|mv!=N!Kx zdLL;%_I#E9if@>s*s9BoJljoAPcKWo8C*Prr&2uq)+QUl2BdiCEE5mjG$*Y$M;`SP zAdToCyupK1H%hV~#Q#uqD+pQ|TU+2qIIqai9hoJwe}qxy1lvLF(PnR4hSn>B7T;hG zF7AqH;*6c|)$Y@xNDnLV2bHcu-#yM`Y#9Gs>X{^LNuQ@eUYRr@14az6)kQ z4ymoHQtVitR)8bH_Wpee(AwZbG&<8p`>HoGh+B5w^N}YiUUph>Qn$}-ND>iRPEP5N?A+WAXcOP=KN}gV#bS?ArMtK2h{%?e22%nd z!kA+T(oal>h`juRHZf@XB5kjqdNOQ5XJg@*Z9bZOxb!0&sI=-!tA;?7du;O6O)k${ z0@&-xT)E`32CwIArs%OD7NpENv$AeD2imi8x2cqS5{swSPcH&t6RV6SQKsrj$W7V7HomOyhUuPSAz``4zqu+f1PeIW$Y=!(&`z}( zhbsvEI%%U*m5dz8>h)(%H~K+ih>Ex-AZ<7SV~vW{w!?PNgyQo?zqiLLs{WA~GUwRp zdg1SP)3`3voz}L%$|Aqh(L}-0aV|a87{bzZ|I>ZddnOOw(tY(z8(!N$aiU;b;}bjp zMEeJihn(PQPmT`*1`^(Jr(l^V(F-1((_NBJ&tBzSY>0=(GBmlLpyovX@UF>g^RI>F z?(t|BHb_fpm#AW8dfmmDv$2Mx_{iXRxt>6%D_Q z2b@koPh+>Q*w%o?+I0=~be)A4++eR-=4UtlKCOgHOjInznY6EviK=s#8oldRqTXBj zKk{&Y^O}>4SYOt){>B+g9>#lFJT2D>p(UM4RB>hi!eR-Nr^SmmV5mjWaHVu-9ua0d zC}E>Q0Mzb}w**Vg;oh3Gg@ElV1p{*VvHieSm^KX|NNcANkxy%*6M7fKCRTng#U&)n z!B!X%i-_3E-&?v#uI$z&F|AK_%?lqVh`OfV>rp!K9#7+tn-V5R&@#TE3bduvCQq0M6Z!lF zo9*cMyII%HuwIO4w+8v0w$-Y<$i!rkvs);47gwIfS9h${hTi#La)~*-_s}_t&h99; zGvgT*N)yv*8b2SHx)rv}*d4lf2Hv-_Usl_E=d?5l$FQgNYO9Y)^Mv&-`~=WXk@lLg8)UM|Y4?7xsOtW-#< zRFrmfmSDlV(c9V{Z^SyAhko#Q1;L(rF5OCl`wYkl*&VUNEgbDwDuP6W+f|GWcqxJS ze{+%m%01)pQ1Z}PQ)Tgq)@Uw?ZeD)sFLI%B^A>P`jY?Yx9aCkv&8+%7^j)>n=4?Op z-X<}ox^ddoaYWW~b$BP`)q>f|@&iondW`MGj9!2?id&(hizfN|!QRiQNWwL~+o!N( zkrE+%rh=sZHXXWb9rjx6iXCkVpNP3MCoT+C0+$dx$%16BPgLu}i<}G8+8q z=@!?hBgZMlfYFrD&RBL0?POWu{RT1H-20@LDP@#1123gKS=C{=%f&k{#~m%LMql|! z7Ez_IMWla9rO7hBgP(O5^H5sKPjLy`tDy*822k)L?eI>RTkUs3N*#4Y7EFh7c-Vv! zt~$ngYLd6m5Hos>=0wH#NM(0GwRWa!l#ykoE%3Q!Q|_~70eb|k(0PhaJ8Ym8r^xrv z9Dy|y*Vkxk?e2*POMWg^=+WvfwvWOhObB|aB;*{%wsAC8Vm(8w-yK7Vn2-8CN4bl4*FXctOC{} zXla3k2*3Ubgfn`fp#-i`@wjxm9wq$(%LJ?+qYOk9OONNlN3Nk*x43Jv@>{jqxu3$mXFc>Fi%VD!Sz;! zCfDYsQj@ zlC2_r5YQ3H+%%1RSDR;OKcg`F8H5H9i>PH2hcklo6!Q89K0tkz@f1@JD287x=*9oI z03ameyj#U4<>lp}(Cvaw(`N)Qgp|6=x7Wc;2aZKN;{4ONz}?;5(JamnOjY-dSUF#a zN89zXyZ*Lfe_fSj0)6Y=R_(k`CBX(SintNHl6DFBS-o<(H`y*ZLE>xRSAkXwzlAg~ zX5yQ%RN@&NR~0y-pe_~~iHDXKEaTQ~3AE(IY6G=7D`E>X0wEeiB zd|S(u-$T369Nm_MoR|)q#jKRcqW7+jmBoQVhcii<9HPnzad9)A`G@1o=&C6{<5g>v zx`ll9>l+bvO|je0AMV6;$0G~+4GGqACEnp0mRCD_)^Z+vx1I?)e=+GL;Ur_-6_G8` zl^vZ@cO2caevyc1tX5h$hBw=#yV9^uX#|6&e(W@!HO!ZPgW3B$xXR1JVUGtj0k|{p z{dm)oHx@zA)cif}9)p0ov->mdrn|!EX(Q}yNYu6z01^EP;HM*~uY$F0?<{zV? zO7a~q%+(&v*6zzKk*~W-nB&owg3B#qL2|P4YY4l%(7qclUc%>hmXMQ#LkkX1t+0Xo zO`}c{V6Vk@23OK!_@{a|M1uwP-e%Y;a=O)-ze&9eIu=mql_Zq{iw~yY#>BhHcvG~^ zVbbtT_9UmvY0pNLq;vIoSmK^HPz1CVx$_qjS#w+)$A*(UZ!Xeq2e4D0NvX^H(S_|j2~glznQUYQ z;0aY-gJeq*#&!Z>lg(82Qm{*a6weCysPf70eoN}C<(#QP zp*}_YA!?=EO-{bMAKi;z3UM92%I_KaWjyWNg+Tl1jIxaJ=5 z5)7MrQbQ)3_IS8!YK0LInl~}b{K7X^1b`9o)mW~>t>1g&FNVbgVHaa~=^`R4Dl+U*t91HvMuz0KZWA$zA@e#GwbybP4VVV%dlQ-$u69F}dHwiN&u%4@ReuP9L;^T_+3)-39%e7NBPvDl!*g4;lcM za8Se{4pVr!=dcLfEGABy?#{Zm?nWNg$&Y4;U@pqkTqkG>RlFp165utTp&j% zo_SGIpL5h~!uWb4gNrijLJJ$gJ3-{zRzn@welq$8S;`R80nT2$o;{E-oFRLbic5s( zdCUYh6q*E|7N~ARHZB-kVoG?f?Fbv`>u#ij4LW)-U55`Ey=v2l%)hZ7gX|ZH#4n}| zGs`^ERJq%hcEaOa(5G9V@0^k+%KCGC3mnY-SP*u3ZlLDe2PKo|(x`3b+aA)h$baEI zap~>o^8;@ig#C{H#J1jaMoxGvrMPmqES9-xL+~n|_2PqsWTUTFQSwiD6wU3*;D3C$#$;ArVRE#kP`|6r_w@=@l~? zu=f)jCB618Zqw{&0G;aDmUq`Yuz?zVMyn0(Dw7^-h7*xRXrO<+sJ-c zqo^!2;*mgT@|6xy#t~wq@f1x)kwOuTZbObEik*!S2 z0A}AP6RkDs9`U*-Nn(n&_-kU;=)_F8&hk1u9KQdFL;KD<#F6}3l5XH!kj<$GU1Ir+ z^Tjo&t82-&_Svhzau>zdXv?B_hj%6CKP8h4d2>`7r_TpfMYnjbRgj0~rr6#}>^i(S zO#O~~vlgeSb#yx~<%71cja^;vcQo z?RiD8AeEjw;6N(bl+RI=x`%D4bSG(~icji1{#sSltiH}@Lg`A3Tl($N1wzUT2#nCI3i%dI19s6OK4n%f!k z8{G}EUdbemn;;}$vgwU;02l{~^KIS*4iXTN=4sb`fnFhEFZBD3qL*thH4;unGd8OV zy*;%N9ze(?7me6o(zQGzdnX~WIerpKj&~?*_#Wj1cu}1q5c%GW{K$}i!nX`Ts?3pb zZ<{wxMCj`2y)+Z##&-{&>DXR>C6LDH*H}0!FeQxYIvHigRub_l=c8HLZ&%t}U8EY> zGLFn&DL;$BdJliK5MQWWz*gi_j#(SCgY*Xg=FOT`h1tsOx#Vs;v=X)XEjth4y`WL; z+Sg<)b!K0~`q_UkVlaC322#QJy$LDodmr`rQ~v$%pZwmf+El=N!?x(@A3K zfo@p&xwhnv-skQKj-Ec!e!AX8vqUQVx~`d&dT_s^=3sBs>g#{ZCy!e$o_+TW8gkErZQ9DNyhPCDUNYDVRAJ;R7&Jfpdo=n%zk zyROyd_f4Tk_O`lsUvD_t3eYh}T0QG{g_S)Q!(7ZBI{GZVQgTg}+PTn3wu5M5z%z9# zoLJ=&dwf+^he6?E&&)BMs=n*VW)_-Cj4PxqvVw8KWu%Qwp5!cih{az<71L&Qiz2+8 zIMI>xoJ-7Q84dcIp2(djE_LjY&d9T*+`;zd8?Cbeb}~uxhNV8Z9`!;}Vfu`Rj*DKh zl(?qe24=jU@iM+ImX{X^f`s}mo^3MTk~*^f`@|$t2CY4A-!!CeOdwQO*=9@ zC323Dk(&JFnJ&y0LWh7uT(2eo6K3ts&%6C=(v!YClknR&1iri3_3La- zhQ1%1z+(fxr8f~S;GK_t(QvEs{f)>-8B)7aGV1`x>OEmbg8+g>8_iP@dF%n-dt)D( zI<6~yZGY3ylSq%r%qj2=R&7pva&#}R0Boe@9q!)s_vpnlhNO{ZKh}IL))p7#1&6o& z8y5q?6-b`pu2$knKETMLZQ+Q}Sb#p6!wDtIol4uTmY*YGt|g4fA$PVR#q%Eju{K?Y z=z2Z-xj#M$2T6p7Yu?}U`wo{JzbtiiJ$iyl>4{Xd2+nvChT8H~;O|aCo=GRzBgf=esBIDmBrLDwguBe2Vs`Q0*{YVZ6sK>GIg;|HIaq$3xxk z?|(>1ks?_mjIj^K64@ykYauE7o=_pOZ;51|v1TuFYqMp`nth+5Vj|mEL-sA?_nOY* z@%`&}9`|48obLF{XWsAEa$V00m*no=g@k*=ZrN-qZM@0lUhLzd{1#EXv%upL4dV*L zj70D#j)x6nB}~z45jg`#$_ses)JTtgrY=;6_5eQ`}7$M}u4gTpcMh>kmk z>4>}AQUn=2R<%?y95~f$Ugasle0Rq5!5J+i!>h&XzPSoqSVW#L@APos>d(M_*r#xd%{`PcjRK+b!1G#o zUStc;-~!bA;odMOdWr7DSr0E%234v{SNv$-9&+;w_0YrxFDV37*RL$Q*WWMTaHE?X z+qv}K6mIobl)@lB2mJ-O8<&Xa=hie?l9GRYER4KN-z5{N!vl_LvZN`0)BpA{(G7bB z!A@umg|!>3iK8#GfhOjnsPAQr!zDoO;BZrRADHjU>rrRirc|fNcJrB6#Oj-(4mIZu z*^buaMcTD2Z*NO=jF-$O4ELYAC4pc(iRaTaqRHF-Oz6hXirQbJ8dPZX%gMQWs3g%p|2eArKtR_}7rw#{rzFiDC{3AVG0sMfxJh!H z+GgRI5q_XlLZIwSHFC1UEqM)^Dg}ip)cc25YKJdwyL1l@zs8#_$Yw7|6Hw<5l(hT& zV$%puy33Q|8cmdvUaIAOW=zg`E`(31HWg+PouLEcHrOtq3$iOCW-%C=?v4mn+0it5 zROf&$4tD#^3qMCz9;ZKC$>sQ;v;%Zjx-K`hETn8oCrNyR02EqV0`JvpAYp^Gs=!&D$qUTKQHON@?CYsv@>}Qiy7nw)a*qh)x!M-$#1aGF3*aG+szV_@?FA8$TXy~q;U5=4@aZp-qFMYJQ z{Ng1`^`;AT%Js?V&tZf^I)9yE+NM2gEkj@A(8l}O3C2#;>`A%` zC#KkrZ-{M@O7bXw+${$<#t_%cUYY`h? z<<~z=J|k=&W2~q@#cl0w1Y-tOv*tuW`sM=y1Si|;Bd1A zNWcM(lRXL*ZppI_DO!R`{ z0K^V^TT73-r<+J|%CP`p&?~ULef;Xn>x?IIsIL-alC(f6o$enAZjIVm#pO?81k$gTY-0Ql z*X3qC$JZTGZmh{A+l|Qlhl}54uX)FzNgdK&jAdPBjvJ19cv>OWtVXkRsrr6|>aK_; zi7*=x%kAePK5_${qT7FQtozyN-#-L}FIFAvF7DR*#CHYJ_bn7{yX5jq?SA&<;A!U! zvwrQhUH>+5kK6)|qm6bOKWJ;S`9+zftBYOvl~+}*UgRnyiF?XK=fzDMi-m#`S zilfLysrgEphaURr7NzjIsGUt>%m8-QfM;o&la(QdSsmALnxR{dfOPFzFD9gI>%LZS zbT)IPH}c(gx9IMofz8jzfbq9Q$B03bt}p$J%Gu+N+S3tycS@l%I5v5#%1 z_7-st)tq;ak5f*XiOk*Gc90`N!3f1zm5QzGdSl_J7LDLb4{xHj+VM$Iu&*|hB15C#yw;?#UDxX z*l3zk`vh~&lNmp#kpIJJxODDL;q@mw5_o4u?%XLOiohTS#IsMJ^#_XpXre(&u1xY- z(P`XkrjkY|;?RUN19Y==siIJfM85f`ZFR?ne^ZFUUo7cpxV%ZA;P6ARJ}|zP zrPEsI*`=h%U6U)U6qj| zBcEcMY@yuFJ7&wj(-Cn!_GfGqme^;pKkd^M(XoYas?u!IxO%nZ!-ucDf?W%ue1!Ec zKay%*7JZXouwjU$IVVn}7Puj?#`*@QvO zO|?Gry@1+wqiZ`ZYiz4OD8-#cnr~qogIl&AzV65etjD4I!1``&C)-S)2dHvSBT%W> zPRS%K?z1OYz4WUMzDIRM3gU}{MVp1W9P}f%+Euftj7t zhfA5U*gTT+-1$|LHS1aRCX&194fMWLU{7O#3sy`+h{OLleByhJ5^Gh^`;%#SP>BPg z5w@+m1ybN}2YXe!ThCV2+hxTRvOFW%)GP1hY&WwG2uFqnS_p`r-$x7Q=`1*s)7r$3xk~>xRy!d(y}QXxxON!5FGb?mP1rWO_@RutXcY?V}a z5*op1l@PoX5pN*9F4ZUPa{oE!k&6!#@?XHx9<*=qD7I@@giD;}3oh&=fuZ6i5__ab z4$IDbt*<+fN(J?iQrtFW)d0Ja*CI^w?w!o)eS;f6&=fJVd^CBAj(JyqEVKQf3MIVO z=~o<#&u(4)*Bx00dD)vl*YU-{D!Lv1*Z$FuF((-~z& zA&QQC6mtb@U05iz^!;kGb zpKZt0Kbi1!Cj)5<6c~hN)%(dmJ7hZ%sec^Wc0=ApugT;mEMzzw%lf&&zD$@YftM0qO|rqD>vbQKcbr{M5^3f|`_adl$dgY(SNH87 zNyueS9q{J)wzO)aZDfcEMG2-kr7z6@4FS$s*vC6j&^8K~0V}}aH$NU*b{zcpWS26~ zKaGSoDOjx+rYrTiSMH;DjgXcm+~xjIR(W$vhe?D>W{v+DW-XwNP_C8 zJ~LsuS~^`9hSH=bYx`#J-zhOjnH2D9G01c#XI-4_n2+V_OsmzvSfD+0ca*U$-b+~T z>WT*(iC_16Lza%etPPhrqmaqdRH9jqJ23puC1FIfpewNc&%u&G1Oq58^l`gbjgu~- zZJ6ZC=Y&mjf6#|7B@N>4-1>0`Lvhvs4(C|j8#}C@r+`U5 zqEUd^Z~J#Es1L9fI!FePkzA2UmkuK{WC!NKcuU^F!VIHo=DD-Z)pD>KksEw?=60sq z58k_`B>G;0o?~DvJ0@pG0oStTnNhQLsq=K>?%Ldxq?jsi!-o%4z(h9^vj5s{C4T39 zt`2AUvV5FaoZz4cmL+8Ld$+r5>AH}MzG>G!&TLiI-8|7+C@t)+aOjqgX5pdEpuRBz zyRlkvQEm@?*I+ykFEu=2Z#}cAaJKkuY2yEA@Wrksn-_oG6%{|d#1(Up!Tp;1p=d#bEf%H%Uof&GQZ<_V2IC}hDa z>%g(`A?;QWT9v*u`=**^Bz#j!TQP+7htqeqCQ*u#=sRmcYvr_zU%XdF!LX^Lub;kf zmDlXeH;_e-4s?f1#h1?kB>{jKP^-8!HD#P-vtkQCuMPjC-}~r>)>O0Qf4(WtNh3RJ zqddf&7+5mpK{M=4j@m3N)`kK*$1K_4MuR@>I=l9(|AMy}oGeqKmQHZK7m zX6d_y$!KZFd`B&2IjsMe+L!U{(m4W$@T_#F@QquQer33m!NmJbCL*N*xP-r!0H3!9ZZMID3VDoe0YN;Tvvw3eFd%|^xxjY zPLu{Me$^+@M`bOoGTYiGz(?2qIDMla=Q~}4kas&ZMu?rBF2{uR_-wv)W<*B+nE}*2 zT;h;jld*scPrts~l){AB@*~BeYtJm9t@}VV;|Hjn9=WcCkA~P_281d?K+J$4$@MM; zY=C)S2~3@cPi6h+Ua8>pd1_KG?)5bRD*zYo_fUiD`UKeMU%m1V2&m(~+KA?#Y<9fJ zHW}s^8D#DYJHn;{1vpUubkV5$7sf>idh#>rShHNIS zmglQ$0xV8xQ|E%Odsa125TdZL8GDOqFrMi3Dtrr4WZ5DtkL&#r&g_gzhW^i*m{S?g zb@-Q$&Pw3>b`CXOezBdKDp#;P5lm7ON#CFy5!svMLP^)y6LiTPlgQ1~9+=CWF0gc#R)GTH%cq7O(HX&~ zFFtU~t>6LS&Q$*%u;m5%l&#ik;r>A@Mz_w&1l=WY1X1 zjdwrK?C|?Bnt55zv8?XRq9Nfy+uB-bWO`@uQ}Z84Vhx=IyU)A4i#*(lDoS(FKlvCU zIVopkV|UH(srtXau&f+ZX>TlqGI~5z`kVyHfVN==!Xs8;`+mNdq7jMr!%JHqHm6y3 zh#2jLZ+9o4e~|TAL%y%ux-E%Dpu+oPgTPzAX74UI+Y2Ag3ey9!*h-NFO>V z?8qczIDXS+H2N=eEbx9SPBMNnj(wxY5yH~2t2M8+`Ct#l2z}q6Aj+EQK z1kV}C*>9TcQ9iu%eE$UTOWeA4vYl3_ZTIp)Q$Pi^XglAxGk!e=6ZmlR@M2(GHVhn@ zU6^K5?I_vib?`6R*yp>B4`UtrK`Z*t^#-?4nsoeZ>q1-ICFrqW83o!KGB@g-aY;pm zgId}CWWYpf6=_^AlmW5P<>Z2p0&}zwWe3|u8JXyP5iTqAIEI(#R#Bn%^B-`m9p+>@ zTzBEi2aZQ_1jWaN_svj5KMwJ{&J_h{x*V(v+BNA7yOv<|vSOew)hvZ?< zdx40HN=~Gz7XSQjSqcX*1N;gTva#2lSsLUAi@Rfvvu=&6Ir(Wux3BNpnceWUb64eC z#d%JeEiN6s%{BtFi$4UzR703;!ZV;1{-U8bk3JEcA%+pTtcGsybygu}&J~>4 z+&ds<%zAa(lnJN3-eQI~}OK zHP{@&UZV^i?Y(hlC(o|8^NPNOOl1P@Oqw7ws?P`KE;T(%52xQhZLHQG$}LIg^sBu&;u1a@0Q#kq z(Tl2L!yshE-KCdr_(Fnp-;A&1eU%y8j(dq)sqir(#+@zq*yLQJF5U>9w3N1sOOrYBiyT9w4{7Ey}TcL@UYN6N2kN$b%t0{bW&SW zkfiMyY==iCz77>#`k}=z`&8lYZll*-(EmK(JHuO2`Hh~H$M$IiA;jFviGO;F{W0xL zin_jdU89{IEe1hLUMA5!#eG~hVY}PW;ywLAB4uE#kxIzBu$O)Q=3T#Vt>pVw9kY0dXf5xOMK@A_{lrQqSp(+uiHGq`CVZ8Bbd)YJw{f{ zrgW2iXP|Q;8(hFHa&sI4Udj^oLo9AZ(`fC>=j+W=xQ`%oXt&AgSlugC*Vacs&JO%-15OWwpA^zto_V)KPzzdDy=hwZ{1hgg}f*&VzMSv{$GSDT1 z?_`-bulSN^k)nf6d~05D`sknS8yBY31i2=`8SkwyivK3Eexi?W?wv;n{-g*UOTJgK zr&~z{Way5N!#ZAmN&T)Xci9 z4A2a66%SAkSJz&nVgPg`YUS6vixA#%$xTRGr#?eU1L6$Skfmm6gbNJ=3*~kGGa((j zVv4dfY+u$@S@?V=YOMt#h;xV@j)_eYi~YiVgX5fwU<-@Eb-FM0VL z$7d+7J=eZ(=DTFz`O=*?j+Z9PNM?E@zC|VW)=bLK;PsiF6={&-g}v{Zb|2deo4Tx| z&cT@etn(SiE@!pg64_^U_`TLlGmnbD`)_LARcs;fxyX8ZAS{AHdwkVXau4}TG4^|N@c1dT>v%KfS6t!4vOH*4# zsOgF8dHYhE$>tk%98Dem@*Y5mGsSwa)I1XF`yezalnR+k3-6h*P zNW{0>x=04lRJPedY!4jiRcl?sy+nAIY@y_L@bZ^g_(1>XX?E zhuFV&MEo^V%{s}=e5q*A`3G9k)G~{US=ZvouqNg=J5V?^BycWU!-*})snaI;SHFve zJhMygZx~zvE;AXk9TtbpE5H5jK6PDS|3|4~71!gD!KUk&_k^{ZM5>5oe&V?QD@VdH zbCDzKpcE*l72Y&NwqR11w}lEr)LP0}}CA*AZs*@J}wheCOHK*o@}C z^v`wHZ+oe6#I-JD#W^z&EQS_}@cw;2# z-RIw{*V3o(#__mcC$~o~sRB;dAHCU3>HG!GP{XGT3G3;^E8~ zKW19`3f1c0+uk4(SXXkojg$61i#|HOs{@%q0=Lo0K~nJ zro$!{PJ?w}uw{2+U{V@N#8f}+*t;+-i;}`PXUa>I-eTbT?xBl7WK3={=)~$23^;Jx z62bz*hquNHe~DigV~9*$=-K+@b<&0g?NZ@*uX`2a|7HH6&J8WlM+1SNB{|9$%rM-D zYT2&Vv~8WP5rd!ccd3_!5$i;k$LT`mD*C+}3LPQPxPP58>t;N$h^_R8r1)4K%}dDObI!9oJF zY%~>bFUNwh1xy-SFZI-vI!H*GEZ_}?8_Ay`-fLtfxs1DPjdj<{(pIC7gyzce;{=3 zdw1#R6qA}^X{oCaPp<|HXpqi8j?r}hv*pfG!jzfW6fu+AH|-9`2khTx`~{`gxNT<8 zmWJ<)V{Wz$!bsoDqgOgyLEJWdItH{izkP;S)h5c5{669Xv|CkBqW4njM7S)prrzEy zW`5>DBk$$Jej7akFwN+1dgp%LXp!qWyH(e(iv&um0L2KMKCpe61_ky4&xb zU&&lfS$lhMYs-6a&$^+lFFRf+_8qFlri4=+)vS?t=v;m~j)7aUc1gT(_ZkAUua4bv zjgFZ##kGWr)#S_1J5$Z{S@aS#mLJZdZX6f<(w)5PMy z2Hl4a%J#>JZU_B}M|}DB_5wFgdai6{jCrLf`@S>^2e26s^K_p;E(0cQL?_hNou?=X zFks-}(>jZ#E8fh=UJycP?bLehyIf-0zyWfKY~uTMrD+akW{!FhVJ8qw)q&@aR7#rE zreMUvvIXk`{q#B?P<&G`Mi)y-L;dY%L%5Z5k=HW(;Ev1E0|acTgoGofWS6czrsZB? zF%!$n6H7XWawvUtY*`m3LFQsND276;c#apB=NO)_aZn^}lE)mRuVkPh>|0^f2mm3L z&V-Z7bem8=5-6nrAqYK~9sl>A>l4Wa@0aRYZA!A6U5912j}Nq4^);BeVazERX|R#R4VZWQ5XrzfnO2$^zy633`BbINa_w_>-ie;d@R& znYAX-O->C(PhmP-x90CtyM7dmK@DY)`c;0cVqr2M;``ApgKo-E>%nTl zW#JoQ!*B8m9N9g018SU6MNewCD=-)A@7!{0_PZa!X!4?4<1!LqL^n0$qQ7CLj#F^5 za>Y1C97mRr{B{%u=GNbENg${8OKpFxUD`0L_~Y}}E1(X^iTkR}t2;y*ckJE`l<7Lh zy`D8yF@@_H^3cDewXYDX9ggr`&ZEqsvWf`7mAbfgb*dlf?#IDm68tF&hi{7N*#I*R z^|!d_Rro{!o$6To99|V@;J{&Icvl+SuOI0^@rG~VH6_9f6(G7O>@(I0_w9fg zG1JF*h60jocyQ+w2i9(iM~%19ybi(g*tgu9-*{}4CP42Zh z!Edgu4+gM0EI0EciWj!z-UEk)4CyzquxOi{eBm=h#9l)wtzOdNQ56e)b`($HO1$lR ze~YqhRU1fVEe~miZEe(;>aO{o>iLaM(o&>C40RF5vm`wsr8&b~exRQGX_6RWI2?Pn}~r40P?xJ=P6T-)0mc>CZ}(D4w`ny8o<`@O#x zvuvi`_FV3mJZ}hud znNIng@`!y9fXf!M9E|ITSHWy({1$Lco{;&`AnzT$~-zOpsIAI&pds@>O zHPAXDacn>(0j>`~6pEb((ZCbsP49i)8s+BVdk%#7P>PekAQn8ux4yTcE-m(-i))8T z96+!265{0a5DvrNlai9Ms8gag7Z>09=z~YuLV?-f7Wy&)2~43?i7lb-;wimQ4sF;d z!hq%Ty-HYb+i`j&ABUdUc7(VXMvp2gi)LCcv#(MM3Pto*maby93M zWuDp$g>O^NxwgX7&0=mAGZ0P4W$=?ADUMfF8^1JtH}7@51TE?7#EbljID(TfNLPZ$ViH@eGoqFg;&mv738J z^S-CkD)2Oc7#pzedvBYzqhZ*ffmW zGvt@WK2An}!|=Otrv3}Gjdr<@YRt>rK7$B#(D&EjKuUOlt zUr6pJx;dnk-&1}IX9m0+pc$8*I0eFKHU>90YlD}Gl&&PfAP3IS#P(^~U{PcG9LJFO z@EQNcWZhkPLehB(I3_@vvif6gVs%8*!CPnk=YxdV&76|NaFcq1%+^}a{!b-zgUic4 zXCY=+pOK|=>U-;VO!BA&rX6FSa3X1>*)Mc1Xge_vt!d_mq)^@L6O)V3D?p4uiY7UP zj~rM9LF&9Ul{!0*CENNeXbU{w2#+9FN4971-jkFph_hF|K z465NmJQgA9Y@b=@-cwiK4g7-|Qn#yvb;IWb@wJG$pY2l)DizFH&Fy|I z)dJh)vjO9d#A9zQ!L)R-|MS{`0=0ZX9QVo5i(B!4-cBo+%Hx>l1<;o*r)4c z!lLc4NnN9(#rK3z@HQX?Yr5r+BPBBwzY9DK6QIgb-#5Dlz)ES^8{JkyH1aF0(r_sH zo<)%FOLF!H8SqaI6V3E`zp~yuAr3S?a#Ygq-T)q$yb-?`#6Izh2BhPFc1xDwn(uJ< zO(AjjQ$tj>TogGW$?c?r7uNP8iY&BS0wyCZ&$zz<*8x<|S>mw|1(0qf&1wft$JXk* zuDu}1l2y2tXD(ey(#nq*g2SP#_XCn2zDZLx9VjP-t2l+NaJUF4gWp|N5v0d%0qK!U zC{lmz;c8Xa5}A64M1DNEm2!j%L-eh`;|suqxq zkpBhPkspT6V%vo?diP-rxWQ-jm@TcN+3SVDWRklS6SY>rminA*EH-hz(p(~@Vz{oH zDVL#I&_*ZmY zya#Rn5m;3@;JI=tU-B@!v;I!_hT7i;4-mk@eJMY8X!WC*=&N(^3P;4NPag=;Ak*+u zg0Kv<7v_vh_i0=h0p~QJ%HBsv{Wh>3-^E`xP)e~*9N_Z|7(c?*NY2gp$EdZJX`l=S zni9aWGQRn9Q-B5A=&?b)_d$f zOsNxI=h}>9-Llzgad)BQ{I^$ULs z5SM{ej~vLM#r!W0s7G$SUVvgKH=drEAEl1icq+?k(#KD_mdI&edYtYzoaE}f$`t9e z*_@|{?sXP0Df_s~!Nyu)YyU_I;h@gBb(y+?b04tga3q#hk=U|Z=*sx z!%Z06Ii&g(Qa~^V5O81Y%5H+Ws1L25QfG;#y7gGY(o8Qo67S{JxXF{2JE4&Q*>t}f z4*$_LW*%LlHtPP*MXt}d=@!s-Vb_ISA!!(_ePqC?tP#t;X=at_e)e|#Q+QD(AwHXb z@QUBCec{{qJN*Ld9M~CqeJaz;_*1Fx#)sOnJ)Tpk#io!Z93LnpsFbojo*lSb4qm>P zkVhQUux8p=k0Zy7FOwEx{DZLi-@bO{lLheOS5>;+s1$|ui9VIfB@VSF_t0p)h9M&) zEMeTVylCy{sjQrt%K=UUB{^i}LYP9@2ql=Xa=zV7J6D9sjj>HCajntiC*@;^F;NO} zw(PmXnu_guxwXliOVWMW{AaXVR^+(@*_kAYZXyccY znXJa{qxpl?pngVt%T0zO7D0j6-HPj+&^-pM_{e((g}A}c^;CHZgA(_QUh~t{6Ui>2 z>K%kxh3SzAPsiHK_L;puf(T%e?yb!02eHvB?-%=QK^_zt5P1R+>=9{cX@;YI1jX%f zNZylZ0MQQqY_}QDOwYf7Cm-mZpFg--Swl>~SJV5S`Y-fB{d!<0#|1VSnbOW__kwtP zzfpIKAvu8q29%s-l_4_eN`;0a&v~ZvN@RC1d8VEh%dSizu64ZTSy#;a#a*F>sakwr z2$G@n@)rn20PaS9j1Wk=#P@QF4d0Mt0V7G?{cbd_oHN`;x|&~L?uEZSA*0TPRYCJ`_5%NPOP=JM94Y#98A@6ui7m8 zurc|mCUd6I6`FNmDgsAe>AqTAPmp6=)2_GFA{iOk{f!OCl42Qt5=H)w_%GUWH8;~M zM?=r|_wTEVbu{FR@D;F0F~=!xv4Cqh67tcfqdmeb_!TXygQ$zHgEfzxleA!GD*}RC z+n&s>JmmK+Sr>cV(UWSvUuABk*r(ANt_H6ESm4LpnJSNjFJxj@9x<@`#MThj z%s!HH_SsT?_x6UN4%Wnua5nj>A$L4op%-NC%BI`%L`Qfq;3K; zQ(~_irjsz_-8xO->kO(7sM#GZ2lQV(i1lCIKRH3nEe*+|iZiB>~oaJTlcP-_}5Hip5 z@Xz4t|CfPL{e8&`t|+n`VBO4vT2G6huY4dy=Jo>kpf7SeZI(AO3Ymyp>QC)l5Wy?+ zMV8J|#0l2~eKdQ|$@Hw621NL4*0F;mq6?zMFR9ZG(WtNuu7)r}pZnefNT%sDpHOtv zdum?&sXX=s)1Y>>ZiSJ1b?gT3Ti}Ho6y}(S*m!y}!J`gGKuu>0BV=F&Lp=ecgjY*z zP^Sk6t&X_dy5aDA-E+TYB<%6#3s{Vb`{@0FrR?+LSciM7fxIpqE3?pHZoas(i_2Bc~l;5-k!vAUNn+vvYa3#YAFE@VJMStG9=Av&g zdPLq!j|X*lD&ym7Z*`av|CA!1)6|RJ!T94HF@fG$My_|J>?e~FiLM08uAIcAeEv3D zmx3JNzguu)Bcx)z6u!&+3fmaLit|y-KjQQ>gE;A^LHZ~hKR)lGExWQetOS`X9`;Z7*=GlOH!_58{;n%GPhbyARq9YhT}w?R&t*CNIC{=Kk}M^>$G@ z?H>TSsAM+=2&~Qk!V07)3f8G5wJ0Pfd;`3b6dqYzWxLw-vnPD!h|YX<_LL6&^GNv$ z5r4EQ@j5zQfmuin&TWV5xC17EHxX*w<&q{s+QxMNY#v6o0J9@~BXWMAWzNvPMq$Mw0^l~_Jew_$kC^O0 zHu%w?0S=-snb@?EW>EcxbMwF^SEa?!#u1U4YzFVuX_@puwAYuT<6`fsuq@dwnuK!7 z@i|EIA&^QjSJ*6YtRS|Q6wCJ=_M0uUC^YijLQi~b?srIo97n!yGJWJNKk!e1+V}Dv zfW9itieND1PzJN9SN3~)O|d+PW#7S?2cT0SXQJ+WEl_&$n3{gFq@7cqv^UhEfjUZD z6Dm%kQva?+YQ+k6&*oi3F_Z*K( zOh#lvo_wS8qKvg0R$xXsx-HnS*5GmFi@#8k*?T44rWNw$(P@V%#A)2OZ2F;2+qKd7 z=<9*A3#>PhPI(g(p0gYYx}jBN&y8ZI%6TcqHASu^hNvFVR4Dup&4fOpV3v&66*mKmwIt#+1;5>A&elhXta@#hH z8JkV)G3QwYglR#*6a}mxFyfNrj?5)YbhJ3dyBrbba~3)$wdF4k!vPpp=ydC51^r9d z{3;mc1d3}Ga5n8y_1t|W@#1V3b;496DV{w-vsy3N0wbBR-G^eBrNpdivN`@f?#6y*r8<)l4!3w*(=r6YZCNqlSyST77AVk1a~V?pc*e_<0Ag|bURy*JrmSE(a;_|cb;E$`MuROa;zQ&xiN6x z-sRv!FmsdR^CBZ7v#@f2LjjHN00Y8G+Ze}Lc%b4I+AVs=UNBlm78j*N`iSud&-BlCS;ZlFs?kCdA9TSrG&rHnl5uK}E;aso3pK?n#^z+ia zid)b^z}u^_HZ^mtv<%4v<97$mbIhvqF&<_hRR+8S=!q4P5iL;`@lr1~jBee&BE~WF zqd*PaD1}r&6H+{)bZ;Ri>`joFdhATW>69gYoJHq_?Olrc`{ZN?xnDvjT(-cq%>t*( z%;COXvn=GGnAdn&L;48Bqd0h=e93&&#bbAct)!a5%o=v&D%_h6B{^=t`KDvK3W^hm zhTA##o8`w7Sy7wyP>1E%%gNT=mgJ8}XINNVMQjLADe$MI^EIrGUKins^Y}g zIUxK6Ec-E}nN44E9Ll9jcR!}M2O%y6Fqi(CGqY+x9bES0=YKCDHIY15T#32wPf8qA z+8VOm8E!ZjUYDzNd;*{79Vy?o!IF3Lt>I|oA;PnJr-uAq={%Qh<8cj{lszlHO0nUUO%@sBlaQqcDNb+MX~<@=W`QlA@-Vi zR-J;pJw1B@w%{n|x1i}M;VN<=&^W{z`B%TUBFO=Z% z_}Alh(mZz*1R!q+jo0yqaF*W@Jtimlzls)nhr~ zJQpnSoiM_v^u`@+5Mvc_HGGO?PrqOQA+z`LK{E<>4qj}*DtWH743aF&sAcnSMg08l z$WYH;b2BrA?B)QyTvCvicZD3UmrTt*d!0#|KI9z8eKD*cEz>r9mQ3h0H!{~m?D$BP zW-KpSXfz8cs{1Y&rKFw~xWN^EhKv(xYiki>Gk(n#4OF=2b-#&zp~7ZcMfH@2JVFCQaXv;5x0+WU<(ZA?JLjdJ`ED_5MYIFY7JgR&SJ1EbayQ<>G;fiIHv!Fmm>Z(*Q@{&hT#NCPn*vj z6#0NeG`V$4;@86M<6@7UZ3&Zdox z4c6(PR;x+kOfyt$qNBFMrFRi? zV}n@}wDp$0PxrGI^90)6m2il(%1`1)Z#)G=j^-K5S+APj zY{IO_EMivt1~2Zs!{&N9=$)pp60^_XZt)|=#+!8wNl+mWe-{aVX{qTsTgdYkxU8r- zy~ow)v2F?EXYqOX#YQh3{!U9(Dh%84jeMkOv!^g0)C2BHgfui^3Ur*0ClF+=vE@uk z@e;atTG6en5FRm*amtEdP1O$6FQ9qA8XR0mfjiAy&n+1H#Ze42WPTZRCC9`FexvK; zkU1!i@FQ1PZ!vJk>N=2y+bRd`-N4}L1v{+&ooqMQis0}-bb^Tr=NWmegIi}uPjrf2OW5N4siHp^WY z6J`{3E@y)!3AsXFe=AXvn9GWK3CJPx{z&VHe5X6V)zve>-C_+KmIuEe%6@M#zA^vU z`NQhRnUYN{a^qj?k9c`LS&|rvijacR#^SBWY#HD15>9TZ_1qAKC9$3uR}Wycz+_b~&Hk-=oJ6u>2)HJ;)rSjqi-8dY z^NrM_UN$zAmb+ay_1+*l^rBKuWW7OluRmE=9Npa9^!PrRw6+EtHV~ka-3R3EMMFXk zCoR8 z*i3{3K*$RUz3?h%6Uoq-t6yx`&BGN~J|=LV3Ky@Mk2POa=l#9DOV0cPBQ97tAO(w4 zP2KZp?g^zaP|(30(mtTC90TUu^atvod=|D?Jy8~U6R32RkYl27urUDb7OWtaXe0qo zXVx!wlR;h!V&(hJ5o8?mzT7c$$EI8wJ$dq0Tj#H1LWq$v3luMAA>$iTC((9D4Hega zXF#Q^Mc1iuZ`Wt*aF=hao3thTGBHcq-mh&mZKu;tpW!r{C$UI1JUm#G&qdx-SBUE1 zH4XB5LQDRaJJ4QlEmmkvelq7Go{6_y`|_E8>?J7-e>C}kRqj(Z-e=qlAKKb z4GRkeA^r_GqVUI_mr5BsLRUdn_=16-j2FB8FSb?pg@F1=jNRqso5`2Et}%Ri>+L(? za-q%r5)Lt++kH$Qp~H})(}B+~{$JD_%B>hCjHAbZd*q^`K^PmQR%i20PmF&kPIG4N z-LZI@+{NA!7+LUMjlGc4oooDt8xq36cmqmB*o*}>aDh@0aMA@-1NXE(;Ke^vjT66y zSZV^116GaqKarcoUv6Y^1v!n{o7im;4l#6aMj#r`KN< zK?j4YGZ!0nLw`m%rc1uKroh-i8}wVL{ho&l;`_Zy;GFugnSyf`if!=r0PzC`i}?7q z(PJBW`MCucE5Fr^M0-9eMxjELjuvI#rTs|<>&1D($`P8-=!SvgWq!QMmR_YIDcvaL zqruq8mlws_MYXA2Z7#^OV?_GJu9EA>Hj|!PphiSZHT`Au+Bzgo8JoRkxkI_)vd}1o z{QYqOUAt9Y^aMx-5lS1}BR;d4-ct!z5eRamjN9H)rRC?D#v(@T_bfNTx+&8`Co~q$0!i(RA5AC$6FJ zS|s`nFNNvlQdPWEJy2)Jp--9T?b&VQm4mZ?g8rej)P_x3!WsexZS3uj5tI)QA@Er7x5LmIvWu#pNFDDwS$)$W;xFG|p7{GBL~Fum09ZYs`ZvNAtHPGy*Zk#b zLy2Ol@vDVL8my8w_RwU>auNb~3*)Zm} zTvzqy*BkQd#R@~TjiVgIE$>HLXP+&IOh1oPy`I=}7bB8NZ-nOqwYi0sYz z)7p_AjUK)PvS1;`rilmol$@1Fh<)xT+M>m?0x>9$<0c*ijhmoIjlBHA@$guU zbFRx4@=@lLb0Oy1E$dOrB#Pf9jioKHWCJ?{JT&-N0nS2xKj27%p8M5xM$7K4ZkgQc zN3Ez;f1gLVDE+_ouKbL7Z&Ic08{SGuL(B&vX9+&-FZAH9u5C=llJ9-s@}0 zT$mCoT*oP!E){3-CbBtki`+QZIW`&{YTK<$($I4zTK1;M*J*q{_6AJrC8g-H`F>4@ z1Ji_jRrnz*h4?Zq$yjBWMrcf2^@mgsxwyS~&orup?Z@~^W?$vh!swFf8Gh7${AO!6 zsIUy)I4h1wy-PEmlrp+63Bqw}%#S(kN73MM3}xGz+#x!7Z$K~vmDIs4uM)29bxwqk zs;ukp+zDUxP>YRgS~~8ra`UWt!}62Ei~L$I^+fegb4TW>{_htg#61eFBrMnV70zC4 z`*hg%5x?n5TAHW1nG+uTX*C6Sh#1nz= zJSR6UNQ4FRPTOxViiyEn9lsf&;QtvOB?b#+#y`=dw#_LSPUXhEgIeUfO&1iCer9mT zPRzf_S&$J^pfNHc&aWcjjW+quZ@AbRL=cdqU+2ZmAx&d12(|z@03TeT;#k-0>np02 z9#E1|To|+W-BE|z=13p1|%Lhk{@RnfRQ@>pQBz&2V)Plqj zPp2RwJH=9kRDh_QVGOBs&2nP+P?4P*%_GU>*0K8npx+}xKy|y;^!?N7ybof%oILuD zXA=y$Lq^z(5-_zSkJyk~Dc(aLy%;w$SMz13n=pJs3{ulBl-dhYdQ0=wV;so@&65SC;0c1t09@nYZQ&^R+;vVl{h4>P z^7;G3>P!c>%3vQO2jyvM_t1j=a( z_~KY*x!TF7`&Z@#+t&_!FgYhOmBdYTc*@z7>0~^^S`{LqtR?5I+x~@DLD7vB=L9lM z+@4b(zuKb(!WU64{WGNXx(gEnX!IF$Axww<7*=)P%=>=V^Hjb~lvOoHj8(V#Oh+*`gdP>5PPeT*r0QrJLKRg4BTz}fIEXds|TcS^G1EP#z06dL7@yEPzzW{xb@=h zj_;h7-RNCUpOWCi!jBkHO}K$ogB(Y?bUV8ms21-R9`0NW4Y_2?cTg=&NaM!InqaHj zl(E0}mK4grE-m?Dd?bkl0Dzy`*fSRu>34t#${jaaJlBE#Rl1+S61Ge(Mib>*PWFQR zK3GtZ3}Qj2AF6#tg&PlIj+jNP9Q+N<0XlZ^$y@m-`q??z6UqC%3SNz5Q@k5#SqE1p zwSBkc1|FB~1E({tW_gYG1!Mw_+*UJUAuVQoWXW!r2`p3Cd8tUS(Uf>B6H^`n3D7Hh z*1sF=MPHu^6yPyF{sVhE1nx)rRjQ#U=c(Vq=sCZ(Chg}!yZAxqSzVatC@yMua$@~R za)GccW2{oJNp+jFvc@l*G@*8vo?SA;L;EidAFA^wPvP~;z}hAPUg*#-lZ@MZvq`m# z6XOMX_ss9L z)o15GuopntMp#2g0KLe9N-#wL<_cqIK$fCNkHczq27h|^;Rc~-ohzTps5tS}vFt}j zr6}lf^qQ|~d&}fNVTTMSBd~x2(S`l+3}%8j78ds*Tu^&e(I{9hj`ryv9wOBeCh7w% zcb`4|6)G}1&oeff#HIO^%gbC<$zt6!K2RyKTcPfZWJk`LHFX>4!O6uHCE>{05M6?@ zhLXg`qk2GK5xp^kQ>FI1f_Us^;~y6q&VKKg<9j>jXP71LQ`1;IsEzpy(ceCx< z^`5A$kBkvcF#|&zPC!JEAWSuI9!42PrV~qO!9AM(Yl3I9nKJNKy(;Y5ch17_<864Q zf`1ArWt;wstr6@PLTHl#$FDr*tp}uN@zC>-)Z$xp_An z-ZS>yvZz1mJ5zAzflHqca|@W} zq8387(HW?%1|h}$CcjmDUIKl7hsp9kL(nqRT{Z=MH}v1kf1(0qd0az~g0HboQLzr( z5x7HedX0F!03LABNO-&%M^oU;C5&@YexY?~bzsub7!X?>V$;xY>vP&EKz3ROe{D{Qfgq7S@04c24Xp^Tkbnat?M11!G4C26DSCoWclui z3LdQ!9x2(iXfi5=ZPHACIa&kU5lTeZw}ycAG0U5_KK?{@Z9~AFAj(?E@pEpO)>gAC z!b``UbCV+P)H!KmABt#?FV-t$?R*R7)|38FscZ`0m6vf<$J1BdP*ht;F5iCgjdY4vt#ToT#a)wGqM&^!neQGDXaDh*j92Io@eE?%U zM8ve7~n+jAQOvsjeLTzLN69b(|GPRz&~uJhKgZr)Og6qQI5p+$XJ6x z{n$|B4UTzi`8qNHudn|M(-@*`{Y5~jeFVH#VnT67Y%D5Jx9n3p8P8vopN8Ls#ffqO zzm{1@_<=)W6s;TlpdvwE9`O*%0(1WXH|yT7do@j!wo8X(ssMlVvI6H4oo_1t|+{D(PLLMAil8poivItT3;uoqox=F^%bL(2X7i zV^b7>q}9TREs4ddo1dovLyce<@-Un};a?6+0BpC&)CLRk^8K>zC#?+IQjC2ih-dR% zK|ZSUUFe2j`9lOC?j7vLK|&jawiH`;;(Dl>acyBbIe=0jSBKOxy4P?f(<2b|I;I1! z^Q+R~HO*oaA5 zLsj2m8#{LUMUd@gyr;oR`_+C z6~seD+Tp>oNCM#JS4T>xJwi%q#pq?s%@bOUmgo-?UWvAMjkw+T#T&{E+~(SY!u^ z5c=huwn6!!2g#+YflvcY5@tDpYKRR4Lw z@&E(>1r23s#1GRwRGlaSF|I`3#n8M5N>qk#Ms#swu^b=;6Le1y@UR=KI^Q7+^#RB^ zf_q`(tR!O_PQBTbr9^?vA}%S`qy#+AuxlGVWQdyg@kb)#*n?0??}s`yB4P z_Xe0iy#!3@Q5=7hR58Fw!B2F(!tlnkF$%*KLe6vsXBBk^Dv86#j_r_=XkWh=d|$-d zzba=bxeBbtks?t(vN`DEIZDW`l6Rtv>Ef;!Y@gH4TGT7<^xf7j(6aAku>{W$- zxZ_#!Q3$^-5cB+sp-Gvzq9ehVqb6d%`s@{!|-6Yq|A2?gn9P}q0k8vLUp=K>A$gT@e0(ZGRW6^-E# zT5nRY5$^&#Gx&PhD$6~6Eh-R-k_uoiz4L>sLu_wX^_fag-cu+k$0i{e47XuPUB^~B zo0nK5JUmzc|8UEd&6hJoRn_A=@RF+_9}H{+ArLPi9ImrBhggLpw1Iy`urGVIH^*F* z{Pb(yVn`~#x9+rS_HrFSvmm34vx^JUtOVy4@7xg$O2Xl~v5*drxK7^`Zg~TWal4;vOMLgn|ot}1HXvT5-n+bpDm%(e8urwV*rdC;txOeqr%%u zKF{ubcALVl@{dWmLB*>j%ohThu%O{m=LGg|&Hk2B$Psgyv8ML>9H|SC@m9`ArJ!<0 z1QkIkTyw>KVk3>)9ZF8Wg8!frd6;@ZNWUy|Dz23yCbk@`j&wI;z2-gEZPJ0R z1<#R8j4*0i8>J|;9Fn(r!)LPh0V=Y~3gJl9l|dPTBw-q?pN93^Wrg2%{1EHsoo*F^ zG@h|fWWzy{a8_M*qGT+c&9za~u;o`SNcO8|e*K_&+?VY_5~^)M>6Mj;Xa!xt24v}4 z(!El%0^jHqAsYhw9FMR73ywrfE?|sVIy7(?FKVLx z7NJL(^v9`Rw2&%!y9^8h_D3)9=0@wt&|&CN@$>l+Cxy`(vF}%8;xY5b{;Ntla+Wat zRvC%EoEN6z9)XMcVOuDqx{@PD99L4ecnawsZ5eLd@$PG>QShP*;!b26#lY5#X{IMv z3l(}y$cb3~X<%~SwlZuK-ofVcH;_akulSTC{+0C3i4p_Q4yhE<-Uk83`@kvkY-euF70(3c>NBwBRF+d(bG=LhjX8rz-k%3 z|9o)CpDkU5-5KkQm-5ShINksMm(b+>-+E3_i{)>>Tus4`)qP&{`aNqzgea8%b-z}& XR$o}44D6pHAH-_U*Jh7)JO1!rZU;uw literal 0 HcmV?d00001 diff --git a/_downloads/f76cc5a46e5368e2c779868abc49e497/someones_epi.nii.gz b/_downloads/f76cc5a46e5368e2c779868abc49e497/someones_epi.nii.gz new file mode 100644 index 0000000000000000000000000000000000000000..c08f9ec66095bc7f13b956a86f8c391fac9bcd7e GIT binary patch literal 93766 zcmV(xK0k<6T8w7`}nv&&^HyQ*B+-F2I8HB@!qhP!4WRsGh? z{F{FhQf7v8ot=B1ohKCExA%8^{eOJ)|LOQYKHBopo{tJY`XB%P`F|Vz&ySWby}{b| z(MNT4|Mw&I@Bimx;9$YCJA3~%|2JsNNB?ulM7N2>%^XB%HBXmA?L-N}5m$oFV&dx5XuI~ltM~jo<;^UV?Msaa* z38~dBhTdaU*@aozVzo>rRxBB%+H(@wu%E}2NJUC5BCjlMBSJ^mp0P51ITT>r%B0-GeBR;Q zikyS@r*%TH!7f2i^uzs@pa=lqbiGa|wmh8JP?cGWk+s&Ou8M=w5Vt068$o!gs3?Ug zRNsI6Xqw+A7oQ@p?KDSa{ow8_k_4 z9Mk&whbKlh9*b;iY3u0fY(uO2&6^U-Z;}sZuUxUF02?EN;A_>1r2hqRsyKZDy_VmfF|1X zlCYbE?V+l4AgHi$Z3Akhaa~^C3Dl9C)rBWJwrAxQGC}hLz1SwSYn2*mH;G7MaReqw zH@Sz((`!vug^LS54|z@%WK}iaEKjPsd8I5PyMlE8sY>XVTRb4ZAyT?~=oEpH-^1vp zc9Z!A(~w5*7i(_M)#n#v9O~Sgxw~~=YI;`A6|Y)5tkK;wnR!%VcQ0Mg(9D ziUycxwVnYZXj_|{k-qNc>B3{p8xoSU3yvFoen0qFr)Nn`{2o@Hh}t6}(PV6957PoL zRhC8Dm}!($kdTp2kL$vQ35N|ZnI)P*D~F-9BC=8| z5AMuMJ7-tQc-?Z##HgN1Ru7Jj7)JiASBoutE$~ysGCOQy5x8!PKA@)bDvV%FdQttx z!eq7u@LTCrZ8*Z|b3_LtjyGR_E>#IsJhkFizxyma5j08h`XP;hh2a`a(aR|X2e%aG znq0Q%fD$Y14^T}L!)Adm@Jl{NDUgVjRPa}${hooDpqLXi_TorNm%pE!R
Nwq_x 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�M@|3Ewb>fcXa8Pm(svdHZbxcq== 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 literal 0 HcmV?d00001 diff --git a/_images/branch_dropdown.png b/_images/branch_dropdown.png new file mode 100644 index 0000000000000000000000000000000000000000..1bb7a577732c91ee6aa31de8f81045b5622126b2 GIT binary patch literal 16311 zcmY+LWmr|+^Y;M}4&5o;ol19icQ+#4hpt0+cL}IScO5{GPDQ0VrMv6dc>n${o)>U& z9rj*(owaAyn)%FkqSaJn(U6IeVPIg;4b9FGh%= z&Ue3i?|Sd5oT=s>!a}#RuHeguyJ_ zr%&ZC_KtNTNV!#Woc5Pkm>gf)rK^TW-b`%T3@M_Wlg+>oW~XY>r;f3s3X9@Al`Hh5 z&iso&m4;=JUdmn+qAF3D*7$%WvNG;+kSA(|^=* zonu2g&8mLXIa3IAN#Yx^G7ok)kW-yea=K}cd>ueHgHyBat)sr?lZa!x{CnwGdLFKZ z1DzC=7&Qk?P7PBU-aM;TO)Nr)nDcGDn<#Y!!kbh-E>D^d9Uc}^b>eow9oexA)W@DyeowcL4v~TY?EwF z)9zK#vAjCDnYND~<+6#+3k*+uE&_g)@4ra)o=veKLbvho$N~j`5xf)gevf>G~N|bKw(L|B7MpJ zGG_hC$Qb9>h-4{DZQmWS&=^x&kkrtap`Ec-#Ba#fw%GNW&HhE|L{iKzaozV>!8-M> z<`k>;u~y^uwo+p*P=$CpB=gSs8}w278#p!^Z~!D1Iem8+7!;hBA6S^2JVF>43K)4Q zaV;?HVLoCWuJqL)x!o{7y?m$@Cg2WIuT{tBx8Vy4klMO^_wxA{vo|OaqyT1mOf31jpFqiv?DerZ(X!qRg zyuzmaRVzA0(wP}9CYY)SWQ7eUZRzNcOeGBwrIi-LQiI2ZmHw6}HZ}r@12b^)aXkrK zv;fyJz{QAB%2Kdd!{P7c%LVg#TSe9Bh|(orApac8f|XY zj2c=kPV#RD3<~~@H!MLxXT8oOo6J|XUQN3m#T!ahu2vk1%Upe2M+2wHD*3WzArDe7 zYhyXAK?kN`5qz>#{jD5#jzeCh_}_|BAi!G`1b?oyV!$3*sUk-7My8I8id%{s-i9mRugkk*sSI5Nrm!>2hFJCHS

CgDNcy+&Ya(k9lN=hb;Idgr@uX&#;=1~;I7H)Rf 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 z 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�nFit!F^tA|}am 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 literal 0 HcmV?d00001 diff --git a/_images/neuro_radio_conventions-2_00.png b/_images/neuro_radio_conventions-2_00.png new file mode 100644 index 0000000000000000000000000000000000000000..93a56cc54cfaff980ba0986586ac0283f034df04 GIT binary patch literal 45578 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≺48wcGA{D$UR3 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 XR$o}44D6pHAH-_U*Jh7)JO1!rZU;uw literal 0 HcmV?d00001 diff --git a/_images/neuro_radio_conventions-2_01.png b/_images/neuro_radio_conventions-2_01.png new file mode 100644 index 0000000000000000000000000000000000000000..e7ddf823b323ab17d14ac0a8b2de85ac31d71f8a GIT binary patch literal 58088 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 literal 0 HcmV?d00001 diff --git a/_images/pull_button.png b/_images/pull_button.png new file mode 100644 index 0000000000000000000000000000000000000000..e5031681b97bcc3b323a01653153c8d6bcfb5507 GIT binary patch literal 12893 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 I#f$>~7cL{PD*ylh literal 0 HcmV?d00001 diff --git a/_images/rorden_radio_neuro.jpg b/_images/rorden_radio_neuro.jpg new file mode 100644 index 0000000000000000000000000000000000000000..09bc5fdf4cc3356f329f2e0c1401a72a2a8c8f0b GIT binary patch literal 102453 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
YO(tgYR;+=M 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�$27z2Jp8eG*`ol}@q9Ta5Sa1CJ@JdX>xEZpjk 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.3.0``. + +Bug fixes +--------- +* Detect ``IndexedGzipFile`` as compressed file type (pr/925) (PM, reviewed by + CM) +* Correctly cast ``nan`` when testing ``array_to_file``, fixing ARM64 builds + (pr/862) (CM, reviewed by MB) + + +3.1.0 (Monday 20 April 2020) +============================ + +New feature release in the 3.1.x series. + +New features +------------ +* Conformation function (``processing.conform``) and CLI tool + (``nib-conform``) to apply shape, orientation and zooms (pr/853) (Jakub + Kaczmarzyk, reviewed by CM, YOH) +* Affine rescaling function (``affines.rescale_affine``) to update + dimensions and voxel sizes (pr/853) (CM, reviewed by Jakub Kaczmarzyk) + +Bug fixes +--------- +* Delay import of h5py until needed (pr/889) (YOH, reviewed by CM) + +Maintenance +----------- +* Fix typo in documentation (pr/893) (Zvi Baratz, reviewed by CM) +* Tests converted from nose to pytest (pr/865 + many sub-PRs) + (Dorota Jarecka, Krzyzstof Gorgolewski, Roberto Guidotti, Anibal Solon, + and Or Duek) + +API changes and deprecations +---------------------------- +* ``kw_only_meth``/``kw_only_func`` decorators are deprecated (pr/848) + (RM, reviewed by CM) + + +2.5.2 (Wednesday 8 April 2020) +============================== + +Bug-fix release in the 2.5.x series. This is an extended-support series, +providing bug fixes for Python 2.7 and 3.4. + +This and all future releases in the 2.5.x series will be incompatible with +Python 3.9. The last compatible series of numpy and scipy are 1.16.x and +1.2.x, respectively. + +If you are able to upgrade to Python 3, it is recommended to upgrade to +NiBabel 3. + +Bug fixes +--------- +* Change strings with invalid escapes to raw strings (pr/827) (EL, reviewed + by CM) +* Re-import externals/netcdf.py from scipy to resolve numpy deprecation + (pr/821) (CM) + +Maintenance +----------- +* Set maximum numpy to 1.16.x, maximum scipy to 1.2.x (pr/901) (CM) + + +3.0.2 (Monday 9 March 2020) +=========================== + +Bug fixes +--------- +* Attempt to find versioneer version when building docs (pr/894) (CM) +* Delay import of h5py until needed (backport of pr/889) (YOH, reviewed by CM) + +Maintenance +----------- +* Fix typo in documentation (backport of pr/893) (Zvi Baratz, reviewed by CM) +* Set minimum matplotlib to 1.5.3 to ensure wheels are available on all + supported Python versions. (backport of pr/887) (CM) +* Remove ``pyproject.toml`` for now. (issue/859) (CM) + + +3.0.1 (Monday 27 January 2020) +============================== + +Bug fixes +--------- +* Test failed by using array method on tuple. (pr/860) (Ben Darwin, reviewed by + CM) +* Validate ``ExpiredDeprecationError``\s, promoted by 3.0 release from + ``DeprecationWarning``\s. (pr/857) (CM) + +Maintenance +----------- +* Remove logic accommodating numpy without float16 types. (pr/866) (CM) +* Accommodate new numpy dtype strings. (pr/858) (CM) + + +3.0.0 (Wednesday 18 December 2019) +================================== + +New features +------------ +* ArrayProxy ``__array__()`` now accepts a ``dtype`` parameter, allowing + ``numpy.array(dataobj, dtype=...)`` calls, as well as casting directly + with a dtype (for example, ``numpy.float32(dataobj)``) to control the + output type. Scale factors (slope, intercept) are applied, but may be + cast to narrower types, to control memory usage. This is now the basis + of ``img.get_fdata()``, which will scale data in single precision if + the output type is ``float32``. (pr/844) (CM, reviewed by Alejandro + de la Vega, Ross Markello) +* GiftiImage method ``agg_data()`` to return usable data arrays (pr/793) + (Hao-Ting Wang, reviewed by CM) +* Accept ``os.PathLike`` objects in place of filenames (pr/610) (Cameron + Riddell, reviewed by MB, CM) +* Function to calculate obliquity of affines (pr/815) (Oscar Esteban, + reviewed by MB) + +Enhancements +------------ +* Improve testing of data scaling in ArrayProxy API (pr/847) (CM, reviewed + by Alejandro de la Vega) +* Document ``SpatialImage.slicer`` interface (pr/846) (CM) +* ``get_fdata(dtype=np.float32)`` will attempt to avoid casting data to + ``np.float64`` when scaling parameters would otherwise promote the data + type unnecessarily. (pr/833) (CM, reviewed by Ross Markello) +* ``ArraySequence`` now supports a large set of Python operators to combine + or update in-place. (pr/811) (MC, reviewed by Serge Koudoro, Philippe Poulin, + CM, MB) +* Warn, rather than fail, on DICOMs with unreadable Siemens CSA tags (pr/818) + (Henry Braun, reviewed by CM) +* Improve clarity of coordinate system tutorial (pr/823) (Egor Panfilov, + reviewed by MB) + +Bug fixes +--------- +* Sliced ``Tractogram``\s no longer ``apply_affine`` to the original + ``Tractogram``'s streamlines. (pr/811) (MC, reviewed by Serge Koudoro, + Philippe Poulin, CM, MB) +* Change strings with invalid escapes to raw strings (pr/827) (EL, reviewed + by CM) +* Re-import externals/netcdf.py from scipy to resolve numpy deprecation + (pr/821) (CM) + +Maintenance +----------- +* Remove replicated metadata for packaged data from MANIFEST.in (pr/845) (CM) +* Support Python >=3.5.1, including Python 3.8.0 (pr/787) (CM) +* Manage versioning with slightly customized Versioneer (pr/786) (CM) +* Reference Nipy Community Code and Nibabel Developer Guidelines in + GitHub community documents (pr/778) (CM, reviewed by MB) + +API changes and deprecations +---------------------------- +* Fully remove deprecated ``checkwarns`` and ``minc`` modules. (pr/852) (CM) +* The ``keep_file_open`` argument to file load operations and ``ArrayProxy``\s + no longer accepts the value ``"auto"``, raising a ``ValueError``. (pr/852) + (CM) +* Deprecate ``ArraySequence.data`` in favor of ``ArraySequence.get_data()``, + which will return a copy. ``ArraySequence.data`` now returns a read-only + view. (pr/811) (MC, reviewed by Serge Koudoro, Philippe Poulin, CM, MB) +* Deprecate ``DataobjImage.get_data()`` API, to be removed in nibabel 5.0 + (pr/794, pr/809) (CM, reviewed by MB) + + +2.5.1 (Monday 23 September 2019) +================================ + +Enhancements +------------ +* Ignore endianness in ``nib-diff`` if values match (pr/799) (YOH, reviewed + by CM) + +Bug fixes +--------- +* Correctly handle Philips DICOMs w/ derived volume (pr/795) (Mathias + Goncalves, reviewed by CM) +* Raise CSA tag limit to 1000, parametrize for future relaxing (pr/798, + backported to 2.5.x in pr/800) (Henry Braun, reviewed by CM, MB) +* Coerce data types to match NIfTI intent codes when writing GIFTI data + arrays (pr/806) (CM, reported by Tom Holroyd) + +Maintenance +----------- +* Require h5py 2.10 for Windows + Python < 3.6 to resolve unexpected dtypes + in Minc2 data (pr/804) (CM, reviewed by YOH) + +API changes and deprecations +---------------------------- +* Deprecate ``nicom.dicomwrappers.Wrapper.get_affine()`` in favor of ``affine`` + property; final removal in nibabel 4.0 (pr/796) (YOH, reviewed by CM) + +2.5.0 (Sunday 4 August 2019) +============================ + +The 2.5.x series is the last with support for either Python 2 or Python 3.4. +Extended support for this series 2.5 will last through December 2020. + +Thanks for the test ECAT file and fix provided by Andrew Crabb. + +Enhancements +------------ +* Add SerializableImage class with to/from_bytes methods (pr/644) (CM, + reviewed by MB) +* Check CIFTI-2 data shape matches shape described by header (pr/774) + (Michiel Cottaar, reviewed by CM) + +Bug fixes +--------- +* Handle stricter numpy casting rules in tests (pr/768) (CM) + reviewed by PM) +* TRK header fields flipped in files written on big-endian systems + (pr/782) (CM, reviewed by YOH, MB) +* Load multiframe ECAT images with Python 3 (CM and Andrew Crabb) + +Maintenance +----------- +* Fix CodeCov paths on Appveyor for more accurate coverage (pr/769) (CM) +* Move to setuptools and reduce use ``nisext`` functions (pr/764) (CM, + reviewed by YOH) +* Better handle test setup/teardown (pr/785) (CM, reviewed by YOH) + +API changes and deprecations +---------------------------- +* Effect threatened warnings and set some deprecation timelines (pr/755) (CM) + * Trackvis methods now default to v2 formats + * ``nibabel.trackvis`` scheduled for removal in nibabel 4.0 + * ``nibabel.minc`` and ``nibabel.MincImage`` will be removed in nibabel 3.0 + +2.4.1 (Monday 27 May 2019) +========================== + +Contributions from Egor Pafilov, Jath Palasubramaniam, Richard Nemec, and +Dave Allured. + +Enhancements +------------ +* Enable ``mmap``, ``keep_file_open`` options when loading any + ``DataobjImage`` (pr/759) (CM, reviewed by PM) + +Bug fixes +--------- +* Ensure loaded GIFTI files expose writable data arrays (pr/750) (CM, + reviewed by PM) +* Safer warning registry manipulation when checking for overflows (pr/753) + (CM, reviewed by MB) +* Correctly write .annot files with duplicate labels (pr/763) (Richard Nemec + with CM) + +Maintenance +----------- +* Fix typo in coordinate systems doc (pr/751) (Egor Panfilov, reviewed by + CM) +* Replace invalid MINC1 test file with fixed file (pr/754) (Dave Allured + with CM) +* Update Sphinx config to support recent Sphinx/numpydoc (pr/749) (CM, + reviewed by PM) +* Pacify ``FutureWarning`` and ``DeprecationWarning`` from h5py, numpy + (pr/760) (CM) +* Accommodate Python 3.8 deprecation of collections.MutableMapping + (pr/762) (Jath Palasubramaniam, reviewed by CM) + +API changes and deprecations +---------------------------- +* Deprecate ``keep_file_open == 'auto'`` (pr/761) (CM, reviewed by PM) + +2.4.0 (Monday 1 April 2019) +============================ + +New features +------------ +* Alternative ``Axis``-based interface for manipulating CIFTI-2 headers + (pr/641) (Michiel Cottaar, reviewed by Demian Wassermann, CM, SG) + +Enhancements +------------ +* Accept TCK files produced by tools with other delimiter/EOF defaults + (pr/720) (Soichi Hayashi, reviewed by CM, MB, MC) +* Allow BrainModels or Parcels to contain a single vertex in CIFTI + (pr/739) (Michiel Cottaar, reviewed by CM) +* Support for ``NIFTI_XFORM_TEMPLATE_OTHER`` xform code (pr/743) (CM) + +Bug fixes +--------- +* Skip refcheck in ArraySequence construction/extension (pr/719) (Ariel + Rokem, reviewed by CM, MC) +* Use safe resizing for ArraySequence extension (pr/724) (CM, reviewed + by MC) +* Fix typo in error message (pr/726) (Jon Haitz Legarreta GorroΓ±o, + reviewed by CM) +* Support DICOM slice sorting in Python 3 (pr/728) (Samir Reddigari, + reviewed by CM) +* Correctly reorient dim_info when reorienting NIfTI images + (Konstantinos Raktivan, CM, reviewed by CM) + +Maintenance +----------- +* Import updates to reduce upstream deprecation warnings (pr/711, + pr/705, pr/738) (EL, YOH, reviewed by CM) +* Delay import of ``nibabel.testing``, ``nose`` and ``mock`` to speed up + import (pr/699) (CM) +* Increase coverage testing, drop coveralls (pr/722, pr/732) (CM) +* Add Zenodo metadata, sorted by commits (pr/732) (CM + others) +* Update author listing and copyrights (pr/742) (MB, reviewed by CM) + +2.3.3 (Wednesday 16 January 2019) +================================= + +Maintenance +----------- +* Restore ``six`` dependency (pr/714) (CM, reviewed by Gael Varoquaux, MB) + +2.3.2 (Wednesday 2 January 2019) +================================ + +Enhancements +------------ +* Enable toggling crosshair with ``Ctrl-x`` in ``OrthoSlicer3D`` viewer (pr/701) + (Miguel Estevan Moreno, reviewed by CM) + +Bug fixes +--------- +* Read .PAR files corresponding to ADC maps (pr/685) (Gregory R. Lee, reviewed + by CM) +* Increase maximum number of items read from Siemens CSA format (Igor Solovey, + reviewed by CM, MB) +* Check boolean dtypes with ``numpy.issubdtype(..., np.bool_)`` (pr/707) + (Jon Haitz Legarreta GorroΓ±o, reviewed by CM) + +Maintenance +----------- +* Fix small typos in parrec2nii help text (pr/682) (Thomas Roos, reviewed by + MB) +* Remove deprecated calls to ``numpy.asscalar`` (pr/686) (CM, reviewed by + Gregory R. Lee) +* Update QA directives to accommodate Flake8 3.6 (pr/695) (CM) +* Update DOI links to use ``https://doi.org`` (pr/703) (Katrin Leinweber, + reviewed by CM) +* Remove deprecated calls to ``numpy.fromstring`` (pr/700) (Ariel Rokem, + reviewed by CM, MB) +* Drop ``distutils`` support, require ``bz2file`` for Python 2.7 (pr/700) + (CM, reviewed by MB) +* Replace mutable ``bytes`` hack, disabled in numpy pre-release, with + ``bytearray``/``readinto`` strategy (pr/700) (Ariel Rokem, CM, reviewed by + CM, MB) + +API changes and deprecations +---------------------------- +* Add ``Opener.readinto`` method to read file contents into pre-allocated buffers + (pr/700) (Ariel Rokem, reviewed by CM, MB) + +2.3.1 (Tuesday 16 October 2018) +=============================== + +New features +------------ +* ``nib-diff`` command line tool for comparing image files (pr/617, pr/672, + pr/678) (CC, reviewed by YOH, Pradeep Raamana and CM) + +Enhancements +------------ +* Speed up reading of numeric arrays in CIFTI2 (pr/655) (Michiel Cottaar, + reviewed by CM) +* Add ``ndim`` property to ``ArrayProxy`` and ``DataobjImage`` (pr/674) (CM, + reviewed by MB) + +Bug fixes +--------- +* Deterministic deduction of slice ordering in degenerate cases (pr/647) + (YOH, reviewed by CM) +* Allow 0ms TR in MGH files (pr/653) (EL, reviewed by CM) +* Allow for PPC64 little-endian long doubles (pr/658) (MB, reviewed by CM) +* Correct construction of FreeSurfer annotation labels (pr/666) (CM, reviewed + by EL, Paul D. McCarthy) +* Fix logic for persisting filehandles with indexed-gzip (pr/679) (Paul D. + McCarthy, reviewed by CM) + +Maintenance +----------- +* Fix semantic error in coordinate systems documentation (pr/646) (Ariel + Rokem, reviewed by CM, MB) +* Test on Python 3.7, minor associated fixes (pr/651) (CM, reviewed by Gregory + R. Lee, MB) + +2.3 (Tuesday 12 June 2018) +========================== + +New features +------------ +* TRK <=> TCK streamlines conversion CLI tools (pr/606) (MC, reviewed by CM) +* Image slicing for SpatialImages (pr/550) (CM) + +Enhancements +------------ +* Simplfiy MGHImage and add footer fields (pr/569) (CM, reviewed by MB) +* Force sform/qform codes to be ints, rather than numpy types (pr/575) (Paul + McCarthy, reviewed by MB, CM) +* Auto-fill color table in FreeSurfer annotation file (pr/592) (PM, + reviewed by CM, MB) +* Set default intent code for CIFTI2 images (pr/604) (Mathias Goncalves, + reviewed by CM, SG, MB, Tim Coalson) +* Raise informative error on empty files (pr/611) (Pradeep Raamana, reviewed + by CM, MB) +* Accept degenerate filenames such as ``.nii`` (pr/621) (Dimitri + Papadopoulos-Orfanos, reviewed by Yaroslav Halchenko) +* Take advantage of ``IndexedGzipFile`` ``drop_handles`` flag to release + filehandles by default (pr/614) (PM, reviewed by CM, MB) + +Bug fixes +--------- +* Preserve first point of :py:class:`~nibabel.streamlines.LazyTractogram` + (pr/588) (MC, reviewed by Nil Goyette, CM, MB) +* Stop adding extraneous metadata padding (pr/593) (Jon Stutters, reviewed by + CM, MB) +* Accept lower-case orientation codes in TRK files (pr/600) (Kesshi Jordan, + MB, reviewed by MB, MC, CM) +* Annotation file reading (pr/592) (PM, reviewed by CM, MB) +* Fix buffer size calculation in ArraySequence (pr/597) (Serge Koudoro, + reviewed by MC, MB, Eleftherios Garyfallidis, CM) +* Resolve ``UnboundLocalError`` in Python 3 (pr/607) (Jakub Kaczmarzyk, + reviewed by MB, CM) +* Do not crash on non-``ImportError`` failures in optional imports (pr/618) + (Yaroslav Halchenko, reviewed by CM) +* Return original array from ``get_fdata`` for array image, if no cast + required (pr/638, MB, reviewed by CM) + +Maintenance +----------- +* Use SSH address to use key-based auth (pr/587) (CM, reviewed by MB) +* Fix doctests for numpy 1.14 array printing (pr/591) (MB, reviewed by CM) +* Refactor for pydicom 1.0 API changes (pr/599) (MB, reviewed by CM) +* Increase test coverage, remove unreachable code (pr/602) (CM, reviewed by + Yaroslav Halchenko, MB) +* Move ``nib-ls`` and other programs to a new cmdline module (pr/601, pr/615) + (Chris Cheng, reviewed by MB, Yaroslav Halchenko) +* Remove deprecated numpy indexing (EL, reviewed by CM) +* Update documentation to encourage ``get_fdata`` over ``get_data`` (pr/637, + MB, reviewed by CM) + +API changes and deprecations +---------------------------- +* Support for ``keep_file_open = 'auto'`` as a parameter to ``Opener()`` will + be deprecated in 2.4, for removal in 3.0. Accordingly, support for + ``openers.KEEP_FILE_OPEN_DEFAULT = 'auto'`` will be dropped on the same + schedule. +* Drop-in support for ``indexed_gzip < 0.7`` has been removed. + + +2.2.1 (Wednesday 22 November 2017) +================================== + +Bug fixes +--------- + +* Set L/R labels in orthoview correctly (pr/564) (CM) +* Defer use of ufunc / memmap test - allows "freezing" (pr/572) (MB, reviewed + by SG) +* Fix doctest failures with pre-release numpy (pr/582) (MB, reviewed by CM) + +Maintenance +----------- + +* Update documentation around NIfTI qform/sform codes (pr/576) (PM, + reviewed by MB, CM) + (pr/580) (Bennet Fauber, reviewed by PM) +* Skip precision test on macOS, newer numpy (pr/583) (MB, reviewed by CM) +* Simplify AppVeyor script, removing conda (pr/584) (MB, reviewed by CM) + +2.2 (Friday 13 October 2017) +============================ + +New features +------------ + +* CIFTI support (pr/249) (SG, Michiel Cottaar, BC, CM, Demian Wassermann, MB) +* Support for MRtrix TCK streamlines file format (pr/486) (MC, reviewed by + MB, Arnaud Bore, J-Donald Tournier, Jean-Christophe Houde) +* Added ``get_fdata()`` as default method to retrieve scaled floating point + data from ``DataobjImage``\s (pr/551) (MB, reviewed by CM, SG) + +Enhancements +------------ + +* Support for alternative header field name variants in .PAR files + (pr/507) (Gregory R. Lee) +* Various enhancements to streamlines API by MC: support for reading TRK + version 1 (pr/512); concatenation of tractograms using ``+``/``+=`` operators + (pr/495); function to concatenate multiple ArraySequence objects (pr/494) +* Support for numpy 1.12 (pr/500, pr/502) (MC, MB) +* Allow dtype specifiers as fileslice input (pr/485) (MB) +* Support "headerless" ArrayProxy specification, enabling memory-efficient + ArrayProxy reshaping (pr/521) (CM) +* Allow unknown NIfTI intent codes, add FSL codes (pr/528) (PM) +* Improve error handling for ``img.__getitem__`` (pr/533) (Ariel Rokem) +* Delegate reorientation to SpatialImage classes (pr/544) (Mark Hymers, CM, + reviewed by MB) +* Enable using ``indexed_gzip`` to reduce memory usage when reading from + gzipped NIfTI and MGH files (pr/552) (PM, reviewed by MB, CM) + +Bug fixes +--------- + +* Miscellaneous MINC reader fixes (pr/493) (Robert D. Vincent, reviewed by CM, + MB) +* Fix corner case in ``wrapstruct.get`` (pr/516) (PM, reviewed by + CM, MB) + +Maintenance +----------- + +* Fix documentation errors (pr/517, pr/536) (Fernando Perez, Venky Reddy) +* Documentation update (pr/514) (Ivan Gonzalez) +* Update testing to use pre-release builds of dependencies (pr/509) (MB) +* Better warnings when nibabel not on path (pr/503) (MB) + +API changes and deprecations +---------------------------- + +* ``header`` argument to ``ArrayProxy.__init__`` is renamed to ``spec`` +* Deprecation of ``header`` property of ``ArrayProxy`` object, for removal in + 3.0 +* ``wrapstruct.get`` now returns entries evaluating ``False``, instead of ``None`` +* ``DataobjImage.get_data`` to be deprecated April 2018, scheduled for removal + April 2020 + + +2.1 (Monday 22 August 2016) +=========================== + +New features +------------ + +* New API for managing streamlines and their different file formats. This + adds a new module ``nibabel.streamlines`` that will eventually deprecate + the current trackvis reader found in ``nibabel.trackvis`` (pr/391) (MC, + reviewed by Jean-Christophe Houde, Bago Amirbekian, Eleftherios + Garyfallidis, Samuel St-Jean, MB); +* A prototype image viewer using matplotlib (pr/404) (EL, based on a + proto-prototype by Paul Ivanov) (Reviewed by Gregory R. Lee, MB); +* Functions for image resampling and smoothing using scipy ndimage (pr/255) + (MB, reviewed by EL, BC); +* Add ability to write FreeSurfer morphology data (pr/414) (CM, BC, reviewed + by BC); +* Read and write support for DICOM tags in NIfTI Extended Header using + pydicom (pr/296) (Eric Kastman). + +Enhancements +------------ + +* Extensions to FreeSurfer module to fix reading and writing of FreeSurfer + geometry data (pr/460) (Alexandre Gramfort, Jaakko LeppΓ€kangas, reviewed + by EL, CM, MB); +* Various improvements to PAR / REC handling by Gregory R. Lee: supporting + multiple TR values (pr/429); output of volume labels (pr/427); fix for + some diffusion files (pr/426); option for more sophisticated sorting of + volumes (pr/409); +* Original trackvis reader will now allow final streamline to have fewer + points than the number declared in the header, with ``strict=False`` + argument to ``read`` function; +* Helper function to return voxel sizes from an affine matrix (pr/413); +* Fixes to DICOM multiframe reading to avoid assumptions on the position of + the multiframe index (pr/439) (Eric M. Baker); +* More robust handling of "CSA" private information in DICOM files (pr/393) + (Brendan Moloney); +* More explicit error when trying to read image from non-existent file + (pr/455) (Ariel Rokem); +* Extension to ``nib-ls`` command to show image statistics (pr/437) and other + header files (pr/348) (Yarik Halchenko). + +Bug fixes +--------- + +* Fixes to rotation order to generate affine matrices of PAR / REC files (MB, + Gregory R Lee). + +Maintenance +----------- + +* Dropped support for Pythons 2.6 and 3.2; +* Comprehensive refactor and generalization of surface / GIFTI file support + with improved API and extended tests (pr/352-355, pr/360, pr/365, pr/403) + (BC, reviewed by CM, MB); +* Refactor of image classes (pr/328, pr/329) (BC, reviewed by CM); +* Better Appveyor testing on new Python versions (pr/446) (Ariel Rokem); +* Fix shebang lines in scripts for correct install into virtualenvs via pip + (pr/434); +* Various fixes for numpy, matplotlib, and PIL / Pillow compatibility (CM, + Ariel Rokem, MB); +* Improved test framework for warnings (pr/345) (BC, reviewed by CM, MB); +* New decorator to specify start and end versions for deprecation warnings + (MB, reviewed by CM); +* Write qform affine matrix to NIfTI images output by ``parrec2nii`` (pr/478) + (Jasper J.F. van den Bosch, reviewed by Gregory R. Lee, MB). + +API changes and deprecations +---------------------------- + +* Minor API breakage in original (rather than new) trackvis reader. We are now + raising a ``DataError`` if there are too few streamlines in the file, + instead of a ``HeaderError``. We are raising a ``DataError`` if the track + is truncated when ``strict=True`` (the default), rather than a ``TypeError`` + when trying to create the points array. +* Change sform code that ``parrec2nii`` script writes to NIfTI images; change + from 2 ("aligned") to 1 ("scanner"); +* Deprecation of ``get_header``, ``get_affine`` method of image objects for + removal in version 4.0; +* Removed broken ``from_filespec`` method from image objects, and deprecated + ``from_filespec`` method of ECAT image objects for removal in 4.0; +* Deprecation of ``class_map`` instance in ``imageclasses`` module in favor of + new image class attributes, for removal in 4.0; +* Deprecation of ``ext_map`` instance in ``imageclasses`` module in favor of + new image loading API, for removal in 4.0; +* Deprecation of ``Header`` class in favor of ``SpatialHeader``, for removal + in 4.0; +* Deprecation of ``BinOpener`` class in favor of more generic ``Opener`` + class, for removal in 4.0; +* Deprecation of ``GiftiMetadata`` methods ``get_metadata`` and ``get_rgba``; + ``GiftiDataArray`` methods ``get_metadata``, ``get_labeltable``, + ``set_labeltable``; ``GiftiImage`` methods ``get_meta``, ``set_meta``. All + these deprecated in favor of corresponding properties, for removal in 4.0; +* Deprecation of ``giftiio`` ``read`` and ``write`` functions in favor of + nibabel ``load`` and ``save`` functions, for removal in 4.0; +* Deprecation of ``gifti.data_tag`` function, for removal in 4.0; +* Deprecation of write-access to ``GiftiDataArray.num_dim``, and new error + when trying to set invalid values for ``num_dim``. We will remove + write-access in 4.0; +* Deprecation of ``GiftiDataArray.from_array`` in favor of ``GiftiDataArray`` + constructor, for removal in 4.0; +* Deprecation of ``GiftiDataArray`` ``to_xml_open, to_xml_close`` methods in + favor of ``to_xml`` method, for removal in 4.0; +* Deprecation of ``parse_gifti_fast.Outputter`` class in favor of + ``GiftiImageParser``, for removal in 4.0; +* Deprecation of ``parse_gifti_fast.parse_gifti_file`` function in favor of + ``GiftiImageParser.parse`` method, for removal in 4.0; +* Deprecation of ``loadsave`` functions ``guessed_image_type`` and + ``which_analyze_type``, in favor of new API where each image class tests the + file for compatibility during load, for removal in 4.0. + +2.0.2 (Monday 23 November 2015) +=============================== + +* Fix for integer overflow on large images (pr/325) (MB); +* Fix for Freesurfer nifti files with unusual dimensions (pr/332) (Chris + Markiewicz); +* Fix typos on benchmarks and tests (pr/336, pr/340, pr/347) (Chris + Markiewicz); +* Fix Windows install script (pr/339) (MB); +* Support for Python 3.5 (pr/363) (MB) and numpy 1.10 (pr/358) (Chris + Markiewicz); +* Update pydicom imports to permit version 1.0 (pr/379) (Chris Markiewicz); +* Workaround for Python 3.5.0 gzip regression (pr/383) (Ben Cipollini). +* tripwire.TripWire object now raises subclass of AttributeError when trying + to get an attribute, rather than a direct subclass of Exception. This + prevents Python 3.5 triggering the tripwire when doing inspection prior to + running doctests. +* Minor API change for tripwire.TripWire object; code that checked for + AttributeError will now also catch TripWireError. + +2.0.1 (Saturday 27 June 2015) +============================= + +Contributions from Ben Cipollini, Chris Markiewicz, Alexandre Gramfort, +Clemens Bauer, github user freec84. + +* Bugfix release with minor new features; +* Added ``axis`` parameter to ``concat_images`` (pr/298) (Ben Cipollini); +* Fix for unsigned integer data types in ECAT images (pr/302) (MB, test data + and issue report from Github user freec84); +* Added new ECAT and Freesurfer data files to automated testing; +* Fix for Freesurfer labels error on early numpies (pr/307) (Alexandre + Gramfort); +* Fixes for PAR / REC header parsing (pr/312) (MB, issue reporting and test + data by Clemens C. C. Bauer); +* Workaround for reading Freesurfer ico7 surface files (pr/315) (Chris + Markiewicz); +* Changed to github pages for doc hosting; +* Changed docs to point to neuroimaging@python.org mailing list. + +2.0.0 (Tuesday 9 December 2014) +=============================== + +This release had large contributions from Eric Larson, Brendan Moloney, +Nolan Nichols, Basile Pinsard, Chris Johnson and Nikolaas N. Oosterhof. + +* New feature, bugfix release with minor API breakage; +* Minor API breakage: default write of NIfTI / Analyze image data offset + value. The data offset is the number of bytes from the beginning of file + to skip before reading the image data. Nibabel behavior changed from + keeping the value as read from file, to setting the offset to zero on + read, and setting the offset when writing the header. The value of the + offset will now be the minimum value necessary to make room for the header + and any extensions when writing the file. You can override the default + offset by setting value explicitly to some value other than zero. To read + the original data offset as read from the header, use the ``offset`` + property of the image ``dataobj`` attribute; +* Minor API breakage: data scaling in NIfTI / Analyze now set to NaN when + reading images. Data scaling refers to the data intercept and slope + values in the NIfTI / Analyze header. To read the original data scaling + you need to look at the ``slope`` and ``inter`` properties of the image + ``dataobj`` attribute. You can set scaling explicitly by setting the + slope and intercept values in the header to values other than NaN; +* New API for managing image caching; images have an ``in_memory`` property + that is true if the image data has been loaded into cache, or is already + an array in memory; ``get_data`` has new keyword argument ``caching`` to + specify whether the cache should be filled by ``get_data``; +* Images now have properties ``dataobj``, ``affine``, ``header``. We will + slowly phase out the ``get_affine`` and ``get_header`` image methods; +* The image ``dataobj`` can be sliced using an efficient algorithm to avoid + reading unnecessary data from disk. This makes it possible to do very + efficient reads of single volumes from a time series; +* NIfTI2 read / write support; +* Read support for MINC2; +* Much extended read support for PAR / REC, largely due to work from Eric + Larson and Gregory R. Lee on new code, advice and code review. Thanks also + to Jeff Stevenson and Bennett Landman for helpful discussion; +* ``parrec2nii`` script outputs images in LAS voxel orientation, which + appears to be necessary for compatibility with FSL ``dtifit`` / + ``fslview`` diffusion analysis pipeline; +* Preliminary support for Philips multiframe DICOM images (thanks to Nolan + Nichols, Ly Nguyen and Brendan Moloney); +* New function to save Freesurfer annotation files (by Github user ohinds); +* Method to return MGH format ``vox2ras_tkr`` affine (Eric Larson); +* A new API for reading unscaled data from NIfTI and other images, using + ``img.dataobj.get_unscaled()``. Deprecate previous way of doing this, + which was to read data with the ``read_img_data`` function; +* Fix for bug when replacing NaN values with zero when writing floating + point data as integers. If the input floating point data range did not + include zero, then NaN would not get written to a value corresponding to + zero in the output; +* Improvements and bug fixes to image orientation calculation and DICOM + wrappers by Brendan Moloney; +* Bug fixes writing GIfTI files. We were using a base64 encoding that didn't + match the spec, and the wrong field name for the endian code. Thanks to + Basile Pinsard and Russ Poldrack for diagnosis and fixes; +* Bug fix in ``freesurfer.read_annot`` with ``orig_ids=False`` when annot + contains vertices with no label (Alexandre Gramfort); +* More tutorials in the documentation, including introductory tutorial on + DICOM, and on coordinate systems; +* Lots of code refactoring, including moving to common code-base for Python + 2 and Python 3; +* New mechanism to add images for tests via git submodules. + +1.3.0 (Tuesday 11 September 2012) +================================= + +Special thanks to Chris Johnson, Brendan Moloney and JB Poline. + +* New feature and bugfix release +* Add ability to write Freesurfer triangle files (Chris Johnson) +* Relax threshold for detecting rank deficient affines in orientation + detection (JB Poline) +* Fix for DICOM slice normal numerical error (issue #137) (Brendan Moloney) +* Fix for Python 3 error when writing zero bytes for offset padding + +1.2.2 (Wednesday 27 June 2012) +============================== + +* Bugfix release +* Fix longdouble tests for Debian PPC (thanks to Yaroslav Halchecko for + finding and diagnosing these errors) +* Generalize longdouble tests in the hope of making them more robust +* Disable saving of float128 nifti type unless platform has real IEEE + binary128 longdouble type. + +1.2.1 (Wednesday 13 June 2012) +============================== + +Particular thanks to Yaroslav Halchecko for fixes and cleanups in this +release. + +* Bugfix release +* Make compatible with pydicom 0.9.7 +* Refactor, rename nifti diagnostic script to ``nib-nifti-dx`` +* Fix a bug causing an error when analyzing affines for orientation, when the + affine contained all 0 columns +* Add missing ``dicomfs`` script to installation list and rename to + ``nib-dicomfs`` + +1.2.0 (Sunday 6 May 2012) +========================= + +This release had large contributions from Krish Subramaniam, Alexandre +Gramfort, Cindee Madison, FΓ©lix C. Morency and Christian Haselgrove. + +* New feature and bugfix release +* Freesurfer format support by Krish Subramaniam and Alexandre Gramfort. +* ECAT read write support by Cindee Madison and FΓ©lix C. Morency. +* A DICOM fuse filesystem by Christian Haselgrove. +* Much work on making data scaling on read and write more robust to rounding + error and overflow (MB). +* Import of nipy functions for working with affine transformation matrices. +* Added methods for working with nifti sform and qform fields by Bago + Amirbekian and MB, with useful discussion by Brendan Moloney. +* Fixes to read / write of RGB analyze images by Bago Amirbekian. +* Extensions to ``concat_images`` by Yannick Schwartz. +* A new ``nib-ls`` script to display information about neuroimaging files, and + various other useful fixes by Yaroslav Halchenko. + +1.1.0 (Thursday 28 April 2011) +============================== + +Special thanks to Chris Burns, Jarrod Millman and Yaroslav Halchenko. + +* New feature release +* Python 3.2 support +* Substantially enhanced gifti reading support (Stephan Gerhard) +* Refactoring of trackvis read / write to allow reading and writing of voxel + points and mm points in tracks. Deprecate use of negative voxel sizes; + set voxel_order field in trackvis header. Thanks to Chris Filo + Gorgolewski for pointing out the problem and Ruopeng Wang in the trackvis + forum for clarifying the coordinate system of trackvis files. +* Added routine to give approximate array orientation in form such as 'RAS' + or 'LPS' +* Fix numpy dtype hash errors for numpy 1.2.1 +* Other bug fixes as for 1.0.2 + +1.0.2 (Thursday 14 April 2011) +============================== + +* Bugfix release +* Make inference of data type more robust to changes in numpy dtype hashing +* Fix incorrect thresholds in quaternion calculation (thanks to Yarik H for + pointing this one out) +* Make parrec2nii pass over errors more gracefully +* More explicit checks for missing or None field in trackvis and other + classes - thanks to Marc-Alexandre Cote +* Make logging and error level work as expected - thanks to Yarik H +* Loading an image does not change qform or sform - thanks to Yarik H +* Allow 0 for nifti scaling as for spec - thanks to Yarik H +* nifti1.save now correctly saves single or pair images + +1.0.1 (Wednesday 23 Feb 2011) +============================= + +* Bugfix release +* Fix bugs in tests for data package paths +* Fix leaks of open filehandles when loading images (thanks to Gael + Varoquaux for the report) +* Skip rw tests for SPM images when scipy not installed +* Fix various windows-specific file issues for tests +* Fix incorrect reading of byte-swapped trackvis files +* Workaround for odd numpy dtype comparisons leading to header errors for + some loaded images (thanks to Cindee Madison for the report) + +1.0.0 (Thursday, 13, Oct 2010) +============================== + +* This is the first public release of the NiBabel package. +* NiBabel is a complete rewrite of the PyNifti package in pure python. It was + designed to make the code simpler and easier to work with. Like PyNifti, + NiBabel has fairly comprehensive NIfTI read and write support. +* Extended support for SPM Analyze images, including orientation affines from + matlab ``.mat`` files. +* Basic support for simple MINC 1.0 files (MB). Please let us know if you + have MINC files that we don't support well. +* Support for reading and writing PAR/REC images (MH) +* ``parrec2nii`` script to convert PAR/REC images to NIfTI format (MH) +* Very preliminary, limited and highly experimental DICOM reading support (MB, + Ian Nimmo Smith). +* Some functions (:py:mod:`nibabel.funcs`) for basic image shape changes, including + the ability to transform to the image with data closest to the canonical + image orientation (first axis left-to-right, second back-to-front, third + down-to-up) (MB, Jonathan Taylor) +* Gifti format read and write support (preliminary) (Stephen Gerhard) +* Added utilities to use nipy-style data packages, by rip then edit of nipy + data package code (MB) +* Some improvements to release support (Jarrod Millman, MB, Fernando Perez) +* Huge downward step in the quality and coverage by the docs, caused by MB, + mostly fixed by a lot of good work by MH. +* NiBabel will not work with Python < 2.5, and we haven't even tested it with + Python 3. We will get to it soon... + +**************** +PyNifti releases +**************** + +Modifications are done by Michael Hanke, if not indicated otherwise. 'Closes' +statement IDs refer to the Debian bug tracking system and can be queried by +visiting the URL:: + + http://bugs.debian.org/ + +0.20100706.1 (Tue, 6 Jul 2010) +============================== + +* Bugfix: NiftiFormat.vx2s() used the qform not the sform. Thanks to Tom + Holroyd for reporting. + +0.20100412.1 (Mon, 12 Apr 2010) +=============================== + +* Bugfix: Unfortunate interaction between Python garbage collection and C + library caused memory problems. Thanks to Yaroslav Halchenko for the + diagnose and fix. + +0.20090303.1 (Tue, 3 Mar 2009) +============================== + +* Bugfix: Updating the NIfTI header from a dictionary was broken. +* Bugfix: Removed left-over print statement in extension code. +* Bugfix: Prevent saving of bogus 'None.nii' images when the filename + was previously assign, before calling NiftiImage.save() (Closes: #517920). +* Bugfix: Extension length was to short for all ``edata`` whose length matches + n*16-8, for all integer n. + +0.20090205.1 (Thu, 5 Feb 2009) +============================== + +* This release is the first in a series that aims stabilize the API and + finally result in PyNIfTI 1.0 with full support of the NIfTI1 standard. +* The whole package was restructured. The included renaming + ``nifti.nifti(image,format,clibs)`` to ``nifti.(image,format,clibs)``. Redirect + modules make sure that existing user code will not break, but they will + issue a DeprecationWarning and will be removed with the release of PyNIfTI + 1.0. +* Added a special extension that can embed any serializable Python object + into the NIfTI file header. The contents of this extension is + automatically expanded upon request into the ``.meta`` attribute of each + NiftiImage. When saving files to disk the content of the dictionary is also + automatically dumped into this extension. + Embedded meta data is not loaded automatically, since this has security + implications, because code from the file header is actually executed. + The documentation explicitly mentions this risk. +* Added :class:`~nifti.extensions.NiftiExtensions`. This is a container-like + handler to access and manipulate NIfTI1 header extensions. +* Exposed :class:`~nifti.image.MemMappedNiftiImage` in the root module. +* Moved :func:`~nifti.utils.cropImage` into the :mod:`~nifti.utils` module. +* From now on Sphinx is used to generate the documentation. This includes a + module reference that replaces that old API reference. +* Added methods :meth:`~nifti.format.NiftiFormat.vx2q` and + :meth:`~nifti.format.NiftiFormat.vx2s` to convert voxel indices into + coordinates defined by qform or sform respectively. +* Updating the ``cal_min`` and ``cal_max`` values in the NIfTI header when + saving a file is now conditional, but remains enabled by default. +* Full set of methods to query and modify axis units. This includes + expanding the previous ``xyzt_units`` field in the header dictionary into + editable ``xyz_unit`` and ``time_unit`` fields. The former ``xyzt_units`` field + is no longer available. See: + :meth:`~nifti.format.NiftiFormat.getXYZUnit`, + :meth:`~nifti.format.NiftiFormat.setXYZUnit`, + :meth:`~nifti.format.NiftiFormat.getTimeUnit`, + :meth:`~nifti.format.NiftiFormat.setTimeUnit`, + :attr:`~nifti.format.NiftiFormat.xyz_unit`, + :attr:`~nifti.format.NiftiFormat.time_unit` +* Full set of methods to query and manuipulate qform and sform codes. See: + :meth:`~nifti.format.NiftiFormat.getQFormCode`, + :meth:`~nifti.format.NiftiFormat.setQFormCode`, + :meth:`~nifti.format.NiftiFormat.getSFormCode`, + :meth:`~nifti.format.NiftiFormat.setSFormCode`, + :attr:`~nifti.format.NiftiFormat.qform_code`, + :attr:`~nifti.format.NiftiFormat.sform_code` +* Each image instance is now able to generate a human-readable dump of its + most important header information via ``__str__()``. +* :class:`~nifti.image.NiftiImage` objects can now be pickled. +* Switched to NumPy's distutils for building the package. Cleaned and + simplified the build procedure. Added optimization flags to SWIG call. +* :attr:`nifti.image.NiftiImage.filename` can now also be used to assign a + filename. +* Introduced :data:`nifti.__version__` as canonical version string. +* Removed ``updateQFormFromQuarternion()`` from the list of public methods of + :class:`~nifti.format.NiftiFormat`. This is an internal method that + should not be used in user code. However, a redirect to the new method + will remain in-place until PyNIfTI 1.0. +* Bugfix: :meth:`~nifti.image.NiftiImage.getScaledData` returns a + unmodified data array if ``slope`` is set to zero (as required by the NIfTI + standard). Thanks to Thomas Ross for reporting. +* Bugfix: Unicode filenames are now handled properly, as long as they do not + contain pure-unicode characters (since the NIfTI library does not support + them). Thanks to GaΓ«l Varoquaux for reporting this issue. + +0.20081017.1 (Fri, 17 Oct 2008) +=============================== + +* Updated included minimal copy of the nifticlibs to version 1.1.0. +* Few changes to the Makefiles to enhance Posix compatibility. Thanks to + Chris Burns. +* When building on non-Debian systems, only add include and library paths + pointing to the local nifticlibs copy, when it is actually built. + On Debian system the local copy is still not used at all, as a proper + nifticlibs package is guaranteed to be available. +* Added minimal setup_egg.py for setuptools users. Thanks to GaΓ«l Varoquaux. +* PyNIfTI now does a proper wrapping of the image data with NumPy arrays, + which no longer leads to accidental memory leaks, when accessing array + data that has not been copied before (e.g. via the *data* property of + NiftiImage). Thanks to GaΓ«l Varoquaux for mentioning this possibility. + +0.20080710.1 (Thu, 7 Jul 2008) +============================== + +* Bugfix: Pointer bug introduced by switch to new NumPy API in 0.20080624 + Thanks to Christopher Burns for fixing it. +* Bugfix: Honored DeprecationWarning: sync() -> flush() for memory mapped + arrays. Again thanks to Christopher Burns. +* More unit tests and other improvements (e.g. fixed circular imports) done + by Christopher Burns. + +0.20080630.1 (Tue, 30 Jun 2008) +=============================== + +* Bugfix: NiftiImage caused a memory leak by not calling the NiftiFormat + destructor. +* Bugfix: Merged bashism-removal patch from Debian packaging. + +0.20080624.1 (Tue, 24 Jun 2008) +=============================== + +* Converted all documentation (including docstrings) into the restructured + text format. +* Improved Makefile. +* Included configuration and Makefile support for profiling, API doc + generation (via epydoc) and code quality checks (with PyLint). +* Consistently import NumPy as N. +* Bugfix: Proper handling of [qs]form codes, which previously have not been + handled at all. Thanks to Christopher Burns for pointing it out. +* Bugfix: Make NiftiFormat work without setFilename(). Thanks to Benjamin + Thyreau for reporting. +* Bugfix: setPixDims() stored meaningless values. +* Use new NumPy API and replace deprecated function calls + (``PyArray_FromDimsAndData``). +* Initial support for memory mapped access to uncompressed NIfTI files + (``MemMappedNiftiImage``). +* Add a proper Makefile and setup.cfg for compiling PyNIfTI under Windows + with MinGW. +* Include a minimal copy of the most recent nifticlibs (just libniftiio and + znzlib; version 1.0), to lower the threshold to build PyNIfTI on systems + that do not provide a developer package for those libraries. + +0.20070930.1 (Sun, 30 Sep 2007) +=============================== + +* Relicense under the MIT license, to be compatible with SciPy license. + http://www.opensource.org/licenses/mit-license.php +* Updated documentation. + +0.20070917.1 (Mon, 17 Sep 2007) +=============================== + +* Bugfix: Can now update NIfTI header data when no filename is set + (Closes: #442175). +* Unloading of image data without a filename set is no checked and prevented + as it would damage data integrity and the image data could not be + recovered. +* Added 'pixdim' property (Yaroslav Halchenko). + +0.20070905.1 (Wed, 5 Sep 2007) +=============================== + +* Fixed a bug in the qform/quaternion handling that caused changes to the + qform to vanish when saving to file (Yaroslav Halchenko). +* Added more unit tests. +* 'dim' vector in the NIfTI header is now guaranteed to only contain + non-zero elements. This caused problems with some applications. + +0.20070803.1 (Fri, 3 Aug 2007) +============================== + +* Does not depend on SciPy anymore. +* Initial steps towards a unittest suite. +* pynifti_pst can now print the peristimulus signal matrix for a single + voxel (onsets x time) for easier processing of this information in + external applications. +* utils.getPeristimulusTimeseries() can now be used to compute mean and + variance of the signal (among others). +* pynifti_pst is able to compute more than just the mean peristimulus + timeseries (e.g. variance and standard deviation). +* Set default image description when saving a file if none is present. +* Improved documentation. + +0.20070425.1 (Wed, 25 Apr 2007) +=============================== + +* Improved documentation. Added note about the special usage of the header + property. Also added notes about the relevant properties in the docstring + of the corresponding accessor methods. +* Added property and accessor methods to access/modify the repetition time + of timeseries (dt). +* Added functions to manipulate the pixdim values. +* Added utils.py with some utility functions. +* Added functions/property to determine the bounding box of an image. +* Fixed a bug that caused a corrupted sform matrix when converting a NumPy + array and a header dictionary into a NIfTI image. +* Added script to compute peristimulus timeseries (pynifti_pst). +* Package now depends on python-scipy. + +0.20070315.1 (Thu, 15 Mar 2007) +=============================== + +* Removed functionality for "NiftiImage.save() raises an IOError + exception when writing the image file fails." (Yaroslav Halchenko) +* Added ability to force a filetype when setting the filename or saving + a file. +* Reverse the order of the 'header' and 'load' argument in the NiftiImage + constructor. 'header' is now first as it seems to be used more often. +* Improved the source code documentation. +* Added getScaledData() method to NiftiImage that returns a copy of the data + array that is scaled with the slope and intercept stored in the NIfTI + header. + +0.20070301.2 (Thu, 1 Mar 2007) +============================== + +* Fixed wrong link to the source tarball in README.html. + +0.20070301.1 (Thu, 1 Mar 2007) +============================== + +* Initial upload to the Debian archive. (Closes: #413049) +* NiftiImage.save() raises an IOError exception when writing the image file + fails. +* Added extent, volextent, and timepoints properties to NiftiImage + class (Yaroslav Halchenko). + +0.20070220.1 (Tue, 20 Feb 2007) +=============================== + +* NiftiFile class is renamed to NiftiImage. +* SWIG-wrapped libniftiio functions are no available in the nifticlib + module. +* Fixed broken NiftiImage from Numpy array constructor. +* Added initial documentation in README.html. +* Fulfilled a number of Yarik's wishes ;) + +0.20070214.1 (Wed, 14 Feb 2007) +=============================== + +* Does not depend on libfslio anymore. +* Up to seven-dimensional dataset are supported (as much as NIfTI can do). +* The complete NIfTI header dataset is modifiable. +* Most image properties are accessible via class attributes and accessor + methods. +* Improved documentation (but still a long way to go). + +0.20061114 (Tue, 14 Nov 2006) +============================= + +* Initial release. diff --git a/_sources/coordinate_systems.rst.txt b/_sources/coordinate_systems.rst.txt new file mode 100644 index 0000000000..3c68d71271 --- /dev/null +++ b/_sources/coordinate_systems.rst.txt @@ -0,0 +1,962 @@ +############################## +Coordinate systems and affines +############################## + +A nibabel (and nipy) image is the association of three things: + +* The *image data array*: a 3D or 4D *array* of image data +* An *affine array* that tells you the position of the image array data in + a *reference space*. +* *image metadata* (data about the data) describing the image, usually in the + form of an image *header*. + +This document describes how the *affine array* describes the position of the +image data in a reference space. On the way we will define what we mean by +reference space, and the reference spaces that Nibabel uses. + +******************* +Introducing Someone +******************* + +We have scanned someone called "Someone", and we have a two MRI images of +their brain, a single EPI volume, and a structural scan. In general we never +use the person's name in the image filenames, but we make an +exception in this case: + +* :download:`someones_epi.nii.gz `. +* :download:`someones_anatomy.nii.gz `. + +We can load up the EPI image to get the image data array: + +.. plot:: + :context: + :nofigs: + + >>> import nibabel as nib + >>> epi_img = nib.load('downloads/someones_epi.nii.gz') + >>> epi_img_data = epi_img.get_fdata() + >>> epi_img_data.shape + (53, 61, 33) + +Then we have a look at slices over the first, second and third dimensions of +the array. + +.. plot:: + :context: + + >>> import matplotlib.pyplot as plt + >>> def show_slices(slices): + ... """ Function to display row of image slices """ + ... fig, axes = plt.subplots(1, len(slices)) + ... for i, slice in enumerate(slices): + ... axes[i].imshow(slice.T, cmap="gray", origin="lower") + >>> + >>> slice_0 = epi_img_data[26, :, :] + >>> slice_1 = epi_img_data[:, 30, :] + >>> slice_2 = epi_img_data[:, :, 16] + >>> show_slices([slice_0, slice_1, slice_2]) + >>> plt.suptitle("Center slices for EPI image") # doctest: +SKIP + +We collected an anatomical image in the same session. We can load that image +and look at slices in the three axes: + +.. plot:: + :context: + + >>> anat_img = nib.load('downloads/someones_anatomy.nii.gz') + >>> anat_img_data = anat_img.get_fdata() + >>> anat_img_data.shape + (57, 67, 56) + >>> show_slices([anat_img_data[28, :, :], + ... anat_img_data[:, 33, :], + ... anat_img_data[:, :, 28]]) + >>> plt.suptitle("Center slices for anatomical image") # doctest: +SKIP + +As is usually the case, we had a different field of view for the anatomical +scan, and so the anatomical image has a different shape, size, and orientation +in the magnet. + +********************************************************* +Voxel coordinates are coordinates in the image data array +********************************************************* + +As y'all know, a voxel is a pixel with volume. + +In the code above, ``slice_0`` from the EPI data is a 2D slice from a 3D +image. The plot of the EPI slices displays the slices in grayscale (graded +between black for the minimum value, white for the maximum). Each pixel in +the slice grayscale image also represents a voxel, because this 2D image +represents a slice from the 3D image with a certain thickness. + +The 3D array is therefore also a voxel array. As for any array, we can select +particular values by indexing. For example, we can get the value for the +middle voxel in the EPI data array like this: + +.. plot:: + :context: + :nofigs: + + >>> n_i, n_j, n_k = epi_img_data.shape + >>> center_i = (n_i - 1) // 2 # // for integer division + >>> center_j = (n_j - 1) // 2 + >>> center_k = (n_k - 1) // 2 + >>> center_i, center_j, center_k + (26, 30, 16) + >>> center_vox_value = epi_img_data[center_i, center_j, center_k] + >>> center_vox_value + 81.5492877960205... + +The values (26, 30, 16) are indices into the data array ``epi_img_data``. (26, +30, 16) is therefore a 'voxel coordinate' - a coordinate into the voxel array. + +A coordinate is a set of numbers giving positions relative to a set of *axes*. +In this case 26 is a position on the first array axis, where the axis is of +length ``epi_img_data.shape[0]``, and therefore goes from 0 to 52 +(``epi_img_data.shape == (53, 61, 33)``). Similarly 30 gives a position on +the second axis (0 to 60) and 16 is the position on the third axis (0 to 32). + +************************************* +Voxel coordinates and points in space +************************************* + +The voxel coordinate tells us almost nothing about where the data came from +in terms of position in the scanner. For example, let's say we have the voxel +coordinate (26, 30, 16). Without more information we have no idea whether +this voxel position is on the left or right of the brain, or came from the +left or right of the scanner. + +This is because the scanner allows us to collect voxel data in almost any +arbitrary position and orientation within the magnet. + +In the case of Someone's EPI, we took transverse slices at a moderate angle to +the floor to ceiling direction. This localizer image from the scanner console +has a red box that shows the position of the slice block for +``someones_epi.nii.gz`` and a blue box for the slice block of +``someones_anatomy.nii.gz``: + +.. images generated by /doc/source/scripts/make_coord_examples.py + +.. _localizer-image: + +.. image:: /images/localizer.png + +The localizer is oriented to the magnet, so that the left and right borders of +the image are parallel to the floor of the scanner room, with the left border +being towards the floor and the right border towards the ceiling. + +You will see from the labels on the localizer that the center of the EPI voxel +data block (at 26, 30, 16 in ``epi_img_data``) is not quite at the center of +magnet bore (the magnet *isocenter*). + +We have an anatomical and an EPI scan, and later on we will surely want to be +able to relate the data from ``someones_epi.nii.gz`` to +``someones_anatomy.nii.gz``. We can't easily do this at the moment, because +we collected the anatomical image with a different field of view and +orientation to the EPI image, so the voxel coordinates in the EPI image refer +to different locations in the magnet to the voxel coordinates in the +anatomical image. + +We solve this problem by keeping track of the relationship of voxel +coordinates to some *reference space*. In particular, the *affine array* +stores the relationship between voxel coordinates in the image data array and +coordinates in the reference space. We store the relationship of voxel +coordinates from ``someones_epi.nii.gz`` and the reference space, and also the +(different) relationship of voxel coordinates in ``someones_anatomy.nii.gz`` +to the *same* reference space. Because we know the relationship of (voxel +coordinates to the reference space) for both images, we can use this +information to relate voxel coordinates in ``someones_epi.nii.gz`` to spatially +equivalent voxel coordinates in ``someones_anatomy.nii.gz``. + +*********************************** +The scanner-subject reference space +*********************************** + +What does "space" mean in the phrase "reference space"? The space is defined +by an ordered set of axes. For our 3D spatial world, it is a set of 3 +independent axes. + +We can decide what space we want to use, by choosing these axes. We need to +choose the origin of the axes, their direction and their units. + +To start with, we define a set of three orthogonal *scanner axes*. + +The scanner axes +================ + +* The origin of the axes is at the magnet isocenter. This is coordinate (0, 0, + 0) in our reference space. All three axes pass through the isocenter. +* The units for all three axes are millimeters. +* Imagine an observer standing behind the scanner looking through the magnet + bore towards the end of the scanner bed. Imagine a line traveling towards + the observer through the center of the magnet bore, parallel to the bed, + with the zero point at the magnet isocenter, and positive values closer to + the observer. Call this line the *scanner-bore* axis. +* Draw a line traveling from the scanner room floor up through the magnet + isocenter towards the ceiling, at right angles to the scanner bore axis. + 0 is at isocenter and positive values are towards the ceiling. Call this + the *scanner-floor/ceiling* axis. +* Draw a line at right angles to the other two lines, traveling from the + observer's left, parallel to the floor, and through the magnet isocenter to + the observer's right. 0 is at isocenter and positive values are to the + right. Call this the *scanner-left/right*. + +If we make the axes have order (scanner left-right; scanner floor-ceiling; +scanner bore) then we have an ordered set of 3 axes and therefore the +definition of a 3D *space*. Call the first axis the "X" axis, the second "Y" +and the third "Z". A coordinate of $(x, y, z) = (10, -5, -3)$ in this space +refers to the point in space 10mm to the (fictional observer's) right of +isocenter, 5mm towards the floor from the isocenter, and 3mm towards the foot +of the scanner bed. This reference space is sometimes known as "scanner XYZ". +It was the standard reference space for the predecessor to DICOM, called ACR / +NEMA 2.0. + +From scanner to subject +======================= + +If the subject is lying in the usual position for a brain scan, face up +and head first in the scanner, then scanner-left/right is also the left-right +axis of the subject's head, scanner-floor/ceiling is the posterior-anterior +axis of the head and scanner-bore is the inferior-superior axis of the head. + +Sometimes the subject is not lying in the standard position. For example, the +subject may be lying with their face pointing to the right (in terms of the +scanner-left/right axis). In that case "scanner XYZ" will not tell us about +the subject's left and right, but only the scanner left and right. We might +prefer to know where we are in terms of the subject's left and right. + +To deal with this problem, most reference spaces use subject- or patient- +centered scanner coordinate systems. In these systems, the axes are still the +scanner axes above, but the ordering and direction of the axes comes from the +position of the subject. The most common subject-centered scanner coordinate +system in neuroimaging is called "scanner RAS" (right, anterior, superior). +Here the scanner axes are reordered and flipped so that the first axis is the +scanner axis that is closest to the left to right axis of the subject, the +second is the closest scanner axis to the posterior-anterior axis of the +subject, and the third is the closest scanner axis to the inferior-superior +axis of the subject. For example, if the subject was lying face to the right +in the scanner, then the first (X) axis of the reference system would be +scanner-floor/ceiling, but reversed so that positive values are towards the +floor. This axis goes from left to right in the subject, with positive values +to the right. The second (Y) axis would be scanner-left/right +(posterior-anterior in the subject), and the Z axis would be scanner-bore +(inferior-superior). + +Naming reference spaces +======================= + +Reading names of reference spaces can be confusing because of different +meanings that authors use for the same terms, such as 'left' and 'right'. + +We are using the term "RAS" to mean that the axes are (in terms of the +subject): left to Right; posterior to Anterior; and inferior to Superior, +respectively. Although it is common to call this convention "RAS", it is not +quite universal, because some use "R", "A" and "S" in "RAS" to mean that the +axes *starts* on the right, anterior, superior of the subject, rather than +*ending* on the right, anterior, superior. In other words, they would use +"RAS" to refer to a coordinate system we would call "LPI". To be safe, we'll +call our interpretation of the RAS convention "RAS+", meaning that Right, +Anterior, Superior are all positive values on these axes. + +Some people also use "right" to mean the right hand side when an observer +looks at the front of the scanner, from the foot the scanner bed. +Unfortunately, this means that you have to read coordinate system definitions +carefully if you are not familiar with a particular convention. We nibabel / +nipy folks agree with most of our brain imaging friends and many of our +enemies in that we always use "right" to mean the subject's right. + +************************************ +Voxel coordinates are in voxel space +************************************ + +We have not yet made this explicit, but voxel coordinates are also in a space. +In this case the space is defined by the three voxel axes (first axis, second +axis, third axis), where 0, 0, 0 is the center of the first voxel in the +array and the units on the axes are voxels. Voxel coordinates are therefore +defined in a reference space called *voxel space*. + +**************************************************** +The affine matrix as a transformation between spaces +**************************************************** + +We have voxel coordinates (in voxel space). We want to get scanner RAS+ +coordinates corresponding to the voxel coordinates. We need a *coordinate +transform* to take us from voxel coordinates to scanner RAS+ coordinates. + +In general, we have some voxel space coordinate $(i, j, k)$, and we want to +generate the reference space coordinate $(x, y, z)$. + +Imagine we had solved this, and we had a coordinate transform function $f$ +that accepts a voxel coordinate and returns a coordinate in the reference +space: + +.. math:: + + (x, y, z) = f(i, j, k) + +$f$ accepts a coordinate in the *input* space and returns a coordinate in the +*output* space. In our case the input space is voxel space and the output +space is scanner RAS+. + +In theory $f$ could be a complicated non-linear function, but in practice, we +know that the scanner collects data on a regular grid. This means that the +relationship between $(i, j, k)$ and $(x, y, z)$ is linear (actually +*affine*), and can be encoded with linear (actually affine) transformations +comprising translations, rotations and zooms (`wikipedia linear transform`_, +`wikipedia affine transform`_). + +Scaling (zooming) in three dimensions can be represented by a diagonal 3 by 3 +matrix. Here's how to zoom the first dimension by $p$, the second by $q$ and +the third by $r$ units: + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + \end{bmatrix} = + \begin{bmatrix} + p i\\ + q j\\ + r k\\ + \end{bmatrix} = + \begin{bmatrix} + p & 0 & 0 \\ + 0 & q & 0 \\ + 0 & 0 & r \\ + \end{bmatrix} + \begin{bmatrix} + i\\ + j\\ + k\\ + \end{bmatrix} + +A rotation in three dimensions can be represented as a 3 by 3 *rotation +matrix* (`wikipedia rotation matrix`_). For example, here is a rotation by +$\theta$ radians around the third array axis: + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + \end{bmatrix} = + \begin{bmatrix} + \cos(\theta) & -\sin(\theta) & 0 \\ + \sin(\theta) & \cos(\theta) & 0 \\ + 0 & 0 & 1 \\ + \end{bmatrix} + \begin{bmatrix} + i\\ + j\\ + k\\ + \end{bmatrix} + +This is a rotation by $\phi$ radians around the second array axis: + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + \end{bmatrix} = + \begin{bmatrix} + \cos(\phi) & 0 & \sin(\phi) \\ + 0 & 1 & 0 \\ + -\sin(\phi) & 0 & \cos(\phi) \\ + \end{bmatrix} + \begin{bmatrix} + i\\ + j\\ + k\\ + \end{bmatrix} + +.. _rotate-axis-0: + +A rotation of $\gamma$ radians around the first array axis: + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + \end{bmatrix} = + \begin{bmatrix} + 1 & 0 & 0 \\ + 0 & \cos(\gamma) & -\sin(\gamma) \\ + 0 & \sin(\gamma) & \cos(\gamma) \\ + \end{bmatrix} + \begin{bmatrix} + i\\ + j\\ + k\\ + \end{bmatrix} + +Zoom and rotation matrices can be combined by matrix multiplication. + +Here's a scaling of $p, q, r$ units followed by a rotation of $\theta$ radians +around the third axis followed by a rotation of $\phi$ radians around the +second axis: + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + \end{bmatrix} = + \begin{bmatrix} + \cos(\phi) & 0 & \sin(\phi) \\ + 0 & 1 & 0 \\ + -\sin(\phi) & 0 & \cos(\phi) \\ + \end{bmatrix} + \begin{bmatrix} + \cos(\theta) & -\sin(\theta) & 0 \\ + \sin(\theta) & \cos(\theta) & 0 \\ + 0 & 0 & 1 \\ + \end{bmatrix} + \begin{bmatrix} + p & 0 & 0 \\ + 0 & q & 0 \\ + 0 & 0 & r \\ + \end{bmatrix} + \begin{bmatrix} + i\\ + j\\ + k\\ + \end{bmatrix} + +This can also be written: + +.. math:: + + M = + \begin{bmatrix} + \cos(\phi) & 0 & \sin(\phi) \\ + 0 & 1 & 0 \\ + -\sin(\phi) & 0 & \cos(\phi) \\ + \end{bmatrix} + \begin{bmatrix} + \cos(\theta) & -\sin(\theta) & 0 \\ + \sin(\theta) & \cos(\theta) & 0 \\ + 0 & 0 & 1 \\ + \end{bmatrix} + \begin{bmatrix} + p & 0 & 0 \\ + 0 & q & 0 \\ + 0 & 0 & r \\ + \end{bmatrix} + + \begin{bmatrix} + x\\ + y\\ + z\\ + \end{bmatrix} = M + \begin{bmatrix} + i\\ + j\\ + k\\ + \end{bmatrix} + +This might be obvious because the matrix multiplication is the result of +applying each transformation in turn on the coordinates output from the +previous transformation. Combining the transformations into a single matrix +$M$ works because matrix multiplication is associative -- $ABCD = (ABC)D$. + +A translation in three dimensions can be represented as a length 3 vector to +be added to the length 3 coordinate. For example, a translation of $a$ units +on the first axis, $b$ on the second and $c$ on the third might be written +as: + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + \end{bmatrix} = + \begin{bmatrix} + i\\ + j\\ + k\\ + \end{bmatrix} + + \begin{bmatrix} + a \\ + b \\ + c \\ + \end{bmatrix} + +We can write our function $f$ as a combination of matrix multiplication by +some 3 by 3 rotation / zoom matrix $M$ followed by addition of a 3 by 1 +translation vector $(a, b, c)$ + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + \end{bmatrix} = M + \begin{bmatrix} + i\\ + j\\ + k\\ + \end{bmatrix} + + \begin{bmatrix} + a\\ + b\\ + c\\ + \end{bmatrix} + +We could record the parameters necessary for $f$ as the 3 by 3 matrix, $M$ +and the 3 by 1 vector $(a, b, c)$. + +In fact, the 4 by 4 image *affine array* does include exactly this +information. If $m_{i,j}$ is the value in row $i$ column $j$ of matrix $M$, +then the image affine matrix $A$ is: + +.. math:: + + A = + \begin{bmatrix} + m_{1,1} & m_{1,2} & m_{1,3} & a \\ + m_{2,1} & m_{2,2} & m_{2,3} & b \\ + m_{3,1} & m_{3,2} & m_{3,3} & c \\ + 0 & 0 & 0 & 1 \\ + \end{bmatrix} + +Why the extra row of $[0, 0, 0, 1]$? We need this row because we have +rephrased the combination of rotations / zooms and translations as a +transformation in *homogeneous coordinates* (see `wikipedia homogeneous +coordinates`_). This is a trick that allows us to put the translation part +into the same matrix as the rotations / zooms, so that both translations and +rotations / zooms can be applied by matrix multiplication. In order to make +this work, we have to add an extra 1 to our input and output coordinate +vectors: + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + 1\\ + \end{bmatrix} = + \begin{bmatrix} + m_{1,1} & m_{1,2} & m_{1,3} & a \\ + m_{2,1} & m_{2,2} & m_{2,3} & b \\ + m_{3,1} & m_{3,2} & m_{3,3} & c \\ + 0 & 0 & 0 & 1 \\ + \end{bmatrix} + \begin{bmatrix} + i\\ + j\\ + k\\ + 1\\ + \end{bmatrix} + +This results in the same transformation as applying $M$ and $(a, b, c)$ +separately. One advantage of encoding transformations this way is that we can +combine two sets of [rotations, zooms, translations] by matrix multiplication +of the two corresponding affine matrices. + +In practice, although it is common to combine 3D transformations using 4 by 4 +affine matrices, we usually *apply* the transformations by breaking up the +affine matrix into its component $M$ matrix and $(a, b, c)$ vector and doing: + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + \end{bmatrix} = M + \begin{bmatrix} + i\\ + j\\ + k\\ + \end{bmatrix} + + \begin{bmatrix} + a\\ + b\\ + c\\ + \end{bmatrix} + +As long as the last row of the 4 by 4 is $[0, 0, 0, 1]$, applying the +transformations in this way is mathematically the same as using the full 4 by +4 form, without the inconvenience of adding the extra 1 to our input and +output vectors. + +***************************************************************** +The inverse of the affine gives the mapping from scanner to voxel +***************************************************************** + +The affine arrays we have described so far have another pleasant property |--| +they are usually invertible. As y'all know, the inverse of a matrix $A$ is +the matrix $A^{-1}$ such that $I = A^{-1} A$, where $I$ is the identity +matrix. Put another way: + +.. math:: + + \begin{bmatrix} + x\\ + y\\ + z\\ + 1\\ + \end{bmatrix} = A + \begin{bmatrix} + i\\ + j\\ + k\\ + 1\\ + \end{bmatrix} + + A^{-1}\begin{bmatrix} + x\\ + y\\ + z\\ + 1\\ + \end{bmatrix} = A^{-1} A + \begin{bmatrix} + i\\ + j\\ + k\\ + 1\\ + \end{bmatrix} + + \begin{bmatrix} + i\\ + j\\ + k\\ + 1\\ + \end{bmatrix} = A^{-1} + \begin{bmatrix} + x\\ + y\\ + z\\ + 1\\ + \end{bmatrix} + +That means that the inverse of the affine matrix gives the transformation from +scanner RAS+ coordinates to voxel coordinates in the image data. + +Now imagine we have affine array $A$ for ``someones_epi.nii.gz``, and affine array +$B$ for ``someones_anatomy.nii.gz``. $A$ gives the mapping from voxels in the +image data array of ``someones_epi.nii.gz`` to millimeters in scanner RAS+. $B$ +gives the mapping from voxels in image data array of +``someones_anatomy.nii.gz`` to *the same* scanner RAS+. Now let's say we have +a particular voxel coordinate $(i, j, k)$ in the data array of +``someones_epi.nii.gz``, and we want to find the voxel in +``someones_anatomy.nii.gz`` that is in the same spatial position. Call this +matching voxel coordinate $(i', j', k')$ . We first apply the transform from +``someones_epi.nii.gz`` voxels to scanner RAS+ ($A$) and then apply the transform +from scanner RAS+ to voxels in ``someones_anatomy.nii.gz`` ($B^{-1}$): + +.. math:: + + \begin{bmatrix} + i'\\ + j'\\ + k'\\ + 1\\ + \end{bmatrix} = B^{-1} A + \begin{bmatrix} + i\\ + j\\ + k\\ + 1\\ + \end{bmatrix} + +********************* +The affine by example +********************* + +We can get the affine from the nibabel image object. Here is the affine for +the EPI scan: + +.. plot:: + :context: + :nofigs: + + >>> # Set numpy to print 3 decimal points and suppress small values + >>> import numpy as np + >>> np.set_printoptions(precision=3, suppress=True) + >>> # Print the affine + >>> epi_img.affine + array([[ 3. , 0. , 0. , -78. ], + [ 0. , 2.866, -0.887, -76. ], + [ 0. , 0.887, 2.866, -64. ], + [ 0. , 0. , 0. , 1. ]]) + +As you see, the last row is $[0, 0, 0, 1]$ + +Applying the affine +=================== + +To make the affine simpler to apply, we split it into $M$ and $(a, b, c)$: + +.. plot:: + :context: + :nofigs: + + >>> M = epi_img.affine[:3, :3] + >>> abc = epi_img.affine[:3, 3] + +Then we can define our function $f$: + +.. plot:: + :context: + :nofigs: + + >>> def f(i, j, k): + ... """ Return X, Y, Z coordinates for i, j, k """ + ... return M.dot([i, j, k]) + abc + +The labels on the :ref:`localizer image ` give the impression +that the center voxel of ``someones_epi.nii.gz`` was a little above the magnet +isocenter. Now we can check: + +.. plot:: + :context: + :nofigs: + + >>> epi_vox_center = (np.array(epi_img_data.shape) - 1) / 2. + >>> f(epi_vox_center[0], epi_vox_center[1], epi_vox_center[2]) + array([ 0. , -4.205, 8.453]) + +That means the center of the image field of view is at the isocenter of the +magnet on the left to right axis, and is around 4.2mm posterior to the +isocenter and ~8.5 mm above the isocenter. + +The parameters in the affine array can therefore give the position of any +voxel coordinate, relative to the scanner RAS+ reference space. + +We get the same result from applying the affine directly instead of using $M$ +and $(a, b, c)$ in our function. As above, we need to add a 1 +to the end of the vector to apply the 4 by 4 affine matrix. + +.. plot:: + :context: + :nofigs: + + >>> epi_img.affine.dot(list(epi_vox_center) + [1]) + array([ 0. , -4.205, 8.453, 1. ]) + +In fact nibabel has a function ``apply_affine`` that applies an affine to an +$(i, j, k)$ point by splitting the affine into $M$ and $abc$ then multiplying +and adding as above: + +.. plot:: + :context: + :nofigs: + + >>> from nibabel.affines import apply_affine + >>> apply_affine(epi_img.affine, epi_vox_center) + array([ 0. , -4.205, 8.453]) + +Now we can apply the affine, we can use matrix inversion on the anatomical +affine to map between voxels in the EPI image and voxels in the anatomical +image. + +.. plot:: + :context: + :nofigs: + + >>> import numpy.linalg as npl + >>> epi_vox2anat_vox = npl.inv(anat_img.affine).dot(epi_img.affine) + +What is the voxel coordinate in the anatomical corresponding to the voxel +center of the EPI image? + +.. plot:: + :context: + :nofigs: + + >>> apply_affine(epi_vox2anat_vox, epi_vox_center) + array([28.364, 31.562, 36.165]) + +The voxel coordinate of the center voxel of the anatomical image is: + +.. plot:: + :context: + :nofigs: + + >>> anat_vox_center = (np.array(anat_img_data.shape) - 1) / 2. + >>> anat_vox_center + array([28. , 33. , 27.5]) + +The voxel location in the anatomical image that matches the center voxel of +the EPI image is nearly exactly half way across the first axis, a voxel or two +back from the anatomical voxel center on the second axis, and about 9 voxels +above the anatomical voxel center. We can check the :ref:`localizer image +` by eye to see whether this makes sense, by seeing how the +red EPI field of view center relates to the blue anatomical field of view +center and the blue anatomical image field of view. + +The affine as a series of transformations +========================================= + +You can think of the image affine as a combination of a series of +transformations to go from voxel coordinates to mm coordinates in terms of the +magnet isocenter. Here is the EPI affine broken down into a series of +transformations, with the results shown on the localizer image: + +.. image:: /images/illustrating_affine.png + +We start by putting the voxel grid onto the isocenter coordinate +system, so a translation of one voxel equates to a translation of one +millimeter in the isocenter coordinate system. Our EPI image would then have +the black bounding box in the image above. Next we scale the voxels to +millimeters by scaling by the voxel size (green bounding box). We could do +this with an affine: + +.. plot:: + :context: + :nofigs: + + >>> scaling_affine = np.array([[3, 0, 0, 0], + ... [0, 3, 0, 0], + ... [0, 0, 3, 0], + ... [0, 0, 0, 1]]) + +After applying this affine, when we move one voxel in any direction, we are +moving 3 millimeters in that direction: + +.. plot:: + :context: + :nofigs: + + >>> one_vox_axis_0 = [1, 0, 0] + >>> apply_affine(scaling_affine, one_vox_axis_0) + array([3, 0, 0]) + +Next we rotate the scaled voxels around the first axis by 0.3 radians (see +:ref:`rotate around first axis `): + +.. plot:: + :context: + :nofigs: + + >>> cos_gamma = np.cos(0.3) + >>> sin_gamma = np.sin(0.3) + >>> rotation_affine = np.array([[1, 0, 0, 0], + ... [0, cos_gamma, -sin_gamma, 0], + ... [0, sin_gamma, cos_gamma, 0], + ... [0, 0, 0, 1]]) + >>> affine_so_far = rotation_affine.dot(scaling_affine) + >>> affine_so_far + array([[ 3. , 0. , 0. , 0. ], + [ 0. , 2.866, -0.887, 0. ], + [ 0. , 0.887, 2.866, 0. ], + [ 0. , 0. , 0. , 1. ]]) + +The EPI voxel block coordinates transformed by ``affine_so_far`` are at the +position of the yellow box on the figure. + +Finally we translate the 0, 0, 0 coordinate at the bottom, posterior, left +corner of our array to be at its final position relative to the isocenter, +which is -78, -76, -64: + +.. plot:: + :context: + :nofigs: + + >>> translation_affine = np.array([[1, 0, 0, -78], + ... [0, 1, 0, -76], + ... [0, 0, 1, -64], + ... [0, 0, 0, 1]]) + >>> whole_affine = translation_affine.dot(affine_so_far) + >>> whole_affine + array([[ 3. , 0. , 0. , -78. ], + [ 0. , 2.866, -0.887, -76. ], + [ 0. , 0.887, 2.866, -64. ], + [ 0. , 0. , 0. , 1. ]]) + +This brings the affine-transformed voxel coordinates to the red box on the +figure, matching the position on the :ref:`localizer `. + +********************** +Other reference spaces +********************** + +The scanner RAS+ reference space is a "real-world" space, in the sense that a +coordinate in this space refers to a position in the real world, in a +particular scanner in a particular room. + +Imagine that we used some fancy software to register ``someones_epi.nii.gz`` +to a template image, such as the Montreal Neurological Institute (MNI) +template brain. The registration has moved the voxels around in complicated +ways |--| the image has changed shape to match the template brain. We +probably do not want to know how the voxel locations relate to the original +scanner, but how they relate to the template brain. So, what reference space +should we use? + +In this case we use a space defined in terms of the template brain |--| the MNI +reference space. + +* The origin (0, 0, 0) point is defined to be the point that the anterior + commissure of the MNI template brain crosses the midline (the AC point). +* Axis units are millimeters. +* The Y axis follows the midline of the MNI brain between the left and right + hemispheres, going from posterior (negative) to anterior (positive), passing + through the AC point. The template defines this line. +* The Z axis is at right angles to the Y axis, going from inferior (negative) + to superior (positive), with the superior part of the line passing between + the two hemispheres. +* The X axis is a line going from the left side of the brain (negative) to + right side of the brain (positive), passing through the AC point, and at + right angles to the Y and Z axes. + +These axes are defined with reference to the template. The exact position of +the Y axis, for example, is somewhat arbitrary, as is the definition of the +origin. Left and right are left and right as defined by the template. These +are the axes and the space that MNI defines for its template. + +A coordinate in this reference system gives a position relative to the +particular brain template. It is not a real-world space because it does not +refer to any particular place but to a position relative to a template. + +The axes are still left to right, posterior to anterior and inferior to +superior in terms of the template subject. This is still an RAS+ space |--| +the MNI RAS+ space. + +An image aligned to this template will therefore have an affine giving the +relationship between voxels in the aligned image and the MNI RAS+ space. + +There are other reference spaces. For example, we might align an image to the +Talairach atlas brain. This brain has a different shape and size than the MNI +brain. The origin is the AC point, but the Y axis passes through the point +that the posterior commissure crosses the midline (the PC point), giving a +slightly different trajectory from the MNI Y axis. Like the MNI RAS+ space, +the Talairach axes also run left to right, posterior to anterior and inferior +superior, so this is the Talairach RAS+ space. + +There are conventions other than RAS+ for the reference space. For example, +DICOM files map input voxel coordinates to coordinates in scanner LPS+ space. +Scanner LPS+ space uses the same scanner axes and isocenter as scanner RAS+, +but the X axis goes from right to the subject's Left, the Y axis goes from +anterior to Posterior, and the Z axis goes from inferior to Superior. A +positive X coordinate in this space would mean the point was to the subject's +*left* compared to the magnet isocenter. + +**************************************** +Nibabel always uses an RAS+ output space +**************************************** + +Nibabel images always use RAS+ output coordinates, regardless of the preferred +output coordinates of the underlying format. For example, we convert affines +for DICOM images to output RAS+ coordinates instead of LPS+ coordinates. We +chose this convention because it is the most popular in neuroimaging; for +example, it is the standard used by NIfTI_ and MINC_ formats. + +Nibabel does not enforce a particular RAS+ space. For example, NIfTI images +contain codes that specify whether the affine maps to scanner or MNI or +Talairach RAS+ space. For the moment, you have to consult the specifics of +each format to find which RAS+ space the affine maps to. + +See also :doc:`neuro_radio_conventions` + +.. include:: links_names.txt diff --git a/_sources/devel/add_image_format.rst.txt b/_sources/devel/add_image_format.rst.txt new file mode 100644 index 0000000000..6251876464 --- /dev/null +++ b/_sources/devel/add_image_format.rst.txt @@ -0,0 +1,159 @@ +######################################## +How to add a new image format to nibabel +######################################## + +These are some work-in-progress notes in the hope that they will help adding a +new image format to NiBabel. + +********** +Philosophy +********** + +As usual, the general idea is to make your image as explicit and transparent +as possible. + +From the Zen of Python (``import this``), these guys spring to mind: + +* Explicit is better than implicit. +* Errors should never pass silently. +* In the face of ambiguity, refuse the temptation to guess. +* Now is better than never. +* If the implementation is hard to explain, it's a bad idea. + +So far we have tried to make the nibabel version of the image as close as +possible to the way the user of the particular format is expecting to see it. + +For example, the NIfTI format documents describe the image with the first +dimension of the image data array being the fastest varying in memory (and on +disk). Numpy defaults to having the last dimension of the array being the +fastest varying in memory. We chose to have the first dimension vary fastest +in memory to match the conventions in the NIfTI specification. + +****************************** +Helping us to review your code +****************************** + +You are likely to know the image format much much better than the rest of us +do, but to help you with the code, we will need to learn. The following will +really help us get up to speed: + +#. Links in the code or in the docs to the information on the file format. + For example, you'll see the canonical links for the NIfTI 2 format at the + top of the :mod:`.nifti2` file, in the module docstring; +#. Example files in the format; see :doc:`add_test_data`; +#. Good test coverage. The tests help us see how you are expecting the code + and the format to be used. We recommend writing the tests first; the tests + do an excellent job in helping us and you see how the API is going to work. + +*************************** +The format can be read-only +*************************** + +Read-only access to a format is better than no access to a format, and often +much better. For example, we can read but not write PAR / REC and MINC files. +Having the code to read the files makes it easier to work with these files in +Python, and easier for someone else to add the ability to write the format +later. + +************* +The image API +************* + +An image should conform to the image API. See the module docstring for +:mod:`.spatialimages` for a description of the API. + +You should test whether your image does conform to the API by adding a test +class for your image in :mod:`nibabel.tests.test_image_api`. For example, the +API test for the PAR / REC image format looks like:: + + class TestPARRECAPI(LoadImageAPI): + def loader(self, fname): + return parrec.load(fname) + + example_images = PARREC_EXAMPLE_IMAGES + +where your work is to define the ``EXAMPLE_IMAGES`` list |--| see the +:mod:`nibabel.tests.test_parrec` file for the PAR / REC example images +definition. + +**************************** +Where to start with the code +**************************** + +There is no API requirement that a new image format inherit from the general +:class:`.SpatialImage` class, but in fact all our image +formats do inherit from this class. We strongly suggest you do the same, to +get many simple methods implemented for free. You can always override the +ones you don't want. + +There is also a generic header class you might consider building on to contain +your image metadata |--| :class:`.Header`. See that +class for the header API. + +The API does not require it, but if it is possible, it may be good to +implement the image data as loaded from disk as an array proxy. See the +docstring of :mod:`.arrayproxy` for a description of the API, and see the +module code for an implementation of the API. You may be able to use the +unmodified :class:`.ArrayProxy` class for your image type. + +If you write a new array proxy class, add tests for the API of the class in +:mod:`nibabel.tests.test_proxy_api`. See +:class:`.TestPARRECAPI` for an example. + +A nibabel image is the association of: + +#. The image array data (as implemented by an array proxy or a numpy array); +#. An affine relating the image array coordinates to an RAS+ world (see + :doc:`../coordinate_systems`); +#. Image metadata in the form of a header. + +Your new image constructor may well be the default from +:class:`.SpatialImage`, which looks like this:: + + def __init__(self, dataobj, affine, header=None, + extra=None, file_map=None): + +Your job when loading a file is to create: + +#. ``dataobj`` - an array or array proxy; +#. ``affine`` - 4 by 4 array relating array coordinates to world coordinates; +#. ``header`` - a metadata container implementing at least ``get_data_dtype``, + ``get_data_shape``. + +You will likely implement this logic in the ``from_file_map`` method of the +image class. See :class:`.PARRECImage` for an example. + +*************************************** +A recipe for writing a new image format +*************************************** + +#. Find one or more examples images; +#. Put them in ``nibabel/tests/data`` or a data submodule (see + :doc:`add_test_data`); +#. Create a file ``nibabel/tests/test_my_format_name_here.py``; +#. Use some program that can read the format correctly to fill out the needed + fields for an ``EXAMPLE_IMAGES`` list (see + :mod:`nibabel.tests.test_parrec.py` for example); +#. Add a test class using your ``EXAMPLE_IMAGES`` to + :mod:`nibabel.tests.test_image_api`, using the PARREC image test class as + an example. Now you have some failing tests |--| good job!; +#. If you can, extract the metadata information from the test file, so it is + small enough to fit as a small test file into ``nibabel/tests/data`` (don't + forget the license); +#. Write small maybe private functions to extract the header metadata from + your new test file, testing these functions in + ``test_my_format_name_here.py``. See :mod:`.parrec` for examples; +#. When that is working, try sub-classing :class:`.Header`, and working out how + to make the ``__init__`` and ``from_fileboj`` methods for that class. Test + in ``test_my_format_name_here.py``; +#. When that is working, try sub-classing :class:`.SpatialImage` and working + out how to load the file with the ``from_file_map`` class; +#. Now try seeing if you can get your ``test_image_api.py`` tests to pass; +#. Consider adding more test data files, maybe to a test data repository + submodule (:doc:`add_test_data`). Check you can read these files correctly + (see :mod:`nibabel.tests.test_parrec_data` for an example). +#. Ask for advice as early and as often as you can, either with a + work-in-progress pull request (the easiest way for us to review) or on + the mailing list or via github issues. + +.. include:: ../links_names.txt diff --git a/_sources/devel/add_test_data.rst.txt b/_sources/devel/add_test_data.rst.txt new file mode 100644 index 0000000000..b25e417cc9 --- /dev/null +++ b/_sources/devel/add_test_data.rst.txt @@ -0,0 +1,137 @@ +################ +Adding test data +################ + +#. We really, really like test images, but +#. We are rather conservative about the size of our code repository. + +So, we have two different ways of adding test data. + +#. Small, open licensed files can go in the ``nibabel/tests/data`` directory + (see below); +#. Larger files or files with extra licensing terms can go in their own git + repositories and be added as submodules to the ``nibabel-data`` directory. + +*********** +Small files +*********** + +Small files are around 50K or less when compressed. By "compressed", we mean, +compressed with zlib, which is what git uses when storing the file in the +repository. You can check the exact length directly with Python and a script +like:: + + import sys + import zlib + + for fname in sys.argv[1:]: + with open(fname, 'rb') as fobj: + contents = fobj.read() + compressed = zlib.compress(contents) + print(fname, len(compressed) / 1024.) + +One way of making files smaller when compressed is to set uninteresting values +to zero or some other number so that the compression algorithm can be more +effective. + +Please don't compress the file yourself before committing to a git repo unless +there's a really good reason; git will do this for you when adding to the +repository, and it's a shame to make git compress a compressed file. + +************************ +Files with open licenses +************************ + +We very much prefer files with completely open licenses such as the `PDDL +1.0`_ or the CC0_ license. + +The files in the ``nibabel/tests/data`` will get distributed with the nibabel +source code, and this can easily get installed without the user having an +opportunity to review the full license. We don't think this is compatible +with extra license terms like agreeing to cite the people who provided the +data or agreeing not to try and work out the identity of the person who has +been scanned, because it would be too easy to miss these requirements when +using nibabel. It is fine to use files with these kind of licenses, but they +should go in their own repository to be used as a submodule, so they do not +need to be distributed with nibabel. + +***************************************** +Adding the file to ``nibabel/tests/data`` +***************************************** + +If the file is less then about 50K compressed, and the license is open, then +you might want to commit the file under ``nibabel/tests/data``. + +Put the license for any new files in the COPYING file at the top level of the +nibabel repo. You'll see some examples in that file already. + +***************************************** +Adding as a submodule to ``nibabel-data`` +***************************************** + +Make a new git repository with the data. + +There are example repos at + +* https://github.com/yarikoptic/nitest-balls1 +* https://github.com/matthew-brett/nitest-minc2 + +Despite the fact that both the examples are on github, Bitbucket_ is good for +repos like this because they don't enforce repository size limits. + +Don't forget to include a LICENSE and README file in the repo. + +When all is done, and the repository is safely on the internet and accessible, +add the repo as a submodule to the ``nitests-data`` directory, with something +like this:: + + git submodule add https://bitbucket.org/nipy/rosetta-samples.git nitests-data/rosetta-samples + +You should now have a checked out copy of the ``rosetta-samples`` repository +in the ``nibabel-data/rosetta-samples`` directory. Commit the submodule that +is now in your git staging area. + +If you are writing tests using files from this repository, you should use the +``needs_nibabel_data`` decorator to skip the tests if the data has not been +checked out into the submodules. See ``nibabel/tests/test_parrec_data.py`` +for an example. For our example repository above it might look something +like:: + + from .nibabel_data import get_nibabel_data, needs_nibabel_data + + ROSETTA_DATA = pjoin(get_nibabel_data(), 'rosetta-samples') + + @needs_nibabel_data('rosetta-samples') + def test_something(): + # Some test using the data + +Using submodules for tests +========================== + +Tests run via `nibabel on travis`_ start with an automatic checkout of all +submodules in the project, so all test data submodules get checked out by +default. + +If you are running the tests locally, you may well want to do:: + + git submodule update --init + +from the root nibabel directory. This will checkout all the test data +repositories. + +How much data should go in a single submodule? +============================================== + +The limiting factor is how long it takes travis-ci_ to checkout the data for +the tests. Up to a hundred megabytes in one repository should be OK. The joy +of submodules is we can always drop a submodule, split the repository into two +and add only one back, so you aren't committing us to anything awful if you +accidentally put some very large files into your own data repository. + +If in doubt +=========== + +If you are not sure, try us with a pull request to `nibabel github`_, or on the +`nipy mailing list`_, we will try to help. + +.. include:: ../links_names.txt diff --git a/_sources/devel/advanced_testing.rst.txt b/_sources/devel/advanced_testing.rst.txt new file mode 100644 index 0000000000..77b6522cb1 --- /dev/null +++ b/_sources/devel/advanced_testing.rst.txt @@ -0,0 +1,32 @@ +.. -*- mode: rst -*- +.. ex: set sts=4 ts=4 sw=4 et tw=79: + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + # + # See COPYING file distributed along with the NiBabel package for the + # copyright and license terms. + # + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + +.. _advanced_testing: + +**************** +Advanced Testing +**************** + +Setup +----- + +Before running advanced tests, please update all submodules of nibabel, by +running ``git submodule update --init`` + +Long-running tests +------------------ + +Long-running tests are not enabled by default, and can be resource-intensive. To run these tests: + +* Set environment variable ``NIPY_EXTRA_TESTS=slow``; +* Run ``pytest nibabel``. + +Note that some tests may require a machine with >4GB of RAM. + +.. include:: ../links_names.txt diff --git a/_sources/devel/biaps/biap_0000.rst.txt b/_sources/devel/biaps/biap_0000.rst.txt new file mode 100644 index 0000000000..b960505abe --- /dev/null +++ b/_sources/devel/biaps/biap_0000.rst.txt @@ -0,0 +1,281 @@ +.. _biap0: + +============================ +BIAP 0 - Purpose and process +============================ + +:Author: Jarrod Millman +:Status: Draft +:Type: Process +:Created: 2020-06-25 + + +What is a BIAP? +--------------- + + +BIAP stands for Nibabel Enhancement Proposal. BIAPs are the primary +mechanisms for proposing major new features, for collecting community input on +an issue, and for documenting the design decisions that have gone into +Nibabel. A BIAP should provide a concise technical specification of the +feature and a rationale for the feature. The BIAP author is responsible for +building consensus within the community and documenting dissenting opinions. + +Because the BIAPs are maintained as text files in a versioned +repository, their revision history is the historical record of the +feature proposal [1]_. + + +Types +^^^^^ + +There are three kinds of BIAPs: + +1. A **Standards Track** BIAP describes a new feature or implementation + for Nibabel. + +2. An **Informational** BIAP describes a Nibabel design issue, or provides + general guidelines or information to the Python community, but does not + propose a new feature. Informational BIAPs do not necessarily represent a + Nibabel community consensus or recommendation, so users and implementers are + free to ignore Informational BIAPs or follow their advice. + +3. A **Process** BIAP describes a process surrounding Nibabel, or + proposes a change to (or an event in) a process. Process BIAPs are + like Standards Track BIAPs but apply to areas other than the Nibabel + language itself. They may propose an implementation, but not to + Nibabel's codebase; they require community consensus. Examples include + procedures, guidelines, changes to the decision-making process, and + changes to the tools or environment used in Nibabel development. + Any meta-BIAP is also considered a Process BIAP. + + +BIAP Workflow +------------- + +The BIAP process begins with a new idea for Nibabel. It is highly +recommended that a single BIAP contain a single key proposal or new +idea. Small enhancements or patches often don't need +a BIAP and can be injected into the Nibabel development workflow with a +pull request to the Nibabel `repo`_. The more focused the +BIAP, the more successful it tends to be. +If in doubt, split your BIAP into several well-focused ones. + +Each BIAP must have a champion---someone who writes the BIAP using the style +and format described below, shepherds the discussions in the appropriate +forums, and attempts to build community consensus around the idea. The BIAP +champion (a.k.a. Author) should first attempt to ascertain whether the idea is +suitable for a BIAP. Posting to the Nibabel discussion `mailing list`_ is the +best way to go about doing this. + +The proposal should be submitted as a draft BIAP via a `GitHub pull request`_ +to the ``doc/source/devel/biaps`` directory with the name ``biap_.rst`` +where ```` is an appropriately assigned four-digit number (e.g., +``biap_0000.rst``). The draft must use the :doc:`biap_template` file. + +Once the PR for the BIAP is in place, a post should be made to the +mailing list containing the sections up to "Backward compatibility", +with the purpose of limiting discussion there to usage and impact. +Discussion on the pull request will have a broader scope, also including +details of implementation. + +At the earliest convenience, the PR should be merged (regardless of +whether it is accepted during discussion). Additional PRs may be made +by the Author to update or expand the BIAP, or by maintainers to set +its status, discussion URL, etc. + +Standards Track BIAPs consist of two parts, a design document and a +reference implementation. It is generally recommended that at least a +prototype implementation be co-developed with the BIAP, as ideas that sound +good in principle sometimes turn out to be impractical when subjected to the +test of implementation. Often it makes sense for the prototype implementation +to be made available as PR to the Nibabel repo (making sure to appropriately +mark the PR as a WIP). + + +Review and Resolution +^^^^^^^^^^^^^^^^^^^^^ + +BIAPs are discussed on the mailing list. The possible paths of the +status of BIAPs are as follows: + +.. image:: biap_flowchart.png + +All BIAPs should be created with the ``Draft`` status. + +Eventually, after discussion, there may be a consensus that the BIAP +should be accepted – see the next section for details. At this point +the status becomes ``Accepted``. + +Once a BIAP has been ``Accepted``, the reference implementation must be +completed. When the reference implementation is complete and incorporated +into the main source code repository, the status will be changed to ``Final``. + +To allow gathering of additional design and interface feedback before +committing to long term stability for a language feature or standard library +API, a BIAP may also be marked as "Provisional". This is short for +"Provisionally Accepted", and indicates that the proposal has been accepted for +inclusion in the reference implementation, but additional user feedback is +needed before the full design can be considered "Final". Unlike regular +accepted BIAPs, provisionally accepted BIAPs may still be Rejected or Withdrawn +even after the related changes have been included in a Python release. + +Wherever possible, it is considered preferable to reduce the scope of a +proposal to avoid the need to rely on the "Provisional" status (e.g. by +deferring some features to later BIAPs), as this status can lead to version +compatibility challenges in the wider Nibabel ecosystem. + +A BIAP can also be assigned status ``Deferred``. The BIAP author or a +core developer can assign the BIAP this status when no progress is being made +on the BIAP. + +A BIAP can also be ``Rejected``. Perhaps after all is said and done it +was not a good idea. It is still important to have a record of this +fact. The ``Withdrawn`` status is similar---it means that the BIAP author +themselves has decided that the BIAP is actually a bad idea, or has +accepted that a competing proposal is a better alternative. + +When a BIAP is ``Accepted``, ``Rejected``, or ``Withdrawn``, the BIAP should be +updated accordingly. In addition to updating the status field, at the very +least the ``Resolution`` header should be added with a link to the relevant +thread in the mailing list archives. + +BIAPs can also be ``Superseded`` by a different BIAP, rendering the +original obsolete. The ``Replaced-By`` and ``Replaces`` headers +should be added to the original and new BIAPs respectively. + +Process BIAPs may also have a status of ``Active`` if they are never +meant to be completed, e.g. BIAP 0 (this BIAP). + + +How a BIAP becomes Accepted +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A BIAP is ``Accepted`` by consensus of all interested contributors. We +need a concrete way to tell whether consensus has been reached. When +you think a BIAP is ready to accept, send an email to the +Nibabel discussion mailing list with a subject like: + + Proposal to accept BIAP #: + +In the body of your email, you should: + +* link to the latest version of the BIAP, + +* briefly describe any major points of contention and how they were + resolved, + +* include a sentence like: "If there are no substantive objections + within 7 days from this email, then the BIAP will be accepted; see + BIAP 0 for more details." + +After you send the email, you should make sure to link to the email +thread from the ``Discussion`` section of the BIAP, so that people can +find it later. + +Generally the BIAP author will be the one to send this email, but +anyone can do it – the important thing is to make sure that everyone +knows when a BIAP is on the verge of acceptance, and give them a final +chance to respond. If there's some special reason to extend this final +comment period beyond 7 days, then that's fine, just say so in the +email. You shouldn't do less than 7 days, because sometimes people are +travelling or similar and need some time to respond. + +In general, the goal is to make sure that the community has consensus, +not provide a rigid policy for people to try to game. When in doubt, +err on the side of asking for more feedback and looking for +opportunities to compromise. + +If the final comment period passes without any substantive objections, +then the BIAP can officially be marked ``Accepted``. You should send a +followup email notifying the list (celebratory emoji optional but +encouraged), and then update the BIAP by setting its ``:Status:`` to +``Accepted``, and its ``:Resolution:`` header to a link to your followup +email. + +If there *are* substantive objections, then the BIAP remains in +``Draft`` state, discussion continues as normal, and it can be +proposed for acceptance again later once the objections are resolved. + +In unusual cases, disagreements about the direction or approach may +require escalation to the Nibabel :ref:`steering_council` who +then decide whether a controversial BIAP is ``Accepted``. + + +Maintenance +^^^^^^^^^^^ + +In general, Standards track BIAPs are no longer modified after they have +reached the Final state as the code and project documentation are considered +the ultimate reference for the implemented feature. +However, finalized Standards track BIAPs may be updated as needed. + +Process BIAPs may be updated over time to reflect changes +to development practices and other details. The precise process followed in +these cases will depend on the nature and purpose of the BIAP being updated. + + +Format and Template +------------------- + +BIAPs are UTF-8 encoded text files using the reStructuredText_ format. Please +see the :doc:`biap_template` file and the reStructuredTextPrimer_ for more +information. We use Sphinx_ to convert BIAPs to HTML for viewing on the web +[2]_. + + +Header Preamble +^^^^^^^^^^^^^^^ + +Each BIAP must begin with a header preamble. The headers +must appear in the following order. Headers marked with ``*`` are +optional. All other headers are required. :: + + :Author: <list of authors' real names and optionally, email addresses> + :Status: <Draft | Active | Accepted | Deferred | Rejected | + Withdrawn | Final | Superseded> + :Type: <Standards Track | Process> + :Created: <date created on, in dd-mmm-yyyy format> + * :Requires: <BIAP numbers> + * :Nibabel-Version: <version number> + * :Replaces: <BIAP number> + * :Replaced-By: <BIAP number> + * :Resolution: <url> + +The Author header lists the names, and optionally the email addresses +of all the authors of the BIAP. The format of the Author header +value must be + + Random J. User <address@dom.ain> + +if the email address is included, and just + + Random J. User + +if the address is not given. If there are multiple authors, each should be on +a separate line. + + +References and Footnotes +------------------------ + +.. [1] This historical record is available by the normal git commands + for retrieving older revisions, and can also be browsed on + `GitHub <https://github.com/nipy/nibabel/tree/master/doc/source/devel/biaps>`_. + +.. [2] The URL for viewing BIAPs on the web is + https://nipy.org/nibabel/devel/biaps/index.html + +.. _repo: https://github.com/nipy/nibabel + +.. _mailing list: https://mail.python.org/mailman/listinfo/neuroimaging + +.. _issue tracker: https://github.com/nipy/nibabel/issues + +.. _`GitHub pull request`: https://github.com/nipy/nibabel/pulls + +.. _reStructuredText: http://docutils.sourceforge.net/rst.html + +.. _reStructuredTextPrimer: http://www.sphinx-doc.org/en/stable/rest.html + +.. _Sphinx: http://www.sphinx-doc.org/en/stable/ diff --git a/_sources/devel/biaps/biap_0001.rst.txt b/_sources/devel/biaps/biap_0001.rst.txt new file mode 100644 index 0000000000..659967b549 --- /dev/null +++ b/_sources/devel/biaps/biap_0001.rst.txt @@ -0,0 +1,299 @@ +.. _biap1: + +################################ +BIAP1 - Towards immutable images +################################ + +:Author: Matthew Brett +:Status: Rejected +:Type: Standards +:Created: 2011-03-23 + +********** +Resolution +********** + +Retired as of nibabel 2.0 in favor of exposed `dataobj` property. See: + +* http://nipy.org/nibabel/nibabel_images.html#the-image-data-array +* http://nipy.org/nibabel/images_and_memory.html + +See image `in_memory` attribute and `uncache` method. + +We haven't implemented an `is_as_loaded` attribute yet. + +********** +Background +********** + +Nibabel implicitly has two types of images + +* array images +* proxy images + +Array images +============ + +Array images are the images you get from a typical constructor call:: + + import numpy as np + import nibabel as nib + arr = np.arange(24).reshape((2,3,4)) + img = nib.Nifti1Image(arr, np.eye(4)) + +``img`` here is an array image, that is to say that, internally, the private +``img._data`` attribute is reference to ``arr`` above. ``img.get_data()`` just +returns ``img._data``. If you modify ``arr``, you will modify the result of +``img.get_data()``. + +Proxy images +============ + +Proxy images are what you get from a call to ``load``:: + + px_img = nib.load('test.nii') + +It's a proxy image in the sense that, internally, ``px_arr._data`` is a proxy +object that does not yet contain an array, but can get an array by the +application of:: + + actual_arr = np.asarray(px_img._data) + +This is in fact what ``px_img.get_data()`` does. Actually, +``px_img.get_data()`` also stores the read array in ``px_img._data``, so that:: + + px_img = nib.load('test.nii') + assert not isinstance(px_img._data, np.ndarray) # it's a proxy + actual_arr = px_img.get_data() + assert isinstance(px_img._data, np.ndarray) # it's an array now + +So, at this point, if you change ``actual_arr`` you'll also be changing +``px_img._data`` and therefore the result of ``px_img.get_data()``. + +In other words, ``actual_arr = px_img.get_data()`` turns the proxy image into an +array image. + +Issues for design +================= + +The code at the moment is a little bit confusing because: + +* there isn't an explicit API to check if you have an array image or a proxy + image and +* there isn't anywhere in the docs that you can go and see this distinction. + +Use cases +========= + +Loading images, minimizing memory +--------------------------------- + +I want to load lots of images, or several large images. I'm going to do +something with the image data. I want to minimize memory use. This tempts me +to do something like this:: + + large_img1 = nib.load('large1.nii') + large_img2 = nib.load('large2.nii') + li1_mean = large_img1.get_data().mean() + li2_mean = large_img2.get_data().mean() + +The problem with the current design is that, after the ``li1_mean =`` line, +``large_img1`` got unproxied, and there's a huge array inside it. + +Loading images, maximizing speed +-------------------------------- + +On the other hand, I might want to do the same thing, but each call to unproxy +the data (loading off disk, applying scalefactors) will be expensive. So, when +I do ``li1_mean = large_img1.get_data().mean()`` I want any subsequent call to +to ``large_img1.get_data()`` to be much faster. This is the case at the moment, +at the expense of the memory hit above. + +Loading images, assert not modified +----------------------------------- + +In pipelines in particular, we frequently want to load images, maybe have a +look at some parameters, and then pass that image *filename* to some other +program such as SPM or FSL. At the moment we've got a problem:: + + img = nib.load('test.nii') + # do stuff + run_spm_thing_on(img) # is 'img' the same as test.nii? + +The problem is that when the routine ``run_spn_thing`` receives ``img``, it +can know that ``img`` has a filename, ``test.nii``, but it can't currently +know if ``img`` is the same object that it was when it was loaded. That is, +it can't know whether ``test.img`` still corresponds to ``img`` or not. In +practice that means that ``run_spm_thing`` will need to save every ``img`` to +another file before passing that filename to the SPM routine, just in case +``img`` has been modified. So, we would like a *dirty bit* for the image, +something like:: + + # Not implemented yet + if not img.is_as_loaded(): + save(img, 'some_filename.nii') + +The last line, like it or not, modifies ``img`` in-place. + +Array images, proxy images, copy, view +====================================== + +With thanks to Roberto Viviani for some clarifying thoughts on the nipy +mailing list. + +At the moment, ``img.get_data()`` always returns a reference to an array. +That is, whenever you call:: + + data = img.get_data() + +Then, if you modify ``data`` you will modify the next result of +``img.get_data()``. + +In particular, the interface currently intends that there should be no +functional difference between proxied images and non-proxied images. The +proposal below exposes a functional difference between them. + +When do you want a copy and when do you want a view? +---------------------------------------------------- + +This is a discussion of this proposal:: + + img.get_data(copy=True|False) + +compared to:: + + img.get_data(unproxy=True|False) + +Summary: + +* array images - you nearly always want a view +* proxy images - you may want a copy, but you want a copy only because you + want to leave the image as a proxy. You might want to leave the image as a + proxy because you want to be sure the image corresponds to the file, or save + memory. + +For array images, it doesn't make sense to return a copy from +``img.get_data()``, because it buys you nothing that you would not get from +``data = img.get_data().copy()``. This is because you can't save memory (the +image already contains the whole array), and it won't help you be sure that +the image has not been modified compared to the original array, because there +may be references to the array that existed before the image was made, that +can be used to modify the data. So, for array images, you always want a +reference, or you want to do a manual copy, as above. + +For proxied images, it does make sense to get a copy, because a) you want to +preserve memory by not unproxying the image, and / or b) you want to be able +to be sure that the file associated with the image still corresponds to the +data. + +For the ``img.get_data(copy=False)`` proposal, on a proxied image, the +``copy=False`` call, in order to return a view, must *implicitly* unproxy the +image. + +Similarly, ``img.get_data(unproxy=False)`` must *implicitly* copy the image. + +It seems to me (MB) that an implicit copy is familiar to a numpy user, but the +implicit unproxying may be less obvious. + +My (MBs) reasons then for preferring 'unproxy' to 'copy=True' or 'copy=False' +or get_data_copy() is that 'unproxy' is closer to how I think the user would +think about deciding what they wanted to do. + +The ``unproxy=False`` case covers the situation where you want to preserve +memory. It doesn't fully cover the cases where we want to keep track of when +the image data has been modified. + +Here there are three cases: + +* array image, instantiated with an array; the image data can be modified + using the array reference passed into the image - we can't know whether the + data has been modified without doing hashing or similar. +* proxy image; the array data is still in the file, so we know it corresponds + to the file. +* proxy images that have been converted to array images, but have not passed + out a reference to the data. Let's call these *shy unproxied* images. For + example, with an API like this:: + + img = load('test.nii') + data = img.get_data(copy=True) + + the ``img`` is now an array image, but there's no public reference to the + internal array object. Someone could get one by cheating with ``ref = + img._data``, but, we don't need to worry about that - following Python's "mess + around if you like but take the consequences" philosophy. + +Proposal +======== + +An ``is_proxy`` property:: + + img.is_proxy + +This is just for clarity. + +Allow the user to specify what unproxying they want with a kwarg to +``get_data()``:: + + arr = large_img1.get_data(unproxy=False) + +* for proxied images, ``unproxy=False`` would leave the underlying array data + as a pointer to the file. The returned ``arr`` would be therefore a copy of + the data as loaded from file, and ``arr[0] = 99`` would have no effect on + the data in the image. ``unproxy=True`` would convert the proxy image into + an array image (load the data into memory, return reference). Here ``arr[0] + = 99`` would affect the data in the image +* for array images, ``unproxy`` would always be ignored. + +Thus ``unproxy=True`` in fact means, +``unproxy_if_this_is_a_proxy_do_nothing_otherwise``. + +The default would continue to be ``unproxy=True`` so that the proxied image +would continue, by default, to behave the same way as an unproxied image +(``get_data`` returns a view). + +If ``img.is_proxy`` is True, then we know that the array data has not changed. +We then need to be sure that the ``header`` and ``affine`` data haven't +changed. We might be able to do this with default ``copy`` kwargs to the +``get_header`` and ``get_affine`` methods:: + + hdr = img.get_header(copy=True) # will be default + aff = img.get_affine(copy=True) # will be default + +We could also do that by caching the original header and affine, but the +header in particular can be rather large. + +For the next version of nibabel, for backwards compatibility, we'll set +``copy=False`` to be the default, but warn about the upcoming change. After +that we'll set ``copy=True`` as the default. + +Now we can know whether the image has been modified, because if ``get_header`` +and ``get_affine`` have only been called with ``copy=True`` and ``img.is_proxy +== True`` - then it must be the same as when loaded. + +This leads to an ``is_as_loaded`` property:: + + if img.is_as_loaded: + fname = img.get_filename() + else: + fname = 'tempname.nii' + save(img, 'tempname.nii') + +Questions +========= + +Should there also be a ``set_header`` and ``set_affine`` method? + +The header may conflict with the affine. So, would we need something like:: + + img.set_header(hdr, hdr_affine_from='affine') + +or some other nasty syntax. Or can we avoid this and just do:: + + img2 = nib.Nifti1Image(img.get_data(), new_affine, new_header) + +? + +How about the names in the proposal? ``is_proxy``; ``unproxy=True``? + + +.. vim: ft=rst diff --git a/_sources/devel/biaps/biap_0002.rst.txt b/_sources/devel/biaps/biap_0002.rst.txt new file mode 100644 index 0000000000..89ba4e913a --- /dev/null +++ b/_sources/devel/biaps/biap_0002.rst.txt @@ -0,0 +1,176 @@ +.. _biap2: + +################# +BIAP2 - Slicecopy +################# + +:Author: Matthew Brett +:Status: Rejected +:Type: Standards +:Created: 2011-03-26 + +****** +Status +****** + +Alternative implementation as of Nibabel 2.0 with image proxy slicing : see +http://nipy.org/nibabel/images_and_memory.html#saving-time-and-memory + +********** +Background +********** + +Please see https://github.com/nipy/nibabel/issues#issue/9 for motivation. + +Sometimes we have a biiig images and we don't want to load the whole array into +memory. In this case it is useful to be able to load as a proxy:: + + img = load('my_huge_image.nii') + +and then take out individual slices, as in something very approximately like:: + + slice0 = img.get_slice(0) + +Questions +========= + +Should ``slice0`` be a copy or a view? +-------------------------------------- + +As from the previous discussion - :doc:`biap_0001` - an image may be a proxy +or an array. + +If the image is an array, the most natural thing to return is a view. That is, +modifying ``slice0`` will modify the underlying array in ``img``. + +If the image is a proxy, it would be self-defeating to return a view, because +that would involve reading the whole image into memory, exactly what we are +trying to avoid. So, for a proxied image, we'd nearly always want to return a +copy. + +What slices should the slicing allow? +------------------------------------- + +The ``img.get_slice(0)`` syntax needs us to know what slice 0 is. In a nifti +image of 3 dimensions, the first is fastest changing on disk. To be useful +``0`` will probably refer to the slowest changing on disk. Otherwise we'll +have to load nearly the whole image anyway. So, for a nifti, 0 should be the +first slice in the last dimension. + +For Minc on the other hand, you can and I (MB) think always do get C ordered +arrays back, so that the slowest changing dimension in the image array is the +first. Actually, I don't know how to read a Minc file slice by slice, but the +general point is that, to know which slice is worth reading, you need to know +the relationship of the image array dimensions to fastest / slowest on disk. + +We could always solve this by assuming that we always want to do this for +Analyze / Nifti1 files (Fortran ordered). It's a little ugly of course. + +Note that taking the slowest changing slice in a nifti image would be the +equivalent of taking a slice from the last dimension:: + + arr = img.get_data() + slice0 = arr[...,0] + +In general, we can get contiguous data off disk for the same data as contiguous +data in memory (perhaps obviously). So, all of these are contiguous in the +Fortran ordering case:: + + arr[...,0:5] + arr[:,:,0] + arr[:,0:,0] + arr[0:,:,0] + arr[:,1,0] + arr[1,1,1] + +That is, in general, ``:`` up until the first specified dimension, then +contiguous slices, followed by integer slices. So, all of these can be read +directly off disk as slices. Obviously the rules are the reverse for c-ordered +arrays. + +Option 1: fancy slice object +============================ + +It's option 1 because it's the first one I thought of: + +.. code:: python + + slice0 = img.slicecopy[...,0] + +Here we solve the copy or view problem with 'always copy'. We solve the 'what +slicing to allow' by letting the object decide how to do the slicing. We could +obviously just do the full load (deproxy the image) and return a copy of the +sliced array, as in: + +.. code:: python + + class SomeImage: + class Slicer: + def __init__(self, parent): + self.parent = parent + def __getitem__(self, slicedef): + data = parent._data + if is_proxy(data) and iscontinguous(slicedef, order='F'): + return read_off_disk_somehow(slicedef, data) + data = parent.get_data(unproxy=True) + return data.__getitem__(slicedef) + def __init__(self, stuff): + self.slicecopy = Slicer(self) + +The problem with this is that: + +.. code:: python + + slice0 = img.slicecopy[...,1] + +might unproxy the image. At the moment, it's rather hidden whether the image +is proxied or not on the basis that it's an optimization that should be +transparent. + +Option 2: not-fancy method call +=============================== + +.. code:: python + + slice0 = img.get_slice(0, copy=True) + +'slice or view' solved with explicit keyword. 'which slice' solved by assuming +you always mean one slice in the last dimension. Or we could also allow: + +.. code:: python + + slices = img.get_slices(slice(0,3), copy=True) + +This is ugly, but fairly clear. This simple 'I mean the last dimension' might +be annoying because it assumes the last dimension is the slowest changing, and +it does not get to optimize the more complex contiguous cases above. So we +could even allow full slicing with stuff like: + +.. code:: python + + slice = img.get_slices((slice(None), slice(None), slice(3)), copy=True) + +Again - this looks a lot more ugly than the ``slicecopy`` syntax above. + +Now, when would you choose ``copy=True``? I think, when the image is a proxy. +Otherwise you'd want a view. Probably. So what you mean, probably, is +something like this: + +.. code:: python + + slices = img.get_slices(slicedef, copy_if='is_proxy') + +But, we've established that for some slices, you're going to have to load the +whole image anyway. So in fact probably what you want is to: + +#. Take a view if this image is not a proxy +#. Take a copy if we can read this directly off disk +#. Unproxy the image if we have to read the whole thing off disk anyway to get + the slices we want, on the basis that we have to read the whole thing into + memory anyway, we might as well do that and save ourselves lots of disk + thrashing getting the individual slices. + +Of course that's what option 1 boils down to. So I think I prefer version 1. + + +.. vim: ft=rst diff --git a/_sources/devel/biaps/biap_0003.rst.txt b/_sources/devel/biaps/biap_0003.rst.txt new file mode 100644 index 0000000000..7abb07efc1 --- /dev/null +++ b/_sources/devel/biaps/biap_0003.rst.txt @@ -0,0 +1,751 @@ +.. _biap3: + +##################################### +BIAP3 - A JSON nifti header extension +##################################### + +:Author: Matthew Brett, Bob Dougherty +:Status: Draft +:Type: Standards +:Created: 2011-03-26 + +The following Wiki documents should be merged with this one: + +* `NIfTI metadata extension + <https://github.com/nipy/nibabel/wiki/NIfTI-metadata-extension>`_ + +******** +Abstract +******** + +A draft specification of the JSON header for Nibabel. + +********** +Background +********** + +DICOM files in particular have a lot of information in them that we might want +to carry with the image. There are other image file types like Minc_ or Nrrd_ +that have information we'd like to support but can't with standard nifti. + +One obvious place to store this information is in a `nifti header extension`_. + +Nifti extension types +===================== + +From `adding nifti extensions`_: + +* 0 = NIFTI_ECODE_IGNORE = unknown private format (not recommended!) +* 2 = NIFTI_ECODE_DICOM = DICOM format (i.e., attribute tags and values): + http://medical.nema.org/ +* 4 = NIFTI_ECODE_AFNI = AFNI header attributes: The format of the AFNI + extension in the NIfTI-1.1 format is described at + http://nifti.nimh.nih.gov/nifti-1/AFNIextension1/ +* 6 = NIFTI_ECODE_COMMENT = comment: arbitrary non-NUL ASCII text, with no + additional structure implied +* 8 = NIFTI_ECODE_XCEDE = XCEDE metadata: + http://www.nbirn.net/Resources/Users/Applications/xcede/index.htm +* 10 = NIFTI_ECODE_JIMDIMINFO = Dimensional information for the JIM software + (XML format); contact info is Dr Mark A Horsfield: mah5*AT*leicester.ac.uk. +* 12 = NIFTI_ECODE_WORKFLOW_FWDS = Fiswidget XML pipeline descriptions; + documented at + http://kraepelin.wpic.pitt.edu/~fissell/NIFTI_ECODE_WORKFLOW_FWDS/NIFTI_ECODE_WORKFLOW_FWDS.html + ; contact info is Kate Fissell: fissell+*AT*pitt.edu. + +Alternatives +============ + +Summary: we need probably need our own extension format + +There is a DICOM type extension - code 2. This might be OK for DICOM but: + +#. We probably don't want to have to dump the entire DICOM header for every + DICOM image. If we don't that means we have to edit the DICOM header, and +#. The DICOM format is awful to work with, so it is not a pleasant prospect + making a new DICOM header for images (like Minc) that aren't DICOM to start + with. +#. I (MB) can't find any evidence that it's being used in the wild. +#. It's not completely clear what format the data should be in. See `this + nifti thread + <http://nifti.nimh.nih.gov/board/read.php?f=1&i=2077&t=2069>`_. + +The AFNI extension format looks as if it is specific to AFNI. + +The XCEDE format looks rather heavy. I'm (MB) trying to work out where the +most current schema is. Candidates are `bxh-xcede-tools`_ and the `xcede +website`_. We'd need to validate the XML with the schema. It appears the +python standard library doesn't support that so we'd need extra XML tools as a +dependency. + +JIM_ is closed source. + +fiswidgets seems to have been quiet recently. The link for code 12 is dead, I +had to go back to the http://www.archive.org to get `an old copy +<http://replay.waybackmachine.org/20060514073534/http://kraepelin.wpic.pitt.edu/~fissell/NIFTI_ECODE_WORKFLOW_FWDS/NIFTI_ECODE_WORKFLOW_FWDS.html>`_ +and that didn't have the DTD or example links that we need to understand the +format. + +Learning from NRRDs +=================== + +Gordon Kindlmann's NRRD_ format has gone through a few versions and has +considerable use particularly by the `3D slicer`_ team. I've tried to +summarize the NRRD innovations not properly covered by nifti in +[[nifti-nrrd]]. + +******** +Proposal +******** + +`JSON <http://json.org/>`_, as y'all know, encodes strings, numbers, objects +and arrays, An object is like a Python dict, with strings as keys, and an +array is like a Python list. + +In what follows, I will build dicts and lists corresponding to the objects and +arrays of the JSON header. In each case, the ``json.dumps`` of the given Python +object gives the corresponding JSON string. + +I'll use the term *field* to refer to a (key, value) pair from a Python dict / +JSON object. + +General principles +================== + +We specify image axes by name in the header, and give the correspondence of the +names to the image array axes by the order of the names. This is the +``axis_names`` field at the top level of the header. + +If the user transposes or otherwise reorders the axes of the data array, the +header should change only in the ordering of the axis names in +``axis_names``. Call this the "axis transpose" principle. + +The JSON header should make sense as a key, value pair store for DICOM +fields using a standard way of selecting DICOM fields -- the *simple DICOM* +principle. + +The NIfTI image also contains the standard image metadata in the NIfTI header +C-struct (the standard NIfTI header). Nibabel and Nipy will write JSON +headers correctly, and so the information in the NIfTI C-struct should always +match the information in the JSON header. Other software may write the JSON +incorrectly, or copy the JSON header into another image to which it may not +apply, but other software should always set the C-struct correctly. For that +reason the C-struct always overrides the JSON header, unless the C-struct has +values implying "not-set" or "don't know". This is the *C-struct primacy* +principle. + +See also +======== + +* `JSON-LD <http://json-ld.org/>`_ - provides a way of using json that can be + mapped into the Resource Description Framework (RDF). It is highly + recommended to take a look at the `RDF Primer + <http://www.w3.org/TR/rdf11-primer/>`_ to get a sense of why we might want + to use JSON-LD/RDF, but essentially it boils down to a couple points: + + * JSON keys are turned into URIs + * URIs can dereference to a Web URL with additional documentation, such as a + definition, a pretty label (e.g., ``nipy_header_version`` has_label + ``"NIPY Header Version"``), etc. + * The URI link to documentation makes the meaning of your JSON keys + explicit, in a machine readable way (i.e., the json key becomes a + "resource" on the Web that avoids name clashes) + * JSON-LD/RDF has a full query language called `SPARQL + <http://www.w3.org/TR/sparql11-query/>`_ and a python library called + `RDFLib <https://rdflib.readthedocs.org/en/latest/>`_ that acts as a + parser, serializer, database, and query engine. + * In the example below, the ``@context`` section provides the namespace + prefix ``dcm`` as a placeholder for the URL + ``http://neurolex.org/wiki/Category:``, thus ``dcm:Echo_Time`` + dereferences to http://neurolex.org/wiki/Category:Echo_Time where + additional documentation is provided:: + + { + "@context": { + "dcm": "http://neurolex.org/wiki/Category:#" + }, + "dcm:Echo_Time": 45, + "dcm:Repetition_Time": 2, + } + +The header must contain the header version +========================================== + +:: + + >>> hdr = dict(nipy_header_version='1.0') + +We chose the name "nipy_header_version" in the hope that this would not often +occur in an unrelated JSON file. + +* First version will be "1.0". +* Versioning will use `Semantic Versioning <http://semver.org>`_ of form + ``major.minor[.patch[-extra]]`` where ``major``, ``minor``, ``patch`` are + all integers, ``extra`` may be a string, and both ``patch`` and ``extra`` + are optional. Header versions with the same ``major`` value are `forwards + compatible <https://en.wikipedia.org/wiki/Forward_compatibility>`_ -- that + is, a reader that can read a header with a particular major version should + be able to read any header with that major version. Specifically, any + changes to the header format within major version number should allow older + readers of that major version to read the header correctly, but can expand + on the information in the header, so that older readers can safely ignore + new information in the header. +* All fields other than ``nipy_header_version`` are optional. The dict in + ``hdr`` above is therefore the minimal valid header. + +The header will usually contain image metadata fields +===================================================== + +The base level header will usually also have image metadata fields giving +information about the whole image. A field is an "image metadata field" if it +is defined at the top level of the header. For example:: + + >>> hdr = dict(nipy_header_version='1.0', + ... Manufacturer="SIEMENS") + +All image metadata fields are optional. + +As for all keys in this standard, IM (Image Metadata) keys are case sensitive. +IM keys that begin with a capital letter must be from the DICOM data +dictionary standard short names (DICOM keyword). Call these "DICOM IM keys". +This is to conform to the *simple DICOM* principle. + +Keys beginning with "extended" will be read and written, but not further +processed by a header reader / writer. If you want to put extra fields into +the header that are outside this standard you could use a dict / object of +form:: + + >>> hdr = dict(nipy_header_version='1.0', + ... extended=dict(my_field1=0.1, my_field2='a string')) + +or:: + + >>> hdr = dict(nipy_header_version='1.0', + ... extended_mysoft=dict(mysoft_one='expensive', mysoft_two=1000)) + +Values for DICOM IM keys are constrained by the DICOM standard. This standard +constrains values for ("nipy_header_version", "axis_names", "axis_metadata"). +Other values have no constraint. + +Questions +========== + +* Should all DICOM values be allowed? +* Should DICOM values be allowed at this level that in fact refer to a + particular axis, and therefore might go in the ``axis_metadata`` elements? +* How should we relate the DICOM standard values to JSON? For example, how + should we store dates and times? One option would be to use the new DICOM + JSON encoding for DICOM values, but omitting the tag and value + representation (VR). For example, the `DICOM JSON spec + <ftp://medical.nema.org/medical/dicom/final/sup166_ft5.pdf>`_ has:: + + "00080070": { + "vr": "LO", + "Value": [ "SIEMENS" ] + }, + + but we might prefer:: + + "Manufacturer": "SIEMENS" + + Using the DICOM data dictionary we can reconstruct the necessary tag and VR, + so our version is lossless if the DICOM keyword exists in the DICOM data + dictionary. Of course this may well not be true for private tags, or if the + keyword comes from a DICOM dictionary that is later than the one we are + using to look up the keyword. For the latter, we could make sure we're + always using the latest dictionary. For the private tags, we might want to + recode these in any case, maybe using our own dictionary. Maybe it is + unlikely we will want to reconstruct the private tags of a DICOM file from + the JSON. Comments welcome. + +The header will usually contain axis names +========================================== + +``axis_names`` is a list of strings corresponding to the axes of the image data +to which the header refers. + +>>> hdr = dict(nipy_header_version='1.0', +... axis_names=["frequency", "phase", "slice", "time"]) + +The names must be valid Python identifiers (should not begin with a digit, nor +contain spaces etc). + +There must be the same number of names as axes in the image to which the header +refers. For example, the header above is valid for a 4D image but invalid for a +3D or 5D image. + +The names appear in fastest-slowest order in which the image data is stored on +disk. The first name in ``axis_names`` corresponds to the axis over which +the data on disk varies fastest, and the last corresponds to the axis over which +the data varies slowest. + +For a NIfTI image, nibabel (and nipy) will create an image where the axes have +this same fastest to slowest ordering in memory. For example, let's say the +read image is called ``img``. ``img`` has shape (4, 5, 6, 10), and a 2-byte +datatype such as int16. In the case of the NIfTI default fastest-slowest ordered +array, the distance in memory between ``img[0, 0, 0, 0]`` and ``img[1, 0, 0, +0]`` is 2 bytes, and the distance between ``img[0, 0, 0, 0]`` and ``img[0, 0, 0, +1]`` is 4 * 5 * 6 * 2 = 240 bytes. The names in ``axis_names`` will then refer +to the first, second, third and fourth axes respectively. In the example above, +"frequency" is the first axis and "time" is the last. + +``axis_names`` is optional only if ``axis_metadata`` is empty or absent. +Otherwise, the ``set()`` of ``axis_names`` must be a superset of the union of +all axis names specified in the ``applies_to`` fields of ``axis_metadata`` +elements. + +The header will often contain axis metadata +=========================================== + +``axis_metadata`` is a list of *axis metadata elements*. + +Each *axis metadata element* in the ``axis_metadata`` list gives data that +applies to a particular axis, or combination of axes. ``axis_metadata`` can +be empty:: + + >>> hdr['axis_metadata'] = [] + +We prefer you delete this section if it is empty, to avoid clutter, but hey, +mi casa, su casa. + +The axis metadata element +------------------------- + +An axis metadata element must contain a field ``applies_to``, with a value that +is a list that contains one or more values from ``axis_names``. From the above +example, the following would be valid axis metadata elements:: + + >>> hdr = dict(nipy_header_version='1.0', + ... axis_names = ["frequency", "phase", "slice", "time"], + ... axis_metadata = [ + ... dict(applies_to = ['time']), + ... dict(applies_to = ['slice']), + ... dict(applies_to = ['slice', 'time']), + ... ]) + +.. note:: + + The ``applies_to`` field plays the role of a dictionary key for each axis + metadata element, where the rest of the fields in the element are a dict + giving the value. For example, in Python (but not in JSON, we could + represent the above as:: + + >>> hdr = dict(nipy_header_version='1.0', + ... axis_names = ["frequency", "phase", "slice", "time"], + ... axis_metadata = { + ... 'time': {}, + ... 'slice': {}, + ... ('slice', 'time'): {}, + ... ]) + + We can't do this in JSON because all object fields must be strings, so we + cannot represent the key ``('slice', 'time')`` directly. The + ``applies_to`` field allows us to do that in JSON. See below for why we + might want to specify more than one axis. + +As for image metadata keys, keys that begin with a capital letter are DICOM +standard keywords. + +A single axis name for ``applies_to`` specifies that any axis metadata values in +the element apply to the named axis. + +In this case, axis metadata values may be: + +* a scalar. The value applies to every point along the corresponding image + axis OR +* a vector of length N (where N is the length of the corresponding image + axis). Value $v_i$ in the vector $v$ corresponds to the image slice at + point $i$ on the corresponding axis OR +* an array of shape (1, ...) where "..." can be any further shape, expressing + a vector or array that applies to all points on the given axis, OR +* an array of shape (N, ...) where "..." can be any further shape. The (N, + ...) array N vectors or arrays with one (vector or array) corresponding to + each point in the image axis. + +More than one axis name for ``applies_to`` specifies that any values in the +element apply to the combination of the given axes. + +In the case of more than one axis for ``applies_to``, the axis metadata values +apply to the Cartesian product of the image axis values. For example, if the +values of ``applies_to`` == ``['slice', 'time']``, and the slice and time axes +in the array are lengths (6, 10) respectively, then the values apply to all +combinations of the 6 possible values for slice indices and the 10 possible +values for the time indices (ie apply to all 6x10=60 values). The axis metadata +values in this case can be: + +* a scalar. The value applies to every combination of (slice, time) +* an array of shape (S, T) (where S is the length of the slice axis and T is + the length of the time axis). Value $a_{i,j}$ in the array $a$ corresponds + to the image slice at point $i$ on the slice axis and $j$ on the time axis. +* an array of shape (S, T, ...) where "..." can be any further shape. The (S, + T, ...) case gives N vectors or arrays with one vector / array corresponding + to each combination of slice, time points in the image, + +In contrast to the single axis case, we do not allow length 1 axes, to +indicate a value constant across an axis. For example, we do not allow shape +(1, T) arrays to indicate a value constant across slice but varying across +time, as this should be specified with the single time axis metadata element. + +In general, for a given value ``applies_to``, we can take the corresponding +axis lengths:: + + >>> shape_of_image = [4, 5, 6, 10] + >>> image_names = ['frequency', 'phase', 'slice', 'time'] + >>> applies_to = ['slice', 'time'] + >>> axis_indices = [image_names.index(name) for name in applies_to] + >>> axis_lengths = [shape_of_image[i] for i in axis_indices] + >>> axis_lengths + [6, 10] + +The axis metadata value can therefore be of shape: + +* () (a scalar) (a scalar value for every combination of points); +* ``axis_lengths`` (a scalar value for each combination of points); +* [1] + ``any_other_list`` if ``len(axis_lengths) == 1``; +* ``axis_lengths + any_other_list`` (an array or vector corresponding to each + combination of points, where the shape of the array or vector is given by + ``any_other_list``) + +For any unique ordered combination of axis names, there can only be on axis +metadata element. For example, this is valid:: + + >>> # VALID + >>> hdr = dict(nipy_header_version='1.0', + ... axis_names = ["frequency", "phase", "slice", "time"], + ... axis_metadata = [ + ... dict(applies_to = ['time']), + ... dict(applies_to = ['slice', 'time']), + ... dict(applies_to = ['slice']), + ... ]) + +This is not, because of the repeated combination of axis names:: + + >>> # NOT VALID because of repeated axis combination + >>> hdr = dict(nipy_header_version='1.0', + ... axis_names = ["frequency", "phase", "slice", "time"], + ... axis_metadata = [ + ... dict(applies_to = ['time']), + ... dict(applies_to = ['slice', 'time']), + ... dict(applies_to = ['slice']), + ... dict(applies_to = ['slice', 'time']), + ... ]) + +.. _q_vector: + +The ``q_vector`` axis metadata field +------------------------------------ + +We define an axis metadata field ``q_vector`` which gives the q vector +corresponding to the diffusion gradients applied. + +The ``q_vector`` should apply to (``applies_to``) one axis, where that axis is +the image volume axis. The ``q_vector`` is a dict / object with two fields, +``spatial_axes`` and ``array``. + +If there are T volumes then the array will be of shape (T, 3). One row from +this array corresponds to the direction of the diffusion gradient with axes +oriented to the three spatial axes of the data. To preserve the *axis +transpose* principle, the ``spatial_axes`` field value is a list of the +spatial image axes to which the first, second and third column of the +``array`` refer. + +For example:: + + >>> import numpy as np + >>> element = dict(applies_to=['time'], + ... q_vector = dict( + ... spatial_axes = ['frequency', 'phase', 'slice'], + ... array = [[0, 0, 0], + ... [1000, 0, 0], + ... [0, 1000, 0], + ... [0, 0, 1000], + ... [0, 0, 0], + ... [1000, 0, 0], + ... [0, 1000, 0], + ... [0, 0, 1000], + ... [0, 0, 0], + ... [1000, 0, 0] + ... ])) + >>> np.array(element['q_vector']['array']).shape + (10, 3) + +An individual (3,) vector is the unit vector expressing the direction of the +gradient, multiplied by the scalar b value of the gradient. In the example, +there are three b == 0 scans (corresponding to volumes 0, 4, 8), with the rest +having b value of 1000. + +The first value corresponds to the direction along the first named image axis +('frequency'), the second value to direction along the second named axis +('phase'), and the third to direction along the 'slice' axis. + +Note that the ``q_vector`` is always specified in the axes of the image. This is +the same convention as FSL uses for its ``bvals`` and ``bvecs`` files. + +``acquisition_times`` field +--------------------------- + +This gives a list of times of acquisition of each spatial unit of data. + +``acquisition_times`` can apply to (``applies_to``) slices or to volumes or to +both. + +Units are milliseconds and can be expressed as integers or as floating point. +Milliseconds is a reasonable choice for units because a Python integer can +decode / encode any integer number in the JSON correctly, a signed 32-bit int +can encode to around 6000 hours, and a 32-bit float can encode to 23 hours +without loss of precision. + +``acquisition_times`` applying to slices +======================================== + +If ``acquisition_times`` applies to an image axis representing slices, then the +array should be of shape (S,) where S is the number of slices. Each value +$a_i$ represents the time of acquisition of slice $i$, relative to the start +of the volume, in milliseconds. For example, to specify an ascending +sequential slice acquisition scheme: + +>>> element = dict(applies_to=['slice'], +... acquisition_times=[0, 20, 40, 60, 80, 100]) + +We use "slice" as the axis name here, but any name is valid. + +NIfTI 1 and 2 can encode some slice acquisition times using a somewhat +complicated scheme, but they cannot - for example - encode multi-slice +acquisitions, and NIfTI slice time encoding is rarely set. According to the +*C-struct primacy* principle, if the slice timing is set, it overrides this +``acquisition_times`` field. Slice timing is set in the C-struct if the +`slice_code +<http://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/slice_code.html>`_ +in the C-struct is other than 0 (=unknown). The specific slice times from the +C-struct also depend on C-struct fields ``slice_start`` and ``slice_end``. + +``acquisition_times`` applying to volumes +========================================= + +When `acquisition_times`` applies to a volume axis, it is a list of times of +acquisition of each volume in milliseconds relative to the beginning of the +acquisition of the run. + +These values can be useful for recording runs with missing or otherwise +not-continuous time data. + +We use "time" as the axis name, but any name is valid. + +>>> element = dict(applies_to=['time'], +... acquisition_times=[0, 120, 240, 480, 600]) + +The NIfTI C-struct can encode a non-zero start point for volumes, using the +`toffset +<http://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/toffset.html>`_ +field. If this is not-zero, and not equal to the first value in +``acquisition_times``, JSON acquisition times applying to volumes are ignored. +The C-struct ``slice_code`` field (see above) is not relevant to volume times, +and can have any value. + +``acquisition_times`` applying to slices and volumes +==================================================== + +When `acquisition_times`` applies to both a slice and a volume axis, it is a +list of times of acquisition of each slice in each volume in milliseconds +relative to the beginning of the acquisition of the run. + +>>> element = dict(applies_to=['slice', 'time'], +... acquisition_times = [[0, 100, 200], +... [10, 110, 210], +... [20, 120, 220], +... [30, 130, 230], +... [40, 140, 240]] +... ) + +This meaning becomes invalid with non-zero and conflicting values for +``slice_code`` or ``toffset`` in the C-struct. Conflicting values are values +different from those implied from a strict per-volume repetition of the +acquisition times from ``slice_code, slice_start, slice_end``, starting at +``toffset``. + +``axis_meanings`` field +======================= + +So far we are allowing any axis to be a slice or volume axis, but it might be +nice to check. One way of doing this is: + +>>> element = dict(applies_to=['mytime'], +... axis_meanings=["volume", "time"], +... acquisition_times=[0, 120, 240, 480, 600]) +>>> element = dict(applies_to=['myslice'], +... axis_meanings=["slice"], +... acquisition_times=[0, 20, 40, 60, 80, 100]) + +In this case we can assert that ``acquisition_times`` applies to an axis with +meanings that include "slice" or that it applies to an axis with meaning +"volume". For example: + +>>> # Should raise an error on reading full JSON +>>> element = dict(applies_to=['myslice'], +... axis_meanings=["frequency"], +... acquisition_times=[0, 20, 40, 60, 80, 100]) + +Being able to specify meanings that apply to more than one axis might also +help for the situation where there is more than one frequency axis: + +>>> hdr = dict(nipy_header_version='1.0', +... axis_names = ["frequency1", "frequency2", "slice", "time"], +... axis_metadata = [ +... dict(applies_to = ["frequency1"], +... axis_meanings = ["frequency"]), +... dict(applies_to = ["frequency2"], +... axis_meanings = ["frequency"]), +... dict(applies_to = ['slice'], +... axis_meanings = ["slice"]), +... dict(applies_to = ['time'], +... axis_meanings = ["time", "volume"]), +... ]) + +We can also check that space axes really are space axes: + +>>> hdr = dict(nipy_header_version='1.0', +... axis_names = ["frequency", "phase", "slice", "time"], +... axis_metadata = [ +... dict(applies_to = ["frequency"], +... axis_meanings = ["frequency", "space"]), +... dict(applies_to = ["phase"], +... axis_meanings = ["phase", "space"]), +... dict(applies_to = ["slice"], +... axis_meanings = ["slice", "space"]), +... dict(applies_to = ["time"], +... axis_meanings = ["time", "volume"]), +... dict(applies_to=["time"], +... q_vector = dict( +... spatial_axes = ["frequency", "phase", "slice"], +... array = [[0, 0, 0], +... [1000, 0, 0]])) +... ]) + +For the ``q_vector`` field, we can check that all of the ``spatial_axes`` axes +("frequency", "phase", "slice") do in fact have meaning "space". + +For this check to pass, either of these must be true: + +* no axes are labeled with the meaning "space" OR +* the only three axes with label "space" are those named in ``spatial_axes``. + +``multi_affine`` field +---------------------- + +Use case +^^^^^^^^ + +When doing motion correction on a 4D image, we calculate the required affine +transformation from, say, the second image to the first image; the +third image to the first image; etc. If there are N volumes in the 4D image, +we would need to store N-1 affine transformations. If we have registered to +the mean volume of the volume series instead of one of the volumes in the +volume series, then we need to store all N transforms. + +We often want to store this set of required transformations with the image, +but NIfTI does not allow us to do that. SPM therefore stores these transforms +in a separate MATLAB-format ``.mat`` file. We currently don't read these +transformations because we have no API in nibabel to present or store multiple +affines. + +Implementation +^^^^^^^^^^^^^^ + +Assume the 4D volume has T time points (volumes). + +There are two ways we could implement the multi-affines. The first would be to +have (T x 3 x 4) ``array`` of affines, with one for each volume / time point, +and a ``spatial_axes`` field specifying the input axes for the affine. This +is the same general idea as the `q_vector` field:: + + >>> element = dict(applies_to=['time'], + ... multi_affine = dict( + ... spatial_axes = ['frequency', 'phase', 'slice'], + ... array = [[[ 2.86, -0.7 , 0.83, -80.01], + ... [ 0.71, 2.91, 0.01, -114.59], + ... [ -0.54, 0.13, 4.42, -54.34]], + ... [[ 2.87, -0.38, 1.19, -92.77], + ... [ 0.31, 2.97, 0.45, -110.87], + ... [ -0.82, -0.2 , 4.32, -33.89]], + ... [[ 2.97, -0.39, 0.31, -78.95], + ... [ 0.33, 2.9 , 1.06, -116.99], + ... [ -0.29, -0.68, 4.36, -36.41]], + ... [[ 2.93, -0.5 , 0.61, -78.02], + ... [ 0.4 , 2.9 , 0.99, -118.9 ], + ... [ -0.5 , -0.59, 4.35, -33.61]], + ... [[ 2.95, -0.44, 0.49, -77.86], + ... [ 0.3 , 2.78, 1.62, -125.83], + ... [ -0.46, -1.03, 4.17, -21.66]]])) + >>> np.array(element['multi_affine']['array']).shape + (5, 3, 4) + +This obeys the axis transpose principle, because the spatial axes are +specified. If the user transposes the image, the order of axis names in +``axis_names`` changes, but the correspondence between axis names and affine +columns is still correctly encoded in the ``spatial_axes``. + +Another option would be to partially follow the `NRRD format +<http://teem.sourceforge.net/nrrd/format.html>`_ in giving the column vectors +from the affine to the axis to which they apply, and split the translation +into a separate offset vector:: + + >>> hdr = dict(nipy_header_version='1.0', + ... axis_names = ["time"], + ... axis_metadata = [ + ... dict(applies_to=['time'], + ... output_vector=dict( + ... spatial_axis = ['frequency'], + ... array = [ + ... [ 2.86, 0.71, -0.54], + ... [ 2.87, 0.31, -0.82], + ... [ 2.97, 0.33, -0.29], + ... [ 2.93, 0.4 , -0.5 ], + ... [ 2.95, 0.3 , -0.46], + ... ])), + ... dict(applies_to=['time'], + ... output_vector=dict( + ... spatial_axis = ['phase'], + ... array = [ + ... [ -0.7 , 2.91, 0.13], + ... [ -0.38, 2.97, -0.2 ], + ... [ -0.39, 2.9 , -0.68], + ... [ -0.5 , 2.9 , -0.59], + ... [ -0.44, 2.78, -1.03], + ... ])), + ... dict(applies_to=['time'], + ... output_vector = dict( + ... spatial_axis = ['slice'], + ... array = [ + ... [ 0.83, 0.01, 4.42], + ... [ 1.19, 0.45, 4.32], + ... [ 0.31, 1.06, 4.36], + ... [ 0.61, 0.99, 4.35], + ... [ 0.49, 1.62, 4.17], + ... ])), + ... dict(applies_to=['time'], + ... output_offset = [ + ... [ -80.01, -114.59, -54.34], + ... [ -92.77, -110.87, -33.89], + ... [ -78.95, -116.99, -36.41], + ... [ -78.02, -118.9, -33.61], + ... [ -77.86, -125.83, -21.66], + ... ])], + ... ) + >>> np.array(hdr['axis_metadata'][0]['output_vector']['array']).shape + (5, 3) + >>> np.array(hdr['axis_metadata'][1]['output_vector']['array']).shape + (5, 3) + >>> np.array(hdr['axis_metadata'][2]['output_vector']['array']).shape + (5, 3) + >>> np.array(hdr['axis_metadata'][3]['output_offset']).shape + (5, 3) + +.. _minc: http://en.wikibooks.org/wiki/MINC/Reference/MINC1_File_Format_Reference +.. _nrrd: http://teem.sourceforge.net/nrrd/descformat.html +.. _nifti header extension: http://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/extension.html +.. _adding nifti extensions: http://nifti.nimh.nih.gov/nifti-1/documentation/faq#Q19 +.. _bxh-xcede-tools: http://www.nitrc.org/projects/bxh_xcede_tools/ +.. _xcede website: http://www.xcede.org/XCEDE.html +.. _JIM: http://www.xinapse.com/Manual/index.html +.. _3D slicer: http://www.slicer.org + +.. vim: ft=rst diff --git a/_sources/devel/biaps/biap_0004.rst.txt b/_sources/devel/biaps/biap_0004.rst.txt new file mode 100644 index 0000000000..229025d01a --- /dev/null +++ b/_sources/devel/biaps/biap_0004.rst.txt @@ -0,0 +1,235 @@ +.. _biap4: + +#################################### +BIAP4 - Merging nibabel and dcmstack +#################################### + +:Author: Brendan Moloney, Matthew Brett +:Status: Draft +:Type: Standards +:Created: 2012-11-21 + +In which we set out what dcmstack_ does and how it might integrate with the +nibabel objects and functions. + +********** +Motivation +********** + +It is very common to convert source DICOM images to another format, typically +Nifti, before doing any image processing. The Nifti format is significantly +easier to work with and has wide spread compatibility. However, the vast +amount of meta data stored in the source DICOM files will be lost. + +After implementing this proposal, users will be able to preserve all of the +meta data from the DICOM files during conversion, including meta data from +private elements. The meta data will then be easily accessible through the +`SpatialImage` API:: + + >>> nii = nb.load('input.nii') + >>> data = nii.get_data() + >>> print data.shape + (256, 256, 24, 8) + >>> print nii.get_meta('RepetitionTime') + 3500.0 + >>> echo_times = [nii.get_meta('EchoTime', (0, 0, 0, idx)) + for idx in xrange(data.shape[-1])] + >>> print echo_times + [16.4, 32.8, 49.2, 65.6, 82.0, 98.4, 114.8, 131.2] + >>> print nii.get_meta('AcquisitionTime', (0, 0, 1, 0)) + 110455.370000 + >>> print nii.get_meta('AcquisitionTime', (0, 0, 2, 0)) + 110457.272500 + >>> print nii.get_meta('AcquisitionTime', (0, 0, 1, 1)) + 110455.387500 + + + +******** +Overview +******** + +dcmstack reads a series of DICOM images, works out their relationship in terms +of slices and volumes, and compiles them into multidimensional volumes. It can +produce the corresponding data volume and affine, or a Nifti image (with any +additional header information set appropriately). + +In the course of the read, dcmstack creates a `DcmMeta` object for +each input file. This object is an ordered mapping that can contain a copy +of all the meta data in the DICOM header. By default some filtering is +applied to reduce the chance of including PHI. The set of DcmMeta objects are +then merged together in the same order as the image data to create a single +DcmMeta object that summarizes all of the meta data for the series. + +To summarize the meta data, each element is classified based on how the values +repeat (e.g. const, per_slice, per_volume, etc.). Each element has a name (the +keyword from the DICOM standard) and one or more values (the number of values +depends on the classification and the shape of the image). Each classification's +meta data is stored stored in a separate nested dictionary. + +While creating the Nifti image output, the `DcmMeta` is stored in a +`DcmMetaExtension` which can be added as a header extension. This extension +simply does a JSON encoding directly on the `DcmMeta` object. + +When working with these images, it's possible to keep track of the +meta-information in the `DcmMetaExtension`. For example, when taking slice out +of a 3D volume, we keep track of the information specific to the chosen +slice, and remove information for other slices. Or when merging 3D volumes to +a 4D time series, we want to merge together the meta data too. + +At the moment, dcmstack only creates Nifti images. There's no reason that this +should be so, and the relationship of dcmstack to other spatial images should be +more flexible. + +****** +Issues +****** + +`DcmMetaExtension` tied to `NiftiExtension` +=========================================== + +At the moment, `DcmMetaExtension` inherits from the `NiftiExtension`, allowing +the data to be dumped out to JSON when writing into the extension part of a +Nifti header. + +There's no reason that the `DcmMetaExtension` should be tied to the Nifti +format. + +Plan +---- + +Refactor `DcmMetaExtension` to inherit from `object`. Maybe rename `DcmMeta` or +something. Make a `NiftiExtension` object when needed with a new object +wrapping the `DcmMeta` in the Extension API? + +Status +------ + +Resolved. We now have a separate `DcmMeta` object which inherits from +`OrderedDict` and contains all of the functionality previously in +`DcmMetaExtension` except those related to acting as a Nifti1Extension. +The `DcmMetaExtension` now provides just the functionality for being +a Nifti1Extension. + +Keeping track of metadata when manipulating images +================================================== + +When slicing images, it is good to be able to keep track of the relevant DICOM +metadata for the particular slice. Or when merging images, it is good to be +able to compile the metadata across slices into the (e.g) volume metadata. Or, +say, when coregistering an image, it is good to be able to know that the +metadata that is per-slice no longer directly corresponds to a slice of the +data array. + +At the moment, dcmstack deals with this by wrapping the image with DICOM meta +information in `NiftiWrapper` object : see +https://github.com/moloney/dcmstack/blob/d157741/src/dcmstack/dcmmeta.py#L1232. +This object accepts a Nifti image as input, that usually contains a +`DcmMetaExtension`, and has methods `get_meta` (to get metadata from extension), +`split` (for taking slice specific metadata into the split parts), `meta_valid` +to check the metadata against the Nifti information, and methods to remove / +replace the extension, save to a filename, and create the object with various +alternative classmethod constructors. + +In particular, the `meta_valid` method needs to know about both the enclosed +image, and the enclosed meta data. + +Can we put this stuff into the `SpatialImage` image object of nibabel, so we +don't need this wrapper object? + +Plan +---- + +Put the `DcmMeta` data into the `extra` object that is input to the +`SpatialImage` and all other nibabel image types. + +Add a `get_meta` method to `SpatialImage` that uses the to-be-defined API of the +`extra` object. Maybe, by default, this would just get keys out of the mapping. + +Define an API for the `extra` object to give back metadata that is potentially +varying (per slice or volume). We also need a way to populate the `extra` object +when loading an image that has an associated `DcmMeta` object. + +Use this API to get metadata. Try and make this work with functions outside the +`SpatialImage` such as `four_to_three` and `three_to_four` in `nibabel.funcs`. +These functions could use the `extra` API to get varying meta-information. + +** TODO : specific proposal for `SpatialImage` and `extra` API changes ** + +Detecting slice or volume-specific data difficult for 3D and 4D DICOMS +====================================================================== + +The `DcmMeta` object needs to be able to identify slice and volume specific +information when reading the DICOM, so that it can correctly split the resulting +metadata, or merge it. + +This is easy for slice-by-slice DICOM files because anything that differs +between the slices is by definition slice-specific. For 3D and 4D data, such as +Siemens Mosaic, some of the fields in the private headers contains +slice-by-slice information for the volume contained. There's not automatic way +of detecting slice-by-slice information in this case, so we have to specify +which fields are slice-by-slice when reading. That is, we need to specialize +the DICOM read for each type of volume-containing DICOM - such as Mosaic or the +Philips multi-frame format. + +Plan +---- + +Add `create_dcmmeta` method to the nibabel DICOM wrapper objects, that can be +specialized for each known DICOM format variation. Put the rules for slice +information etc into each class. + +For the Siemens files, we will need to make a list of elements from the private +CSA headers that are known to be slice specific. For the multiframe DICOM files +we should be able to do this in a programmatic manner, since the varying data +should live in the PerFrameFunctionalSequence DICOM element. Each element that +is reclassified should be simplified with the `DcmMeta.simplify` method so that +it can be classified appropriately. + +Meta data in nested DICOM sequences can not be independently classified +======================================================================= + +The code for summarizing meta data only works on the top level of key/value +pairs. Any value that is a nested dataset is treated as a single entity, +which prevents us from classifying its individual elements differently. + +In a DICOM data set, any element that is a sequence contains one or more +nested DICOM data sets. For most MRI images this is not an issue since +they rarely contain many sequences, and the ones they do are usually small +and relatively unimportant. However in multiframe DICOM files make heavy +use of nested sequences to store data. + +Plan +---- +This same issue was solved for the translated Siemens CSA sub headers by +unpacking each nested dataset by joining the keys from each level with a +dotted notation. For example, in the `CsaSeries` subheader there is a nested +`MrPhoenixProtocol` dataset which has an element `ulVersion` so the key we +use after unpacking is `CsaSeries.MrPhoenixProtocol.ulVersion`. + +We can take the same approach for DICOM sequence elements. One additional +consideration is that each of these element is actually a list of data sets, +so we would need to add an index number to the key somehow. + +The alternative is to handle nested data sets recursively in the meta data +summarizing code. This would be fairly complex and you would no longer be +able to refer to each element with a single string, at least not without +some mini-language for traversing the nested datasets. + +Improving access to varying meta data through the Nifti +======================================================= + +Currently, when accessing varying meta data through the `get_meta` method +you can only get one value at a time:: + + >>> echo_times = [nii.get_meta('EchoTime', (0, 0, 0, idx)) + for idx in xrange(data.shape[-1])] + +You can easily get multiple values from the `DcmMeta` object itself, but +then you lose the capability to automatically check if the meta data is +valid in relation to the current image. + + +.. _dcmstack : https://github.com/moloney/dcmstack +.. _DcmMetaExtension : https://github.com/moloney/dcmstack/blob/d157741/src/dcmstack/dcmmeta.py#L112 +.. vim: ft=rst diff --git a/_sources/devel/biaps/biap_0005.rst.txt b/_sources/devel/biaps/biap_0005.rst.txt new file mode 100644 index 0000000000..95d4e5245d --- /dev/null +++ b/_sources/devel/biaps/biap_0005.rst.txt @@ -0,0 +1,160 @@ +.. _biap5: + +############################### +BIAP5 - A streamlines converter +############################### + +:Author: Marc-Alexandre CΓ΄tΓ© +:Status: Draft +:Type: Standards +:Created: 2013-09-03 + +The first objective of this proposal is to add support to other streamlines +format. The second objective is to be able to easily convert from one file +format to another. + +********** +Motivation +********** + +There are a couple of different formats for saving streamlines to a file. +Currently, NiBabel only support one of them: `TRK +<http://www.trackvis.org/docs/?subsect=fileformat>`_ from `Trackvis +<http://www.trackvis.org>`_. NiBabel could greatly benefit from supporting +other formats: +`TCK <http://www.brain.org.au/software/mrtrix/appendix/mrtrix.html#tracks>`_ +(`MRtrix <http://www.brain.org.au/software/mrtrix/>`_), +`VTK <http://www.vtk.org/VTK/img/file-formats.pdf>`_ +(`Camino <http://cmic.cs.ucl.ac.uk/camino/>`_, `MITK <http://www.mitk.org/>`_) +and more. Moreover, being able to move from one format to another would be +convenient. To ease the conversion process, a generic format from which to +inherit and some common header fields would be necessary. This is similar to +what NiBabel already has for neuroimages. + +After implementing this proposal, users could load and use streamlines file like this:: + + >>> import nibabel as nib + >>> f = nib.streamlines.load('my_trk.trk', lazy_load=False) + >>> type(f) + nibabel.streamlines.base_format.Streamlines + >>> f.points + [array([ [1, 1, 1], + [2, 2, 2], + [3, 3, 3] ]), + array([ [4, 4, 4], + [5, 5, 5] ])] + >>> nib.streamlines.convert('my_trk.trk', 'my_tck.tck') + >>> f2 = nib.streamlines.load('my_trk.tck', lazy_load=False) + >>> type(f2) + nibabel.streamlines.base_format.Streamlines + >>> f2.points + [array([ [1, 1, 1], + [2, 2, 2], + [3, 3, 3] ]), + array([ [4, 4, 4], + [5, 5, 5] ])] + +Of course, similar functions will be available for 'scalars' (per point) and 'properties' (per streamline) as defined in the TrackVis format. A simple example to save three streamlines with no scalars nor properties would look like this:: + + >>> import nibabel as nib + >>> points = [np.arange(1*3).reshape((1,3)), + np.arange(2*3).reshape((2,3)), + np.arange(5*3).reshape((5,3))] + >>> streamlines = nib.streamlines.Streamlines(points) + >>> nib.streamlines.save(streamlines, 'data1.trk') # Default TRK header is used but updated with streamlines information. + + >>> FA = nib.load('FA.nii') + >>> streamlines.header = nib.streamlines.header.from_nifti(FA) # Uses information of the FA to create an header. + >>> nib.streamlines.save(streamlines, 'data2.trk') # Streamlines' header is used but also updated with streamlines information. + + >>> from nib.streamlines.header import VOXEL_ORDER, VOXEL_SIZES + >>> hdr = nib.streamlines.TrkFile.get_empty_header() # Default TRK header + >>> hdr[VOXEL_ORDER] = "LAS" + >>> hdr[VOXEL_SIZES] = (2, 2, 2) + >>> streamlines.header = hdr + >>> nib.streamlines.save(streamlines, 'data3.trk') # Uses hdr to create a TRK header. + +******** +Overview +******** + +All code related to managing streamlines should be kept in a separate folder: +``nibabel.streamlines``. A first file, ``base_format.py``, would contain base +classes acting as general interfaces from which new streamlines file format +will inherit. + +Streamlines would be represented by its own class ``Streamlines`` which will +have three main properties: ``points``, ``scalars`` and ``properties``. +Streamlines objects can be iterate over producing tuple of ``points``, +``scalars`` and ``properties`` for each streamline. + +The generic class ``StreamlinesFile`` would look like this: + +.. code:: python + + class StreamlinesFile: + @classmethod + def get_magic_number(cls): + raise NotImplementedError() + + @classmethod + def is_correct_format(cls, fileobj): + raise NotImplementedError() + + @classmethod + def get_empty_header(cls): + raise NotImplementedError() + + @classmethod + def load(cls, fileobj, lazy_load=True): + raise NotImplementedError() + + @classmethod + def save(cls, streamlines, fileobj): + raise NotImplementedError() + + @staticmethod + def pretty_print(streamlines): + raise NotImplementedError() + +When inheriting from a base class, a specific streamline format class should know how to do its i/o, in particular how to iterate through the streamlines without loading the whole file into memory. + +Once, the right interface is in place, the conversion part should be quite easy. Moreover, the conversion could be done without loading the input file entirely into memory thanks to generators. Actually, the convert function should looks like this: + +.. code:: python + + def convert(in_fileobj, out_filename): + # Loading part + streamlines_file = detect_format(in_fileobj) + streamlines = streamlines_file.load(in_fileobj, lazy_load=True) + + # Saving part + streamlines_file = detect_format(out_filename) + streamlines_file.save(streamlines, out_filename) + +Of course, this implies some sort of general header compatibility between every format. + + +****** +Issues +****** + +Header +====== + +Like it is done in NiBabel, headers should be defined using the +``numpy.dtype``. This consists of a list of tuples, each one containing +information (name, datatype and shape) about one field of the header. Once +loaded, the header will acted as a dictionary using the name of each field as +the key. Ideally, header of different formats would be the same, but it is +not. To avoid manually writing each possible conversion between header +formats, a general architecture should be put in place. + +One solution is to define some sort of ``CommonHeader`` containing an enum of the most common field (i.e. NB_FIBERS, VOXEL_SIZES, DIMENSIONS, etc). Like that, instead of specifying a field's name in the header definition, the suited enum constant should be used if there is one, otherwise the name is hard coded to a string representing the field. It should be make clear, in the documentation of ``CommonHeader``, what is the expected value of a common field. + +*********** +Future Work +*********** + +A first interesting subclass would be the ``DynamicStreamlineFile`` offering +a way to append streamlines to an existing file when format permits it. diff --git a/_sources/devel/biaps/biap_0006.rst.txt b/_sources/devel/biaps/biap_0006.rst.txt new file mode 100644 index 0000000000..effe3d343c --- /dev/null +++ b/_sources/devel/biaps/biap_0006.rst.txt @@ -0,0 +1,284 @@ +.. _biap6: + +############################## +BIAP6 - Identifying image axes +############################## + +:Author: Matthew Brett +:Status: Draft +:Type: Standards +:Created: 2015-07-11 + +********** +Background +********** + +Image axes can have meaningful labels. + +For example in a typical 4D NIfTI file, as we move along the 4th dimension in +the image array, we are also moving in time. For example, this would be the +first volume (in time): + +.. code:: python + + img = nibabel.load('my_4d.nii') + data = img.get_data() + vol0 = data[..., 0] + +and this would be second volume in time: + +.. code:: python + + vol1 = data[..., 1] + +It would therefore be reasonable to label the 4th axis of this image as 'time' +or 't'. + +We need to know which axis is the "time" axis for many reasons, including +being able to select whole image volumes to align during motion correction, +and doing spatial smoothing, where we want to avoid smoothing along the time +dimension. + +It is common to acquire MRI images one slice at a time. In a 3D or 4D NIfTI, +the 3rd axis often contains these slices. So this these would be the first +and second slices of data collected by the scanner: + +.. code:: python + + slice0 = vol0[:, :, 0] + slice1 = vol0[:, :, 1] + +In this case we might refer to the 3rd axis as the "slice" axis. We might +care about knowing the "slice" axis, because we do processing specific to the +slice axis, such as slice-timing correction. + +For an individual 2D slice, MRI physicists distinguish between the image axis +encoded during a single continual readout of the signal (frequency encoding +direction) and the image axis encoded in a series of stepwise changes in the +phase encode gradient (phase encoding direction). We care about the phase +encoding direction because we usually correct for image distortion only along +this direction. + +Let us say that the first axis is the frequency encoding axis, and the second +is the phase encoding axis. Now we can label all four of our axes: + +* "frequency"; +* "phase"; +* "slice"; +* "time". + +In fact the NIfTI format can store this information. NIfTI specifies that the +fourth image dimension should have units in terms of time (seconds), frequency +(Hertz, radians per second) or concentration (parts per million), where the +value difference between elements on the fourth axis is in +``img.header['pixdim'][4]``, and the units of this difference are available in +``img.header['xyzt_units']``. The field ``img.header['dim_info']`` can +identify the frequency, phase and slice-encoding axes. + +Time axis as the fourth axis +============================ + +In the NIfTI standard, time must be the fourth dimension. + +In fact, the NIfTI standard specifies that the fourth axis *must* be time. If +we want to store more than one volume that do not differ across time, then we +have to set the 4th dimension to be length 1, and have 5th dimension have +length > 1. Quoting from the standard:: + + In NIFTI-1 files, dimensions 1,2,3 are for space, dimension 4 is for time, + and dimension 5 is for storing multiple values at each spatiotemporal + voxel. + +This arrangement happens in practice. For example, SPM deformation fields +have three values for each voxel (x, y, z displacement), and have shape (I, J, +K, 1, 3): + +.. code:: python + + In [7]: img = nib.load('y_highres001.nii') + In [8]: img.shape + Out[8]: (121, 145, 121, 1, 3) + +So, for correctly written NIfTI images, we can identify time by the fact that +it is the fourth axis. + +MGH format also appears to use the fourth dimension for time. The dimensions +are listed in order ``width, height, depth, nframes`` and "frames" is always +the slowest changing dimension in the image data buffer. Of course, in numpy, +this does not tell us which axis this must be in the returned array, but at +least the ``load_mgh.m`` MATLAB function (see `MGH format`_) returns the frame +axis as the last axis, as does nibabel. + +The ECAT and PAR / REC formats seem to be primarily based on and stored as +slices (2D arrays) which can then be concatenated to form volumes, implying a +slowest-changing axis of volume. Nibabel currently arranges PAR images with +volume as the 4th and last axis. + +On the other hand, the MINC format: + +#. gives specific names to the image data axes so we can directly find the + time axis +#. expects (given the common ordering of these names in MINC files) that the + time axis will be first:: + + In [31]: mnc2 = h5py.File('nibabel/tests/data/minc2_4d.mnc', 'r')['minc-2.0'] + In [32]: mnc2['dimensions'].values() + Out[32]: + [<HDF5 dataset "time": shape (2,), type "<f8">, + <HDF5 dataset "xspace": shape (), type "<i4">, + <HDF5 dataset "yspace": shape (), type "<i4">, + <HDF5 dataset "zspace": shape (), type "<i4">] + +This reflects MINC's lineage as C-library, where the C convention is for the +first axis in an array is the slowest changing. ``arr[0]`` in a C-convention +4D array would be the first volume, where time (volume) is the slowest +changing axis. + +MINC2 uses HDF5 storage, and HDF5 uses C storage order for standard contiguous +arrays on disk - see "7.3.2.5. C versus Fortran Dataspaces" in `chapter 7 of +the HDF5 user guide +<http://www.hdfgroup.org/HDF5/doc/UG/UG_frame12Dataspaces.html>`_. + +BrainVoyager `STC <STC format definition>`_ files store data in (fastest to +slowest changing) order: columns (of slice); rows (of slice); time; slice. The +`VTC <VTC format definition>`_ stores the data in the (fast to slow) order: +time; Anterior->Posterior; Superior->Inferior; Left->Right. + +Images can have more than four axes +=================================== + +We've already seen the example of NIfTI images where the 4th axis is length 1 +and the 5th axis is length 3, encoding a deformation field. + +This is a trick NIfTI uses to allow us to identify the "time" axis. + +We can also have (rarely) images of 5D, where the time axis has length > 1. +For example, some MR acquisitions take two echoes per time point, so we might +have an image of shape (64, 64, 32, 200, 2), where the fourth axis is time and +the fifth axis is echo number. + +The current nibabel convention +============================== + +The nibabel rule of thumb has been that, when we return an image array, it +should be in the order described in the format's user documentation. + +So, for NIfTI format images, the image dimension sizes are listed in fastest +to slowest changing order, implying that the expected array to be returned +will have that same axis order. Time is always the fourth (rather than the +first) dimension of a 4D NIfTI. Nibabel NIfTI images return the array in that +order, and the time / volume axis is the last in a 4D nibabel NIfTI image +array. + +On the other hand MINC clearly expects that the axes will be returned in the +order the axes are listed in the MINC file. This is also (usually) the +slowest-to-fastest changing order in the underlying file, and by convention, +the first axis is the time axis. Nibabel MINC images return the array in this +same order with the time / volume axis first, but in general it returns the +array with the axes in the order listed in the MINC file. + +We don't currently have BrainVoyager support, so this will be a decision we +have to make before finalizing the API. + +Distinguishing time and volume +============================== + +A *volume* is a complete set of slices making up one brain image. + +In NIfTI: + +* 3D image: volume == image array i.e. ``arr[:, :, :]``; +* > 3D image: volume == a single slice over the final dim > 3 dimensions + e.g.: ``arr[:, :, :, 2]`` (4D); ``arr[:, :, :, 0, 3]`` (5D). + +We saw above that the MGH format refers to a volume (in our sense) as a +*frame*. ECAT has the same usage - a frame is a 3D volume. The fmristat +software uses frame in the same sense, e.g., `line 32 of example.m +<https://github.com/matthew-brett/fmristat/blob/64ad8bf/fmristat/example.m#L32>`_. + +Unfortunately DICOM appears to use "frame" to mean a 2D slice. For example, +here is the definition of a "multi-frame image":: + + 3.8.9 Multi-frame image: + Image that contains multiple two-dimensional pixel planes. + +From `PS 3.3 of the 2011 DICOM standard +<http://medical.nema.org/Dicom/2011/11_03pu.pdf>`_. + +********************************** +Possible solutions to finding axes +********************************** + +A general solution for finding axes would be to attach axis labels to the +returned image data array, or to the image object. + +A less general solution would be to identify the time axis by convention - say +- by being the fourth axis in a 4D array. + +Finding the time axis is an urgent problem, because we are currently +considering utility routines for (spatial) smoothing, and viewing images, that +need to know which axis is time. + +General solution: associating axes and labels +============================================= + +Possible options: + +* Add a property `time_axis_index` to the image class. This always returns 3 + (4th axis) for images other than MINC. For MINC, it returns the index of + the image dimension labeled ``time``; +* Add a property `axis_labels` to the image class. By default, most image + types return `'i', 'j', 'k', 'time'`. MINC returns the image dimension + labels; +* Copy or depend on datarray_ (no other dependencies) or `xray` (depends on + Pandas). Use these to attach labels directly to the image data array axes. + These labels could then be preserved through operations like slicing. + +Using convention : enforcing time as 4th axis +============================================= + +This solution could be implemented as well as the solution using labels. + +At the moment, we can always identify the time axis in the NIfTI file, because +it is the 4th axis in the returned image. + +This is probably so for: + +* PAR/REC +* ECAT +* MGH + +but not so for MINC1 or MINC2, where time is typically (?always) the first +axis. + +One option would be to make a new MINC1, MINC2 image class that reorders the +MINC axes to have time last. Call these new classes `NiMINC1, NiMINC2`. + +In order to avoid surprise, we continue to return MINC1, MINC2 class images +from `nibabel.load`, but give a ``DeprecationWarning`` when doing this, saying +that the default load will change in future versions of nibabel, and +suggesting the `as_niminc=True` keyword-only argument to load, defaulting to +`as_niminc=False` (giving the current nibabel behavior). + +In Nibabel 3.0, we require the `as_niminc` keyword argument. + +In Nibabel 4.0, we default to `as_niminc=True`. + +We would still have to deal with MINC1, MINC2 images in memory - and therefore +cannot in general assume that the fourth dimension of any image data array is +time. In order to deal with this, routines that need to know the time +dimension would have to check whether they were dealing with MINC1, MINC2, +which ends up being similar to the `time_axis_index` option above. + + +.. _MGH format: https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/MghFormat +.. _BV file format index page: http://support.brainvoyager.com/automation-aamp-development/23-file-formats.html. +.. _BV file format overview: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/382-developer-guide-26-file-formats-overview.html +.. _vmr format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/385-developer-guide-26-the-format-of-vmr-files.html +.. _STC format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/384-developer-guide-26-the-format-of-stc-files.html +.. _VTC format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/379-users-guide-23-the-format-of-vtc-files.html. +.. _NR-VMP format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/377-users-guide-23-the-format-of-nr-vmp-files.html; +.. _AR-VMP format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/376-users-guide-23-the-format-of-ar-vmp-files.html +.. _SMP format definition: : http://support.brainvoyager.com/automation-aamp-development/23-file-formats/476-the-format-of-smp-files.html. +.. _datarray: https://pypi.python.org/pypi/datarray +.. _xray: https://pypi.python.org/pypi/xray diff --git a/_sources/devel/biaps/biap_0007.rst.txt b/_sources/devel/biaps/biap_0007.rst.txt new file mode 100644 index 0000000000..a33aec946d --- /dev/null +++ b/_sources/devel/biaps/biap_0007.rst.txt @@ -0,0 +1,116 @@ +.. _biap7: + +############################### +BIAP7 - Loading multiple images +############################### + +:Author: Matthew Brett +:Status: Draft +:Type: Standards +:Created: 2015-07-18 + +********** +Background +********** + +Some formats store images with different shapes in the same file +================================================================ + +The ECAT file format can contain more than one type of image in a single image +file. + +ECAT can store many *frames* in a single image file. Each frame has its own +*subheader*. The subheader specifies the 3D image size; each frame can +therefore have a different image size. + +We currently raise an error if you try and load an ECAT file where the frames +do not have the same 3D dimensions. + +It would be better if we could allow loading multiple images with different +image dimensions, from a single ECAT file. + +`Vista data format`_ and `Lipsia format`_ are other formats that allow saving +multiple images with different image dimensions in the same file. We don't +currently support Lipsia or Vista formats and it is not clear how we would do +that with the current ``load`` API. + +We have had some discussion about saving multiple images into a +single HDF5 file - see https://github.com/nipy/nibabel/pull/215#issuecomment-122357444 + +It can be useful to load 4D images as multiple 3D images +======================================================== + +We sometimes want to load a 4D image as multiple 3D images. + +When we are doing motion correction, we often want to split up a 4D image into +separate 3D images. + +Motion estimation results in different affines for each volume in the 4D time +series. At the moment we have no API for returning these affines with a 4D +image. One way of doing that is to load the 4D image and affines as a +sequence of 3D images, each with their own affine. + +We currently have a proposal open for a JSON header extension that can store +these 4D affines for a 4D NIfTI file. + +SPM saves the affines in an associated ``.mat`` file, with one affine per +volume in the 4D image. + +******* +Options +******* + +************************************************************ +Return an image sequence from ``load`` for some file formats +************************************************************ + +We don't currently load ECAT files from the top-level ``nibabel.load`` +function. + +We do have ``nibabel.ecat.load``, which raises an error for an ECAT file +having frames with different image dimensions. + +We could therefore choose to return a sequence of images from ``nibabel.load`` +on an ECAT file, with one element per frame in the ECAT file. + +Most ECAT images are 4D images, in the sense that the frames in the file do +all have the same image dimensions and data type, so this might be cumbersome +as a default. + +We would have to work out how to deal with ``nibabel.ecat.load``. + +The same principles apply to the Lipsia / Vista formats, except we have no +backward-compatibility problems, and it seems to be more common for these +formats to mix image types in a single file. + +*************************************** +Add a ``load_multi`` top-level function +*************************************** + +``nibabel.load_multi`` always returns an image sequence. + +``nibabel.load`` always returns a single image. + +``nibabel.load`` on ECAT (etc) files could first do ``load_multi``, then check +the resulting image dimensions, raising an error if incompatible, +concatenating otherwise. + +``load_multi`` on current formats like NIfTI could return one image per +volume, where each volume might have its own affine, as loaded from the JSON +header extension or the SPM ``.mat`` file. + +.. _Lipsia format: http://static.cbs.mpg.de/lipsia/START/index3.html +.. _Vista data format: http://www.cs.ubc.ca/labs/lci/vista/file.html + +.. vim:ft=rst + + +*************************************** +Next steps: +*************************************** + + +* Make sure there are use-cases where you could wish to call `load` vs. `load_multi` on the same image (perhaps a Nifti image with different affines for each volume) +* Investigate AFNI file formats as a use-case for this. +* Check the `nilearn` codebase, see if `iter_img` and `slice_img` functions might offer a post-`load` alternative. Also check if those functions could be deprecated in favor of slicing / iterating on `dataobj` +* Create a new issue to implement getting an iterator on `dataobj`? diff --git a/_sources/devel/biaps/biap_0008.rst.txt b/_sources/devel/biaps/biap_0008.rst.txt new file mode 100644 index 0000000000..d58e4bd56e --- /dev/null +++ b/_sources/devel/biaps/biap_0008.rst.txt @@ -0,0 +1,158 @@ +.. _biap8: + +################################################ +BIAP8 - Always load image data as floating point +################################################ + +:Author: Matthew Brett +:Status: Accepted +:Type: Standards +:Created: 2018-04-18 + +``get_fdata`` shipped as of nibabel 2.2.0. + +See `this mailing list thread <https://mail.python.org/pipermail/neuroimaging/2015-July/thread.html#21>`_ for discussion on an earlier version of this proposal. + +********** +Background +********** + +Summary +======= + +The problem with our current ``get_data`` method is that the returned data +type is difficult to predict, and can switch between integer and floating +point types depending on values in the image header. + +The underlying problem is that the author and the user of a given NIfTI image +would be unlikely to expect that the scalefactors of the NIfTI header (which +the user will probably not be aware of) will affect the calculations done on +the image data after loading into memory. + +In detail +========= + +At the moment, if you do this: + +.. code:: python + + img = nib.load('my_image.nii') + data = img.get_data() + +then the data type (dtype) of the returned data array depends on the values in +the header of ``my_image.nii``. Specifically, if the raw on-disk data type +is ``np.int16`` (it often is) and the header scalefactor values are default (1 +for slope, 0 for intercept) then you will get back an array of the on-disk +data type - here ``np.int16``. + +This is very efficient in terms of memory, but it can be a real trap unless +you are careful. + +For example, let's say you had a pipeline where you did this: + +.. code:: python + + sum = img.get_data().sum() + +That would work fine most of the time, when the data on disk is +floating point, or the scalefactors are not default (1, 0). Then one +day, you get an image with ``int16`` data type on disk and (1, 0) +scalefactors, and your `sum` calculation is now being done in int16, and +silently overflows. I (MB) ran into this when teaching - I had to cast some +image arrays to floating point to get sensible answers. + +Current implementation +====================== + +``get_data`` has the following implementation, at time of writing: + +.. code:: python + + def get_data(self): + """ Return image data from image with any necessary scalng applied + + If the image data is a array proxy (data not yet read from disk) then + read the data, and store in an internal cache. Future calls to + ``get_data`` will return the cached copy. + + Returns + ------- + data : array + array of image data + """ + if self._data_cache is None: + self._data_cache = np.asanyarray(self._dataobj) + return self._data_cache + +Note that: + +* ``self._dataobj`` may well be an array proxy object; +* ``np.asanyarray`` forces the read of an array proxy object into a numpy + array; +* the read also fills an internal cache. + +******************************************* +Proposal - add, prefer ``get_fdata`` method +******************************************* + +The future default behavior of nibabel should be to do the thing least likely +to trip you up by accident. But - we do not want the result of ``get_data`` +to change silently between nibabel versions. + +* step 1: now - add ``get_fdata`` method: + + .. code:: python + + def get_fdata(self, dtype=np.float64): + """ Return floating point image data with necessary scalng applied. + + If the image data is an array proxy (data not yet read from disk) then + read the data from file, and retain the result in an internal cache. + Future calls to ``get_fdata`` on the same image instance will return + the cached copy. + + Parameters + ---------- + dtype : numpy dtype specifier + A numpy dtype specifier specifying a floating point type. Data is + returned as this floating point type. Default is ``np.float64``. + + Returns + ------- + fdata : array + Array of image data of data type `dtype`. + """ + dtype = np.dtype(dtype) + if not issubclass(dtype, np.inexact): + raise ValueError('{} should be floating point type'.format(dtype)) + if self._fdata_cache is None: + self._fdata_cache = np.asanyarray(self._dataobj).astype(dtype) + return self._fdata_cache + + Change all instances of ``get_data`` in documentation to ``get_fdata``. + + Add warning about pending deprecation in ``get_data`` method, with + suggestion to use ``get_fdata`` or ``np.asanyarray(img.dataobj)`` if you + want the previous behavior, on the lines of:: + + We recommend you use the ``get_fdata`` method instead of the ``get_data`` + method, because it is easier to predict the return data type. We will + deprecate the ``get_data`` method around April 2018, and remove it around + April 2020. + + If you don't care about the predictability of the return data type, and + you want the minimum possible data size in memory, you can replicate the + array that would be returned by ``img.get_data()`` by using + ``np.asanyarray(img.dataobj)``. + + Add floating point cache ``self._fdata_cache`` to cache cleared by + ``uncache`` method. + +* step 2: around one year from now - deprecate ``get_data`` method; + +* step 3: around three years from now - make ``get_data`` method raise an + error such as ``NotImplementedError`` with a helpful message, and remove + associated ``self._data_cache`` attribute. Leave this error in place for + a long time, to help people porting older code. + +.. vim: ft=rst diff --git a/_sources/devel/biaps/biap_0009.rst.txt b/_sources/devel/biaps/biap_0009.rst.txt new file mode 100644 index 0000000000..0d43b1507a --- /dev/null +++ b/_sources/devel/biaps/biap_0009.rst.txt @@ -0,0 +1,335 @@ +.. _biap9: + +################################ +BIAP9 - The Coordinate Image API +################################ + +:Author: Chris Markiewicz +:Status: Draft +:Type: Standards +:Created: 2021-09-16 + +********** +Background +********** + +Surface data is generally kept separate from geometric metadata +=============================================================== + +In contrast to volumetric data, whose geometry can be fully encoded in the +shape of a data array and a 4x4 affine matrix, data sampled to a surface +require the location of each sample to be explicitly represented by a +coordinate. In practice, the most common approach is to have a geometry file +and a data file. + +A geometry file consists of a vertex coordinate array and a triangle array +describing the adjacency of vertices, while a data file is an n-dimensional +array with one axis corresponding to vertex. + +Keeping these files separate is a pragmatic optimization to avoid costly +reproductions of geometric data, but presents an administrative burden to +direct consumers of the data. + +Terminology +=========== + +For the purposes of this BIAP, the following terms are used: + +* Coordinate - a triplet of floating point values in RAS+ space +* Vertex - an index into a table of coordinates +* Triangle (or face) - a triplet of adjacent vertices (A-B-C); + the normal vector for the face is ($\overline{AB}\times\overline{AC}$) +* Topology - vertex adjacency data, independent of vertex coordinates, + typically in the form of a list of triangles +* Geometry - topology + a specific set of coordinates for a surface +* Parcel - a subset of vertices; can be the full topology. Special cases include: + * Patch - a connected parcel + * Decimated mesh - a parcel that has a desired density of vertices +* Parcel sequence - an ordered set of parcels +* Data array - an n-dimensional array with one axis corresponding to the + vertices (typical) OR faces (more rare) in a patch sequence + +Currently supported surface formats +=================================== + +* FreeSurfer + * Geometry (e.g. ``lh.pial``): + :py:func:`~nibabel.freesurfer.io.read_geometry` / + :py:func:`~nibabel.freesurfer.io.write_geometry` + * Data + * Morphometry: + :py:func:`~nibabel.freesurfer.io.read_morph_data` / + :py:func:`~nibabel.freesurfer.io.write_morph_data` + * Labels: :py:func:`~nibabel.freesurfer.io.read_label` + * MGH: :py:class:`~nibabel.freesurfer.mghformat.MGHImage` +* GIFTI: :py:class:`~nibabel.gifti.gifti.GiftiImage` + * Every image contains a collection of data arrays, which may be + coordinates, topology, or data (further subdivided by type and intent) +* CIFTI-2: :py:class:`~nibabel.cifti2.cifti2.Cifti2Image` + * Pure data array, with image header containing flexible axes + * The ``BrainModelAxis`` is a subspace sequence including patches for + each hemisphere (cortex without the medial wall) and subcortical + structures defined by indices into three-dimensional array and an + affine matrix + * Geometry referred to by an associated ``wb.spec`` file + (no current implementation in NiBabel) + * Possible to have one with no geometric information, e.g., parcels x time + +Other relevant formats +====================== + +* MNE's STC (source time course) format. Contains: + * Subject name (resolvable with a FreeSurfer ``SUBJECTS_DIR``) + * Index arrays into left and right hemisphere surfaces (subspace sequence) + * Data, one of: + * ndarray of shape ``(n_verts, n_times)`` + * tuple of ndarrays of shapes ``(n_verts, n_sensors)`` and ``(n_sensors, n_times)`` + * Time start + * Time step + +***************************************** +Desiderata for an API supporting surfaces +***************************************** + +The following are provisional guiding principles: + +1. A surface image (data array) should carry a reference to geometric metadata + that is easily transferred to a new image. +2. Partial images (data only or geometry only) should be possible. Absence of + components should have a well-defined signature, such as a property that is + ``None`` or a specific ``Exception`` is raised. +3. All arrays (coordinates, triangles, data arrays) should be proxied to + avoid excess memory consumption +4. Selecting among coordinates (e.g., gray/white boundary, inflated surface) + for a single topology should be possible. +5. Combining multiple brain structures (canonically, left and right hemispheres) + in memory should be easy; serializing to file may be format-specific. +6. Splitting a data array into independent patches that can be separately + operated on and serialized should be possible. + + +Prominent use cases +=================== + +We consider the following use cases for working with surface data. +A good API will make retrieving the components needed for each use case +straightforward, as well as storing the results in new images. + +* Arithmetic/modeling - per-vertex mathematical operations +* Smoothing - topology/geometry-respecting smoothing +* Plotting - paint the data array as a texture on a surface +* Decimation - subsampling a topology (possibly a subset, possibly with + interpolated vertex locations) +* Resampling to a geometrically-aligned surface + * Downsampling by decimating, smoothing, resampling + * Inter-subject resampling by using ``?h.sphere.reg`` +* Interpolation of per-vertex and per-face data arrays + +When possible, we prefer to expose NumPy ``ndarray``\s and +allow use of numpy, scipy, scikit-learn. In some cases, it may +make sense for NiBabel to provide methods. + +******** +Proposal +******** + +A ``CoordinateImage`` is an N-dimensional array, where one axis corresponds +to a sequence of points in one or more parcels. + +.. code-block:: python + + class CoordinateImage: + """ + Attributes + ---------- + header : a file-specific header + coordaxis : ``CoordinateAxis`` + dataobj : array-like + """ + + class CoordinateAxis: + """ + Attributes + ---------- + parcels : list of ``Parcel`` objects + """ + + def load_structures(self, mapping): + """ + Associate parcels to ``Pointset`` structures + """ + + def __getitem__(self, slicer): + """ + Return a sub-sampled CoordinateAxis containing structures + matching the indices provided. + """ + + def get_indices(self, parcel, indices=None): + """ + Return the indices in the full axis that correspond to the + requested parcel. If indices are provided, further subsample + the requested parcel. + """ + + class Parcel: + """ + Attributes + ---------- + name : str + structure : ``Pointset`` + indices : object that selects a subset of coordinates in structure + """ + +To describe coordinate geometry, the following structures are proposed: + +.. code-block:: python + + class Pointset: + @property + def n_coords(self): + """ Number of coordinates """ + + def get_coords(self, name=None): + """ Nx3 array of coordinates in RAS+ space """ + + + class TriangularMesh(Pointset): + @property + def n_triangles(self): + """ Number of faces """ + + def get_triangles(self, name=None): + """ Mx3 array of indices into coordinate table """ + + def get_mesh(self, name=None): + return self.get_coords(name=name), self.get_triangles(name=name) + + def get_names(self): + """ List of surface names that can be passed to + ``get_{coords,triangles,mesh}`` + """ + + def decimate(self, *, n_coords=None, ratio=None): + """ Return a TriangularMesh with a smaller number of vertices that + preserves the geometry of the original """ + # To be overridden when a format provides optimization opportunities + + + class NdGrid(Pointset): + """ + Attributes + ---------- + shape : 3-tuple + number of coordinates in each dimension of grid + """ + def get_affine(self, name=None): + """ 4x4 array """ + + +The ``NdGrid`` class allows raveled volumetric data to be treated the same as +triangular mesh or other coordinate data. + +Finally, a structure for containing a collection of related geometric files is +defined: + +.. code-block:: python + + class GeometryCollection: + """ + Attributes + ---------- + structures : dict + Mapping from structure names to ``Pointset`` + """ + + @classmethod + def from_spec(klass, pathlike): + """ Load a collection of geometries from a specification. """ + +The canonical example of a geometry collection is a left hemisphere mesh, +right hemisphere mesh. + +Here we present common use cases: + + +Modeling +======== + +.. code-block:: python + + from nilearn.glm.first_level import make_first_level_design_matrix, run_glm + + bold = CoordinateImage.from_filename("/data/func/hemi-L_bold.func.gii") + dm = make_first_level_design_matrix(...) + labels, results = run_glm(bold.get_fdata(), dm) + betas = CoordinateImage(results["betas"], bold.coordaxis, bold.header) + betas.to_filename("/data/stats/hemi-L_betas.mgz") + +In this case, no reference to the surface structure is needed, as the operations +occur on a per-vertex basis. +The coordinate axis and header are preserved to ensure that any metadata is +not lost. + +Here we assume that ``CoordinateImage`` is able to make the appropriate +translations between formats (GIFTI, MGH). This is not guaranteed in the final +API. + +Smoothing +========= + +.. code-block:: python + + bold = CoordinateImage.from_filename("/data/func/hemi-L_bold.func.gii") + bold.coordaxis.load_structures({"lh": "/data/anat/hemi-L_midthickness.surf.gii"}) + # Not implementing networkx weighted graph here, so assume we have a function + # that retrieves a graph for each structure + graphs = get_graphs(bold.coordaxis) + distances = distance_matrix(graphs['lh']) # n_coords x n_coords matrix + weights = normalize(gaussian(distances, sigma)) + # Wildly inefficient smoothing algorithm + smoothed = CoordinateImage(weights @ bold.get_fdata(), bold.coordaxis, bold.header) + smoothed.to_filename(f"/data/func/hemi-L_smooth-{sigma}_bold.func.gii") + + +Plotting +======== + +Nilearn currently provides a +`plot_surf <https://nilearn.github.io/modules/generated/nilearn.plotting.plot_surf.html>`_ function. +With the proposed API, we could interface as follows: + +.. code-block:: python + + def plot_surf_img(img, surface="inflated"): + from nilearn.plotting import plot_surf + coords, triangles = img.coordaxis.parcels[0].get_mesh(name=surface) + + data = img.get_fdata() + + return plot_surf((triangles, coords), data) + + tstats = CoordinateImage.from_filename("/data/stats/hemi-L_contrast-taskVsBase_tstat.mgz") + # Assume a GeometryCollection that reads a FreeSurfer subject directory + fs_subject = FreeSurferSubject.from_spec("/data/subjects/fsaverage5") + tstats.coordaxis.load_structures(fs_subject.get_structure("lh")) + plot_surf_img(tstats) + +Subsampling CIFTI-2 +=================== + +.. code-block:: python + + img = nb.load("sub-01_task-rest_bold.dtseries.nii") # Assume CIFTI CoordinateImage + parcel = nb.load("sub-fsLR_hemi-L_label-DLPFC_mask.label.gii") # GiftiImage + structure = parcel.meta.metadata['AnatomicalStructurePrimary'] # "CortexLeft" + vtx_idcs = np.where(parcel.agg_data())[0] + dlpfc_idcs = img.coordaxis.get_indices(parcel=structure, indices=vtx_idcs) + + # Subsampled coordinate axes will override any duplicate information from header + dlpfc_img = CoordinateImage(img.dataobj[dlpfc_idcs], img.coordaxis[dlpfc_idcs], img.header) + + # Now load geometry so we can plot + wbspec = CaretSpec("fsLR.wb.spec") + dlpfc_img.coordaxis.load_structures(wbspec) + ... diff --git a/_sources/devel/biaps/biap_template.rst.txt b/_sources/devel/biaps/biap_template.rst.txt new file mode 100644 index 0000000000..10fe87cee0 --- /dev/null +++ b/_sources/devel/biaps/biap_template.rst.txt @@ -0,0 +1,92 @@ +.. _biap_template: + +================================== +BIAP X β€” Template and Instructions +================================== + +:Author: <list of authors' real names and optionally, email addresses> +:Status: <Draft | Active | Accepted | Deferred | Rejected | Withdrawn | Final | Superseded> +:Type: <Standards Track | Process> +:Created: <date created on, in yyyy-mm-dd format> +:Resolution: <url> (required for Accepted | Rejected | Withdrawn) + + +Abstract +-------- + +The abstract should be a short description of what the BIAP will achieve. + +Note that the β€” in the title is an elongated dash, not -. + +Motivation and Scope +-------------------- + +This section describes the need for the proposed change. It should describe +the existing problem, who it affects, what it is trying to solve, and why. +This section should explicitly address the scope of and key requirements for +the proposed change. + +Usage and Impact +---------------- + +This section describes how users of Nibabel will use features described in this +BIAP. It should be comprised mainly of code examples that wouldn't be possible +without acceptance and implementation of this BIAP, as well as the impact the +proposed changes would have on the ecosystem. This section should be written +from the perspective of the users of Nibabel, and the benefits it will provide +them; and as such, it should include implementation details only if +necessary to explain the functionality. + +Backward compatibility +---------------------- + +This section describes the ways in which the BIAP breaks backward compatibility. + +The mailing list post will contain the BIAP up to and including this section. +Its purpose is to provide a high-level summary to users who are not interested +in detailed technical discussion, but may have opinions around, e.g., usage and +impact. + +Detailed description +-------------------- + +This section should provide a detailed description of the proposed change. +It should include examples of how the new functionality would be used, +intended use-cases and pseudo-code illustrating its use. + + +Related Work +------------ + +This section should list relevant and/or similar technologies, possibly in other +libraries. It does not need to be comprehensive, just list the major examples of +prior and relevant art. + + +Implementation +-------------- + +This section lists the major steps required to implement the BIAP. Where +possible, it should be noted where one step is dependent on another, and which +steps may be optionally omitted. Where it makes sense, each step should +include a link to related pull requests as the implementation progresses. + +Any pull requests or development branches containing work on this BIAP should +be linked to from here. (A BIAP does not need to be implemented in a single +pull request if it makes sense to implement it in discrete phases). + + +Alternatives +------------ + +If there were any alternative solutions to solving the same problem, they should +be discussed here, along with a justification for the chosen approach. + + +Discussion +---------- + +This section may just be a bullet list including links to any discussions +regarding the BIAP: + +- This includes links to mailing list threads or relevant GitHub issues. diff --git a/_sources/devel/biaps/index.rst.txt b/_sources/devel/biaps/index.rst.txt new file mode 100644 index 0000000000..42dcd276e3 --- /dev/null +++ b/_sources/devel/biaps/index.rst.txt @@ -0,0 +1,27 @@ +.. _biap_list: + +##### +BIAPs +##### + +niBabel Increased Awesomeness Proposals (BIAPs) document major changes or +proposals. + +.. toctree:: + :maxdepth: 1 + + biap_0000 + biap_0001 + biap_0002 + biap_0003 + biap_0004 + biap_0005 + biap_0006 + biap_0007 + biap_0008 + biap_0009 + +.. toctree:: + :hidden: + + biap_template diff --git a/_sources/devel/bv_formats.rst.txt b/_sources/devel/bv_formats.rst.txt new file mode 100644 index 0000000000..627aa2769f --- /dev/null +++ b/_sources/devel/bv_formats.rst.txt @@ -0,0 +1,98 @@ +######################### +BrainVoyager file formats +######################### + +With notes on nibabel support. + +PR for some BrainVoyager support at https://github.com/nipy/nibabel/pull/216. + +******** +Overview +******** + +See : + +* All files are little-endian byte order regardless of byte-order on the + machine writing the data; +* BV apparently provides a "BVQXtools" library for reading writing BV files in + MATLAB; + +.. _bv-internal-axes: + +*********************** +BV internal format axes +*********************** + +BV files have a internal format that has axes named `X`, `Y` and `Z`. Quoting +from the `VMR format definition`_:: + + BV X front -> back = Y in Tal space + BV Y top -> bottom = Z in Tal space + BV Z left -> right = X in Tal space + +Put another way |--| the correspondence of BV XYZ to Talairach axes is: + +* BV X -> Anterior to Posterior; +* BV Y -> Superior to Inferior; +* BV Z -> Left to Right. + +or: + +* BV X -> Talairach -Y; +* BV Y -> Talairach -Z; +* BV Z -> Talairach X; + +Nice! + +***************** +Types of BV files +***************** + +There appear to be 38 BV file types at the time of writing of which 18 appear +to have a page of description on the `BV file format index page`_. + +Here are some examples of BV formats: + +* FMR |--| "FMR project files are simple text files containing the information + defining a functional project created from raw MRI data". This text file + contains meta-data about the functional time course data, stored in one or + more STC files. See the `FMR format definition`_. +* STC |--| "A STC file (STC = "slice time course") contains the functional + data (time series) of a FMR project." The time-course data of a 4D + ("single-slice") format STC file are stored on disk in + fastest-to-slowest-changing order: columns, rows, time, slice. STC files + can also contain the data for one single slice ("multi-slice format"), in + which case the data are in fast-to-slow order: columns, rows, time. This is + a raw data file where the relevant meta-data such as image size come from an + associated FMR format file. See `STC format definition`_; +* VTC |--| "A VTC file contains the functional data (time series) of one + experimental run (one functional scan) in the space of a 3D anatomical data + set (VMR), e.g. in Talairach space.". See `VTC format definition`_; + This is a different format to the STC (raw data in native-space) format. + The file is a header followed by ints or floats in + fastest-to-slowest-changing order of: time; BV X; BV Y; BV Z; where BV X, BV + Y, BV Z refer to the :ref:`bv-internal-axes`, and therefore Talairach -Y, + -Z, X. +* NR-VMP |--| "A native resolution volume map (NR-VMP) file contains + statistical results in 3D format.". See `NR-VMP format definition`_ +* AR-VMP |--| "An anatomical-resolution VMP (volume map) file contains + statistical results in 3D format" at anatomical scan resolution. See + `AR-VMP format definition`_; +* VMR |--| 'high-resolution anatomical MR' - see `VMR format definition`_. +* MSK |--| mask file. Only documentation appears to be + http://www.brainvoyager.com/ubb/Forum8/HTML/000087.html +* SMP |--| 'surface map'. See `SMP format definition`_. Contains one or more + "maps", where a map is a ``NrOfVertices`` (number of vertices) length vector + of float64 values. + +.. _BV file format index page: http://support.brainvoyager.com/automation-aamp-development/23-file-formats.html +.. _AR-VMP format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/376-users-guide-23-the-format-of-ar-vmp-files.html +.. _NR-VMP format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/377-users-guide-23-the-format-of-nr-vmp-files.html +.. _VTC format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/379-users-guide-23-the-format-of-vtc-files.html +.. _BV file format overview: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/382-developer-guide-26-file-formats-overview.html +.. _FMR format definition: http://support.brainvoyager.com/installation-introduction/23-file-formats/383-developer-guide-26-the-format-of-fmr-files.html +.. _STC format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/384-developer-guide-26-the-format-of-stc-files.html +.. _vmr format definition: http://support.brainvoyager.com/automation-aamp-development/23-file-formats/385-developer-guide-26-the-format-of-vmr-files.html +.. _SMP format definition: : http://support.brainvoyager.com/automation-aamp-development/23-file-formats/476-the-format-of-smp-files.html + +.. include:: ../links_names.txt diff --git a/_sources/devel/core_developer.rst.txt b/_sources/devel/core_developer.rst.txt new file mode 100644 index 0000000000..6b67730d1b --- /dev/null +++ b/_sources/devel/core_developer.rst.txt @@ -0,0 +1,152 @@ +.. _core_dev: + +Core Developer Guide +==================== + +As a core developer, you should continue making pull requests +in accordance with the :ref:`chap_devguide`. +You are responsible for shepherding other contributors through the review process. +You also have the ability to merge or approve other contributors' pull requests. + +Reviewing +--------- + +How to Conduct A Good Review +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +*Always* be kind to contributors. Nearly all of Nibabel is +volunteer work, for which we are tremendously grateful. Provide +constructive criticism on ideas and implementations, and remind +yourself of how it felt when your own work was being evaluated as a +novice. + +Nibabel strongly values mentorship in code review. New users +often need more handholding, having little to no git +experience. Repeat yourself liberally, and, if you don’t recognize a +contributor, point them to our development guide, or other GitHub +workflow tutorials around the web. Do not assume that they know how +GitHub works (e.g., many don't realize that adding a commit +automatically updates a pull request). Gentle, polite, kind +encouragement can make the difference between a new core developer and +an abandoned pull request. + +When reviewing, focus on the following: + +1. **API:** The API is what users see when they first use + Nibabel. APIs are difficult to change once released, so + should be simple, consistent with other parts of the library, and + should avoid side-effects such as changing global state or modifying + input variables. + +2. **Documentation:** Any new feature should have a tutorial + example that not only illustrates but explains it. + +3. **The algorithm:** You should understand the code being modified or + added before approving it. (See `Merge Only Changes You + Understand`_ below.) Implementations should do what they claim, + and be simple, readable, and efficient. + +4. **Tests:** All contributions to the library *must* be tested, and + each added line of code should be covered by at least one test. Good + tests not only execute the code, but explore corner cases. It is tempting + not to review tests, but please do so. + +Other changes may be *nitpicky*: spelling mistakes, formatting, +etc. Do not ask contributors to make these changes, and instead +make the changes by `pushing to their branch +<https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/committing-changes-to-a-pull-request-branch-created-from-a-fork>`__, +or using GitHub’s `suggestion +<https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request>`__ +`feature +<https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request>`__. +(The latter is preferred because it gives the contributor a choice in +whether to accept the changes.) + +Please add a note to a pull request after you push new changes; GitHub +may not send out notifications for these. + +Merge Only Changes You Understand +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +*Long-term maintainability* is an important concern. Code doesn't +merely have to *work*, but should be *understood* by multiple core +developers. Changes will have to be made in the future, and the +original contributor may have moved on. + +Therefore, *do not merge a code change unless you understand it*. Ask +for help freely: we have a long history of consulting community +members, or even external developers, for added insight where needed, +and see this as a great learning opportunity. + +While we collectively "own" any patches (and bugs!) that become part +of the code base, you are vouching for changes you merge. Please take +that responsibility seriously. + +Closing issues and pull requests +-------------------------------- + +Sometimes, an issue must be closed that was not fully resolved. This can be +for a number of reasons: + +- the person behind the original post has not responded to calls for + clarification, and none of the core developers have been able to reproduce + their issue; +- fixing the issue is difficult, and it is deemed too niche a use case to + devote sustained effort or prioritize over other issues; or +- the use case or feature request is something that core developers feel + does not belong in Nibabel, + +among others. Similarly, pull requests sometimes need to be closed without +merging, because: + +- the pull request implements a niche feature that we consider not worth the + added maintenance burden; +- the pull request implements a useful feature, but requires significant + effort to bring up to Nibabel's standards, and the original + contributor has moved on, and no other developer can be found to make the + necessary changes; or +- the pull request makes changes that make maintenance harder, such as + increasing the code complexity of a function significantly to implement a + marginal speedup, + +among others. + +All these may be valid reasons for closing, but we must be wary not to alienate +contributors by closing an issue or pull request without an explanation. When +closing, your message should: + +- explain clearly how the decision was made to close. This is particularly + important when the decision was made in a community meeting, which does not + have as visible a record as the comments thread on the issue itself; +- thank the contributor(s) for their work; and +- provide a clear path for the contributor or anyone else to appeal the + decision. + +These points help ensure that all contributors feel welcome and empowered to +keep contributing, regardless of the outcome of past contributions. + +Further resources +----------------- + +As a core member, you should be familiar with community and developer +resources such as: + +- Our :ref:`chap_devguide` +- Our :ref:`community_guidelines` +- `PEP8 <https://www.python.org/dev/peps/pep-0008/>`__ for Python style +- `PEP257 <https://www.python.org/dev/peps/pep-0257/>`__ and the `NumPy + documentation + guide <https://numpy.org/doc/stable/docs/howto_document.html>`__ + for docstrings. (NumPy docstrings are a superset of PEP257. You + should read both.) +- The Nibabel `tag on NeuroStars <https://neurostars.org/tag/nibabel>`__ +- Our `mailing + list <https://mail.python.org/mailman/listinfo/neuroimaging>`__ + +Please do monitor any of the resources above that you find helpful. + +Acknowledgments +=============== + +This document is based on the `NetworkX Core Developer guide +<https://networkx.org/documentation/latest/developer/core_developer.html>`_. diff --git a/_sources/devel/data_pkg_discuss.rst.txt b/_sources/devel/data_pkg_discuss.rst.txt new file mode 100644 index 0000000000..f983351925 --- /dev/null +++ b/_sources/devel/data_pkg_discuss.rst.txt @@ -0,0 +1,383 @@ +.. _data-package-discuss: + +########################## +Principles of data package +########################## + +******* +Summary +******* + +This is a discussion of data packages, as they are currently implemented in +nibabel / nipy. + +This API proved to be very uncomfortable, and we intend to replace it fairly +soon. See ``data_packages.rst`` in the `nibabel wiki`_ for our current +thinking, not yet implemented. + +********** +Motivation +********** + +When developing or using nipy, many data files can be useful. + +#. *small test data* - very small data files required for routine code testing. + By small we mean less than 100K, and probably much less. They have to be + small because we keep them in the main code repository, and you therefore + always get them with any download. +#. *large test data*. These files can be much larger, and don't come in the + standard repository. We use them for tests, but we skip the tests if the + data are not present. +#. *template data* - data files required for some algorithms to function, + such as templates or atlases +#. *example data* - data files for running examples. + +We need some standard way to provide the larger data sets. To do this, we are +here defining the idea of a *data package*. This document is a draft +specification of what a *data package* looks like and how to use it. + +******************* +Separation of ideas +******************* + +This section needs some healthy beating to make the ideas clearer. However, in +the interests of the 0SAGA_ software model, here are some ideas that may be +separable. + +Package +======= + +This idea is rather difficult to define, but is a bit like a data project, that +is a set of information that the packager believed had something in common. The +package then is an abstract idea, and what is in the package could change +completely over course of the life of the package. The package then is a little +bit like a namespace, having itself no content other than a string (the package +name) and the data it contains. + +Package name +============ + +This is a string that gives a name to the package. + +Package instantiation +===================== + +By *instantiation* we mean some particular actual set of data for a particular +package. By actual, we mean stuff that can be read as bytes. As we add and +remove data from the package, the *instantiation* changes. In version control, +the instantiation would be the particular state of the working tree at any +moment, whether this has been committed or not. + +It might not be enjoyable, but we'll call a package instantiation a *pinstance*. + +Pinstance revision +================== + +A revision is an instantiation of the working tree that has a unique label - the +*revision id*. + +Pinstance revision id +===================== + +The *revision id* is a string that identifies a particular *pinstance*. This is +the equivalent of the revision number in subversion_, or the commit hash in +systems like git_ or mercurial_. There is only one pinstance for any given +revision id, but there can be more than one revision id for a pinstance. For +example, you might have a revision of id '200', delete a file, restore the file, +call this revision id '201', but they might both refer to the same instantiation +of the package. Or they might not, that's up to you, the author of the package. + +Pinstance tag +============= + +A *tag* is a memorable string that refers to a particular pinstance. It differs +from a revision id only in that there is not likely to be a tag for every +revision. It's possible to imagine pinstances without a revision id but with a +tag, but perhaps it's reasonable to restrict tags to refer to revisions. A +*tag* is equivalent to a tag name in git or mercurial - a memorable string that +refers to a static state of the data. An example might be a numbered version. +So, a package may have a revision uniquely identified by a revision id +``af5bd6``. We might decide to label this revision ``release-0.3`` (the +equivalent of applying a git tag). ``release-0.3`` is the tag and ``af5bd6`` is +the revision id. Different sources of the same package might possibly produce +different tags [#tag-sources]_ + +Pinstance version +================= + +A *pinstance* might also have a version. A version is just a tag that can be +compared using some algorithm. + +.. _prundle: + +Package provider bundle +======================= + +Maybe we could call this a "prundle". + +The *provider bundle* is something that can deliver the bytes of a particular +pinstance. For example, if you have a package named "interesting-images", you +might have a revision of that package identified by revision id "f745dc2" and +tagged with "version-0.2". There might be a *provider bundle* of that +instantiation that is a zipfile ``interesting-images-version-0.2.zip``. There +might also be a directory on an http server with the same contents +``http://my.server.org/packages/interesting-images/version-9.2``. The zipfile +and the http directory would both be *provider bundles* of the particular +instantiation. When I unpack the zipfile onto my hard disk, I might have a +directory ``/my/home/packages/interesting-images/version-0.2``. Now this path +is a provider bundle. + +Provider bundle format +====================== + +In the example above, the zipfile, the http directory and the local path are +three different provider bundle formats delivering the same package +instantiation. Let's call those formats: + +* zipfile format +* url-path format +* local-path format + +Pinstance release +================= + +A release might be a package instantiation that one person has: + +#. tagged +#. made available as one or more *provider bundles* + +.. _prundle-discovery: + +Prundle discovery +================= + +We *discover* a package bundle when we ask a system (local or remote) whether +they have a package bundle at a given revision, tag, or bundle format. That +implies two discoveries - *local discovery* (is the package bundle on my local +system, if so where is it?); and *remote discovery* (is the package bundle on +your expensive server and if so, how do I get it?). For the Debian +distributions, the ``sources.list`` file identifies sources from which we can +query for software packages. Those would be sources for *remote discovery* in +our language. + +Prundle discovery source +======================== + +A *prundle discovery source* is somewhere that can answer prundle discovery +queries. + +One such thing might be a prundle registry, where an element in the registry +contains information about a particular prundle. At a first pass this might +contain: + +* package name +* bundle format +* revision id (optional) +* tag (optional) + +Maybe it should also contain information about where the information came from. + +Pinstance metadata query +======================== + +We query a pinstance when we know that a particular system (local or remote) has +a package bundle of the pinstance we want. Then we get some information about +that pinstance. + +By definition, different prundles relating to the same pinstance have the same +metadata. + +Pinstance metadata query source +=============================== + +A *pinstance metadata query source* is somewhere that can answer pinstance +metadata queries. + +Obviously a source may well be both a *prundle discovery source* and a +*pinstance metadata query source*. + +Pinstance installation +====================== + +We install a pinstance when we get some prundle containing the pinstance and +place it on local storage, such that we can *discover* the prundle on our own +(local) system. That is we take some prundle and convert it to a *local-path* +format bundle *and* we register this local-path format bundle to a *discovery +source*. + +Data and metadata +================= + +Pinstance data + is the bytes as they are arranged in a particular pinstance. + +Pinstance metadata + is data about the pinstance. It might include information about what data + is in the package. + +Prundle metadata + Information about the particular prundle format. + +*********************** +Comparative terminology +*********************** + +In which we compare the package terminology above to the terminology of Debian +packaging. + +Compared to Debian packaging +============================ + +* A Debian distribution is a label - such as 'unstable' or 'lenny' - that refers to a + set of package revisions that go together. We have no equivalent. +* A Debian *repository* is a set of packages within a distribution that go + together - e.g. 'main' or 'contrib'. We probably don't have an equivalent + (unless we consider Debian's repository as being like a very large package + in our language). +* A Debian source is a URI giving a location from which you can collect one or + more repositories. For example, the line: "http://www.example.com/packages + stable main contrib" in a "sources.list" file refers to the *source* + "http://www.example.com/packages" providing *distribution* "stable" and + *repositories* (within stable) of "main" and "contrib". In our language the + combination of URI, distribution and repository would refer to a *prundle + discovery source* - that is - something that will answer queries about + bundles. +* package probably means the same for us as for Debian - a name - like + "python-numpy" - that refers to a set of files that go together and should be + installed together. +* Debian packages have versions to reflect the different byte contents. For + example there might be a .deb file (see below) "some-package-0.11_3-i386.deb" + for one distribution, and another (with different contents) for another + distribution - say "some-package-0.12_9-i386.deb". The "0.11_3" and "0.12_9" + parts of the deb filename are what we would call *package instantiation tags*. +* A Debian deb file is an archive in a particular format that unpacks to provide + the files for a particular package version. We'd call the deb file a *package + bundle*, that is in *bundle format* "deb-format". + +********** +Desiderata +********** + +We want to build a package system that is very simple ('S' in 0SAGA_). For the +moment, the main problems we want to solve are: creation of a package +instantiation, installation of package instantiations, local discovery of +package instantiations. For now we are not going to try and solve queries. + +At least local discovery should be so simple that it can be implemented in any +language, and should not require a particular tool to be installed. We hope we +can write a spec that makes all of (creation, installation, local discovery) +clearly defined, so that it would be simple to write an implementation. +Obviously we're going to end up writing our own implementation, or adapting +someone else's. datapkg_ looks like the best candidate at the moment. + +****** +Issues +****** + +From a brief scan of the `debian package management documentation +<https://www.debian.org/doc/manuals/debian-reference/ch02.en.html>`_. + +Dependency management +===================== + +(no plan at the moment) + +Authentication and validation +============================= + +* Authentication - using signatures to confirm that you made this package. +* Verification - verify that the contents have not been corrupted or changed + since the original instantiation. + +For dependency and validation, see the `Debian secure apt`_ page. One related +proposal would be: + +.. _Debian secure apt: https://wiki.debian.org/SecureApt + +* Each package instantiation would carry a table of checksums for the files + within. Someone using this instantiation would check the checksums to confirm + that they had the intended content. +* Authentication would involve some kind of signing of the table of checksums, + as in the ``Release.gpg`` file in Debian distributions (`Debian secure apt`_ + again). This involves taking a checksum of the table of checksums, then using + our trusted private key to encrypt this checksum, generating a digital + signature. The signature is the thing we provide to the user. The user then + gets our public key or has it already; they use the key to decrypt the + signature to get the checksum, and they check the resulting checksum against + the actual checksum of the checksum table. The property of the public/private + key pair is that it is very hard to go backwards. To explain, here's an + example. Imagine someone we don't like has made a version of the package + instantiation, but wants to persuade the world that we made it. Their + contents will have different checksums, and therefore a different checksum for + the checksum table. Let's say the checksum of the new checksum table is *X*. + They know that you, the user, will use your own copy of our public key, and + they can't get at that. Their job then, is to make a new encrypted checksum + (the signature) that will decrypt with our real public key, to equal *X*. + That's going backwards from the desired result *X* to the signature, and that + is very hard, if they don't have our private key. + +****************************** +Differences from code packages +****************************** + +The obvious differences are: + +#. Data packages can be very large +#. We have less need for full history tracking (probably) + +The size of data packages probably mean that using git_ itself will not work +well. git_ stores (effectively) all previous versions of the files in the +repository, as zlib compressed blobs. The working tree is an uncompressed +instantiation of the current state. Thus, if we have, over time, had 4 +different versions of a large file with little standard diff relationship to one +another, the repository will have four zlib compressed versions of the file in +the ``.git/objects`` database, and one uncompressed version in the working tree. +The files in data packages may or may not compress well. + +In contrast to the full git_ model, we may want to avoid duplicates of the data. +We probably won't by default want to keep all previous versions of the data +together at least locally. + +We probably do want to be able to keep track of which files are the same across +different instantiations of the package, in the case where we already have one +instantiation on local disk, and we are asking for another, with some shared +files. We might well want to avoid downloading duplicate data in that case. + +Maybe the way to think of it is of the different costs that become important as +files get larger. So the cost for holding a full history becomes very large, +whereas the benefit decreases a little bit (compared to code). + +************* +Some usecases +************* + +Discovery +========= + +:: + + from ourpkg import default_registry + + my_pkg_path = default_registry.pathfor('mypkg', '0.3') + if mypkg_path is None: + raise RuntimeError('It looks like mypkg version 0.3 is not installed') + + +.. rubric:: Footnotes + +.. [#tag-sources] + + Revision ids could for example be hashes of the package instantiation + (package contents), so they could be globally unique to the contents, + wherever the contents was when the identifier was made. However, *tags* + are just names that someone has attached to a particular revision id. If + there is more than one person providing versions of a particular package, + there may not be agreement on the revision that a particular tag is attached + to. For example, I might think that ``release-0.3`` of ``some-package`` + refers to package state identified by revision id ``af5bd6``, but you might + think that ``release-0.3`` of ``some-package`` refers to some other package + state. In this case you and are are both a *tag sources* for the package. + The state that particular tag refers to can depend then on the source from + which the tag came. + +.. include:: ../links_names.txt diff --git a/_sources/devel/devdiscuss.rst.txt b/_sources/devel/devdiscuss.rst.txt new file mode 100644 index 0000000000..bc23e823c2 --- /dev/null +++ b/_sources/devel/devdiscuss.rst.txt @@ -0,0 +1,25 @@ +.. -*- mode: rst; fill-column: 79 -*- +.. ex: set sts=4 ts=4 sw=4 et tw=79: + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + # + # See COPYING file distributed along with the NiBabel package for the + # copyright and license terms. + # + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + +.. _chap_devdiscuss: + +********************* +Developer discussions +********************* + +Some miscellaneous documents on background, future development and work in +progress. + +.. toctree:: + :maxdepth: 2 + + spm_use + modified_images + scaling + bv_formats diff --git a/_sources/devel/devguide.rst.txt b/_sources/devel/devguide.rst.txt new file mode 100644 index 0000000000..8748270f11 --- /dev/null +++ b/_sources/devel/devguide.rst.txt @@ -0,0 +1,211 @@ +.. -*- mode: rst; fill-column: 79 -*- .. ex: set sts=4 ts=4 sw=4 et tw=79: + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + # + # See COPYING file distributed along with the NiBabel package for the + # copyright and license terms. + # + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + +.. _chap_devguide: + +**************************** +NiBabel Developer Guidelines +**************************** + +Also see :ref:`devindex` + +NiBabel source code +=================== + +.. toctree:: + :maxdepth: 2 + + ../gitwash/index + +Documentation +============= + +Code Documentation +------------------ + +Please write documentation using Numpy documentation conventions: + + https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard + + +Git Repository +============== + +Layout +------ + +The main release branch is called ``master``. This is a merge-only branch. +Features finished or updated by some developer are merged from the +corresponding branch into ``master``. At a certain point the current state of +``master`` is tagged -- a release is done. + +Only usable feature should end-up in ``master``. Ideally ``master`` should be +releasable at all times. + +Additionally, there are distribution branches. They are prefixed ``dist/`` +and labeled after the packaging target (e.g. *debian* for a Debian package). +If necessary, there can be multiple branches for each distribution target. + +``dist/debian/proper`` + Official Debian packaging + +``dist/debian/dev`` + Debian packaging of unofficial development snapshots. They do not go into the + main Debian archive, but might be distributed through other channels (e.g. + NeuroDebian). + +Releases are merged into the packaging branches, packaging is updated if +necessary and the branch gets tagged when a package version is released. +Maintenance (as well as backport) releases or branches off from the respective +packaging tag. + +There might be additional branches for each developer, prefixed with initials. +Alternatively, several GitHub (or elsewhere) clones might be used. + + +Commits +------- + +Please prefix all commit summaries with one (or more) of the following labels. +This should help others to easily classify the commits into meaningful +categories: + + * *BF* : bug fix + * *RF* : refactoring + * *NF* : new feature + * *BW* : addresses backward-compatibility + * *OPT* : optimization + * *BK* : breaks something and/or tests fail + * *PL* : making pylint happier + * *DOC*: for all kinds of documentation related commits + * *TEST*: for adding or changing tests + +Merges +------ + +For easy tracking of what changes were absorbed during merge, we +advise that you enable merge summaries within git: + + git-config merge.summary true + +See :ref:`configure-git` for more detail. + +Testing +======= + +NiBabel uses tox_ to organize our testing and development workflows. +tox runs tests in isolated environments that we specify, +ensuring that we are able to test across many different environments, +and those environments do not depend on our local configurations. + +If you have the pipx_ tool installed, then you may simply:: + + pipx run tox + +Alternatively, you can install tox and run it:: + + python -m pip install tox + tox + +This will run the tests in several configurations, with multiple sets of +optional dependencies. +If you have multiple versions of Python installed in your path, it will +repeat the process for each version of Python iin our supported range. +It may be useful to pick a particular version for rapid development:: + + tox -e py311-full-x64 + +This will run the environment using the Python 3.11 interpreter, with the +full set of optional dependencies that are available for 64-bit +interpreters. If you are using 32-bit Python, replace ``-x64`` with ``-x86``. + + +Style guide +=========== + +To ensure code consistency and readability, NiBabel has adopted the following +tools: + +* blue_ - An auto-formatter that aims to reduce diffs to relevant lines +* isort_ - An import sorter that groups stdlib, third-party and local imports. +* flake8_ - A style checker that can catch (but generally not fix) common + errors in code. +* codespell_ - A spell checker targeted at source code. +* pre-commit_ - A pre-commit hook manager that runs the above and various + other checks/fixes. + +While some amount of personal preference is involved in selecting and +configuring auto-formatters, their value lies in largely eliminating the +need to think or argue about style. +With pre-commit turned on, you can write in the style that works for you, +and the NiBabel style will be adopted prior to the commit. + +To apply our style checks uniformly, simply run:: + + tox -e style,spellcheck + +To fix any issues found:: + + tox -e style-fix + tox -e spellcheck -- -w + +Occasionally, codespell has a false positive. To ignore the suggestion, add +the intended word to ``tool.codespell.ignore-words-list`` in ``pyproject.toml``. +However, the ignore list is a blunt instrument and could cause a legitimate +misspelling to be missed. Consider choosing a word that does not trigger +codespell before adding it to the ignore list. + +Pre-commit hooks +---------------- + +NiBabel uses pre-commit_ to help committers validate their changes +before committing. To enable these, you can use pipx_:: + + pipx run pre-commit install + +Or install and run:: + + python -m pip install pre-commit + pre-commit install + + +Changelog +========= + +The changelog is located in the toplevel directory of the source tree in the +`Changelog` file. The content of this file should be formatted as restructured +text to make it easy to put it into manual appendix and on the website. + +This changelog should neither replicate the VCS commit log nor the +distribution packaging changelogs (e.g. debian/changelog). It should be +focused on the user perspective and is intended to list rather macroscopic +and/or important changes to the module, like feature additions or bugfixes in +the algorithms with implications to the performance or validity of results. + +It may list references to 3rd party bugtrackers, in case the reported bugs +match the criteria listed above. + +.. _mission_and_values: + +.. _community_guidelines: + +.. _code_of_conduct: + +Community guidelines +==================== + +Please see `our community guidelines +<https://github.com/nipy/nibabel/blob/master/.github/CODE_OF_CONDUCT.md>`_. +Other projects call these guidelines the "code of conduct". + +.. _blue: https://blue.readthedocs.io/ +.. _codespell: https://github.com/codespell-project/codespell +.. _flake8: https://flake8.pycqa.org/ +.. _pipx: https://pypa.github.io/pipx/ +.. _precommit: https://pre-commit.com/ +.. _tox: https://tox.wiki/ diff --git a/_sources/devel/governance.rst.txt b/_sources/devel/governance.rst.txt new file mode 100644 index 0000000000..407080c061 --- /dev/null +++ b/_sources/devel/governance.rst.txt @@ -0,0 +1,180 @@ +.. _governance: + +============================== +Governance and Decision Making +============================== + +Abstract +======== + +Nibabel is a consensus-based community project. Anyone with an interest in the +project can join the community, contribute to the project design, and +participate in the decision making process. This document describes how that +participation takes place, how to find consensus, and how deadlocks are +resolved. + +Roles And Responsibilities +========================== + +The Community +------------- + +The Nibabel community consists of anyone using or working with the project +in any way. + +Contributors +------------ + +Any community member can become a contributor by interacting directly with the +project in concrete ways, such as: + +- proposing a change to the code or documentation via a GitHub pull request; +- reporting issues on our + `GitHub issues page <https://github.com/nipy/nibabel/issues>`_; +- discussing the design of the library, website, or tutorials on the + `mailing list <https://mail.python.org/mailman/listinfo/neuroimaging>`_, + or in existing issues and pull requests; or +- reviewing + `open pull requests <https://github.com/nipy/nibabel/pulls>`_, + +among other possibilities. By contributing to the project, community members +can directly help to shape its future. + +Contributors should read the :ref:`chap_devguide` and our :ref:`community_guidelines`. + +Core Developers +--------------- + +Core developers are community members that have demonstrated continued +commitment to the project through ongoing contributions. They +have shown they can be trusted to maintain Nibabel with care. Becoming a +core developer allows contributors to merge approved pull requests, cast votes +for and against merging a pull request, and be involved in deciding major +changes to the API, and thereby more easily carry on with their project related +activities. + +Core developers: + +================ ============= +Name GitHub user +================ ============= +Chris Markiewicz effigies +Matthew Brett matthew-brett +Oscar Esteban oesteban +================ ============= + +Core developers also appear as team members on the `Nibabel Core Team page +<https://github.com/orgs/nipy/teams/nibabel-core-developers/members>`_ and can +be messaged ``@nipy/nibabel-core-developers``. We expect core developers to +review code contributions while adhering to the :ref:`core_dev`. + +New core developers can be nominated by any existing core developer. Discussion +about new core developer nominations is one of the few activities that takes +place on the project's private management list. The decision to invite a new +core developer must be made by β€œlazy consensus”, meaning unanimous agreement by +all responding existing core developers. Invitation must take place at least +one week after initial nomination, to allow existing members time to voice any +objections. + +.. _steering_council: + +Steering Council +---------------- + +The Steering Council (SC) members are current or former core developers who +have additional responsibilities to ensure the smooth running of the project. +SC members are expected to participate in strategic planning, approve changes +to the governance model, and make decisions about funding granted to the +project itself. (Funding to community members is theirs to pursue and manage.) +The purpose of the SC is to ensure smooth progress from the big-picture +perspective. Changes that impact the full project require analysis informed by +long experience with both the project and the larger ecosystem. When the core +developer community (including the SC members) fails to reach such a consensus +in a reasonable timeframe, the SC is the entity that resolves the issue. + +The steering council is: + +=================== ============= +Name GitHub user +=================== ============= +Chris Markiewicz effigies +Matthew Brett matthew-brett +Michael Hanke mih +Yaroslav Halchenko yarikoptic +=================== ============= + +Steering Council members also appear as team members on the `Nibabel Steering +Council Team page +<https://github.com/orgs/nipy/teams/nibabel-steering-council/members>`_ and +can be messaged ``@nipy/nibabel-steering-council``. + +Decision Making Process +======================= + +Decisions about the future of the project are made through discussion with all +members of the community. All non-sensitive project management discussion takes +place on the project +`mailing list <https://mail.python.org/mailman/listinfo/neuroimaging>`_ +and the `issue tracker <https://github.com/nipy/nibabel/issues>`_. +Occasionally, sensitive discussion may occur on a private list. + +Decisions should be made in accordance with our :ref:`mission_and_values`. + +Nibabel uses a *consensus seeking* process for making decisions. The group +tries to find a resolution that has no open objections among core developers. +Core developers are expected to distinguish between fundamental objections to a +proposal and minor perceived flaws that they can live with, and not hold up the +decision making process for the latter. If no option can be found without +an objection, the decision is escalated to the SC, which will itself use +consensus seeking to come to a resolution. In the unlikely event that there is +still a deadlock, the proposal will move forward if it has the support of a +simple majority of the SC. Any proposal must be described by a Nibabel :ref:`biap`. + +Decisions (in addition to adding core developers and SC membership as above) +are made according to the following rules: + +- **Minor documentation changes**, such as typo fixes, or addition / correction + of a sentence (but no change of the Nibabel landing page or the β€œabout” + page), require approval by a core developer *and* no disagreement or + requested changes by a core developer on the issue or pull request page (lazy + consensus). We expect core developers to give β€œreasonable time” to others to + give their opinion on the pull request if they’re not confident others would + agree. + +- **Code changes and major documentation changes** require agreement by *one* + core developer *and* no disagreement or requested changes by a core developer + on the issue or pull-request page (lazy consensus). + +- **Changes to the API principles** require a :ref:`biap` and follow the + decision-making process outlined above. + +- **Changes to this governance model or our mission and values** require + a :ref:`biap` and follow the decision-making process outlined above, *unless* + there is unanimous agreement from core developers on the change. + +If an objection is raised on a lazy consensus, the proposer can appeal to the +community and core developers and the change can be approved or rejected by +escalating to the SC, and if necessary, a BIAP (see below). + +.. _biap: + +Enhancement Proposals (BIAPs) +============================= + +Any proposals for enhancements of Nibabel should be written as a formal BIAP +following the template :ref:`biap_template`. The BIAP must be made public and +discussed before any vote is taken. The discussion must be summarized by a key +advocate of the proposal in the appropriate section of the BIAP. Once this +summary is made public and after sufficient time to allow the core team to +understand it, they vote. + +The workflow of a BIAP is detailed in :ref:`biap0`. + +A list of all existing BIAPs is available :ref:`here <biap_list>`. + +Acknowledgments +=============== + +Many thanks to Jarrod Millman, Dan Schult and the Scikit-Image team for the +`draft on which we based this document +<https://networkx.github.io/documentation/latest/developer/nxeps/nxep-0001.html>`_. diff --git a/_sources/devel/image_design.rst.txt b/_sources/devel/image_design.rst.txt new file mode 100644 index 0000000000..4aa0b18a76 --- /dev/null +++ b/_sources/devel/image_design.rst.txt @@ -0,0 +1,7 @@ +:orphan: + +######################## +The nibabel image object +######################## + +The latest version of this page is now at :doc:`../nibabel_images`. diff --git a/_sources/devel/index.rst.txt b/_sources/devel/index.rst.txt new file mode 100644 index 0000000000..da9af0751d --- /dev/null +++ b/_sources/devel/index.rst.txt @@ -0,0 +1,21 @@ +.. -*- mode: rst -*- +.. ex: set sts=4 ts=4 sw=4 et tw=79: + +.. _devindex: + +Developer documentation page +============================ + +.. toctree:: + :maxdepth: 2 + + devguide + core_developer + governance + roadmap + biaps/index + add_test_data + add_image_format + devdiscuss + make_release + advanced_testing diff --git a/_sources/devel/make_release.rst.txt b/_sources/devel/make_release.rst.txt new file mode 100644 index 0000000000..6a09d280b2 --- /dev/null +++ b/_sources/devel/make_release.rst.txt @@ -0,0 +1,315 @@ +.. _release-guide: + +*********************************** +A guide to making a nibabel release +*********************************** + +This is a guide for developers who are doing a nibabel release. + +The general idea of these instructions is to go through the following steps: + +* Make sure that the code is in the right state for release; +* update release-related docs such as the Changelog; +* update various documents giving dependencies, dates and so on; +* check all standard and release-specific tests pass; +* make the *release commit* and release tag; +* check Windows binary builds and slow / big memory tests; +* push source and windows builds to pypi; +* push docs; +* push release commit and tag to github; +* announce. + +We leave pushing the tag to the last possible moment, because it's very bad +practice to change a git tag once it has reached the public servers (in our +case, github). So we want to make sure of the contents of the release before +pushing the tag. + +.. _release-checklist: + +Release checklist +================= + +* Review the open list of `nibabel issues`_. Check whether there are + outstanding issues that can be closed, and whether there are any issues that + should delay the release. Label them ! + +* Review and update the release notes. Review and update the ``Changelog`` + file. Get a partial list of contributors with something like:: + + git log 2.0.0.. | grep '^Author' | cut -d' ' -f 2- | sort | uniq + + where ``2.0.0`` was the last release tag name. + + Then manually go over ``git shortlog 2.0.0..`` to make sure the release + notes are as complete as possible and that every contributor was recognized. + +* Look at ``doc/source/index.rst`` and add any authors not yet acknowledged. + You might want to use the following to list authors by the date of their + contributions:: + + git log --format="%aN <%aE>" --reverse | perl -e 'my %dedupe; while (<STDIN>) { print unless $dedupe{$_}++}' + + (From: + http://stackoverflow.com/questions/6482436/list-of-authors-in-git-since-a-given-commit#6482473) + + Consider any updates to the ``AUTHOR`` file. + +* Use the opportunity to update the ``.mailmap`` file if there are any + duplicate authors listed from ``git shortlog -nse``. + +* Check the copyright year in ``doc/source/conf.py`` + +* Refresh the ``README.rst`` text from the ``LONG_DESCRIPTION`` in ``info.py`` + by running ``make refresh-readme``. + + Check the output of:: + + rst2html.py README.rst > ~/tmp/readme.html + + because this will be the output used by pypi_ + +* Check the dependencies listed in ``nibabel/info.py`` (e.g. + ``NUMPY_MIN_VERSION``) and in ``doc/source/installation.rst`` and in + ``requirements.txt`` and ``.travis.yml``. They should at least match. Do + they still hold? Make sure `nibabel on travis`_ is testing the minimum + dependencies specifically. + +* Do a final check on the `nipy buildbot`_. Use the ``try_branch.py`` + scheduler available in nibotmi_ to test particular schedulers. + +* Make sure all tests pass (from the nibabel root directory):: + + pytest --doctest-modules nibabel + +* Make sure you are set up to use the ``try_branch.py`` - see + https://github.com/nipy/nibotmi/blob/master/install.rst#trying-a-set-of-changes-on-the-buildbots + +* Make sure all your changes are committed or removed, because + ``try_branch.py`` pushes up the changes in the working tree; + +* The following checks get run with the ``nibabel-release-checks``, as in:: + + try_branch.py nibabel-release-checks + + Beware: this build does not usually error, even if the steps do not give the + expected output. You need to check the output manually by going to + https://nipy.bic.berkeley.edu/builders/nibabel-release-checks after the + build has finished. + + * Make sure all tests pass from sdist:: + + make sdist-tests + + and the three ways of installing (from tarball, repo, local in repo):: + + make check-version-info + + The last may not raise any errors, but you should detect in the output + lines of this form:: + + {'sys_version': '2.6.6 (r266:84374, Aug 31 2010, 11:00:51) \n[GCC 4.0.1 (Apple Inc. build 5493)]', 'commit_source': 'archive substitution', 'np_version': '1.5.0', 'commit_hash': '25b4125', 'pkg_path': '/var/folders/jg/jgfZ12ZXHwGSFKD85xLpLk+++TI/-Tmp-/tmpGPiD3E/pylib/nibabel', 'sys_executable': '/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python', 'sys_platform': 'darwin'} + /var/folders/jg/jgfZ12ZXHwGSFKD85xLpLk+++TI/-Tmp-/tmpGPiD3E/pylib/nibabel/__init__.pyc + {'sys_version': '2.6.6 (r266:84374, Aug 31 2010, 11:00:51) \n[GCC 4.0.1 (Apple Inc. build 5493)]', 'commit_source': 'installation', 'np_version': '1.5.0', 'commit_hash': '25b4125', 'pkg_path': '/var/folders/jg/jgfZ12ZXHwGSFKD85xLpLk+++TI/-Tmp-/tmpGPiD3E/pylib/nibabel', 'sys_executable': '/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python', 'sys_platform': 'darwin'} + /Users/mb312/dev_trees/nibabel/nibabel/__init__.pyc + {'sys_version': '2.6.6 (r266:84374, Aug 31 2010, 11:00:51) \n[GCC 4.0.1 (Apple Inc. build 5493)]', 'commit_source': 'repository', 'np_version': '1.5.0', 'commit_hash': '25b4125', 'pkg_path': '/Users/mb312/dev_trees/nibabel/nibabel', 'sys_executable': '/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python', 'sys_platform': 'darwin'} + + * Check the ``setup.py`` file is picking up all the library code and scripts, + with:: + + make check-files + + Look for output at the end about missed files, such as:: + + Missed script files: /Users/mb312/dev_trees/nibabel/bin/nib-dicomfs, /Users/mb312/dev_trees/nibabel/bin/nifti1_diagnose.py + + Fix ``setup.py`` to carry across any files that should be in the + distribution. + + * Check the documentation doctests:: + + make -C doc doctest + + This should also be tested by `nibabel on travis`_. + + * Check everything compiles without syntax errors:: + + python -m compileall . + + * Check that nibabel correctly generates a source distribution:: + + make source-release + +* Edit ``nibabel/info.py`` to set ``_version_extra`` to ``''``; commit; + +* You may have virtualenvs for different Python versions. Check the tests + pass for different configurations. The long-hand way looks like this:: + + workon python26 + make distclean + make sdist-tests + deactivate + + etc for the different virtualenvs; + +* Check on different platforms, particularly windows and PPC. Look at the + `nipy buildbot`_ automated test runs for this; + +* Force build of your release candidate branch with the slow and big-memory + tests on the ``zibi`` buildslave:: + + try_branch.py nibabel-py2.7-osx-10.10 + + Check the build web-page for errors: + + * https://nipy.bic.berkeley.edu/builders/nibabel-py2.7-osx-10.10 + +* Force builds of your local branch on the win32 and amd64 binaries on + buildbot:: + + try_branch.py nibabel-bdist32-27 + try_branch.py nibabel-bdist32-33 + try_branch.py nibabel-bdist32-34 + try_branch.py nibabel-bdist32-35 + try_branch.py nibabel-bdist64-27 + + Check the builds completed without error on their respective web-pages: + + * https://nipy.bic.berkeley.edu/builders/nibabel-bdist32-27 + * https://nipy.bic.berkeley.edu/builders/nibabel-bdist32-33 + * https://nipy.bic.berkeley.edu/builders/nibabel-bdist32-34 + * https://nipy.bic.berkeley.edu/builders/nibabel-bdist32-35 + * https://nipy.bic.berkeley.edu/builders/nibabel-bdist64-27 + +* Make sure you have travis-ci_ building set up for your own repo. Make a new + ``release-check`` (or similar) branch, and push the code in its current + state to a branch that will build, e.g:: + + git branch -D release-check # in case branch already exists + git co -b release-check + # You might need the --force flag here + git push your-github-user release-check -u + +* Once everything looks good, you are ready to upload the source release to + PyPi. See `setuptools intro`_. Make sure you have a file + ``\$HOME/.pypirc``, of form:: + + [distutils] + index-servers = + pypi + warehouse + + [pypi] + username:your.pypi.username + password:your-password + + [warehouse] + repository: https://upload.pypi.io/legacy/ + username:your.pypi.username + password:your-password + +* Clean:: + + make distclean + # Check no files outside version control that you want to keep + git status + # Nuke + git clean -fxd + +* When ready:: + + python setup.py register + python setup.py sdist --formats=gztar,zip + # -s flag to sign the release + twine upload -r warehouse -s dist/nibabel* + +* Tag the release with signed tag of form ``2.0.0``:: + + git tag -s 2.0.0 + +* Push the tag and any other changes to trunk with:: + + git push origin 2.0.0 + git push + +* Now the version number is OK, push the docs to github pages with:: + + make upload-html + +* Finally (for the release uploads) upload the Windows binaries you built with + ``try_branch.py`` above; + +* Set up maintenance / development branches + + If this is this is a full release you need to set up two branches, one for + further substantial development (often called 'trunk') and another for + maintenance releases. + + * Branch to maintenance:: + + git co -b maint/2.0.x + + Set ``_version_extra`` back to ``.dev`` and bump ``_version_micro`` by 1. + Thus the maintenance series will have version numbers like - say - + '2.0.1.dev' until the next maintenance release - say '2.0.1'. Commit. + Don't forget to push upstream with something like:: + + git push upstream-remote maint/2.0.x --set-upstream + + * Start next development series:: + + git co main-master + + then restore ``.dev`` to ``_version_extra``, and bump ``_version_minor`` + by 1. Thus the development series ('trunk') will have a version number + here of '2.1.0.dev' and the next full release will be '2.1.0'. + + Next merge the maintenance branch with the "ours" strategy. This just + labels the maintenance `info.py` edits as seen but discarded, so we can + merge from maintenance in future without getting spurious merge conflicts:: + + git merge -s ours maint/2.0.x + + If this is just a maintenance release from ``maint/2.0.x`` or similar, just + tag and set the version number to - say - ``2.0.2.dev``. + +* Push the main branch:: + + git push upstream-remote main-master + +* Make next development release tag + + After each release the master branch should be tagged + with an annotated (or/and signed) tag, naming the intended + next version, plus an 'upstream/' prefix and 'dev' suffix. + For example 'upstream/1.0.0.dev' means "development start + for upcoming version 1.0.0. + + This tag is used in the Makefile rules to create development snapshot + releases to create proper versions for those. The version derives its name + from the last available annotated tag, the number of commits since that, + and an abbreviated SHA1. See the docs of ``git describe`` for more info. + + Please take a look at the Makefile rules ``devel-src``, ``devel-dsc`` and + ``orig-src``. + +* Go to: https://github.com/nipy/nibabel/tags and select the new tag, to fill + in the release notes. Copy the relevant part of the Changelog into the + release notes. Click on "Publish release". This will cause Zenodo_ to + generate a new release "upload", including a DOI. After a few minutes, go + to https://zenodo.org/deposit and click on the new release upload. Click on + the "View" button and click on the DOI badge at the right to display the + text for adding a DOI badge in various formats. Copy the DOI Markdown text. + The markdown will look something like this:: + + [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.60847.svg)](https://doi.org/10.5281/zenodo.60847) + + Go back to the Github release page for this release, click "Edit release". + and copy the DOI into the release notes. Click "Update release". + + See: https://guides.github.com/activities/citable-code + +* Announce to the mailing lists. + +.. _setuptools intro: https://pythonhosted.org/an_example_pypi_project/setuptools.html + +.. include:: ../links_names.txt diff --git a/_sources/devel/modified_images.rst.txt b/_sources/devel/modified_images.rst.txt new file mode 100644 index 0000000000..5b6e203a42 --- /dev/null +++ b/_sources/devel/modified_images.rst.txt @@ -0,0 +1,121 @@ +.. -*- rst -*- + +############################################################# +Keeping track of whether images have been modified since load +############################################################# + +******* +Summary +******* + +This is a discussion of a missing feature in nibabel: the ability to keep +track of whether an image object in memory still corresponds to an image file +(or files) on disk. + +********** +Motivation +********** + +We may need to know whether the image in memory corresponds to the image file +on disk. + +For example, we often need to get filenames for images when passing +images to external programs. Imagine a realignment, in this case, in nipy_ +(the package):: + + import nipy + img1 = nibabel.load('meanfunctional.nii') + img2 = nibabel.load('anatomical.nii') + realigner = nipy.interfaces.fsl.flirt() + params = realigner.run(source=img1, target=img2) + +In ``nipy.interfaces.fsl.flirt.run`` there may at some point be calls like:: + + source_filename = nipy.as_filename(source_img) + target_filename = nipy.as_filename(target_img) + +As the authors of the ``flirt.run`` method, we need to make sure that the +``source_filename`` corresponds to the ``source_img``. + +Of course, in the general case, if ``source_img`` has no corresponding +filename (from ``source_img.get_filename()``, then we will have to save a copy +to disk, maybe with a temporary filename, and return that temporary name as +``source_filename``. + +In our particular case, ``source_img`` does have a filename +(``meanfunctional.nii``). We would like to return that as +``source_filename``. The question is, how can we be sure that the user has +done nothing to ``source_img`` to make it diverge from its original state? +Could ``source_img`` have diverged, in memory, from the state recorded in +``meantunctional.nii``? + +If the image and file have not diverged, we return ``meanfunctional.nii`` as +the ``source_filename``, otherwise we will have to do something like:: + + import tempfile + fname = tempfile.mkstemp('.nii') + img = source_img.to_filename(fname) + +and return ``fname`` as ``source_filename``. + +Another situation where we might like to pass around image objects that are +known to correspond to images on disk is when working in parallel. A set of +nodes may have fast common access to a filesystem on which the images are +stored. If a master is farming out images to nodes, a master node +distribution jobs to workers might want to check if the image was identical to +something on file and pass around a lightweight (proxied) image (with the data +not loaded into memory), relying on the node pulling the image from disk when +it uses it. + +*********************** +Possible implementation +*********************** + +One implementation is to have ``dirty`` flag, which, if set, would tell +you that the image might not correspond to the disk file. We set this +flag when anyone asks for the data, on the basis that the user may then +do something to the data and you can't know if they have:: + + img = nibabel.load('some_image.nii') + data = img.get_fdata() + data[:] = 0 + img2 = nibabel.load('some_image.nii') + assert not np.all(img2.get_fdata() == img.get_fdata()) + +The image consists of the data, the affine and a header. In order to +keep track of the header and affine, we could cache them when loading +the image:: + + img = nibabel.load('some_image.nii') + hdr = img.header + assert img._cache['header'] == img.header + hdr.set_data_dtype(np.complex64) + assert img._cache['header'] != img.header + +When we need to know whether the image object and image file correspond, we +could check the current header and current affine (the header may be separate +from the affine for an SPM Analyze image) against their cached copies, if they +are the same and the 'dirty' flag has not been set by a previous call to +``get_fdata()``, we know that the image file does correspond to the image +object. + +This may be OK for small bits of memory like the affine and the header, +but would quickly become prohibitive for larger image metadata such as +large nifti header extensions. We could just always assume that images +with large header extensions are *not* the same as for on disk. + +The user might be able to override the result of these checks directly:: + + img = nibabel.load('some_image.nii') + assert img.is_dirty == False + hdr = img.header + hdr.set_data_dtype(np.complex64) + assert img.is_dirty == True + img.is_dirty == False + +The checks are magic behind the scenes stuff that do some safe optimization +(in the sense that we are not re-saving the data if that is not necessary), +but drops back to the default (re-saving the data) if there is any +uncertainty, or the cost is too high to be able to check. + +.. include:: ../links_names.txt diff --git a/_sources/devel/roadmap.rst.txt b/_sources/devel/roadmap.rst.txt new file mode 100644 index 0000000000..b8d278ca31 --- /dev/null +++ b/_sources/devel/roadmap.rst.txt @@ -0,0 +1,93 @@ +####### +Roadmap +####### + +The roadmap is intended for larger, fundamental changes to the project that are +likely to take months or years of developer time. Smaller-scoped items will +continue to be tracked on our issue tracker. + +The scope of these improvements means that these changes may be controversial, +are likely to involve significant discussion among the core development team, +and may require the creation of one or more BIAPs (niBabel Increased +Awesomeness Proposals). + +========== +Background +========== + +Nibabel is a workbench that provides a Python API for working with images in +many formats. It is also a base library for tools implementing higher level +processing. + +Nibabel's success depends on: + +* How easy it is to express common imaging tasks in the API. +* The range of tasks it can perform. + +An expressive, broad API will increase adoption and make it easier to teach. + +Expressive API +============== + +Axis and tick labels +-------------------- + +Brain images typically have three or four axes, whose meanings depend on the +way the image was acquired. Axes have natural labels, expressing meaning, +such as "time" or "slice", and they may have tick labels such as acquisition +time. The scanner captures this information, but typical image formats cannot +store it, so it is easy to lose metadata and make analysis errors; see +:ref:`biap6`. + +We plan to expand Nibabel's API to encode axis and tick labels by integrating +the `Xarray package <http://xarray.pydata.org>`_. Xarray simplifies HDF5 +serialization, and visualization. + +An API for labels is not useful if we cannot read labels from the scanner +data, or save them with the image. We plan to: + +* Develop HDF5 equivalents of standard image formats, for serialization of + data with labels. +* Expand the current standard image format, NIfTI, to store labels in a JSON + addition to image metadata: :ref:`biap3`. +* Read image metadata from DICOM, the standard scanner format. + +Reading and attaching DICOM data will start with code integrated from +`Dcmstack <https://github.com/moloney/dcmstack>`_, by Brendan Moloney; see: +:ref:`biap4`. + +DICOM metadata is often hidden inside "private" DICOM elements that need +specialized parsers. We want to expand these parsers to preserve full metadata +and build a normalization layer to abstract vendor-specific storage locations +for metadata elements that describe the same thing. + +API for surface data +-------------------- + +Neuroimaging data often refers to locations on the brain surface. There are +three common formats for such data: GIFTI, CIFTI and Freesurfer. Nibabel can +read these formats, but lacks a standard API for reading and storing surface +data with metadata; see +`nipy/nibabel#936 <https://github.com/nipy/nibabel/issues/936>`_, +`nilearn/nilearn#2171 <https://github.com/nilearn/nilearn/issues/2171>`_. +We plan to develop a standard API, apply it to the standard formats, +and design an efficient general HDF5 storage container for serializing surface +data and metadata. + +Range +===== + +Spatial transforms +------------------ + +Neuroimaging toolboxes include spatial registration methods to align the +objects and features present in two or more images. Registration methods +estimate and store spatial transforms. There is no standard or compatible +format to store and reuse these transforms, across packages. + +Because Nibabel is a workbench, we want to extend its support to read +transforms calculated with AFNI, FreeSurfer, FSL, ITK/ANTs, NiftyReg, and SPM. + +We have developed the NiTransforms project for this task; we plan to complete +and integrate NiTransforms into Nibabel. This will make transforms more +accessible to researchers, and therefore easier to work with, and reason about. diff --git a/_sources/devel/scaling.rst.txt b/_sources/devel/scaling.rst.txt new file mode 100644 index 0000000000..cdeee0b13e --- /dev/null +++ b/_sources/devel/scaling.rst.txt @@ -0,0 +1,70 @@ +########################### +Scalefactors and intercepts +########################### + +SPM Analyze and nifti1 images have *scalefactors*. nifti1 images also have +*intercepts*. If ``A`` is an array in memory, and ``S`` is the array that will +be written to disk, then:: + + R = (A - intercept) / scalefactor + +and ``R == S`` if ``R`` is already the data dtype we need to write. + +If we load the image from disk, we exactly recover ``S`` (and ``R``). To get +something approximating ``A`` (say ``Aprime``) we apply the intercept and +scalefactor:: + + Aprime = (S * scalefactor) + intercept + +In a perfect world ``A`` would be exactly the same as ``Aprime``. However +``scalefactor`` and ``intercept`` are floating point values. With floating +point, if ``r = (a - b) / c; p = (r * c) + b`` it is not necessarily true that +``p == a``. For example: + +>>> import numpy as np +>>> a = 10 +>>> b = np.e +>>> c = np.pi +>>> r = (a - b) / c +>>> p = (r * c) + b +>>> p == a +False + +So there will be some error in this reconstruction, even when ``R`` is the same +type as ``S``. + +More common is the situation where ``R`` is a different type from ``S``. If +``R`` is of type ``r_dtype``, ``S`` is of type ``s_dtype`` and +``cast_function(R, dtype)`` is some function that casts ``R`` to the desired +type ``dtype``, then:: + + R = (A - intercept) / scalefactor + S = cast_function(R, s_dtype) + R_prime = cast_function(S, r_dtype) + A_prime = (R_prime * scalefactor) + intercept + +The type of ``R`` will depend on what numpy did for upcasting ``A, intercept, +scalefactor``. + +In order that ``cast_function(S, r_dtype)`` can best reverse ``cast_function(R, +s_dtype)``, the second needs to know the type of ``R``, which is not stored. The +type of ``R`` depends on the types of ``A`` and of ``intercept, scalefactor``. +We don't know the type of ``A`` because it is not stored. + +``R`` is likely to be a floating point type because of the application of +scalefactor and intercept. If ``(intercept, scalefactor)`` are not the identity +(0, 1), then we can ensure that ``R`` is at minimum the type of the ``intercept, +scalefactor`` by making these be at least 1D arrays, so that floating point +types will upcast in ``R = (A - intercept) / scalefactor``. + +The cast of ``R`` to ``S`` and back to ``R_prime`` can lose resolution if the +types of ``R`` and ``S`` have different resolution. + +Our job is to select: + +* scalefactor +* intercept +* ``cast_function`` + +such that we minimize some measure of difference between ``A`` and +``A_prime``. diff --git a/_sources/devel/spm_use.rst.txt b/_sources/devel/spm_use.rst.txt new file mode 100644 index 0000000000..8c47cd7f5e --- /dev/null +++ b/_sources/devel/spm_use.rst.txt @@ -0,0 +1,299 @@ +.. -*- mode: rst -*- + +======================== + Image use-cases in SPM +======================== + +SPM uses a *vol struct* as a structure characterizing an object. This +is a Matlab ``struct``. A ``struct`` is like a Python dictionary, where +field names (strings) are associated with values. There are various +functions operating on vol structs, so the vol struct is rather like an +object, where the methods are implemented as functions. Actually, the +distinction between methods and functions in Matlab is fairly subtle - +their call syntax is the same for example. + +.. sourcecode:: matlab + + >> fname = 'some_image.nii'; + >> vol = spm_vol(fname) % the vol struct + + vol = + + fname: 'some_image.nii' + mat: [4x4 double] + dim: [91 109 91] + dt: [2 0] + pinfo: [3x1 double] + n: [1 1] + descrip: 'NIFTI-1 Image' + private: [1x1 nifti] + + >> vol.mat % the 'affine' + + ans = + + -2 0 0 92 + 0 2 0 -128 + 0 0 2 -74 + 0 0 0 1 + + >> help spm_vol + Get header information etc for images. + FORMAT V = spm_vol(P) + P - a matrix of filenames. + V - a vector of structures containing image volume information. + The elements of the structures are: + V.fname - the filename of the image. + V.dim - the x, y and z dimensions of the volume + V.dt - A 1x2 array. First element is datatype (see spm_type). + The second is 1 or 0 depending on the endian-ness. + V.mat - a 4x4 affine transformation matrix mapping from + voxel coordinates to real world coordinates. + V.pinfo - plane info for each plane of the volume. + V.pinfo(1,:) - scale for each plane + V.pinfo(2,:) - offset for each plane + The true voxel intensities of the jth image are given + by: val*V.pinfo(1,j) + V.pinfo(2,j) + V.pinfo(3,:) - offset into image (in bytes). + If the size of pinfo is 3x1, then the volume is assumed + to be contiguous and each plane has the same scalefactor + and offset. + ____________________________________________________________________________ + + The fields listed above are essential for the mex routines, but other + fields can also be incorporated into the structure. + + The images are not memory mapped at this step, but are mapped when + the mex routines using the volume information are called. + + Note that spm_vol can also be applied to the filename(s) of 4-dim + volumes. In that case, the elements of V will point to a series of 3-dim + images. + + This is a replacement for the spm_map_vol and spm_unmap_vol stuff of + MatLab4 SPMs (SPM94-97), which is now obsolete. + _______________________________________________________________________ + Copyright (C) 2005 Wellcome Department of Imaging Neuroscience + + + >> spm_type(vol.dt(1)) + + ans = + + uint8 + + >> vol.private + + ans = + + NIFTI object: 1-by-1 + dat: [91x109x91 file_array] + mat: [4x4 double] + mat_intent: 'MNI152' + mat0: [4x4 double] + mat0_intent: 'MNI152' + descrip: 'NIFTI-1 Image' + + +So, in our (provisional) terms: + +* ``vol.mat`` == ``img.affine`` +* ``vol.dim`` == ``img.shape`` +* ``vol.dt(1)`` (``vol.dt[0]`` in Python) is equivalent to + ``img.get_data_dtype()`` +* ``vol.fname`` == ``img.get_filename()`` + +SPM abstracts the implementation of the image to the ``vol.private`` +member, that is not in fact required by the image interface. + +Images in SPM are always 3D. Note this behavior: + +.. sourcecode:: matlab + + >> fname = 'functional_01.nii'; + >> vol = spm_vol(fname) + + vol = + + 191x1 struct array with fields: + fname + mat + dim + dt + pinfo + n + descrip + private + +That is, one vol struct per 3D volume in a 4D dataset. + +SPM image methods / functions +============================= + +Some simple ones: + +.. sourcecode:: matlab + + >> fname = 'some_image.nii'; + >> vol = spm_vol(fname); + >> img_arr = spm_read_vols(vol); + >> size(img_arr) % just loads in scaled data array + + ans = + + 91 109 91 + + >> spm_type(vol.dt(1)) % the disk-level (IO) type is uint8 + + ans = + + uint8 + + >> class(img_arr) % always double regardless of IO type + + ans = + + double + + >> new_fname = 'another_image.nii'; + >> new_vol = vol; % matlab always copies + >> new_vol.fname = new_fname; + >> spm_write_vol(new_vol, img_arr) + + ans = + + fname: 'another_image.nii' + mat: [4x4 double] + dim: [91 109 91] + dt: [2 0] + pinfo: [3x1 double] + n: [1 1] + descrip: 'NIFTI-1 Image' + private: [1x1 nifti] + + +Creating an image from scratch, and writing plane by plane (slice by slice): + +.. sourcecode:: matlab + + >> new_vol = struct(); + >> new_vol.fname = 'yet_another_image.nii'; + >> new_vol.dim = [91 109 91]; + >> new_vol.dt = [spm_type('float32') 0]; % little endian (0) + >> new_vol.mat = vol.mat; + >> new_vol.pinfo = [1 0 0]'; + >> new_vol = spm_create_vol(new_vol); + >> for vox_z = 1:new_vol.dim(3) + new_vol = spm_write_plane(new_vol, img_arr(:,:,vox_z), vox_z); + end + +I think it's true that writing the plane does not change the image +scalefactors, so it's only practical to use ``spm_write_plane`` for data +for which you already know the dynamic range across the volume. + +Simple resampling from an image: + +.. sourcecode:: matlab + + >> fname = 'some_image.nii'; + >> vol = spm_vol(fname); + >> % for voxel coordinate 10,15,20 (1-based) + >> hold_val = 3; % third order spline resampling + >> val = spm_sample_vol(vol, 10, 15, 20, hold_val) + + val = + + 0.0510 + + >> img_arr = spm_read_vols(vol); + >> img_arr(10, 15, 20) % same as simple indexing for integer coordinates + + ans = + + 0.0510 + + >> % more than one point + >> x = [10, 10.5]; y = [15, 15.5]; z = [20, 20.5]; + >> vals = spm_sample_vol(vol, x, y, z, hold_val) + + vals = + + 0.0510 0.0531 + + >> % you can also get the derivatives, by asking for more output args + >> [vals, dx, dy, dz] = spm_sample_vol(vol, x, y, z, hold_val) + + vals = + + 0.0510 0.0531 + + + dx = + + 0.0033 0.0012 + + + dy = + + 0.0033 0.0012 + + + dz = + + 0.0020 -0.0017 + + +This is to speed up optimization in registration - where the optimizer +needs the derivatives. + +``spm_sample_vol`` always works in voxel coordinates. If you want some +other coordinates, you would transform them yourself. For example, +world coordinates according to the affine looks like: + +.. sourcecode:: matlab + + >> wc = [-5, -12, 32]; + >> vc = inv(vol.mat) * [wc 1]' + + vc = + + 48.5000 + 58.0000 + 53.0000 + 1.0000 + + >> vals = spm_sample_vol(vol, vc(1), vc(2), vc(3), hold_val) + + vals = + + 0.6792 + +Odder sampling, often used, can be difficult to understand: + +.. sourcecode:: matlab + + >> slice_mat = eye(4); + >> out_size = vol.dim(1:2); + >> slice_no = 4; % slice we want to fetch + >> slice_mat(3,4) = slice_no; + >> arr_slice = spm_slice_vol(vol, slice_mat, out_size, hold_val); + >> img_slice_4 = img_arr(:,:,slice_no); + >> all(arr_slice(:) == img_slice_4(:)) + + ans = + + 1 + + +This is the simplest use - but in general any affine transform can go in +``slice_mat`` above, giving optimized (for speed) sampling of slices +from volumes, as long as the transform is an affine. + +Miscellaneous functions operating on vol structs: + +* ``spm_conv_vol`` - convolves volume with separable functions in x, y, z +* ``spm_render_vol`` - does a projection of a volume onto a surface +* ``spm_vol_check`` - takes array of vol structs and checks for sameness of + image dimensions and ``mat`` (affines) across the list. + +And then, many SPM functions accept vol structs as arguments. diff --git a/_sources/dicom/dcm2nii_algorithms.rst.txt b/_sources/dicom/dcm2nii_algorithms.rst.txt new file mode 100644 index 0000000000..88cd55dfcd --- /dev/null +++ b/_sources/dicom/dcm2nii_algorithms.rst.txt @@ -0,0 +1,92 @@ +.. _dcm2nii-algorithms: + +==================== + dcm2nii algorithms +==================== + +dcm2nii_ is an open source DICOM_ to nifti_ conversion program, written +by Chris Rorden, in Delphi (object orientated pascal). It's part of +Chris' popular mricron_ collection of programs. The source appears to +be best found on the `mricron NITRC site`_. It's BSD_ licensed. + +.. _mricron NITRC site: https://www.nitrc.org/projects/mricron + +These are working notes looking at Chris' algorithms for working with +DICOM. + +Compiling dcm2nii +================= + +Follow the download / install instructions at the +http://www.lazarus.freepascal.org/ site. I was on a Mac, and followed the +instructions here: +http://wiki.lazarus.freepascal.org/Installing_Lazarus_on_MacOS_X . Default +build with version 0.9.28.2 gave an error linking against Carbon, so I needed to +download a snapshot of fixed Lazarus 0.9.28.3 from +http://www.hu.freepascal.org/lazarus . Open ``<mricron>/dcm2nii/dcm2nii.lpi`` +using the Lazarus GUI. Follow instructions for compiler setup in the mricron +``Readme.txt``; in particular I set other compiler options to:: + + -k-macosx_version_min -k10.5 + -XR/Developer/SDKs/MacOSX10.5.sdk/ + +Further inspiration for building also came from the ``debian/rules`` file in +Michael Hanke's mricron debian package: +http://neuro.debian.net/debian/pool/main/m/mricron/ + +Some tag modifications +====================== + +Note - Chris tells me that ``dicomfastread.pas`` was an attempt to do a fast +dicom read that is not yet fully compatible, and that the algorithm used is in +fact ``dicomcompat.pas``. + +Looking in the source file ``<mricron>/dcm2nii/dicomfastread.pas``. + +Named fields here are as from :ref:`dicom-fields` + +* If 'MOSAIC' is the last string in 'ImageType', this is a mosaic +* 'DateTime' field is combination of 'StudyDate' and 'StudyTime'; fixes + in file ``dicomtypes.pas`` for different scanner date / time formats. +* AcquisitionNumber read as normal, but then set to 1, if this a mosaic + image, as set above. +* If 'EchoNumbers' > 0 and < 16, add 'EchoNumber' * 100 to the + 'AcquisitionNumber' - presumably to identify different echos from the + same series as being different series. +* If 'ScanningSequence' sequence contains 'RM', add 100 to the + 'SeriesNumber' - maybe to differentiate research and not-research + scans with the same acquisition number. +* is_4D flag labeling DICOM file as a 4D file: + + * There's a Philips private tag (2001, 1018) - labeled 'Number of + Slices MR' by pydicom_ call this ``NS`` + * If ``NS>0`` and 'NumberofTemporalPositions' > 0, and + 'NumberOfFrames' is > 1 + +Sorting slices into volumes +=========================== + +Looking in the source file ``<mricron>/dcm2nii/sortdicom.pas``. + +In function ``ShellSortDCM``: + +Sort compares two dicom images, call them ``dcm1`` and ``dcm2``. Tests are: + +#. Are the two images 'repeats' - defined by same 'InstanceNumber' + (0020, 0013), and 'AcquisitionNumber' (0020, 0012) and 'SeriesNumber' + (0020, 0011) and a combination of 'StudyDate' and 'StudyTime')? Then + report an error about files having the same index, flag repeated values. +#. Is ``dcm1`` less than ``dcm2``, defined with comparisons in the + following order: + + #. StudyDate/Time + #. SeriesNumber + #. AcquisitionNumber + #. InstanceNumber + + This should obviously only ever be > or <, not ==, because of the + first check. + +Next remove repeated values as found in the first step above. + +.. include:: ../links_names.txt diff --git a/_sources/dicom/dicom.rst.txt b/_sources/dicom/dicom.rst.txt new file mode 100644 index 0000000000..28cedde5d6 --- /dev/null +++ b/_sources/dicom/dicom.rst.txt @@ -0,0 +1,26 @@ +.. _dicom: + +================================== +DICOM concepts and implementations +================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + dicom_info + dicom_intro + dicom_orientation + dicom_fields + dicom_mosaic + siemens_csa + spm_dicom + dicom_niftiheader + +.. these documents not yet ready for public advertisement + +.. toctree:: + :hidden: + + dcm2nii_algorithms diff --git a/_sources/dicom/dicom_fields.rst.txt b/_sources/dicom/dicom_fields.rst.txt new file mode 100644 index 0000000000..f7d2ab8490 --- /dev/null +++ b/_sources/dicom/dicom_fields.rst.txt @@ -0,0 +1,74 @@ +.. _dicom-fields: + +============== + DICOM fields +============== + +In which we pick out some interesting fields in the DICOM header. + +We're getting the information mainly from the standard `DICOM object +definitions`_ + +We won't talk about the orientation, patient position-type fields here +because we've covered those somewhat in :ref:`dicom-orientation`. + +Fields for ordering DICOM files into images +=========================================== + +You'll see some discussion of this in :ref:`spm-dicom`. + +Section 7.3.1: general series module + +* Modality (0008,0060) - Type of equipment that originally acquired the + data used to create the images in this Series. See C.7.3.1.1.1 for + Defined Terms. +* Series Instance UID (0020,000E) - Unique identifier of the Series. +* Series Number (0020,0011) - A number that identifies this Series. +* Series Time (0008,0031) - Time the Series started. + +Section C.7.6.1: + +* Instance Number (0020,0013) - A number that identifies this image. +* Acquisition Number (0020,0012) - A number identifying the single + continuous gathering of data over a period of time that resulted in + this image. +* Acquisition Time (0008,0032) - The time the acquisition of data that + resulted in this image started + +Section C.7.6.2.1.2: + +Slice Location (0020,1041) is defined as the relative position of the +image plane expressed in mm. This information is relative to an +unspecified implementation specific reference point. + +Section C.8.3.1 MR Image Module + +* Slice Thickness (0018,0050) - Nominal reconstructed slice thickness, + in mm. + +Section C.8.3.1 MR Image Module + +* Spacing Between Slices (0018,0088) - Spacing between slices, in + mm. The spacing is measured from the center-tocenter of each slice. +* Temporal Position Identifier (0020,0100) - Temporal order of a dynamic + or functional set of Images. +* Number of Temporal Positions (0020,0105) - Total number of temporal + positions prescribed. +* Temporal Resolution (0020,0110) - Time delta between Images in a + dynamic or functional set of images + +Multi-frame images +================== + +An image for which the pixel data is a continuous stream of sequential frames. + +Section C.7.6.6: Multi-Frame Module + +* Number of Frames (0028,0008) - Number of frames in a Multi-frame + Image. +* Frame Increment Pointer (0028,0009) - Contains the Data Element Tag of + the attribute that is used as the frame increment in Multi-frame pixel + data. + + +.. include:: ../links_names.txt diff --git a/_sources/dicom/dicom_info.rst.txt b/_sources/dicom/dicom_info.rst.txt new file mode 100644 index 0000000000..b9883d4bfc --- /dev/null +++ b/_sources/dicom/dicom_info.rst.txt @@ -0,0 +1,51 @@ +=================== + DICOM information +=================== + +DICOM_ is a large and sometimes confusing imaging data format. + +In the other pages in this series we try and document our understanding of +various aspects of DICOM relevant to converting to formats such as NIfTI_ . + +There are a large number of DICOM_ image conversion programs already, +partly because it is a complicated format with features that vary from +manufacturer to manufacturer. + +We use the excellent PyDICOM_ as our back-end for reading DICOM. + +Here is a selected list of other tools and relevant resources: + +* Grassroots DICOM : GDCM_ . It is C++ code wrapped with swig_ and so + callable from Python. ITK_ apparently uses it for DICOM conversion. + BSD_ license. +* dcm2nii_ - a BSD_ licensed converter by Chris Rorden. As usual, Chris + has done an excellent job of documentation, and it is well + battle-tested. There's a nice set of example data to test against and + a list of other DICOM software. The `MRIcron install`_ page points to + the source code. Chris has also put effort into extracting diffusion + parameters from the DICOM images. +* SPM8_ - SPM has a stable and robust general DICOM conversion tool + implemented in the ``spm_dicom_convert.m`` and ``spm_dicom_headers.m`` + scripts. The conversions don't try to get the diffusion parameters. + The code is particularly useful because it has been well-tested and is + written in Matlab_ - and so is relatively easy to read. GPL_ license. + We've described some of the algorithms that SPM uses for DICOM + conversion in :ref:`spm-dicom`. +* DICOM2Nrrd_: a command line converter to convert DICOM images to Nrrd_ + format. You can call the command from within the Slicer_ GUI. It + does have algorithms for getting diffusion information from the DICOM + headers, and has been tested with Philips, GE and Siemens data. It's + not clear whether it yet supports the :ref:`dicom-mosaic`. BSD_ style + license. +* The famous Philips cookbook: https://www.archive.org/details/DicomCookbook +* http://dicom.online.fr/fr/dicomlinks.htm + +=============== + Sample images +=============== + +* http://www.barre.nom.fr/medical/samples/ +* http://pubimage.hcuge.ch:8080/ +* Via links from the dcm2nii_ page. + +.. include:: ../links_names.txt diff --git a/_sources/dicom/dicom_intro.rst.txt b/_sources/dicom/dicom_intro.rst.txt new file mode 100644 index 0000000000..e618153396 --- /dev/null +++ b/_sources/dicom/dicom_intro.rst.txt @@ -0,0 +1,793 @@ +.. _dicom-intro: + +##################### +Introduction to DICOM +##################### + +DICOM defines standards for storing data in memory and on disk, and for +communicating this data between machines over a network. + +We are interested here in DICOM data. Specifically we are interested in DICOM +files. + +DICOM files are binary dumps of the objects in memory that DICOM sends across +the network. + +We need to understand the format that DICOM uses to send messages across the +network to understand the terms the DICOM uses when storing data in files. + +For example, I hope, by the time you reach the end of this document, you will +understand the following complicated and confusing statement from section 7 of +the DICOM standards document `PS 3.10`_: + + 7 DICOM File Format + + The DICOM File Format provides a means to encapsulate in a file the Data Set + representing a SOP Instance related to a DICOM IOD. As shown in Figure 7-1, + the byte stream of the Data Set is placed into the file after the DICOM File + Meta Information. Each file contains a single SOP Instance. + +***************** +DICOM is messages +***************** + +The fundamental task of DICOM is to allow different computers to send messages +to one another. These messages can contain data, and the data is very often +medical images. + +The messages are in the form of requests for an operation, or responses to those requests. + +Let's call the requests and the responses - services. + +Every DICOM message starts with a stream of bytes containing information about +the service. This part of the message is called the DICOM Message Service +Element or DIMSE. Depending on what the DIMSE was, there may follow some data +related to the request. + +For example, there is a DICOM service called "C-ECHO". This asks for a response +from another computer to confirm it has seen the echo request. There is no +associated data following the "C-ECHO" DIMSE part. So, the full message is the +DIMSE "C-ECHO". + +There is another DICOM service called "C-STORE". This is a request for the +other computer to store some data, such as an image. The data to be stored +follows the "C-STORE" DIMSE part. + +We go into more detail on this later in the page. + +Both the DIMSE and the subsequent data have a particular binary format - +consisting of DICOM elements (see below). + +Here we will cover: + +* what DICOM elements are; +* how DICOM elements are arranged to form complicated data structures such as images; +* how the service part and the data part go together to form whole messages +* how these parts relate to DICOM files. + +****************** +The DICOM standard +****************** + +The documents defining the standard are: + ++-------------+------------------------------------------------------------------+ +| Number | Name | ++=============+==================================================================+ +| `PS 3.1`_ | Introduction and Overview | ++-------------+------------------------------------------------------------------+ +| `PS 3.2`_ | Conformance | ++-------------+------------------------------------------------------------------+ +| `PS 3.3`_ | Information Object Definitions | ++-------------+------------------------------------------------------------------+ +| `PS 3.4`_ | Service Class Specifications | ++-------------+------------------------------------------------------------------+ +| `PS 3.5`_ | Data Structure and Encoding | ++-------------+------------------------------------------------------------------+ +| `PS 3.6`_ | Data Dictionary | ++-------------+------------------------------------------------------------------+ +| `PS 3.7`_ | Message Exchange | ++-------------+------------------------------------------------------------------+ +| `PS 3.8`_ | Network Communication Support for Message Exchange | ++-------------+------------------------------------------------------------------+ +| PS 3.9 | Retired | ++-------------+------------------------------------------------------------------+ +| `PS 3.10`_ | Media Storage / File Format for Media Interchange | ++-------------+------------------------------------------------------------------+ +| `PS 3.11`_ | Media Storage Application Profiles | ++-------------+------------------------------------------------------------------+ +| `PS 3.12`_ | Media Formats / Physical Media for Media Interchange | ++-------------+------------------------------------------------------------------+ +| PS 3.13 | Retired | ++-------------+------------------------------------------------------------------+ +| `PS 3.14`_ | Grayscale Standard Display Function | ++-------------+------------------------------------------------------------------+ +| `PS 3.15`_ | Security and System Management Profiles | ++-------------+------------------------------------------------------------------+ +| `PS 3.16`_ | Content Mapping Resource | ++-------------+------------------------------------------------------------------+ +| `PS 3.17`_ | Explanatory Information | ++-------------+------------------------------------------------------------------+ +| `PS 3.18`_ | Web Access to DICOM Persistent Objects (WADO) | ++-------------+------------------------------------------------------------------+ +| `PS 3.19`_ | Application Hosting | ++-------------+------------------------------------------------------------------+ +| `PS 3.20`_ | Transformation of DICOM to and from HL7 Standards | ++-------------+------------------------------------------------------------------+ + +***************** +DICOM data format +***************** + +DICOM data is stored in memory and on disk as a sequence of *DICOM elements* +(section 7 of `PS 3.5`_). + +DICOM elements +============== + +A DICOM element is made up of three or four fields. These are (Attribute Tag, +[Value Representation, ], Value Length, Value Field), where *Value +Representation* may be present or absent, depending on the type of "Value +Representation Encoding" (see below) + +Attribute Tag +------------- + +The attribute tag is a pair of 16-bit unsigned integers of form (Group number, +Element number). The tag uniquely identifies the element. + +The *Element number* is badly named, because the element number does not give a +unique number for the element, but only for the element within the group (given +by the *Group number*). + +The (Group number, Element number) are nearly always written as hexadecimal +numbers in the following format: ``(0010, 0010)``. The decimal representation +of hexadecimal 0010 is 16, so this tag refers to group number 16, element number +16. If you look this tag up in the DICOM data dictionary (`PS 3.6`_) you'll see +this must be the element called "PatientName". + +These tag groups have special meanings: + ++-----------+--------------------------------+ +| Tag group | Meaning | ++===========+================================+ +| 0000 | Command elements | ++-----------+--------------------------------+ +| 0002 | File meta elements | ++-----------+--------------------------------+ +| 0004 | Directory structuring elements | ++-----------+--------------------------------+ +| 0006 | (not used) | ++-----------+--------------------------------+ + +See Annex E (command dictionary) of `PS 3.7`_ for details on group 0000. See +sections 7 and 8 of `PS 3.6`_ for details of groups 2 and 4 respectively. + +Tags in groups 0000, 0002, 0004 are therefore not *data* elements, but Command +elements; File meta elements; directory structuring elements. + +Tags with groups from 0008 are *data* element tags. + +Standard attribute tags +^^^^^^^^^^^^^^^^^^^^^^^ + +*Standard* tags are tags with an even group number (see below). There is a full +list of all *standard* data element tags in the DICOM data dictionary in section +6 of DICOM standard `PS 3.6`_. + +Even numbered groups are defined in the DICOM standard data dictionary. Odd +numbered groups are "private", are *not* defined in the standard data dictionary +and can be used by manufacturers as they wish (see below). + +Quoting from section 7.1 of `PS 3.5`_: + + Two types of Data Elements are defined: + + -- Standard Data Elements have an even Group Number that is not (0000,eeee), + (0002,eeee), (0004,eeee), or (0006,eeee). + + Note: Usage of these groups is reserved for DIMSE Commands (see PS 3.7) and + DICOM File Formats. + + -- Private Data Elements have an odd Group Number that is not (0001,eeee), + (0003,eeee), (0005,eeee), (0007,eeee), or (FFFF,eeee). Private Data Elements + are discussed further in Section 7.8. + +Private attribute tags +^^^^^^^^^^^^^^^^^^^^^^ + +Private attribute tags are tags with an odd group number. A private element is +an element with a private tag. + +Private elements still use the (Tag, [Value Representation, ] Value Length, +Value Field) DICOM data format. + +The same odd group may be used by different manufacturers in different ways. + +To try and avoid collisions of private tags from different manufacturers, there +is a mechanism by which a manufacturer can tell other users of a DICOM dataset +that it has reserved a block in the (Group number, Element number) space for +their own use. To do this they write a "Private Creator" element where the tag +is of the form ``(gggg, 00xx)``, the Value Representation (see below) is "LO" +(Long String) and the Value Field is a string identifying what the space is +reserved for. Here ``gggg`` is the odd group we are reserving a portion of and +the ``xx`` is the block of elements we are reserving. A tag of ``(gggg, 00xx)`` +reserves the 256 elements in the range ``(gggg, xx00)`` to ``(gggg, xxFF)``. + +For example, here is a real data element from a Siemens DICOM dataset:: + + (0019, 0010) Private Creator LO: 'SIEMENS MR HEADER' + +This reserves the tags from ``(0019, 1000)`` to ``(0019, 10FF)`` for information +on the "SIEMENS MR HEADER" + +The odd group ``gggg`` must be greater than ``0008`` and the block reservation +``xx`` must be greater than or equal to ``0010`` and less than ``0100``. + +Here is the start of the relevant section from PS 3.5: + + 7.8.1 PRIVATE DATA ELEMENT TAGS + + It is possible that multiple implementers may define Private Elements with the + same (odd) group number. To avoid conflicts, Private Elements shall be + assigned Private Data Element Tags according to the following rules. + + a) Private Creator Data Elements numbered (gggg,0010-00FF) (gggg is odd) shall + be used to reserve a block of Elements with Group Number gggg for use by an + individual implementer. The implementer shall insert an identification code + in the first unused (unassigned) Element in this series to reserve a block of + Private Elements. The VR of the private identification code shall be LO (Long + String) and the VM shall be equal to 1. + + b) Private Creator Data Element (gggg,0010), is a Type 1 Data Element that + identifies the implementer reserving element (gggg,1000-10FF), Private Creator + Data Element (gggg,0011) identifies the implementer reserving elements + (gggg,1100-11FF), and so on, until Private Creator Data Element (gggg,00FF) + identifies the implementer reserving elements (gggg,FF00- FFFF). + + c) Encoders of Private Data Elements shall be able to dynamically assign + private data to any available (unreserved) block(s) within the Private group, + and specify this assignment through the blocks corresponding Private Creator + Data Element(s). Decoders of Private Data shall be able to accept reserved + blocks with a given Private Creator identification code at any position within + the Private group specified by the blocks corresponding Private Creator Data + Element. + +Value Representation +-------------------- + +Value Representation is often abbreviated to VR. + +The VR is a two byte character string giving the code for the encoding of the +subsequent data in the Value Field (see below). + +The VR appears in DICOM data that has "Explicit Value Representation", and is +absent for data with "Implicit Value Representation". "Implicit Value +Representation" uses the fact that the DICOM data dictionary gives VR values for +each tag in the standard DICOM data dictionary, so the VR value is implied by +the tag value, given the data dictionary. + +Most DICOM data uses "Explicit Value Representation" because the DICOM data +dictionary only gives VRs for standard (even group number, not private) data +elements. Each manufacturer writes their own private data elements, and the VR +of these elements is not defined in the standard, and therefore may not be known +to software not from that manufacturer. + +The VR codes have to be one of the values from this table (section 6.2 of DICOM +standard `PS 3.5`_): + ++----------------------+---------------------------------+ +| Value Representation | Description | ++======================+=================================+ +| AE | Application Entity | ++----------------------+---------------------------------+ +| AS | Age String | ++----------------------+---------------------------------+ +| AT | Attribute Tag | ++----------------------+---------------------------------+ +| CS | Code String | ++----------------------+---------------------------------+ +| DA | Date | ++----------------------+---------------------------------+ +| DS | Decimal String | ++----------------------+---------------------------------+ +| DT | Date/Time | ++----------------------+---------------------------------+ +| FL | Floating Point Single (4 bytes) | ++----------------------+---------------------------------+ +| FD | Floating Point Double (8 bytes) | ++----------------------+---------------------------------+ +| IS | Integer String | ++----------------------+---------------------------------+ +| LO | Long String | ++----------------------+---------------------------------+ +| LT | Long Text | ++----------------------+---------------------------------+ +| OB | Other Byte | ++----------------------+---------------------------------+ +| OF | Other Float | ++----------------------+---------------------------------+ +| OW | Other Word | ++----------------------+---------------------------------+ +| PN | Person Name | ++----------------------+---------------------------------+ +| SH | Short String | ++----------------------+---------------------------------+ +| SL | Signed Long | ++----------------------+---------------------------------+ +| SQ | Sequence of Items | ++----------------------+---------------------------------+ +| SS | Signed Short | ++----------------------+---------------------------------+ +| ST | Short Text | ++----------------------+---------------------------------+ +| TM | Time | ++----------------------+---------------------------------+ +| UI | Unique Identifier | ++----------------------+---------------------------------+ +| UL | Unsigned Long | ++----------------------+---------------------------------+ +| UN | Unknown | ++----------------------+---------------------------------+ +| US | Unsigned Short | ++----------------------+---------------------------------+ +| UT | Unlimited Text | ++----------------------+---------------------------------+ + +Value length +------------ + +Value length gives the length of the data contained in the Value Field tag, or +is a flag specifying the Value Field is of undefined length, and thus must be +terminated later in the data stream with a special Item or Sequence Delimitation +tag. + +Quoting from section 7.1.1 of `PS 3.5`_: + + Value Length: Either: + + a 16 or 32-bit (dependent on VR and whether VR is explicit or implicit) + unsigned integer containing the Explicit Length of the Value Field as the + number of bytes (even) that make up the Value. It does not include the + length of the Data Element Tag, Value Representation, and Value Length + Fields. + + a 32-bit Length Field set to Undefined Length (FFFFFFFFH). Undefined + Lengths may be used for Data Elements having the Value Representation + (VR) Sequence of Items (SQ) and Unknown (UN). For Data Elements with + Value Representation OW or OB Undefined Length may be used depending + on the negotiated Transfer Syntax (see Section 10 and Annex A). + +Value field +----------- + +An even number of bytes storing the value(s) of the data element. The exact +format of this data depends on the Value Representation (see above) and the +Value Multiplicity (see next section). + +Data element tags and data dictionaries +======================================= + +We can look up data element tags in a *data dictionary*. + +As we've seen, data element tags with even group numbers are *standard* data +element tags. We can look these up in the standard data dictionary in section 6 +of `PS 3.6`_. + +Data element tags with odd group numbers are *private* data element tags. These +can be used by manufacturers for information that may be specific to the +manufacturer. To look up these tags, we need the private data dictionary of the +manufacturer. + +A data dictionary lists (Attribute tag, Attribute name, Attribute Keyword, Value +Representation, Value Multiplicity) for all tags. + +For example, here is an excerpt from the table in PS 3.6 section 6: + ++-------------+------------------------------------------+-------------------------------------+----+----+ +| Tag | Name | Keyword | VR | VM | ++=============+==========================================+=====================================+====+====+ +| (0010,0010) | Patient's Name | PatientName | PN | 1 | ++-------------+------------------------------------------+-------------------------------------+----+----+ +| (0010,0020) | Patient ID | PatientID | LO | 1 | ++-------------+------------------------------------------+-------------------------------------+----+----+ +| (0010,0021) | Issuer of Patient ID | IssuerOfPatientID | LO | 1 | ++-------------+------------------------------------------+-------------------------------------+----+----+ +| (0010,0022) | Type of Patient ID | TypeOfPatientID | CS | 1 | ++-------------+------------------------------------------+-------------------------------------+----+----+ +| (0010,0024) | Issuer of Patient ID Qualifiers Sequence | IssuerOfPatientIDQualifiersSequence | SQ | 1 | ++-------------+------------------------------------------+-------------------------------------+----+----+ +| (0010,0030) | Patient's Birth Date | PatientBirthDate | DA | 1 | ++-------------+------------------------------------------+-------------------------------------+----+----+ +| (0010,0032) | Patient's Birth Time | PatientBirthTime | TM | 1 | ++-------------+------------------------------------------+-------------------------------------+----+----+ + +The "Name" column gives a standard name for the tag. "Keyword" gives a shorter +equivalent to the name without spaces that can be used as a variable or +attribute name in code. + +Value Representation in the data dictionary +------------------------------------------- + +The "VR" column in the data dictionary gives the Value Representation. There is +usually only one possible VR for each tag [#can_be_two]_. + +If a particular stream of data elements is using "Implicit Value Representation +Encoding" then the data elements consist of (tag, Value Length, Value Field) and +the Value Representation is implicit. In this case we have to get the Value +Representation from the data dictionary. If a stream is using "Explicit Value +Representation Encoding", the elements consist of (tag, Value Representation, +Value Length, Value Field) and the Value Representation is therefore already +specified along with the data. + +Value Multiplicity in the data dictionary +----------------------------------------- + +The "VM" column in the dictionary gives the Value Multiplicity for this tag. +Quoting from PS 3.5 section 6.4: + + The Value Multiplicity of a Data Element specifies the number of Values that + can be encoded in the Value Field of that Data Element. The VM of each Data + Element is specified explicitly in PS 3.6. If the number of Values that may + be encoded in an element is variable, it shall be represented by two numbers + separated by a dash; e.g., "1-10" means that there may be 1 to 10 Values in + the element. + +The most common values for Value Multiplicity in the standard data dictionary +are (in decreasing frequency) '1', '1-n', '3', '2', '1-2', '4' with other values +being less common. + +The data dictionary is the only way to know the Value Multiplicity of a +particular tag. This means that we need the manufacturer's private data +dictionary to know the Value Multiplicity of private attribute tags. + + +DICOM data structures +===================== + +A data set +---------- + +A DICOM *data set* is a ordered list of data elements. The order of the list is +the order of the tags of the data elements. Here is the definition from section +3.10 of `PS 3.5`_: + + DATA SET: Exchanged information consisting of a structured set of Attribute + values directly or indirectly related to Information Objects. The value of + each Attribute in a Data Set is expressed as a Data Element. A collection + of Data Elements ordered by increasing Data Element Tag number that is an + encoding of the values of Attributes of a real world object. + +Background - the DICOM world +---------------------------- + +DICOM has abstract definitions of a set of entities (objects) in the "Real +World". These real world objects have relationships between them. Section 7 of +`PS 3.3`_ has the title "DICOM model of the real world". Examples of Real World +entities are Patient, Study, Series. + +Here is a selected list of real world entities compiled from section 7 of PS +3.3: + +* Patient +* Visit +* Study +* Modality Performed Procedure Steps +* Frame of Reference +* Equipment +* Series +* Registration +* Fiducials +* Image +* Presentation State +* SR Document +* Waveform +* MR Spectroscopy +* Raw Data +* Encapsulated Document +* Real World Value Mapping +* Stereometric Relationship +* Surface +* Measurements + +DICOM refers to its model of the entities and their relationships in the real +world as the DICOM Application Model. PS 3.3: + + 3.8.5 DICOM application model: an Entity-Relationship diagram used to model + the relationships between Real-World Objects which are within the area of + interest of the DICOM Standard. + +DICOM Entities and Information Object Definitions +------------------------------------------------- + +This is rather confusing. + +PS 3.3 gives definitions of fundamental DICOM objects called *Information Object +Definitions* (IODs). Here is the definition of an IOD from section 3.8.7 of PS +3.3: + + 3.8.7 Information object definition (IOD): a data abstraction of a class of + similar Real-World Objects which defines the nature and Attributes relevant + to the class of Real-World Objects represented. + +IODs give lists of attributes (data elements) that refer to one or more objects +in the DICOM Real World. + +A single IOD is the usual atom of data sent in a single DICOM message. + +An IOD that contains attributes (data elements) for only one object in the DICOM +Real World is a *Normalized IOD*. From PS 3.3: + + 3.8.10 Normalized IOD: an Information Object Definition which represents a + single entity in the DICOM Application Model. Such an IOD includes + Attributes which are only inherent in the Real-World Object that the IOD + represents. + +Annex B of PS 3.3 defines the normalized IODs. + +Many DICOM Real World objects do not have corresponding normalized IODs, +presumably because there is no common need to send data only corresponding to - +say - a patient - without also sending related information like - say - an +image. If you do want to send information relating to a patient with +information relating to an image, you need a *composite IOD*. + +An IOD that contains attributes from more than one object in the DICOM Real +World is a *Composite IOD*. PS 3.3 again: + + 3.8.2 Composite IOD: an Information Object Definition which represents parts + of several entities in the DICOM Application Model. Such an IOD includes + Attributes which are not inherent in the Real-World Object that the IOD + represents but rather are inherent in related Real-World Objects + +Annex A of PS 3.3 defines the composite IODs. + +DICOM MR or CT image IODs are classic examples of composite IODs, because they +contain information not just about the image itself, but also information about +the patient, the study, the series, the frame of reference and the equipment. + +The term *Information Entity* (IE) refers to a part of a composite IOD that +relates to a single DICOM Real World object. PS 3.3: + + 3.8.6 Information entity: that portion of information defined by a Composite + IOD which is related to one specific class of Real-World Object. There is a + one-to-one correspondence between Information Entities and entities in the + DICOM Application Model. + +IEs are names of DICOM Real World objects that label parts of a composite IOD. +IEs have no intrinsic content, but serve as meaningful labels for a group of +*modules* (see below) that refer to the same Real World object. + +Annex A 1.2, PS 3.3 lists all the IEs used in composite IODs. + +For example, section A.4 in PD 3.3 defines the composite IOD for an MR Image - +the Magnetic Resonance Image Object Definition. The definition looks like this +(table A.4-1 of PS 3.3) + ++--------------------+-------------------------+-----------+---------------------------------------------------------+ +| IE | Module | Reference | Usage | ++====================+=========================+===========+=========================================================+ +| Patient | Patient | C.7.1.1 | M | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Clinical Trial Subject | C.7.1.3 | U | ++--------------------+-------------------------+-----------+---------------------------------------------------------+ +| Study | General Study | C.7.2.1 | M | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Patient Study | C.7.2.2 | U | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Clinical Trial Study | C.7.2.3 | U | ++--------------------+-------------------------+-----------+---------------------------------------------------------+ +| Series | General Series | C.7.3.1 | M | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Clinical Trial Series | C.7.3.2 | U | ++--------------------+-------------------------+-----------+---------------------------------------------------------+ +| Frame of Reference | Frame of Reference | C.7.4.1 | M | ++--------------------+-------------------------+-----------+---------------------------------------------------------+ +| Equipment | General Equipment | C.7.5.1 | M | ++--------------------+-------------------------+-----------+---------------------------------------------------------+ +| Image | General Image | C.7.6.1 | M | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Image Plane | C.7.6.2 | M | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Image Pixel | C.7.6.3 | M | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Contrast/bolus | C.7.6.4 | C - Required if contrast media was used in this image | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Device | C.7.6.12 | U | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Specimen | C.7.6.22 | U | +| +-------------------------+-----------+---------------------------------------------------------+ +| | MR Image | C.8.3.1 | M | +| +-------------------------+-----------+---------------------------------------------------------+ +| | Overlay Plane | C.9.2 | U | +| +-------------------------+-----------+---------------------------------------------------------+ +| | VOI LUT | C.11.2 | U | +| +-------------------------+-----------+---------------------------------------------------------+ +| | SOP Common | C.12.1 | M | ++--------------------+-------------------------+-----------+---------------------------------------------------------+ + +As you can see, the MR Image IOD is composite and composed of Patient, Study, +Series, Frame of Reference, Equipment and Image IEs. + +The *module* heading defines which modules make up the information relevant to +the IE. + +A module is a named and defined grouping of attributes (data elements) with +related meaning. PS 3.3: + + 3.8.8 Module: A set of Attributes within an Information Entity or Normalized + IOD which are logically related to each other. + +Grouping attributes into modules simplifies the definition of multiple composite +IODs. For example, the composite IODs for a CT image and an MR Image both have +modules for Patient, Clinical Trial Subject, etc. + +Annex C of PS 3.3 defines all the modules used for the IOD definitions. For +example, from the table above, we see that the "Patient" module is at section +C.7.1.1 of PS 3.3. This section gives a table of all the attributes (data +elements) in this module. + +The last column in the table above records whether the particular module is +Mandatory, Conditional or User Option (defined in section A 1.3 of PS 3.3) + +Lastly module definitions may make use of *Attribute macros*. Attribute macros +are very much like modules, in that they are a named group of attributes that +often occur together in module definitions, or definitions of other macros. +From PS 3.3: + + 3.11.1 Attribute Macro: a set of Attributes that are described in a single + table that is referenced by multiple Modules or other tables. + +For example, here is the Patient Orientation Macro definition table from section +10.12 in PS 3.3: + ++------------------------------------------------+-------------------------+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Attribute Name | Tag | Type | Attribute Description | ++================================================+=========================+========+==================================================================================================================================================================================================+ +| Patient Orientation Code Sequence | (0054,0410) | 1 | Sequence that describes the orientation of the patient with respect to gravity. See C.8.11.5.1.2 for further explanation. Only a single Item shall be included in this Sequence. | ++------------------------------------------------+-------------------------+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| >Include 'Code Sequence Macro' Table 8.8-1. | Baseline Context ID 19 | ++------------------------------------------------+-------------------------+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| >Patient Orientation Modifier Code Sequence | (0054,0412) | 1C | Patient orientation modifier. Required if needed to fully specify the orientation of the patient with respect to gravity. Only a single Item shall be included in this Sequence. | ++------------------------------------------------+-------------------------+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| >>Include 'Code Sequence Macro' Table 8.8-1. | Baseline Context ID 20 | ++------------------------------------------------+-------------------------+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Patient Gantry Relationship Code Sequence | (0054,0414) | 3 | Sequence that describes the orientation of the patient with respect to the head of the table. See Section C.8.4.6.1.3 for further explanation. Only a single Item is permitted in this Sequence. | ++------------------------------------------------+-------------------------+--------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| >Include 'Code Sequence Macro' Table 8.8-1. | Baseline Context ID 21 | ++-----------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +As you can see, this macro specifies some tags that should appear when this +macro is "Included" - and also includes other macros. + +DICOM services (DIMSE) +====================== + +We now go back to messages. + +The DICOM application sending the message is called the Service Class User +(SCU). We might also call this the client. + +The DICOM application receiving the message is called the Service Class Provider +(SCP). We might also call this the server - for this particular message. + +Quoting from `PS 3.7`_ section 6.3: + + A Message is composed of a Command Set followed by a conditional Data Set + (see PS 3.5 for the definition of a Data Set). The Command Set is used to + indicate the operations/notifications to be performed on or with the Data + Set. + +The command set consists of command elements (elements with group number 0000). + +Valid sequences of command elements in the command set form valid DICOM Message +Service Elements (DIMSEs). Sections 9 and 10 of PS 3.7 define the valid DIMSEs. + +For example, there is a DIMSE service called "C-ECHO" that requests confirmation +from the responding application that the echo message arrived. + +The definition of the DIMSE services specifies, for a particular DIMSE service, +whether the DIMSE command set should be followed by a data set. + +In particular, the data set will be a full Information Object Definition's worth +of data. + +Of most interest to us, the "C-STORE" service command set should always be +followed by a data set conforming to an image data IOD. + +DICOM service object pairs (SOPs) +================================= + +As we've seen, some DIMSE services should be followed by particular types of +data. + +For example, the "C-STORE" DIMSE command set should be followed by an IOD of +data to store, but the "C-ECHO" has no data object following. + +The association of a particular type of DIMSE (command set) with the associated +IOD's-worth of data is a Service Object Pair. The DIMSE is the "Service" and the +data IOD is the "Object". Thus the combination of a "C-STORE" DIMSE and an "MR +Image" IOD would be a SOP. Services that do not have data following are a +particular type of SOP where the Object is null. For example, the "C-ECHO" +service is the entire contents of a Verification SOP (PS 3.4, section A.4). + +DICOM defines which pairings are possible, by listing them all as Service Object +Pair classes (SOP classes). + +Usually a SOP class describes the pairing of exactly one DIMSE service with one +defined IOD. For example, the "MR Image storage" SOP class pairs the "C-STORE" +DIMSE with the "MR Image" IOD. + +Sometimes a SOP class describes the pairings of one of several possible DIMSEs +with a particular IOP. For example, the "Modality Performed Procedure Step" SOP +class describes the pairing of *either* ("N-CREATE", Modality Performed +Procedure Step IOD) *or* ("N-SET", Modality Performed Procedure Step IOD) (see +PS 3.4 F.7.1). For this reason a SOP class is best described as the pairing of +a *DIMSE service group* with an IOD, where the DIMSE service group usually +contains just one DIMSE service, but sometimes has more. For example, the "MR +Image Storage" SOP class has a DIMSE service group of one element ["C-STORE"]. +The "Modality Performed Procedure Step" SOP class has a DIMSE service group with +two elements: ["N-CREATE", "N-SET"]. + +From PS 3.4: + + 6.4 DIMSE SERVICE GROUP + + DIMSE Service Group specifies one or more operations/notifications defined + in PS 3.7 which are applicable to an IOD. + + DIMSE Service Groups are defined in this Part of the DICOM Standard, in the + specification of a Service - Object Pair Class. + + 6.5 SERVICE-OBJECT PAIR (SOP) CLASS + + A Service-Object Pair (SOP) Class is defined by the union of an IOD and a + DIMSE Service Group. The SOP Class definition contains the rules and + semantics which may restrict the use of the services in the DIMSE Service + Group and/or the Attributes of the IOD. + +The Annexes of `PS 3.4`_ define the SOP classes. + +A pairing of actual data of form (DIMSE group, IOD) that conforms to the SOP +class definition, is a SOP class instance. That is, the instance comprises the +actual values of the service and data elements being transmitted. + +For example, there is a SOP class called "MR Image Storage". This is the +association of the "C-STORE" DIMSE command with the "MR Image" IOD. A +particular "C-STORE" request command set along with the particular "MR Image" +IOD data set would be an *instance* of the MR Image SOP class. + +DICOM files +=========== + +Now let us return to the confusing definition of the DICOM file format from +section 7 of PS 3.10: + + 7 DICOM File Format + + The DICOM File Format provides a means to encapsulate in a file the Data Set + representing a SOP Instance related to a DICOM IOD. As shown in Figure 7-1, + the byte stream of the Data Set is placed into the file after the DICOM File + Meta Information. Each file contains a single SOP Instance. + +The DICOM file Meta Information is: + +* File preamble - 128 bytes, content unspecified +* DICOM prefix - 4 bytes "DICM" character string +* 5 meta information elements (group 0002) as defined in table 7.1 of PS 3.10 + +There follows the IOD dataset part of the SOP instance. In the case of a file +storing an MR Image, this dataset will be of IOD type "MR Image" + +.. rubric:: Footnotes + +.. [#can_be_two] Actually, it is not quite true that there can be only one VR + associated with a particular tag. A small number of tags have VRs which can + be either Unsigned Short (US) or Signed Short (SS). An even smaller number + of tags can be either Other Byte (OB) or Other Word (OW). For all the + relevant tags the VM is a set number (1, 3, or 4). So, in the OB / OW cases + you can tell which of OB or OW you have by the Value Length. The US / SS + cases seem to refer to pixel values; presumably they are US if the Pixel + Representation (tag 0028, 0103) is 0 (for unsigned) and SS if the Pixel + Representation is 1 (for signed) + +.. include:: ../links_names.txt diff --git a/_sources/dicom/dicom_mosaic.rst.txt b/_sources/dicom/dicom_mosaic.rst.txt new file mode 100644 index 0000000000..789247f3ff --- /dev/null +++ b/_sources/dicom/dicom_mosaic.rst.txt @@ -0,0 +1,138 @@ +.. _dicom-mosaic: + +======================= + Siemens mosaic format +======================= + +Siemens mosaic format is a way of storing a 3D image in a DICOM_ image +file. The simplest DICOM_ images only knows how to store 2D files. For +example, a 3D image in DICOM is usually stored as a series of 2D slices, +each slices as a separate DICOM image. . Mosaic format stores the 3D +image slices as a 2D grid - or mosaic. + +For example here are the pixel data as loaded directly from a DICOM image +with something like:: + + import matplotlib.pylab as plt + import dicom + dcm_data = dicom.read_file('my_file.dcm') + plt.imshow(dcm_data.pixel_array) + +.. image:: mosaic_grid.png + +Getting the slices from the mosaic +================================== + +The apparent image in the DICOM file is a 2D array that consists of blocks, +that are the output 2D slices. Let's call the original array the *slab*, and +the contained slices *slices*. The slices are of pixel dimension +``n_slice_rows`` x ``n_slice_cols``. The slab is of pixel dimension +``n_slab_rows`` x ``n_slab_cols``. Because the arrangement of blocks in the +slab is defined as being square, the number of blocks per slab row and slab +column is the same. Let ``n_blocks`` be the number of blocks contained in the +slab. There is also ``n_slices`` - the number of slices actually collected, +some number <= ``n_blocks``. We have the value ``n_slices`` from the +'NumberOfImagesInMosaic' field of the Siemens private (CSA) header. +``n_row_blocks`` and ``n_col_blocks`` are therefore given by +``ceil(sqrt(n_slices))``, and ``n_blocks`` is ``n_row_blocks ** 2``. Also +``n_slice_rows == n_slab_rows / n_row_blocks``, etc. Using these numbers we +can therefore reconstruct the slices from the 2D DICOM pixel array. + +DICOM orientation for mosaic +============================ + +See :ref:`dicom-pcs` and :ref:`dicom-orientation`. We want a 4 x 4 +affine $A$ that will take us from (transposed) voxel coordinates in the +DICOM image to mm in the :ref:`dicom-pcs`. See :ref:`ij-transpose` for +what we mean by transposed voxel coordinates. + +We can think of the affine $A$ as the (3,3) component, $RS$, and a (3,1) +translation vector $\mathbf{t}$. $RS$ can in turn be thought of as the +dot product of a (3,3) rotation matrix $R$ and a scaling matrix $S$, +where ``S = diag(s)`` and $\mathbf{s}$ is a (3,) vector of voxel sizes. +$\mathbf{t}$ is a (3,1) translation vector, defining the coordinate in +millimeters of the first voxel in the voxel volume (the voxel given by +``voxel_array[0,0,0]``). + +In the case of the mosaic, we have the first two columns of $R$ from the +$F$ - the left/right flipped version of the ``ImageOrientationPatient`` +DICOM field described in :ref:`dicom-affines-reloaded`. To make a full +rotation matrix, we can generate the last column from the cross product +of the first two. However, Siemens defines, in its private +:ref:`csa-header`, a ``SliceNormalVector`` which gives the third column, +but possibly with a z flip, so that $R$ is orthogonal, but not a +rotation matrix (it has a determinant of < 0). + +The first two values of $\mathbf{s}$ ($s_1, s_2$) are given by the +``PixelSpacing`` field. We get $s_3$ (the slice scaling +value) from ``SpacingBetweenSlices``. + +The :ref:`spm-dicom` code has a comment saying that mosaic DICOM images +have an incorrect ``ImagePositionPatient`` field. The +``ImagePositionPatient`` field usually gives the $\mathbf{t}$ vector. +The comments imply that Siemens has derived ``ImagePositionPatient`` +from the (correct) position of the center of the first slice (once the +mosaic has been unpacked), but has then adjusted the vector to point to +the top left voxel, where the slice size used for this adjustment is the +size of the mosaic, before it has been unpacked. Let's call the correct +position in millimeters of the center of the first slice $\mathbf{c} = +[c_x, c_y, c_z]$. We have the derived $RS$ matrix from the calculations +above. The unpacked (eventual, real) slice dimensions are $(rd_{rows}, +rd_{cols})$ and the mosaic dimensions are $(md_{rows}, md_{cols})$. The +``ImagePositionPatient`` vector $\mathbf{i}$ resulted from: + +.. math:: + + \mathbf{i} = \mathbf{c} + RS + \begin{bmatrix} -(md_{rows}-1) / 2\\ + -(md_{cols}-1) / 2\\ + 0 \end{bmatrix} + +To correct the faulty translation, we reverse it, and add the correct +translation for the unpacked slice size $(rd_{rows}, rd_{cols})$, giving +the true image position $\mathbf{t}$: + +.. math:: + + \mathbf{t} = \mathbf{i} - + (RS \begin{bmatrix} -(md_{rows}-1) / 2\\ + -(md_{cols}-1) / 2\\ + 0 \end{bmatrix}) + + (RS \begin{bmatrix} -(rd_{rows}-1) / 2\\ + -(rd_{cols}-1) / 2\\ + 0 \end{bmatrix}) + +Because of the final zero in the voxel translations, this simplifies to: + +.. math:: + + \mathbf{t} = \mathbf{i} + + Q \begin{bmatrix} (md_{rows} - rd_{rowss}) / 2 \\ + (md_{cols} - rd_{cols}) / 2 \end{bmatrix} + +where: + +.. math:: + + Q = \begin{bmatrix} rs_{11} & rs_{12} \\ + rs_{21} & rs_{22} \\ + rs_{31} & rs_{32} \end{bmatrix} + +Data scaling +============ + +SPM gets the DICOM scaling, offset for the image ('RescaleSlope', +'RescaleIntercept'). It writes these scalings into the nifti_ header. +Then it writes the raw image data (unscaled) to disk. Obviously these +will have the current scalings applied when the nifti image is read again. + +A comment in the code here says that the data are not scaled by the +maximum amount. I assume by this they mean that the DICOM scaling may +not be the maximum scaling, whereas the standard SPM image write is, +hence the difference, because they are using the DICOM scaling rather +then their own. The comment continues by saying that the scaling as +applied (the DICOM - not maximum - scaling) can lead to rounding errors +but that it will get around some unspecified problems. + + +.. include:: ../links_names.txt diff --git a/_sources/dicom/dicom_niftiheader.rst.txt b/_sources/dicom/dicom_niftiheader.rst.txt new file mode 100644 index 0000000000..a16ead7f20 --- /dev/null +++ b/_sources/dicom/dicom_niftiheader.rst.txt @@ -0,0 +1,73 @@ +.. _dicom-niftiheader: + +############################## +DICOM Tags in the NIfTI Header +############################## + +NIfTI images include an extended header (see the `NIfTI Extensions Standard`_) +to store, amongst others, DICOM tags and attributes. When NiBabel loads a NIfTI +file containing DICOM information (a NIfTI extension with ``ecode == 2``), it +parses it and returns a pydicom dataset as the content of the NIfTI extension. +This can be read and written to in order to facilitate communication with +software that uses specific DICOM codes found in the NIfTI header. + +For example, the commercial PMOD software stores the Frame Start and Duration +times of images using the DICOM tags (0055, 1001) and (0055, 1004). Here's an +example of an image created in PMOD with those stored times accessed through +nibabel. + +.. code:: python + + >> import nibabel as nib + >> nim = nib.load('pmod_pet.nii') + >> dcmext = nim.header.extensions[0] + >> dcmext + Nifti1Extension('dicom', '(0054, 1001) Units CS: 'Bq/ml' + (0055, 0010) Private Creator LO: 'PMOD_1' + (0055, 1001) [Frame Start Times Vector] FD: [0.0, 30.0, 60.0, ..., 13720.0, 14320.0] + (0055, 1004) [Frame Durations (ms) Vector] FD: [30000.0, 30000.0, 30000.0,600000.0, 600000.0]')) + ++-------------+--------------------------------+---------------------------------------------------------+ +| Tag | Name | Value | ++=============+================================+=========================================================+ +| (0054, 1001)| Units | CS: 'Bq/ml' | ++-------------+--------------------------------+---------------------------------------------------------+ +|(0055, 0010) | Private Creator | LO: 'PMOD_1' | ++-------------+--------------------------------+---------------------------------------------------------+ +|(0055, 1001) | [Frame Start Times Vector] | FD: [0.0, 30.0, 60.0, ..., 13720.0, 14320.0 | ++-------------+--------------------------------+---------------------------------------------------------+ +|(0055, 1004) | [Frame Durations (ms) Vector] | FD: [30000.0, 30000.0, 30000.0, ..., 600000.0, 600000.0 | ++-------------+--------------------------------+---------------------------------------------------------+ + +Access each value as you would with pydicom:: + + >> ds = dcmext.get_content() + >> start_times = ds[0x0055, 0x1001].value + >> durations = ds[0x0055, 0x1004].value + +Creating a PMOD-compatible header is just as easy:: + + >> nim = nib.load('pet.nii') + >> nim.header.extensions + [] + >> from dicom.dataset import Dataset + >> ds = Dataset() + >> ds.add_new((0x0054,0x1001),'CS','Bq/ml') + >> ds.add_new((0x0055,0x0010),'LO','PMOD_1') + >> ds.add_new((0x0055,0x1001),'FD',[0.,30.,60.,13720.,14320.]) + >> ds.add_new((0x0055,0x1004),'FD',[30000.,30000.,30000.,600000.,600000.]) + >> dcmext = nib.nifti1.Nifti1DicomExtension(2,ds) # Use DICOM ecode 2 + >> nim.header.extensions.append(dcmext) + >> nib.save(nim,'pet_withdcm.nii') + +Be careful! Many imaging tools don't maintain information in the extended +header, so it's possible [likely] that this information may be lost during +routine use. You'll have to keep track, and re-write the information if +required. + +Optional Dependency Note: If pydicom is not installed, nibabel uses a generic +:class:`nibabel.nifti1.Nifti1Extension` header instead of parsing DICOM data. + +.. _`NIfTI Extensions Standard`: http://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/extension.html + +.. include:: ../links_names.txt diff --git a/_sources/dicom/dicom_orientation.rst.txt b/_sources/dicom/dicom_orientation.rst.txt new file mode 100644 index 0000000000..275b16ce78 --- /dev/null +++ b/_sources/dicom/dicom_orientation.rst.txt @@ -0,0 +1,412 @@ +================================ + Defining the DICOM orientation +================================ + +.. _dicom-pcs: + +DICOM patient coordinate system +=============================== + +First we define the standard DICOM patient-based coordinate system. +This is what DICOM means by x, y and z axes in its orientation +specification. From section C.7.6.2.1.1 of the `DICOM object +definitions`_ (2009): + + If Anatomical Orientation Type (0010,2210) is absent or has a value + of BIPED, the x-axis is increasing to the left hand side of the + patient. The y-axis is increasing to the posterior side of the + patient. The z-axis is increasing toward the head of the patient. + +(we'll ignore the quadupeds for now). + +In a way it's funny to call this the 'patient-based' coordinate system. +'Doctor-based coordinate system' is a better name. Think of a doctor +looking at the patient from the foot of the scanner bed. Imagine the +doctor's right hand held in front of her like Spiderman about to shoot a +web, with her palm towards the patient, defining a right-handed +coordinate system. Her thumb points to her right (the patient's left), +her index finger points down, and the middle finger points at the +patient. + +.. _dicom-pixel-array: + +DICOM pixel data +================ + +C.7.6.3.1.4 - Pixel Data + Pixel Data (7FE0,0010) for this image. The order of pixels sent for + each image plane is left to right, top to bottom, i.e., the upper + left pixel (labeled 1,1) is sent first followed by the remainder of + row 1, followed by the first pixel of row 2 (labeled 2,1) then the + remainder of row 2 and so on. + +The resulting pixel array then has size ('Rows', 'Columns'), with +row-major storage (rows first, then columns). We'll call this the DICOM +*pixel array*. + +Pixel spacing +============= + +Section 10.7.1.3: Pixel Spacing + The first value is the row spacing in mm, that is the spacing between + the centers of adjacent rows, or vertical spacing. The second value + is the column spacing in mm, that is the spacing between the centers + of adjacent columns, or horizontal spacing. + +.. _dicom-orientation: + +DICOM voxel to patient coordinate system mapping +================================================ + +See: + +* http://www.dclunie.com/medical-image-faq/html/part2.html; +* `this dicom mailing list post <https://groups.google.com/forum/#!topic/comp.protocols.dicom/-Nms_GgmdRc>`_; + +See `wikipedia direction cosine`_ for a definition of direction cosines. + +From section C.7.6.2.1.1 of the `DICOM object definitions`_ (2009): + + The Image Position (0020,0032) specifies the x, y, and z coordinates + of the upper left hand corner of the image; it is the center of the + first voxel transmitted. Image Orientation (0020,0037) specifies the + direction cosines of the first row and the first column with respect + to the patient. These Attributes shall be provide as a pair. Row + value for the x, y, and z axes respectively followed by the Column + value for the x, y, and z axes respectively. + +From Section C.7.6.1.1.1 we see that the 'positive row axis' is left to +right, and is the direction of the rows, given by the direction of last +pixel in the first row from the first pixel in that row. Similarly the +'positive column axis' is top to bottom and is the direction of the +columns, given by the direction of the last pixel in the first column +from the first pixel in that column. + +Let's rephrase: the first three values of 'Image Orientation Patient' +are the direction cosine for the 'positive row axis'. That is, they +express the direction change in (x, y, z), in the DICOM patient +coordinate system (DPCS), as you move along the row. That is, as you +move from one column to the next. That is, as the *column* array index +changes. Similarly, the second triplet of values of 'Image Orientation +Patient' (``img_ornt_pat[3:]`` in Python), are the direction cosine for +the 'positive column axis', and express the direction you move, in the +DPCS, as you move from row to row, and therefore as the *row* index +changes. + +Further down section C.7.6.2.1.1 (RCS below is the *reference coordinate +system* - see `DICOM object definitions`_ section 3.17.1): + + The Image Plane Attributes, in conjunction with the Pixel Spacing + Attribute, describe the position and orientation of the image slices + relative to the patient-based coordinate system. In each image frame + the Image Position (Patient) (0020,0032) specifies the origin of the + image with respect to the patient-based coordinate system. RCS and + the Image Orientation (Patient) (0020,0037) attribute values specify + the orientation of the image frame rows and columns. The mapping of + pixel location (i, j) to the RCS is calculated as follows: + + .. math:: + + \begin{bmatrix} P_x\\ + P_y\\ + P_z\\ + 1 \end{bmatrix} = + \begin{bmatrix} X_x\Delta{i} & Y_x\Delta{j} & 0 & S_x \\ + X_y\Delta{i} & Y_y\Delta{j} & 0 & S_y \\ + X_z\Delta{i} & Y_z\Delta{j} & 0 & S_z \\ + 0 & 0 & 0 & 1 \end{bmatrix} + \begin{bmatrix} i\\ + j\\ + 0\\ + 1 \end{bmatrix} + = M + \begin{bmatrix} i\\ + j\\ + 0\\ + 1 \end{bmatrix} + + Where: + + #. $P_{xyz}$ : The coordinates of the voxel (i,j) in the frame's + image plane in units of mm. + #. $S_{xyz}$ : The three values of the Image Position (Patient) + (0020,0032) attributes. It is the location in mm from the origin + of the RCS. + #. $X_{xyz}$ : The values from the row (X) direction cosine of the + Image Orientation (Patient) (0020,0037) attribute. + #. $Y_{xyz}$ : The values from the column (Y) direction cosine of the + Image Orientation (Patient) (0020,0037) attribute. + #. $i$ : Column index to the image plane. The first column is index + zero. + #. $\Delta{i}$: Column pixel resolution of the Pixel Spacing + (0028,0030) attribute in units of mm. + #. $j$ : Row index to the image plane. The first row index is zero. + #. $\Delta{j}$ - Row pixel resolution of the Pixel Spacing + (0028,0030) attribute in units of mm. + +.. _ij-transpose: + +(i, j), columns, rows in DICOM +============================== + +We stop to ask ourselves, what does DICOM mean by voxel (i, j)? + +Isn't that obvious? Oh dear, no it isn't. See the +:ref:`dicom-orientation` formula above. In particular, you'll see: + +* $i$ : Column index to the image plane. The first column is index zero. +* $j$ : Row index to the image plane. The first row index is zero. + +That is, if we have the :ref:`dicom-pixel-array` as defined above, and +we call that ``pixel_array``, then voxel (i, j) in the notation above is +given by ``pixel_array[j, i]``. + +What does this mean? It means that, if we want to apply the formula +above to array indices in ``pixel_array``, we first have to apply a +column / row flip to the indices. Say $M_{pixar}$ (sorry) is the affine +to go from array indices in ``pixel_array`` to mm in the DPCS. Then, +given $M$ above: + +.. math:: + + M_{pixar} = M \left(\begin{smallmatrix}0 & 1 & 0 & 0\\1 & 0 & 0 & 0\\0 & 0 & 1 & 0\\0 & 0 & 0 & 1\end{smallmatrix}\right) + +.. _dicom-affines-reloaded: + +DICOM affines again +=================== + +The :ref:`ij-transpose` is rather confusing, so we're going to rephrase +the affine mapping; we'll use $r$ for the row index (instead of $j$ +above), and $c$ for the column index (instead of $i$). + +Next we define a flipped version of 'ImageOrientationPatient', $F$, that +has flipped columns. Thus if the vector of 6 values in +'ImageOrientationPatient' are $(i_1 .. i_6)$, then: + +.. math:: + + F = \begin{bmatrix} i_4 & i_1 \\ + i_5 & i_2 \\ + i_6 & i_3 \end{bmatrix} + +Now the first column of F contains what the DICOM docs call the 'column +(Y) direction cosine', and second column contains the 'row (X) direction +cosine'. We prefer to think of these as (respectively) the row index +direction cosine and the column index direction cosine. + +Now we can rephrase the DICOM affine mapping with: + +.. _dicom-slice-affine: + +DICOM affine formula +==================== + +.. math:: + + \begin{bmatrix} P_x\\ + P_y\\ + P_z\\ + 1 \end{bmatrix} = + \begin{bmatrix} F_{11}\Delta{r} & F_{12}\Delta{c} & 0 & S_x \\ + F_{21}\Delta{r} & F_{22}\Delta{c} & 0 & S_y \\ + F_{31}\Delta{r} & F_{32}\Delta{c} & 0 & S_z \\ + 0 & 0 & 0 & 1 \end{bmatrix} + \begin{bmatrix} r\\ + c\\ + 0\\ + 1 \end{bmatrix} + = A + \begin{bmatrix} r\\ + c\\ + 0\\ + 1 \end{bmatrix} + +Where: + +* $P_{xyz}$ : The coordinates of the voxel (c, r) in the frame's image + plane in units of mm. +* $S_{xyz}$ : The three values of the Image Position (Patient) + (0020,0032) attributes. It is the location in mm from the origin of + the RCS. +* $F_{:,1}$ : The values from the column (Y) direction cosine of the + Image Orientation (Patient) (0020,0037) attribute - see above. +* $F_{:,2}$ : The values from the row (X) direction cosine of the Image + Orientation (Patient) (0020,0037) attribute - see above. +* $r$ : Row index to the image plane. The first row index is zero. +* $\Delta{r}$ - Row pixel resolution of the Pixel Spacing (0028,0030) + attribute in units of mm. +* $c$ : Column index to the image plane. The first column is index zero. +* $\Delta{c}$: Column pixel resolution of the Pixel Spacing (0028,0030) + attribute in units of mm. + +For later convenience we also define values useful for 3D volumes: + +* $s$ : Slice index to the slice plane. The first slice index is zero. +* $\Delta{s}$ - Spacing in mm between slices. + +.. _dicom-3d-affines: + +Getting a 3D affine from a DICOM slice or list of slices +======================================================== + +Let us say, we have a single DICOM file, or a list of DICOM files that +we believe to be a set of slices from the same volume. We'll call the +first the *single slice* case, and the second, *multi slice*. + +In the *multi slice* case, we can assume that the +'ImageOrientationPatient' field is the same for all the slices. + +We want to get the affine transformation matrix $A$ that maps from voxel +coordinates in the DICOM file(s), to mm in the :ref:`dicom-pcs`. + +By voxel coordinates, we mean coordinates of form $(r, c, s)$ - the row, +column and slice indices - as for the :ref:`dicom-slice-affine`. + +In the single slice case, the voxel coordinates are just the indices +into the pixel array, with the third (slice) coordinate always being 0. + +In the multi-slice case, we have arranged the slices in ascending or +descending order, where slice numbers range from 0 to $N-1$ - where $N$ +is the number of slices - and the slice coordinate is a number on this +scale. + +We know, from :ref:`dicom-slice-affine`, that the first, second and +fourth columns in $A$ are given directly by the (flipped) +'ImageOrientationPatient', 'PixelSpacing' and 'ImagePositionPatient' +field of the first (or only) slice. + +Our job then is to fill the first three rows of the third column of $A$. +Let's call this the vector $\mathbf{k}$ with values $k_1, k_2, k_3$. + +.. _dicom-affine-defs: + +DICOM affine Definitions +------------------------ + +See also the definitions in :ref:`dicom-slice-affine`. In addition + +* $T^1$ is the 3 element vector of the 'ImagePositionPatient' field of + the first header in the list of headers for this volume. +* $T^N$ is the 'ImagePositionPatient' vector for the last header in the + list for this volume, if there is more than one header in the volume. +* vector $\mathbf{n} = (n_1, n_2, n_3)$ is the result of taking the + cross product of the two columns of $F$ from + :ref:`dicom-slice-affine`. + +Derivations +----------- + +For the single slice case we just fill $\mathbf{k}$ with $\mathbf{n} \cdot +\Delta{s}$ - on the basis that the Z dimension should be +right-handed orthogonal to the X and Y directions. + +For the multi-slice case, we can fill in $\mathbf{k}$ by using the information +from $T^N$, because $T^N$ is the translation needed to take the +first voxel in the last (slice index = $N-1$) slice to mm space. So: + +.. math:: + + \left(\begin{smallmatrix}T^N\\1\end{smallmatrix}\right) = A \left(\begin{smallmatrix}0\\0\\N - 1\\1\end{smallmatrix}\right) + +From this it follows that: + +.. math:: + + \begin{Bmatrix}k_{{1}} : \frac{T^{N}_{{1}} - T^{1}_{{1}}}{N - 1}, & k_{{2}} : \frac{T^{N}_{{2}} - T^{1}_{{2}}}{N - 1}, & k_{{3}} : \frac{T^{N}_{{3}} - T^{1}_{{3}}}{N - 1}\end{Bmatrix} + +and therefore: + +.. _dicom-3d-affine-formulae: + +3D affine formulae +------------------ + +.. math:: + + A_{multi} = \left(\begin{smallmatrix}F_{{11}} \Delta{r} & F_{{12}} \Delta{c} & \frac{T^{N}_{{1}} - T^{1}_{{1}}}{N - 1} & T^{1}_{{1}}\\F_{{21}} \Delta{r} & F_{{22}} \Delta{c} & \frac{T^{N}_{{2}} - T^{1}_{{2}}}{N - 1} & T^{1}_{{2}}\\F_{{31}} \Delta{r} & F_{{32}} \Delta{c} & \frac{T^{N}_{{3}} - T^{1}_{{3}}}{N - 1} & T^{1}_{{3}}\\0 & 0 & 0 & 1\end{smallmatrix}\right) + + A_{single} = \left(\begin{smallmatrix}F_{{11}} \Delta{r} & F_{{12}} \Delta{c} & \Delta{s} n_{{1}} & T^{1}_{{1}}\\F_{{21}} \Delta{r} & F_{{22}} \Delta{c} & \Delta{s} n_{{2}} & T^{1}_{{2}}\\F_{{31}} \Delta{r} & F_{{32}} \Delta{c} & \Delta{s} n_{{3}} & T^{1}_{{3}}\\0 & 0 & 0 & 1\end{smallmatrix}\right) + +See :download:`derivations/spm_dicom_orient.py` for the derivations and +some explanations. + +For a single slice $N=1$ the affine matrix is $A_{single}$. In this +case, the slice spacing $\Delta{s}$ may be obtained by the Spacing +Between Slices (0018,0088) attribute in units of mm, if it exists. + +.. _dicom-z-from-slice: + +Working out the Z coordinates for a set of slices +================================================= + +We may have the problem (see e.g. :ref:`spm-volume-sorting`) of trying +to sort a set of slices into anatomical order. For this we want to use +the orientation information to tell us where the slices are in space, +and therefore, what order they should have. + +To do this sorting, we need something that is proportional, plus a +constant, to the voxel coordinate for the slice (the value for the slice +index). + +Our DICOM might have the 'SliceLocation' field (0020,1041). +'SliceLocation' seems to be proportional to slice location, at least for +some GE and Philips DICOMs I was looking at. But, there is a more +reliable way (that doesn't depend on this field), and uses only the very +standard 'ImageOrientationPatient' and 'ImagePositionPatient' fields. + +Consider the case where we have a set of slices, of unknown order, from +the same volume. + +Now let us say we have one of these slices - slice $i$. We have the +affine for this slice from the calculations above, for a single slice +($A_{single}$). + +Now let's say we have another slice $j$ from the same volume. It will +have the same affine, except that the 'ImagePositionPatient' field will +change to reflect the different position of this slice in space. Let us +say that there a translation of $d$ slices between $i$ and $j$. If +$A_i$ ($A$ for slice $i$) is $A_{single}$ then $A_j$ for $j$ is given +by: + +.. math:: + + A_j = A_{single} \left(\begin{smallmatrix}1 & 0 & 0 & 0\\0 & 1 & 0 & 0\\0 & 0 & 1 & d\\0 & 0 & 0 & 1\end{smallmatrix}\right) + +and 'ImagePositionPatient' for $j$ is: + +.. math:: + + T^j = \left(\begin{smallmatrix}T^{1}_{{1}} + \Delta{s} d n_{{1}}\\T^{1}_{{2}} + \Delta{s} d n_{{2}}\\T^{1}_{{3}} + \Delta{s} d n_{{3}}\end{smallmatrix}\right) + +Remember that the third column of $A$ gives the vector resulting from a +unit change in the slice voxel coordinate. So, the +'ImagePositionPatient' of slice - say slice $j$ - can be thought of the +addition of two vectors $T^j = \mathbf{a} + \mathbf{b}$, where +$\mathbf{a}$ is the position of the first voxel in some slice (here +slice 1, therefore $\mathbf{a} = T^1$) and $\mathbf{b}$ is $d$ times the +third column of $A$. Obviously $d$ can be negative or positive. This +leads to various ways of recovering something that is proportional to +$d$ plus a constant. The algorithm suggested in this `ITK post on +ordering slices`_ - and the one used by SPM - is to take the inner +product of $T^j$ with the unit vector component of third column of +$A_j$ - in the descriptions here, this is the vector $\mathbf{n}$: + +.. _ITK post on ordering slices: http://www.itk.org/pipermail/insight-users/2003-September/004762.html + +.. math:: + + T^j \cdot \mathbf{c} = \left(\begin{smallmatrix}T^{1}_{{1}} n_{{1}} + T^{1}_{{2}} n_{{2}} + T^{1}_{{3}} n_{{3}} + \Delta{s} d n_{{1}}^{2} + \Delta{s} d n_{{2}}^{2} + \Delta{s} d n_{{3}}^{2}\end{smallmatrix}\right) + +This is the distance of 'ImagePositionPatient' along the slice direction +cosine. + +The unknown $T^1$ terms pool into a constant, and the operation has the +neat feature that, because the $n_{123}^2$ terms, by definition, sum to 1, +the whole can be expressed as $\lambda + \Delta{s} d$ - i.e. it is +equal to the slice voxel size ($\Delta{s}$) multiplied by $d$, +plus a constant. + +Again, see :download:`derivations/spm_dicom_orient.py` for the derivations. + +.. include:: ../links_names.txt diff --git a/_sources/dicom/siemens_csa.rst.txt b/_sources/dicom/siemens_csa.rst.txt new file mode 100644 index 0000000000..9beec6150a --- /dev/null +++ b/_sources/dicom/siemens_csa.rst.txt @@ -0,0 +1,135 @@ +.. _siemens_csa: + +====================================== + Siemens format DICOM with CSA header +====================================== + +Recent Siemens DICOM images have useful information stored in a private +header. We'll call this the *CSA header*. + +.. _csa-header: + +CSA header +========== + +See this Siemens `Syngo DICOM conformance`_ statement, and a GDCM_ +`Siemens header dump`_. + +.. _`Siemens header dump`: http://sourceforge.net/apps/mediawiki/gdcm/index.php?title=Gdcmdump#SIEMENS_CSA_Header +.. _`Syngo DICOM conformance`: http://www.medical.siemens.com/siemens/en_GLOBAL/rg_marcom_FBAs/files/brochures/DICOM/rs/syngoImaging_DCS_VB30A_External.pdf + +The CSA header is stored in DICOM private tags. In the images we are +looking at, there are several relevant tags:: + + (0029, 1008) [CSA Image Header Type] OB: 'IMAGE NUM 4 ' + (0029, 1009) [CSA Image Header Version] OB: '20100114' + (0029, 1010) [CSA Image Header Info] OB: Array of 11560 bytes + (0029, 1018) [CSA Series Header Type] OB: 'MR' + (0029, 1019) [CSA Series Header Version] OB: '20100114' + (0029, 1020) [CSA Series Header Info] OB: Array of 80248 bytes + +In our case we want to read the 'CSAImageHeaderInfo'. + +From the SPM_ (SPM8) code ``spm_dicom_headers.m`` + +The CSAImageHeaderInfo and the CSA Series Header Info fields are of the +same format. The fields can be of two types, CSA1 and CSA2. + +Both are always little-endian, whatever the machine endian is. + +The CSA2 format begins with the string 'SV10', the CSA1 format does +not. + +The code below keeps track of the position *within the CSA header +stream*. We'll call this ``csa_position``. At this point (after +reading the 8 bytes of the header), ``csa_position == 8``. There's a +variable that sets the last byte position in the file that is sensibly +still CSA header, and we'll call that ``csa_max_pos``. + +CSA1 +==== + +Start header +------------ + +#. n_tags, uint32, number of tags. Number of tags should apparently be + between 1 and 128. If this is not true we just abort and move to + ``csa_max_pos``. +#. unused, uint32, apparently has value 77 + +Each tag +-------- + +#. name : S64, null terminated string 64 bytes +#. vm : int32 +#. vr : S4, first 3 characters only +#. syngodt : int32 +#. nitems : int32 +#. xx : int32 - apparently either 77 or 205 + +``nitems`` gives the number of items in the tag. The items follow +directly after the tag. + +Each item +--------- + +1. xx : int32 * 4 . The first of these seems to be the length of the + item in bytes, modified as below. + +At this point SPM does a check, by calculating the length of this item +``item_len`` with ``xx[0]`` - the ``nitems`` of the *first* read tag. +If ``item_len`` is less than 0 or greater than +``csa_max_pos-csa_position`` (the remaining number of bytes to read in +the whole header) then we break from the item reading loop, +setting the value below to ''. + +Then we calculate ``item_len`` rounded up to the nearest 4 byte boundary +tp get ``next_item_pos``. + +2. value : uint8, ``item_len``. + +We set the stream position to ``next_item_pos``. + +CSA2 +==== + +Start header +------------ + +#. hdr_id : S4 == 'SV10' +#. unused1 : uint8, 4 +#. n_tags, uint32, number of tags. Number of tags should apparently be + between 1 and 128. If this is not true we just abort and move to + ``csa_max_pos``. +#. unused2, uint32, apparently has value 77 + +Each tag +-------- + +#. name : S64, null terminated string 64 bytes +#. vm : int32 +#. vr : S4, first 3 characters only +#. syngodt : int32 +#. nitems : int32 +#. xx : int32 - apparently either 77 or 205 + +``nitems`` gives the number of items in the tag. The items follow +directly after the tag. + +Each item +--------- + +1. xx : int32 * 4 . The first of these seems to be the length of the + item in bytes, modified as below. + +Now there's a different length check from CSA1. ``item_len`` is given +just by ``xx[1]``. If ``item_len`` > ``csa_max_pos - csa_position`` +(the remaining bytes in the header), then we just read the remaining +bytes in the header (as above) into ``value`` below, as uint8, move the +filepointer to the next 4 byte boundary, and give up reading. + +2. value : uint8, ``item_len``. + +We set the stream position to the next 4 byte boundary. + +.. include:: ../links_names.txt diff --git a/_sources/dicom/spm_dicom.rst.txt b/_sources/dicom/spm_dicom.rst.txt new file mode 100644 index 0000000000..5b0deb1672 --- /dev/null +++ b/_sources/dicom/spm_dicom.rst.txt @@ -0,0 +1,309 @@ +.. _spm-dicom: + +====================== + SPM DICOM conversion +====================== + +These are some notes on the algorithms that SPM_ uses to convert from +DICOM_ to nifti_. There are other notes in :ref:`dicom-mosaic`. + +The relevant SPM files are ``spm_dicom_headers.m``, +``spm_dicom_dict.mat`` and ``spm_dicom_convert.m``. These notes refer +the version in SPM8, as of around January 2010. + +``spm_dicom_dict.mat`` +====================== + +This is obviously a Matlab ``.mat`` file. It contains variables +``group`` and ``element``, and ``values``, where ``values`` is a struct +array, one element per (group, element) pair, with fields ``name`` and +``vr`` (the last a cell array). + + +``spm_dicom_headers.m`` +======================= + +Reads the given DICOM files into a struct. It looks like this was +written by John Ahsburner (JA). Relevant fixes are: + +File opening +------------ + +When opening the DICOM file, SPM (subfunction ``readdicomfile``) + +#. opens as little endian +#. reads 4 characters starting at pos 128 +#. checks if these are ``DICM``; if so then continues file read; + otherwise, tests to see if this is what SPM calls *truncated DICOM + file format* - lacking 128 byte lead in and ``DICM`` string: + + #. Seeks to beginning of file + #. Reads two unsigned short values into ``group`` and ``tag`` + #. If the (``group``, ``element``) pair exist in + ``spm_dicom_dict.mat``, then set file pointer to 0 and continue + read with ``read_dicom`` subfunction.. + #. If ``group`` == 8 and ``element`` == 0, this is apparently the + signature for a 'GE Twin+excite' for which JA notes there is no + documentation; set file pointer to 0 and continue read with + ``read_dicom`` subfunction. + #. Otherwise - crash out with error saying that this is not DICOM file. + +tag read for Philips Integra +---------------------------- + +The ``read_dicom`` subfunction reads a tag, then has a loop during which +the tag is processed (by setting values into the return structure). At +the end of the loop, it reads the next tag. The loop breaks when the +current tag is empty, or is the item delimitation tag (group=FFFE, +element=E00D). + +After it has broken out of the loop, if the last tag was (FFFE, E00D) +(item delimitation tag), and the tag length was not 0, then SPM sets the +file pointer back by 4 bytes from the current position. JA comments +that he didn't find that in the standard, but that it seemed to be +needed for the Philips Integra. + +Tag length +---------- + +Tag lengths as read in ``read_tag`` subfunction. If current format is +explicit (as in 'explicit little endian'): + +#. For VR of \x00\x00, then group, element must be (FFFE, E00D) (item + delimitation tag). JA comments that GE 'ImageDelimitationItem' has + no VR, just 4 0 bytes. In this case the tag length is zero, and we + read another two bytes ahead. + +There's a check for not-even tag length. If not even: + +#. 4294967295 appears to be OK - and decoded as Inf for tag length. +#. 13 appears to mean 10 and is reset to be 10 +#. Any other odd number is not valid and gives a tag length of 0 + +``SQ`` VR type (Sequence of items type) +--------------------------------------- + +tag length of 13 set to tag length 10. + + +``spm_dicom_convert.m`` +======================= + +Written by John Ashburner and Jesper Andersson. + +File categorization +------------------- + +SPM makes a special case of Siemens 'spectroscopy images'. These are +images that have 'SOPClassUID' == '1.3.12.2.1107.5.9.1' and the private +tag of (29, 1210); for these it pulls out the affine, and writes a +volume of ones corresponding to the acquisition planes. + +For images that are not spectroscopy: + +* Discards images that do not have any of ('MR', 'PT', 'CT') in 'Modality' field. +* Discards images lacking any of 'StartOfPixelData', 'SamplesperPixel', + 'Rows', 'Columns', 'BitsAllocated', 'BitsStored', 'HighBit', + 'PixelRespresentation' +* Discards images lacking any of 'PixelSpacing', 'ImagePositionPatient', + 'ImageOrientationPatient' - presumably on the basis that SPM cannot + reconstruct the affine. +* Fields 'SeriesNumber', 'AcquisitionNumber' and 'InstanceNumber' are + set to 1 if absent. + +Next SPM distinguishes between :ref:`dicom-mosaic` and standard DICOM. + +Mosaic images are those with the Siemens private tag:: + + (0029, 1009) [CSA Image Header Version] OB: '20100114' + +and a readable CSA header (see :ref:`dicom-mosaic`), and with +non-empty fields from that header of 'AcquisitionMatrixText', +'NumberOfImagesInMosaic', and with non-zero 'NumberOfImagesInMosaic'. The +rest are standard DICOM. + +For converting mosaic format, see :ref:`dicom-mosaic`. The rest of this +page refers to standard (slice by slice) DICOMs. + +.. _spm-volume-sorting: + +Sorting files into volumes +-------------------------- + +First pass +~~~~~~~~~~ + +Take first header, put as start of first volume. For each subsequent header: + +#. Get ``ICE_Dims`` if present. Look for Siemens 'CSAImageHeaderInfo', + check it has a 'name' field, then pull dimensions out of 'ICE_Dims' + field in form of 9 integers separated by '_', where 'X' in this + string replaced by '-1' - giving 'ICE1' + +Then, for each currently identified volume: + +#. If we have ICE1 above, and we do have 'CSAIMageHeaderInfo', with a + 'name', in the first header in this volume, then extract ICE dims in + the same way as above, for the first header in this volume, and check + whether all but ICE1[6:8] are the same as ICE2. Set flag that all + ICE dims are identical for this volume. Set this flag to True if we + did not have ICE1 or CSA information. +#. Match the current header to the current volume iff the following match: + + #. SeriesNumber + #. Rows + #. Columns + #. ImageOrientationPatient (to tolerance of sum squared difference 1e-4) + #. PixelSpacing (to tolerance of sum squared difference 1e-4) + #. ICE dims as defined above + #. ImageType (iff imagetype exists in both) + #. SequenceName (iff sequencename exists in both) + #. SeriesInstanceUID (iff exists in both) + #. EchoNumbers (iff exists in both) + +#. If the current header matches the current volume, insert it there, + otherwise make a new volume for this header + +.. _spm-second-pass: + +Second pass +~~~~~~~~~~~ + +We now have a list of volumes, where each volume is a list of headers +that may match. + +For each volume: + +#. Estimate the z direction cosine by (effectively) finding the cross + product of the x and y direction cosines contained in + 'ImageOrientationPatient' - call this ``z_dir_cos`` +#. For each header in this volume, get the z coordinate by taking the + dot product of the 'ImagePositionPatient' vector and ``z_dir_cos`` + (see :ref:`dicom-z-from-slice`). +#. Sort the headers according to this estimated z coordinate. +#. If this volume is more than one slice, and there are any slices with + the same z coordinate (as defined above), run the + :ref:`dicom-img-resort` on this volume - on the basis that it may + have caught more than one volume-worth of slices. Return one or more + volume's worth of lists. + +Final check +~~~~~~~~~~~ + +For each volume, recalculate z coordinate as above. Calculate the z +gaps. Subtract the mean of the z gaps from all z gaps. If the average of the +(gap-mean(gap)) is greater than 1e-4, then print a warning that there +are missing DICOM files. + +.. _dicom-img-resort: + +Possible volume resort +~~~~~~~~~~~~~~~~~~~~~~ + +This step happens if there were volumes with slices having the same z +coordinate in the :ref:`spm-second-pass` step above. The resort is on the +set of DICOM headers that were in the volume, for which there were +slices with identical z coordinates. We'll call the list of headers +that the routine is still working on - ``work_list``. + +#. If there is no 'InstanceNumber' field for the first header in + ``work_list``, bail out. +#. Print a message about the 'AcquisitionNumber' not changing from + volume to volume. This may be a relic from previous code, because + this version of SPM does not use the 'AcquisitionNumber' field except + for making filenames. +#. Calculate the z coordinate as for :ref:`spm-second-pass`, for each + DICOM header. +#. Sort the headers by 'InstanceNumber' +#. If any headers have the same 'InstanceNumber', then discard all but + the first header with the same number. At this point the remaining + headers in ``work_list`` will have different 'InstanceNumber's, but + may have the same z coordinate. +#. Now sort by z coordinate +#. If there are ``N`` headers, make a ``N`` length vector of flags + ``is_processed``, for which all values == False +#. Make an output list of header lists, call it ``hdr_vol_out``, set to empty. +#. While there are still any False elements in ``is_processed``: + + #. Find first header for which corresponding ``is_processed`` is + False - call this ``hdr_to_check`` + #. Collect indices (in ``work_list``) of headers which have the same + z coordinate as ``hdr_to_check``, call this list + ``z_same_indices``. + #. Sort ``work_list[z_same_indices]`` by 'InstanceNumber' + #. For each index in ``z_same_indices`` such that ``i`` indexes the + indices, and ``zsind`` is ``z_same_indices[i]``: append header + corresponding to ``zsind`` to ``hdr_vol_out[i]``. This assumes + that the original ``work_list`` contained two or more volumes, + each with an identical set of z coordinates. + #. Set corresponding ``is_processed`` flag to True for all ``z_same_indices``. + +#. Finally, if the headers in ``work_list`` have 'InstanceNumber's that + cannot be sorted to a sequence ascending in units of 1, or if any + of the lists in ``hdr_vol_out`` have different lengths, emit a + warning about missing DICOM files. + +Writing DICOM volumes +--------------------- + +This means - writing DICOM volumes from standard (slice by slice) DICOM +datasets rather than :ref:`dicom-mosaic`. + +Making the affine +~~~~~~~~~~~~~~~~~ + +We need the (4,4) affine $A$ going from voxel (array) coordinates in the +DICOM pixel data, to mm coordinates in the :ref:`dicom-pcs`. + +This section tries to explain how SPM achieves this, but I don't +completely understand their method. See :ref:`dicom-3d-affines` for +what I believe to be a simpler explanation. + +First define the constants, matrices and vectors as in +:ref:`dicom-affine-defs`. + +$N$ is the number of slices in the volume. + +Then define the following matrices: + +.. math:: + + R = \left(\begin{smallmatrix}1 & a & 1 & 0\\1 & b & 0 & 1\\1 & c & 0 & 0\\1 & d & 0 & 0\end{smallmatrix}\right) + + L = \left(\begin{smallmatrix}T^{1}_{{1}} & e & F_{{11}} \Delta{r} & F_{{12}} \Delta{c}\\T^{1}_{{2}} & f & F_{{21}} \Delta{r} & F_{{22}} \Delta{c}\\T^{1}_{{3}} & g & F_{{31}} \Delta{r} & F_{{32}} \Delta{c}\\1 & h & 0 & 0\end{smallmatrix}\right) + +For a volume with more than one slice (header), then $a=1; b=1, c=N, d=1$. $e, f, g$ are the values from $T^N$, +and $h == 1$. + +For a volume with only one slice (header) $a=0, b=0, c=1, d=0$ and $e, +f, g, h$ are $n_1 \Delta{s}, n_2 \Delta{s}, n_3 \Delta{s}, 0$. + +The full transform appears to be $A_{spm} = R L^{-1}$. + +Now, SPM, don't forget, is working in terms of Matlab array indexing, +which starts at (1,1,1) for a three dimensional array, whereas DICOM +expects a (0,0,0) start (see :ref:`dicom-slice-affine`). In this +particular part of the SPM DICOM code, somewhat confusingly, the (0,0,0) +to (1,1,1) indexing is dealt with in the $A$ transform, rather than the +``analyze_to_dicom`` transformation used by SPM in other places. So, the +transform $A_{spm}$ goes from (1,1,1) based voxel indices to mm. To +get the (0, 0, 0)-based transform we want, we need to pre-apply the +transform to take 0-based voxel indices to 1-based voxel indices: + +.. math:: + + A = R L^{-1} \left(\begin{smallmatrix}1 & 0 & 0 & 1\\0 & 1 & 0 & 1\\0 & 0 & 1 & 1\\0 & 0 & 0 & 1\end{smallmatrix}\right) + +This formula with the definitions above result in the single and multi +slice formulae in :ref:`dicom-3d-affine-formulae`. + +See :download:`derivations/spm_dicom_orient.py` for the derivations and +some explanations. + +Writing the voxel data +~~~~~~~~~~~~~~~~~~~~~~ + +Just apply scaling and offset from 'RescaleSlope' and 'RescaleIntercept' +for each slice and write volume. + +.. include:: ../links_names.txt diff --git a/_sources/gettingstarted.rst.txt b/_sources/gettingstarted.rst.txt new file mode 100644 index 0000000000..9b3026bcc7 --- /dev/null +++ b/_sources/gettingstarted.rst.txt @@ -0,0 +1,122 @@ +.. -*- mode: rst -*- +.. ex: set sts=4 ts=4 sw=4 et tw=79: + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + # + # See COPYING file distributed along with the NiBabel package for the + # copyright and license terms. + # + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + +.. _gettingstarted: + +*************** +Getting Started +*************** + +NiBabel supports an ever growing collection of neuroimaging file formats. Every +file format format has its own features and peculiarities that need to be taken +care of to get the most out of it. To this end, NiBabel offers both high-level +format-independent access to neuroimages, as well as an API with various levels +of format-specific access to all available information in a particular file +format. The following examples show some of NiBabel's capabilities and give +you an idea of the API. + +For more detail on the API, see :doc:`nibabel_images`. + +When loading an image, NiBabel tries to figure out the image format from the +filename. An image in a known format can easily be loaded by simply passing its +filename to the ``load`` function. + +To start the code examples, we load some useful libraries: + +>>> import os +>>> import numpy as np + +Then we fine the nibabel directory containing the example data: + +>>> from nibabel.testing import data_path + +There is a NIfTI file in this directory called ``example4d.nii.gz``: + +>>> example_filename = os.path.join(data_path, 'example4d.nii.gz') + +Now we can import nibabel and load the image: + +>>> import nibabel as nib +>>> img = nib.load(example_filename) + +A NiBabel image knows about its shape: + +>>> img.shape +(128, 96, 24, 2) + +It also records the data type of the data as stored on disk. In this case the +data on disk are 16 bit signed integers: + +>>> img.get_data_dtype() == np.dtype(np.int16) +True + +The image has an affine transformation that determines the world-coordinates of +the image elements (see :doc:`coordinate_systems`): + +>>> img.affine.shape +(4, 4) + +This information is available without the need to load anything of the main +image data into the memory. Of course there is also access to the image data as +a NumPy_ array + +>>> data = img.get_fdata() +>>> data.shape +(128, 96, 24, 2) +>>> type(data) +<... 'numpy.ndarray'> + +The complete information embedded in an image header is available via a +format-specific header object. + +>>> hdr = img.header + +In case of this NIfTI_ file it allows accessing all NIfTI-specific information, +e.g. + +>>> hdr.get_xyzt_units() +('mm', 'sec') + +Corresponding "setter" methods allow modifying a header, while ensuring its +compliance with the file format specifications. + +In some situations we need even more flexibility and, for those with great +courage, NiBabel also offers access to the raw header information + +>>> raw = hdr.structarr +>>> raw['xyzt_units'] +array(10, dtype=uint8) + +This lowest level of the API is designed for people who know the file format +well enough to work with its internal data, and comes without any safety-net. + +Creating a new image in some file format is also easy. At a minimum it only +needs some image data and an image coordinate transformation (affine): + +>>> import numpy as np +>>> data = np.ones((32, 32, 15, 100), dtype=np.int16) +>>> img = nib.Nifti1Image(data, np.eye(4)) +>>> img.get_data_dtype() == np.dtype(np.int16) +True +>>> img.header.get_xyzt_units() +('unknown', 'unknown') + +In this case, we used the identity matrix as the affine transformation. The +image header is initialized from the provided data array (i.e. shape, dtype) +and all other values are set to reasonable defaults. + +Saving this new image to a file is trivial: + +>>> nib.save(img, os.path.join('build', 'test4d.nii.gz')) # doctest: +SKIP + +This short introduction only gave a quick overview of NiBabel's capabilities. +Please have a look at the :ref:`api` for more details about supported file +formats and their features. + +.. include:: links_names.txt diff --git a/_sources/gitwash/configure_git.rst.txt b/_sources/gitwash/configure_git.rst.txt new file mode 100644 index 0000000000..a19f592bd5 --- /dev/null +++ b/_sources/gitwash/configure_git.rst.txt @@ -0,0 +1,158 @@ +.. _configure-git: + +=============== + Configure git +=============== + +.. _git-config-basic: + +Overview +======== + +Your personal git configurations are saved in the ``.gitconfig`` file in +your home directory. + +Here is an example ``.gitconfig`` file:: + + [user] + name = Your Name + email = you@yourdomain.example.com + + [alias] + ci = commit -a + co = checkout + st = status + stat = status + br = branch + wdiff = diff --color-words + + [core] + editor = vim + + [merge] + summary = true + +You can edit this file directly or you can use the ``git config --global`` +command:: + + git config --global user.name "Your Name" + git config --global user.email you@yourdomain.example.com + git config --global alias.ci "commit -a" + git config --global alias.co checkout + git config --global alias.st "status -a" + git config --global alias.stat "status -a" + git config --global alias.br branch + git config --global alias.wdiff "diff --color-words" + git config --global core.editor vim + git config --global merge.summary true + +To set up on another computer, you can copy your ``~/.gitconfig`` file, +or run the commands above. + +In detail +========= + +user.name and user.email +------------------------ + +It is good practice to tell git_ who you are, for labeling any changes +you make to the code. The simplest way to do this is from the command +line:: + + git config --global user.name "Your Name" + git config --global user.email you@yourdomain.example.com + +This will write the settings into your git configuration file, which +should now contain a user section with your name and email:: + + [user] + name = Your Name + email = you@yourdomain.example.com + +Of course you'll need to replace ``Your Name`` and ``you@yourdomain.example.com`` +with your actual name and email address. + +Aliases +------- + +You might well benefit from some aliases to common commands. + +For example, you might well want to be able to shorten ``git checkout`` +to ``git co``. Or you may want to alias ``git diff --color-words`` +(which gives a nicely formatted output of the diff) to ``git wdiff`` + +The following ``git config --global`` commands:: + + git config --global alias.ci "commit -a" + git config --global alias.co checkout + git config --global alias.st "status -a" + git config --global alias.stat "status -a" + git config --global alias.br branch + git config --global alias.wdiff "diff --color-words" + +will create an ``alias`` section in your ``.gitconfig`` file with contents +like this:: + + [alias] + ci = commit -a + co = checkout + st = status -a + stat = status -a + br = branch + wdiff = diff --color-words + +Editor +------ + +You may also want to make sure that your editor of choice is used :: + + git config --global core.editor vim + +Merging +------- + +To enforce summaries when doing merges (``~/.gitconfig`` file again):: + + [merge] + log = true + +Or from the command line:: + + git config --global merge.log true + +.. _fancy-log: + +Fancy log output +---------------- + +This is a very nice alias to get a fancy log output; it should go in the +``alias`` section of your ``.gitconfig`` file:: + + lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)[%an]%Creset' --abbrev-commit --date=relative + +You use the alias with:: + + git lg + +and it gives graph / text output something like this (but with color!):: + + * 6d8e1ee - (HEAD, origin/my-fancy-feature, my-fancy-feature) NF - a fancy file (45 minutes ago) [Matthew Brett] + * d304a73 - (origin/placeholder, placeholder) Merge pull request #48 from hhuuggoo/master (2 weeks ago) [Jonathan Terhorst] + |\ + | * 4aff2a8 - fixed bug 35, and added a test in test_bugfixes (2 weeks ago) [Hugo] + |/ + * a7ff2e5 - Added notes on discussion/proposal made during Data Array Summit. (2 weeks ago) [Corran Webster] + * 68f6752 - Initial implementation of AxisIndexer - uses 'index_by' which needs to be changed to a call on an Axes object - this is all very sketchy right now. (2 weeks ago) [Corr + * 376adbd - Merge pull request #46 from terhorst/master (2 weeks ago) [Jonathan Terhorst] + |\ + | * b605216 - updated joshu example to current api (3 weeks ago) [Jonathan Terhorst] + | * 2e991e8 - add testing for outer ufunc (3 weeks ago) [Jonathan Terhorst] + | * 7beda5a - prevent axis from throwing an exception if testing equality with non-axis object (3 weeks ago) [Jonathan Terhorst] + | * 65af65e - convert unit testing code to assertions (3 weeks ago) [Jonathan Terhorst] + | * 956fbab - Merge remote-tracking branch 'upstream/master' (3 weeks ago) [Jonathan Terhorst] + | |\ + | |/ + +Thanks to Yury V. Zaytsev for posting it. + +.. include:: links.inc diff --git a/_sources/gitwash/development_workflow.rst.txt b/_sources/gitwash/development_workflow.rst.txt new file mode 100644 index 0000000000..696a939ed8 --- /dev/null +++ b/_sources/gitwash/development_workflow.rst.txt @@ -0,0 +1,415 @@ +.. _development-workflow: + +#################### +Development workflow +#################### + +You already have your own forked copy of the nibabel_ repository, by +following :ref:`forking`. You have :ref:`set-up-fork`. You have configured +git by following :ref:`configure-git`. Now you are ready for some real work. + +Workflow summary +================ + +In what follows we'll refer to the upstream nibabel ``master`` branch, as +"trunk". + +* Don't use your ``master`` branch for anything. Consider deleting it. +* When you are starting a new set of changes, fetch any changes from trunk, + and start a new *feature branch* from that. +* Make a new branch for each separable set of changes |emdash| "one task, one + branch" (`ipython git workflow`_). +* Name your branch for the purpose of the changes - e.g. + ``bugfix-for-issue-14`` or ``refactor-database-code``. +* If you can possibly avoid it, avoid merging trunk or any other branches into + your feature branch while you are working. +* If you do find yourself merging from trunk, consider :ref:`rebase-on-trunk` +* Ask on the `nibabel mailing list`_ if you get stuck. +* Ask for code review! + +This way of working helps to keep work well organized, with readable history. +This in turn makes it easier for project maintainers (that might be you) to see +what you've done, and why you did it. + +See `linux git workflow`_ and `ipython git workflow`_ for some explanation. + +Consider deleting your master branch +==================================== + +It may sound strange, but deleting your own ``master`` branch can help reduce +confusion about which branch you are on. See `deleting master on github`_ for +details. + +.. _update-mirror-trunk: + +Update the mirror of trunk +========================== + +First make sure you have done :ref:`linking-to-upstream`. + +From time to time you should fetch the upstream (trunk) changes from github:: + + git fetch upstream + +This will pull down any commits you don't have, and set the remote branches to +point to the right commit. For example, 'trunk' is the branch referred to by +(remote/branchname) ``upstream/master`` - and if there have been commits since +you last checked, ``upstream/master`` will change after you do the fetch. + +.. _make-feature-branch: + +Make a new feature branch +========================= + +When you are ready to make some changes to the code, you should start a new +branch. Branches that are for a collection of related edits are often called +'feature branches'. + +Making an new branch for each set of related changes will make it easier for +someone reviewing your branch to see what you are doing. + +Choose an informative name for the branch to remind yourself and the rest of us +what the changes in the branch are for. For example ``add-ability-to-fly``, or +``buxfix-for-issue-42``. + +:: + + # Update the mirror of trunk + git fetch upstream + # Make new feature branch starting at current trunk + git branch my-new-feature upstream/master + git checkout my-new-feature + +Generally, you will want to keep your feature branches on your public github_ +fork of nibabel_. To do this, you `git push`_ this new branch up to your +github repo. Generally (if you followed the instructions in these pages, and by +default), git will have a link to your github repo, called ``origin``. You push +up to your own repo on github with:: + + git push origin my-new-feature + +In git >= 1.7 you can ensure that the link is correctly set by using the +``--set-upstream`` option:: + + git push --set-upstream origin my-new-feature + +From now on git will know that ``my-new-feature`` is related to the +``my-new-feature`` branch in the github repo. + +.. _edit-flow: + +The editing workflow +==================== + +Overview +-------- + +:: + + # hack hack + git add my_new_file + git commit -am 'NF - some message' + git push + +In more detail +-------------- + +#. Make some changes +#. See which files have changed with ``git status`` (see `git status`_). + You'll see a listing like this one:: + + # On branch ny-new-feature + # Changed but not updated: + # (use "git add <file>..." to update what will be committed) + # (use "git checkout -- <file>..." to discard changes in working directory) + # + # modified: README + # + # Untracked files: + # (use "git add <file>..." to include in what will be committed) + # + # INSTALL + no changes added to commit (use "git add" and/or "git commit -a") + +#. Check what the actual changes are with ``git diff`` (`git diff`_). +#. Add any new files to version control ``git add new_file_name`` (see + `git add`_). +#. To commit all modified files into the local copy of your repo,, do + ``git commit -am 'A commit message'``. Note the ``-am`` options to + ``commit``. The ``m`` flag just signals that you're going to type a + message on the command line. The ``a`` flag |emdash| you can just take on + faith |emdash| or see `why the -a flag?`_ |emdash| and the helpful use-case + description in the `tangled working copy problem`_. The `git commit`_ manual + page might also be useful. +#. To push the changes up to your forked repo on github, do a ``git + push`` (see `git push`_). + +Ask for your changes to be reviewed or merged +============================================= + +When you are ready to ask for someone to review your code and consider a merge: + +#. Go to the URL of your forked repo, say + ``https://github.com/your-user-name/nibabel``. +#. Use the 'Switch Branches' dropdown menu near the top left of the page to + select the branch with your changes: + + .. image:: branch_dropdown.png + +#. Click on the 'Pull request' button: + + .. image:: pull_button.png + + Enter a title for the set of changes, and some explanation of what you've + done. Say if there is anything you'd like particular attention for - like a + complicated change or some code you are not happy with. + + If you don't think your request is ready to be merged, just say so in your + pull request message. This is still a good way of getting some preliminary + code review. + +Some other things you might want to do +====================================== + +Delete a branch on github +------------------------- + +:: + + git checkout master + # delete branch locally + git branch -D my-unwanted-branch + # delete branch on github + git push origin :my-unwanted-branch + +(Note the colon ``:`` before ``test-branch``. See also: +https://github.com/guides/remove-a-remote-branch + +Several people sharing a single repository +------------------------------------------ + +If you want to work on some stuff with other people, where you are all +committing into the same repository, or even the same branch, then just +share it via github. + +First fork nibabel into your account, as from :ref:`forking`. + +Then, go to your forked repository github page, say +``https://github.com/your-user-name/nibabel`` + +Click on the 'Admin' button, and add anyone else to the repo as a +collaborator: + + .. image:: pull_button.png + +Now all those people can do:: + + git clone git@githhub.com:your-user-name/nibabel.git + +Remember that links starting with ``git@`` use the ssh protocol and are +read-write; links starting with ``git://`` are read-only. + +Your collaborators can then commit directly into that repo with the +usual:: + + git commit -am 'ENH - much better code' + git push origin master # pushes directly into your repo + +Explore your repository +----------------------- + +To see a graphical representation of the repository branches and +commits:: + + gitk --all + +To see a linear list of commits for this branch:: + + git log + +You can also look at the `network graph visualizer`_ for your github +repo. + +Finally the :ref:`fancy-log` ``lg`` alias will give you a reasonable text-based +graph of the repository. + +.. _rebase-on-trunk: + +Rebasing on trunk +----------------- + +Let's say you thought of some work you'd like to do. You +:ref:`update-mirror-trunk` and :ref:`make-feature-branch` called +``cool-feature``. At this stage trunk is at some commit, let's call it E. Now +you make some new commits on your ``cool-feature`` branch, let's call them A, B, +C. Maybe your changes take a while, or you come back to them after a while. In +the meantime, trunk has progressed from commit E to commit (say) G:: + + A---B---C cool-feature + / + D---E---F---G trunk + +At this stage you consider merging trunk into your feature branch, and you +remember that this here page sternly advises you not to do that, because the +history will get messy. Most of the time you can just ask for a review, and not +worry that trunk has got a little ahead. But sometimes, the changes in trunk +might affect your changes, and you need to harmonize them. In this situation +you may prefer to do a rebase. + +rebase takes your changes (A, B, C) and replays them as if they had been made to +the current state of ``trunk``. In other words, in this case, it takes the +changes represented by A, B, C and replays them on top of G. After the rebase, +your history will look like this:: + + A'--B'--C' cool-feature + / + D---E---F---G trunk + +See `rebase without tears`_ for more detail. + +To do a rebase on trunk:: + + # Update the mirror of trunk + git fetch upstream + # go to the feature branch + git checkout cool-feature + # make a backup in case you mess up + git branch tmp cool-feature + # rebase cool-feature onto trunk + git rebase --onto upstream/master upstream/master cool-feature + +In this situation, where you are already on branch ``cool-feature``, the last +command can be written more succinctly as:: + + git rebase upstream/master + +When all looks good you can delete your backup branch:: + + git branch -D tmp + +If it doesn't look good you may need to have a look at +:ref:`recovering-from-mess-up`. + +If you have made changes to files that have also changed in trunk, this may +generate merge conflicts that you need to resolve - see the `git rebase`_ man +page for some instructions at the end of the "Description" section. There is +some related help on merging in the git user manual - see `resolving a merge`_. + +.. _recovering-from-mess-up: + +Recovering from mess-ups +------------------------ + +Sometimes, you mess up merges or rebases. Luckily, in git it is +relatively straightforward to recover from such mistakes. + +If you mess up during a rebase:: + + git rebase --abort + +If you notice you messed up after the rebase:: + + # reset branch back to the saved point + git reset --hard tmp + +If you forgot to make a backup branch:: + + # look at the reflog of the branch + git reflog show cool-feature + + 8630830 cool-feature@{0}: commit: BUG: io: close file handles immediately + 278dd2a cool-feature@{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d + 26aa21a cool-feature@{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj + ... + + # reset the branch to where it was before the botched rebase + git reset --hard cool-feature@{2} + +.. _rewriting-commit-history: + +Rewriting commit history +------------------------ + +.. note:: + + Do this only for your own feature branches. + +There's an embarrassing typo in a commit you made? Or perhaps the you +made several false starts you would like the posterity not to see. + +This can be done via *interactive rebasing*. + +Suppose that the commit history looks like this:: + + git log --oneline + eadc391 Fix some remaining bugs + a815645 Modify it so that it works + 2dec1ac Fix a few bugs + disable + 13d7934 First implementation + 6ad92e5 * masked is now an instance of a new object, MaskedConstant + 29001ed Add pre-nep for a copule of structured_array_extensions. + ... + +and ``6ad92e5`` is the last commit in the ``cool-feature`` branch. Suppose we +want to make the following changes: + +* Rewrite the commit message for ``13d7934`` to something more sensible. +* Combine the commits ``2dec1ac``, ``a815645``, ``eadc391`` into a single one. + +We do as follows:: + + # make a backup of the current state + git branch tmp HEAD + # interactive rebase + git rebase -i 6ad92e5 + +This will open an editor with the following text in it:: + + pick 13d7934 First implementation + pick 2dec1ac Fix a few bugs + disable + pick a815645 Modify it so that it works + pick eadc391 Fix some remaining bugs + + # Rebase 6ad92e5..eadc391 onto 6ad92e5 + # + # Commands: + # p, pick = use commit + # r, reword = use commit, but edit the commit message + # e, edit = use commit, but stop for amending + # s, squash = use commit, but meld into previous commit + # f, fixup = like "squash", but discard this commit's log message + # + # If you remove a line here THAT COMMIT WILL BE LOST. + # However, if you remove everything, the rebase will be aborted. + # + +To achieve what we want, we will make the following changes to it:: + + r 13d7934 First implementation + pick 2dec1ac Fix a few bugs + disable + f a815645 Modify it so that it works + f eadc391 Fix some remaining bugs + +This means that (i) we want to edit the commit message for +``13d7934``, and (ii) collapse the last three commits into one. Now we +save and quit the editor. + +Git will then immediately bring up an editor for editing the commit +message. After revising it, we get the output:: + + [detached HEAD 721fc64] FOO: First implementation + 2 files changed, 199 insertions(+), 66 deletions(-) + [detached HEAD 0f22701] Fix a few bugs + disable + 1 files changed, 79 insertions(+), 61 deletions(-) + Successfully rebased and updated refs/heads/my-feature-branch. + +and the history looks now like this:: + + 0f22701 Fix a few bugs + disable + 721fc64 ENH: Sophisticated feature + 6ad92e5 * masked is now an instance of a new object, MaskedConstant + +If it went wrong, recovery is again possible as explained :ref:`above +<recovering-from-mess-up>`. + +.. include:: links.inc diff --git a/_sources/gitwash/following_latest.rst.txt b/_sources/gitwash/following_latest.rst.txt new file mode 100644 index 0000000000..0a0d82b362 --- /dev/null +++ b/_sources/gitwash/following_latest.rst.txt @@ -0,0 +1,36 @@ +.. _following-latest: + +============================= + Following the latest source +============================= + +These are the instructions if you just want to follow the latest +*nibabel* source, but you don't need to do any development for now. + +The steps are: + +* :ref:`install-git` +* get local copy of the git repository from github +* update local copy from time to time + +Get the local copy of the code +============================== + +From the command line:: + + git clone git://github.com/nipy/nibabel.git + +You now have a copy of the code tree in the new ``nibabel`` directory. + +Updating the code +================= + +From time to time you may want to pull down the latest code. Do this with:: + + cd nibabel + git pull + +The tree in ``nibabel`` will now have the latest changes from the initial +repository. + +.. include:: links.inc diff --git a/_sources/gitwash/forking_hell.rst.txt b/_sources/gitwash/forking_hell.rst.txt new file mode 100644 index 0000000000..1dd14f4618 --- /dev/null +++ b/_sources/gitwash/forking_hell.rst.txt @@ -0,0 +1,32 @@ +.. _forking: + +========================================== +Making your own copy (fork) of nibabel +========================================== + +You need to do this only once. The instructions here are very similar +to the instructions at https://help.github.com/articles/fork-a-repo/ |emdash| +please see that page for more detail. We're repeating some of it here just to +give the specifics for the nibabel_ project, and to suggest some default names. + +Set up and configure a github account +===================================== + +If you don't have a github account, go to the github page, and make one. + +You then need to configure your account to allow write access |emdash| see +the ``Generating SSH keys`` help on `github help`_. + +Create your own forked copy of nibabel_ +=========================================== + +#. Log into your github account. +#. Go to the nibabel_ github home at `nibabel github`_. +#. Click on the *fork* button: + + .. image:: forking_button.png + + Now, after a short pause and some 'Hardcore forking action', you + should find yourself at the home page for your own forked copy of nibabel_. + +.. include:: links.inc diff --git a/_sources/gitwash/git_development.rst.txt b/_sources/gitwash/git_development.rst.txt new file mode 100644 index 0000000000..c5b910d863 --- /dev/null +++ b/_sources/gitwash/git_development.rst.txt @@ -0,0 +1,16 @@ +.. _git-development: + +===================== + Git for development +===================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + forking_hell + set_up_fork + configure_git + development_workflow + maintainer_workflow diff --git a/_sources/gitwash/git_install.rst.txt b/_sources/gitwash/git_install.rst.txt new file mode 100644 index 0000000000..106ae06109 --- /dev/null +++ b/_sources/gitwash/git_install.rst.txt @@ -0,0 +1,26 @@ +.. _install-git: + +============= + Install git +============= + +Overview +======== + +================ ============= +Debian / Ubuntu ``sudo apt-get install git-core`` +Fedora ``sudo yum install git-core`` +Windows Download and install msysGit_ +OS X Use the git-osx-installer_ +================ ============= + +In detail +========= + +See the git page for the most recent information. + +Have a look at the github install help pages available from `github help`_ + +There are good instructions here: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git + +.. include:: links.inc diff --git a/_sources/gitwash/git_intro.rst.txt b/_sources/gitwash/git_intro.rst.txt new file mode 100644 index 0000000000..30171532ae --- /dev/null +++ b/_sources/gitwash/git_intro.rst.txt @@ -0,0 +1,18 @@ +============== + Introduction +============== + +These pages describe a git_ and github_ workflow for the nibabel_ +project. + +There are several different workflows here, for different ways of +working with *nibabel*. + +This is not a comprehensive git reference, it's just a workflow for our +own project. It's tailored to the github hosting service. You may well +find better or quicker ways of getting stuff done with git, but these +should get you started. + +For general resources for learning git, see :ref:`git-resources`. + +.. include:: links.inc diff --git a/_sources/gitwash/git_resources.rst.txt b/_sources/gitwash/git_resources.rst.txt new file mode 100644 index 0000000000..d18b0ef48b --- /dev/null +++ b/_sources/gitwash/git_resources.rst.txt @@ -0,0 +1,59 @@ +.. _git-resources: + +============= +git resources +============= + +Tutorials and summaries +======================= + +* `github help`_ has an excellent series of how-to guides. +* `learn.github`_ has an excellent series of tutorials +* The `pro git book`_ is a good in-depth book on git. +* A `git cheat sheet`_ is a page giving summaries of common commands. +* The `git user manual`_ +* The `git tutorial`_ +* The `git community book`_ +* `git ready`_ |emdash| a nice series of tutorials +* `git casts`_ |emdash| video snippets giving git how-tos. +* `git magic`_ |emdash| extended introduction with intermediate detail +* The `git parable`_ is an easy read explaining the concepts behind git. +* `git foundation`_ expands on the `git parable`_. +* Fernando Perez' git page |emdash| `Fernando's git page`_ |emdash| many + links and tips +* A good but technical page on `git concepts`_ +* `git svn crash course`_: git for those of us used to subversion_ + +Advanced git workflow +===================== + +There are many ways of working with git; here are some posts on the +rules of thumb that other projects have come up with: + +* Linus Torvalds on `git management`_ +* Linus Torvalds on `linux git workflow`_ . Summary; use the git tools + to make the history of your edits as clean as possible; merge from + upstream edits as little as possible in branches where you are doing + active development. + +Manual pages online +=================== + +You can get these on your own machine with (e.g) ``git help push`` or +(same thing) ``git push --help``, but, for convenience, here are the +online manual pages for some common commands: + +* `git add`_ +* `git branch`_ +* `git checkout`_ +* `git clone`_ +* `git commit`_ +* `git config`_ +* `git diff`_ +* `git log`_ +* `git pull`_ +* `git push`_ +* `git remote`_ +* `git status`_ + +.. include:: links.inc diff --git a/_sources/gitwash/index.rst.txt b/_sources/gitwash/index.rst.txt new file mode 100644 index 0000000000..9dcc741fbc --- /dev/null +++ b/_sources/gitwash/index.rst.txt @@ -0,0 +1,16 @@ +.. _using-git: + +Working with *nibabel* source code +====================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + git_intro + git_install + following_latest + patching + git_development + git_resources diff --git a/_sources/gitwash/maintainer_workflow.rst.txt b/_sources/gitwash/maintainer_workflow.rst.txt new file mode 100644 index 0000000000..d2fc6caa53 --- /dev/null +++ b/_sources/gitwash/maintainer_workflow.rst.txt @@ -0,0 +1,96 @@ +.. _maintainer-workflow: + +################### +Maintainer workflow +################### + +This page is for maintainers |emdash| those of us who merge our own or other +peoples' changes into the upstream repository. + +Being as how you're a maintainer, you are completely on top of the basic stuff +in :ref:`development-workflow`. + +The instructions in :ref:`linking-to-upstream` add a remote that has read-only +access to the upstream repo. Being a maintainer, you've got read-write access. + +It's good to have your upstream remote have a scary name, to remind you that +it's a read-write remote:: + + git remote add upstream-rw git@github.com:nipy/nibabel.git + git fetch upstream-rw + +******************* +Integrating changes +******************* + +Let's say you have some changes that need to go into trunk +(``upstream-rw/master``). + +The changes are in some branch that you are currently on. For example, you are +looking at someone's changes like this:: + + git remote add someone git://github.com/someone/nibabel.git + git fetch someone + git branch cool-feature --track someone/cool-feature + git checkout cool-feature + +So now you are on the branch with the changes to be incorporated upstream. The +rest of this section assumes you are on this branch. + +A few commits +============= + +If there are only a few commits, consider rebasing to upstream:: + + # Fetch upstream changes + git fetch upstream-rw + # rebase + git rebase upstream-rw/master + +Remember that, if you do a rebase, and push that, you'll have to close any +github pull requests manually, because github will not be able to detect the +changes have already been merged. + +A long series of commits +======================== + +If there are a longer series of related commits, consider a merge instead:: + + git fetch upstream-rw + git merge --no-ff upstream-rw/master + +The merge will be detected by github, and should close any related pull requests +automatically. + +Note the ``--no-ff`` above. This forces git to make a merge commit, rather than +doing a fast-forward, so that these set of commits branch off trunk then rejoin +the main history with a merge, rather than appearing to have been made directly +on top of trunk. + +Check the history +================= + +Now, in either case, you should check that the history is sensible and you have +the right commits:: + + git log --oneline --graph + git log -p upstream-rw/master.. + +The first line above just shows the history in a compact way, with a text +representation of the history graph. The second line shows the log of commits +excluding those that can be reached from trunk (``upstream-rw/master``), and +including those that can be reached from current HEAD (implied with the ``..`` +at the end). So, it shows the commits unique to this branch compared to trunk. +The ``-p`` option shows the diff for these commits in patch form. + +Push to trunk +============= + +:: + + git push upstream-rw my-new-feature:master + +This pushes the ``my-new-feature`` branch in this repository to the ``master`` +branch in the ``upstream-rw`` repository. + +.. include:: links.inc diff --git a/_sources/gitwash/patching.rst.txt b/_sources/gitwash/patching.rst.txt new file mode 100644 index 0000000000..d9a695bd8e --- /dev/null +++ b/_sources/gitwash/patching.rst.txt @@ -0,0 +1,134 @@ +================ + Making a patch +================ + +You've discovered a bug or something else you want to change +in nibabel_ .. |emdash| excellent! + +You've worked out a way to fix it |emdash| even better! + +You want to tell us about it |emdash| best of all! + +The easiest way is to make a *patch* or set of patches. Here +we explain how. Making a patch is the simplest and quickest, +but if you're going to be doing anything more than simple +quick things, please consider following the +:ref:`git-development` model instead. + +.. _making-patches: + +Making patches +============== + +Overview +-------- + +:: + + # tell git who you are + git config --global user.email you@yourdomain.example.com + git config --global user.name "Your Name Comes Here" + # get the repository if you don't have it + git clone git://github.com/nipy/nibabel.git + # make a branch for your patching + cd nibabel + git branch the-fix-im-thinking-of + git checkout the-fix-im-thinking-of + # hack, hack, hack + # Tell git about any new files you've made + git add somewhere/tests/test_my_bug.py + # commit work in progress as you go + git commit -am 'BF - added tests for Funny bug' + # hack hack, hack + git commit -am 'BF - added fix for Funny bug' + # make the patch files + git format-patch -M -C master + +Then, send the generated patch files to the `nibabel +mailing list`_ |emdash| where we will thank you warmly. + +In detail +--------- + +#. Tell git who you are so it can label the commits you've + made:: + + git config --global user.email you@yourdomain.example.com + git config --global user.name "Your Name Comes Here" + +#. If you don't already have one, clone a copy of the + nibabel_ repository:: + + git clone git://github.com/nipy/nibabel.git + cd nibabel + +#. Make a 'feature branch'. This will be where you work on + your bug fix. It's nice and safe and leaves you with + access to an unmodified copy of the code in the main + branch:: + + git branch the-fix-im-thinking-of + git checkout the-fix-im-thinking-of + +#. Do some edits, and commit them as you go:: + + # hack, hack, hack + # Tell git about any new files you've made + git add somewhere/tests/test_my_bug.py + # commit work in progress as you go + git commit -am 'BF - added tests for Funny bug' + # hack hack, hack + git commit -am 'BF - added fix for Funny bug' + + Note the ``-am`` options to ``commit``. The ``m`` flag just + signals that you're going to type a message on the command + line. The ``a`` flag |emdash| you can just take on faith |emdash| + or see `why the -a flag?`_. + +#. When you have finished, check you have committed all your + changes:: + + git status + +#. Finally, make your commits into patches. You want all the + commits since you branched from the ``master`` branch:: + + git format-patch -M -C master + + You will now have several files named for the commits:: + + 0001-BF-added-tests-for-Funny-bug.patch + 0002-BF-added-fix-for-Funny-bug.patch + + Send these files to the `nibabel mailing list`_. + +When you are done, to switch back to the main copy of the +code, just return to the ``master`` branch:: + + git checkout master + +Moving from patching to development +=================================== + +If you find you have done some patches, and you have one or +more feature branches, you will probably want to switch to +development mode. You can do this with the repository you +have. + +Fork the nibabel_ repository on github |emdash| :ref:`forking`. +Then:: + + # checkout and refresh master branch from main repo + git checkout master + git pull origin master + # rename pointer to main repository to 'upstream' + git remote rename origin upstream + # point your repo to default read / write to your fork on github + git remote add origin git@github.com:your-user-name/nibabel.git + # push up any branches you've made and want to keep + git push origin the-fix-im-thinking-of + +Then you can, if you want, follow the +:ref:`development-workflow`. + +.. include:: links.inc diff --git a/_sources/gitwash/set_up_fork.rst.txt b/_sources/gitwash/set_up_fork.rst.txt new file mode 100644 index 0000000000..c4fb086bf0 --- /dev/null +++ b/_sources/gitwash/set_up_fork.rst.txt @@ -0,0 +1,67 @@ +.. _set-up-fork: + +================== + Set up your fork +================== + +First you follow the instructions for :ref:`forking`. + +Overview +======== + +:: + + git clone git@github.com:your-user-name/nibabel.git + cd nibabel + git remote add upstream git://github.com/nipy/nibabel.git + +In detail +========= + +Clone your fork +--------------- + +#. Clone your fork to the local computer with ``git clone + git@github.com:your-user-name/nibabel.git`` +#. Investigate. Change directory to your new repo: ``cd nibabel``. Then + ``git branch -a`` to show you all branches. You'll get something + like:: + + * master + remotes/origin/master + + This tells you that you are currently on the ``master`` branch, and + that you also have a ``remote`` connection to ``origin/master``. + What remote repository is ``remote/origin``? Try ``git remote -v`` to + see the URLs for the remote. They will point to your github fork. + + Now you want to connect to the upstream `nibabel github`_ repository, so + you can merge in changes from trunk. + +.. _linking-to-upstream: + +Linking your repository to the upstream repo +-------------------------------------------- + +:: + + cd nibabel + git remote add upstream git://github.com/nipy/nibabel.git + +``upstream`` here is just the arbitrary name we're using to refer to the +main nibabel_ repository at `nibabel github`_. + +Note that we've used ``git://`` for the URL rather than ``git@``. The +``git://`` URL is read only. This means we that we can't accidentally +(or deliberately) write to the upstream repo, and we are only going to +use it to merge into our own code. + +Just for your own satisfaction, show yourself that you now have a new +'remote', with ``git remote -v show``, giving you something like:: + + upstream git://github.com/nipy/nibabel.git (fetch) + upstream git://github.com/nipy/nibabel.git (push) + origin git@github.com:your-user-name/nibabel.git (fetch) + origin git@github.com:your-user-name/nibabel.git (push) + +.. include:: links.inc diff --git a/_sources/image_orientation.rst.txt b/_sources/image_orientation.rst.txt new file mode 100644 index 0000000000..bfe512b65f --- /dev/null +++ b/_sources/image_orientation.rst.txt @@ -0,0 +1,91 @@ +####################### +Image voxel orientation +####################### + +It is sometimes useful to know the approximate world-space orientations of the +image voxel axes. + +See :doc:`coordinate_systems` for background on voxel and world axes. + +For example, let's say we had an image with an identity affine: + +>>> import numpy as np +>>> import nibabel as nib +>>> affine = np.eye(4) # identity affine +>>> voxel_data = np.random.normal(size=(10, 11, 12)) +>>> img = nib.Nifti1Image(voxel_data, affine) + +Because the affine is an identity affine, the voxel axes align with the world +axes. By convention, nibabel world axes are always in RAS+ orientation (left +to Right, posterior to Anterior, inferior to Superior). + +Let's say we took a single line of voxels along the first voxel axis: + +>>> single_line_axis_0 = voxel_data[:, 0, 0] + +The first voxel axis is aligned to the left to Right world axes. This means +that the first voxel is towards the left of the world, and the last voxel is +towards the right of the world. + +Here is a single line in the second axis: + +>>> single_line_axis_1 = voxel_data[0, :, 0] + +The first voxel in this line is towards the posterior of the world, and the +last towards the anterior. + +>>> single_line_axis_2 = voxel_data[0, 0, :] + +The first voxel in this line is towards the inferior of the world, and the +last towards the superior. + +This image therefore has RAS+ *voxel* axes. + +In other cases, it is not so obvious what the orientations of the axes are. +For example, here is our example NIfTI 1 file again: + +>>> import os +>>> from nibabel.testing import data_path +>>> example_file = os.path.join(data_path, 'example4d.nii.gz') +>>> img = nib.load(example_file) + +Here is the affine (to two digits decimal precision): + +>>> np.set_printoptions(precision=2, suppress=True) +>>> img.affine +array([[ -2. , 0. , 0. , 117.86], + [ -0. , 1.97, -0.36, -35.72], + [ 0. , 0.32, 2.17, -7.25], + [ 0. , 0. , 0. , 1. ]]) + +What are the orientations of the voxel axes here? + +Nibabel has a routine to tell you, called ``aff2axcodes``. + +>>> nib.aff2axcodes(img.affine) +('L', 'A', 'S') + +The voxel orientations are nearest to: + +#. First voxel axis goes from right to Left; +#. Second voxel axis goes from posterior to Anterior; +#. Third voxel axis goes from inferior to Superior. + +Sometimes you may want to rearrange the image voxel axes to make them as close +as possible to RAS+ orientation. We refer to this voxel orientation as +*canonical* voxel orientation, because RAS+ is our canonical world +orientation. Rearranging the voxel axes means reversing and / or reordering +the voxel axes. + +You can do the arrangement with ``as_closest_canonical``: + +>>> canonical_img = nib.as_closest_canonical(img) +>>> canonical_img.affine +array([[ 2. , 0. , 0. , -136.14], + [ 0. , 1.97, -0.36, -35.72], + [ -0. , 0.32, 2.17, -7.25], + [ 0. , 0. , 0. , 1. ]]) +>>> nib.aff2axcodes(canonical_img.affine) +('R', 'A', 'S') + +.. include:: links_names.txt diff --git a/_sources/images_and_memory.rst.txt b/_sources/images_and_memory.rst.txt new file mode 100644 index 0000000000..2ff0de14c5 --- /dev/null +++ b/_sources/images_and_memory.rst.txt @@ -0,0 +1,225 @@ +################# +Images and memory +################# + +We saw in :doc:`nibabel_images` that images loaded from disk are usually +*proxy images*. Proxy images are images that have a ``dataobj`` property that +is not a numpy array, but an *array proxy* that can fetch the array data from +disk. + +>>> import os +>>> import numpy as np +>>> from nibabel.testing import data_path +>>> example_file = os.path.join(data_path, 'example4d.nii.gz') + +>>> import nibabel as nib +>>> img = nib.load(example_file) +>>> img.dataobj +<nibabel.arrayproxy.ArrayProxy object at ...> + +Nibabel does not load the image array from the proxy when you ``load`` the +image. It waits until you ask for the array data. The standard way to ask +for the array data is to call the ``get_fdata()`` method: + +>>> data = img.get_fdata() +>>> data.shape +(128, 96, 24, 2) + +We also saw in :ref:`proxies-caching` that this call to ``get_fdata()`` will +(by default) load the array data into an internal image cache. The image +returns the cached copy on the next call to ``get_fdata()``: + +>>> data_again = img.get_fdata() +>>> data is data_again +True + +This behavior is convenient if you want quick and repeated access to the image +array data. The down-side is that the image keeps a reference to the image +data array, so the array can't be cleared from memory until the image object +gets deleted. You might prefer to keep loading the array from disk instead of +keeping the cached copy in the image. + +This page describes ways of using the image array proxies to save memory and +time. + +*************************************************** +Using ``in_memory`` to check the state of the cache +*************************************************** + +You can use the ``in_memory`` property to check if the image has cached the +array. + +The ``in_memory`` property is always True for array images, because the image +data is always an array in memory: + +>>> array_data = np.arange(24, dtype=np.int16).reshape((2, 3, 4)) +>>> affine = np.diag([1, 2, 3, 1]) +>>> array_img = nib.Nifti1Image(array_data, affine) +>>> array_img.in_memory +True + +For a proxy image, the ``in_memory`` property is False when the array is not +in cache, and True when it is in cache: + +>>> img = nib.load(example_file) +>>> img.in_memory +False +>>> data = img.get_fdata() +>>> img.in_memory +True + + +***************** +Using ``uncache`` +***************** + +As y'all know, the proxy image has the array in cache, ``get_fdata()`` returns +the cached array: + +>>> data_again = img.get_fdata() +>>> data_again is data # same array returned from cache +True + +You can uncache a proxy image with the ``uncache()`` method: + +>>> img.uncache() +>>> img.in_memory +False +>>> data_once_more = img.get_fdata() +>>> data_once_more is data # a new copy read from disk +False + +``uncache()`` has no effect if the image is an array image, or if the cache is +already empty. + +You need to be careful when you modify arrays returned by ``get_fdata()`` on +proxy images, because ``uncache`` will then change the result you get back +from ``get_fdata()``: + +>>> proxy_img = nib.load(example_file) +>>> data = proxy_img.get_fdata() # array cached and returned +>>> data[0, 0, 0, 0] +0.0 +>>> data[0, 0, 0, 0] = 99 # modify returned array +>>> data_again = proxy_img.get_fdata() # return cached array +>>> data_again[0, 0, 0, 0] # cached array modified +99.0 + +So far the proxy image behaves the same as an array image. ``uncache()`` has +no effect on an array image, but it does have an effect on the returned array +of a proxy image: + +>>> proxy_img.uncache() # cached array discarded from proxy image +>>> data_once_more = proxy_img.get_fdata() # new copy of array loaded +>>> data_once_more[0, 0, 0, 0] # array modifications discarded +0.0 + +************* +Saving memory +************* + +Uncache the array +================= + +If you do not want the image to keep the array in its internal cache, you can +use the ``uncache()`` method: + +>>> img.uncache() + +Use the array proxy instead of ``get_fdata()`` +============================================== + +The ``dataobj`` property of a proxy image is an array proxy. We can ask the +proxy to return the array directly by passing ``dataobj`` to the numpy +``asarray`` function: + +>>> proxy_img = nib.load(example_file) +>>> data_array = np.asarray(proxy_img.dataobj) +>>> type(data_array) +<... 'numpy.ndarray'> + +This also works for array images, because ``np.asarray`` returns the array: + +>>> array_img = nib.Nifti1Image(array_data, affine) +>>> data_array = np.asarray(array_img.dataobj) +>>> type(data_array) +<... 'numpy.ndarray'> + +If you want to avoid caching you can avoid ``get_fdata()`` and always use +``np.asarray(img.dataobj)``. + +Use the ``caching`` keyword to ``get_fdata()`` +============================================== + +The default behavior of the ``get_fdata()`` function is to always fill the +cache, if it is empty. This corresponds to the default ``'fill'`` value +to the ``caching`` keyword. So, this: + +>>> proxy_img = nib.load(example_file) +>>> data = proxy_img.get_fdata() # default caching='fill' +>>> proxy_img.in_memory +True + +is the same as this: + +>>> proxy_img = nib.load(example_file) +>>> data = proxy_img.get_fdata(caching='fill') +>>> proxy_img.in_memory +True + +Sometimes you may want to avoid filling the cache, if it is empty. In this +case, you can use ``caching='unchanged'``: + +>>> proxy_img = nib.load(example_file) +>>> data = proxy_img.get_fdata(caching='unchanged') +>>> proxy_img.in_memory +False + +``caching='unchanged'`` will leave the cache full if it is already full. + +>>> data = proxy_img.get_fdata(caching='fill') +>>> proxy_img.in_memory +True +>>> data = proxy_img.get_fdata(caching='unchanged') +>>> proxy_img.in_memory +True + +See the :meth:`get_fdata() docstring +<nibabel.spatialimages.SpatialImage.get_fdata>` for more detail. + +********************** +Saving time and memory +********************** + +You can use the array proxy to get slices of data from disk in an efficient +way. + +The array proxy API allows you to do slicing on the proxy. In most cases this +will mean that you only load the data from disk that you actually need, often +saving both time and memory. + +For example, let us say you only wanted the second volume from the example +dataset. You could do this: + +>>> proxy_img = nib.load(example_file) +>>> data = proxy_img.get_fdata() +>>> data.shape +(128, 96, 24, 2) +>>> vol1 = data[..., 1] +>>> vol1.shape +(128, 96, 24) + +The problem is that you had to load the whole data array into memory before +throwing away the first volume and keeping the second. + +You can use array proxy slicing to do this more efficiently: + +>>> proxy_img = nib.load(example_file) +>>> vol1 = proxy_img.dataobj[..., 1] +>>> vol1.shape +(128, 96, 24) + +The slicing call in ``proxy_img.dataobj[..., 1]`` will only load the data from +disk that you need to fill the memory of ``vol1``. + +.. include:: links_names.txt diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 0000000000..72c731d25f --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,176 @@ +.. -*- mode: rst -*- +.. ex: set sts=4 ts=4 sw=4 et tw=79: + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + # + # See COPYING file distributed along with the NiBabel package for the + # copyright and license terms. + # + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + +======= +NiBabel +======= + +.. include:: _long_description.inc + +Documentation +============= + +* :ref:`User Documentation <manual>` (manual) +* :ref:`Tutorials <tutorials>` (relevant tutorials on imaging) +* :ref:`API Documentation <api>` (comprehensive reference) +* :ref:`Developer Guidelines <chap_devguide>` (for those who want to contribute) +* :ref:`Development Changelog <changelog>` (see what has changed) +* :ref:`DICOM concepts <dicom>` (details about implementing DICOM reading) +* :ref:`genindex` (access by keywords) +* :ref:`search` (online and offline full-text search) + +See also the :ref:`Developer documentation page <devindex>` for development +discussions, release procedure and more. + +Authors and Contributors +======================== + +Most work on NiBabel so far has been by `Matthew Brett`_, Chris Markiewicz, +`Michael Hanke`_, `Marc-Alexandre CΓ΄tΓ©`_, `Ben Cipollini`_, Paul McCarthy and +Chris Cheng. The authors are grateful to the following people who have +contributed code and discussion (in rough order of appearance): + +* `Yaroslav O. Halchenko`_ +* Chris Burns +* `GaΓ«l Varoquaux`_ +* Ian Nimmo-Smith +* `Jarrod Millman`_ +* `Bertrand Thirion`_ +* Thomas Ballinger +* Cindee Madison +* Valentin Haenel +* `Alexandre Gramfort`_ +* Christian Haselgrove +* Krish Subramaniam +* Yannick Schwartz +* Bago Amirbekian +* Brendan Moloney +* FΓ©lix C. Morency +* JB Poline +* Basile Pinsard +* `Satrajit Ghosh`_ +* Eric Larson +* `Nolan Nichols`_ +* Ly Nguyen +* Philippe Gervais +* Demian Wassermann +* Justin Lecher +* Oliver P. Hinds +* Nikolaas N. Oosterhof +* Kevin S. Hahn +* Michiel Cottaar +* Erik Kastman +* Github user ``freec84`` +* Peter Fischer +* Clemens C. C. Bauer +* Samuel St-Jean +* Gregory R. Lee +* Eric M. Baker +* `Ariel Rokem`_ +* Eleftherios Garyfallidis +* Jaakko LeppΓ€kangas +* Syam Gadde +* Robert D. Vincent +* Ivan Gonzalez +* Demian Wassermann +* Paul McCarthy +* Fernando PΓ©rez GarcΓ­a +* Venky Reddy +* Mark Hymers +* Jasper J.F. van den Bosch +* Bennet Fauber +* Kesshi Jordan +* Jon Stutters +* Serge Koudoro +* Christopher P. Cheng +* Mathias Goncalves +* Jakub Kaczmarzyk +* Dimitri Papadopoulos Orfanos +* Ross Markello +* Miguel Estevan Moreno +* Thomas Roos +* Igor Solovey +* Jon Haitz Legarreta GorroΓ±o +* Katrin Leinweber +* Soichi Hayashi +* Samir Reddigari +* Konstantinos Raktivan +* Matt Cieslak +* Egor Panfilov +* Jath Palasubramaniam +* Henry Braun +* Oscar Esteban +* Cameron Riddell +* Hao-Ting Wang +* Dorota Jarecka +* Chris Gorgolewski +* Benjamin C Darwin +* Zvi Baratz +* Roberto Guidotti +* Or Duek +* Anibal SΓ³lon +* Jonathan Daniel +* MarkΓ©ta CalΓ‘bkovΓ‘ +* Carl Gauthier +* Julian Klug +* Lea Waller +* TomΓ‘Ε‘ Hrnčiar +* Andrew Van +* JΓ©rΓ΄me DockΓ¨s +* Jacob Roberts +* Horea Christian +* Fabian Perez +* Mathieu Scheltienne +* Reinder Vos de Wael +* Peter Suter +* Blake Dewey + +License reprise +=============== + +NiBabel is free-software (beer and speech) and covered by the `MIT License`_. +This applies to all source code, documentation, examples and snippets inside +the source distribution (including this website). Please see the +:ref:`appendix of the manual <license>` for the copyright statement and the +full text of the license. + +Download and Installation +========================= + +Please find detailed :ref:`download and installation instructions +<installation>` in the manual. + +Support +======= + +If you have problems installing the software or questions about usage, +documentation or anything else related to NiBabel, you can post to the NiPy +mailing list. + +:Mailing list: neuroimaging@python.org [subscription_, archive_] + +We recommend that anyone using NiBabel subscribes to the mailing list. The +mailing list is the preferred way to announce changes and additions to the +project. You can also search the mailing list archive using the *mailing list +archive search* located in the sidebar of the NiBabel home page. + +.. _subscription: https://mail.python.org/mailman/listinfo/neuroimaging +.. _archive: https://mail.python.org/pipermail/neuroimaging + +.. include:: links_names.txt + + +.. toctree:: + :hidden: + + manual + tutorials + devel/index + dicom/dicom + api diff --git a/_sources/installation.rst.txt b/_sources/installation.rst.txt new file mode 100644 index 0000000000..4f747e7feb --- /dev/null +++ b/_sources/installation.rst.txt @@ -0,0 +1,139 @@ +.. -*- mode: rst -*- +.. ex: set sts=4 ts=4 sw=4 et tw=79: + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + # + # See COPYING file distributed along with the NiBabel package for the + # copyright and license terms. + # + ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### + +.. _installation: + +************ +Installation +************ + +NiBabel is a pure Python package, +and it should be easy to get NiBabel running on any system. +For the most popular platforms and operating systems +there should be packages in the respective native packaging format +(DEB, RPM or installers). +On other systems you can install NiBabel using pip_. + +.. This remark below is not yet true; comment to avoid confusion + To run all of the tests, you may need some extra data packages - see + :ref:`installing-data`. + +Installer and packages +====================== + +.. _install-pypi: + +pip and the Python package index +-------------------------------- + +If you are not using a Linux package manager, then best way to install NiBabel +is via pip_. If you don't have pip already, follow the `pip install +instructions`_. + +Then open a terminal (``Terminal.app`` on OSX, ``cmd`` or ``Powershell`` on +Windows), and type:: + + pip install nibabel + +This will download and install NiBabel. + +If you really like doing stuff manually, you can install NiBabel by downloading +the source from `NiBabel pypi`_ . Go to the pypi page and select the source +distribution you want. Download the distribution, unpack it, and then, from +the unpacked directory, run:: + + pip install . + +If you get permission errors, this may be because ``pip`` is trying to install +to the system directories. You can solve this error by using ``sudo``, but we +strongly suggest you either do an install into your "user" directories, like +this:: + + pip install --user . + +or you work inside a virtualenv_. + +.. _install_debian: + +Debian/Ubuntu +------------- + +Our friends at NeuroDebian_ have packaged NiBabel at `NiBabel NeuroDebian`_. +Please follow the instructions on the NeuroDebian_ website on how to access +their repositories. Once this is done, installing NiBabel is:: + + apt-get update + apt-get install python-nibabel + +Install a development version +============================= + +If you want to test the latest development version of nibabel, or you'd like to +help by contributing bug-fixes or new features (excellent!), then this section +is for you. + +Requirements +------------ + +.. check these against pyproject.toml + +* Python_ 3.8 or greater +* NumPy_ 1.20 or greater +* Packaging_ 17.0 or greater +* importlib-resources_ 1.3 or greater (or Python 3.9+) +* SciPy_ (optional, for full SPM-ANALYZE support) +* h5py_ (optional, for MINC2 support) +* PyDICOM_ 1.0.0 or greater (optional, for DICOM support) +* `Python Imaging Library`_ (optional, for PNG conversion in DICOMFS) +* pytest_ (optional, to run the tests) +* sphinx_ (optional, to build the documentation) + +Get the development sources +--------------------------- + +You can download a tarball of the latest development snapshot (i.e. the current +state of the *master* branch of the NiBabel source code repository) from the +`NiBabel github`_ page. + +If you want to have access to the full NiBabel history and the latest +development code, do a full clone (AKA checkout) of the NiBabel +repository:: + + git clone https://github.com/nipy/nibabel.git + +Installation +------------ + +Just install the modules by invoking:: + + pip install . + +See :ref:`install-pypi` for advice on what to do for permission errors. + +Validating your install +----------------------- + +For a basic test of your installation, fire up Python and try importing the +module to see if everything is fine. It should look something like this:: + + Python 3.8.5 (default, Sep 4 2020, 07:30:14) + [GCC 7.3.0] :: Anaconda, Inc. on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> import nibabel + >>> + + +To run the nibabel test suite, from the terminal run +``pytest --pyargs nibabel`` or +``python -c "import nibabel; nibabel.test()``. + +To run an extended test suite that validates ``nibabel`` for long-running and +resource-intensive cases, please see :ref:`advanced_testing`. + +.. include:: links_names.txt diff --git a/_sources/legal.rst.txt b/_sources/legal.rst.txt new file mode 100644 index 0000000000..aadf96e90c --- /dev/null +++ b/_sources/legal.rst.txt @@ -0,0 +1,220 @@ +.. -*- mode: rst; fill-column: 78 -*- +.. ex: set sts=4 ts=4 sw=4 et tw=79: +.. vim:syntax=rest + +.. _license: + +********************** +Copyright and Licenses +********************** + +NiBabel +======= + +The nibabel package, including all examples, code snippets and attached +documentation is covered by the MIT license. + +:: + + The MIT License + + Copyright (c) 2009-2019 Matthew Brett <matthew.brett@gmail.com> + Copyright (c) 2010-2013 Stephan Gerhard <git@unidesign.ch> + Copyright (c) 2006-2014 Michael Hanke <michael.hanke@gmail.com> + Copyright (c) 2011 Christian Haselgrove <christian.haselgrove@umassmed.edu> + Copyright (c) 2010-2011 Jarrod Millman <jarrod.millman@gmail.com> + Copyright (c) 2011-2019 Yaroslav Halchenko <debian@onerussian.com> + Copyright (c) 2015-2019 Chris Markiewicz <effigies@gmail.com> + + 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. + + +3rd party code and data +======================= + +Some code distributed within the nibabel sources was developed by other +projects. This code is distributed under its respective licenses that are +listed below. + +NetCDF +------ + +The netcdf IO module has been taken from SciPy. + +:: + + Copyright (c) 1999-2010 SciPy Developers <scipy-dev@scipy.org> + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + a. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + b. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + c. Neither the name of the Enthought nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + + +Sphinx autosummary extension +---------------------------- + +This extension has been copied from NumPy (Jul 16, 2010) as the one shipped with +Sphinx 0.6 doesn't work properly. + +:: + + Copyright (c) 2007-2009 Stefan van der Walt and Sphinx team + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + a. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + b. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + c. Neither the name of the Enthought nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +OrderedSet +----------- + +In ``nibabel/externals/oset.py`` + +Copied from: https://files.pythonhosted.org/packages/d6/b1/a49498c699a3fda5d635cc1fa222ffc686ea3b5d04b84a3166c4cab0c57b/oset-0.1.3.tar.gz + +:: + + Copyright (c) 2009, Raymond Hettinger, and others All rights reserved. + + Package structured based on the one developed to odict Copyright (c) 2010, BlueDynamics Alliance, Austria + + - Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + - Neither the name of the BlueDynamics Alliance nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY BlueDynamics Alliance AS IS AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + SHALL BlueDynamics Alliance BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + OF SUCH DAMAGE. + +mni_icbm152_t1_tal_nlin_asym_09a +-------------------------------- + +The file ``doc/source/someone.nii.gz`` is a subsampled version of the file +``mni_icbm152_t1_tal_nlin_asym_09a.nii`` from the MNI non-linear templates +archive ``mni_icbm152_t1_tal_nlin_asym_09a``. The original image has the +following license (where 'softwware' refers to the image): + +:: + + Copyright (C) 1993-2004 Louis Collins, McConnell Brain Imaging Centre, + Montreal Neurological Institute, McGill University. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies. The authors and + McGill University make no representations about the suitability of this + software for any purpose. It is provided "as is" without express or + implied warranty. The authors are not responsible for any data loss, + equipment damage, property loss, or injury to subjects or patients + resulting from the use or misuse of this software package. + +Philips PAR/REC data +-------------------- + +The files:: + + nibabel/tests/data/phantom_EPI_asc_CLEAR_2_1.PAR + nibabel/tests/data/phantom_EPI_asc_CLEAR_2_1.REC + nibabel/tests/data/Phantom_EPI_3mm_cor_20APtrans_15RLrot_SENSE_15_1.PAR + nibabel/tests/data/Phantom_EPI_3mm_cor_SENSE_8_1.PAR + nibabel/tests/data/Phantom_EPI_3mm_sag_15AP_SENSE_13_1.PAR + nibabel/tests/data/Phantom_EPI_3mm_sag_15FH_SENSE_12_1.PAR + nibabel/tests/data/Phantom_EPI_3mm_sag_15RL_SENSE_11_1.PAR + nibabel/tests/data/Phantom_EPI_3mm_sag_SENSE_7_1.PAR + nibabel/tests/data/Phantom_EPI_3mm_tra_-30AP_10RL_20FH_SENSE_14_1.PAR + nibabel/tests/data/Phantom_EPI_3mm_tra_15FH_SENSE_9_1.PAR + nibabel/tests/data/Phantom_EPI_3mm_tra_15RL_SENSE_10_1.PAR + nibabel/tests/data/Phantom_EPI_3mm_tra_SENSE_6_1.PAR + +are from http://psydata.ovgu.de/philips_achieva_testfiles, and released under +the PDDL version 1.0 available at http://opendatacommons.org/licenses/pddl/1.0/ + +The files:: + + nibabel/nibabel/tests/data/DTI.PAR + nibabel/nibabel/tests/data/NA.PAR + nibabel/nibabel/tests/data/T1.PAR + nibabel/nibabel/tests/data/T2-interleaved.PAR + nibabel/nibabel/tests/data/T2.PAR + nibabel/nibabel/tests/data/T2_-interleaved.PAR + nibabel/nibabel/tests/data/T2_.PAR + nibabel/nibabel/tests/data/fieldmap.PAR + +are from https://github.com/yarikoptic/nitest-balls1, also released under the +the PDDL version 1.0 available at http://opendatacommons.org/licenses/pddl/1.0/ + + nibabel/nibabel/tests/data/umass_anonymized.PAR + +is courtesy of the University of Massachusetts Medical School, also released +under the PDDL. diff --git a/_sources/manual.rst.txt b/_sources/manual.rst.txt new file mode 100644 index 0000000000..eda7fd75f8 --- /dev/null +++ b/_sources/manual.rst.txt @@ -0,0 +1,16 @@ +.. _manual: + +************** +NiBabel Manual +************** + +.. toctree:: + + installation + gettingstarted + nibabel_images + images_and_memory + nifti_images + image_orientation + legal + changelog diff --git a/_sources/neuro_radio_conventions.rst.txt b/_sources/neuro_radio_conventions.rst.txt new file mode 100644 index 0000000000..a9a51ab2c2 --- /dev/null +++ b/_sources/neuro_radio_conventions.rst.txt @@ -0,0 +1,144 @@ + +######################################## +Radiological vs neurological conventions +######################################## + +It is relatively common to talk about images being in "radiological" compared +to "neurological" convention, but the terms can be used in different and +confusing ways. + +See :doc:`coordinate_systems` for background on voxel space, reference space +and affines. + +************************************************ +Neurological and radiological display convention +************************************************ + +Radiologists like looking at their images with the patient's left on the right +of the image. If they are looking at a brain image, it is as if they were +looking at the brain slice from the point of view of the patient's feet. +Neurologists like looking at brain images with the patient's right on the +right of the image. This perspective is as if the neurologist is looking at +the slice from the top of the patient's head. The convention is one of image +display. The image can have any voxel arrangement on disk or memory, and any +output reference space; it is only necessary for the software displaying the +image to know the reference space and the (probably affine) mapping between +voxel space and reference space; then the software can work out which voxels +are on the left or right of the subject and flip the images to the taste of +the viewer. We could unpack these uses as *neurological display convention* +and *radiological display convention*. + +Here is a very nice graphic by `Chris Rorden`_ showing these display +conventions, where the 3D rendering behind the sections shows the directions +that the neurologist and radiologist are thinking of: + +.. image:: /images/rorden_radio_neuro.jpg + +In the image above, the subject has a stroke in left temporal lobe, causing a +dark area on the MRI. + +********************************* +Alignment of world and voxel axes +********************************* + +As we will see in the next section, radiological and neurological are +sometimes used to refer to particular alignments of the voxel input axes to +scanner RAS+ output axes. If we look at the affine mapping between voxel space +and scanner RAS+, we may find that moving along the first voxel axis by one +unit results in a equivalent scanner RAS+ movement that is mainly left to +right. This can happen with a diagonal 3x3 part of the affine mapping to +scanner RAS+ (see :doc:`coordinate_systems`): + +.. plot:: + :context: + :nofigs: + + >>> import numpy as np + >>> from nibabel.affines import apply_affine + >>> diag_affine = np.array([[3., 0, 0, 0], + ... [0, 3., 0, 0], + ... [0, 0, 4.5, 0], + ... [0, 0, 0, 1]]) + >>> ijk = [1, 0, 0] # moving one unit on the first voxel axis + >>> apply_affine(diag_affine, ijk) + array([3., 0., 0.]) + +In this case the voxel axes are aligned to the output axes, in the sense that +moving in a positive direction on the first voxel axis results in increasing +values on the "R+" output axis, and similarly for the second voxel axis with +output "A+" and the third voxel axis with output "S+". + +Some people therefore refer to this alignment of voxel and RAS+ axes as +*RAS voxel axes*. + +**************************************** +Neurological / radiological voxel layout +**************************************** + +Very confusingly, some people refer to images with RAS voxel axes as having +"neurological" voxel layout. This is because the simplest way to display +slices from this voxel array will result in the left of the subject appearing +towards the left hand side of the screen and therefore neurological display +convention. If we take a slice $k$ over the third axis of the image data array +(``img_data[:, :, k]``), the resulting slice will have a first array axis +going from left to right in terms of spatial position and the second array +axis going from posterior to anterior. If we display this image with the +first axis going from left to right on screen and the second from bottom to +top, it will have the subject's right towards the right of the screen, and +anterior towards the top of the screen, as neurologists like it. Here we are +showing the middle slice of :download:`an image +</downloads/someones_anatomy.nii.gz>` with RAS voxel axes: + +.. plot:: + :context: + + >>> import nibabel as nib + >>> import matplotlib.pyplot as plt + >>> img = nib.load('downloads/someones_anatomy.nii.gz') + >>> # The 3x3 part of the affine is diagonal with all +ve values + >>> img.affine + array([[ 2.75, 0. , 0. , -78. ], + [ 0. , 2.75, 0. , -91. ], + [ 0. , 0. , 2.75, -91. ], + [ 0. , 0. , 0. , 1. ]]) + >>> img_data = img.get_fdata() + >>> a_slice = img_data[:, :, 28] + >>> # Need transpose to put first axis left-right, second bottom-top + >>> plt.imshow(a_slice.T, cmap="gray", origin="lower") # doctest: +SKIP + +This slice does have the voxels from the right of isocenter towards the right +of the screen, neurology style. + +Similarly, an "LAS" alignment of voxel axes to RAS+ axes would result in an +image with the left of the subject towards the right of the screen, as +radiologists like it. "LAS" voxel axes can also be called "radiological" +voxel layout for this reason [#memory-layout]_. + +Over time it has become more common for the scanner to generate images with +almost any orientation of the voxel axes relative to the reference axes. +Maybe for this reason, the terms "radiological" and "neurological" are less +commonly used as applied to voxel layout. We nipyers try to avoid the +terms neurological or radiological for voxel layout because they can make it +harder to separate the idea of voxel and reference space axes and the affine +as a mapping between them. + +.. rubric:: Footnotes + +.. [#memory-layout] We have deliberately not fully defined what we mean by + "voxel layout" in the text. Conceptually, an image array could be stored + in any layout on disk; the definition of the image format specifies how + the image reader should interpret the data on disk to return the right + array value for a given voxel coordinate. The relationship of the values + on disk to the coordinate values in the array has no bearing on the fact + that the voxel axes align to the output axes. In practice the terms RAS / + neurological and LAS / radiogical as applied to voxel layout appear to + refer exclusively to the situation where image arrays are stored in + "Fortran array layout" on disk. Imagine an image array of shape $(I, J, + K)$ with values of length $v$. For an image of 64-bit floating point + values, $v = 8$. An image array is stored in Fortran array layout only if + the value for voxel coordinate (1, 0, 0) is $v$ bytes on disk from the + value for (0, 0, 0); (0, 1, 0) is $I * v$ bytes from (0, 0, 0); and (0, 0, + 1) is $I * J * v$ bytes from (0, 0, 0). Analyze_ and NIfTI_ images use + Fortran array layout. + +.. include:: links_names.txt diff --git a/_sources/nibabel_images.rst.txt b/_sources/nibabel_images.rst.txt new file mode 100644 index 0000000000..dcf7be3300 --- /dev/null +++ b/_sources/nibabel_images.rst.txt @@ -0,0 +1,434 @@ +############## +Nibabel images +############## + +A nibabel image object is the association of three things: + +* an N-D array containing the image *data*; +* a (4, 4) *affine* matrix mapping array coordinates to coordinates in some + RAS+ world coordinate space (:doc:`coordinate_systems`); +* image metadata in the form of a *header*. + +**************** +The image object +**************** + +First we load some libraries we are going to need for the examples: + +.. testsetup:: + + # Work in a temporary directory + import os + import tempfile + pwd = os.getcwd() + tmp_dir = tempfile.mkdtemp() + os.chdir(tmp_dir) + +>>> import os +>>> import numpy as np + +There is an example image in the nibabel distribution. + +>>> from nibabel.testing import data_path +>>> example_file = os.path.join(data_path, 'example4d.nii.gz') + +We load the file to create a nibabel *image object*: + +>>> import nibabel as nib +>>> img = nib.load(example_file) + +The object ``img`` is an instance of a nibabel image. In fact it is an +instance of a nibabel :class:`nibabel.nifti1.Nifti1Image`: + +>>> img +<nibabel.nifti1.Nifti1Image object at ...> + +As with any Python object, you can inspect ``img`` to see what attributes it +has. We recommend using IPython tab completion for this, but here are some +examples of interesting attributes: + +``dataobj`` is the object pointing to the image array data: + +>>> img.dataobj +<nibabel.arrayproxy.ArrayProxy object at ...> + +See :ref:`array-proxies` for more on why this is an array *proxy*. + +``affine`` is the affine array relating array coordinates from the image data +array to coordinates in some RAS+ world coordinate system +(:doc:`coordinate_systems`): + +>>> # Set numpy to print only 2 decimal digits for neatness +>>> np.set_printoptions(precision=2, suppress=True) + +>>> img.affine +array([[ -2. , 0. , 0. , 117.86], + [ -0. , 1.97, -0.36, -35.72], + [ 0. , 0.32, 2.17, -7.25], + [ 0. , 0. , 0. , 1. ]]) + +``header`` contains the metadata for this image. In this case it is +specifically NIfTI metadata: + +>>> img.header +<nibabel.nifti1.Nifti1Header object at ...> + +**************** +The image header +**************** + +The header of an image contains the image metadata. The information in the +header will differ between different image formats. For example, the header +information for a NIfTI1 format file differs from the header information for a +MINC format file. + +Our image is a NIfTI1 format image, and it therefore has a NIfTI1 format +header: + +>>> header = img.header +>>> print(header) # doctest: +SKIP +<class 'nibabel.nifti1.Nifti1Header'> object, endian='<' +sizeof_hdr : 348 +data_type : b'' +db_name : b'' +extents : 0 +session_error : 0 +regular : b'r' +dim_info : 57 +dim : [ 4 128 96 24 2 1 1 1] +intent_p1 : 0.0 +intent_p2 : 0.0 +intent_p3 : 0.0 +intent_code : none +datatype : int16 +bitpix : 16 +slice_start : 0 +pixdim : [ -1. 2. 2. 2.2 2000. 1. 1. 1. ] +vox_offset : 0.0 +scl_slope : nan +scl_inter : nan +slice_end : 23 +slice_code : unknown +xyzt_units : 10 +cal_max : 1162.0 +cal_min : 0.0 +slice_duration : 0.0 +toffset : 0.0 +glmax : 0 +glmin : 0 +descrip : b'FSL3.3\x00 v2.25 NIfTI-1 Single file format' +aux_file : b'' +qform_code : scanner +sform_code : scanner +quatern_b : -1.94510681403e-26 +quatern_c : -0.996708512306 +quatern_d : -0.081068739295 +qoffset_x : 117.855102539 +qoffset_y : -35.7229423523 +qoffset_z : -7.24879837036 +srow_x : [ -2. 0. 0. 117.86] +srow_y : [ -0. 1.97 -0.36 -35.72] +srow_z : [ 0. 0.32 2.17 -7.25] +intent_name : b'' +magic : b'n+1' + +The header of any image will normally have the following methods: + +* ``get_data_shape()`` to get the output shape of the image data array: + + >>> print(header.get_data_shape()) + (128, 96, 24, 2) + +* ``get_data_dtype()`` to get the numpy data type in which the image data is + stored (or will be stored if you save the image): + + >>> print(header.get_data_dtype()) + int16 + +* ``get_zooms()`` to get the voxel sizes in millimeters: + + >>> print(header.get_zooms()) + (2.0, 2.0, 2.19999..., 2000.0) + + The last value of ``header.get_zooms()`` is the time between scans in + milliseconds; this is the equivalent of voxel size on the time axis. + +******************** +The image data array +******************** + +The image data array is a little more complicated, because the image array can +be stored in the image object as a numpy array or stored on disk for you to +access later via an *array proxy*. + +.. _array-proxies: + +Array proxies and proxy images +============================== + +When you load an image from disk, as we did here, the data is likely to be +accessible via an array proxy. An array proxy_ is not the array itself but +something that represents the array, and can provide the array when we ask for +it. + +Our image does have an array proxy, as we have already seen: + +>>> img.dataobj +<nibabel.arrayproxy.ArrayProxy object at ...> + +The array proxy allows us to create the image object without immediately +loading all the array data from disk. + +Images with an array proxy object like this one are called *proxy images* +because the image data is not yet an array, but the array proxy points to +(proxies) the array data on disk. + +You can test if the image has a array proxy like this: + +>>> nib.is_proxy(img.dataobj) +True + +Array images +============ + +We can also create images from numpy arrays. For example: + +>>> array_data = np.arange(24, dtype=np.int16).reshape((2, 3, 4)) +>>> affine = np.diag([1, 2, 3, 1]) +>>> array_img = nib.Nifti1Image(array_data, affine) + +In this case the image array data is already a numpy array, and there is no +version of the array on disk. The ``dataobj`` property of the image is the +array itself rather than a proxy for the array: + +>>> array_img.dataobj +array([[[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]], +<BLANKLINE> + [[12, 13, 14, 15], + [16, 17, 18, 19], + [20, 21, 22, 23]]], dtype=int16) +>>> array_img.dataobj is array_data +True + +``dataobj`` is an array, not an array proxy, so: + +>>> nib.is_proxy(array_img.dataobj) +False + +Getting the image data the easy way +=================================== + +For either type of image (array or proxy) you can always get the data with the +:meth:`get_fdata() <nibabel.spatialimages.SpatialImage.get_fdata>` method. + +For the array image, ``get_fdata()`` just returns the data array, if it's already the required floating point type (default 64-bit float). If it isn't that type, ``get_fdata()`` casts it to one: + +>>> image_data = array_img.get_fdata() +>>> image_data.shape +(2, 3, 4) +>>> image_data.dtype == np.dtype(np.float64) +True + +The cast to floating point means the array is not the one attached to the image: + +>>> image_data is array_img.dataobj +False + +Here's an image backed by a floating point array: + +>>> farray_img = nib.Nifti1Image(image_data.astype(np.float64), affine) +>>> farray_data = farray_img.get_fdata() +>>> farray_data.dtype == np.dtype(np.float64) +True + +There was no cast, so the array returned is exactly the array attached to the +image: + +>>> farray_data is farray_img.dataobj +True + +For the proxy image, the ``get_fdata()`` method fetches the array data from +disk using the proxy, and returns the array. + +>>> image_data = img.get_fdata() +>>> image_data.shape +(128, 96, 24, 2) + +The image ``dataobj`` property is still a proxy object: + +>>> img.dataobj +<nibabel.arrayproxy.ArrayProxy object at ...> + +.. _proxies-caching: + +Proxies and caching +=================== + +You may not want to keep loading the image data off disk every time +you call ``get_fdata()`` on a proxy image. By default, when you call +``get_fdata()`` the first time on a proxy image, the image object keeps a +cached copy of the loaded array. The next time you call ``img.get_fdata()``, +the image returns the array from cache rather than loading it from disk again. + +>>> data_again = img.get_fdata() + +The returned data is the same (cached) copy we returned before: + +>>> data_again is image_data +True + +See :doc:`images_and_memory` for more details on managing image memory and +controlling the image cache. + +.. _image-slicing: + +Image slicing +============= + +At times it is useful to manipulate an image's shape while keeping it in the +same coordinate system. +The ``slicer`` attribute provides an array-slicing interface to produce new +images with an appropriately adjusted header, such that the data at a given +RAS+ location is unchanged. + +>>> cropped_img = img.slicer[32:-32, ...] +>>> cropped_img.shape +(64, 96, 24, 2) + +The data is identical to cropping the data block directly: + +>>> np.array_equal(cropped_img.get_fdata(), img.get_fdata()[32:-32, ...]) +True + +However, unused data did not need to be loaded into memory or scaled. +Additionally, the image affine was adjusted so that the X-translation is +32 voxels (64mm) less: + +>>> cropped_img.affine +array([[ -2. , 0. , 0. , 53.86], + [ -0. , 1.97, -0.36, -35.72], + [ 0. , 0.32, 2.17, -7.25], + [ 0. , 0. , 0. , 1. ]]) + +>>> img.affine - cropped_img.affine +array([[ 0., 0., 0., 64.], + [ 0., 0., 0., 0.], + [ 0., 0., 0., 0.], + [ 0., 0., 0., 0.]]) + +Another use for the slicer object is to choose specific volumes from a +time series: + +>>> vol0 = img.slicer[..., 0] +>>> vol0.shape +(128, 96, 24) + +Or a selection of volumes: + +>>> img.slicer[..., :1].shape +(128, 96, 24, 1) +>>> img.slicer[..., :2].shape +(128, 96, 24, 2) + +It is also possible to use an integer step when slicing, downsampling +the image without filtering. +Note that this *will induce artifacts* in the frequency spectrum +(`aliasing <wikipedia aliasing>`_) along any axis that is down-sampled. + +>>> downsampled = vol0.slicer[::2, ::2, ::2] +>>> downsampled.header.get_zooms() +(4.0, 4.0, 4.399998) + +Finally, an image can be flipped along an axis, maintaining an appropriate +affine matrix: + +>>> nib.orientations.aff2axcodes(img.affine) +('L', 'A', 'S') +>>> ras = img.slicer[::-1] +>>> nib.orientations.aff2axcodes(ras.affine) +('R', 'A', 'S') +>>> ras.affine +array([[ 2. , 0. , 0. , 117.86], + [ 0. , 1.97, -0.36, -35.72], + [ -0. , 0.32, 2.17, -7.25], + [ 0. , 0. , 0. , 1. ]]) + + +****************** +Loading and saving +****************** + +The ``save`` and ``load`` functions in nibabel should do all the work for you: + +>>> nib.save(array_img, 'my_image.nii') +>>> img_again = nib.load('my_image.nii') +>>> img_again.shape +(2, 3, 4) + +You can also use the ``to_filename`` method: + +>>> array_img.to_filename('my_image_again.nii') +>>> img_again = nib.load('my_image_again.nii') +>>> img_again.shape +(2, 3, 4) + +You can get and set the filename with ``get_filename()`` and +``set_filename()``: + +>>> img_again.set_filename('another_image.nii') +>>> img_again.get_filename() +'another_image.nii' + +*************************** +Details of files and images +*************************** + +If an image can be loaded or saved on disk, the image will have an attribute +called ``file_map``. ``img.file_map`` is a dictionary where the keys are the +names of the files that the image uses to load / save on disk, and the values +are ``FileHolder`` objects, that usually contain the filenames that the image +has been loaded from or saved to. In the case of a NiFTI1 single file, this +is just a single image file with a ``.nii`` or ``.nii.gz`` extension: + +>>> list(img_again.file_map) +['image'] +>>> img_again.file_map['image'].filename +'another_image.nii' + +Other file types need more than one file to make up the image. The NiFTI1 +pair type is one example. NIfTI pair images have one file containing the +header information and another containing the image array data: + +>>> pair_img = nib.Nifti1Pair(array_data, np.eye(4)) +>>> nib.save(pair_img, 'my_pair_image.img') +>>> sorted(pair_img.file_map) +['header', 'image'] +>>> pair_img.file_map['header'].filename +'my_pair_image.hdr' +>>> pair_img.file_map['image'].filename +'my_pair_image.img' + +The older Analyze format also has a separate header and image file: + +>>> ana_img = nib.AnalyzeImage(array_data, np.eye(4)) +>>> sorted(ana_img.file_map) +['header', 'image'] + +It is the contents of the ``file_map`` that gets changed when you use +``set_filename`` or ``to_filename``: + +>>> ana_img.set_filename('analyze_image.img') +>>> ana_img.file_map['image'].filename +'analyze_image.img' +>>> ana_img.file_map['header'].filename +'analyze_image.hdr' + +.. testcleanup:: + + os.chdir(pwd) + import shutil + shutil.rmtree(tmp_dir) + +.. include:: links_names.txt diff --git a/_sources/nifti_images.rst.txt b/_sources/nifti_images.rst.txt new file mode 100644 index 0000000000..39625e5c58 --- /dev/null +++ b/_sources/nifti_images.rst.txt @@ -0,0 +1,494 @@ +######################### +Working with NIfTI images +######################### + +This page describes some features of the nibabel implementation of the NIfTI +format. Generally all these features apply equally to the NIfTI 1 and the +NIfTI 2 format, but we will note the differences when they come up. NIfTI 1 +is much more common than NIfTI 2. + +.. testsetup:: + + # Work in a temporary directory + import os + import tempfile + pwd = os.getcwd() + tmp_dir = tempfile.mkdtemp() + os.chdir(tmp_dir) + +************* +Preliminaries +************* + +We first set some display parameters to print out numpy arrays in a compact +form: + +>>> import numpy as np +>>> # Set numpy to print only 2 decimal digits for neatness +>>> np.set_printoptions(precision=2, suppress=True) + +******************** +Example NIfTI images +******************** + +>>> import os +>>> import nibabel as nib +>>> from nibabel.testing import data_path + +This is the example NIfTI 1 image: + +>>> example_ni1 = os.path.join(data_path, 'example4d.nii.gz') +>>> n1_img = nib.load(example_ni1) +>>> n1_img +<nibabel.nifti1.Nifti1Image object at ...> + +Here is the NIfTI 2 example image: + +>>> example_ni2 = os.path.join(data_path, 'example_nifti2.nii.gz') +>>> n2_img = nib.load(example_ni2) +>>> n2_img +<nibabel.nifti2.Nifti2Image object at ...> + +**************** +The NIfTI header +**************** + +The NIfTI 1 header is a small C structure of size 352 bytes. It contains the +following fields: + +>>> n1_header = n1_img.header +>>> print(n1_header) # doctest: +SKIP +<class 'nibabel.nifti1.Nifti1Header'> object, endian='<' +sizeof_hdr : 348 +data_type : b'' +db_name : b'' +extents : 0 +session_error : 0 +regular : b'r' +dim_info : 57 +dim : [ 4 128 96 24 2 1 1 1] +intent_p1 : 0.0 +intent_p2 : 0.0 +intent_p3 : 0.0 +intent_code : none +datatype : int16 +bitpix : 16 +slice_start : 0 +pixdim : [ -1. 2. 2. 2.2 2000. 1. 1. 1. ] +vox_offset : 0.0 +scl_slope : nan +scl_inter : nan +slice_end : 23 +slice_code : unknown +xyzt_units : 10 +cal_max : 1162.0 +cal_min : 0.0 +slice_duration : 0.0 +toffset : 0.0 +glmax : 0 +glmin : 0 +descrip : b'FSL3.3\x00 v2.25 NIfTI-1 Single file format' +aux_file : b'' +qform_code : scanner +sform_code : scanner +quatern_b : -1.94510681403e-26 +quatern_c : -0.996708512306 +quatern_d : -0.081068739295 +qoffset_x : 117.855102539 +qoffset_y : -35.7229423523 +qoffset_z : -7.24879837036 +srow_x : [ -2. 0. 0. 117.86] +srow_y : [ -0. 1.97 -0.36 -35.72] +srow_z : [ 0. 0.32 2.17 -7.25] +intent_name : b'' +magic : b'n+1' + +The NIfTI 2 header is similar, but of length 540 bytes, with fewer fields: + +>>> n2_header = n2_img.header +>>> print(n2_header) # doctest: +SKIP + <class 'nibabel.nifti2.Nifti2Header'> object, endian='<' + sizeof_hdr : 540 + magic : b'n+2' + eol_check : [13 10 26 10] + datatype : int16 + bitpix : 16 + dim : [ 4 32 20 12 2 1 1 1] + intent_p1 : 0.0 + intent_p2 : 0.0 + intent_p3 : 0.0 + pixdim : [ -1. 2. 2. 2.2 2000. 1. 1. 1. ] + vox_offset : 0 + scl_slope : nan + scl_inter : nan + cal_max : 1162.0 + cal_min : 0.0 + slice_duration : 0.0 + toffset : 0.0 + slice_start : 0 + slice_end : 23 + descrip : b'FSL3.3\x00 v2.25 NIfTI-1 Single file format' + aux_file : b'' + qform_code : scanner + sform_code : scanner + quatern_b : -1.94510681403e-26 + quatern_c : -0.996708512306 + quatern_d : -0.081068739295 + qoffset_x : 117.855102539 + qoffset_y : -35.7229423523 + qoffset_z : -7.24879837036 + srow_x : [ -2. 0. 0. 117.86] + srow_y : [ -0. 1.97 -0.36 -35.72] + srow_z : [ 0. 0.32 2.17 -7.25] + slice_code : unknown + xyzt_units : 10 + intent_code : none + intent_name : b'' + dim_info : 57 + unused_str : b'' + +You can get and set individual fields in the header using dict (mapping-type) +item access. For example: + +>>> n1_header['cal_max'] +array(1162., dtype=float32) +>>> n1_header['cal_max'] = 1200 +>>> n1_header['cal_max'] +array(1200., dtype=float32) + +Check the attributes of the header for ``get_`` / ``set_`` methods to get and +set various combinations of NIfTI header fields. + +The ``get_`` / ``set_`` methods should check and apply valid combinations of +values from the header, whereas you can do anything you like with the dict / +mapping item access. It is safer to use the ``get_`` / ``set_`` methods and +use the mapping item access only if the ``get_`` / ``set_`` methods will not +do what you want. + +***************** +The NIfTI affines +***************** + +Like other nibabel image types, NIfTI images have an affine relating the voxel +coordinates to world coordinates in RAS+ space: + +>>> n1_img.affine +array([[ -2. , 0. , 0. , 117.86], + [ -0. , 1.97, -0.36, -35.72], + [ 0. , 0.32, 2.17, -7.25], + [ 0. , 0. , 0. , 1. ]]) + +Unlike other formats, the NIfTI header format can specify this affine in one +of three ways |--| the *sform* affine, the *qform* affine and the *fall-back +header* affine. + +Nibabel uses an :ref:`algorithm <choosing-image-affine>` to chose which of +these three it will use for the overall image ``affine``. + +The sform affine +================ + +The header stores the three first rows of the 4 by 4 affine in the header +fields ``srow_x``, ``srow_y``, ``srow_z``. The header does not store the +fourth row because it is always ``[0, 0, 0, 1]`` (see +:doc:`coordinate_systems`). + +You can get the sform affine specifically with the ``get_sform()`` method of +the image or the header. + +For example: + +>>> print(n1_header['srow_x']) +[ -2. 0. 0. 117.86] +>>> print(n1_header['srow_y']) +[ -0. 1.97 -0.36 -35.72] +>>> print(n1_header['srow_z']) +[ 0. 0.32 2.17 -7.25] +>>> print(n1_header.get_sform()) +[[ -2. 0. 0. 117.86] + [ -0. 1.97 -0.36 -35.72] + [ 0. 0.32 2.17 -7.25] + [ 0. 0. 0. 1. ]] + +This affine is valid only if the ``sform_code`` is not zero. + +>>> print(n1_header['sform_code']) +1 + +The different sform code values specify which RAS+ space the sform affine +refers to, with these interpretations: + +==== ========= =========== +Code Label Meaning +==== ========= =========== +0 unknown sform not defined +1 scanner RAS+ in scanner coordinates +2 aligned RAS+ aligned to some other scan +3 talairach RAS+ in Talairach atlas space +4 mni RAS+ in MNI atlas space +==== ========= =========== + +In our case the code is 1, meaning "scanner" alignment. + +You can get the affine and the code using the ``coded=True`` argument to +``get_sform()``: + +>>> print(n1_header.get_sform(coded=True)) +(array([[ -2. , 0. , 0. , 117.86], + [ -0. , 1.97, -0.36, -35.72], + [ 0. , 0.32, 2.17, -7.25], + [ 0. , 0. , 0. , 1. ]]), 1) + +You can set the sform with the ``set_sform()`` method of the header and +the image. + +>>> n1_header.set_sform(np.diag([2, 3, 4, 1])) +>>> n1_header.get_sform() +array([[2., 0., 0., 0.], + [0., 3., 0., 0.], + [0., 0., 4., 0.], + [0., 0., 0., 1.]]) + +Set the affine and code using the ``code`` parameter to ``set_sform()``: + +>>> n1_header.set_sform(np.diag([3, 4, 5, 1]), code='mni') +>>> n1_header.get_sform(coded=True) +(array([[3., 0., 0., 0.], + [0., 4., 0., 0.], + [0., 0., 5., 0.], + [0., 0., 0., 1.]]), 4) + +The qform affine +================ + +This affine can be calculated from a combination of the voxel sizes (entries 1 +through 4 of the ``pixdim`` field), a sign flip called ``qfac`` stored in +entry 0 of ``pixdim``, and a `quaternion <wikipedia quaternion_>`_ that can be +reconstructed from fields ``quatern_b``, ``quatern_c``, ``quatern_d``. + +See the code for the :meth:`get_qform() method +<nibabel.nifti1.Nifti1Header.get_qform>` for details. + +You can get and set the qform affine using the equivalent methods to those for +the sform: ``get_qform()``, ``set_qform()``. + +>>> n1_header.get_qform(coded=True) +(array([[ -2. , 0. , -0. , 117.86], + [ 0. , 1.97, -0.36, -35.72], + [ 0. , 0.32, 2.17, -7.25], + [ 0. , 0. , 0. , 1. ]]), 1) + +The qform also has a corresponding ``qform_code`` with the same interpretation +as the `sform_code`. + +The fall-back header affine +=========================== + +This is the affine of last resort, constructed only from the ``pixdim`` voxel +sizes. The `NIfTI specification <nifti1>`_ says that this should set the +first voxel in the image as [0, 0, 0] in world coordinates, but we nibabblers +follow SPM_ in preferring to set the central voxel to have [0, 0, 0] world +coordinate. The NIfTI spec also implies that the image should be assumed to be +in RAS+ *voxel* orientation for this affine (see :doc:`coordinate_systems`). +Again like SPM, we prefer to assume LAS+ voxel orientation by default. + +You can always get the fall-back affine with ``get_base_affine()``: + +>>> n1_header.get_base_affine() +array([[ -2. , 0. , 0. , 127. ], + [ 0. , 2. , 0. , -95. ], + [ 0. , 0. , 2.2, -25.3], + [ 0. , 0. , 0. , 1. ]]) + +.. _choosing-image-affine: + +Choosing the image affine +========================= + +Given there are three possible affines defined in the NIfTI header, nibabel +has to chose which of these to use for the image ``affine``. + +The algorithm is defined in the ``get_best_affine()`` method. It is: + +#. If ``sform_code`` != 0 ('unknown') use the sform affine; else +#. If ``qform_code`` != 0 ('unknown') use the qform affine; else +#. Use the fall-back affine. + +.. _default-sform-qform-codes: + +Default sform and qform codes +============================= + +If you create a new image, e.g.: + +>>> data = np.random.random((20, 20, 20)) +>>> xform = np.eye(4) * 2 +>>> img = nib.nifti1.Nifti1Image(data, xform) + +The sform and qform codes will be initialised to 2 (aligned) and 0 (unknown) +respectively: + +>>> img.get_sform(coded=True) # doctest: +NORMALIZE_WHITESPACE +(array([[2., 0., 0., 0.], + [0., 2., 0., 0.], + [0., 0., 2., 0.], + [0., 0., 0., 1.]]), 2) +>>> img.get_qform(coded=True) +(None, 0) + +This is based on the assumption that the affine you specify for a newly +created image will align the image to some known coordinate system. According +to the `NIfTI specification <nifti1>`_, the qform is intended to encode a +transformation into scanner coordinates - for a programmatically created +image, we have no way of knowing what the scanner coordinate system is; +furthermore, the qform cannot be used to store an arbitrary affine transform, +as it is unable to encode shears. So the provided affine will be stored in the +sform, and the qform will be left uninitialised. + +If you create a new image and specify an existing header, e.g.: + +>>> example_ni1 = os.path.join(data_path, 'example4d.nii.gz') +>>> n1_img = nib.load(example_ni1) +>>> new_header = header=n1_img.header.copy() +>>> new_data = np.random.random(n1_img.shape[:3]) +>>> new_img = nib.nifti1.Nifti1Image(data, None, header=new_header) + +then the newly created image will inherit the same sform and qform codes that +are in the provided header. However, if you create a new image with both an +affine and a header specified, e.g.: + +>>> xform = np.eye(4) +>>> new_img = nib.nifti1.Nifti1Image(data, xform, header=new_header) + +then the sform and qform codes will *only* be preserved if the provided affine +is the same as the affine in the provided header. If the affines do not match, +the sform and qform codes will be set to their default values of 2 and 0 +respectively. This is done on the basis that, if you are changing the affine, +you are likely to be changing the space to which the affine is pointing. So +the original sform and qform codes can no longer be assumed to be valid. + +If you wish to set the sform and qform affines and/or codes to some other +value, you can always set them after creation using the ``set_sform`` and +``set_qform`` methods, as described above. + +************ +Data scaling +************ + +NIfTI uses a simple scheme for data scaling. + +By default, nibabel will take care of this scaling for you, but there may be +times that you want to control the data scaling yourself. If so, the next +section describes how the scaling works and the nibabel implementation of +same. + +There are two scaling fields in the header called ``scl_slope`` and +``scl_inter``. + +The output data from a NIfTI image comes from: + +#. Loading the binary data from the image file; +#. Casting the numbers to the binary format given in the header and returned + by ``get_data_dtype()``; +#. Reshaping to the output image shape; +#. Multiplying the result by the header ``scl_slope`` value, if + both of ``scl_slope`` and ``scl_inter`` are defined; +#. Adding the value header ``scl_inter`` value to the result, if both of + ``scl_slope`` and ``scl_inter`` are defined; + +'Defined' means, the value is not NaN (not a number). + +All this gets built into the array proxy when you load a NIfTI image. + +When you load an image, the header scaling values automatically get set to NaN +(undefined) to mark the fact that the scaling values have been consumed by the +read. The scaling values read from the header on load only appear in the +array proxy object. + +To see how this works, let's make a new image with some scaling: + +>>> array_data = np.arange(24, dtype=np.int16).reshape((2, 3, 4)) +>>> affine = np.diag([1, 2, 3, 1]) +>>> array_img = nib.Nifti1Image(array_data, affine) +>>> array_header = array_img.header + +The default scaling values are NaN (undefined): + +>>> array_header['scl_slope'] +array(nan, dtype=float32) +>>> array_header['scl_inter'] +array(nan, dtype=float32) + +You can get the scaling values with the ``get_slope_inter()`` method: + +>>> array_header.get_slope_inter() +(None, None) + +None corresponds to the NaN scaling value (undefined). + +We can set them in the image header, so they get saved to the header when the +image is written. We can do this by setting the fields directly, or with +``set_slope_inter()``: + +>>> array_header.set_slope_inter(2, 10) +>>> array_header.get_slope_inter() +(2.0, 10.0) +>>> array_header['scl_slope'] +array(2., dtype=float32) +>>> array_header['scl_inter'] +array(10., dtype=float32) + +Setting the scale factors in the header has no effect on the image data before +we save and load again: + +>>> array_img.get_fdata() +array([[[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.]], +<BLANKLINE> + [[12., 13., 14., 15.], + [16., 17., 18., 19.], + [20., 21., 22., 23.]]]) + +Now we save the image and load it again: + +>>> nib.save(array_img, 'scaled_image.nii') +>>> scaled_img = nib.load('scaled_image.nii') + +The data array has the scaling applied: + +>>> scaled_img.get_fdata() +array([[[10., 12., 14., 16.], + [18., 20., 22., 24.], + [26., 28., 30., 32.]], +<BLANKLINE> + [[34., 36., 38., 40.], + [42., 44., 46., 48.], + [50., 52., 54., 56.]]]) + +The header for the loaded image has had the scaling reset to undefined, to +mark the fact that the scaling has been "consumed" by the load: + +>>> scaled_img.header.get_slope_inter() +(None, None) + +The original slope and intercept are still accessible in the array proxy +object: + +>>> scaled_img.dataobj.slope +2.0 +>>> scaled_img.dataobj.inter +10.0 + +If the header scaling is undefined when we save the image, nibabel will try to +find an optimum slope and intercept to best preserve the precision of the data +in the output data type. Because nibabel will set the scaling to undefined +when loading the image, or creating a new image, this is the default behavior. + +.. testcleanup:: + + os.chdir(pwd) + import shutil + shutil.rmtree(tmp_dir) + +.. include:: links_names.txt diff --git a/_sources/notebooks/index.rst.txt b/_sources/notebooks/index.rst.txt new file mode 100644 index 0000000000..538be3b0ee --- /dev/null +++ b/_sources/notebooks/index.rst.txt @@ -0,0 +1,16 @@ +.. _notebooks: + +##################################### +IPython notebooks for Nibabel project +##################################### + +***************************** +Rotation matrix orthogonality +***************************** + +See :download:`ATA error calculations <ata_error.ipynb>` and :download:`Cross +product error <cross_product_error.ipynb>`. You can use the `IPython notebook +viewer`_ to view these files; copy the URL and paste into the Notebook viewer +URL box. + +.. include:: ../links_names.txt diff --git a/_sources/old/ioimplementation.rst.txt b/_sources/old/ioimplementation.rst.txt new file mode 100644 index 0000000000..fd7914f467 --- /dev/null +++ b/_sources/old/ioimplementation.rst.txt @@ -0,0 +1,128 @@ +.. -*- mode: rst -*- + +:orphan: + +################################################## +Relationship between images and io implementations +################################################## + +******************** +Summary and sign-off +******************** + +These were some meditations about splitting the image into two API parts. + +The first part would be the lower level IO implementation. This part is +rather like a fusion of the :class:`.Header` and :class:`.ArrayProxy` objects +in current nibabel. It takes care of lower level details like i/o data dtype, +shape, offset, and it might help with slicing to get the data. On top of that +would be a high level interface implementing ``load``, ``save``, ``filename``, +``data``. The top-level image also had the novel idea of a ``mode`` parameter +which, if ``'r'``, would raise an error on attempting to ``save``. + +****** +Images +****** + +An image houses the association of the: + +* data array +* affine +* output space +* metadata +* mode + +These are straightforward attributes, and have no necessary relationship +to stuff on disk. + +By ''disk'', we mean, file-like objects - not necessarily on disk. + +The *io implementation* manages the relationship of images and stuff on +disk. + +Specifically, it manages ``load`` of images from disk, and ``save`` of +images to disk. + +The user does not see the io implementation unless they ask to. In +standard use of images they will not need to do this. + +****************** +IO implementations +****************** + +By use case. + +:: + + Creating array image, saving + + >>> import tempfile + >>> from nibabel.images import Image + >>> from nibabel import load, save + >>> fp, fname = tempfile.mkstemp('.nii') + >>> data = np.arange(24).reshape((2,3,4)) + >>> img = Image(data) + >>> img.filename is None + True + >>> img.save() + Traceback (most recent call last): + ... + ImageError: no filespec to save to + >>> save(img) + Traceback (most recent call last): + ... + ImageError: no filespec to save to + >>> img2 = save(img, 'some_image.nii') # type guessed from filename + >>> img2.filename == fname + True + >>> img.filename is None # still + True + >>> img.filename = 'some_filename.nii' # read only property + Traceback (most recent call last): + ... + AttributeError: can't set attribute + + Load, futz, save + + >>> img3 = load(fname, mode='r') + >>> img3.filename == fname + True + >>> np.all(img3.data == data) + True + >>> img3.data[0,0] = 99 + >>> img3.save() + Traceback (most recent call last): + ... + ImageError: trying to write to read only image + >>> img3.mode = 'rw' + >>> img3.save() + >>> load(img4) + >>> img4.mode # 'r' is the default + 'r' + >>> mod_data = data.copy() + >>> mod_data[0,0] = 99 + >>> np.all(img4.data = mod_data) + True + + Prepare image for later writing + + >>> img5 = Image(np.zeros(2,3,4)) + >>> fp, fname2 = tempfile.mkstemp('.nii') + >>> img5.set_filespec(fname2) + >>> # then do some things to the image + >>> img5.save() + + This is an example where you do need the io API + + >>> from nibabel.ioimps import guessed_imp + >>> fp, fname3 = tempfile.mkstemp('.nii') + >>> ioimp = guessed_imp(fname3) + >>> ioimp.set_data_dtype(np.float64) + >>> ioimp.set_data_shape((2,3,4)) # set_data_shape method + >>> slice_def = (slice(None), slice(None), 0) + >>> ioimp.write_slice(data[slice_def], slice_def) # write_slice method + >>> slice_def = (2, 3, 1) + >>> ioimp.write_slice(data[slice_def], slice_def) # write_slice method + Traceback (most recent call last): + ... + ImageIOError: data write is not contiguous diff --git a/_sources/reference/index.rst.txt b/_sources/reference/index.rst.txt new file mode 100644 index 0000000000..f33bc46ba8 --- /dev/null +++ b/_sources/reference/index.rst.txt @@ -0,0 +1,67 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +API Reference +============= + +.. toctree:: + + nibabel.rst + nibabel._compression.rst + nibabel.affines.rst + nibabel.analyze.rst + nibabel.arrayproxy.rst + nibabel.arraywriters.rst + nibabel.batteryrunners.rst + nibabel.benchmarks.rst + nibabel.brikhead.rst + nibabel.caret.rst + nibabel.casting.rst + nibabel.cifti2.rst + nibabel.cmdline.rst + nibabel.data.rst + nibabel.dataobj_images.rst + nibabel.deprecated.rst + nibabel.deprecator.rst + nibabel.dft.rst + nibabel.ecat.rst + nibabel.environment.rst + nibabel.eulerangles.rst + nibabel.filebasedimages.rst + nibabel.fileholders.rst + nibabel.filename_parser.rst + nibabel.fileslice.rst + nibabel.fileutils.rst + nibabel.freesurfer.rst + nibabel.funcs.rst + nibabel.gifti.rst + nibabel.imageclasses.rst + nibabel.imageglobals.rst + nibabel.imagestats.rst + nibabel.loadsave.rst + nibabel.minc1.rst + nibabel.minc2.rst + nibabel.mriutils.rst + nibabel.nicom.rst + nibabel.nifti1.rst + nibabel.nifti2.rst + nibabel.onetime.rst + nibabel.openers.rst + nibabel.optpkg.rst + nibabel.orientations.rst + nibabel.parrec.rst + nibabel.pointset.rst + nibabel.processing.rst + nibabel.pydicom_compat.rst + nibabel.quaternions.rst + nibabel.rstutils.rst + nibabel.spaces.rst + nibabel.spatialimages.rst + nibabel.spm2analyze.rst + nibabel.spm99analyze.rst + nibabel.streamlines.rst + nibabel.tmpdirs.rst + nibabel.tripwire.rst + nibabel.viewers.rst + nibabel.volumeutils.rst + nibabel.wrapstruct.rst + nibabel.xmlutils.rst diff --git a/_sources/reference/nibabel._compression.rst.txt b/_sources/reference/nibabel._compression.rst.txt new file mode 100644 index 0000000000..9f5e27d051 --- /dev/null +++ b/_sources/reference/nibabel._compression.rst.txt @@ -0,0 +1,13 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`_compression` +=================== +.. automodule:: nibabel._compression + +.. currentmodule:: nibabel._compression +.. autosummary:: + + + +.. currentmodule:: nibabel._compression + diff --git a/_sources/reference/nibabel.affines.rst.txt b/_sources/reference/nibabel.affines.rst.txt new file mode 100644 index 0000000000..938f3bc0a0 --- /dev/null +++ b/_sources/reference/nibabel.affines.rst.txt @@ -0,0 +1,74 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`affines` +============== +.. automodule:: nibabel.affines + +.. currentmodule:: nibabel.affines +.. autosummary:: + + AffineError + append_diag + apply_affine + dot_reduce + from_matvec + obliquity + rescale_affine + to_matvec + voxel_sizes + + +.. currentmodule:: nibabel.affines + + +:class:`AffineError` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: AffineError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +append_diag +~~~~~~~~~~~ + +.. autofunction:: append_diag + +apply_affine +~~~~~~~~~~~~ + +.. autofunction:: apply_affine + +dot_reduce +~~~~~~~~~~ + +.. autofunction:: dot_reduce + +from_matvec +~~~~~~~~~~~ + +.. autofunction:: from_matvec + +obliquity +~~~~~~~~~ + +.. autofunction:: obliquity + +rescale_affine +~~~~~~~~~~~~~~ + +.. autofunction:: rescale_affine + +to_matvec +~~~~~~~~~ + +.. autofunction:: to_matvec + +voxel_sizes +~~~~~~~~~~~ + +.. autofunction:: voxel_sizes + diff --git a/_sources/reference/nibabel.analyze.rst.txt b/_sources/reference/nibabel.analyze.rst.txt new file mode 100644 index 0000000000..3668e1fc49 --- /dev/null +++ b/_sources/reference/nibabel.analyze.rst.txt @@ -0,0 +1,39 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`analyze` +============== +.. automodule:: nibabel.analyze + +.. currentmodule:: nibabel.analyze +.. autosummary:: + + AnalyzeHeader + AnalyzeImage + + +.. currentmodule:: nibabel.analyze + + +:class:`AnalyzeHeader` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: AnalyzeHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`AnalyzeImage` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: AnalyzeImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.arrayproxy.rst.txt b/_sources/reference/nibabel.arrayproxy.rst.txt new file mode 100644 index 0000000000..0a0d9302e1 --- /dev/null +++ b/_sources/reference/nibabel.arrayproxy.rst.txt @@ -0,0 +1,57 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`arrayproxy` +================= +.. automodule:: nibabel.arrayproxy + +.. currentmodule:: nibabel.arrayproxy +.. autosummary:: + + ArrayLike + ArrayProxy + get_obj_dtype + is_proxy + reshape_dataobj + + +.. currentmodule:: nibabel.arrayproxy + + +:class:`ArrayLike` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ArrayLike + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ArrayProxy` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ArrayProxy + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +get_obj_dtype +~~~~~~~~~~~~~ + +.. autofunction:: get_obj_dtype + +is_proxy +~~~~~~~~ + +.. autofunction:: is_proxy + +reshape_dataobj +~~~~~~~~~~~~~~~ + +.. autofunction:: reshape_dataobj + diff --git a/_sources/reference/nibabel.arraywriters.rst.txt b/_sources/reference/nibabel.arraywriters.rst.txt new file mode 100644 index 0000000000..2955ce2225 --- /dev/null +++ b/_sources/reference/nibabel.arraywriters.rst.txt @@ -0,0 +1,90 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`arraywriters` +=================== +.. automodule:: nibabel.arraywriters + +.. currentmodule:: nibabel.arraywriters +.. autosummary:: + + ArrayWriter + ScalingError + SlopeArrayWriter + SlopeInterArrayWriter + WriterError + get_slope_inter + make_array_writer + + +.. currentmodule:: nibabel.arraywriters + + +:class:`ArrayWriter` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ArrayWriter + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ScalingError` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ScalingError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SlopeArrayWriter` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SlopeArrayWriter + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SlopeInterArrayWriter` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SlopeInterArrayWriter + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`WriterError` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: WriterError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +get_slope_inter +~~~~~~~~~~~~~~~ + +.. autofunction:: get_slope_inter + +make_array_writer +~~~~~~~~~~~~~~~~~ + +.. autofunction:: make_array_writer + diff --git a/_sources/reference/nibabel.batteryrunners.rst.txt b/_sources/reference/nibabel.batteryrunners.rst.txt new file mode 100644 index 0000000000..238ffca2da --- /dev/null +++ b/_sources/reference/nibabel.batteryrunners.rst.txt @@ -0,0 +1,39 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`batteryrunners` +===================== +.. automodule:: nibabel.batteryrunners + +.. currentmodule:: nibabel.batteryrunners +.. autosummary:: + + BatteryRunner + Report + + +.. currentmodule:: nibabel.batteryrunners + + +:class:`BatteryRunner` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: BatteryRunner + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Report` +~~~~~~~~~~~~~~~ + + +.. autoclass:: Report + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.benchmarks.rst.txt b/_sources/reference/nibabel.benchmarks.rst.txt new file mode 100644 index 0000000000..9b6a516f68 --- /dev/null +++ b/_sources/reference/nibabel.benchmarks.rst.txt @@ -0,0 +1,133 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`benchmarks` +================= +.. automodule:: nibabel.benchmarks + +.. currentmodule:: nibabel.benchmarks +.. autosummary:: + + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`benchmarks.bench_array_to_file` +--------------------------------------------- +.. automodule:: nibabel.benchmarks.bench_array_to_file + +.. currentmodule:: nibabel.benchmarks.bench_array_to_file +.. autosummary:: + + bench_array_to_file + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`benchmarks.bench_arrayproxy_slicing` +-------------------------------------------------- +.. automodule:: nibabel.benchmarks.bench_arrayproxy_slicing + +.. currentmodule:: nibabel.benchmarks.bench_arrayproxy_slicing +.. autosummary:: + + bench_arrayproxy_slicing + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`benchmarks.bench_fileslice` +----------------------------------------- +.. automodule:: nibabel.benchmarks.bench_fileslice + +.. currentmodule:: nibabel.benchmarks.bench_fileslice +.. autosummary:: + + bench_fileslice + run_slices + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`benchmarks.bench_finite_range` +-------------------------------------------- +.. automodule:: nibabel.benchmarks.bench_finite_range + +.. currentmodule:: nibabel.benchmarks.bench_finite_range +.. autosummary:: + + bench_finite_range + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`benchmarks.bench_load_save` +----------------------------------------- +.. automodule:: nibabel.benchmarks.bench_load_save + +.. currentmodule:: nibabel.benchmarks.bench_load_save +.. autosummary:: + + bench_load_save + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`benchmarks.butils` +-------------------------------- +.. automodule:: nibabel.benchmarks.butils + +.. currentmodule:: nibabel.benchmarks.butils +.. autosummary:: + + print_git_title + + +.. currentmodule:: nibabel.benchmarks + + +.. currentmodule:: nibabel.benchmarks.bench_array_to_file + +bench_array_to_file +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: bench_array_to_file + + +.. currentmodule:: nibabel.benchmarks.bench_arrayproxy_slicing + +bench_arrayproxy_slicing +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: bench_arrayproxy_slicing + + +.. currentmodule:: nibabel.benchmarks.bench_fileslice + +bench_fileslice +~~~~~~~~~~~~~~~ + +.. autofunction:: bench_fileslice + +run_slices +~~~~~~~~~~ + +.. autofunction:: run_slices + + +.. currentmodule:: nibabel.benchmarks.bench_finite_range + +bench_finite_range +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: bench_finite_range + + +.. currentmodule:: nibabel.benchmarks.bench_load_save + +bench_load_save +~~~~~~~~~~~~~~~ + +.. autofunction:: bench_load_save + + +.. currentmodule:: nibabel.benchmarks.butils + +print_git_title +~~~~~~~~~~~~~~~ + +.. autofunction:: print_git_title + diff --git a/_sources/reference/nibabel.brikhead.rst.txt b/_sources/reference/nibabel.brikhead.rst.txt new file mode 100644 index 0000000000..3c2143f099 --- /dev/null +++ b/_sources/reference/nibabel.brikhead.rst.txt @@ -0,0 +1,84 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`brikhead` +=============== +.. automodule:: nibabel.brikhead + +.. currentmodule:: nibabel.brikhead +.. autosummary:: + + AFNIArrayProxy + AFNIHeader + AFNIHeaderError + AFNIImage + AFNIImageError + parse_AFNI_header + + +.. currentmodule:: nibabel.brikhead + + +:class:`AFNIArrayProxy` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: AFNIArrayProxy + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`AFNIHeader` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: AFNIHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`AFNIHeaderError` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: AFNIHeaderError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`AFNIImage` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: AFNIImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`AFNIImageError` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: AFNIImageError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +parse_AFNI_header +~~~~~~~~~~~~~~~~~ + +.. autofunction:: parse_AFNI_header + diff --git a/_sources/reference/nibabel.caret.rst.txt b/_sources/reference/nibabel.caret.rst.txt new file mode 100644 index 0000000000..d955ba66b7 --- /dev/null +++ b/_sources/reference/nibabel.caret.rst.txt @@ -0,0 +1,26 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`caret` +============ +.. automodule:: nibabel.caret + +.. currentmodule:: nibabel.caret +.. autosummary:: + + CaretMetaData + + +.. currentmodule:: nibabel.caret + + +:class:`CaretMetaData` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: CaretMetaData + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.casting.rst.txt b/_sources/reference/nibabel.casting.rst.txt new file mode 100644 index 0000000000..0e1225f753 --- /dev/null +++ b/_sources/reference/nibabel.casting.rst.txt @@ -0,0 +1,141 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`casting` +============== +.. automodule:: nibabel.casting + +.. currentmodule:: nibabel.casting +.. autosummary:: + + CastingError + FloatingError + able_int_type + as_int + best_float + ceil_exact + float_to_int + floor_exact + floor_log2 + have_binary128 + int_abs + int_to_float + longdouble_lte_float64 + longdouble_precision_improved + ok_floats + on_powerpc + shared_range + type_info + ulp + + +.. currentmodule:: nibabel.casting + + +:class:`CastingError` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: CastingError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`FloatingError` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: FloatingError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +able_int_type +~~~~~~~~~~~~~ + +.. autofunction:: able_int_type + +as_int +~~~~~~ + +.. autofunction:: as_int + +best_float +~~~~~~~~~~ + +.. autofunction:: best_float + +ceil_exact +~~~~~~~~~~ + +.. autofunction:: ceil_exact + +float_to_int +~~~~~~~~~~~~ + +.. autofunction:: float_to_int + +floor_exact +~~~~~~~~~~~ + +.. autofunction:: floor_exact + +floor_log2 +~~~~~~~~~~ + +.. autofunction:: floor_log2 + +have_binary128 +~~~~~~~~~~~~~~ + +.. autofunction:: have_binary128 + +int_abs +~~~~~~~ + +.. autofunction:: int_abs + +int_to_float +~~~~~~~~~~~~ + +.. autofunction:: int_to_float + +longdouble_lte_float64 +~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: longdouble_lte_float64 + +longdouble_precision_improved +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: longdouble_precision_improved + +ok_floats +~~~~~~~~~ + +.. autofunction:: ok_floats + +on_powerpc +~~~~~~~~~~ + +.. autofunction:: on_powerpc + +shared_range +~~~~~~~~~~~~ + +.. autofunction:: shared_range + +type_info +~~~~~~~~~ + +.. autofunction:: type_info + +ulp +~~~ + +.. autofunction:: ulp + diff --git a/_sources/reference/nibabel.cifti2.rst.txt b/_sources/reference/nibabel.cifti2.rst.txt new file mode 100644 index 0000000000..d900edf1b8 --- /dev/null +++ b/_sources/reference/nibabel.cifti2.rst.txt @@ -0,0 +1,402 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`cifti2` +============= +.. automodule:: nibabel.cifti2 + +.. currentmodule:: nibabel.cifti2 +.. autosummary:: + + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cifti2.cifti2` +---------------------------- +.. automodule:: nibabel.cifti2.cifti2 + +.. currentmodule:: nibabel.cifti2.cifti2 +.. autosummary:: + + Cifti2BrainModel + Cifti2Header + Cifti2HeaderError + Cifti2Image + Cifti2Label + Cifti2LabelTable + Cifti2Matrix + Cifti2MatrixIndicesMap + Cifti2MetaData + Cifti2NamedMap + Cifti2Parcel + Cifti2Surface + Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ + Cifti2VertexIndices + Cifti2Vertices + Cifti2Volume + Cifti2VoxelIndicesIJK + LimitedNifti2Header + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cifti2.cifti2_axes` +--------------------------------- +.. automodule:: nibabel.cifti2.cifti2_axes + +.. currentmodule:: nibabel.cifti2.cifti2_axes +.. autosummary:: + + Axis + BrainModelAxis + LabelAxis + ParcelsAxis + ScalarAxis + SeriesAxis + from_index_mapping + to_header + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cifti2.parse_cifti2` +---------------------------------- +.. automodule:: nibabel.cifti2.parse_cifti2 + +.. currentmodule:: nibabel.cifti2.parse_cifti2 +.. autosummary:: + + Cifti2Extension + Cifti2Parser + + +.. currentmodule:: nibabel.cifti2 + + +.. currentmodule:: nibabel.cifti2.cifti2 + + +:class:`Cifti2BrainModel` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2BrainModel + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2Header` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Header + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2HeaderError` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2HeaderError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2Image` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Image + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2Label` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Label + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2LabelTable` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2LabelTable + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2Matrix` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Matrix + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2MatrixIndicesMap` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2MatrixIndicesMap + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2MetaData` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2MetaData + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2NamedMap` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2NamedMap + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2Parcel` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Parcel + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2Surface` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Surface + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2VertexIndices` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2VertexIndices + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2Vertices` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Vertices + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2Volume` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Volume + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2VoxelIndicesIJK` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2VoxelIndicesIJK + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`LimitedNifti2Header` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: LimitedNifti2Header + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +.. currentmodule:: nibabel.cifti2.cifti2_axes + + +:class:`Axis` +~~~~~~~~~~~~~ + + +.. autoclass:: Axis + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`BrainModelAxis` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: BrainModelAxis + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`LabelAxis` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: LabelAxis + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ParcelsAxis` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ParcelsAxis + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ScalarAxis` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ScalarAxis + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SeriesAxis` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SeriesAxis + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +from_index_mapping +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: from_index_mapping + +to_header +~~~~~~~~~ + +.. autofunction:: to_header + + +.. currentmodule:: nibabel.cifti2.parse_cifti2 + + +:class:`Cifti2Extension` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Extension + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Cifti2Parser` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Cifti2Parser + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.cmdline.rst.txt b/_sources/reference/nibabel.cmdline.rst.txt new file mode 100644 index 0000000000..94d2526798 --- /dev/null +++ b/_sources/reference/nibabel.cmdline.rst.txt @@ -0,0 +1,425 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`cmdline` +============== +.. automodule:: nibabel.cmdline + +.. currentmodule:: nibabel.cmdline +.. autosummary:: + + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.conform` +------------------------------ +.. automodule:: nibabel.cmdline.conform + +.. currentmodule:: nibabel.cmdline.conform +.. autosummary:: + + main + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.convert` +------------------------------ +.. automodule:: nibabel.cmdline.convert + +.. currentmodule:: nibabel.cmdline.convert +.. autosummary:: + + main + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.dicomfs` +------------------------------ +.. automodule:: nibabel.cmdline.dicomfs + +.. currentmodule:: nibabel.cmdline.dicomfs +.. autosummary:: + + DICOMFS + FileHandle + dummy_fuse + fuse + get_opt_parser + main + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.diff` +--------------------------- +.. automodule:: nibabel.cmdline.diff + +.. currentmodule:: nibabel.cmdline.diff +.. autosummary:: + + are_values_different + diff + display_diff + get_data_diff + get_data_hash_diff + get_headers_diff + get_opt_parser + main + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.ls` +------------------------- +.. automodule:: nibabel.cmdline.ls + +.. currentmodule:: nibabel.cmdline.ls +.. autosummary:: + + get_opt_parser + main + proc_file + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.nifti_dx` +------------------------------- +.. automodule:: nibabel.cmdline.nifti_dx + +.. currentmodule:: nibabel.cmdline.nifti_dx +.. autosummary:: + + main + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.parrec2nii` +--------------------------------- +.. automodule:: nibabel.cmdline.parrec2nii + +.. currentmodule:: nibabel.cmdline.parrec2nii +.. autosummary:: + + error + get_opt_parser + main + proc_file + verbose + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.roi` +-------------------------- +.. automodule:: nibabel.cmdline.roi + +.. currentmodule:: nibabel.cmdline.roi +.. autosummary:: + + lossless_slice + main + parse_slice + sanitize + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.stats` +---------------------------- +.. automodule:: nibabel.cmdline.stats + +.. currentmodule:: nibabel.cmdline.stats +.. autosummary:: + + main + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.tck2trk` +------------------------------ +.. automodule:: nibabel.cmdline.tck2trk + +.. currentmodule:: nibabel.cmdline.tck2trk +.. autosummary:: + + main + parse_args + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.trk2tck` +------------------------------ +.. automodule:: nibabel.cmdline.trk2tck + +.. currentmodule:: nibabel.cmdline.trk2tck +.. autosummary:: + + main + parse_args + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`cmdline.utils` +---------------------------- +.. automodule:: nibabel.cmdline.utils + +.. currentmodule:: nibabel.cmdline.utils +.. autosummary:: + + ap + safe_get + table2string + verbose + + +.. currentmodule:: nibabel.cmdline + + +.. currentmodule:: nibabel.cmdline.conform + +main +~~~~ + +.. autofunction:: main + + +.. currentmodule:: nibabel.cmdline.convert + +main +~~~~ + +.. autofunction:: main + + +.. currentmodule:: nibabel.cmdline.dicomfs + + +:class:`DICOMFS` +~~~~~~~~~~~~~~~~ + + +.. autoclass:: DICOMFS + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`FileHandle` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: FileHandle + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`dummy_fuse` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: dummy_fuse + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`fuse` +~~~~~~~~~~~~~ + + +.. autoclass:: fuse + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +get_opt_parser +~~~~~~~~~~~~~~ + +.. autofunction:: get_opt_parser + +main +~~~~ + +.. autofunction:: main + + +.. currentmodule:: nibabel.cmdline.diff + +are_values_different +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: are_values_different + +diff +~~~~ + +.. autofunction:: diff + +display_diff +~~~~~~~~~~~~ + +.. autofunction:: display_diff + +get_data_diff +~~~~~~~~~~~~~ + +.. autofunction:: get_data_diff + +get_data_hash_diff +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: get_data_hash_diff + +get_headers_diff +~~~~~~~~~~~~~~~~ + +.. autofunction:: get_headers_diff + +get_opt_parser +~~~~~~~~~~~~~~ + +.. autofunction:: get_opt_parser + +main +~~~~ + +.. autofunction:: main + + +.. currentmodule:: nibabel.cmdline.ls + +get_opt_parser +~~~~~~~~~~~~~~ + +.. autofunction:: get_opt_parser + +main +~~~~ + +.. autofunction:: main + +proc_file +~~~~~~~~~ + +.. autofunction:: proc_file + + +.. currentmodule:: nibabel.cmdline.nifti_dx + +main +~~~~ + +.. autofunction:: main + + +.. currentmodule:: nibabel.cmdline.parrec2nii + +error +~~~~~ + +.. autofunction:: error + +get_opt_parser +~~~~~~~~~~~~~~ + +.. autofunction:: get_opt_parser + +main +~~~~ + +.. autofunction:: main + +proc_file +~~~~~~~~~ + +.. autofunction:: proc_file + +verbose +~~~~~~~ + +.. autofunction:: verbose + + +.. currentmodule:: nibabel.cmdline.roi + +lossless_slice +~~~~~~~~~~~~~~ + +.. autofunction:: lossless_slice + +main +~~~~ + +.. autofunction:: main + +parse_slice +~~~~~~~~~~~ + +.. autofunction:: parse_slice + +sanitize +~~~~~~~~ + +.. autofunction:: sanitize + + +.. currentmodule:: nibabel.cmdline.stats + +main +~~~~ + +.. autofunction:: main + + +.. currentmodule:: nibabel.cmdline.tck2trk + +main +~~~~ + +.. autofunction:: main + +parse_args +~~~~~~~~~~ + +.. autofunction:: parse_args + + +.. currentmodule:: nibabel.cmdline.trk2tck + +main +~~~~ + +.. autofunction:: main + +parse_args +~~~~~~~~~~ + +.. autofunction:: parse_args + + +.. currentmodule:: nibabel.cmdline.utils + +ap +~~ + +.. autofunction:: ap + +safe_get +~~~~~~~~ + +.. autofunction:: safe_get + +table2string +~~~~~~~~~~~~ + +.. autofunction:: table2string + +verbose +~~~~~~~ + +.. autofunction:: verbose + diff --git a/_sources/reference/nibabel.data.rst.txt b/_sources/reference/nibabel.data.rst.txt new file mode 100644 index 0000000000..c8e689c639 --- /dev/null +++ b/_sources/reference/nibabel.data.rst.txt @@ -0,0 +1,102 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`data` +=========== +.. automodule:: nibabel.data + +.. currentmodule:: nibabel.data +.. autosummary:: + + Bomber + BomberError + DataError + Datasource + VersionedDatasource + datasource_or_bomber + find_data_dir + get_data_path + make_datasource + + +.. currentmodule:: nibabel.data + + +:class:`Bomber` +~~~~~~~~~~~~~~~ + + +.. autoclass:: Bomber + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`BomberError` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: BomberError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`DataError` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: DataError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Datasource` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Datasource + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`VersionedDatasource` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: VersionedDatasource + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +datasource_or_bomber +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: datasource_or_bomber + +find_data_dir +~~~~~~~~~~~~~ + +.. autofunction:: find_data_dir + +get_data_path +~~~~~~~~~~~~~ + +.. autofunction:: get_data_path + +make_datasource +~~~~~~~~~~~~~~~ + +.. autofunction:: make_datasource + diff --git a/_sources/reference/nibabel.dataobj_images.rst.txt b/_sources/reference/nibabel.dataobj_images.rst.txt new file mode 100644 index 0000000000..bda68d7c53 --- /dev/null +++ b/_sources/reference/nibabel.dataobj_images.rst.txt @@ -0,0 +1,26 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`dataobj_images` +===================== +.. automodule:: nibabel.dataobj_images + +.. currentmodule:: nibabel.dataobj_images +.. autosummary:: + + DataobjImage + + +.. currentmodule:: nibabel.dataobj_images + + +:class:`DataobjImage` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: DataobjImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.deprecated.rst.txt b/_sources/reference/nibabel.deprecated.rst.txt new file mode 100644 index 0000000000..9b45620fcf --- /dev/null +++ b/_sources/reference/nibabel.deprecated.rst.txt @@ -0,0 +1,58 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`deprecated` +================= +.. automodule:: nibabel.deprecated + +.. currentmodule:: nibabel.deprecated +.. autosummary:: + + FutureWarningMixin + ModuleProxy + VisibleDeprecationWarning + alert_future_error + + +.. currentmodule:: nibabel.deprecated + + +:class:`FutureWarningMixin` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: FutureWarningMixin + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ModuleProxy` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ModuleProxy + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`VisibleDeprecationWarning` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: VisibleDeprecationWarning + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +alert_future_error +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: alert_future_error + diff --git a/_sources/reference/nibabel.deprecator.rst.txt b/_sources/reference/nibabel.deprecator.rst.txt new file mode 100644 index 0000000000..3cb5d5c9e7 --- /dev/null +++ b/_sources/reference/nibabel.deprecator.rst.txt @@ -0,0 +1,39 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`deprecator` +================= +.. automodule:: nibabel.deprecator + +.. currentmodule:: nibabel.deprecator +.. autosummary:: + + Deprecator + ExpiredDeprecationError + + +.. currentmodule:: nibabel.deprecator + + +:class:`Deprecator` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Deprecator + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ExpiredDeprecationError` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ExpiredDeprecationError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.dft.rst.txt b/_sources/reference/nibabel.dft.rst.txt new file mode 100644 index 0000000000..9abc68218d --- /dev/null +++ b/_sources/reference/nibabel.dft.rst.txt @@ -0,0 +1,83 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`dft` +========== +.. automodule:: nibabel.dft + +.. currentmodule:: nibabel.dft +.. autosummary:: + + CachingError + DFTError + InstanceStackError + VolumeError + clear_cache + get_studies + update_cache + + +.. currentmodule:: nibabel.dft + + +:class:`CachingError` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: CachingError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`DFTError` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: DFTError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`InstanceStackError` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: InstanceStackError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`VolumeError` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: VolumeError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +clear_cache +~~~~~~~~~~~ + +.. autofunction:: clear_cache + +get_studies +~~~~~~~~~~~ + +.. autofunction:: get_studies + +update_cache +~~~~~~~~~~~~ + +.. autofunction:: update_cache + diff --git a/_sources/reference/nibabel.ecat.rst.txt b/_sources/reference/nibabel.ecat.rst.txt new file mode 100644 index 0000000000..cdb4ff5914 --- /dev/null +++ b/_sources/reference/nibabel.ecat.rst.txt @@ -0,0 +1,89 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`ecat` +=========== +.. automodule:: nibabel.ecat + +.. currentmodule:: nibabel.ecat +.. autosummary:: + + EcatHeader + EcatImage + EcatImageArrayProxy + EcatSubHeader + get_frame_order + get_series_framenumbers + read_mlist + read_subheaders + + +.. currentmodule:: nibabel.ecat + + +:class:`EcatHeader` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: EcatHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`EcatImage` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: EcatImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`EcatImageArrayProxy` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: EcatImageArrayProxy + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`EcatSubHeader` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: EcatSubHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +get_frame_order +~~~~~~~~~~~~~~~ + +.. autofunction:: get_frame_order + +get_series_framenumbers +~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: get_series_framenumbers + +read_mlist +~~~~~~~~~~ + +.. autofunction:: read_mlist + +read_subheaders +~~~~~~~~~~~~~~~ + +.. autofunction:: read_subheaders + diff --git a/_sources/reference/nibabel.environment.rst.txt b/_sources/reference/nibabel.environment.rst.txt new file mode 100644 index 0000000000..84b297da14 --- /dev/null +++ b/_sources/reference/nibabel.environment.rst.txt @@ -0,0 +1,31 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`environment` +================== +.. automodule:: nibabel.environment + +.. currentmodule:: nibabel.environment +.. autosummary:: + + get_home_dir + get_nipy_system_dir + get_nipy_user_dir + + +.. currentmodule:: nibabel.environment + +get_home_dir +~~~~~~~~~~~~ + +.. autofunction:: get_home_dir + +get_nipy_system_dir +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: get_nipy_system_dir + +get_nipy_user_dir +~~~~~~~~~~~~~~~~~ + +.. autofunction:: get_nipy_user_dir + diff --git a/_sources/reference/nibabel.eulerangles.rst.txt b/_sources/reference/nibabel.eulerangles.rst.txt new file mode 100644 index 0000000000..360ba20a9e --- /dev/null +++ b/_sources/reference/nibabel.eulerangles.rst.txt @@ -0,0 +1,49 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`eulerangles` +================== +.. automodule:: nibabel.eulerangles + +.. currentmodule:: nibabel.eulerangles +.. autosummary:: + + angle_axis2euler + euler2angle_axis + euler2mat + euler2quat + mat2euler + quat2euler + + +.. currentmodule:: nibabel.eulerangles + +angle_axis2euler +~~~~~~~~~~~~~~~~ + +.. autofunction:: angle_axis2euler + +euler2angle_axis +~~~~~~~~~~~~~~~~ + +.. autofunction:: euler2angle_axis + +euler2mat +~~~~~~~~~ + +.. autofunction:: euler2mat + +euler2quat +~~~~~~~~~~ + +.. autofunction:: euler2quat + +mat2euler +~~~~~~~~~ + +.. autofunction:: mat2euler + +quat2euler +~~~~~~~~~~ + +.. autofunction:: quat2euler + diff --git a/_sources/reference/nibabel.filebasedimages.rst.txt b/_sources/reference/nibabel.filebasedimages.rst.txt new file mode 100644 index 0000000000..6b93396805 --- /dev/null +++ b/_sources/reference/nibabel.filebasedimages.rst.txt @@ -0,0 +1,65 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`filebasedimages` +====================== +.. automodule:: nibabel.filebasedimages + +.. currentmodule:: nibabel.filebasedimages +.. autosummary:: + + FileBasedHeader + FileBasedImage + ImageFileError + SerializableImage + + +.. currentmodule:: nibabel.filebasedimages + + +:class:`FileBasedHeader` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: FileBasedHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`FileBasedImage` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: FileBasedImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ImageFileError` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ImageFileError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SerializableImage` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SerializableImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.fileholders.rst.txt b/_sources/reference/nibabel.fileholders.rst.txt new file mode 100644 index 0000000000..81f10271ee --- /dev/null +++ b/_sources/reference/nibabel.fileholders.rst.txt @@ -0,0 +1,45 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`fileholders` +================== +.. automodule:: nibabel.fileholders + +.. currentmodule:: nibabel.fileholders +.. autosummary:: + + FileHolder + FileHolderError + copy_file_map + + +.. currentmodule:: nibabel.fileholders + + +:class:`FileHolder` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: FileHolder + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`FileHolderError` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: FileHolderError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +copy_file_map +~~~~~~~~~~~~~ + +.. autofunction:: copy_file_map + diff --git a/_sources/reference/nibabel.filename_parser.rst.txt b/_sources/reference/nibabel.filename_parser.rst.txt new file mode 100644 index 0000000000..1bfb64ed7a --- /dev/null +++ b/_sources/reference/nibabel.filename_parser.rst.txt @@ -0,0 +1,44 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`filename_parser` +====================== +.. automodule:: nibabel.filename_parser + +.. currentmodule:: nibabel.filename_parser +.. autosummary:: + + TypesFilenamesError + parse_filename + splitext_addext + types_filenames + + +.. currentmodule:: nibabel.filename_parser + + +:class:`TypesFilenamesError` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: TypesFilenamesError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +parse_filename +~~~~~~~~~~~~~~ + +.. autofunction:: parse_filename + +splitext_addext +~~~~~~~~~~~~~~~ + +.. autofunction:: splitext_addext + +types_filenames +~~~~~~~~~~~~~~~ + +.. autofunction:: types_filenames + diff --git a/_sources/reference/nibabel.fileslice.rst.txt b/_sources/reference/nibabel.fileslice.rst.txt new file mode 100644 index 0000000000..459d863b6f --- /dev/null +++ b/_sources/reference/nibabel.fileslice.rst.txt @@ -0,0 +1,97 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`fileslice` +================ +.. automodule:: nibabel.fileslice + +.. currentmodule:: nibabel.fileslice +.. autosummary:: + + calc_slicedefs + canonical_slicers + fileslice + fill_slicer + is_fancy + optimize_read_slicers + optimize_slicer + predict_shape + read_segments + slice2len + slice2outax + slicers2segments + strided_scalar + threshold_heuristic + + +.. currentmodule:: nibabel.fileslice + +calc_slicedefs +~~~~~~~~~~~~~~ + +.. autofunction:: calc_slicedefs + +canonical_slicers +~~~~~~~~~~~~~~~~~ + +.. autofunction:: canonical_slicers + +fileslice +~~~~~~~~~ + +.. autofunction:: fileslice + +fill_slicer +~~~~~~~~~~~ + +.. autofunction:: fill_slicer + +is_fancy +~~~~~~~~ + +.. autofunction:: is_fancy + +optimize_read_slicers +~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: optimize_read_slicers + +optimize_slicer +~~~~~~~~~~~~~~~ + +.. autofunction:: optimize_slicer + +predict_shape +~~~~~~~~~~~~~ + +.. autofunction:: predict_shape + +read_segments +~~~~~~~~~~~~~ + +.. autofunction:: read_segments + +slice2len +~~~~~~~~~ + +.. autofunction:: slice2len + +slice2outax +~~~~~~~~~~~ + +.. autofunction:: slice2outax + +slicers2segments +~~~~~~~~~~~~~~~~ + +.. autofunction:: slicers2segments + +strided_scalar +~~~~~~~~~~~~~~ + +.. autofunction:: strided_scalar + +threshold_heuristic +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: threshold_heuristic + diff --git a/_sources/reference/nibabel.fileutils.rst.txt b/_sources/reference/nibabel.fileutils.rst.txt new file mode 100644 index 0000000000..250403ed93 --- /dev/null +++ b/_sources/reference/nibabel.fileutils.rst.txt @@ -0,0 +1,19 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`fileutils` +================ +.. automodule:: nibabel.fileutils + +.. currentmodule:: nibabel.fileutils +.. autosummary:: + + read_zt_byte_strings + + +.. currentmodule:: nibabel.fileutils + +read_zt_byte_strings +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: read_zt_byte_strings + diff --git a/_sources/reference/nibabel.freesurfer.rst.txt b/_sources/reference/nibabel.freesurfer.rst.txt new file mode 100644 index 0000000000..43aab31775 --- /dev/null +++ b/_sources/reference/nibabel.freesurfer.rst.txt @@ -0,0 +1,120 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`freesurfer` +================= +.. automodule:: nibabel.freesurfer + +.. currentmodule:: nibabel.freesurfer +.. autosummary:: + + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`freesurfer.io` +---------------------------- +.. automodule:: nibabel.freesurfer.io + +.. currentmodule:: nibabel.freesurfer.io +.. autosummary:: + + read_annot + read_geometry + read_label + read_morph_data + write_annot + write_geometry + write_morph_data + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`freesurfer.mghformat` +----------------------------------- +.. automodule:: nibabel.freesurfer.mghformat + +.. currentmodule:: nibabel.freesurfer.mghformat +.. autosummary:: + + MGHError + MGHHeader + MGHImage + + +.. currentmodule:: nibabel.freesurfer + + +.. currentmodule:: nibabel.freesurfer.io + +read_annot +~~~~~~~~~~ + +.. autofunction:: read_annot + +read_geometry +~~~~~~~~~~~~~ + +.. autofunction:: read_geometry + +read_label +~~~~~~~~~~ + +.. autofunction:: read_label + +read_morph_data +~~~~~~~~~~~~~~~ + +.. autofunction:: read_morph_data + +write_annot +~~~~~~~~~~~ + +.. autofunction:: write_annot + +write_geometry +~~~~~~~~~~~~~~ + +.. autofunction:: write_geometry + +write_morph_data +~~~~~~~~~~~~~~~~ + +.. autofunction:: write_morph_data + + +.. currentmodule:: nibabel.freesurfer.mghformat + + +:class:`MGHError` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: MGHError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`MGHHeader` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: MGHHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`MGHImage` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: MGHImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.funcs.rst.txt b/_sources/reference/nibabel.funcs.rst.txt new file mode 100644 index 0000000000..9d8245fd6b --- /dev/null +++ b/_sources/reference/nibabel.funcs.rst.txt @@ -0,0 +1,37 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`funcs` +============ +.. automodule:: nibabel.funcs + +.. currentmodule:: nibabel.funcs +.. autosummary:: + + as_closest_canonical + concat_images + four_to_three + squeeze_image + + +.. currentmodule:: nibabel.funcs + +as_closest_canonical +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: as_closest_canonical + +concat_images +~~~~~~~~~~~~~ + +.. autofunction:: concat_images + +four_to_three +~~~~~~~~~~~~~ + +.. autofunction:: four_to_three + +squeeze_image +~~~~~~~~~~~~~ + +.. autofunction:: squeeze_image + diff --git a/_sources/reference/nibabel.gifti.rst.txt b/_sources/reference/nibabel.gifti.rst.txt new file mode 100644 index 0000000000..2b6c3cef33 --- /dev/null +++ b/_sources/reference/nibabel.gifti.rst.txt @@ -0,0 +1,175 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`gifti` +============ +.. automodule:: nibabel.gifti + +.. currentmodule:: nibabel.gifti +.. autosummary:: + + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`gifti.gifti` +-------------------------- +.. automodule:: nibabel.gifti.gifti + +.. currentmodule:: nibabel.gifti.gifti +.. autosummary:: + + GiftiCoordSystem + GiftiDataArray + GiftiImage + GiftiLabel + GiftiLabelTable + GiftiMetaData + GiftiNVPairs + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`gifti.parse_gifti_fast` +------------------------------------- +.. automodule:: nibabel.gifti.parse_gifti_fast + +.. currentmodule:: nibabel.gifti.parse_gifti_fast +.. autosummary:: + + GiftiImageParser + GiftiParseError + read_data_block + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`gifti.util` +------------------------- +.. automodule:: nibabel.gifti.util + +.. currentmodule:: nibabel.gifti.util +.. autosummary:: + + + +.. currentmodule:: nibabel.gifti + + +.. currentmodule:: nibabel.gifti.gifti + + +:class:`GiftiCoordSystem` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GiftiCoordSystem + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`GiftiDataArray` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GiftiDataArray + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`GiftiImage` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GiftiImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`GiftiLabel` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GiftiLabel + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`GiftiLabelTable` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GiftiLabelTable + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`GiftiMetaData` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GiftiMetaData + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`GiftiNVPairs` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GiftiNVPairs + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +.. currentmodule:: nibabel.gifti.parse_gifti_fast + + +:class:`GiftiImageParser` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GiftiImageParser + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`GiftiParseError` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GiftiParseError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +read_data_block +~~~~~~~~~~~~~~~ + +.. autofunction:: read_data_block + + +.. currentmodule:: nibabel.gifti.util + diff --git a/_sources/reference/nibabel.imageclasses.rst.txt b/_sources/reference/nibabel.imageclasses.rst.txt new file mode 100644 index 0000000000..bea117241b --- /dev/null +++ b/_sources/reference/nibabel.imageclasses.rst.txt @@ -0,0 +1,19 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`imageclasses` +=================== +.. automodule:: nibabel.imageclasses + +.. currentmodule:: nibabel.imageclasses +.. autosummary:: + + spatial_axes_first + + +.. currentmodule:: nibabel.imageclasses + +spatial_axes_first +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: spatial_axes_first + diff --git a/_sources/reference/nibabel.imageglobals.rst.txt b/_sources/reference/nibabel.imageglobals.rst.txt new file mode 100644 index 0000000000..0c125bc5e1 --- /dev/null +++ b/_sources/reference/nibabel.imageglobals.rst.txt @@ -0,0 +1,39 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`imageglobals` +=================== +.. automodule:: nibabel.imageglobals + +.. currentmodule:: nibabel.imageglobals +.. autosummary:: + + ErrorLevel + LoggingOutputSuppressor + + +.. currentmodule:: nibabel.imageglobals + + +:class:`ErrorLevel` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ErrorLevel + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`LoggingOutputSuppressor` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: LoggingOutputSuppressor + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.imagestats.rst.txt b/_sources/reference/nibabel.imagestats.rst.txt new file mode 100644 index 0000000000..36ab0c0446 --- /dev/null +++ b/_sources/reference/nibabel.imagestats.rst.txt @@ -0,0 +1,25 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`imagestats` +================= +.. automodule:: nibabel.imagestats + +.. currentmodule:: nibabel.imagestats +.. autosummary:: + + count_nonzero_voxels + mask_volume + + +.. currentmodule:: nibabel.imagestats + +count_nonzero_voxels +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: count_nonzero_voxels + +mask_volume +~~~~~~~~~~~ + +.. autofunction:: mask_volume + diff --git a/_sources/reference/nibabel.loadsave.rst.txt b/_sources/reference/nibabel.loadsave.rst.txt new file mode 100644 index 0000000000..7ed3ae5b70 --- /dev/null +++ b/_sources/reference/nibabel.loadsave.rst.txt @@ -0,0 +1,37 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`loadsave` +=============== +.. automodule:: nibabel.loadsave + +.. currentmodule:: nibabel.loadsave +.. autosummary:: + + guessed_image_type + load + read_img_data + save + + +.. currentmodule:: nibabel.loadsave + +guessed_image_type +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: guessed_image_type + +load +~~~~ + +.. autofunction:: load + +read_img_data +~~~~~~~~~~~~~ + +.. autofunction:: read_img_data + +save +~~~~ + +.. autofunction:: save + diff --git a/_sources/reference/nibabel.minc1.rst.txt b/_sources/reference/nibabel.minc1.rst.txt new file mode 100644 index 0000000000..c9cba6f7ea --- /dev/null +++ b/_sources/reference/nibabel.minc1.rst.txt @@ -0,0 +1,91 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`minc1` +============ +.. automodule:: nibabel.minc1 + +.. currentmodule:: nibabel.minc1 +.. autosummary:: + + Minc1File + Minc1Header + Minc1Image + MincError + MincHeader + MincImageArrayProxy + + +.. currentmodule:: nibabel.minc1 + + +:class:`Minc1File` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Minc1File + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Minc1Header` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Minc1Header + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Minc1Image` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Minc1Image + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`MincError` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: MincError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`MincHeader` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: MincHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`MincImageArrayProxy` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: MincImageArrayProxy + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.minc2.rst.txt b/_sources/reference/nibabel.minc2.rst.txt new file mode 100644 index 0000000000..03c2f0c94a --- /dev/null +++ b/_sources/reference/nibabel.minc2.rst.txt @@ -0,0 +1,65 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`minc2` +============ +.. automodule:: nibabel.minc2 + +.. currentmodule:: nibabel.minc2 +.. autosummary:: + + Hdf5Bunch + Minc2File + Minc2Header + Minc2Image + + +.. currentmodule:: nibabel.minc2 + + +:class:`Hdf5Bunch` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Hdf5Bunch + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Minc2File` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Minc2File + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Minc2Header` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Minc2Header + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Minc2Image` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Minc2Image + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.mriutils.rst.txt b/_sources/reference/nibabel.mriutils.rst.txt new file mode 100644 index 0000000000..1b1de427db --- /dev/null +++ b/_sources/reference/nibabel.mriutils.rst.txt @@ -0,0 +1,32 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`mriutils` +=============== +.. automodule:: nibabel.mriutils + +.. currentmodule:: nibabel.mriutils +.. autosummary:: + + MRIError + calculate_dwell_time + + +.. currentmodule:: nibabel.mriutils + + +:class:`MRIError` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: MRIError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +calculate_dwell_time +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: calculate_dwell_time + diff --git a/_sources/reference/nibabel.nicom.rst.txt b/_sources/reference/nibabel.nicom.rst.txt new file mode 100644 index 0000000000..13f5639e54 --- /dev/null +++ b/_sources/reference/nibabel.nicom.rst.txt @@ -0,0 +1,435 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`nicom` +============ +.. automodule:: nibabel.nicom + +.. currentmodule:: nibabel.nicom +.. autosummary:: + + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`nicom.ascconv` +---------------------------- +.. automodule:: nibabel.nicom.ascconv + +.. currentmodule:: nibabel.nicom.ascconv +.. autosummary:: + + AscconvParseError + Atom + NoValue + assign2atoms + obj_from_atoms + parse_ascconv + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`nicom.csareader` +------------------------------ +.. automodule:: nibabel.nicom.csareader + +.. currentmodule:: nibabel.nicom.csareader +.. autosummary:: + + CSAError + CSAReadError + get_acq_mat_txt + get_b_matrix + get_b_value + get_csa_header + get_g_vector + get_ice_dims + get_n_mosaic + get_scalar + get_slice_normal + get_vector + is_mosaic + nt_str + read + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`nicom.dicomreaders` +--------------------------------- +.. automodule:: nibabel.nicom.dicomreaders + +.. currentmodule:: nibabel.nicom.dicomreaders +.. autosummary:: + + DicomReadError + mosaic_to_nii + read_mosaic_dir + read_mosaic_dwi_dir + slices_to_series + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`nicom.dicomwrappers` +---------------------------------- +.. automodule:: nibabel.nicom.dicomwrappers + +.. currentmodule:: nibabel.nicom.dicomwrappers +.. autosummary:: + + MosaicWrapper + MultiframeWrapper + SiemensWrapper + Wrapper + WrapperError + WrapperPrecisionError + none_or_close + wrapper_from_data + wrapper_from_file + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`nicom.dwiparams` +------------------------------ +.. automodule:: nibabel.nicom.dwiparams + +.. currentmodule:: nibabel.nicom.dwiparams +.. autosummary:: + + B2q + nearest_pos_semi_def + q2bg + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`nicom.structreader` +--------------------------------- +.. automodule:: nibabel.nicom.structreader + +.. currentmodule:: nibabel.nicom.structreader +.. autosummary:: + + Unpacker + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`nicom.utils` +-------------------------- +.. automodule:: nibabel.nicom.utils + +.. currentmodule:: nibabel.nicom.utils +.. autosummary:: + + find_private_section + + +.. currentmodule:: nibabel.nicom + + +.. currentmodule:: nibabel.nicom.ascconv + + +:class:`AscconvParseError` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: AscconvParseError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Atom` +~~~~~~~~~~~~~ + + +.. autoclass:: Atom + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`NoValue` +~~~~~~~~~~~~~~~~ + + +.. autoclass:: NoValue + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +assign2atoms +~~~~~~~~~~~~ + +.. autofunction:: assign2atoms + +obj_from_atoms +~~~~~~~~~~~~~~ + +.. autofunction:: obj_from_atoms + +parse_ascconv +~~~~~~~~~~~~~ + +.. autofunction:: parse_ascconv + + +.. currentmodule:: nibabel.nicom.csareader + + +:class:`CSAError` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: CSAError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`CSAReadError` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: CSAReadError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +get_acq_mat_txt +~~~~~~~~~~~~~~~ + +.. autofunction:: get_acq_mat_txt + +get_b_matrix +~~~~~~~~~~~~ + +.. autofunction:: get_b_matrix + +get_b_value +~~~~~~~~~~~ + +.. autofunction:: get_b_value + +get_csa_header +~~~~~~~~~~~~~~ + +.. autofunction:: get_csa_header + +get_g_vector +~~~~~~~~~~~~ + +.. autofunction:: get_g_vector + +get_ice_dims +~~~~~~~~~~~~ + +.. autofunction:: get_ice_dims + +get_n_mosaic +~~~~~~~~~~~~ + +.. autofunction:: get_n_mosaic + +get_scalar +~~~~~~~~~~ + +.. autofunction:: get_scalar + +get_slice_normal +~~~~~~~~~~~~~~~~ + +.. autofunction:: get_slice_normal + +get_vector +~~~~~~~~~~ + +.. autofunction:: get_vector + +is_mosaic +~~~~~~~~~ + +.. autofunction:: is_mosaic + +nt_str +~~~~~~ + +.. autofunction:: nt_str + +read +~~~~ + +.. autofunction:: read + + +.. currentmodule:: nibabel.nicom.dicomreaders + + +:class:`DicomReadError` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: DicomReadError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +mosaic_to_nii +~~~~~~~~~~~~~ + +.. autofunction:: mosaic_to_nii + +read_mosaic_dir +~~~~~~~~~~~~~~~ + +.. autofunction:: read_mosaic_dir + +read_mosaic_dwi_dir +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: read_mosaic_dwi_dir + +slices_to_series +~~~~~~~~~~~~~~~~ + +.. autofunction:: slices_to_series + + +.. currentmodule:: nibabel.nicom.dicomwrappers + + +:class:`MosaicWrapper` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: MosaicWrapper + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`MultiframeWrapper` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: MultiframeWrapper + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SiemensWrapper` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SiemensWrapper + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Wrapper` +~~~~~~~~~~~~~~~~ + + +.. autoclass:: Wrapper + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`WrapperError` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: WrapperError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`WrapperPrecisionError` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: WrapperPrecisionError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +none_or_close +~~~~~~~~~~~~~ + +.. autofunction:: none_or_close + +wrapper_from_data +~~~~~~~~~~~~~~~~~ + +.. autofunction:: wrapper_from_data + +wrapper_from_file +~~~~~~~~~~~~~~~~~ + +.. autofunction:: wrapper_from_file + + +.. currentmodule:: nibabel.nicom.dwiparams + +B2q +~~~ + +.. autofunction:: B2q + +nearest_pos_semi_def +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: nearest_pos_semi_def + +q2bg +~~~~ + +.. autofunction:: q2bg + + +.. currentmodule:: nibabel.nicom.structreader + + +:class:`Unpacker` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Unpacker + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +.. currentmodule:: nibabel.nicom.utils + +find_private_section +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: find_private_section + diff --git a/_sources/reference/nibabel.nifti1.rst.txt b/_sources/reference/nibabel.nifti1.rst.txt new file mode 100644 index 0000000000..025989324a --- /dev/null +++ b/_sources/reference/nibabel.nifti1.rst.txt @@ -0,0 +1,116 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`nifti1` +============= +.. automodule:: nibabel.nifti1 + +.. currentmodule:: nibabel.nifti1 +.. autosummary:: + + Nifti1DicomExtension + Nifti1Extension + Nifti1Extensions + Nifti1Header + Nifti1Image + Nifti1Pair + Nifti1PairHeader + load + save + + +.. currentmodule:: nibabel.nifti1 + + +:class:`Nifti1DicomExtension` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti1DicomExtension + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Nifti1Extension` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti1Extension + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Nifti1Extensions` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti1Extensions + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Nifti1Header` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti1Header + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Nifti1Image` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti1Image + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Nifti1Pair` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti1Pair + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Nifti1PairHeader` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti1PairHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +load +~~~~ + +.. autofunction:: load + +save +~~~~ + +.. autofunction:: save + diff --git a/_sources/reference/nibabel.nifti2.rst.txt b/_sources/reference/nibabel.nifti2.rst.txt new file mode 100644 index 0000000000..072fb2afe3 --- /dev/null +++ b/_sources/reference/nibabel.nifti2.rst.txt @@ -0,0 +1,77 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`nifti2` +============= +.. automodule:: nibabel.nifti2 + +.. currentmodule:: nibabel.nifti2 +.. autosummary:: + + Nifti2Header + Nifti2Image + Nifti2Pair + Nifti2PairHeader + load + save + + +.. currentmodule:: nibabel.nifti2 + + +:class:`Nifti2Header` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti2Header + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Nifti2Image` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti2Image + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Nifti2Pair` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti2Pair + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Nifti2PairHeader` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Nifti2PairHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +load +~~~~ + +.. autofunction:: load + +save +~~~~ + +.. autofunction:: save + diff --git a/_sources/reference/nibabel.onetime.rst.txt b/_sources/reference/nibabel.onetime.rst.txt new file mode 100644 index 0000000000..38b7c98f30 --- /dev/null +++ b/_sources/reference/nibabel.onetime.rst.txt @@ -0,0 +1,51 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`onetime` +============== +.. automodule:: nibabel.onetime + +.. currentmodule:: nibabel.onetime +.. autosummary:: + + OneTimeProperty + ResetMixin + auto_attr + setattr_on_read + + +.. currentmodule:: nibabel.onetime + + +:class:`OneTimeProperty` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: OneTimeProperty + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ResetMixin` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ResetMixin + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +auto_attr +~~~~~~~~~ + +.. autofunction:: auto_attr + +setattr_on_read +~~~~~~~~~~~~~~~ + +.. autofunction:: setattr_on_read + diff --git a/_sources/reference/nibabel.openers.rst.txt b/_sources/reference/nibabel.openers.rst.txt new file mode 100644 index 0000000000..f01be129db --- /dev/null +++ b/_sources/reference/nibabel.openers.rst.txt @@ -0,0 +1,65 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`openers` +============== +.. automodule:: nibabel.openers + +.. currentmodule:: nibabel.openers +.. autosummary:: + + DeterministicGzipFile + Fileish + ImageOpener + Opener + + +.. currentmodule:: nibabel.openers + + +:class:`DeterministicGzipFile` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: DeterministicGzipFile + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Fileish` +~~~~~~~~~~~~~~~~ + + +.. autoclass:: Fileish + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ImageOpener` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ImageOpener + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Opener` +~~~~~~~~~~~~~~~ + + +.. autoclass:: Opener + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.optpkg.rst.txt b/_sources/reference/nibabel.optpkg.rst.txt new file mode 100644 index 0000000000..3d8b7d4c8f --- /dev/null +++ b/_sources/reference/nibabel.optpkg.rst.txt @@ -0,0 +1,19 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`optpkg` +============= +.. automodule:: nibabel.optpkg + +.. currentmodule:: nibabel.optpkg +.. autosummary:: + + optional_package + + +.. currentmodule:: nibabel.optpkg + +optional_package +~~~~~~~~~~~~~~~~ + +.. autofunction:: optional_package + diff --git a/_sources/reference/nibabel.orientations.rst.txt b/_sources/reference/nibabel.orientations.rst.txt new file mode 100644 index 0000000000..3eed93437d --- /dev/null +++ b/_sources/reference/nibabel.orientations.rst.txt @@ -0,0 +1,74 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`orientations` +=================== +.. automodule:: nibabel.orientations + +.. currentmodule:: nibabel.orientations +.. autosummary:: + + OrientationError + aff2axcodes + apply_orientation + axcodes2ornt + flip_axis + inv_ornt_aff + io_orientation + ornt2axcodes + ornt_transform + + +.. currentmodule:: nibabel.orientations + + +:class:`OrientationError` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: OrientationError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +aff2axcodes +~~~~~~~~~~~ + +.. autofunction:: aff2axcodes + +apply_orientation +~~~~~~~~~~~~~~~~~ + +.. autofunction:: apply_orientation + +axcodes2ornt +~~~~~~~~~~~~ + +.. autofunction:: axcodes2ornt + +flip_axis +~~~~~~~~~ + +.. autofunction:: flip_axis + +inv_ornt_aff +~~~~~~~~~~~~ + +.. autofunction:: inv_ornt_aff + +io_orientation +~~~~~~~~~~~~~~ + +.. autofunction:: io_orientation + +ornt2axcodes +~~~~~~~~~~~~ + +.. autofunction:: ornt2axcodes + +ornt_transform +~~~~~~~~~~~~~~ + +.. autofunction:: ornt_transform + diff --git a/_sources/reference/nibabel.parrec.rst.txt b/_sources/reference/nibabel.parrec.rst.txt new file mode 100644 index 0000000000..e115a415b3 --- /dev/null +++ b/_sources/reference/nibabel.parrec.rst.txt @@ -0,0 +1,95 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`parrec` +============= +.. automodule:: nibabel.parrec + +.. currentmodule:: nibabel.parrec +.. autosummary:: + + PARRECArrayProxy + PARRECError + PARRECHeader + PARRECImage + exts2pars + one_line + parse_PAR_header + vol_is_full + vol_numbers + + +.. currentmodule:: nibabel.parrec + + +:class:`PARRECArrayProxy` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: PARRECArrayProxy + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`PARRECError` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: PARRECError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`PARRECHeader` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: PARRECHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`PARRECImage` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: PARRECImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +exts2pars +~~~~~~~~~ + +.. autofunction:: exts2pars + +one_line +~~~~~~~~ + +.. autofunction:: one_line + +parse_PAR_header +~~~~~~~~~~~~~~~~ + +.. autofunction:: parse_PAR_header + +vol_is_full +~~~~~~~~~~~ + +.. autofunction:: vol_is_full + +vol_numbers +~~~~~~~~~~~ + +.. autofunction:: vol_numbers + diff --git a/_sources/reference/nibabel.pointset.rst.txt b/_sources/reference/nibabel.pointset.rst.txt new file mode 100644 index 0000000000..6f9eac8f99 --- /dev/null +++ b/_sources/reference/nibabel.pointset.rst.txt @@ -0,0 +1,65 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`pointset` +=============== +.. automodule:: nibabel.pointset + +.. currentmodule:: nibabel.pointset +.. autosummary:: + + CoordinateArray + Grid + GridIndices + Pointset + + +.. currentmodule:: nibabel.pointset + + +:class:`CoordinateArray` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: CoordinateArray + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Grid` +~~~~~~~~~~~~~ + + +.. autoclass:: Grid + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`GridIndices` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: GridIndices + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Pointset` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Pointset + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.processing.rst.txt b/_sources/reference/nibabel.processing.rst.txt new file mode 100644 index 0000000000..f58cdcb135 --- /dev/null +++ b/_sources/reference/nibabel.processing.rst.txt @@ -0,0 +1,55 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`processing` +================= +.. automodule:: nibabel.processing + +.. currentmodule:: nibabel.processing +.. autosummary:: + + adapt_affine + conform + fwhm2sigma + resample_from_to + resample_to_output + sigma2fwhm + smooth_image + + +.. currentmodule:: nibabel.processing + +adapt_affine +~~~~~~~~~~~~ + +.. autofunction:: adapt_affine + +conform +~~~~~~~ + +.. autofunction:: conform + +fwhm2sigma +~~~~~~~~~~ + +.. autofunction:: fwhm2sigma + +resample_from_to +~~~~~~~~~~~~~~~~ + +.. autofunction:: resample_from_to + +resample_to_output +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: resample_to_output + +sigma2fwhm +~~~~~~~~~~ + +.. autofunction:: sigma2fwhm + +smooth_image +~~~~~~~~~~~~ + +.. autofunction:: smooth_image + diff --git a/_sources/reference/nibabel.pydicom_compat.rst.txt b/_sources/reference/nibabel.pydicom_compat.rst.txt new file mode 100644 index 0000000000..2860303b4a --- /dev/null +++ b/_sources/reference/nibabel.pydicom_compat.rst.txt @@ -0,0 +1,19 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`pydicom_compat` +===================== +.. automodule:: nibabel.pydicom_compat + +.. currentmodule:: nibabel.pydicom_compat +.. autosummary:: + + dicom_test + + +.. currentmodule:: nibabel.pydicom_compat + +dicom_test +~~~~~~~~~~ + +.. autofunction:: dicom_test + diff --git a/_sources/reference/nibabel.quaternions.rst.txt b/_sources/reference/nibabel.quaternions.rst.txt new file mode 100644 index 0000000000..2354787f7e --- /dev/null +++ b/_sources/reference/nibabel.quaternions.rst.txt @@ -0,0 +1,97 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`quaternions` +================== +.. automodule:: nibabel.quaternions + +.. currentmodule:: nibabel.quaternions +.. autosummary:: + + angle_axis2mat + angle_axis2quat + conjugate + eye + fillpositive + inverse + isunit + mat2quat + mult + nearly_equivalent + norm + quat2angle_axis + quat2mat + rotate_vector + + +.. currentmodule:: nibabel.quaternions + +angle_axis2mat +~~~~~~~~~~~~~~ + +.. autofunction:: angle_axis2mat + +angle_axis2quat +~~~~~~~~~~~~~~~ + +.. autofunction:: angle_axis2quat + +conjugate +~~~~~~~~~ + +.. autofunction:: conjugate + +eye +~~~ + +.. autofunction:: eye + +fillpositive +~~~~~~~~~~~~ + +.. autofunction:: fillpositive + +inverse +~~~~~~~ + +.. autofunction:: inverse + +isunit +~~~~~~ + +.. autofunction:: isunit + +mat2quat +~~~~~~~~ + +.. autofunction:: mat2quat + +mult +~~~~ + +.. autofunction:: mult + +nearly_equivalent +~~~~~~~~~~~~~~~~~ + +.. autofunction:: nearly_equivalent + +norm +~~~~ + +.. autofunction:: norm + +quat2angle_axis +~~~~~~~~~~~~~~~ + +.. autofunction:: quat2angle_axis + +quat2mat +~~~~~~~~ + +.. autofunction:: quat2mat + +rotate_vector +~~~~~~~~~~~~~ + +.. autofunction:: rotate_vector + diff --git a/_sources/reference/nibabel.rst.txt b/_sources/reference/nibabel.rst.txt new file mode 100644 index 0000000000..5508dc2830 --- /dev/null +++ b/_sources/reference/nibabel.rst.txt @@ -0,0 +1,31 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`nibabel` +============== +.. automodule:: nibabel + +.. currentmodule:: nibabel +.. autosummary:: + + bench + get_info + test + + +.. currentmodule:: nibabel + +bench +~~~~~ + +.. autofunction:: bench + +get_info +~~~~~~~~ + +.. autofunction:: get_info + +test +~~~~ + +.. autofunction:: test + diff --git a/_sources/reference/nibabel.rstutils.rst.txt b/_sources/reference/nibabel.rstutils.rst.txt new file mode 100644 index 0000000000..0068d5e0d5 --- /dev/null +++ b/_sources/reference/nibabel.rstutils.rst.txt @@ -0,0 +1,19 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`rstutils` +=============== +.. automodule:: nibabel.rstutils + +.. currentmodule:: nibabel.rstutils +.. autosummary:: + + rst_table + + +.. currentmodule:: nibabel.rstutils + +rst_table +~~~~~~~~~ + +.. autofunction:: rst_table + diff --git a/_sources/reference/nibabel.spaces.rst.txt b/_sources/reference/nibabel.spaces.rst.txt new file mode 100644 index 0000000000..ec46a383bd --- /dev/null +++ b/_sources/reference/nibabel.spaces.rst.txt @@ -0,0 +1,25 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`spaces` +============= +.. automodule:: nibabel.spaces + +.. currentmodule:: nibabel.spaces +.. autosummary:: + + slice2volume + vox2out_vox + + +.. currentmodule:: nibabel.spaces + +slice2volume +~~~~~~~~~~~~ + +.. autofunction:: slice2volume + +vox2out_vox +~~~~~~~~~~~ + +.. autofunction:: vox2out_vox + diff --git a/_sources/reference/nibabel.spatialimages.rst.txt b/_sources/reference/nibabel.spatialimages.rst.txt new file mode 100644 index 0000000000..ccf82f93b2 --- /dev/null +++ b/_sources/reference/nibabel.spatialimages.rst.txt @@ -0,0 +1,123 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`spatialimages` +==================== +.. automodule:: nibabel.spatialimages + +.. currentmodule:: nibabel.spatialimages +.. autosummary:: + + HasDtype + HeaderDataError + HeaderTypeError + ImageDataError + SpatialFirstSlicer + SpatialHeader + SpatialImage + SpatialProtocol + supported_np_types + + +.. currentmodule:: nibabel.spatialimages + + +:class:`HasDtype` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: HasDtype + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`HeaderDataError` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: HeaderDataError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`HeaderTypeError` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: HeaderTypeError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ImageDataError` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ImageDataError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SpatialFirstSlicer` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SpatialFirstSlicer + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SpatialHeader` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SpatialHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SpatialImage` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SpatialImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SpatialProtocol` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SpatialProtocol + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +supported_np_types +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: supported_np_types + diff --git a/_sources/reference/nibabel.spm2analyze.rst.txt b/_sources/reference/nibabel.spm2analyze.rst.txt new file mode 100644 index 0000000000..ac8d29e3d2 --- /dev/null +++ b/_sources/reference/nibabel.spm2analyze.rst.txt @@ -0,0 +1,39 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`spm2analyze` +================== +.. automodule:: nibabel.spm2analyze + +.. currentmodule:: nibabel.spm2analyze +.. autosummary:: + + Spm2AnalyzeHeader + Spm2AnalyzeImage + + +.. currentmodule:: nibabel.spm2analyze + + +:class:`Spm2AnalyzeHeader` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Spm2AnalyzeHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Spm2AnalyzeImage` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Spm2AnalyzeImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.spm99analyze.rst.txt b/_sources/reference/nibabel.spm99analyze.rst.txt new file mode 100644 index 0000000000..8c02fdefdb --- /dev/null +++ b/_sources/reference/nibabel.spm99analyze.rst.txt @@ -0,0 +1,52 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`spm99analyze` +=================== +.. automodule:: nibabel.spm99analyze + +.. currentmodule:: nibabel.spm99analyze +.. autosummary:: + + Spm99AnalyzeHeader + Spm99AnalyzeImage + SpmAnalyzeHeader + + +.. currentmodule:: nibabel.spm99analyze + + +:class:`Spm99AnalyzeHeader` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Spm99AnalyzeHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Spm99AnalyzeImage` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Spm99AnalyzeImage + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SpmAnalyzeHeader` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SpmAnalyzeHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.streamlines.rst.txt b/_sources/reference/nibabel.streamlines.rst.txt new file mode 100644 index 0000000000..1b5e3ea022 --- /dev/null +++ b/_sources/reference/nibabel.streamlines.rst.txt @@ -0,0 +1,434 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`streamlines` +================== +.. automodule:: nibabel.streamlines + +.. currentmodule:: nibabel.streamlines +.. autosummary:: + + detect_format + is_supported + load + save + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`streamlines.array_sequence` +----------------------------------------- +.. automodule:: nibabel.streamlines.array_sequence + +.. currentmodule:: nibabel.streamlines.array_sequence +.. autosummary:: + + ArraySequence + concatenate + create_arraysequences_from_generator + is_array_sequence + is_ndarray_of_int_or_bool + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`streamlines.header` +--------------------------------- +.. automodule:: nibabel.streamlines.header + +.. currentmodule:: nibabel.streamlines.header +.. autosummary:: + + Field + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`streamlines.tck` +------------------------------ +.. automodule:: nibabel.streamlines.tck + +.. currentmodule:: nibabel.streamlines.tck +.. autosummary:: + + TckFile + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`streamlines.tractogram` +------------------------------------- +.. automodule:: nibabel.streamlines.tractogram + +.. currentmodule:: nibabel.streamlines.tractogram +.. autosummary:: + + LazyDict + LazyTractogram + PerArrayDict + PerArraySequenceDict + SliceableDataDict + Tractogram + TractogramItem + is_data_dict + is_lazy_dict + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`streamlines.tractogram_file` +------------------------------------------ +.. automodule:: nibabel.streamlines.tractogram_file + +.. currentmodule:: nibabel.streamlines.tractogram_file +.. autosummary:: + + DataError + DataWarning + ExtensionWarning + HeaderError + HeaderWarning + TractogramFile + abstractclassmethod + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`streamlines.trk` +------------------------------ +.. automodule:: nibabel.streamlines.trk + +.. currentmodule:: nibabel.streamlines.trk +.. autosummary:: + + TrkFile + decode_value_from_name + encode_value_in_name + get_affine_rasmm_to_trackvis + get_affine_trackvis_to_rasmm + +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +Module: :mod:`streamlines.utils` +-------------------------------- +.. automodule:: nibabel.streamlines.utils + +.. currentmodule:: nibabel.streamlines.utils +.. autosummary:: + + get_affine_from_reference + peek_next + + +.. currentmodule:: nibabel.streamlines + +detect_format +~~~~~~~~~~~~~ + +.. autofunction:: detect_format + +is_supported +~~~~~~~~~~~~ + +.. autofunction:: is_supported + +load +~~~~ + +.. autofunction:: load + +save +~~~~ + +.. autofunction:: save + + +.. currentmodule:: nibabel.streamlines.array_sequence + + +:class:`ArraySequence` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ArraySequence + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +concatenate +~~~~~~~~~~~ + +.. autofunction:: concatenate + +create_arraysequences_from_generator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: create_arraysequences_from_generator + +is_array_sequence +~~~~~~~~~~~~~~~~~ + +.. autofunction:: is_array_sequence + +is_ndarray_of_int_or_bool +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: is_ndarray_of_int_or_bool + + +.. currentmodule:: nibabel.streamlines.header + + +:class:`Field` +~~~~~~~~~~~~~~ + + +.. autoclass:: Field + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +.. currentmodule:: nibabel.streamlines.tck + + +:class:`TckFile` +~~~~~~~~~~~~~~~~ + + +.. autoclass:: TckFile + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +.. currentmodule:: nibabel.streamlines.tractogram + + +:class:`LazyDict` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: LazyDict + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`LazyTractogram` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: LazyTractogram + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`PerArrayDict` +~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: PerArrayDict + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`PerArraySequenceDict` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: PerArraySequenceDict + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`SliceableDataDict` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: SliceableDataDict + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Tractogram` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: Tractogram + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`TractogramItem` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: TractogramItem + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +is_data_dict +~~~~~~~~~~~~ + +.. autofunction:: is_data_dict + +is_lazy_dict +~~~~~~~~~~~~ + +.. autofunction:: is_lazy_dict + + +.. currentmodule:: nibabel.streamlines.tractogram_file + + +:class:`DataError` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: DataError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`DataWarning` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: DataWarning + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`ExtensionWarning` +~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: ExtensionWarning + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`HeaderError` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: HeaderError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`HeaderWarning` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: HeaderWarning + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`TractogramFile` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: TractogramFile + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`abstractclassmethod` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: abstractclassmethod + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +.. currentmodule:: nibabel.streamlines.trk + + +:class:`TrkFile` +~~~~~~~~~~~~~~~~ + + +.. autoclass:: TrkFile + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +decode_value_from_name +~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: decode_value_from_name + +encode_value_in_name +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: encode_value_in_name + +get_affine_rasmm_to_trackvis +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: get_affine_rasmm_to_trackvis + +get_affine_trackvis_to_rasmm +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: get_affine_trackvis_to_rasmm + + +.. currentmodule:: nibabel.streamlines.utils + +get_affine_from_reference +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: get_affine_from_reference + +peek_next +~~~~~~~~~ + +.. autofunction:: peek_next + diff --git a/_sources/reference/nibabel.tmpdirs.rst.txt b/_sources/reference/nibabel.tmpdirs.rst.txt new file mode 100644 index 0000000000..633f86d94f --- /dev/null +++ b/_sources/reference/nibabel.tmpdirs.rst.txt @@ -0,0 +1,38 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`tmpdirs` +============== +.. automodule:: nibabel.tmpdirs + +.. currentmodule:: nibabel.tmpdirs +.. autosummary:: + + TemporaryDirectory + InGivenDirectory + InTemporaryDirectory + + +.. currentmodule:: nibabel.tmpdirs + + +:class:`TemporaryDirectory` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: TemporaryDirectory + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +InGivenDirectory +~~~~~~~~~~~~~~~~ + +.. autofunction:: InGivenDirectory + +InTemporaryDirectory +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: InTemporaryDirectory + diff --git a/_sources/reference/nibabel.tripwire.rst.txt b/_sources/reference/nibabel.tripwire.rst.txt new file mode 100644 index 0000000000..1829eb239c --- /dev/null +++ b/_sources/reference/nibabel.tripwire.rst.txt @@ -0,0 +1,45 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`tripwire` +=============== +.. automodule:: nibabel.tripwire + +.. currentmodule:: nibabel.tripwire +.. autosummary:: + + TripWire + TripWireError + is_tripwire + + +.. currentmodule:: nibabel.tripwire + + +:class:`TripWire` +~~~~~~~~~~~~~~~~~ + + +.. autoclass:: TripWire + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`TripWireError` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: TripWireError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +is_tripwire +~~~~~~~~~~~ + +.. autofunction:: is_tripwire + diff --git a/_sources/reference/nibabel.viewers.rst.txt b/_sources/reference/nibabel.viewers.rst.txt new file mode 100644 index 0000000000..652e29d602 --- /dev/null +++ b/_sources/reference/nibabel.viewers.rst.txt @@ -0,0 +1,26 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`viewers` +============== +.. automodule:: nibabel.viewers + +.. currentmodule:: nibabel.viewers +.. autosummary:: + + OrthoSlicer3D + + +.. currentmodule:: nibabel.viewers + + +:class:`OrthoSlicer3D` +~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: OrthoSlicer3D + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.volumeutils.rst.txt b/_sources/reference/nibabel.volumeutils.rst.txt new file mode 100644 index 0000000000..617027df94 --- /dev/null +++ b/_sources/reference/nibabel.volumeutils.rst.txt @@ -0,0 +1,129 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`volumeutils` +================== +.. automodule:: nibabel.volumeutils + +.. currentmodule:: nibabel.volumeutils +.. autosummary:: + + DtypeMapper + Recoder + apply_read_scaling + array_from_file + array_to_file + best_write_scale_ftype + better_float_of + finite_range + fname_ext_ul_case + int_scinter_ftype + make_dt_codes + pretty_mapping + rec2dict + seek_tell + shape_zoom_affine + working_type + write_zeros + + +.. currentmodule:: nibabel.volumeutils + + +:class:`DtypeMapper` +~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: DtypeMapper + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`Recoder` +~~~~~~~~~~~~~~~~ + + +.. autoclass:: Recoder + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + +apply_read_scaling +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: apply_read_scaling + +array_from_file +~~~~~~~~~~~~~~~ + +.. autofunction:: array_from_file + +array_to_file +~~~~~~~~~~~~~ + +.. autofunction:: array_to_file + +best_write_scale_ftype +~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: best_write_scale_ftype + +better_float_of +~~~~~~~~~~~~~~~ + +.. autofunction:: better_float_of + +finite_range +~~~~~~~~~~~~ + +.. autofunction:: finite_range + +fname_ext_ul_case +~~~~~~~~~~~~~~~~~ + +.. autofunction:: fname_ext_ul_case + +int_scinter_ftype +~~~~~~~~~~~~~~~~~ + +.. autofunction:: int_scinter_ftype + +make_dt_codes +~~~~~~~~~~~~~ + +.. autofunction:: make_dt_codes + +pretty_mapping +~~~~~~~~~~~~~~ + +.. autofunction:: pretty_mapping + +rec2dict +~~~~~~~~ + +.. autofunction:: rec2dict + +seek_tell +~~~~~~~~~ + +.. autofunction:: seek_tell + +shape_zoom_affine +~~~~~~~~~~~~~~~~~ + +.. autofunction:: shape_zoom_affine + +working_type +~~~~~~~~~~~~ + +.. autofunction:: working_type + +write_zeros +~~~~~~~~~~~ + +.. autofunction:: write_zeros + diff --git a/_sources/reference/nibabel.wrapstruct.rst.txt b/_sources/reference/nibabel.wrapstruct.rst.txt new file mode 100644 index 0000000000..63a27ccad4 --- /dev/null +++ b/_sources/reference/nibabel.wrapstruct.rst.txt @@ -0,0 +1,52 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`wrapstruct` +================= +.. automodule:: nibabel.wrapstruct + +.. currentmodule:: nibabel.wrapstruct +.. autosummary:: + + LabeledWrapStruct + WrapStruct + WrapStructError + + +.. currentmodule:: nibabel.wrapstruct + + +:class:`LabeledWrapStruct` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: LabeledWrapStruct + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`WrapStruct` +~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: WrapStruct + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`WrapStructError` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: WrapStructError + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/reference/nibabel.xmlutils.rst.txt b/_sources/reference/nibabel.xmlutils.rst.txt new file mode 100644 index 0000000000..1a8863272f --- /dev/null +++ b/_sources/reference/nibabel.xmlutils.rst.txt @@ -0,0 +1,52 @@ +.. AUTO-GENERATED FILE -- DO NOT EDIT! + +:mod:`xmlutils` +=============== +.. automodule:: nibabel.xmlutils + +.. currentmodule:: nibabel.xmlutils +.. autosummary:: + + XmlBasedHeader + XmlParser + XmlSerializable + + +.. currentmodule:: nibabel.xmlutils + + +:class:`XmlBasedHeader` +~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: XmlBasedHeader + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`XmlParser` +~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: XmlParser + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + + +:class:`XmlSerializable` +~~~~~~~~~~~~~~~~~~~~~~~~ + + +.. autoclass:: XmlSerializable + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: __init__ + diff --git a/_sources/tutorials.rst.txt b/_sources/tutorials.rst.txt new file mode 100644 index 0000000000..36cf7a7156 --- /dev/null +++ b/_sources/tutorials.rst.txt @@ -0,0 +1,11 @@ +.. _tutorials: + +***************** +General tutorials +***************** + +.. toctree:: + + coordinate_systems + neuro_radio_conventions + dicom/dicom_intro diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 0000000000..30fee9d0f7 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/contents.png b/_static/contents.png new file mode 100644 index 0000000000000000000000000000000000000000..6c59aa1f9c8c3b754b258b8ab4f6b95971c99109 GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfx!2~2XTwzxLQbwLGjv*C{Q@c%>8XN?UO#1VG zcLb|!+10i0Jzf{Gv>fyFaQYL)bKk!I{m<u>Jd!3^2Uu$-u=wds-dX_E&EV<k=d#Wz Gp$P!?(joW& literal 0 HcmV?d00001 diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 0000000000..d06a71d751 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 0000000000..f9bbedc660 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '5.2.0', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0002xNkl<Zcmb`G zgHi?o6ovOGdxdP*AltSE*&JruJwUGI3!FN?xxO>s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHD<M{a4P!N^sPbQKi=?mBx zoos%BSoiGXjr-;%$QixXMOVNSUNp6L0a1Oz&cgu)wqE?07u5I7qrQIu4Fij)Y3c&0 z@0u_#NH6I?Mk(n;dT}d~^J<WkTLqp|RW-hV56tKpXqu)k@V{?amI+5DOlEU@funz+ kySsbM>fiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/_static/graphviz.css b/_static/graphviz.css new file mode 100644 index 0000000000..8d81c02ed9 --- /dev/null +++ b/_static/graphviz.css @@ -0,0 +1,19 @@ +/* + * graphviz.css + * ~~~~~~~~~~~~ + * + * Sphinx stylesheet -- graphviz extension. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +img.graphviz { + border: 0; + max-width: 100%; +} + +object.graphviz { + max-width: 100%; +} diff --git a/_static/item.png b/_static/item.png new file mode 100644 index 0000000000000000000000000000000000000000..e52a3e2618650dd493851567264f6e99c8e55d4d GIT binary patch literal 378 zcmV-=0fqjFP)<h;3K|Lk000e1NJLTq000UA000UI1^@s6jWW-@00001b5ch_0Itp) z=>Px$G)Y83R2b7u&(AA^aRA5h_wzj8ZO<0kD5b<4sHGI;uo4F+yGU{K2e>#XManpk zA|-d_IJvlJrzIu1IEV`eKXQ`%cxKO-Js+nnpY!YRd6N@S6)-{}A)Dl$D`8Y1F40VF zGYPH^(@ZE&t3)V=93+DjL2~PGDTS6h`B`e?;%tnOClN&ov!TZS(Aw=nA2Ij>svmfE zg_Fr7*@1Izj=KpmcYFg_YkeqG1Y^K=q3DBE<~0%FXzqYjtDk!S<9|XBBk)Vuu_}bZ z@EoJ%wZiz?C_TUsfbCZB0w23%;Jt~U1iuX)j~yOci&-+YkG2=aacsPJ72G!%HtcLq zlfHb(Zd$YYtyiz4&~i8Bg?9EePa~QNKb(@#EfFMBhwDl5*MsyTxk!%48X*g0gq)iD Y10wf<#v%Iq%m4rY07*qoM6N<$f}aSXasU7T literal 0 HcmV?d00001 diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 0000000000..250f5665fa --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, is available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..d96755fdaf8bb2214971e0db9c1fd3077d7c419d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu=nj kDsEF_5m^0CR;1wuP-*O&G^0G}KYk!hp00i_>zopr08q^qX#fBK literal 0 HcmV?d00001 diff --git a/_static/navigation.png b/_static/navigation.png new file mode 100644 index 0000000000000000000000000000000000000000..fda6cd29ede1be6168ce8b5e02d099ea9055ccfb GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI|!2~2VCcCc%QudxMjv*C{TfG{24>0g7{2zat zIm@i@&@2&y-PR1xY$qjFM{J&XU;25XW1{_&{(Ldr+IaofPcAOcp2zd*+4*{gj8%&M U)(><J1C3(vboFyt=akR{0L>{V3jhEB literal 0 HcmV?d00001 diff --git a/_static/nibabel-logo.svg b/_static/nibabel-logo.svg new file mode 100644 index 0000000000..7c0d04ee82 --- /dev/null +++ b/_static/nibabel-logo.svg @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg2" + version="1.1" + inkscape:version="0.48.4 r9939" + width="200" + height="200" + sodipodi:docname="233707.png"> + <metadata + id="metadata8"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs6" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="640" + inkscape:window-height="480" + id="namedview4" + showgrid="false" + inkscape:zoom="1.18" + inkscape:cx="100" + inkscape:cy="100" + inkscape:window-x="65" + inkscape:window-y="24" + inkscape:window-maximized="0" + inkscape:current-layer="g2987" /> + <g + id="g2987" + transform="translate(0.02139466,4.7457627e-7)"> + <path + style="fill:#cec890" + d="m 124,185.31049 c -6.27392,-3.72336 -8.54492,-6.62669 -12.25663,-15.66932 -2.62755,-6.40139 -4.15462,-8.62683 -8.23423,-12 C 100.75449,155.36352 97.705572,152.6 96.733758,151.5 94.534237,149.01036 92,143.35535 92,140.93689 c 0,-2.93878 -1.586403,-3.16533 -9.631597,-1.37544 -10.2655,2.28386 -18.200058,1.57988 -25.905229,-2.29838 -3.279746,-1.6508 -7.420815,-3.5629 -9.202377,-4.24911 -7.188848,-2.76895 -12.354774,-11.79408 -10.903723,-19.04933 L 36.95,111 28.225,110.991 C 20.369803,110.983 18.978776,110.68269 14.271599,107.9831 8.2349892,104.5207 5.9333266,100.8209 5.6542723,94.130812 5.5240198,91.008118 4.6464222,88.312187 3.0137723,86.019341 -0.1633083,81.557543 -1.0696674,71.281464 1.3836359,67.53725 2.2726362,66.180464 3,63.17161 3,60.850908 3,54.875406 6.0339083,49.333205 13.652478,41.39146 17.288542,37.601157 21.441715,33.203023 22.881751,31.617829 26.116293,28.057242 33.998817,24.267198 39.993144,23.390396 42.471915,23.027822 45.625,21.954119 47,21.004391 c 5.089597,-3.515445 19.481015,-6.376637 33.013723,-6.563537 4.682548,-0.06467 9.490464,-0.640319 10.684258,-1.279219 3.486567,-1.865953 10.379969,-1.322172 15.302019,1.207089 3.73624,1.919914 5.09404,2.150011 8,1.355701 5.03127,-1.375238 13.83284,-0.314741 19.55861,2.35661 2.71776,1.267969 7.11855,2.45979 9.77953,2.648491 2.66098,0.1887 6.86283,1.294807 9.33745,2.458016 5.28503,2.484259 14.41557,11.137957 16.34084,15.487451 0.74142,1.674972 3.35539,4.315356 5.80884,5.867521 8.37723,5.299837 15.86543,13.601511 19.90705,22.069642 3.19821,6.70101 3.81686,9.102788 4.11158,15.962511 0.19081,4.441067 -0.0561,9.616067 -0.54879,11.5 -0.60701,2.321282 -0.4948,4.553451 0.34814,6.925333 2.82743,7.95587 1.10435,17.05986 -4.37724,23.12732 -4.31746,4.77891 -8.91408,6.87268 -15.08813,6.87268 -3.56057,0 -4.31121,0.26667 -3.37788,1.2 1.87716,1.87716 1.42318,9.46828 -0.81273,13.58984 -3.40414,6.27499 -11.36723,15.55378 -16.0915,18.75021 -6.76173,4.57498 -15.42843,5.88608 -25.84569,3.90997 -4.5071,-0.85499 -9.32353,-1.98369 -10.70317,-2.50823 -2.42406,-0.92162 -2.48614,-0.84418 -1.8455,2.30225 1.69951,8.34701 2.85071,11.13995 6.0524,14.68384 5.32166,5.89044 4.55779,6.60309 -2.55381,2.38261 z M 64,101.3 c 0,-2.010992 -0.289072,-2.410928 -1.132783,-1.567217 -0.62303,0.623027 -0.862153,1.838027 -0.531384,2.699997 C 63.251264,104.81836 64,104.3087 64,101.3 z m 2.662281,-1.55 c -0.277413,-0.6875 -0.504386,-0.125 -0.504386,1.25 0,1.375 0.226973,1.9375 0.504386,1.25 0.277412,-0.6875 0.277412,-1.8125 0,-2.5 z" + id="path3001" + inkscape:connector-curvature="0" /> + <path + style="fill:#d8d8ad" + d="m 125,185.89667 c -6.3567,-3.80648 -9.89156,-8.08273 -13.08043,-15.8239 -2.64329,-6.41674 -4.25454,-8.64136 -10.5548,-14.57277 -6.533151,-6.15067 -7.581069,-7.637 -8.636686,-12.25 -0.660762,-2.8875 -1.657393,-5.24963 -2.214735,-5.24918 -0.557342,4.5e-4 -4.388349,0.71668 -8.513349,1.59162 -10.234415,2.17079 -18.236164,1.44748 -25.64891,-2.3185 -3.218099,-1.63493 -7.614418,-3.8279 -9.769597,-4.87327 -2.155178,-1.04537 -5.297678,-3.62067 -6.983333,-5.7229 -2.645216,-3.29892 -3.064827,-4.63381 -3.064827,-9.75 l 0,-5.92777 -8.516666,-0.009 c -7.623654,-0.008 -9.06489,-0.3238 -13.745068,-3.0079 C 8.0522491,104.4159 5.7054475,100.47619 5.854671,93.852725 5.9136317,91.235685 5.5140206,88.817682 4.9666462,88.479386 0.74534363,85.870478 -1.6366541,71.54611 1.4681966,67.44113 c 0.8075082,-1.067622 1.4825082,-3.936554 1.5,-6.375406 0.040993,-5.715547 3.0780955,-11.912089 8.2022054,-16.734802 2.238686,-2.107007 4.803671,-4.688974 5.699968,-5.737704 6.972037,-8.157774 9.233907,-10.187617 13.622774,-12.225326 2.746229,-1.275048 7.021229,-2.614921 9.5,-2.977496 C 42.471915,23.027822 45.625,21.954119 47,21.004391 c 5.049478,-3.487734 19.582842,-6.4062 32.592461,-6.54494 4.450854,-0.04746 9.520811,-0.677943 11.266572,-1.401061 3.985683,-1.650923 10.821607,-0.941067 15.837427,1.644591 3.04619,1.570308 4.50045,1.774156 7.30354,1.023751 5.40483,-1.446909 14.42179,-0.238678 20.00468,2.680533 3.21073,1.678848 6.555,2.592735 9.48781,2.592735 2.52402,0 6.51799,0.93479 9.02111,2.111396 5.20845,2.448259 14.67919,11.525608 16.42663,15.744305 0.68487,1.653424 3.42594,4.329069 6.38025,6.227955 10.54508,6.777872 18.02624,16.268564 22.14456,28.092835 1.54363,4.431964 1.9187,17.228891 0.63965,21.823509 -0.38278,1.375 -0.13267,4.075 0.55578,6 2.82609,7.90202 1.08569,17.06145 -4.39446,23.12732 -4.31746,4.77891 -8.91408,6.87268 -15.08813,6.87268 -3.56057,0 -4.31121,0.26667 -3.37788,1.2 1.72972,1.72972 1.47559,9.36031 -0.43627,13.09966 -0.89996,1.76019 -3.03746,4.86407 -4.75,6.89752 -1.71255,2.03345 -4.19026,5.10694 -5.50602,6.82998 -3.62739,4.75019 -9.3545,8.05917 -16.56443,9.5705 -5.59961,1.17378 -7.70502,1.15406 -15.13554,-0.14171 -4.74713,-0.82783 -9.51942,-1.98054 -10.60509,-2.56157 -1.08567,-0.58103 -2.16973,-0.86063 -2.40904,-0.62133 -0.65969,0.6597 1.67411,10.88506 3.13299,13.72695 0.70585,1.375 2.45113,3.59094 3.87839,4.92431 4.55026,4.25095 3.22087,5.34121 -2.40499,1.97236 z M 122.45753,180.25 c -0.79719,-1.5125 -2.07749,-4.37572 -2.84509,-6.3627 -0.9833,-2.54531 -2.14884,-3.75669 -3.94489,-4.10002 l -2.54924,-0.48732 2.4077,4.75137 c 1.94817,3.84453 6.54677,8.94867 8.06234,8.94867 0.17525,0 -0.33362,-1.2375 -1.13082,-2.75 z m 21.2685,-16.75 c 1.7667,-1.925 3.62794,-3.5 4.13609,-3.5 0.50815,0 1.16591,-0.63066 1.46169,-1.40146 0.65216,-1.69949 -2.10302,-2.56015 -8.32381,-2.6002 -6.11674,-0.0394 -3.38456,-1.7275 4.19813,-2.59388 4.9743,-0.56835 5.51417,-0.83501 4.25,-2.09919 -1.98417,-1.98416 -1.93117,-2.0766 2.17399,-3.79185 4.38926,-1.83395 10.98876,-1.9812 11.80563,-0.26342 0.32694,0.6875 0.4045,0.22958 0.17236,-1.01759 -0.23393,-1.25681 0.29752,-2.98718 1.19227,-3.88193 1.48579,-1.48579 1.45879,-1.57097 -0.33902,-1.06973 -4.60587,1.28415 -9.45336,1.74174 -9.45336,0.89237 0,-0.50463 -1.77708,-1.20167 -3.94906,-1.54898 -2.17199,-0.34732 -5.55181,-1.57713 -7.51071,-2.73291 -3.48825,-2.05811 -3.70326,-2.06672 -10.43323,-0.41745 l -6.87158,1.68397 -6.44617,-2.57888 c -3.5454,-1.41838 -7.53586,-2.55792 -8.86771,-2.53231 -1.93361,0.0372 -1.41407,0.56774 2.57846,2.63313 5.97982,3.09345 6.4649,3.7324 6.48469,8.54172 0.0138,3.34441 -0.31393,3.81647 -3.23469,4.65981 -2.90632,0.83917 -2.58153,0.94794 3.07143,1.02859 5.84143,0.0833 6.19774,-0.0335 4.69249,-1.53875 -0.89592,-0.89592 -1.37806,-2.28272 -1.07143,-3.08179 0.30663,-0.79906 0.55751,-1.87265 0.55751,-2.38576 0,-1.91384 6.5713,-4.8961 10.79651,-4.89977 3.74535,-0.003 4.51503,0.38544 6,3.03012 1.26181,2.24724 2.22205,2.89531 3.70349,2.49947 3.26725,-0.87301 10.12594,-1.60195 8.5,-0.90338 -0.825,0.35445 -6,2.78286 -11.5,5.39646 -5.5,2.6136 -10.9,5.07445 -12,5.46856 -1.9267,0.69029 -1.91467,0.75621 0.32829,1.79854 1.28057,0.5951 3.42565,3.2475 4.76685,5.89424 2.94107,5.80393 4.76766,6.06644 9.13089,1.31225 z m -7.43974,-1.55249 c -1.06331,-2.81703 -0.96104,-3.12067 1.3466,-3.99804 3.05445,-1.16129 9.36711,-1.25333 9.36711,-0.13656 0,1.28313 -5.28924,5.89908 -7.5315,6.57278 -1.60479,0.48218 -2.27321,-0.03 -3.18221,-2.43818 z m -24.66652,-2.75631 c -0.86468,-0.86468 -1.87199,-1.27231 -2.23846,-0.90584 -0.95892,0.95892 1.65472,3.8104 2.82796,3.08531 0.58453,-0.36126 0.34569,-1.24428 -0.5895,-2.17947 z m -9.31072,-10.01452 c -0.71998,-0.17783 -2.01324,-0.17783 -2.873906,0 -1.289421,0.26641 -1.162965,0.75326 0.718446,2.76599 l 2.28331,2.44266 0.5906,-2.44266 c 0.38258,-1.58235 0.12954,-2.55655 -0.71845,-2.76599 z m 58.42012,4.21915 c -0.3323,-0.33229 -1.1948,-0.36781 -1.91667,-0.0789 -0.79773,0.31922 -0.56078,0.55618 0.60417,0.60416 1.05416,0.0434 1.64479,-0.19293 1.3125,-0.52522 z M 98.977764,139.75 c 0.02985,-1.00669 -0.745897,-0.94446 -2.953308,0.23691 -1.253269,0.67073 -1.66476,1.67257 -1.284401,3.12706 0.559425,2.13925 0.560431,2.13915 2.387567,-0.23691 1.005349,-1.30738 1.837912,-2.71456 1.850142,-3.12706 z m 4.670086,1.69091 c 0.0813,-1.40672 0.93856,-3.4314 1.90499,-4.49929 1.98799,-2.19671 1.66337,-2.35452 -1.98774,-0.96637 -2.8351,1.0779 -3.01756,1.70449 -1.58985,5.45965 1.22078,3.21089 1.48728,3.21184 1.6726,0.006 z m -30.961754,-4.04637 c -1.779247,-0.96451 -3.896697,-1.28756 -5.758726,-0.87859 -4.510461,0.99067 -2.437441,2.48889 3.381647,2.44401 l 5.190983,-0.04 -2.813904,-1.52538 z m 75.647814,-5.31411 c 0.33564,-1.6782 1.41446,-3.18318 2.53725,-3.53954 1.07433,-0.34098 3.62242,-1.94638 5.66241,-3.56757 2.04,-1.62119 6.09093,-3.69842 9.00206,-4.61607 3.52094,-1.10988 5.72689,-2.47926 6.58909,-4.09029 1.8695,-3.49318 4.9191,-4.94004 6.07161,-2.88062 0.49668,0.88751 1.75413,1.61366 2.79434,1.61366 1.04021,0 2.18292,0.47185 2.53934,1.04856 0.44301,0.7168 1.09446,0.67806 2.05902,-0.12245 C 187.75658,114.1272 187.2749,112 184.7,112 c -4.32439,0 -4.92264,-1.94437 -2.08701,-6.78301 2.14438,-3.65911 2.47347,-5.15478 1.93064,-8.774582 -0.35989,-2.399978 -0.34256,-8.206329 0.0385,-12.903002 C 185.18377,76.124855 185.52037,75 187.13752,75 c 1.39325,0 1.83325,-0.692828 1.74648,-2.75 -0.0779,-1.847923 -0.27144,-2.147788 -0.58986,-0.914145 -0.37034,1.434797 -1.05454,1.690113 -3.13195,1.168716 -1.46195,-0.366926 -2.71428,-0.743061 -2.78296,-0.835855 -0.0687,-0.09279 -0.85711,-1.608869 -1.75205,-3.369056 -1.77154,-3.484273 -2.07517,-5.904754 -0.83671,-6.670162 1.56515,-0.967319 7.13087,2.628882 8.08086,5.221322 0.78755,2.149177 0.98825,2.271703 1.06338,0.64918 0.0509,-1.1 0.36394,-3.0125 0.69558,-4.25 0.51343,-1.915869 0.21238,-2.25 -2.02723,-2.25 -1.44661,0 -3.41159,-0.38968 -4.36663,-0.865956 -3.30001,-1.645713 -8.74893,-3.386666 -12.17939,-3.891368 l -3.44296,-0.506542 4.69148,5.363061 c 7.73697,8.844521 9.19506,12.737971 9.13804,24.400805 -0.0423,8.661959 -0.40002,10.739431 -2.67319,15.52622 -5.26531,11.08759 -15.81191,19.71816 -28.81415,23.57941 -3.36587,0.99956 -4.83063,1.85398 -4.02834,2.34982 0.99337,0.61394 0.92263,1.43288 -0.33362,3.86219 -2.01793,3.90226 -1.99914,4.18236 0.2807,4.18236 1.27186,0 2.06283,-0.93916 2.45891,-2.91957 z m -77.882542,-1.56374 c 3.586252,-1.55363 3.771057,-1.80756 2,-2.74809 -1.073253,-0.56996 -3.222295,-2.21356 -4.775649,-3.65245 -2.759097,-2.55577 -2.857187,-2.57135 -4.25,-0.67502 C 62.641573,124.50875 62,125.9825 62,126.71613 c 0,0.73363 -1.359364,1.60574 -3.020809,1.93803 -1.661446,0.33229 -3.263003,0.99604 -3.559017,1.475 -0.296015,0.47896 -1.97415,0.90247 -3.729191,0.94113 -2.746448,0.0605 -2.912363,0.19848 -1.190983,0.99052 2.986277,1.37404 15.440246,0.41017 19.951368,-1.54412 z M 110,131.02811 c 7.54002,-1.66353 7.99177,-1.88078 4,-1.92356 -2.475,-0.0265 -6.975,0.80754 -10,1.85348 -7.020465,2.42744 -4.802279,2.45335 6,0.0701 z m -15.348643,-4.6326 c 2.077672,-0.55741 2.094797,-0.67865 0.5,-3.53973 -1.595889,-2.86305 -1.57206,-3.02794 0.709427,-4.90917 2.656347,-2.19032 9.058546,-2.62728 10.939216,-0.74661 1.47198,1.47198 1.56536,5.03464 0.16858,6.43142 -0.70856,0.70856 -0.0731,0.89077 2.02997,0.5821 2.4191,-0.35505 2.94012,-0.83141 2.48336,-2.27051 -1.45962,-4.59886 7.93735,-4.9407 12.10802,-0.44047 2.56187,2.7643 3.9507,3.1347 4.67745,1.24746 0.59282,-1.53947 9.25171,-4.19391 10.97763,-3.36527 0.69024,0.3314 2.06885,1.1679 3.06356,1.85891 1.49534,1.03877 2.01789,0.97531 3.01721,-0.36641 0.66475,-0.89253 3.2259,-1.95734 5.69143,-2.36626 2.46554,-0.40891 5.5284,-1.28358 6.80636,-1.94372 2.0243,-1.04565 2.12952,-1.36129 0.81693,-2.45065 -1.21438,-1.00784 -1.95611,-0.96549 -3.82358,0.21834 -4.00704,2.54014 -8.41085,2.95159 -12.22405,1.14211 -5.2669,-2.49931 -6.15263,-3.97381 -4.18811,-6.97204 1.40797,-2.14883 1.42979,-2.50501 0.15348,-2.50501 -0.81833,0 -1.95209,0.8674 -2.51946,1.92754 -0.82365,1.539 -0.50329,2.55541 1.58924,5.04224 1.44147,1.71308 2.45235,3.25788 2.24641,3.4329 -0.20594,0.17501 -3.79187,0.59435 -7.96874,0.93185 -5.81208,0.46963 -8.04154,0.27517 -9.5,-0.82864 C 121.35756,115.71263 119.4875,115.0493 118.25,115.0318 117.0125,115.01431 116,114.55 116,114 c 0,-0.55172 -2.6,-1 -5.8,-1 -6.27892,0 -8.2,-1.10712 -8.2,-4.72568 0,-2.29898 -0.0373,-2.30655 -3.25,-0.65937 -1.7875,0.91647 -5.131079,2.95302 -7.430175,4.52568 -2.299097,1.57265 -4.999097,2.87305 -6,2.88978 -1.654998,0.0276 -1.638678,0.12949 0.180175,1.12432 3.163473,1.73029 4.5,3.96864 4.5,7.5364 0,3.39322 0.657949,3.77576 4.651357,2.70438 z M 77.5,121.46408 l 0,-4.53591 -7,0.6661 c -3.85,0.36636 -7.151544,0.79657 -7.336764,0.95602 -0.637047,0.54841 4.729921,3.6077 9.529668,5.43213 2.643903,1.00496 4.807096,1.87005 4.807096,1.9224 0,0.0524 0,-1.94598 0,-4.44074 z m 119.33449,-9.06637 c 0.82225,0.50818 1.16551,-0.62238 1.16551,-3.83869 0,-5.11731 -1.2969,-5.95375 -2.80488,-1.80902 -0.5503,1.5125 -1.74773,4.55 -2.66097,6.75 l -1.66043,4 2.39763,-2.91131 c 1.40053,-1.70059 2.88233,-2.61175 3.56314,-2.19098 z m -139.565458,1.94635 c -0.677033,-0.27392 -2.027033,-0.29059 -3,-0.037 -0.972968,0.25354 -0.419032,0.47766 1.230968,0.49804 1.65,0.0204 2.446064,-0.18706 1.769032,-0.46099 z M 65.75,113.31067 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z m -10.605955,-1.3386 c 5.695775,-0.56537 11.666426,-1.4674 13.268113,-2.00451 3.614133,-1.21198 4.568722,-0.45167 2.014841,1.60477 -1.799484,1.44899 -1.662307,1.51116 2.073001,0.93958 5.382461,-0.82362 10.5,-2.49484 10.5,-3.42895 0,-1.64318 -5.684951,-3.19541 -14.92871,-4.07617 -5.32332,-0.50721 -10.667082,-0.66375 -11.875027,-0.34786 C 54.902924,104.99714 54,104.77419 54,104.11663 54,103.50248 54.520024,103 55.155609,103 c 0.635585,0 2.711691,-1.18688 4.613569,-2.63751 2.922593,-2.229175 4.64024,-2.682058 11.09439,-2.925206 C 75.063606,97.279056 86.825,96.843956 97,96.470394 l 18.5,-0.679202 3.8212,3.604404 c 2.88112,2.717654 4.60324,3.567544 7,3.454574 3.00712,-0.14174 3.03091,-0.17227 0.44042,-0.5653 -2.8585,-0.4337 -8.77282,-5.580843 -8.74631,-7.611793 0.0392,-3.001301 1.92583,-3.796242 10.07741,-4.246107 8.10404,-0.447243 19.39105,-2.876168 21.35728,-4.596013 C 149.9725,85.373931 150.76,85 151.2,85 c 1.15936,0 0.98186,5.755479 -0.25646,8.315741 -1.00179,2.071207 -0.9507,2.062904 0.98694,-0.160404 1.12388,-1.289565 2.52251,-4.12388 3.10806,-6.298479 0.91883,-3.41227 0.77923,-4.415642 -1.01923,-7.32561 -2.46376,-3.986458 -7.40906,-7.105302 -14.4316,-9.101558 L 134.5,68.983437 l 5.75,0.340554 c 6.24377,0.369799 7.27196,-0.472939 3.07384,-2.519425 -5.50902,-2.685523 -3.11199,-5.092614 4.96039,-4.981207 7.42241,0.102437 12.58908,8.05069 7.53459,11.590992 -2.13218,1.493439 -2.13945,1.573871 -0.32363,3.580333 2.25059,2.48688 3.5978,1.43933 3.72099,-2.893334 0.1141,-4.013041 1.00498,-4.5526 3.79143,-2.296269 C 167.01413,75.049364 165.394,87 160.94765,87 c -0.94291,0 -1.96669,0.964823 -2.27507,2.14405 -0.41391,1.582806 -0.26743,1.850803 0.55958,1.023794 0.75114,-0.751147 1.51543,-0.792291 2.31962,-0.124874 0.93088,0.772565 0.91593,1.819832 -0.0668,4.678405 -1.5266,4.44058 -4.76768,7.273175 -8.34576,7.293935 -1.45157,0.008 -3.29075,0.42751 -4.08707,0.93129 -1.14641,0.72528 -0.93821,1.02793 1,1.45368 2.72134,0.59777 5.83677,0.89001 7.62112,0.71487 1.84392,-0.18097 7.3898,-5.199632 7.15031,-6.470561 C 164.70496,98.015065 164.97435,96.375 165.42223,95 c 1.86231,-5.717305 6.1333,-7.617203 9.75516,-4.339464 2.41028,2.18127 3.10522,1.337033 1.57263,-1.910487 -0.99115,-2.100229 -1.7398,-2.502093 -3.86823,-2.076406 -1.60473,0.320945 -2.95727,0.01325 -3.45061,-0.785 -1.0136,-1.640042 -0.66126,-7.59021 0.58764,-9.923801 0.69042,-1.290069 0.2849,-2.711769 -1.5409,-5.402246 -3.02979,-4.464638 -3.12165,-6.160994 -0.37256,-6.879896 4.04714,-1.058352 1.49774,-3.122185 -3.47873,-2.816157 -2.86637,0.176267 -5.36297,-0.232871 -6.33262,-1.037778 -1.02142,-0.84788 -4.61139,-1.366621 -9.91971,-1.433368 -4.96915,-0.06248 -8.9165,-0.600491 -9.80284,-1.33609 -1.80678,-1.499493 -3.6965,-0.548739 -2.92183,1.470026 0.31718,0.826556 -0.79163,3.0073 -2.54367,5.002771 C 131.39768,65.477723 130,67.471791 130,67.963368 130,69.525132 133.07312,72 135.01241,72 c 3.51043,0 2.9783,1.778951 -0.77116,2.578086 -5.1879,1.105714 -11.22364,0.52124 -14.50622,-1.40472 -4.05896,-2.381479 -5.94508,-10.033628 -3.57131,-14.489107 1.02157,-1.917441 0.97521,-2.028826 -0.37949,-0.911833 -0.84876,0.699835 -1.89725,2.724835 -2.32997,4.5 C 112.34653,66.816639 112.13068,78 113.1507,78 113.61782,78 114,77.598145 114,77.106989 c 0,-2.078637 3.4216,-1.908332 8.22612,0.409443 6.15751,2.970482 7.38782,3.06788 8.02397,0.635224 C 130.80051,76.046833 134.7599,75 142.17045,75 c 3.92731,0 5.42978,0.50932 7.44383,2.523369 3.18263,3.182632 2.74955,5.709778 -1.12032,6.537434 -1.64668,0.352178 -4.73642,1.38257 -6.86608,2.28976 -2.37913,1.013454 -6.62046,1.651587 -11,1.655014 -8.07914,0.0063 -14.03523,1.383088 -17.38603,4.018826 -2.08562,1.640545 -4.0067,1.751261 -21.558842,1.242478 -21.744936,-0.630319 -21.340339,-0.703099 -38.517327,6.928639 -8.193146,3.64022 -11.636969,4.73319 -12.426372,3.94379 -0.789402,-0.7894 -0.584512,-1.65288 0.739307,-3.11568 C 43.055029,99.281712 43.089526,99 41.726416,99 c -3.759272,0 -7.023616,6.72903 -4.577405,9.43574 0.743044,0.82217 1.931231,2.18547 2.640416,3.02956 1.527883,1.81852 1.986762,1.83366 15.354618,0.50677 z m -21.913926,-5.39553 c 0.579361,-3.03073 -2.161527,-4.01331 -5.219771,-1.87123 -1.165471,0.81632 -3.107082,1.2434 -4.314693,0.94905 C 22.488045,105.36001 19.925,105.47402 18,105.90771 l -3.5,0.78852 3.5,1.0617 c 1.925,0.58393 6.03504,1.10228 9.133423,1.15188 5.199315,0.0832 5.669122,-0.0966 6.096696,-2.33327 z M 64,101.3 c 0,-2.010992 -0.289072,-2.410928 -1.132783,-1.567217 -0.62303,0.623027 -0.862153,1.838027 -0.531384,2.699997 C 63.251264,104.81836 64,104.3087 64,101.3 z m 2.662281,-1.55 c -0.277413,-0.6875 -0.504386,-0.125 -0.504386,1.25 0,1.375 0.226973,1.9375 0.504386,1.25 0.277412,-0.6875 0.277412,-1.8125 0,-2.5 z m 68.606749,2.59406 c -0.67703,-0.27392 -2.02703,-0.29059 -3,-0.037 -0.97297,0.25354 -0.41903,0.47766 1.23097,0.49804 1.65,0.0204 2.44606,-0.18706 1.76903,-0.46099 z M 36.70031,99.678795 c 0.439829,-0.726663 2.802112,-2.108999 5.249516,-3.071858 2.447405,-0.962859 5.984896,-3.098461 7.861091,-4.745782 C 53.834902,88.32805 56.954599,87.005652 61.3151,86.984687 63.066795,86.976265 65.175,86.533156 66,86 67.110332,85.282448 66.460886,85.015334 63.5,84.971762 61.3,84.939387 57.475,84.521546 55,84.043227 52.525,83.564908 50.337116,83.334891 50.138035,83.532077 49.839408,83.827861 49.469142,86.488158 49.063836,91.25 49.028726,91.6625 48.019449,92 46.820998,92 c -1.198451,0 -3.613417,0.518691 -5.366591,1.152647 -2.851295,1.031042 -3.547565,0.87808 -6.599646,-1.449855 -3.157155,-2.40808 -3.738409,-2.519665 -7.780567,-1.493656 -3.836487,0.973804 -4.529367,0.888862 -5.68932,-0.697467 -0.726444,-0.993472 -1.109016,-2.149 -0.850158,-2.56784 C 21.091617,86.042744 15.337174,81 13.752015,81 13.150022,81 11.834548,80.255256 10.828741,79.345012 9.0887789,77.770369 9,77.867462 9,81.345012 9,85.359325 9.1844004,85.506863 12.190741,83.897918 15.443403,82.157147 19,84.544694 19,88.46898 c 0,1.722061 -0.50354,3.63456 -1.118978,4.249998 -0.825304,0.825304 -0.04566,1.666546 2.970673,3.205362 3.28111,1.673898 3.972619,1.781405 3.497697,0.543777 C 23.481965,94.207639 26.874048,91 30.131935,91 c 1.898596,0 3.352298,0.8094 4.44277,2.47367 1.488664,2.271989 1.489794,2.604688 0.01386,4.08062 -1.574122,1.574122 -1.34558,3.44571 0.42076,3.44571 0.490211,0 1.251153,-0.59454 1.690983,-1.321205 z m 22.777932,-9.643589 c 1.163727,-1.882951 -4.644329,0.472929 -7.6341,3.096565 L 48.5,96.06638 53.758504,93.423939 c 2.892177,-1.453342 5.466059,-2.978272 5.719738,-3.388733 z M 6.6393423,82.943295 C 5.7669161,79.674744 5.8752722,78.000249 7.1970615,74.324507 8.0993451,71.815361 8.3341223,70.265878 7.7187886,70.881211 6.2211563,72.378844 3.28883,72.302753 2.6622807,70.75 2.3848684,70.0625 2.1223684,71.836778 2.0789474,74.69284 c -0.05456,3.588734 0.5693794,6.291672 2.0198285,8.75 2.7851062,4.720403 3.8765673,4.505792 2.5405664,-0.499545 z M 94.5,85.558836 l 6,-1.353895 -6.5,-0.02639 C 90.425,84.164033 85.925,84.758686 84,85.5 l -3.5,1.347844 4,0.03244 c 2.2,0.01784 6.7,-0.576809 10,-1.321451 z M 79.573795,81.880598 C 79.873126,81.396269 78.768034,81 77.118034,81 c -2.837625,0 -4.655046,1.129655 -3.567345,2.217355 0.726603,0.726603 5.387144,-0.307749 6.023106,-1.336757 z M 66.5,81.471164 C 64.3,80.678586 62.3875,80.023337 62.25,80.015056 62.1125,80.006775 62,79.538862 62,78.975249 62,78.411636 63.125,77.522774 64.5,77 c 3.62768,-1.379241 3.112747,-3.662466 -1,-4.434022 -3.186759,-0.59784 -4.016808,-1.506162 -3.583334,-3.921238 0.08443,-0.470393 -0.395052,-1.516233 -1.065513,-2.32409 -1.00203,-1.207372 -0.555806,-2.076414 2.506831,-4.882158 3.085528,-2.826716 3.550415,-3.741133 2.705042,-5.320727 C 63.501581,55.068696 61.682719,53.736444 60.021109,53.157203 58.359499,52.577963 57,51.40563 57,50.55202 57,49.644458 56.132273,49 54.910293,49 c -1.149339,0 -2.910604,-1.0125 -3.913921,-2.25 -1.003317,-1.2375 -2.170449,-1.905 -2.593626,-1.483333 -0.423177,0.421666 -0.236913,1.299166 0.413921,1.95 C 49.4675,47.8675 50,49.1488 50,50.063999 c 0,1.757766 -5.950924,6.276408 -9.75,7.403347 -3.275579,0.971652 -2.754018,2.255001 1.099268,2.70485 2.72145,0.317714 3.268616,0.08259 2.919009,-1.254306 C 43.857091,57.345512 48.194661,53 50.175351,53 51.741346,53 57,57.318656 57,58.604725 c 0,0.675735 0.529673,1.405166 1.177051,1.620959 2.563357,0.854452 -0.537233,2.774532 -4.486068,2.778054 L 49.5,63.007476 52.75,64.98904 c 4.218817,2.572263 4.456671,6.299868 0.5,7.835919 -1.5125,0.587181 -6.891049,0.995324 -11.952331,0.906985 -5.061282,-0.08834 -9.561282,0.201172 -10,0.643356 -0.985252,0.993038 4.638964,5.642551 6.702331,5.540785 1.024366,-0.05052 1.103638,-0.233915 0.25,-0.578366 C 37.5625,79.060307 37,78.442357 37,77.964498 c 0,-0.47786 2.1375,-0.220231 4.75,0.572509 5.59787,1.698623 6.262192,1.7686 4.25,0.44768 -3.824065,-2.510338 6.372983,-4.138758 11.445131,-1.827733 3.28742,1.497848 1.665398,3.785995 -2.817576,3.974687 L 51.5,81.263282 55,82 c 1.925,0.405195 6.2,0.776204 9.5,0.824466 l 6,0.08775 -4,-1.44105 z M 91.929715,78.25 c -0.143576,-1.532065 -1.791738,-4.706892 -1.85943,-3.581787 -0.03866,0.642516 -0.34343,1.880016 -0.677274,2.75 C 88.9947,78.456196 89.33849,79 90.393011,79 c 0.883844,0 1.575361,-0.3375 1.536704,-0.75 z M 88.078472,65.343771 C 86.225518,58.670663 87.312377,48.748434 90.889087,39.6849 c 1.736235,-4.39969 1.344502,-4.396537 -1.899995,0.0153 -1.656,2.251809 -3.681,4.351337 -4.5,4.665617 C 83.670091,44.680092 83,45.824796 83,46.909598 83,49.446862 82.123499,49.937427 78.744303,49.291452 76.525779,48.867355 76,48.227324 76,45.950811 76,44.044202 75.374866,42.936365 74.064275,42.5204 72.999627,42.182494 71.946629,41.139669 71.72428,40.203012 71.422676,38.93249 71.135625,39.15551 70.593963,41.081196 c -0.529755,1.883358 -0.09989,3.561633 1.589996,6.207674 1.273823,1.994563 2.730608,3.645525 3.2373,3.668804 0.506693,0.02328 1.735752,0.779431 2.731243,1.680338 1.533594,1.387884 2.058425,1.431824 3.436953,0.287747 1.390716,-1.154192 1.829073,-1.073873 3.018758,0.553117 C 85.373696,54.525737 86,56.671982 86,58.24831 c 0,3.36704 2.055518,12.029506 2.701256,11.383767 0.244494,-0.244494 -0.03576,-2.174232 -0.622784,-4.288306 z M 23.510113,57.820167 c 1.598199,-2.124691 5.219005,-5.456227 8.046235,-7.403415 5.229232,-3.601511 18.7498,-8.416369 23.634635,-8.416616 1.480041,-7.5e-5 2.994075,-0.490549 3.364521,-1.089943 0.406373,-0.657526 2.11558,-0.8477 4.309017,-0.479442 3.091169,0.518979 3.336036,0.435408 1.635479,-0.558176 -1.1,-0.642697 -2.802277,-1.998993 -3.782837,-3.013991 -0.980561,-1.014998 -3.60062,-2.136126 -5.822353,-2.491395 -4.013327,-0.641757 -4.037425,-0.672004 -3.717163,-4.665598 0.209907,-2.617487 -0.124583,-4.171296 -0.958897,-4.454372 -0.704688,-0.239096 -1.213898,-0.05503 -1.131579,0.409031 0.08232,0.464062 0.09638,2.98125 0.03125,5.59375 L 49,36 44.5,36 C 42.025,36 40,35.61571 40,35.146023 c 0,-1.520871 -4.979796,-6.276544 -5.946639,-5.679002 -0.515793,0.318778 -1.247593,2.645404 -1.626221,5.17028 -0.906673,6.046126 -4.784567,10.352429 -12.400221,13.770131 -3.314805,1.487596 -6.044223,3.016986 -6.065372,3.398644 -0.02115,0.381658 -0.133649,3.680513 -0.25,7.330788 L 13.5,65.773728 17.052149,63.728484 c 1.953682,-1.124884 4.859766,-3.783626 6.457964,-5.908317 z M 15.483532,62.5 c 0.392444,-1.1 0.952141,-3.677774 1.243771,-5.728386 0.442197,-3.10933 1.319221,-4.234676 5.282051,-6.777616 2.613498,-1.677077 6.151455,-4.386804 7.862128,-6.021615 3.378803,-3.228965 7.92739,-4.222305 6.339209,-1.384383 -0.488779,0.873399 -2.635333,2.567752 -4.770119,3.765227 -2.134786,1.197476 -4.825752,3.578508 -5.979924,5.291184 C 22.084976,56.65357 14.704325,64.68408 15.483532,62.5 z M 42.49267,39.381702 c 0.896134,-0.655269 3.917657,-1.939871 6.714497,-2.854671 4.608432,-1.507342 5.231503,-1.516932 6.646141,-0.102295 2.386728,2.386729 0.463535,3.329457 -7.67164,3.760553 -5.840883,0.309518 -6.989397,0.147287 -5.688998,-0.803587 z M 114,51.903907 C 114,40.349692 120.3706,28.707059 129.26842,24 c 7.68095,-4.063318 5.80761,-5.240805 -3.86451,-2.429042 -2.97215,0.864028 -5.45522,1.876528 -5.51793,2.25 -0.0627,0.373473 -0.26104,1.920319 -0.44073,3.437435 -0.51119,4.315863 -4.46876,10.508704 -7.52454,11.774448 -1.52735,0.63265 -3.02021,1.784072 -3.31747,2.558716 -0.63964,1.666866 -6.18302,1.897396 -7.17135,0.298231 -0.81921,-1.325507 -6.969946,-0.518057 -9.02112,1.184266 -2.567136,2.130534 -1.470893,2.952394 3.313176,2.483908 3.486085,-0.34138 5.204004,-0.02816 6.555944,1.195331 1.48435,1.343324 2.19524,1.431076 3.74628,0.462436 2.16302,-1.350825 2.78414,-0.588997 4.91977,6.034271 C 112.64275,58.512329 114,57.914112 114,51.903907 z m 20.79798,-8.491708 c 0.16388,-1.649832 1.31248,-4.272009 2.55243,-5.827059 l 2.25447,-2.827365 4.15772,2.121112 C 146.69634,38.375568 149.77393,39 154.21676,39 c 3.46305,0 7.75597,0.418587 9.53984,0.930194 3.45979,0.992255 4.00642,0.411149 1.9934,-2.119124 -1.45098,-1.823811 -7.30882,-3.52427 -6.25243,-1.815005 0.45401,0.734612 -0.86843,0.925168 -4.16621,0.600327 -2.65725,-0.261745 -5.41535,-0.503011 -6.12911,-0.536146 -0.71376,-0.03314 -2.41294,-1.263563 -3.77596,-2.734283 -1.89706,-2.046954 -2.75354,-2.398716 -3.65225,-1.5 -1.89548,1.895475 -3.7361,1.37258 -6.42749,-1.825963 -1.83559,-2.181475 -3.38682,-2.994816 -5.68544,-2.981 l -3.16111,0.019 4.75,2.982836 c 2.6125,1.64056 4.75,3.700043 4.75,4.576629 0,2.459975 -3.71948,7.10946 -6.23892,7.798872 -1.24359,0.340294 -3.4658,2.375288 -4.93823,4.52221 l -2.67714,3.903494 6.17714,-2.205074 c 5.54497,-1.979404 6.20765,-2.512067 6.47513,-5.204769 z M 145.76793,45 c -1.4547,-2.329339 -3.51358,-2.507828 -6.12338,-0.530847 -1.69767,1.286022 -1.48507,1.438536 2.5,1.793489 2.3955,0.213369 4.47176,0.466562 4.61392,0.562651 C 146.90063,46.921382 146.45489,46.1 145.76793,45 z M 98.249012,26.897074 c 2.061958,-2.659656 5.083588,-5.82243 6.714728,-7.028387 l 2.96572,-2.192648 -2.57904,-1.33802 c -3.33085,-1.728066 -5.2704,-1.731208 -2.90927,-0.0047 1.73871,1.271383 1.74279,1.456339 0.0877,3.982389 -0.95466,1.456996 -3.296978,3.61398 -5.205157,4.7933 -3.406245,2.105175 -5.381236,5.371086 -5.264836,8.706105 0.05159,1.47816 0.204969,1.45378 1.25,-0.198694 0.655156,-1.035977 2.878248,-4.059676 4.940205,-6.719332 z M 72,30.968615 C 72,30.401354 71.2125,29.646677 70.25,29.291557 66.846238,28.035717 65.920279,25 68.940983,25 c 2.732614,0 3.318541,-1.468286 1.285436,-3.221201 -1.561832,-1.346589 -1.987401,-1.180771 -4.463954,1.739329 l -2.737534,3.227822 3.737534,2.566914 C 70.901406,32.155461 72,32.502761 72,30.968615 z" + id="path2999" + inkscape:connector-curvature="0" /> + <path + style="fill:#8e8e72" + d="m 124.5,185.4306 c -6.34472,-3.29308 -8.7167,-6.57821 -14.59562,-20.2145 -1.48225,-3.43811 -3.40162,-5.97833 -5.49456,-7.27183 -6.752977,-4.17357 -10.144995,-9.3051 -12.966094,-19.61543 -0.235964,-0.86239 -1.852703,-0.75185 -6.132089,0.41926 -3.1964,0.87473 -9.411637,1.62675 -13.811637,1.67116 -7.317876,0.0739 -8.682124,-0.24805 -16,-3.77533 -4.4,-2.12084 -9.051402,-4.3552 -10.336448,-4.96524 -1.285047,-0.61005 -3.722547,-2.85927 -5.416667,-4.99827 -2.652219,-3.3487 -3.080218,-4.7083 -3.080218,-9.78476 l 0,-5.89566 -8.083334,-0.022 C 18.950978,110.95187 14.018364,109.06282 9.1732513,103.54454 6.3149016,100.28906 5.8972345,99.142501 6.1099234,95.13524 6.3058902,91.443038 5.7698325,89.609313 3.4853632,86.157247 -0.11448216,80.717513 -1.1650755,71.427075 1.3803242,67.542304 2.2711459,66.182739 3.0098829,63.367034 3.021962,61.285183 3.0549042,55.60754 6.4360814,49.228608 12.798453,42.84085 c 3.135851,-3.148364 6.775973,-7.13397 8.089161,-8.856902 3.36786,-4.418706 9.133423,-7.785252 16.384106,-9.566772 3.425554,-0.841671 8.260859,-2.600836 10.745122,-3.909255 C 53.534995,17.601603 69.842403,14.542159 80,14.507538 c 4.125,-0.01406 9.23366,-0.63414 11.352577,-1.377956 4.536147,-1.592351 10.169713,-0.9241 15.610823,1.851746 3.17294,1.618712 4.40003,1.75711 7.64214,0.86192 5.20494,-1.437152 12.38404,-0.452446 19.09248,2.618777 3.05945,1.400665 7.39401,2.542353 9.67282,2.547744 8.0994,0.01916 19.61901,8.069626 25.36483,17.726177 1.059,1.77977 3.9142,4.645944 6.34489,6.369274 7.01761,4.9754 14.78813,12.96886 17.88175,18.39478 5.44235,9.5454 7.50197,21.907566 5.06539,30.403403 -0.72931,2.542974 -0.57193,4.614245 0.62978,8.288257 4.53568,13.86703 -5.39275,28.80834 -19.143,28.80834 -4.22303,0 -4.50315,0.15265 -3.54966,1.93426 2.46472,4.60538 0.7917,11.31677 -4.25664,17.07562 -1.7645,2.01285 -3.95551,5.05053 -4.86892,6.75042 -2.16973,4.03799 -10.23453,9.84361 -15.53208,11.18111 -6.16529,1.55659 -15.8535,1.1934 -23.80718,-0.89247 -3.85,-1.00968 -7.18473,-1.66151 -7.41051,-1.44852 -0.73585,0.69418 2.11322,11.77932 3.61758,14.07526 0.80593,1.23 1.19419,2.67506 0.86281,3.21125 -0.33138,0.53618 -0.0756,1.3005 0.56832,1.69848 0.73122,0.45192 0.90292,0.29014 0.45729,-0.4309 C 125.20305,183.51953 125.25028,183 125.70044,183 c 0.45015,0 1.38053,0.9 2.06749,2 1.49977,2.40152 0.72588,2.50349 -3.26793,0.4306 z m -2.49806,-6.16579 C 120.90087,177.21045 120,174.79055 120,173.88725 c 0,-0.9033 -0.5625,-2.08247 -1.25,-2.62037 -1.40547,-1.09965 -5.75,-2.3264 -5.75,-1.6236 0,2.58761 8.22242,13.35672 10.19811,13.35672 0.44318,0 -0.0951,-1.68084 -1.19617,-3.73519 z M 142,165.5 c 0,-0.825 0.3375,-1.50208 0.75,-1.50463 0.4125,-0.003 2.25316,-1.41335 4.09036,-3.13513 4.01983,-3.76729 3.08439,-4.81476 -4.34036,-4.86024 -3.60094,-0.0221 -4.58028,-0.30187 -3.5,-1 0.825,-0.53316 4.41263,-0.97627 7.97251,-0.98469 6.14509,-0.0145 6.36008,-0.0941 4.25,-1.57201 -3.07719,-2.15535 -2.78968,-3.30837 1.24537,-4.99433 4.25893,-1.77949 10.18829,-1.88803 10.86984,-0.19897 0.27741,0.6875 0.53991,0.1025 0.58333,-1.3 0.0434,-1.4025 0.57395,-3.045 1.17895,-3.65 0.8,-0.8 -0.53813,-1.1 -4.90646,-1.1 -7.62913,0 -11.84492,-0.90029 -15.98144,-3.41286 -2.43574,-1.47949 -4.25,-1.83797 -7,-1.3831 -11.76908,1.94668 -13.72363,1.87682 -18.78067,-0.6713 -4.7445,-2.39063 -5.13958,-2.4311 -10.42267,-1.06754 -3.02019,0.77951 -5.87821,1.80425 -6.35117,2.27721 -1.16143,1.16143 0.12413,6.63154 1.90608,8.11043 1.20896,1.00335 1.34056,0.71833 0.83515,-1.80874 -1.23813,-6.19064 3.16567,-9.53058 8.8012,-6.67504 5.43761,2.75526 6.79998,4.44647 6.79998,8.44127 0,3.29423 -0.3567,3.81477 -3.25,4.74292 -2.93388,0.94117 -2.56913,1.04955 3.75,1.11425 5.20722,0.0533 6.5518,-0.18937 5.25,-0.9476 -1.03657,-0.60374 -1.75,-2.21377 -1.75,-3.94927 0,-2.40663 0.70737,-3.29085 3.96016,-4.95031 6.54761,-3.34034 12.24071,-2.34043 13.41969,2.35698 0.60408,2.40686 0.65486,2.41652 5.32182,1.01197 8.44422,-2.54134 6.41448,-0.99923 -6.72681,5.11073 -12.70621,5.90767 -12.86274,6.02033 -10.17253,7.32122 1.70228,0.82316 3.42277,2.99073 4.56402,5.75 1.57154,3.79964 2.24386,4.42878 4.73271,4.42878 1.91195,0 2.90094,-0.51138 2.90094,-1.5 z m -5.35062,-3.73275 c -0.76714,-2.93355 0.25755,-3.81095 5.22954,-4.47783 5.09295,-0.68311 5.65957,1.47889 1.21671,4.64249 -3.7483,2.66902 -5.71838,2.6187 -6.44625,-0.16466 z m -23.98521,-2.20003 C 112.3334,158.70525 111.12764,158 109.9847,158 c -2.02662,0 -2.03359,0.0599 -0.28138,2.42138 1.87277,2.52393 4.01949,1.90463 2.96085,-0.85416 z M 103.38401,152.25 c 0.3395,-0.9625 0.84967,-2.22304 1.1337,-2.80119 0.32885,-0.66939 -0.76101,-0.90206 -3.00065,-0.6406 -3.98817,0.4656 -4.176465,0.80567 -1.862072,3.36305 2.069272,2.28652 2.943762,2.30499 3.729022,0.0787 z m 56.88502,1.09406 c -0.67703,-0.27392 -2.02703,-0.29059 -3,-0.0371 -0.97297,0.25354 -0.41903,0.47766 1.23097,0.49804 1.65,0.0204 2.44606,-0.18706 1.76903,-0.46099 z M 98.993411,139.75 c 0.0087,-0.9929 -2.161294,-0.93001 -3.801401,0.11017 -0.863579,0.54769 -1.074838,1.7585 -0.621778,3.56363 l 0.686213,2.7341 1.865188,-2.82895 c 1.025854,-1.55592 1.868154,-3.16645 1.871778,-3.57895 z m -25.806785,-2.33184 c -1.654801,-1.15906 -3.352864,-1.39692 -6.353495,-0.88997 -5.393208,0.91118 -3.134676,2.43564 3.639375,2.4565 4.81796,0.0148 4.902315,-0.0339 2.71412,-1.56653 z m 75.506414,-5.41588 c 0.62233,-1.64875 1.95849,-3.28972 2.96924,-3.64659 1.01074,-0.35688 2.96272,-1.63271 4.33772,-2.83518 2.94425,-2.57482 12.8289,-6.74429 14.11071,-5.95208 0.48911,0.30228 0.88929,-0.0678 0.88929,-0.82232 0,-0.75456 1.30477,-2.62198 2.89949,-4.14982 2.52653,-2.42056 3.01538,-2.57082 3.80037,-1.16812 0.49549,0.88538 1.8924,1.80072 3.10427,2.03411 1.21186,0.23338 2.59156,0.66423 3.06598,0.95745 0.47443,0.29321 1.62705,-0.31161 2.56139,-1.34403 1.36184,-1.50483 1.43794,-2.04035 0.38364,-2.69999 -0.72333,-0.45257 -1.76514,-0.8787 -2.31514,-0.94696 -0.55,-0.0683 -1.5625,-0.19266 -2.25,-0.27644 -1.89632,-0.23107 -1.49995,-2.99254 0.91667,-6.38637 1.19166,-1.67354 2.06426,-4.21801 1.93909,-5.654372 C 184.7741,95.305581 184.64447,86.287219 184.83463,80.25 184.97726,75.721789 185.27497,75 187,75 c 2.32514,0 2.22416,0.32237 2.42767,-7.75 0.14889,-5.905486 0.0305,-6.25 -2.14862,-6.25 -1.2684,0 -3.08758,-0.38968 -4.04262,-0.865956 -3.25873,-1.625128 -8.73159,-3.38411 -12.06652,-3.878191 l -3.33008,-0.493364 5.58346,7.226472 c 6.90076,8.931393 9.07541,15.522503 8.27429,25.078334 -1.44047,17.181885 -14.85325,31.899615 -33.65473,36.929055 -3.52335,0.9425 -4.1133,1.38472 -2.81593,2.11076 1.45889,0.81644 1.48258,1.22253 0.2133,3.65568 -1.86172,3.56881 -1.808,4.23721 0.34054,4.23721 1.06002,0 2.23873,-1.21329 2.91228,-2.99772 z M 183.6563,71.867465 c -2.1136,-1.22861 -5.01172,-7.48337 -4.1291,-8.911483 2.09027,-3.382127 8.4728,1.784333 8.4728,6.858469 0,3.357604 -1.1579,3.904876 -4.3437,2.053014 z M 110.5,131.08667 c 8.2153,-1.76876 8.58454,-1.9442 4.2349,-2.01219 -5.31243,-0.083 -16.7349,2.75424 -16.7349,4.15686 0,0.49689 0.7875,0.65359 1.75,0.34823 0.9625,-0.30536 5.8,-1.42717 10.75,-2.4929 z m -40,-0.48879 c 3.645164,-1.6264 3.832875,-1.88732 2.116036,-2.9413 C 71.579855,127.02046 69.489895,125.4875 67.97168,124.25 66.453464,123.0125 64.983197,122 64.70442,122 c -0.278778,0 -1.436141,1.575 -2.571919,3.5 -1.47552,2.50082 -2.77153,3.5 -4.539759,3.5 -1.361089,0 -2.752823,0.45 -3.092742,1 -0.339919,0.55 -1.828976,1.00689 -3.309017,1.01531 -2.148081,0.0122 -2.38836,0.22194 -1.190983,1.03947 2.279163,1.55614 15.919714,0.58673 20.5,-1.4569 z m 52.22917,-2.20205 c -0.3323,-0.33229 -1.1948,-0.36781 -1.91667,-0.0789 -0.79773,0.31922 -0.56078,0.55618 0.60417,0.60416 1.05416,0.0434 1.64479,-0.19293 1.3125,-0.52522 z m -26.349255,-1.98812 c 1.323713,-0.50796 1.235799,-1.00847 -0.617419,-3.51508 -1.978657,-2.67628 -2.02629,-3.05741 -0.564768,-4.51893 0.877877,-0.87788 3.651334,-1.82779 6.163232,-2.11092 4.17677,-0.47078 4.66821,-0.29287 5.75009,2.08161 0.93001,2.04115 0.90723,2.92866 -0.10653,4.15016 -1.74636,2.10424 -0.93355,2.64126 2.8518,1.88419 2.49633,-0.49927 2.93997,-0.91927 2.07363,-1.96314 -2.72191,-3.2797 3.47716,-5.26531 8.70029,-2.78677 1.95438,0.92741 3.78524,2.29032 4.06858,3.02869 0.66775,1.74012 3.93518,1.73865 4.60315,-0.002 0.28378,-0.7395 2.59143,-1.92565 5.12811,-2.63587 4.04422,-1.13232 4.83475,-1.08989 6.41978,0.34455 2.195,1.98644 4.7506,2.11944 5.45497,0.28388 0.28534,-0.74359 2.60163,-1.63747 5.14731,-1.9864 4.94545,-0.67785 8.54786,-2.19073 8.54786,-3.5898 0,-1.34965 -3.13358,-2.20381 -4.37675,-1.19303 -0.61779,0.50231 -2.87172,1.39063 -5.00875,1.97406 -4.26828,1.16527 -8.68293,-0.0641 -11.94537,-3.32656 -1.62677,-1.62678 -1.63596,-1.92796 -0.12897,-4.22791 1.51231,-2.30808 1.5054,-2.45332 -0.10161,-2.13736 -0.9483,0.18644 -2.20979,1.11012 -2.80331,2.05262 -0.86566,1.37466 -0.50568,2.31217 1.81992,4.73956 1.59447,1.66427 2.70684,3.1934 2.47194,3.39807 -0.23491,0.20466 -3.64456,0.6294 -7.57701,0.94385 -5.30413,0.42415 -7.62753,0.20991 -9,-0.82988 -1.01755,-0.77089 -2.58615,-1.41593 -3.48578,-1.43343 -0.89963,-0.0175 -2.92463,-0.71 -4.5,-1.53892 -1.57841,-0.83052 -4.0209,-1.26091 -5.44059,-0.9587 C 105.75464,113.42166 102,111.48129 102,108.43926 l 0,-2.61025 -4.75,2.75356 c -2.6125,1.51445 -6.712669,3.78972 -9.111488,5.05613 l -4.361487,2.30258 2.522722,1.14943 c 2.523862,1.14995 4.528575,6.76002 3.18974,8.9263 -0.663391,1.07339 4.367923,1.35867 6.890428,0.3907 z M 78.2,124.8 c -1.621854,-1.62185 -1.513658,-4.79602 0.229104,-6.72126 1.297417,-1.43326 0.603437,-1.49314 -7.531208,-0.64976 l -8.960313,0.92897 3.233271,2.07103 C 71.246153,124.32042 80.988929,127.58893 78.2,124.8 z m 118.29766,-11.43927 c 1.22359,0.46953 1.50234,-0.43817 1.50234,-4.89211 0,-3.00774 -0.3375,-5.46799 -0.75,-5.46723 -0.4125,7.7e-4 -1.81204,2.58827 -3.11009,5.75 -3.40644,8.29728 -3.54458,9.0174 -1.22596,6.39072 1.20534,-1.36548 2.71368,-2.11524 3.58371,-1.78138 z m -128.828728,0.1569 c 5.592912,-0.79516 11.663625,-2.05563 13.490473,-2.80107 l 3.321542,-1.35533 -2.490474,-1.60391 c -3.233496,-2.08243 -11.63849,-3.4344 -20.738378,-3.33583 -3.986347,0.0432 -7.248847,-0.0248 -7.25,-0.15117 C 54.000943,104.144 55.8,103.12236 58,102 c 2.2,-1.12236 4,-2.439334 4,-2.926617 0,-0.963449 11.387154,-1.792672 36.782946,-2.67857 l 16.282944,-0.568008 3.96994,3.586598 c 3.76477,3.401247 4.31861,3.581447 10.71705,3.486917 3.71092,-0.0548 7.87212,-0.44201 9.24712,-0.86041 1.375,-0.4184 -1.10991,-0.54127 -5.52203,-0.27305 -7.61072,0.46267 -8.18753,0.34841 -11.25,-2.228486 -3.22524,-2.713867 -4.31025,-6.751455 -2.16978,-8.074337 0.582,-0.359698 4.7445,-0.816202 9.25,-1.014453 4.50562,-0.198256 11.06284,-1.280479 14.57208,-2.40502 7.88207,-2.525815 8.11973,-2.525195 8.11973,0.02118 0,2.476327 -1.4967,5.54238 -4.36128,8.934259 -1.16124,1.375 -0.19944,0.715739 2.13734,-1.465024 3.9105,-3.649425 6.20379,-8.336145 6.21836,-12.708251 0.0148,-4.436462 -8.88729,-11.038254 -17.33817,-12.857999 -3.99068,-0.859323 -3.92719,-0.883208 1.59375,-0.599578 6.51669,0.334785 7.70087,-1.175574 2.5,-3.188611 -3.11966,-1.207489 -3.17215,-1.316542 -1.30887,-2.719237 1.06762,-0.803715 3.87302,-1.4613 6.23422,-1.4613 5.6806,0 10.96408,4.316155 9.99755,8.167145 -0.34619,1.379306 -1.51028,2.918459 -2.58688,3.420342 -1.92818,0.898863 -1.92892,0.94731 -0.0497,3.238796 2.35288,2.869011 3.54038,2.243533 4.39561,-2.315238 C 160.66279,67.950117 165,71.222242 165,78.711752 165,82.890407 162.74063,87 160.4433,87 159.64948,87 159,87.188196 159,87.418213 c 0,0.230016 -0.26055,1.097183 -0.57899,1.927036 -0.43481,1.133094 -0.0613,1.373439 1.5,0.965156 2.41847,-0.632444 2.47059,-0.349495 0.90079,4.890048 C 159.5577,99.419626 156.0614,102 151.60868,102 c -4.19373,0 -3.90376,1.83131 0.49884,3.15036 3.74146,1.12097 4.53289,1.03549 7.77886,-0.84016 2.87176,-1.65942 4.02421,-3.27262 5.61362,-7.857955 2.71812,-7.841583 4.63601,-8.87821 9.70204,-5.243979 2.36953,1.699839 3.09929,0.547185 1.65728,-2.617678 -0.775,-1.700942 -1.74571,-2.464426 -2.67832,-2.106551 -0.80451,0.308722 -2.29936,0.295785 -3.32188,-0.02875 -2.1253,-0.674544 -2.53263,-5.553628 -0.83616,-10.015688 0.86123,-2.265205 0.62408,-3.213575 -1.5,-5.998378 -3.07944,-4.037361 -3.11996,-4.800886 -0.35227,-6.63856 3.19324,-2.120234 1.49126,-3.77121 -3.29321,-3.194516 -2.71042,0.3267 -4.86932,-0.028 -6.44188,-1.058383 C 156.77731,58.46321 153.57906,58 147.73518,58 142.94815,58 138.92627,57.52627 138.28713,56.887132 136.74276,55.342761 135,56.666916 135,59.384703 c 0,1.246668 -1.14371,3.341133 -2.54159,4.654367 -3.40439,3.198259 -2.88372,6.18852 1.29159,7.417727 1.7875,0.526238 3.25,1.277983 3.25,1.670544 0,1.107794 -6.06354,2.230724 -10.5,1.944536 -5.64419,-0.364095 -9.3417,-2.8432 -10.50939,-7.046327 -1.31328,-4.727159 -1.24132,-6.021197 0.52297,-9.404148 1.35797,-2.603873 1.35187,-2.754626 -0.0639,-1.579606 -2.69483,2.236508 -4.19964,7.353724 -4.19964,14.281161 0,3.672374 0.17486,6.677043 0.38857,6.677043 0.21371,0 1.27289,-0.552269 2.35373,-1.227265 1.55272,-0.969687 2.59927,-0.969687 4.98643,0 1.6617,0.674996 4.341,1.764497 5.95401,2.421114 2.62606,1.069008 3.12863,0.951927 4.80609,-1.119646 1.54578,-1.908959 3.08756,-2.393806 8.81726,-2.772788 6.46701,-0.427749 7.1366,-0.275854 9.74951,2.211672 3.63157,3.457297 3.16137,5.792155 -1.31637,6.536548 -1.91907,0.319034 -4.59513,1.179199 -5.94679,1.911478 -1.35165,0.732278 -7.3514,1.65851 -13.33277,2.058292 -9.18989,0.614233 -11.36605,1.092978 -14.04245,3.08928 C 112.33275,92.849947 110.31683,93.435311 107,93.335017 73.818921,92.331696 68.798355,92.793623 57.574052,97.882551 45.974446,103.14164 43.789838,104 42.004633,104 c -3.568592,0 -1.05299,-2.6875 6.812949,-7.278504 4.22533,-2.466138 8.733459,-5.023809 10.018064,-5.683712 1.284606,-0.659904 2.095077,-1.440395 1.801047,-1.734424 -1.010497,-1.010498 -7.104532,1.757663 -10.11895,4.596441 -1.659759,1.563051 -5.212959,3.658203 -7.896001,4.655894 -3.812791,1.41779 -5.18481,2.547665 -6.281812,5.173165 -1.352936,3.23803 -1.040342,5.82205 0.58294,4.81881 0.431571,-0.26673 1.290829,0.62593 1.909463,1.98369 0.941499,2.06636 1.820844,2.4673 5.396228,2.46044 4.747053,-0.009 20.796984,-1.7325 24.738472,-2.65633 2.102224,-0.49273 2.316138,-0.3634 1.25791,0.76048 -0.701282,0.74479 -5.426282,1.87313 -10.5,2.50743 C 54.651224,114.23767 52.075,114.80315 54,114.86 c 1.925,0.0568 8.076019,-0.54722 13.668932,-1.34237 z M 31.5,109.15032 c 2.412477,-0.78444 3.056992,-4.7226 0.907866,-5.5473 -0.844006,-0.32388 -2.896667,0.11551 -4.561468,0.97641 -1.664802,0.8609 -3.721706,1.29866 -4.570898,0.97279 -1.748132,-0.67082 -8.654057,0.40256 -7.838317,1.2183 0.814963,0.81496 9.810334,3.09856 12.062817,3.06231 1.1,-0.0177 2.9,-0.32483 4,-0.68251 z m 32.731363,-7.72035 C 63.902914,99.711795 63.407675,99.192325 62.737252,99.862748 61.626446,100.97355 62.425761,104 63.829943,104 c 0.490992,0 0.671631,-1.15652 0.40142,-2.57003 z m 2.872262,-1.726345 c -0.804833,-0.804833 -1.095392,-0.304951 -1.073216,1.846375 0.02666,2.58611 0.162791,2.72225 1.103624,1.10362 0.769152,-1.32326 0.760537,-2.15905 -0.03041,-2.949995 z M 36.957547,99.551152 c 0.661341,-0.796866 2.853941,-1.989917 4.872445,-2.651224 2.018504,-0.661307 5.484449,-2.683181 7.702099,-4.493054 C 54.253628,88.553524 57.9022,87.005904 62.3151,86.984687 64.066795,86.976265 66.175,86.533156 67,86 c 1.121282,-0.724628 0.587665,-0.973241 -2.11351,-0.984687 -1.987431,-0.0084 -5.997766,-0.467478 -8.911856,-1.020124 -2.91409,-0.552645 -5.500895,-0.802261 -5.748455,-0.554701 -0.24756,0.24756 -0.558972,1.833971 -0.692026,3.525359 -0.307101,3.903869 -0.648621,4.210232 -6.332605,5.680691 -4.417445,1.142803 -4.926823,1.062078 -8.429579,-1.335895 -2.800809,-1.917423 -4.417466,-2.384108 -6.5,-1.876371 -5.553398,1.353957 -6.758801,1.158336 -7.087047,-1.150138 C 20.873849,86.096435 15.759588,81 13.875309,81 13.341126,81 11.87043,79.798324 10.607094,78.329609 l -2.2969739,-2.670392 0.2406032,3.920392 c 0.1323317,2.156215 0.2875547,4.534645 0.3449399,5.285401 0.082595,1.080565 0.6399176,1.014084 2.6745088,-0.319032 2.360797,-1.546853 2.768114,-1.554345 5,-0.09196 2.887093,1.891695 3.413037,7.231455 0.81063,8.230092 -1.250711,0.479943 -0.738671,1.154355 2.25,2.963492 4.784485,2.896199 5.40741,2.917435 5.107408,0.174116 -0.159831,-1.461553 0.640759,-2.682612 2.433164,-3.711058 2.3305,-1.337194 3.01017,-1.351464 5.326453,-0.111827 2.65811,1.422577 2.863189,2.8751 1.02378,7.251163 -0.9209,2.190884 1.678524,2.418714 3.43594,0.301152 z M 7.5777112,85.75 C 5.8844424,79.938322 5.8585009,77.174309 7.4680125,74.061857 9.3238717,70.473021 8.8802722,69.02455 6.524166,70.979944 5.3691694,71.938506 4.6645752,71.966512 3.6151534,71.095569 0.22911193,68.285404 0.96181,78.741035 4.5801729,84.866435 6.7264625,88.499814 8.5341314,89.032649 7.5777112,85.75 z M 90,86.487182 c 3.575,-0.348996 7.85,-1.239835 9.5,-1.979641 l 3,-1.345103 -4.11351,-0.08122 C 93.059224,82.976035 85.101827,84.50116 80.85539,86.441251 L 77.5,87.974246 l 3,-0.426263 c 1.65,-0.234445 5.925,-0.711805 9.5,-1.060801 z M 78.75,83.013655 c 2.166935,-0.02367 1.354221,-1.760578 -1.037742,-2.21783 C 74.617142,80.204156 73,80.857614 73,82.699965 c 0,1.10208 0.63278,1.363719 2.25,0.930321 1.2375,-0.331637 2.8125,-0.609121 3.5,-0.616631 z M 69.5,82.327908 C 65.759237,81.504774 62,79.76018 62,78.847295 c 0,-0.821738 0.842772,-1.250033 4.733141,-2.405375 2.097607,-0.622936 0.310197,-3.139803 -2.886035,-4.063849 -2.282352,-0.659839 -3.356936,-1.809601 -4.323655,-4.626141 -1.267438,-3.692684 -1.234016,-3.790133 2.26171,-6.594502 4.252434,-3.411422 3.888858,-5.560032 -1.30829,-7.731539 -2.392507,-0.999653 -3.457538,-2.045364 -3.264058,-3.204847 0.208565,-1.249877 -0.321569,-1.657107 -1.93644,-1.487505 -1.362571,0.143105 -2.634694,-0.534548 -3.285184,-1.75 C 51.407333,45.892592 49.975721,45 48.809829,45 46.819539,45 46.79114,45.111731 48.345012,46.828741 49.255256,47.834548 50,49.100357 50,49.641649 c 0,1.56947 -5.203191,5.922425 -8.75,7.320193 C 38.261368,58.139638 36.807078,60 38.875,60 c 0.48125,0 2.39375,0.300895 4.25,0.668655 3.012781,0.596891 3.233663,0.496748 2.058088,-0.933088 -1.112824,-1.353512 -0.996593,-1.922062 0.75,-3.668655 C 47.069889,54.930111 48.896577,54 49.992394,54 c 2.643495,0 6.996868,3.864407 6.325196,5.614757 C 56.025228,60.376641 56.374167,61 57.093011,61 59.879133,61 56.366744,62.86964 53,63.178703 L 49.5,63.5 l 3,1.509367 c 1.65,0.830151 3.134216,2.444529 3.298257,3.587505 0.502186,3.499036 -2.367962,4.875787 -9.672265,4.639587 C 37.320268,72.951708 31,73.833022 31,75.345665 31,76.64446 36.020194,80 37.963309,80 c 0.635099,0 0.836049,-0.515629 0.446555,-1.145843 -0.678504,-1.097842 1.336123,-0.87417 6.833844,0.758721 1.255861,0.373007 1.580143,0.09166 1.159079,-1.005616 -0.75297,-1.962207 3.336439,-3.066366 8.068707,-2.178588 5.887409,1.104485 5.559842,4.351947 -0.471494,4.674328 -5.327237,0.284746 3.359659,1.660322 10.5,1.662682 3.85,0.0013 6.1,-0.195727 5,-0.437776 z m 22.067491,-3.643192 c 0.277597,-0.723406 0.067,-2.410906 -0.467998,-3.75 C 90.564497,73.595622 90.092104,73.175 90.049732,74 c -0.04237,0.825 -0.348381,2.5125 -0.680018,3.75 -0.647251,2.41521 1.310197,3.247714 2.197777,0.934716 z M 88.915143,68.388688 C 86.953386,63.421267 87.489892,50.275295 89.951292,43 92.991181,34.014834 96.20858,28.821101 102.6804,22.451865 105.72721,19.453339 108.00051,17 107.73216,17 107.46381,17 105.61429,16.318961 103.62212,15.48658 101.50432,14.601704 100,14.394047 100,14.98658 100,15.543961 100.675,16 101.5,16 c 3.07841,0 1.34311,3.955102 -3.606133,8.219129 -3.981005,3.429841 -5.3644,5.416353 -6.278216,9.015329 -0.748145,2.946497 -2.699084,6.294007 -5.393867,9.255045 C 83.899803,45.040905 82,47.549522 82,48.064208 82,48.578894 80.65,49 79,49 c -2.673569,0 -3,-0.329846 -3,-3.031385 0,-1.843263 -0.620708,-3.269573 -1.583681,-3.6391 -0.871024,-0.334243 -1.947549,-1.55762 -2.392278,-2.718615 -0.761683,-1.988427 -0.851052,-1.947741 -1.540324,0.701242 -1.454324,5.589201 6.118221,14.389232 11.231492,13.052082 2.648263,-0.692537 3.812934,1.390188 4.57568,8.18247 0.534624,4.760839 2.600246,10.895504 3.39953,10.09622 0.201046,-0.201045 -0.147829,-1.665447 -0.775276,-3.254226 z M 16.82375,64.25 c 1.579648,-0.9625 5.243519,-4.346078 8.141934,-7.519063 C 31.267892,49.831716 40.994905,44.750571 51.5,42.870083 c 3.85,-0.689178 7.317254,-1.723182 7.705009,-2.297787 0.486126,-0.720378 1.650383,-0.687897 3.75,0.10462 C 64.721187,41.343574 66,41.429599 66,40.881751 66,40.362265 65.2125,39.635737 64.25,39.267245 63.2875,38.898753 61.825,37.792814 61,36.809602 60.175,35.82639 57.7,34.655129 55.5,34.206799 c -3.835221,-0.781565 -4,-0.974192 -4,-4.676006 0,-2.249174 -0.534848,-4.039826 -1.28125,-4.289577 -0.704688,-0.235794 -1.213898,-0.04903 -1.131579,0.415034 0.08232,0.464062 0.09638,2.735859 0.03125,5.048437 -0.113266,4.021642 -0.278353,4.23469 -3.792186,4.893889 -3.379425,0.633984 -3.907972,0.397257 -6.596995,-2.954687 -3.965258,-4.942807 -5.458059,-4.68021 -6.287969,1.106111 -0.938981,6.54679 -4.038089,10.227484 -11.551803,13.719637 -3.514207,1.6333 -6.570401,3.089234 -6.791542,3.235407 C 13.514225,51.090869 12.905759,66 13.473714,66 c 0.262871,0 1.770387,-0.7875 3.350036,-1.75 z M 15.902894,61.181443 C 16.506303,60.053965 17,58.037098 17,56.699516 17,54.99057 18.386634,53.187233 21.66411,50.633775 26.686298,46.721023 28.272198,46.127088 27.361626,48.5 27.045044,49.325 26.384167,50 25.893011,50 25.401855,50 25,50.647631 25,51.43918 c 0,1.474635 -7.512298,10.768173 -9.236465,11.426522 -0.531617,0.20299 -0.469612,-0.546385 0.139359,-1.684259 z M 29.649034,44.47222 C 30.632263,41.909965 36,39.760113 36,41.928571 36,43.529337 32.941552,46 30.959956,46 29.669079,46 29.25013,45.511747 29.649034,44.47222 z M 46,38 c 5.406817,-2.268766 9.589945,-2.510969 10.32411,-0.597766 0.860571,2.242612 -0.231211,2.601128 -7.740777,2.541893 L 41.5,39.888255 46,38 z m 68.2871,14.103786 c -1.30978,-9.765102 6.51569,-23.796044 15.66066,-28.079319 2.73896,-1.282858 4.71467,-2.761644 4.39048,-3.286192 -0.71767,-1.161226 -7.28614,-0.20471 -11.93609,1.738163 C 119.47756,23.69841 119,24.375645 119,27.30109 c 0,3.86002 -3.46218,9.622435 -6.77313,11.273122 -1.2172,0.606842 -3.03913,1.850898 -4.04872,2.764569 -2.09906,1.899616 -5.73087,2.193948 -6.74878,0.546939 -0.90985,-1.472173 -8.45258,-0.455404 -9.558177,1.288454 -1.707086,2.692585 -0.827302,3.322699 4.157082,2.977364 2.826161,-0.195806 5.632085,0.151621 6.404965,0.793059 0.7565,0.627837 2.49046,0.861674 3.85324,0.519637 2.28619,-0.573796 2.61365,-0.189943 4.23475,4.963947 1.34567,4.278253 2.05203,5.340947 3.01746,4.539708 0.79882,-0.662962 1.07294,-2.444527 0.74841,-4.864103 z M 128,49.038359 c 5.69711,-1.96431 6.50712,-2.745335 7.42775,-7.16191 0.30079,-1.442953 1.35836,-3.625689 2.35017,-4.850524 l 1.8033,-2.226973 3.49666,1.963957 c 2.36592,1.328857 6.23332,2.142138 11.95939,2.514956 4.6545,0.30305 9.58382,0.895386 10.95404,1.316303 2.43168,0.746986 2.45357,0.708459 0.91442,-1.609626 -1.87052,-2.817157 -6.7929,-4.785135 -7.81842,-3.125819 -1.16531,1.885513 -12.25917,-0.435105 -14.16618,-2.963287 -1.33738,-1.772998 -1.96161,-1.944137 -3.69926,-1.014179 -2.97487,1.592104 -3.99818,1.398886 -4.72535,-0.892224 -0.84956,-2.67671 -6.04083,-5.343429 -8.12809,-4.175339 -1.31315,0.734873 -0.9836,1.261024 1.90988,3.049292 5.5195,3.411242 6.09873,4.507225 4.26061,8.061748 -0.90282,1.745873 -3.08402,3.694009 -5.06059,4.519873 -1.91062,0.798309 -3.9971,2.599853 -4.63661,4.003432 C 124.20221,47.851618 123.3012,49 122.83948,49 122.37777,49 122,49.45 122,50 c 0,1.21705 -0.59586,1.31255 6,-0.961641 z m 17.99156,-4.547346 c -2.10681,-2.242589 -2.44714,-2.306783 -5.0617,-0.95474 -4.46749,2.310226 -4.10437,2.950508 1.79286,3.161355 l 5.52751,0.197629 -2.25867,-2.404244 z M 70.142111,29.097582 C 66.51195,26.113651 66.185504,25 68.940983,25 c 2.752402,0 3.472681,-1.729194 1.529635,-3.672239 -1.54253,-1.54253 -1.857544,-1.442206 -4.563758,1.453437 C 64.308087,24.491882 63,26.116282 63,26.390977 c 0,1.054094 8.545964,6.375439 9.401126,5.853831 0.495619,-0.302304 -0.520938,-1.718556 -2.259015,-3.147226 z" + id="path2997" + inkscape:connector-curvature="0" /> + <path + style="fill:#656555" + d="m 122.94578,184.17949 c -5.21376,-3.30773 -8.67356,-8.24878 -11.9109,-17.01036 -1.97049,-5.33294 -3.16702,-6.9424 -7.59077,-10.21042 -6.587053,-4.86614 -9.196757,-8.50539 -10.731094,-14.96459 -1.124413,-4.73352 -1.382005,-5.04219 -3.710654,-4.4464 C 72.595139,141.7455 66.927781,141.66435 57.5,137.09665 54.2,135.49782 49.475,133.22776 47,132.05206 40.227674,128.83502 37.599939,124.89415 37,117.05483 l -0.5,-6.53342 -7.5,0.29798 c -6.584331,0.2616 -8.171364,-0.0449 -12.99896,-2.51071 C 8.975862,104.72046 5.6886446,100.06299 6.254943,94.5 6.5810045,91.296959 6.0656311,89.619992 3.6682436,86.08317 -0.02845177,80.629503 -0.96468449,73.57894 1.2942237,68.204947 2.1507609,66.167226 3.1117793,62.286435 3.4298202,59.580967 4.1322714,53.605448 7.8434725,46.993129 12.586182,43.266898 14.523107,41.745104 17.646235,38.378661 19.526467,35.785914 23.405433,30.437011 31.315442,25.439229 37.440743,24.467133 39.673334,24.112817 44.2,22.53715 47.5,20.96565 c 7.104506,-3.38325 22.655769,-6.325632 34,-6.432981 4.644948,-0.04396 8.991573,-0.631332 10.36437,-1.400579 2.951381,-1.653807 9.39917,-0.805955 14.75634,1.940386 3.4046,1.745359 4.46383,1.8496 8.65631,0.851892 5.57336,-1.326324 10.02486,-0.664464 17.94144,2.667582 3.1467,1.324427 7.29295,2.40805 9.2139,2.40805 6.27908,0 13.72091,3.57395 19.23132,9.235873 2.81779,2.89527 5.83214,6.677096 6.69855,8.404058 0.86641,1.726961 4.40813,5.161398 7.87048,7.632081 12.14924,8.669519 19.29214,18.965608 21.89294,31.557465 1.01653,4.92154 1.0309,7.631588 0.0702,13.234002 -0.93806,5.470345 -0.9408,7.535902 -0.0122,9.240811 0.65773,1.20764 1.20314,5.14808 1.21201,8.75654 0.0132,5.3775 -0.48187,7.41063 -2.74501,11.27239 -3.98092,6.79293 -9.54045,10.17515 -16.65884,10.13465 l -5.6471,-0.0321 1.32151,2.53213 c 0.72682,1.39267 1.31439,3.65713 1.3057,5.03213 -0.018,2.85531 -3.22691,10.42155 -4.84354,11.42068 -0.59395,0.36708 -2.67161,3.06542 -4.61702,5.99631 -8.96579,13.50753 -23.50025,16.73209 -45.26132,10.04152 -1.97495,-0.60721 -2.24601,-0.34135 -2.21735,2.17486 0.0179,1.57665 0.84187,5.20867 1.83094,8.07116 0.98906,2.8625 1.43153,4.97787 0.98327,4.70083 -0.44826,-0.27705 -1.42558,-2.59765 -2.17182,-5.1569 -1.09864,-3.76779 -1.90078,-4.79866 -4.21566,-5.41775 -1.57236,-0.42052 -3.03242,-0.591 -3.24457,-0.37886 -0.21214,0.21215 0.39405,2.02897 1.34711,4.03739 2.16316,4.55853 7.28745,9.78254 8.96454,9.13898 0.69335,-0.26606 2.28698,0.60874 3.5414,1.94401 3.0367,3.23243 1.33672,3.07046 -4.12208,-0.39274 z m 22.44605,-21.6141 c 5.61315,-5.65819 5.58293,-6.54738 -0.22362,-6.5807 C 143.7007,155.97627 141.825,155.53316 141,155 c -1.02002,-0.65919 1.93987,-0.97427 9.25,-0.98469 5.9125,-0.008 10.75,-0.41003 10.75,-0.89247 0,-0.48244 -1.9125,-0.67212 -4.25,-0.42152 -2.84424,0.30494 -4.91153,-0.0442 -6.25,-1.05551 -2.58724,-1.95488 -1.38742,-3.15909 4.78716,-4.80467 3.79081,-1.01029 5.19567,-1.0207 6.75,-0.05 1.75062,1.09328 1.96284,0.95998 1.96284,-1.23297 0,-1.35233 0.7875,-2.91746 1.75,-3.47806 1.29739,-0.75566 -0.28673,-1.02715 -6.12495,-1.04969 -6.2962,-0.0243 -9.04315,-0.55467 -13.70198,-2.64542 -4.41031,-1.97923 -6.75043,-2.46797 -9.62505,-2.01023 -12.08625,1.92458 -11.95288,1.92986 -17.69939,-0.70098 -5.41485,-2.479 -5.78401,-2.51605 -11.14826,-1.11884 C 104.399,135.34972 101.69938,136 101.45121,136 101.20304,136 101,137.32491 101,138.94424 c 0,1.76178 1.02827,4.07107 2.56034,5.75 2.03028,2.22488 2.34083,2.35355 1.5,0.6215 -1.65176,-3.40256 -1.26729,-5.77269 1.33262,-8.21518 l 2.39296,-2.24807 4.5782,2.08561 c 5.0403,2.29612 6.63588,4.42917 6.63588,8.87116 0,2.49628 -0.4912,3.0548 -3.25,3.69544 l -3.25,0.7547 3.83478,0.72666 c 4.48944,0.85072 11.25608,-0.15325 8.41522,-1.24857 -1.11725,-0.43076 -1.75,-1.73853 -1.75,-3.6169 0,-2.50079 0.68002,-3.27137 4.53288,-5.13651 5.99756,-2.90337 10.73849,-2.15737 12.44311,1.95796 1.09922,2.65375 1.43764,2.80973 4.08994,1.88513 1.59036,-0.5544 3.40038,-0.8384 4.02226,-0.63111 0.62188,0.2073 -3.75606,2.57778 -9.72875,5.26775 -5.97269,2.68996 -11.22198,5.19608 -11.66507,5.56915 -0.4431,0.37307 0.5694,1.24787 2.25,1.944 1.68059,0.69612 3.05563,1.90192 3.05563,2.67954 0,2.61212 4.25937,8.28755 6.25024,8.32819 0.41263,0.008 3.17634,-2.43027 6.14159,-5.4193 z m -8.24345,-0.69941 c -1.57844,-2.52748 -0.69951,-3.3524 4.63895,-4.35391 4.66319,-0.87482 5.0773,-0.024 1.70268,3.49836 -3.40113,3.55001 -4.56118,3.70651 -6.34163,0.85555 z m -24.25849,-2.49866 C 112.26576,158.61529 110.89984,158 109.8545,158 c -1.80098,0 -1.81414,0.13196 -0.25109,2.51749 1.30047,1.98475 1.94279,2.27409 3.03539,1.36732 1.04849,-0.87018 1.10962,-1.48302 0.25109,-2.51749 z m -9.05041,-7.91437 c 1.63061,-3.57879 1.54749,-3.69476 -2.08948,-2.91559 -4.268185,0.9144 -4.38882,1.09927 -2.255548,3.45651 2.356858,2.6043 2.945358,2.53104 4.345028,-0.54092 z M 99.108458,140.75 c 0.799477,-1.45449 0.543772,-1.75 -1.514257,-1.75 -3.09658,0 -3.972815,1.35535 -3.106849,4.80563 0.660743,2.63261 0.708524,2.64789 2.167417,0.69316 0.820479,-1.09933 1.924639,-2.78629 2.453689,-3.74879 z M 75,138.61501 c 0,-0.21174 -1.064137,-1.08224 -2.36475,-1.93443 -2.026451,-1.32779 -2.985945,-1.36603 -6.706978,-0.26734 -2.640401,0.77962 -3.771203,1.50683 -2.885251,1.85549 C 64.681204,138.91342 75,139.21226 75,138.61501 z m 73.8178,-5.88783 c 0.23652,-2.05091 1.32349,-3.26878 4.25,-4.76177 2.16271,-1.10333 3.9322,-2.36357 3.9322,-2.80052 0,-1.21956 6.55807,-4.07059 10.99558,-4.78017 2.18244,-0.34899 3.75738,-0.97543 3.49987,-1.39208 -0.61001,-0.98702 3.32998,-5.99264 4.71689,-5.99264 0.58695,0 1.56678,0.61939 2.17742,1.37642 0.61063,0.75704 2.56388,1.64401 4.34054,1.97106 2.61308,0.48102 3.44487,0.19373 4.35325,-1.50359 1.19079,-2.22501 -0.23084,-4.08518 -2.49287,-3.26187 -0.59987,0.21833 -1.76051,-0.0287 -2.57918,-0.54894 -1.26963,-0.80683 -1.05551,-1.74635 1.45611,-6.38942 2.50317,-4.62744 2.7755,-5.814682 1.81654,-7.919375 -0.78721,-1.727734 -0.8531,-4.665874 -0.21804,-9.723489 0.50052,-3.986194 0.62306,-8.39108 0.27229,-9.788636 -0.51271,-2.042798 -0.32864,-2.422392 0.93881,-1.936026 2.4622,0.944834 4.04403,-1.844463 3.47058,-6.119806 -0.28213,-2.103495 -0.11024,-4.544188 0.382,-5.423763 1.00072,-1.788185 -0.25968,-2.958009 -3.57929,-3.322082 -3.81733,-0.41866 -9.78919,-2.249169 -10.87276,-3.332747 C 174.55851,55.958507 168,55.547466 168,56.59655 c 0,0.328103 1.84687,2.690603 4.10416,5.25 7.02349,7.96351 9.2792,13.43358 9.34165,22.65345 0.0423,6.244912 -0.49427,9.409424 -2.44581,14.424404 -4.38897,11.278596 -15.68215,21.197216 -28.5,25.031096 -7.35502,2.19991 -7.09443,2.05909 -5.5624,3.00594 1.13981,0.70444 1.1618,1.38438 0.12566,3.88584 -1.41314,3.41163 -0.69165,5.41786 1.77998,4.94954 0.96145,-0.18218 1.79013,-1.47043 1.97456,-3.06964 z M 184.22896,72.32632 C 182.56088,71.660927 180,66.648938 180,64.04966 c 0,-2.806858 2.54684,-2.593732 5.61003,0.469463 3.71782,3.717817 2.70602,9.437522 -1.38107,7.807197 z M 62,133.06882 c 3.025,-0.50579 7.213452,-1.64506 9.307672,-2.53173 l 3.807672,-1.61212 -5.033565,-3.46249 C 67.313318,123.55812 64.631387,122 64.121932,122 c -0.509455,0 -1.396894,1.35 -1.972087,3 -0.575193,1.65 -1.631715,3.06854 -2.347825,3.15231 -2.89025,0.33812 -3.386904,0.48693 -5.486279,1.64392 C 53.114399,130.4583 51.126899,131 49.899075,131 c -3.887034,0 -0.459081,1.62485 6.100925,2.89185 0.275,0.0531 2.975,-0.31725 6,-0.82303 z m 51,-2.2677 11.5,-2.30112 -5.77587,-0.30068 c -6.01026,-0.31287 -19.118452,2.72542 -21.145601,4.90126 -0.804387,0.86339 -0.443074,1.01072 1.421471,0.57965 1.375,-0.3179 7.675,-1.61349 14,-2.87911 z m -16.113881,-4.4085 c 1.119373,-0.35074 1.055799,-0.79932 -0.330357,-2.331 -2.706789,-2.99097 -1.647306,-6.2909 2.350706,-7.32165 C 104.12277,115.39512 107,116.48973 107,119.81905 c 0,1.52952 -0.54,3.32095 -1.2,3.98095 -0.93333,0.93333 -0.41481,1.2 2.33333,1.2 4.24494,0 5.10749,-0.68151 3.84596,-3.0387 -0.77952,-1.45654 -0.40695,-1.96517 2.0726,-2.82954 3.61257,-1.25935 7.31801,-0.11358 9.15727,2.83156 1.25222,2.00511 5.79084,2.89429 5.79084,1.13451 0,-1.20949 5.59623,-3.09783 9.18061,-3.09783 1.63943,0 3.13035,0.64677 3.45776,1.5 0.76579,1.99562 1.90992,1.89114 4.07267,-0.37192 0.98393,-1.02955 3.81396,-2.17666 6.28896,-2.54913 2.475,-0.37246 5.58802,-1.27385 6.91782,-2.00308 2.40097,-1.31663 2.40334,-1.33362 0.34046,-2.43764 -1.58816,-0.84996 -2.91531,-0.76165 -5.6357,0.375 -4.92566,2.05807 -9.29179,1.8585 -12.71821,-0.58132 -3.36047,-2.39287 -3.57346,-3.53509 -1.15712,-6.20512 1.68277,-1.85944 1.65886,-1.9177 -0.64787,-1.57874 -3.96342,0.5824 -4.76534,3.10796 -2.15213,6.77787 1.24901,1.75408 2.10934,3.32878 1.91184,3.49933 -0.1975,0.17056 -3.38295,0.54173 -7.07877,0.82484 -4.77398,0.36569 -7.23518,0.12366 -8.5,-0.83587 -0.97918,-0.74284 -2.70282,-1.36492 -3.83032,-1.38242 -1.1275,-0.0175 -2.61215,-0.5943 -3.29922,-1.2818 -0.68707,-0.6875 -4.03957,-1.475 -7.45,-1.75 -5.9888,-0.48291 -6.19943,-0.59401 -6.16136,-3.25 0.0505,-3.52042 -1.03401,-3.45933 -7.093639,0.39961 -2.72018,1.73229 -6.733838,3.9552 -8.919241,4.93979 l -3.97346,1.79018 2.626321,0.99853 c 3.346419,1.2723 3.890225,2.21055 4.082989,7.04449 0.152165,3.81583 0.255661,3.92665 3.197433,3.4239 1.672097,-0.28576 3.663931,-0.71501 4.426296,-0.95388 z M 78.2,124.8 c -1.71979,-1.71979 -1.479869,-4.82611 0.55,-7.121 1.695648,-1.91703 1.672354,-1.96065 -0.75,-1.40455 -1.375,0.31567 -5.604996,0.8927 -9.399992,1.2823 l -6.899991,0.70837 2.399991,1.85695 c 2.584356,1.9996 11.477965,5.74059 13.849992,5.82582 1.127778,0.0405 1.183333,-0.21456 0.25,-1.14789 z M 196.92597,113.45425 C 197.6462,113.89938 198,112.12213 198,108.05902 c 0,-3.33246 -0.3375,-6.05133 -0.75,-6.04194 -0.69757,0.0159 -4.65176,8.952 -5.96613,13.48292 -0.53337,1.83865 -0.37251,1.81003 1.99395,-0.35477 1.41577,-1.29512 3.05744,-2.05606 3.64815,-1.69098 z m -130.248329,0.4986 c 4.302297,-0.57594 10.042783,-1.76464 12.756635,-2.64158 l 4.934276,-1.59442 -2.215513,-1.79401 C 79.729696,105.96054 71.246485,103.9584 66.5,104.22854 c -1.65,0.0939 -4.8,0.0779 -7,-0.0355 l -4,-0.20623 2.987005,-1.96887 c 2.981689,-1.96537 2.988352,-1.96523 3.743805,0.0769 1.068167,2.88753 5.297299,2.24042 5.195158,-0.79493 -0.06533,-1.941482 0.581027,-2.273417 5.5,-2.824506 C 75.991686,98.132002 80.975,97.447978 84,96.95541 c 3.025,-0.492568 11.35,-0.839856 18.5,-0.771751 l 13,0.123828 3.35,3.346257 c 3.22631,3.222696 3.63247,3.344586 11,3.301156 4.61567,-0.0272 8.83993,-0.62817 10.65,-1.51508 1.65,-0.80849 2.1,-1.20565 1,-0.88258 -1.1,0.32307 -5.02349,0.84395 -8.71888,1.15751 -6.20241,0.52628 -6.9903,0.36308 -10.25,-2.123213 -4.10313,-3.129613 -4.79848,-7.054516 -1.43873,-8.120862 1.15082,-0.365255 4.86332,-0.661216 8.25,-0.657692 3.71825,0.0039 9.28289,-0.959146 14.04666,-2.430906 4.33898,-1.340522 8.12357,-2.202786 8.41022,-1.916142 1.29137,1.291373 -2.10133,8.626915 -5.07334,10.969336 -1.77426,1.398403 -2.81841,2.547541 -2.32032,2.55364 C 148.33712,100.03705 156,89.350243 156,83.819134 156,78.696124 149.44074,72.926831 140.85435,70.497563 L 135.5,68.982705 l 5.74604,0.580109 c 4.848,0.489445 5.65598,0.345429 5.16982,-0.921477 -0.31691,-0.825872 -2.00263,-2.007479 -3.74603,-2.625795 -3.03982,-1.078099 -3.09021,-1.183506 -1.2287,-2.569876 3.93049,-2.927253 13.17818,-0.894031 15.47788,3.403011 1.30254,2.433819 0.35151,5.718234 -1.9653,6.787239 -1.81508,0.837498 -1.81663,0.937738 -0.0504,3.257904 2.24213,2.945356 3.8145,2.127432 4.66927,-2.428899 0.73969,-3.942913 1.06243,-4.105229 3.5987,-1.809933 2.06193,1.866023 2.48926,8.242302 0.76794,11.458621 -0.58344,1.090169 -2.15844,2.399448 -3.5,2.909508 -2.98841,1.13619 -3.37818,4.035192 -0.4392,3.266632 2.35209,-0.615086 2.41708,-0.07439 0.6137,5.106158 -1.44255,4.144006 -4.52616,6.500993 -8.6137,6.583973 -4.18624,0.085 -5.42457,1.50564 -2.48132,2.84668 6.51521,2.96852 14.31862,-0.56784 15.67672,-7.104399 C 166.15899,93.084331 168.74005,89 170.70728,89 c 0.81249,0 2.66248,0.93229 4.11107,2.071756 2.96232,2.33016 3.73082,1.50288 2.24188,-2.413341 -0.61185,-1.609288 -1.70124,-2.585231 -2.78284,-2.493034 -4.48949,0.382689 -5.27746,-0.12786 -5.27123,-3.415381 0.003,-1.7875 0.61493,-4.416629 1.35899,-5.842508 1.23364,-2.364091 1.09675,-2.968065 -1.55364,-6.855043 -2.75263,-4.036936 -2.81133,-4.334682 -1.10898,-5.625689 0.98861,-0.749734 2.19007,-1.377465 2.66991,-1.394957 0.47985,-0.01749 0.27657,-0.7498 -0.45174,-1.627351 -0.98484,-1.186656 -2.31094,-1.437761 -5.17462,-0.97984 -2.66133,0.425565 -4.52067,0.146251 -6.02076,-0.904452 C 157.19286,58.446782 154.03402,58 147.97749,58 143.01254,58 138.9313,57.531299 138.28713,56.887132 136.8074,55.407396 135,56.627838 135,59.106766 c 0,1.093802 -1.04603,2.979745 -2.32451,4.190983 -1.27848,1.211238 -2.59814,2.947471 -2.93256,3.858295 C 129.0422,69.064487 131.82128,72 134.32874,72 c 2.58626,0 1.9753,1.450933 -1.07874,2.561816 -3.48475,1.267552 -10.21525,0.346199 -13.58101,-1.859135 C 115.986,70.289496 114.4791,64.182451 116.42028,59.536565 117.23299,57.591454 117.52601,56 117.07142,56 c -2.52747,0 -5.3979,8.847595 -5.29921,16.333899 0.0841,6.379542 0.83835,8.113379 2.35248,5.407771 C 114.66077,76.783751 115.90788,76 116.89605,76 c 2.06366,0 8.30067,2.889706 9.22678,4.27491 C 126.82977,81.332314 131,79.440714 131,78.062641 131,76.683678 136.89667,75 141.72615,75 c 3.56044,0 5.00024,0.572547 7.35077,2.923077 3.51045,3.510449 3.66027,4.744653 0.67308,5.544929 -1.2375,0.33153 -4.5,1.255024 -7.25,2.052208 -2.75,0.797185 -8.97445,1.724732 -13.83211,2.061215 -7.09214,0.491263 -9.93746,1.193234 -14.44284,3.563204 l -5.61073,2.951416 -9.459486,-1.190671 C 93.525286,92.196783 85.470095,91.973232 79.25947,92.353232 c -10.740455,0.657161 -10.702663,0.646007 -29.490102,8.703398 -4.251848,1.82349 -7.97494,3.07113 -8.273539,2.77253 -1.368172,-1.36817 1.149036,-3.65169 8.278617,-7.510049 C 54.023501,94.019622 58.4,91.399835 59.5,90.497361 c 1.925388,-1.579647 1.874431,-1.619599 -1.365916,-1.070928 -1.851253,0.313463 -4.933325,1.946137 -6.849047,3.628164 -1.915723,1.682026 -5.834166,4.097969 -8.707651,5.36876 -3.831843,1.694623 -5.567482,3.138523 -6.511123,5.416673 -1.19799,2.8922 -1.089833,3.31462 1.570319,6.13305 2.443892,2.58931 3.584046,3.02692 7.886405,3.02692 5.344117,0 20.630139,-1.68986 23.977013,-2.65065 1.496948,-0.42973 1.722759,-0.2812 0.897763,0.59049 -0.60623,0.64055 -5.78123,1.76552 -11.5,2.49994 -8.145456,1.04605 -9.276211,1.35966 -5.220122,1.44776 2.847702,0.0618 8.697702,-0.35876 13,-0.93469 z M 63.755249,100.5 C 63.228787,97.745993 64.430098,97.072477 65.393011,99.581787 66.245231,101.80264 66.148399,103 65.116577,103 c -0.485882,0 -1.09848,-1.125 -1.361328,-2.5 z m -31.337036,8.89301 c 2.097329,-0.80482 2.0337,-5.28236 -0.08663,-6.09601 -0.917629,-0.35213 -2.982469,0.11393 -4.588533,1.03568 -1.606064,0.92176 -3.346791,1.41222 -3.868282,1.08992 -1.408412,-0.87044 -9.20649,0.65036 -8.220669,1.60322 2.220968,2.14671 13.272115,3.7072 16.764113,2.36719 z m 8.43882,-11.538843 c 3.653632,-1.730208 8.275839,-4.604684 10.271571,-6.387724 2.888485,-2.580648 4.839468,-3.382426 9.565137,-3.930898 8.440084,-0.979575 9.510253,-2.136019 2.629765,-2.841771 -3.202928,-0.328533 -7.464395,-0.895348 -9.469925,-1.259587 -3.2307,-0.586752 -3.735902,-0.392736 -4.431299,1.701779 -0.431684,1.300219 -0.815795,3.254539 -0.853581,4.342934 -0.05103,1.469809 -0.977847,2.127742 -3.602666,2.557466 -1.943681,0.318212 -4.050241,0.897642 -4.681243,1.287623 C 39.653789,93.71397 37.468777,92.90061 35.42921,91.516523 31.498365,88.848979 27.143953,88.256047 25.267217,90.132783 23.56698,91.83302 21,90.381256 21,87.719443 21,85.612489 16.431892,81 14.345211,81 13.940536,81 12.415457,79.856094 10.956147,78.457986 l -2.6532912,-2.542014 0.1523706,4.512479 c 0.1708613,5.060086 1.0104909,6.505832 2.7614406,4.754882 1.55591,-1.55591 5.456993,-1.515583 6.448995,0.06667 1.571252,2.506155 1.421431,5.965831 -0.31328,7.234282 -1.574934,1.151621 -1.341079,1.480837 2.411956,3.395492 C 24.964575,98.532737 25,98.530023 25,95.478561 c 0,-3.669165 4.031429,-5.343213 7.459036,-3.097359 2.939146,1.925803 3.151036,3.302786 0.98426,6.396292 -2.138772,3.053526 -0.572026,2.858396 7.413737,-0.923327 z M 7.5600753,85.383337 C 5.9445878,78.946721 5.983588,77.338703 7.8422258,73.75 9.7955428,69.978488 8.83941,68.580263 6.1326794,71.25 5.1170452,72.251753 4.5907418,72.128049 3.4825755,70.627107 c -1.31404,-1.779784 -1.415592,-1.742172 -2.0427372,0.756573 -0.88899899,3.542055 0.2210829,8.927304 2.7096527,13.145116 2.4314517,4.121003 4.3511344,4.601991 3.4105843,0.854541 z M 94.953706,85.934261 C 102.93611,84.555968 103.68456,83 96.365156,83 91.189396,83 78.602051,86.061733 77,87.710361 76.398129,88.32973 87.361767,87.245134 94.953706,85.934261 z M 70.15,82.5 c -0.1925,-0.55 -0.768588,-0.882971 -1.280196,-0.739935 -0.511608,0.143036 -2.379108,-0.494297 -4.15,-1.416296 L 61.5,78.667407 64.75,77.330836 c 1.7875,-0.735115 3.243109,-1.672781 3.234687,-2.083704 -0.03714,-1.812076 -1.711016,-3.091894 -4.455889,-3.406899 -2.51531,-0.28866 -3.101125,-0.920591 -3.864702,-4.168936 -0.843068,-3.586507 -0.691787,-4.002527 2.391494,-6.576564 3.872234,-3.232684 3.572961,-5.133749 -1.272009,-8.080151 -1.80597,-1.098276 -3.285405,-2.563351 -3.287634,-3.255723 -0.0022,-0.692373 -1.052674,-1.270102 -2.334322,-1.283843 -1.281649,-0.01374 -2.764685,-0.801241 -3.295638,-1.75 C 51.335035,45.776257 49.971226,45 48.8353,45 c -2.007725,0 -2.016581,0.07438 -0.317561,2.667417 1.735605,2.648868 1.724236,2.686964 -1.63499,5.478668 C 45.022237,54.692274 42.6,56.247012 41.5,56.601058 c -1.1,0.354046 -2.5838,1.111423 -3.297334,1.68306 -1.799134,1.441348 0.272805,2.680382 4.515949,2.700569 2.488156,0.01184 3.084739,-0.333562 2.628719,-1.521932 C 44.604268,57.526355 47.707737,54 50.154988,54 52.375939,54 56,57.410144 56,59.5 c 0,0.825 0.5625,1.506891 1.25,1.515313 C 58.083333,61.025521 58,61.35375 57,62 c -0.825,0.533156 -2.833002,0.976265 -4.462226,0.984687 L 49.575548,63 l 3.462226,2.923451 c 2.90272,2.451013 3.282939,3.218627 2.352796,4.75 -0.93468,1.538844 -2.588567,1.852748 -10.5,1.992878 C 39.725757,72.75781 34.15,73.353927 32.5,73.991034 c -2.926921,1.130157 -2.951281,1.194951 -1,2.659882 3.877276,2.910878 7.368725,4.370509 8.002266,3.345417 C 39.840938,79.44835 39.566476,79 38.89235,79 38.218224,79 37.875093,78.791574 38.129836,78.536831 38.384579,78.282088 41.026153,78.715514 44,79.5 c 5.186848,1.368265 8.36988,1.386946 4.075361,0.02392 C 46.933912,79.161637 46,78.481304 46,78.012068 c 0,-1.563214 5.945525,-2.185151 9.542132,-0.998163 2.887858,0.953079 3.331447,1.433496 2.381017,2.578694 C 57.280728,80.36667 55.385211,81 53.710889,81 48.871813,81 51.190184,82.019049 58.130898,82.942833 65.992184,83.989142 70.61163,83.818943 70.15,82.5 z m 9.69375,-0.01042 c 0.812113,-0.812113 -0.201002,-1.320466 -3.31567,-1.663712 -2.252429,-0.248226 -3.049168,0.125714 -3.343836,1.569389 -0.337023,1.651186 0.03535,1.810821 2.891541,1.239583 1.80311,-0.360622 3.498694,-0.875989 3.767965,-1.14526 z m 12.407929,-3.074595 c 0.321756,-0.321756 0.09654,-1.98625 -0.500487,-3.698874 -0.961711,-2.758766 -1.172458,-2.891618 -1.84806,-1.164988 C 88.696662,77.634495 88.883424,80 90.333333,80 c 0.733334,0 1.596589,-0.263255 1.918346,-0.585012 z M 88.982898,67.94037 C 87.493371,62.746693 87.805379,51.025593 89.595379,44.931501 91.931004,36.97982 96.606895,28.728257 101.711,23.551023 104.1787,21.04796 106.60324,19 107.09887,19 c 2.24256,0 0.55894,-2.245028 -2.70696,-3.609608 -3.73779,-1.561752 -6.203807,-0.983885 -3.13358,0.734301 C 102.21625,16.660771 103,17.705403 103,18.446098 103,19.907603 96.530574,26 94.978624,26 93.866704,26 91,32.456706 91,34.961095 c 0,2.158602 -5.080472,8.953597 -6.730948,9.002461 -0.677021,0.02004 -1.519476,1.186031 -1.872121,2.591082 -0.513424,2.045641 -1.164763,2.493941 -3.269052,2.25 -2.135977,-0.247614 -2.685111,-0.89389 -2.933626,-3.452585 -0.205833,-2.119238 -0.941104,-3.314096 -2.25,-3.65638 -1.069339,-0.279639 -1.980801,-1.338063 -2.025472,-2.352053 -0.05721,-1.29861 -0.465704,-0.971537 -1.381825,1.106395 -1.173959,2.662757 -1.058914,3.315235 1.181461,6.700671 3.137396,4.740926 6.557446,6.998647 10.049805,6.634307 2.641767,-0.275603 2.782956,-0.03787 4.284989,7.215007 1.539076,7.431746 2.860153,11.419969 3.553226,10.726896 0.197648,-0.197648 -0.08294,-1.901584 -0.623539,-3.786526 z M 16.34563,64.788605 C 18.080533,63.572338 22.2,59.822393 25.5,56.455393 32.510868,49.302185 39.822076,45.508816 50.880695,43.286799 c 4.190618,-0.842024 8.15304,-1.957246 8.805383,-2.47827 0.758646,-0.605928 1.960726,-0.532737 3.335646,0.203097 3.609747,1.931878 3.558056,0.120022 -0.08433,-2.955849 -1.890568,-1.59652 -5.396557,-3.405421 -7.791088,-4.019779 -4.259171,-1.092763 -4.339919,-1.190428 -3.719316,-4.498525 0.383894,-2.04633 0.201143,-3.649264 -0.462839,-4.059628 -1.771428,-1.094803 -2.407384,0.332324 -2.20636,4.951222 0.176616,4.058068 0.0014,4.36909 -2.773697,4.924114 C 42.77394,35.995212 40,35.318348 40,33.893011 40,32.46463 36.13766,29 34.545313,29 33.641401,29 32.855517,30.41983 32.469664,32.75 31.073932,41.178845 29.191001,43.398772 19.5,48.040905 c -2.75,1.317291 -5.225,2.55859 -5.5,2.758442 -0.564927,0.410553 -1.690122,16.202433 -1.15437,16.201351 0.190096,-3.84e-4 1.765096,-0.995826 3.5,-2.212093 z m 0.227951,-5.921091 C 17.238811,54.290623 19.710136,51.36787 25.5,48.310539 c 2.955697,-1.560753 2.974157,-1.555121 1.25,0.381398 -0.9625,1.081049 -1.75,2.407007 -1.75,2.946573 0,0.539565 -2.038774,3.369513 -4.530609,6.288773 l -4.530609,5.307744 0.634799,-4.367513 z M 30,45.2 c 0,-1.496801 2.393542,-3.200105 4.45,-3.166731 1.96501,0.03189 1.952125,0.114808 -0.310784,2 C 31.671515,46.089071 30,46.560225 30,45.2 z m 16.948934,-7.314119 c 5.131119,-2.275354 8.386594,-2.141627 8.864174,0.364119 0.292295,1.533596 -0.510227,1.741265 -6.489784,1.679363 L 42.5,39.858726 46.948934,37.885881 z M 114.613,50.242214 c 0.39011,-11.34611 6.78668,-22.214038 15.46771,-26.280018 7.98813,-3.741438 4.3048,-5.292967 -5.6768,-2.391238 C 119.43158,23.016453 119,23.379026 119,26.110797 c 0,4.232824 -3.53464,10.597197 -6.83264,12.30266 -1.54717,0.800068 -3.39785,2.159341 -4.11264,3.020606 -1.54271,1.858855 -5.71533,2.084108 -6.29673,0.339921 -0.47118,-1.413562 -6.028757,-1.234625 -8.869253,0.285562 C 91.849932,42.615498 91,43.911714 91,44.940027 c 0,1.608305 0.566942,1.793617 4.055745,1.32567 2.40795,-0.322973 5.022115,-0.0268 6.434295,0.728971 1.3082,0.700128 3.33389,1.023133 4.50152,0.717789 2.19666,-0.574439 2.19459,-0.577345 5.06162,7.093178 1.73112,4.631499 3.31342,2.603113 3.55982,-4.563421 z m 12.95886,-0.88036 C 133.33435,47.446364 136,45.400103 136,42.892065 136,40.056981 138.18398,36 139.71017,36 c 0.76403,0 2.81659,0.738158 4.56124,1.640352 1.90708,0.986191 5.97491,1.713297 10.20034,1.823268 3.86554,0.100604 8.50833,0.547212 10.31733,0.992463 3.24096,0.797705 3.27221,0.77253 2.13605,-1.721057 -1.21413,-2.664735 -6.76767,-4.607841 -7.90589,-2.766163 -0.40206,0.650557 -2.63831,0.662775 -6.49259,0.03547 -5.38731,-0.876807 -7.47084,-2.087768 -7.51134,-4.365629 -0.008,-0.47371 -1.5325,-0.576664 -3.38685,-0.228787 -2.84257,0.53327 -3.87895,0.158505 -6.60575,-2.388709 -3.34131,-3.12125 -5.45501,-3.66581 -7.99468,-2.059695 -1.23357,0.78012 -1.15259,1.046943 0.5,1.647412 C 131.47576,30.043347 135,33.177397 135,35.253643 135,37.857759 131.26964,42 128.92446,42 c -1.39476,0 -4.89499,4.283187 -6.74193,8.25 -0.47571,1.021728 -0.23882,0.982688 5.38933,-0.888146 z M 146.41564,44.75 c -1.04188,-1.2375 -1.94253,-2.368407 -2.00144,-2.513127 -0.0589,-0.144719 -1.72044,0.410963 -3.69228,1.234849 C 134.84423,45.927577 135.26188,47 142.09597,47 l 6.21401,0 -1.89434,-2.25 z M 70.142111,29.097582 C 66.335955,25.968986 66.18411,25 69.5,25 c 2.838203,0 3.319469,-2.075011 0.939403,-4.050291 -1.324614,-1.099332 -2.091217,-0.764562 -5.069673,2.213894 l -3.509075,3.509075 4.766866,3.100806 c 5.561864,3.617946 8.136085,3.122889 3.51459,-0.675902 z" + id="path2995" + inkscape:connector-curvature="0" /> + <path + style="fill:#2f83c8" + d="m 126.58491,186.10872 c -1.0533,-0.41289 -2.03297,-1.55386 -2.17704,-2.53549 -0.22486,-1.53206 0.0817,-1.46192 2.16509,0.49531 1.33487,1.25405 2.42704,2.42665 2.42704,2.60577 0,0.38556 0.0281,0.39214 -2.41509,-0.56559 z M 117.87244,180.25 c -1.24387,-1.58606 -1.2085,-1.62143 0.37756,-0.37756 0.9625,0.75485 1.75,1.54235 1.75,1.75 0,0.82304 -0.82119,0.29331 -2.12756,-1.37244 z m 4.58644,-0.31653 c -0.36253,-0.58659 -0.44468,-1.281 -0.18255,-1.54313 0.26212,-0.26213 0.74306,0.21781 1.06875,1.06653 0.67618,1.76211 0.0999,2.07206 -0.8862,0.4766 z m -5.90861,-9.98636 c -1.62236,-0.48454 -3.15088,-0.67984 -3.39671,-0.434 -0.24584,0.24583 -1.43567,-1.68703 -2.64408,-4.29525 -1.25472,-2.70817 -3.87256,-6.00434 -6.10329,-7.68475 -6.419581,-4.83586 -9.35184,-8.7138 -11.177038,-14.78172 C 92.278118,139.58965 91.05,137.00749 90.5,137.01325 c -0.55,0.006 -3.475,0.67481 -6.5,1.48675 -5.126225,1.37594 -12.13707,1.99557 -9.167619,0.81026 0.880776,-0.35158 0.267142,-1.17966 -1.810413,-2.44309 -2.725933,-1.65774 -3.661001,-1.75599 -7.049635,-0.74073 -4.487001,1.34433 -4.324394,2.80453 0.336684,3.02339 3.116399,0.14633 3.125167,0.15972 0.375095,0.57278 -1.901324,0.28558 -5.523457,-0.89984 -11.152328,-3.64983 C 50.946743,133.83275 46.792719,132 46.30062,132 c -0.492098,0 -2.673551,-1.8211 -4.847672,-4.04688 -3.748281,-3.83736 -3.962309,-4.39395 -4.133742,-10.75 L 37.138411,110.5 l -6.819205,0.11577 c -6.17989,0.10491 -6.350445,0.058 -1.819206,-0.5 4.804769,-0.59173 5.012597,-0.74752 5.322618,-3.98993 0.353157,-3.69354 0.980661,-3.5549 -7.822618,-1.72831 -1.375,0.2853 -4.678743,0.79632 -7.34165,1.13561 -5.44087,0.69324 -5.438718,1.06954 0.01724,3.01522 2.20483,0.78628 2.97744,1.37548 1.824409,1.3913 -2.874289,0.0394 -9.463171,-3.96935 -11.8797229,-7.22782 C 7.1644207,100.74877 6.5278887,98.319826 6.4692857,94.503874 6.4148637,90.960165 5.813202,88.451072 4.7311641,87.255433 0.24450836,82.297735 -1.3621094,72.389696 1.6283355,68.120238 2.5239201,66.841612 3.3733615,63.632774 3.5159832,60.989488 3.8540251,54.724373 8.084633,46.990999 13.684041,42.402705 c 2.390844,-1.959117 5.003249,-4.831098 5.805344,-6.382178 2.18137,-4.218304 12.620022,-10.78601 18.289239,-11.507076 2.596757,-0.330281 7.198684,-1.900805 10.226505,-3.490054 3.027821,-1.58925 7.977821,-3.197212 11,-3.57325 3.022179,-0.376038 8.18009,-1.289042 11.462024,-2.028897 3.515717,-0.792558 8.273981,-1.10408 11.582309,-0.758292 3.588344,0.375057 6.438018,0.146518 7.894844,-0.633151 3.562105,-1.906381 11.377804,-1.416291 16.137474,1.011915 3.79634,1.936748 4.80098,2.04611 9.82352,1.069354 5.93638,-1.154475 12.28246,-0.0982 18.5947,3.094997 1.65,0.834692 5.53008,1.766351 8.6224,2.070352 3.09231,0.304001 7.50009,1.51066 9.79506,2.681464 4.52675,2.309378 11.62604,8.320607 13.11715,11.106785 0.84677,1.582204 0.61253,1.639828 -2.62582,0.645951 -2.76955,-0.849997 -3.73278,-0.80444 -4.35732,0.206088 -0.54279,0.878256 -1.5689,1.037237 -3.17662,0.492174 -1.30617,-0.442825 -2.77701,-0.694428 -3.26854,-0.559116 -2.28468,0.628943 -6.57531,-1.176751 -7.15792,-3.012375 -0.5328,-1.678704 -1.20474,-1.918086 -3.9424,-1.404497 -2.79094,0.523583 -3.77743,0.141818 -6.39349,-2.474242 -2.22394,-2.22394 -3.84727,-3.004157 -5.7758,-2.776003 -4.09719,0.484715 -3.74721,2.105213 0.93242,4.317346 5.38475,2.545453 6.21895,6.184322 2.15125,9.383978 C 130.94082,41.04779 129.20259,42 128.55764,42 c -0.64495,0 -2.59999,2.025 -4.34453,4.5 -1.74454,2.475 -2.84367,4.495129 -2.4425,4.489176 0.40116,-0.006 2.94672,-0.683455 5.65679,-1.505559 C 133.04,47.781026 136,45.505057 136,42.892065 136,40.222535 138.14854,36 139.50688,36 c 0.65221,0 2.71748,0.768986 4.58948,1.708859 2.16571,1.087331 6.13146,1.77172 10.90364,1.881694 4.125,0.09506 8.79254,0.685863 10.37232,1.312897 2.71084,1.075967 2.84013,1.012344 2.29974,-1.131695 -0.5577,-2.212675 -0.53593,-2.219743 0.83691,-0.271755 1.9252,2.731764 2.09916,2.884806 9.63705,8.478103 3.65531,2.71233 8.20103,6.864347 10.1016,9.226703 8.091,10.056905 11.90716,23.248193 9.80972,33.909253 -0.88805,4.513863 -0.89726,6.840957 -0.0374,9.446351 0.6275,1.90136 0.91525,4.0156 0.63944,4.69831 -0.27582,0.6827 -0.53701,0.30378 -0.58043,-0.84205 -0.14939,-3.94212 -1.41279,-3.40419 -3.13494,1.33481 -0.94909,2.61169 -2.45579,6.43602 -3.34823,8.49852 -1.85196,4.28001 -0.66287,5.02753 1.86365,1.17158 0.94288,-1.43902 2.29085,-2.34765 3.0504,-2.05618 0.74853,0.28723 1.5795,-0.015 1.84661,-0.67158 0.26712,-0.6566 0.52119,-0.38839 0.56461,0.59602 0.0434,0.98441 -0.82144,3.55474 -1.92191,5.71184 -3.88297,7.61126 -9.84413,11.39158 -17.65517,11.19618 l -5.15602,-0.12897 1.49059,3.79466 c 1.98856,5.0624 0.50536,10.57833 -4.46072,16.58908 -2.0448,2.47494 -4.81003,5.9155 -6.14495,7.64567 -4.2804,5.54779 -9.5939,8.63447 -17.20511,9.99467 -6.94359,1.24089 -11.73893,0.73938 -26.45717,-2.76696 -1.84014,-0.43838 -2.03538,-0.12961 -1.6365,2.58811 0.2491,1.69723 0.28933,3.0472 0.0894,2.99993 -0.19993,-0.0473 -1.69088,-0.4824 -3.31323,-0.96694 z M 142,166.87607 c 0,-0.61816 2.025,-2.9064 4.5,-5.08499 2.475,-2.17858 4.5,-4.37281 4.5,-4.87607 0,-0.50325 -1.4625,-0.94664 -3.25,-0.9853 -1.7875,-0.0386 -4.15,-0.45702 -5.25,-0.92971 -1.2897,-0.5542 1.8388,-0.88439 8.80902,-0.92971 6.17465,-0.0402 10.56925,-0.45823 10.24981,-0.97511 -0.30757,-0.49765 -2.29426,-0.6721 -4.41487,-0.38766 C 153.39818,153.20993 149,151.79424 149,150.08614 c 0,-2.07169 12.32724,-4.98371 13.4445,-3.17595 1.23343,1.99575 2.60207,1.12355 2.00016,-1.27465 -0.42679,-1.70049 -0.0811,-2.59894 1.23095,-3.19942 1.22529,-0.56077 -0.96687,-1.02374 -6.67561,-1.40987 -5.94894,-0.40237 -9.93171,-1.27263 -13.27038,-2.89965 -3.86145,-1.8818 -5.67155,-2.19696 -9.5,-1.65409 -9.39554,1.33229 -13.6166,1.046 -18.29534,-1.24088 -5.43693,-2.65746 -4.78932,-2.62035 -11.53037,-0.66067 -5.10988,1.48548 -5.40391,1.74805 -5.40391,4.82568 0,2.17875 0.82648,4.03117 2.5,5.60336 2.71558,2.55115 3.22494,2.13368 1.25174,-1.02592 -1.61214,-2.58144 0.7992,-7.32715 3.95491,-7.78357 2.69744,-0.39014 9.84218,3.19138 10.67002,5.34868 1.5328,3.99443 0.67708,6.54611 -2.57554,7.67998 -2.81911,0.98275 -2.96751,1.20567 -1.25,1.8777 2.66424,1.04247 8.65594,1.05819 10.28272,0.027 1.07393,-0.68077 1.02522,-0.96395 -0.25,-1.4533 -2.71874,-1.04328 -1.88743,-5.3182 1.50377,-7.73294 5.56277,-3.96105 13.91238,-2.58474 13.91238,2.29324 0,2.02525 0.36102,2.03911 6.6571,0.25565 1.01359,-0.28712 -3.01405,1.90541 -8.95032,4.87229 -5.93627,2.96688 -11.04059,5.64169 -11.34293,5.94403 -0.30234,0.30234 0.84211,1.26944 2.54322,2.14912 1.70111,0.87968 3.09461,2.15036 3.09667,2.82374 0.002,0.67338 0.89544,2.68682 1.9853,4.47432 1.38998,2.27974 2.73231,3.25 4.49626,3.25 1.38309,0 2.5147,-0.50577 2.5147,-1.12393 z m -4.82874,-4.97345 c -1.5977,-2.55832 -1.33884,-2.84991 3.49864,-3.94094 5.17689,-1.16758 6.11052,0.20385 2.31371,3.39866 -3.78373,3.18379 -4.14183,3.2172 -5.81235,0.54228 z m -24.28137,-2.5353 C 112.26576,158.61529 110.89984,158 109.8545,158 c -1.80098,0 -1.81414,0.13196 -0.25109,2.51749 1.30047,1.98475 1.94279,2.27409 3.03539,1.36732 1.04849,-0.87018 1.10962,-1.48302 0.25109,-2.51749 z m -7.61904,-9.53472 c 2.11951,-1.30992 0.0697,-1.91069 -4.1934,-1.22899 l -4.189561,0.66993 2.772608,2.89398 2.772603,2.89398 0.83327,-2.25252 c 0.45829,-1.23889 1.36031,-2.57825 2.00448,-2.97638 z m 6.64582,-0.19715 c -0.22917,-0.2005 -1.54167,-0.90032 -2.91667,-1.55516 -2.35727,-1.12265 -2.38918,-1.10183 -0.55887,0.36454 1.593,1.27626 4.84786,2.39128 3.47554,1.19062 z M 99.607914,139.5 c -0.353688,-1.12139 -3.637586,-0.78517 -4.984698,0.51036 -0.482231,0.46376 -0.565324,2.08416 -0.184651,3.60089 l 0.692134,2.75768 2.396308,-2.93447 C 98.844976,141.82051 99.781385,140.05 99.607914,139.5 z M 149,133.57143 C 149,130.96912 151.34331,128 153.39711,128 c 0.68985,0 2.28963,-1.10209 3.55507,-2.4491 2.20932,-2.35171 9.69124,-5.5509 12.98185,-5.5509 0.86776,0 2.19056,-1.38445 2.93956,-3.07655 1.63272,-3.68857 3.78211,-4.73559 5.42445,-2.64239 1.83688,2.34113 7.12365,3.12068 8.65449,1.27613 1.7971,-2.16537 0.55735,-4.55719 -2.36213,-4.55719 -3.61074,0 -3.95242,-1.45185 -1.34447,-5.7128 2.13621,-3.49021 2.30934,-4.82946 2.20775,-17.078292 -0.0853,-10.28608 0.17355,-13.182195 1.14493,-12.809441 2.17842,0.835936 3.69285,-2.189838 3.14402,-6.281634 -0.28498,-2.124667 -0.16028,-4.442053 0.27709,-5.149748 1.14253,-1.848645 -0.0164,-4.183326 -1.74699,-3.519249 -1.46424,0.561883 -6.33704,-0.842055 -13.59613,-3.917279 -2.10288,-0.890856 -4.70161,-1.341007 -5.77496,-1.000338 -1.74911,0.555145 -1.4663,1.156209 2.72625,5.794091 10.99536,12.163314 12.99414,26.564341 5.69263,41.0149 -4.99749,9.89064 -16.15022,18.74026 -27.32052,21.67869 -5.66586,1.49045 -6.53922,2.02981 -4.91362,3.03449 1.03223,0.63795 1.05421,1.34262 0.10676,3.42205 C 143.35291,134.51431 143.70435,136 146.5,136 c 1.98039,0 2.5,-0.50476 2.5,-2.42857 z M 184.36408,71.774037 C 180.62188,70.060801 178.29732,62 181.54545,62 183.95286,62 188,66.637155 188,69.395528 c 0,3.067781 -0.87709,3.641544 -3.63592,2.378509 z m -113.846611,59.218473 4.831353,-2.07096 -3.674411,-2.49682 C 69.653485,125.05147 68,123.74336 68,123.51781 c 0,-0.22555 2.548835,0.46684 5.664077,1.53864 5.980205,2.05749 7.370523,2.04708 4.860089,-0.0364 -2.131615,-1.76909 -1.899051,-4.24055 0.657231,-6.98439 l 2.181398,-2.34146 -5.431398,0.67492 c -13.521255,1.68017 -14.031125,1.80578 -12.893659,3.17634 1.82261,2.19611 -2.992847,10.21834 -5.283797,8.80246 -0.462853,-0.28606 -1.384339,-0.0719 -2.047746,0.47583 C 55.042788,129.37153 52.925,130.24732 51,130.76995 l -3.5,0.95024 3.5,1.10895 c 4.76187,1.50876 13.668214,0.67066 19.517469,-1.83663 z M 111.8984,131.25 125.5,128.5 l -6.73957,-0.29545 c -6.78288,-0.29735 -19.959795,2.69098 -21.279191,4.82581 -0.811478,1.31299 -0.994444,1.33559 14.417161,-1.78036 z m -13.987864,-4.88303 c 0.225795,-0.19509 -0.336705,-1.1804 -1.25,-2.18958 -2.875093,-3.17694 -2.1187,-5.95688 1.924571,-7.07328 4.755743,-1.31312 8.414893,0.0658 8.414893,3.17114 0,1.27861 -0.54,2.86475 -1.2,3.52475 -0.93333,0.93333 -0.26667,1.2 3,1.2 4.53857,0 4.71538,-0.16848 3.18254,-3.03263 -0.87633,-1.63743 -0.56423,-2.02383 2.25,-2.78568 3.58654,-0.97093 8.42364,0.75876 9.4259,3.3706 0.57304,1.49333 5.34156,2.07235 5.34156,0.6486 0,-1.01594 5.97252,-3.20089 8.74957,-3.20089 1.15916,0 2.78257,0.675 3.60757,1.5 1.96647,1.96647 2.97798,1.89217 5.02438,-0.36908 0.93032,-1.02799 3.69023,-2.14304 6.13312,-2.47787 C 156.95748,118.04409 161,116.18914 161,114.75945 161,114.34175 160.325,114 159.5,114 c -0.825,0 -1.5,-0.46037 -1.5,-1.02305 0,-0.56423 -1.00909,-0.36266 -2.25,0.44946 -3.79238,2.48192 -10.03216,2.99616 -13.6506,1.12499 -4.04946,-2.09406 -4.82509,-4.09203 -2.56015,-6.59478 2.1203,-2.3429 1.68377,-3.08921 -1.34386,-2.29746 -3.24644,0.84896 -3.94172,4.9175 -1.31769,7.71065 3.01464,3.20895 2.65303,3.95835 -1.6277,3.37325 -2.0625,-0.2819 -4.875,-0.19216 -6.25,0.19943 -2.40233,0.68416 -5.72341,-0.26949 -12.33104,-3.54087 C 115.11189,112.63073 111.67949,112 109.04141,112 c -5.08016,0 -7.72524,-1.77558 -6.68467,-4.48727 0.84202,-2.19426 -1.27778,-1.83692 -5.85674,0.98729 -2.2,1.35692 -6.236606,3.53671 -8.970234,4.84398 l -4.970235,2.37686 3.220235,1.66525 c 3.146845,1.6273 3.845555,3.45706 3.388656,8.87411 -0.128058,1.51828 0.434337,1.67096 4.091557,1.11084 2.332011,-0.35716 4.424762,-0.809 4.650557,-1.00409 z M 66.5,114.07464 c 6.6,-1.00867 13.35,-2.37305 15,-3.03197 l 3,-1.19803 -2.261496,-1.84192 C 80.263272,106.39395 72.166617,104 68.700779,104 68.040351,104 67.5,102.93233 67.5,101.62741 c 0,-2.31117 0.362415,-2.412075 14,-3.897919 7.7,-0.838931 18.53687,-1.458766 24.08193,-1.37741 9.7199,0.142607 10.16876,0.248549 12.5,2.950271 3.1301,3.627548 8.35767,4.767788 16.5436,3.608518 10.15155,-1.43764 15.99731,-5.168983 19.7575,-12.61121 3.67389,-7.271427 1.06779,-13.349612 -7.63985,-17.818348 -3.13046,-1.606543 -4.13508,-2.439431 -2.49318,-2.066996 3.85393,0.874194 3.67782,-1.883162 -0.25,-3.914316 -3.93905,-2.036964 -3.79046,-3.261083 0.49343,-4.064745 4.41725,-0.828682 7.44494,-0.07297 10.27647,2.565001 2.86697,2.670989 2.85816,6.333445 -0.0199,8.26888 l -2.25,1.513079 2.47442,2.662226 c 2.30083,2.475466 2.5639,2.539849 3.75,0.917762 C 159.42599,77.402749 160,75.353749 160,73.80887 c 0,-3.379692 1.32833,-3.605896 3.4433,-0.586364 C 166.71611,77.895104 164.08443,87 159.46104,87 158.55107,87 158,87.989125 158,89.622445 c 0,2.236159 0.22451,2.436118 1.52417,1.357499 2.45978,-2.041435 2.81093,-0.424266 0.96018,4.421867 -1.77327,4.643249 -2.6861,5.232499 -10.98336,7.089929 l -2.99901,0.67136 2.49901,1.38301 c 3.96741,2.19567 8.8981,1.76823 12.65462,-1.097 1.83941,-1.40299 3.34439,-3.41272 3.34439,-4.466074 0,-2.732069 3.06377,-8.79353 4.77699,-9.450955 0.79668,-0.305712 2.97276,0.386208 4.83575,1.537599 3.74535,2.314752 4.30699,1.479603 2.39209,-3.556974 -0.79817,-2.099338 -1.33744,-2.425948 -2.72418,-1.649892 -4.34798,2.433253 -6.86012,-3.312372 -3.9155,-8.955322 1.2338,-2.364409 1.0966,-2.968284 -1.55937,-6.863456 -1.60171,-2.349021 -2.77576,-4.383938 -2.60899,-4.522037 0.16677,-0.138099 1.29895,-0.768909 2.51597,-1.401799 1.43798,-0.747794 1.99807,-1.710187 1.59961,-2.748556 -0.47473,-1.237128 -1.59056,-1.487678 -4.94271,-1.109842 -2.76715,0.311897 -4.96832,0.0033 -6.09961,-0.855096 -1.17544,-0.891915 -4.85756,-1.353783 -10.96103,-1.374903 C 143.25398,58.014312 138.83992,57.55 138.5,57 c -1.11862,-1.809964 -3.5,-1.049293 -3.5,1.117985 0,1.164892 -1.35,3.65555 -3,5.534796 -1.65,1.879246 -3,3.837681 -3,4.352078 0,0.514396 1.35945,1.940349 3.02099,3.168784 l 3.021,2.233518 -2.22863,1.192726 c -1.429,0.764777 -3.04801,0.881197 -4.51231,0.324472 -1.25603,-0.47754 -2.85009,-0.655733 -3.54237,-0.395984 -2.27718,0.854419 -6.92574,-2.9332 -8.2101,-6.689538 -1.01646,-2.972815 -1.00053,-4.382917 0.0847,-7.5 1.74162,-5.002223 1.70328,-5.863083 -0.1911,-4.290888 -2.67447,2.219618 -4.60816,8.181644 -4.93144,15.204822 -0.3215,6.984615 0.80973,9.396973 3.00117,6.400004 1.64545,-2.250295 2.9024,-2.096352 8.71523,1.06739 l 4.99784,2.720166 1.67937,-2.073926 C 134.96296,73.119326 151,74.372063 151,81.014295 151,83.319945 139.69707,87 132.61549,87 125.3382,87 117.14847,88.659585 114.05857,90.760419 111.8237,92.279918 108.77994,92.5 90,92.5 l -21.5,0 -11.25358,5.231846 c -11.874873,5.520694 -16.256313,7.039524 -16.231107,5.626564 0.03309,-1.85504 1.849774,-3.19893 11.393906,-8.428644 8.371546,-4.587196 9.493285,-5.479184 7.228816,-5.748233 -2.825331,-0.335685 -8.016566,2.369282 -11.112633,5.790398 -1.013656,1.120077 -3.592072,2.507477 -5.729813,3.083111 -2.66843,0.718534 -4.498263,2.049438 -5.837458,4.245778 C 34.655654,106.07701 34.426359,109 36.432612,109 c 0.787937,0 1.702495,0.85032 2.032351,1.88961 0.329856,1.03928 1.82268,2.12738 3.317387,2.41799 3.544672,0.68919 19.586238,-1.00655 27.71765,-2.93001 1.56745,-0.37077 1.675587,-0.26911 0.5,0.47007 C 68.220427,111.9666 55.641686,114 50.49943,114 c -2.156999,0 -3.367947,0.40373 -2.99943,1 0.864962,1.39954 5.154358,1.19063 19,-0.92536 z M 56.083333,103.69734 C 56.3125,103.53088 57.7375,102.6205 59.25,101.67429 61.910709,100.00975 62,100.01958 62,101.97695 62,103.58178 61.345362,104 58.833333,104 c -1.741666,0 -2.979166,-0.1362 -2.75,-0.30266 z M 64.227992,100.25 c -0.159436,-2.105653 0.02018,-2.398538 0.766579,-1.25 1.178004,1.81268 1.30024,4 0.223537,4 -0.430041,0 -0.875593,-1.2375 -0.990116,-2.75 z M 123,99.812278 c -2.21705,-1.505615 -3.61167,-3.328311 -3.80464,-4.972458 -0.37321,-3.179829 2.36018,-4.12873 11.30464,-3.924423 4.05418,0.0926 8.3512,-0.662893 13.25,-2.3296 l 7.25,-2.466651 0,2.490087 c 0,7.019608 -6.69227,11.831207 -18,12.941627 -5.79018,0.56859 -6.88221,0.37873 -10,-1.738582 z m 14.75,-30.474559 c 0.6875,-0.277412 1.8125,-0.277412 2.5,0 0.6875,0.277413 0.125,0.504386 -1.25,0.504386 -1.375,0 -1.9375,-0.226973 -1.25,-0.504386 z M 36.451325,100.07876 C 36.764472,99.572075 39.15353,98.373925 41.760342,97.416203 44.367154,96.458481 47.85,94.452037 49.5,92.957439 53.305722,89.510151 56.249549,88.001491 59.184259,87.994423 60.457916,87.991356 63.3,87.449842 65.5,86.791059 l 4,-1.197788 -4,-0.65473 -4,-0.65473 4.833333,-0.141906 c 3.367617,-0.09887 4.707408,-0.519683 4.418081,-1.387664 C 70.523025,82.069074 69.698025,81.497357 68.91808,81.48376 66.551968,81.44251 63,79.922773 63,78.951664 63,78.449206 64.149112,77.749695 65.553582,77.397196 69.581225,76.386322 68.503826,72.643404 64,72 61.226755,71.603822 60.493763,71.043867 60.469964,69.303297 60.453444,68.09511 60.115944,66.78261 59.719964,66.38663 58.221677,64.888343 59.103844,62.99766 62,61.5 66.319656,59.266219 66.125162,55.504195 61.577913,53.335763 59.695766,52.43823 57.937894,50.87051 57.671533,49.851942 57.363938,48.675698 56.279969,48 54.700608,48 53.332961,48 51.954956,47.325 51.638374,46.5 51.321791,45.675 50.148646,45 49.031385,45 c -2.457797,0 -2.554834,0.764114 -0.399485,3.145748 1.524518,1.684573 1.442235,1.969659 -1.250443,4.332443 -1.585289,1.391067 -4.415534,3.315047 -6.289434,4.275511 -4.421893,2.266433 -4.116774,3.670503 0.88083,4.053332 3.326377,0.254808 3.904087,0.03585 3.396367,-1.287246 -0.338183,-0.881291 0.182594,-2.472054 1.164486,-3.557033 C 48.64838,53.626067 53,53.314647 53,55.5 c 0,0.825 0.675,1.5 1.5,1.5 0.825,0 1.5,0.8625 1.5,1.916667 0,1.054166 0.5625,2.112703 1.25,2.352304 0.6875,0.2396 -0.6625,0.766654 -3,1.171231 C 50.261437,63.130546 48.23624,65 51.476947,65 c 0.812321,0 2.215551,1.127253 3.11829,2.505006 1.386607,2.11623 1.43241,2.756755 0.295124,4.1271 -1.094558,1.318863 -2.66431,1.522407 -8.397164,1.088833 -6.687462,-0.505772 -14.864641,0.317171 -16.175339,1.62787 -0.886351,0.886351 1.615852,3.565551 4.931144,5.279955 2.167627,1.120924 3.234202,1.215102 4.246504,0.374966 0.99925,-0.829304 2.441351,-0.828549 5.529107,0.0029 4.238229,1.141236 6.860215,0.726369 3.050748,-0.48271 -5.5018,-1.746203 1.775698,-3.956054 7.669177,-2.328787 4.052539,1.11896 3.506022,2.33875 -1.483493,3.311062 -3.178951,0.619486 -3.451507,0.858306 -1.761045,1.543078 1.99576,0.808441 1.99574,0.810307 -0.0095,0.880444 -2.511451,0.08784 -4.784176,3.569783 -3.981268,6.099521 0.473447,1.4917 -0.0036,2.034647 -2.202464,2.50666 -1.543748,0.331385 -3.84603,1.0239 -5.116181,1.538922 -1.834705,0.743937 -2.984563,0.421405 -5.594391,-1.569208 C 32.128609,88.860717 27.183144,88.216856 25.242382,90.157618 23.754804,91.645196 21,89.562406 21,86.950135 21,85.121081 16.615727,81 14.66986,81 14.086628,81 12.392314,79.833922 10.904719,78.408715 L 8.2,75.81743 l 0,3.657952 c 0,2.011873 -0.27,3.927951 -0.6,4.257951 C 6.3443065,84.989027 7.0792843,75.371637 8.4380714,72.766935 9.7586083,70.235557 8.916103,67.708697 7.5100813,69.983688 6.678587,71.329074 3,71.294242 3,69.940983 3,69.358524 2.55,69.160081 2,69.5 c -1.83493421,1.134052 -1.07856514,9.036864 1.2943835,13.524177 2.494937,4.717998 4.6594306,6.21503 4.7845639,3.309156 0.049651,-1.153015 0.2736777,-1.346795 0.6037103,-0.522202 0.4114625,1.028047 0.916382,0.956721 2.3385873,-0.330358 2.993159,-2.708771 6.290487,-1.541668 7.117381,2.519227 0.525335,2.579935 0.332384,3.713313 -0.734004,4.31146 -1.964117,1.101693 -1.000792,2.343749 3.663227,4.723154 L 25,99.040648 25,96.180839 c 0,-3.954525 4.152735,-5.966008 7.622832,-3.692313 C 35.350676,94.275878 35.658301,96.208769 33.5,98 c -0.825,0.684689 -1.5,1.639789 -1.5,2.12244 0,1.1668 3.725805,1.13023 4.451325,-0.0437 z M 57.269032,83.307009 c 0.972967,-0.253543 2.322967,-0.236869 3,0.03705 C 60.946064,83.617986 60.15,83.825431 58.5,83.805051 56.85,83.784672 56.296064,83.560553 57.269032,83.307009 z m 32.367142,3.610768 c 4.279492,-0.595222 9.149553,-1.683514 10.822356,-2.418426 2.91547,-1.280846 2.74796,-1.339582 -4.043374,-1.417777 -6.054001,-0.0697 -18.427759,2.678896 -20.331823,4.516338 -0.764581,0.737829 5.685195,0.414154 13.552841,-0.680135 z M 78.75,83.369714 c 3.17118,-0.849843 2.793844,-2.010945 -0.89316,-2.748346 -3.189543,-0.637909 -6.31166,0.833701 -5.286813,2.491939 0.632517,1.023433 2.957824,1.11991 6.179973,0.256407 z m 13.462553,-3.9156 C 92.51279,79.153876 91.68779,75.536733 90.379219,71.416018 84.975551,54.399759 89.814597,35.08577 102.48363,23.103927 105.51763,20.234492 108,17.698805 108,17.469066 c 0,-0.830576 -5.94378,-3.46781 -7.70034,-3.416614 -1.554618,0.04531 -1.493299,0.266158 0.45034,1.621972 C 101.9875,16.53766 103,17.81744 103,18.51838 103,19.920279 96.491625,26 94.990884,26 93.6425,26 91,31.476801 91,34.271439 c 0,1.44735 -1.752747,4.200027 -4.5,7.06722 -2.475,2.583053 -4.5,5.363558 -4.5,6.1789 C 82,48.432163 81.042395,49 79.5,49 77.384343,49 77,48.534983 77,45.975249 77,43.668981 76.406164,42.724722 74.5,42 72.891801,41.388564 71.971028,40.238052 71.918781,38.774751 71.845534,36.723273 71.702732,36.794458 70.463885,39.5 c -2.023071,4.418223 -1.878353,4.889991 3.058118,9.969247 3.782552,3.891959 5.039915,4.60194 7.689204,4.341776 3.546577,-0.348278 4.502401,1.380035 4.689113,8.478815 0.05482,2.084411 0.944154,5.459411 1.97629,7.5 1.183236,2.339325 1.695523,4.910977 1.3865,6.960162 -0.361168,2.394973 -0.109469,3.25 0.956724,3.25 0.795758,0 1.692481,-0.245649 1.992719,-0.545886 z M 16,65 c 1.375,-1.075541 2.975875,-1.965534 3.5575,-1.977764 0.581624,-0.01223 2.489987,-2.054523 4.240806,-4.53843 5.192366,-7.366467 17.648047,-13.962358 28.69083,-15.193194 2.755975,-0.307183 5.76093,-1.209103 6.677677,-2.004267 1.309695,-1.135998 2.125017,-1.20053 3.805439,-0.301195 1.176244,0.629506 2.610694,0.987201 3.187666,0.794877 1.800928,-0.600309 -8.257847,-7.707772 -11.866442,-8.384749 -3.35431,-0.629272 -3.413452,-0.725671 -2.772551,-4.519133 C 52.036455,25.824752 51.860693,25 50.694887,25 c -2.016428,0 -2.70035,2.191486 -2.010532,6.442335 L 49.261685,35 44.880842,34.9937 c -3.816456,-0.0055 -4.600303,-0.391999 -6.084332,-3 C 37.762086,30.175802 36.276903,29 35.015126,29 c -2.268307,0 -2.847653,0.952668 -3.344718,5.5 -0.710446,6.499428 -3.113927,9.058021 -12.821537,13.648995 L 13,50.915074 l 0,6.460675 c 0,3.553372 -0.273145,7.17248 -0.606989,8.042464 C 11.57929,67.538735 12.958911,67.378775 16,65 z m 0.353114,-3.331787 C 16.708901,60.660729 17,58.76644 17,57.458682 c 0,-2.517028 3.074111,-5.889816 8.044111,-8.825667 l 3.004111,-1.774573 -2.774111,3.894615 c -5.61353,7.880915 -9.550637,12.698105 -8.920997,10.915156 z M 30,45.10638 C 30,43.739912 32.421041,42 34.322445,42 c 1.529123,0 1.686096,0.284782 0.767241,1.391935 C 33.809391,44.934596 30,46.217778 30,45.10638 z M 46,38.269697 C 50.791565,36.207841 55.5,36.074173 55.5,38 c 0,1.165345 -1.450173,1.530764 -6.5,1.63789 l -6.5,0.137889 3.5,-1.506082 z m 69.01506,12.373314 c 0.0305,-12.457703 6.0174,-22.184766 16.67035,-27.084874 4.56214,-2.098479 4.70082,-2.275636 2.64482,-3.378615 -1.74026,-0.933596 -3.47234,-0.761692 -8.75,0.868412 C 119.31241,22.983866 119,23.228583 119,26.202323 119,29.769647 114.55764,38 112.63216,38 c -0.70594,0 -2.34041,1.125 -3.63216,2.5 -2.72656,2.902291 -4.63462,3.140643 -7.12192,0.889663 -1.5679,-1.41893 -2.278576,-1.448646 -5.979014,-0.25 -2.681536,0.868603 -4.491805,2.1647 -5.007938,3.585532 -0.777731,2.140968 -0.637701,2.201808 3.699444,1.607336 2.870562,-0.393454 5.374041,-0.154245 6.892888,0.658619 1.31182,0.702063 3.24426,1.05181 4.29431,0.777214 1.81537,-0.474728 4.22223,1.892652 4.22223,4.152967 0,2.769529 2.05207,5.995918 3.46799,5.45258 1.14347,-0.438793 1.53583,-2.145829 1.54707,-6.7309 z m 31.28162,-6.111586 C 145.30851,43.173709 144.05,42.050391 143.5,42.035163 142.30942,42.0022 136,45.745906 136,46.485302 136,46.768386 138.72101,47 142.04668,47 l 6.04669,0 -1.79669,-2.468575 z M 72.76605,31.201851 C 72.981127,30.556619 71.996752,29.500012 70.57855,28.853836 67.552988,27.475297 67.143482,25 69.940983,25 c 2.943441,0 3.246142,-1.47563 0.778197,-3.79362 L 68.5,19.122041 l -3.256617,3.879605 -3.256618,3.879606 4.256618,3.011957 c 4.353681,3.080639 5.833065,3.377448 6.522667,1.308642 z M 199.15789,109 c 0,-1.375 0.22698,-1.9375 0.50439,-1.25 0.27741,0.6875 0.27741,1.8125 0,2.5 -0.27741,0.6875 -0.50439,0.125 -0.50439,-1.25 z" + id="path2993" + inkscape:connector-curvature="0" /> + <path + style="fill:#0c0f05" + d="m 126.58491,186.10872 c -1.0533,-0.41289 -2.03297,-1.55386 -2.17704,-2.53549 -0.22486,-1.53206 0.0817,-1.46192 2.16509,0.49531 1.33487,1.25405 2.42704,2.42665 2.42704,2.60577 0,0.38556 0.0281,0.39214 -2.41509,-0.56559 z M 117.87244,180.25 c -1.24387,-1.58606 -1.2085,-1.62143 0.37756,-0.37756 0.9625,0.75485 1.75,1.54235 1.75,1.75 0,0.82304 -0.82119,0.29331 -2.12756,-1.37244 z m 4.58644,-0.31653 c -0.36253,-0.58659 -0.44468,-1.281 -0.18255,-1.54313 0.26212,-0.26213 0.74306,0.21781 1.06875,1.06653 0.67618,1.76211 0.0999,2.07206 -0.8862,0.4766 z m -5.90861,-9.98636 c -1.62236,-0.48454 -3.15088,-0.67984 -3.39671,-0.434 -0.24584,0.24583 -1.43567,-1.68703 -2.64408,-4.29525 -1.25472,-2.70817 -3.87256,-6.00434 -6.10329,-7.68475 -6.419581,-4.83586 -9.35184,-8.7138 -11.177038,-14.78172 C 92.278118,139.58965 91.05,137.00749 90.5,137.01325 c -0.55,0.006 -3.475,0.67481 -6.5,1.48675 -5.126225,1.37594 -12.13707,1.99557 -9.167619,0.81026 0.880776,-0.35158 0.267142,-1.17966 -1.810413,-2.44309 -2.725933,-1.65774 -3.661001,-1.75599 -7.049635,-0.74073 -4.487001,1.34433 -4.324394,2.80453 0.336684,3.02339 3.116399,0.14633 3.125167,0.15972 0.375095,0.57278 -1.901324,0.28558 -5.523457,-0.89984 -11.152328,-3.64983 C 50.946743,133.83275 46.792719,132 46.30062,132 c -0.492098,0 -2.673551,-1.8211 -4.847672,-4.04688 -3.748281,-3.83736 -3.962309,-4.39395 -4.133742,-10.75 L 37.138411,110.5 l -6.819205,0.11577 c -6.17989,0.10491 -6.350445,0.058 -1.819206,-0.5 4.804769,-0.59173 5.012597,-0.74752 5.322618,-3.98993 0.353157,-3.69354 0.980661,-3.5549 -7.822618,-1.72831 -1.375,0.2853 -4.678743,0.79632 -7.34165,1.13561 -5.44087,0.69324 -5.438718,1.06954 0.01724,3.01522 2.20483,0.78628 2.97744,1.37548 1.824409,1.3913 -2.874289,0.0394 -9.463171,-3.96935 -11.8797229,-7.22782 C 7.1644207,100.74877 6.5278887,98.319826 6.4692857,94.503874 6.4148637,90.960165 5.813202,88.451072 4.7311641,87.255433 0.24450836,82.297735 -1.3621094,72.389696 1.6283355,68.120238 2.5239201,66.841612 3.3733615,63.632774 3.5159832,60.989488 3.8540251,54.724373 8.084633,46.990999 13.684041,42.402705 c 2.390844,-1.959117 5.003249,-4.831098 5.805344,-6.382178 2.18137,-4.218304 12.620022,-10.78601 18.289239,-11.507076 2.596757,-0.330281 7.198684,-1.900805 10.226505,-3.490054 3.027821,-1.58925 7.977821,-3.197212 11,-3.57325 3.022179,-0.376038 8.18009,-1.289042 11.462024,-2.028897 3.515717,-0.792558 8.273981,-1.10408 11.582309,-0.758292 3.588344,0.375057 6.438018,0.146518 7.894844,-0.633151 3.562105,-1.906381 11.377804,-1.416291 16.137474,1.011915 3.79634,1.936748 4.80098,2.04611 9.82352,1.069354 5.93638,-1.154475 12.28246,-0.0982 18.5947,3.094997 1.65,0.834692 5.53008,1.766351 8.6224,2.070352 3.09231,0.304001 7.50009,1.51066 9.79506,2.681464 4.52675,2.309378 11.62604,8.320607 13.11715,11.106785 0.84677,1.582204 0.61253,1.639828 -2.62582,0.645951 -2.76955,-0.849997 -3.73278,-0.80444 -4.35732,0.206088 -0.54279,0.878256 -1.5689,1.037237 -3.17662,0.492174 -1.30617,-0.442825 -2.77701,-0.694428 -3.26854,-0.559116 -2.28468,0.628943 -6.57531,-1.176751 -7.15792,-3.012375 -0.5328,-1.678704 -1.20474,-1.918086 -3.9424,-1.404497 -2.79094,0.523583 -3.77743,0.141818 -6.39349,-2.474242 -2.22394,-2.22394 -3.84727,-3.004157 -5.7758,-2.776003 -4.09719,0.484715 -3.74721,2.105213 0.93242,4.317346 5.38475,2.545453 6.21895,6.184322 2.15125,9.383978 C 130.94082,41.04779 129.20259,42 128.55764,42 c -0.64495,0 -2.59999,2.025 -4.34453,4.5 -1.74454,2.475 -2.84367,4.495129 -2.4425,4.489176 0.40116,-0.006 2.94672,-0.683455 5.65679,-1.505559 C 133.04,47.781026 136,45.505057 136,42.892065 136,40.222535 138.14854,36 139.50688,36 c 0.65221,0 2.71748,0.768986 4.58948,1.708859 2.16571,1.087331 6.13146,1.77172 10.90364,1.881694 4.125,0.09506 8.79254,0.685863 10.37232,1.312897 2.71084,1.075967 2.84013,1.012344 2.29974,-1.131695 -0.5577,-2.212675 -0.53593,-2.219743 0.83691,-0.271755 1.9252,2.731764 2.09916,2.884806 9.63705,8.478103 3.65531,2.71233 8.20103,6.864347 10.1016,9.226703 8.091,10.056905 11.90716,23.248193 9.80972,33.909253 -0.88805,4.513863 -0.89726,6.840957 -0.0374,9.446351 0.6275,1.90136 0.91525,4.0156 0.63944,4.69831 -0.27582,0.6827 -0.53701,0.30378 -0.58043,-0.84205 -0.14939,-3.94212 -1.41279,-3.40419 -3.13494,1.33481 -0.94909,2.61169 -2.45579,6.43602 -3.34823,8.49852 -1.85196,4.28001 -0.66287,5.02753 1.86365,1.17158 0.94288,-1.43902 2.29085,-2.34765 3.0504,-2.05618 0.74853,0.28723 1.5795,-0.015 1.84661,-0.67158 0.26712,-0.6566 0.52119,-0.38839 0.56461,0.59602 0.0434,0.98441 -0.82144,3.55474 -1.92191,5.71184 -3.88297,7.61126 -9.84413,11.39158 -17.65517,11.19618 l -5.15602,-0.12897 1.49059,3.79466 c 1.98856,5.0624 0.50536,10.57833 -4.46072,16.58908 -2.0448,2.47494 -4.81003,5.9155 -6.14495,7.64567 -4.2804,5.54779 -9.5939,8.63447 -17.20511,9.99467 -6.94359,1.24089 -11.73893,0.73938 -26.45717,-2.76696 -1.84014,-0.43838 -2.03538,-0.12961 -1.6365,2.58811 0.2491,1.69723 0.28933,3.0472 0.0894,2.99993 -0.19993,-0.0473 -1.69088,-0.4824 -3.31323,-0.96694 z M 118,166.12244 c 0,-2.2521 -2.49428,-4.55303 -3.9562,-3.64951 -1.45114,0.89686 -1.30888,4.25344 0.2062,4.86479 2.51989,1.0168 3.75,0.61815 3.75,-1.21528 z m 24,0.75363 c 0,-0.61816 2.025,-2.9064 4.5,-5.08499 2.475,-2.17858 4.5,-4.37281 4.5,-4.87607 0,-0.50325 -1.4625,-0.94664 -3.25,-0.9853 -1.7875,-0.0386 -4.15,-0.45702 -5.25,-0.92971 -1.2897,-0.5542 1.8388,-0.88439 8.80902,-0.92971 6.17465,-0.0402 10.56925,-0.45823 10.24981,-0.97511 -0.30757,-0.49765 -2.29426,-0.6721 -4.41487,-0.38766 -3.7084,0.4974 -8.14396,-0.90897 -8.14396,-2.58219 0,-1.0458 4.60476,-3.13658 6.79705,-3.08619 0.93662,0.0215 0.20871,0.68815 -1.61758,1.48138 -4.71154,2.04641 -3.13597,3.85982 2.69866,3.10604 2.54203,-0.3284 5.27262,-0.18513 6.06799,0.3184 C 166.49806,154.19358 175,145.385 175,139.45634 c 0,-1.15921 -0.49468,-1.20279 -2.75,-0.24232 -3.31373,1.41122 -6.19732,4.65274 -6.22776,7.0008 -0.0381,2.93538 -3.22419,3.84982 -5.89065,1.69065 C 157.87958,146.0819 157.86662,146 159.8302,146 c 1.12847,0 2.32988,0.45 2.6698,1 1.18836,1.92281 2.53293,0.97939 1.94466,-1.36446 -0.42679,-1.70049 -0.0811,-2.59894 1.23095,-3.19942 1.22529,-0.56077 -0.96687,-1.02374 -6.67561,-1.40987 -5.94894,-0.40237 -9.93171,-1.27263 -13.27038,-2.89965 -3.86145,-1.8818 -5.67155,-2.19696 -9.5,-1.65409 -9.39554,1.33229 -13.6166,1.046 -18.29534,-1.24088 -5.43693,-2.65746 -4.78932,-2.62035 -11.53037,-0.66067 -5.10988,1.48548 -5.40391,1.74805 -5.40391,4.82568 0,2.17875 0.82648,4.03117 2.5,5.60336 2.71558,2.55115 3.22494,2.13368 1.25174,-1.02592 -1.61214,-2.58144 0.7992,-7.32715 3.95491,-7.78357 2.69744,-0.39014 9.84218,3.19138 10.67002,5.34868 1.5328,3.99443 0.67708,6.54611 -2.57554,7.67998 -2.81911,0.98275 -2.96751,1.20567 -1.25,1.8777 2.66424,1.04247 8.65594,1.05819 10.28272,0.027 1.07393,-0.68077 1.02522,-0.96395 -0.25,-1.4533 -2.71874,-1.04328 -1.88743,-5.3182 1.50377,-7.73294 5.56277,-3.96105 13.91238,-2.58474 13.91238,2.29324 0,2.02525 0.36102,2.03911 6.6571,0.25565 1.01359,-0.28712 -3.01405,1.90541 -8.95032,4.87229 -5.93627,2.96688 -11.04059,5.64169 -11.34293,5.94403 -0.30234,0.30234 0.84211,1.26944 2.54322,2.14912 1.70111,0.87968 3.09461,2.15036 3.09667,2.82374 0.002,0.67338 0.89544,2.68682 1.9853,4.47432 1.38998,2.27974 2.73231,3.25 4.49626,3.25 1.38309,0 2.5147,-0.50577 2.5147,-1.12393 z m -4.82874,-4.97345 c -1.5977,-2.55832 -1.33884,-2.84991 3.49864,-3.94094 5.17689,-1.16758 6.11052,0.20385 2.31371,3.39866 -3.78373,3.18379 -4.14183,3.2172 -5.81235,0.54228 z m 5.36769,-1.94565 c 1.63487,-1.80652 1.65281,-1.98017 0.15498,-1.5 -0.93166,0.29866 -2.39745,0.76485 -3.25731,1.03597 -0.85986,0.27111 -1.2833,0.94611 -0.94099,1.5 0.92975,1.50436 1.99024,1.23264 4.04332,-1.03597 z m 13.9598,3.59663 c 7.10619,-4.16451 7.2875,-5.17954 0.97082,-5.43509 -4.18551,-0.16934 -5.63425,0.14707 -6.08805,1.32964 C 151.054,160.30167 150.43176,161 149.99877,161 c -0.43299,0 -2.29735,1.42097 -4.14301,3.1577 l -3.35576,3.1577 4.91903,-0.66174 c 2.70547,-0.36395 6.79135,-1.75898 9.07972,-3.10006 z M 133,164.96482 C 133,160.90906 126.31558,156 120.79306,156 c -1.81845,0 -4.76579,-0.41859 -6.54966,-0.93019 -4.34602,-1.24643 -4.08531,-0.0811 0.87339,3.9038 6.34396,5.09815 17.88321,8.96401 17.88321,5.99121 z m -20.11011,-5.5975 C 112.26576,158.61529 110.89984,158 109.8545,158 c -1.80098,0 -1.81414,0.13196 -0.25109,2.51749 1.30047,1.98475 1.94279,2.27409 3.03539,1.36732 1.04849,-0.87018 1.10962,-1.48302 0.25109,-2.51749 z M 109,156.54705 C 109,155.37912 106.59701,151 105.95612,151 c -1.33531,0 -1.90295,4.41444 -0.66852,5.19891 1.32882,0.84445 3.7124,1.06798 3.7124,0.34814 z m -3.72915,-6.71445 c 2.11951,-1.30992 0.0697,-1.91069 -4.1934,-1.22899 l -4.189561,0.66993 2.772608,2.89398 2.772603,2.89398 0.83327,-2.25252 c 0.45829,-1.23889 1.36031,-2.57825 2.00448,-2.97638 z m 6.64582,-0.19715 c -0.22917,-0.2005 -1.54167,-0.90032 -2.91667,-1.55516 -2.35727,-1.12265 -2.38918,-1.10183 -0.55887,0.36454 1.593,1.27626 4.84786,2.39128 3.47554,1.19062 z m 24.61545,-2.08442 C 140.51477,145.88697 140.80174,144.80174 138,142 c -2.42755,-2.42755 -3.22201,-2.46302 -7.68908,-0.34325 -3.27427,1.55374 -5.62917,4.90393 -4.63449,6.59325 0.73819,1.2537 7.17406,0.83931 10.85569,-0.69897 z m -35.23397,-0.18251 c 0.94235,-0.94236 -1.24615,-4.51869 -2.348323,-3.83751 -1.441931,0.89116 -1.1349,4.46899 0.383506,4.46899 0.733337,0 1.617497,-0.28417 1.964817,-0.63148 z m 15.53193,-0.24234 c 0.75546,-0.47892 1.18747,-2.09236 1,-3.73469 -0.241,-2.11116 -0.93729,-2.97773 -2.58008,-3.21104 -1.2375,-0.17575 -2.25,-0.76677 -2.25,-1.31336 0,-0.54659 -1.4625,-0.8528 -3.25,-0.68045 -2.84286,0.2741 -3.28867,0.71264 -3.55868,3.50068 -0.25411,2.62377 0.18791,3.45653 2.5,4.70996 3.15935,1.71275 6.16254,1.98171 8.13876,0.7289 z M 99.607914,139.5 c -0.353688,-1.12139 -3.637586,-0.78517 -4.984698,0.51036 -0.482231,0.46376 -0.565324,2.08416 -0.184651,3.60089 l 0.692134,2.75768 2.396308,-2.93447 C 98.844976,141.82051 99.781385,140.05 99.607914,139.5 z M 87.840137,136.05939 C 96.094095,133.91573 97.742742,133 93.348168,133 c -1.641841,0 -5.325878,-0.69512 -8.186749,-1.5447 -5.073284,-1.50661 -5.30193,-1.48487 -9.269924,0.88136 l -4.068341,2.42606 2.310929,1.61864 c 2.938696,2.05835 4.700236,2.01696 13.706054,-0.32197 z m 42.839153,-0.20885 c 4.46301,-1.1238 4.51197,-1.17883 2.19282,-2.46457 -2.62131,-1.45326 -9.26101,-1.69108 -12.37211,-0.44315 -1.79698,0.7208 -1.64471,0.95917 1.5,2.34814 1.925,0.85024 3.63823,1.5826 3.80718,1.62747 0.16895,0.0449 2.3614,-0.43569 4.87211,-1.06789 z M 149,133.57143 C 149,130.96912 151.34331,128 153.39711,128 c 0.68985,0 2.28963,-1.10209 3.55507,-2.4491 2.20932,-2.35171 9.69124,-5.5509 12.98185,-5.5509 0.86776,0 2.19056,-1.38445 2.93956,-3.07655 1.63272,-3.68857 3.78211,-4.73559 5.42445,-2.64239 1.83688,2.34113 7.12365,3.12068 8.65449,1.27613 1.7971,-2.16537 0.55735,-4.55719 -2.36213,-4.55719 -3.61074,0 -3.95242,-1.45185 -1.34447,-5.7128 2.13621,-3.49021 2.30934,-4.82946 2.20775,-17.078292 -0.0853,-10.28608 0.17355,-13.182195 1.14493,-12.809441 2.17842,0.835936 3.69285,-2.189838 3.14402,-6.281634 -0.28498,-2.124667 -0.16028,-4.442053 0.27709,-5.149748 1.14253,-1.848645 -0.0164,-4.183326 -1.74699,-3.519249 -1.46424,0.561883 -6.33704,-0.842055 -13.59613,-3.917279 -2.10288,-0.890856 -4.70161,-1.341007 -5.77496,-1.000338 -1.74911,0.555145 -1.4663,1.156209 2.72625,5.794091 10.99536,12.163314 12.99414,26.564341 5.69263,41.0149 -4.99749,9.89064 -16.15022,18.74026 -27.32052,21.67869 -5.66586,1.49045 -6.53922,2.02981 -4.91362,3.03449 1.03223,0.63795 1.05421,1.34262 0.10676,3.42205 C 143.35291,134.51431 143.70435,136 146.5,136 c 1.98039,0 2.5,-0.50476 2.5,-2.42857 z M 184.36408,71.774037 C 180.62188,70.060801 178.29732,62 181.54545,62 183.95286,62 188,66.637155 188,69.395528 c 0,3.067781 -0.87709,3.641544 -3.63592,2.378509 z m 1.70564,-4.643759 c -0.61356,-1.146443 -2.00524,-2.560587 -3.09264,-3.142543 C 181.30867,63.094828 181,63.247374 181,64.964816 c 0,2.685828 3.85615,6.579035 5.19264,5.242543 0.65685,-0.656854 0.61527,-1.697757 -0.12292,-3.077081 z m -23.18446,66.410202 c 4.79424,-1.6915 11.39736,-6.05509 16.62862,-10.9888 3.91994,-3.69698 3.85101,-6.04575 -0.15496,-5.27996 -1.32366,0.25303 -2.64747,0.0704 -2.9418,-0.40583 -0.97587,-1.57898 -2.27347,-0.89761 -2.59757,1.36399 -0.30927,2.1581 -1.82597,2.97518 -7.81955,4.21254 -1.375,0.28386 -4.04561,1.53795 -5.93469,2.78685 -1.88908,1.2489 -4.58908,2.97972 -6,3.84627 -1.41092,0.86655 -2.70911,2.55405 -2.88486,3.75 -0.28202,1.91906 0.14367,2.17446 3.62427,2.17446 2.16911,0 5.80535,-0.65678 8.08054,-1.45952 z m -92.367791,-2.54797 4.831353,-2.07096 -3.674411,-2.49682 C 69.653485,125.05147 68,123.74336 68,123.51781 c 0,-0.22555 2.548835,0.46684 5.664077,1.53864 5.980205,2.05749 7.370523,2.04708 4.860089,-0.0364 -2.131615,-1.76909 -1.899051,-4.24055 0.657231,-6.98439 l 2.181398,-2.34146 -5.431398,0.67492 c -13.521255,1.68017 -14.031125,1.80578 -12.893659,3.17634 1.82261,2.19611 -2.992847,10.21834 -5.283797,8.80246 -0.462853,-0.28606 -1.384339,-0.0719 -2.047746,0.47583 C 55.042788,129.37153 52.925,130.24732 51,130.76995 l -3.5,0.95024 3.5,1.10895 c 4.76187,1.50876 13.668214,0.67066 19.517469,-1.83663 z M 111.8984,131.25 125.5,128.5 l -6.73957,-0.29545 c -6.78288,-0.29735 -19.959795,2.69098 -21.279191,4.82581 -0.811478,1.31299 -0.994444,1.33559 14.417161,-1.78036 z m 30.59207,0.12421 c 2.2596,-3.4486 0.88981,-4.33855 -6.70909,-4.3589 -6.65745,-0.0178 -6.93854,1.34038 -0.99095,4.78827 4.79436,2.77934 5.62806,2.73286 7.70004,-0.42937 z M 54.5,128 c 0.339919,-0.55 1.458518,-1 2.485775,-1 1.076024,0 2.502134,-1.27167 3.364338,-3 l 1.496598,-3 -3.788497,0 c -2.274301,0 -4.804725,-0.79937 -6.331085,-2 -1.398423,-1.1 -3.429154,-2 -4.512734,-2 -1.083581,0 -3.600103,-0.68104 -5.592271,-1.51342 C 38.033483,113.98715 38,113.99579 38,116.42148 c 0,3.40987 1.748196,7.6675 4.240926,10.32852 1.614842,1.72386 3.22233,2.25 6.874371,2.25 2.621668,0 5.044784,-0.45 5.384703,-1 z m 132.09278,-0.61105 C 190.80001,125.39249 196,119.60906 196,116.92625 c 0,-1.99839 -0.006,-1.99832 -2.17629,0.0234 -1.19695,1.11513 -2.90175,2.25777 -3.78843,2.53919 -2.07395,0.65825 -9.50743,9.5112 -7.98618,9.5112 0.63175,0 2.67641,-0.72497 4.54368,-1.61105 z m -88.682244,-1.02198 c 0.225795,-0.19509 -0.336705,-1.1804 -1.25,-2.18958 -2.875093,-3.17694 -2.1187,-5.95688 1.924571,-7.07328 4.755743,-1.31312 8.414893,0.0658 8.414893,3.17114 0,1.27861 -0.54,2.86475 -1.2,3.52475 -0.93333,0.93333 -0.26667,1.2 3,1.2 4.53857,0 4.71538,-0.16848 3.18254,-3.03263 -0.87633,-1.63743 -0.56423,-2.02383 2.25,-2.78568 3.58654,-0.97093 8.42364,0.75876 9.4259,3.3706 0.60387,1.57367 5.34156,2.03485 5.34156,0.51996 0,-0.52167 2.51679,-0.70537 5.75,-0.41969 4.26955,0.37724 5.3638,0.23036 4.25,-0.57048 -0.825,-0.59319 -2.85,-0.82703 -4.5,-0.51963 -2.27094,0.42308 -2.63547,0.30486 -1.5,-0.48646 2.19346,-1.52864 6.62956,-1.30357 8.35714,0.42401 1.96647,1.96647 2.97798,1.89217 5.02438,-0.36908 0.93032,-1.02799 3.69023,-2.14304 6.13312,-2.47787 C 156.95748,118.04409 161,116.18914 161,114.75945 161,114.34175 160.325,114 159.5,114 c -0.825,0 -1.5,-0.43875 -1.5,-0.975 0,-0.54531 1.29411,-0.71618 2.93644,-0.38771 2.52347,0.50469 3.51489,-0.0262 7.04941,-3.775 4.48216,-4.75385 8.01866,-10.748968 8.00635,-13.572452 -0.004,-0.984411 -1.21069,-2.348415 -2.68089,-3.03112 -2.25349,-1.046433 -2.95865,-0.98286 -4.4922,0.404987 -1.00051,0.905449 -1.82162,2.139026 -1.82469,2.741283 -0.003,0.602256 -0.48206,2.810935 -1.06444,4.908172 -0.88673,3.19327 -1.79898,4.13041 -5.61154,5.76467 -3.69902,1.58558 -5.23387,1.76229 -8.18556,0.94241 -5.09427,-1.41501 -9.03115,-1.26483 -10.70431,0.40833 -1.98387,1.98387 -1.79063,3.20443 0.79394,5.01473 2.79312,1.95638 7.69998,1.99711 11.36752,0.0944 3.30544,-1.71488 4.75658,-0.9955 2.02337,1.00307 -3.21764,2.35279 -9.95512,2.85103 -13.53313,1.00077 -4.03094,-2.08448 -4.80305,-4.08536 -2.54102,-6.58489 2.1203,-2.3429 1.68377,-3.08921 -1.34386,-2.29746 -3.24644,0.84896 -3.94172,4.9175 -1.31769,7.71065 1.16726,1.2425 2.1223,2.53303 2.1223,2.86784 0,0.33482 -2.46477,0.55105 -5.47726,0.48051 -5.4166,-0.12682 -5.64332,-1.67306 -0.24969,-1.70285 2.70708,-0.0149 2.73513,-0.0732 1.17893,-2.44825 -1.18343,-1.80614 -1.33003,-2.9264 -0.56905,-4.34831 0.97757,-1.8266 0.4363,-1.94473 -11.67893,-2.54889 -13.69601,-0.68299 -16.73822,-0.32605 -17.65836,2.07181 -0.86304,2.24902 -0.14916,2.58706 6.47541,3.06623 3.28842,0.23787 5.97895,0.79807 5.97895,1.2449 0,0.44684 1.0125,1.10792 2.25,1.46909 4.04872,1.18161 7.75,2.95156 7.75,3.70604 0,0.71855 -4.56975,-0.97395 -10.33104,-3.82631 C 115.11189,112.63073 111.67949,112 109.04141,112 c -5.08016,0 -7.72524,-1.77558 -6.68467,-4.48727 0.84202,-2.19426 -1.27778,-1.83692 -5.85674,0.98729 -2.2,1.35692 -6.236606,3.53671 -8.970234,4.84398 l -4.970235,2.37686 3.220235,1.66525 c 3.146845,1.6273 3.845555,3.45706 3.388656,8.87411 -0.128058,1.51828 0.434337,1.67096 4.091557,1.11084 2.332011,-0.35716 4.424762,-0.809 4.650557,-1.00409 z m -10.649292,-1.95325 c 0.337337,-1.76466 -0.224606,-3.42217 -1.768886,-5.2175 -1.921566,-2.23395 -2.501205,-2.43377 -3.839095,-1.32342 -2.791814,2.317 -3.016964,5.07717 -0.586123,7.18543 3.149208,2.73129 5.597477,2.47655 6.194104,-0.64451 z M 103.8,123.8 c 1.68483,-1.68483 1.49517,-5.47276 -0.30868,-6.16496 C 101.28905,116.78995 97,118.69447 97,120.51746 c 0,3.62097 4.3579,5.72464 6.8,3.28254 z m 18.2,-0.6 c 0,-1.66089 -2.50105,-3.2 -5.2,-3.2 -3.03429,0 -3.0952,0.0672 -2.19301,2.41821 C 115.2322,124.04748 122,124.76316 122,123.2 z m -55.47192,-9.08479 c 12.160847,-1.81315 13.070589,-2.12435 22.641913,-7.74544 6.9984,-4.11004 14.433467,-5.7861 21.913357,-4.93985 6.32656,0.71577 7.22847,0.34251 3.71539,-1.53763 C 109.39782,97.001802 84.624289,98.376349 72,102.26696 c -4.389726,1.35284 -4.5,1.33293 -4.5,-0.81266 0,-2.088601 0.705752,-2.276372 14,-3.724809 7.7,-0.838931 18.53687,-1.458766 24.08193,-1.37741 9.7199,0.142607 10.16876,0.248549 12.5,2.950271 3.1301,3.627548 8.35767,4.767788 16.5436,3.608518 10.15155,-1.43764 15.99731,-5.168983 19.7575,-12.61121 3.67389,-7.271427 1.06779,-13.349612 -7.63985,-17.818348 -3.13046,-1.606543 -4.13508,-2.439431 -2.49318,-2.066996 3.85393,0.874194 3.67782,-1.883162 -0.25,-3.914316 -3.93905,-2.036964 -3.79046,-3.261083 0.49343,-4.064745 4.41725,-0.828682 7.44494,-0.07297 10.27647,2.565001 2.86697,2.670989 2.85816,6.333445 -0.0199,8.26888 l -2.25,1.513079 2.47442,2.662226 c 2.30083,2.475466 2.5639,2.539849 3.75,0.917762 C 159.42599,77.402749 160,75.353749 160,73.80887 c 0,-3.379692 1.32833,-3.605896 3.4433,-0.586364 C 166.74591,77.937644 164.07695,87 159.38568,87 c -1.09554,0 -1.44988,0.824974 -1.23485,2.874982 0.16587,1.581239 -0.19051,3.493739 -0.79194,4.25 -0.60144,0.75626 -1.61906,2.387518 -2.26139,3.625018 -0.95003,1.830326 -0.90035,2.25 0.26635,2.25 0.78882,0 2.37243,-1.8 3.51913,-4 1.34147,-2.573662 1.66274,-4 0.90097,-4 -0.91159,0 -0.91173,-0.272222 -6.2e-4,-1.183333 2.1364,-2.136398 2.45991,-0.02044 0.70102,4.585144 -1.77327,4.643249 -2.6861,5.232499 -10.98336,7.089929 l -2.99901,0.67136 2.49901,1.38301 c 3.96741,2.19567 8.8981,1.76823 12.65462,-1.097 1.83941,-1.40299 3.34439,-3.41272 3.34439,-4.466074 0,-2.732069 3.06377,-8.79353 4.77699,-9.450955 0.79668,-0.305712 2.97276,0.386208 4.83575,1.537599 3.74535,2.314752 4.30699,1.479603 2.39209,-3.556974 -0.79817,-2.099338 -1.33744,-2.425948 -2.72418,-1.649892 -4.34798,2.433253 -6.86012,-3.312372 -3.9155,-8.955322 1.2338,-2.364409 1.0966,-2.968284 -1.55937,-6.863456 -1.60171,-2.349021 -2.77576,-4.383938 -2.60899,-4.522037 0.16677,-0.138099 1.29895,-0.768909 2.51597,-1.401799 1.43798,-0.747794 1.99807,-1.710187 1.59961,-2.748556 -0.47473,-1.237128 -1.59056,-1.487678 -4.94271,-1.109842 -2.76715,0.311897 -4.96832,0.0033 -6.09961,-0.855096 -1.17544,-0.891915 -4.85756,-1.353783 -10.96103,-1.374903 C 143.25398,58.014312 138.83992,57.55 138.5,57 c -1.11862,-1.809964 -3.5,-1.049293 -3.5,1.117985 0,1.164892 -1.35,3.65555 -3,5.534796 -1.65,1.879246 -3,3.837681 -3,4.352078 0,0.514396 1.35945,1.940349 3.02099,3.168784 l 3.021,2.233518 -2.22863,1.192726 c -1.429,0.764777 -3.04801,0.881197 -4.51231,0.324472 -1.25603,-0.47754 -2.85009,-0.655733 -3.54237,-0.395984 -2.27718,0.854419 -6.92574,-2.9332 -8.2101,-6.689538 -1.01646,-2.972815 -1.00053,-4.382917 0.0847,-7.5 1.74162,-5.002223 1.70328,-5.863083 -0.1911,-4.290888 -2.67447,2.219618 -4.60816,8.181644 -4.93144,15.204822 -0.3215,6.984615 0.80973,9.396973 3.00117,6.400004 1.64545,-2.250295 2.9024,-2.096352 8.71523,1.06739 l 4.99784,2.720166 1.67937,-2.073926 C 134.96296,73.119326 151,74.372063 151,81.014295 c 0,2.359932 -11.42897,6.024821 -18.271,5.8589 l -5.229,-0.126805 6.39611,-0.828588 c 3.51786,-0.455723 7.86087,-1.52366 9.65113,-2.373195 C 145.3375,82.695073 147.52175,82 148.40113,82 c 3.8874,0 -0.2889,-4.627554 -5.03251,-5.576277 -4.15729,-0.831458 -10.604,1.099215 -12.18946,3.650524 -1.28771,2.072163 -1.21554,2.107695 2.87655,1.41634 2.88668,-0.487701 3.99079,-0.374846 3.53577,0.361402 C 136.5059,83.60849 130.83693,84.152842 125.5,83.01305 112.79984,80.300716 106.1884,79.742721 98.38574,80.724654 L 90.5,81.717043 l 8.25,0.141478 c 4.5375,0.07781 8.25,0.519247 8.25,0.980964 0,1.179705 -4.66034,3.169396 -7.297053,3.115411 -1.907911,-0.03906 -1.801163,-0.229077 0.797053,-1.418781 l 3,-1.373677 -5.125,-0.08122 c -2.81875,-0.04467 -6.601221,-0.376463 -8.405491,-0.737317 -2.414484,-0.482897 -3.085331,-0.340322 -2.541211,0.540081 0.536734,0.868455 -0.03711,1.02605 -2.094509,0.575215 C 83.109336,82.971756 82.822538,83.077182 84,83.949493 c 1.169065,0.86609 0.860378,0.96207 -1.399153,0.435041 -1.633884,-0.381099 -2.660324,-0.28525 -2.351916,0.219623 0.30098,0.492714 -1.305892,1.005392 -3.570826,1.139286 -2.264935,0.133894 -7.440779,1.821394 -11.501876,3.75 C 56.844524,93.450152 55.102091,93.91262 59.5,91 l 3,-1.986822 -3.099962,-0.0066 c -2.864321,-0.0061 -10.224606,4.282505 -11.842422,6.900186 -0.353133,0.571381 -2.443583,1.523975 -4.645445,2.116875 -2.786979,0.750455 -4.59608,2.050051 -5.95404,4.277171 C 34.655654,106.07701 34.426359,109 36.432612,109 c 0.787937,0 1.702495,0.85032 2.032351,1.88961 0.329856,1.03928 1.82268,2.12738 3.317387,2.41799 3.544672,0.68919 19.586238,-1.00655 27.71765,-2.93001 1.56745,-0.37077 1.675587,-0.26911 0.5,0.47007 C 68.220427,111.9666 55.641686,114 50.49943,114 c -2.156999,0 -3.367947,0.40373 -2.99943,1 0.859149,1.39013 5.089404,1.19343 19.02808,-0.88479 z M 56.083333,103.69734 C 56.3125,103.53088 57.7375,102.6205 59.25,101.67429 61.910709,100.00975 62,100.01958 62,101.97695 62,103.58178 61.345362,104 58.833333,104 c -1.741666,0 -2.979166,-0.1362 -2.75,-0.30266 z M 64.227992,100.25 c -0.159436,-2.105653 0.02018,-2.398538 0.766579,-1.25 1.178004,1.81268 1.30024,4 0.223537,4 -0.430041,0 -0.875593,-1.2375 -0.990116,-2.75 z M 123,99.812278 c -2.21705,-1.505615 -3.61167,-3.328311 -3.80464,-4.972458 -0.37321,-3.179829 2.36018,-4.12873 11.30464,-3.924423 4.05418,0.0926 8.3512,-0.662893 13.25,-2.3296 l 7.25,-2.466651 0,2.490087 c 0,7.019608 -6.69227,11.831207 -18,12.941627 -5.79018,0.56859 -6.88221,0.37873 -10,-1.738582 z m 19.5,-1.747875 c 4.95744,-2.155709 6.73923,-4.231541 6.32226,-7.365587 L 148.5,88.276688 143,90.110186 c -3.025,1.008424 -8.2,1.852314 -11.5,1.875311 -7.02076,0.04893 -10.5,0.819798 -10.5,2.326416 0,0.593257 1.2375,2.371384 2.75,3.951393 2.61324,2.729884 3.04839,2.839614 8.75,2.206604 3.3,-0.36637 7.8,-1.448852 10,-2.405507 z M 60,95.672162 68.5,91.5 90,91 c 18.33776,-0.42646 21.86366,-0.757392 23.97251,-2.25 1.55853,-1.103105 4.14611,-1.709499 7,-1.640434 l 4.52749,0.109565 -4.37975,0.860438 c -2.40886,0.473241 -5.55886,1.661437 -7,2.640435 C 111.8088,92.290224 108.96618,92.5 90,92.5 l -21.5,0 -7.853792,3.75 c -4.319585,2.0625 -8.144585,3.714973 -8.5,3.672162 C 51.790794,99.879351 55.325,97.966851 60,95.672162 z M 50,96.55136 c 0,-0.275 1.35,-1.198112 3,-2.05136 1.65,-0.853248 3,-1.32636 3,-1.05136 0,0.275 -1.35,1.198112 -3,2.05136 -1.65,0.853248 -3,1.32636 -3,1.05136 z m 20.521261,-7.437343 c 1.137671,-1.176971 3.320446,-1.507806 8.395406,-1.272461 4.791373,0.222194 3.596917,0.788025 -3.416667,1.618523 -4.205818,0.498022 -5.694612,0.394539 -4.978739,-0.346062 z M 85.083333,87.638898 C 85.3125,87.440292 88.2,87.013135 91.5,86.68966 c 3.811226,-0.373586 5.270409,-0.267498 4,0.290817 -1.892037,0.831505 -11.302751,1.426342 -10.416667,0.658421 z M 137.75,69.337719 c 0.6875,-0.277412 1.8125,-0.277412 2.5,0 0.6875,0.277413 0.125,0.504386 -1.25,0.504386 -1.375,0 -1.9375,-0.226973 -1.25,-0.504386 z m 55.27021,33.453661 c 4.06456,-10.539765 4.91342,-20.067996 2.52099,-28.297651 -0.94445,-3.248786 -2.39321,-6.826424 -3.21948,-7.950307 -1.41127,-1.919605 -1.47546,-1.80105 -1.05929,1.956578 0.52228,4.715729 -0.64425,8.5 -2.62019,8.5 -1.97537,0 -3.22125,13.715545 -1.67223,18.40912 1.00043,3.031341 0.82805,4.055885 -1.43325,8.51833 -2.44629,4.82752 -2.47588,5.07255 -0.61262,5.07255 1.0768,0 2.23594,0.45 2.57586,1 1.33872,2.16609 2.47935,0.67657 5.52021,-7.20862 z m -175.464706,1.11881 c 0.401259,-0.64925 2.010597,-0.83897 3.981036,-0.46931 4.511754,0.84641 5.264287,-0.98135 1.246156,-3.02667 C 20.977213,99.495171 17.19671,96.791796 14.381579,94.406705 11.566447,92.021614 8.9789469,90.354386 8.6315786,90.701755 8.2842104,91.049123 8,93.243331 8,95.577773 c 0,3.511936 0.5309804,4.691227 3.076725,6.833337 3.290815,2.76903 5.393251,3.2555 6.478779,1.49908 z m 18.895821,-3.83143 C 36.764472,99.572075 39.15353,98.373925 41.760342,97.416203 44.367154,96.458481 47.85,94.452037 49.5,92.957439 53.305722,89.510151 56.249549,88.001491 59.184259,87.994423 60.457916,87.991356 63.3,87.449842 65.5,86.791059 l 4,-1.197788 -4,-0.65473 -4,-0.65473 4.833333,-0.141906 c 3.367617,-0.09887 4.707408,-0.519683 4.418081,-1.387664 C 70.523025,82.069074 69.698025,81.497357 68.91808,81.48376 66.551968,81.44251 63,79.922773 63,78.951664 63,78.449206 64.149112,77.749695 65.553582,77.397196 69.581225,76.386322 68.503826,72.643404 64,72 61.226755,71.603822 60.493763,71.043867 60.469964,69.303297 60.453444,68.09511 60.115944,66.78261 59.719964,66.38663 58.221677,64.888343 59.103844,62.99766 62,61.5 66.319656,59.266219 66.125162,55.504195 61.577913,53.335763 59.695766,52.43823 57.937894,50.87051 57.671533,49.851942 57.363938,48.675698 56.279969,48 54.700608,48 53.332961,48 51.954956,47.325 51.638374,46.5 51.321791,45.675 50.148646,45 49.031385,45 c -2.457797,0 -2.554834,0.764114 -0.399485,3.145748 1.524518,1.684573 1.442235,1.969659 -1.250443,4.332443 -1.585289,1.391067 -4.415534,3.315047 -6.289434,4.275511 -4.421893,2.266433 -4.116774,3.670503 0.88083,4.053332 3.326377,0.254808 3.904087,0.03585 3.396367,-1.287246 -0.338183,-0.881291 0.182594,-2.472054 1.164486,-3.557033 C 48.64838,53.626067 53,53.314647 53,55.5 c 0,0.825 0.675,1.5 1.5,1.5 0.825,0 1.5,0.8625 1.5,1.916667 0,1.054166 0.5625,2.112703 1.25,2.352304 0.6875,0.2396 -0.6625,0.766654 -3,1.171231 C 50.261437,63.130546 48.23624,65 51.476947,65 c 0.812321,0 2.215551,1.127253 3.11829,2.505006 1.386607,2.11623 1.43241,2.756755 0.295124,4.1271 -1.094558,1.318863 -2.66431,1.522407 -8.397164,1.088833 -6.725632,-0.508659 -14.866226,0.318757 -16.193374,1.645905 -0.341492,0.341492 0.196091,1.523653 1.194629,2.627025 C 32.49299,78.097241 32.859975,79 32.309975,79 c -0.55,0 -1.766086,-0.846516 -2.702413,-1.881146 -1.542065,-1.703962 -1.555538,-2.028021 -0.143041,-3.440518 2.051041,-2.051041 9.240208,-3.070616 15.838432,-2.246222 2.909904,0.363568 6.057155,0.36693 6.993891,0.0075 2.217253,-0.85084 2.189055,-3.330866 -0.04684,-4.119982 -0.9625,-0.339695 -2.774289,-1.540088 -4.026197,-2.66754 -1.986974,-1.789442 -3.638807,-2.056402 -13,-2.100988 -11.969856,-0.05701 -17.158975,1.640496 -22.702406,7.426591 l -2.8576554,2.98275 1.8955334,3.519792 C 12.601818,78.416094 14.186766,80 15.081381,80 17.453414,80 22,84.568688 22,86.952251 c 0,2.303624 1.001946,2.481172 5.966652,1.057313 2.981569,-0.855103 3.939536,-0.653577 7.010876,1.474863 2.834376,1.964224 4.317193,2.342005 7.295495,1.858693 3.124379,-0.507017 3.877715,-1.118538 4.588676,-3.724862 1.283459,-4.705062 -1.07551,-6.963242 -6.434527,-6.159608 -3.188664,0.47817 -4.436064,0.233298 -5.523056,-1.084208 -1.287337,-1.560337 -1.211669,-1.599324 0.909806,-0.468768 1.725972,0.919789 2.659425,0.946373 3.673671,0.104623 1.00854,-0.837014 2.438695,-0.837962 5.53702,-0.0037 4.238229,1.141236 6.860215,0.726369 3.050748,-0.48271 C 45.39967,78.674687 45.388826,77 48.059017,77 c 1.132459,0 1.780902,0.45 1.440983,1 -0.371237,0.600673 0.903008,0.993885 3.190983,0.984687 C 55.518501,78.97332 56.113483,78.719588 55,78 c -1.333333,-0.861666 -1.333333,-0.969374 0,-0.969374 2.022683,0 4.425403,1.593893 3.356763,2.226777 C 57.885543,79.536475 55.925,80.106416 54,80.523939 c -3.004152,0.651586 -3.216658,0.870795 -1.5,1.547312 1.995571,0.786433 1.99555,0.788334 -0.0095,0.858464 -2.511451,0.08784 -4.784176,3.569783 -3.981268,6.099521 0.473447,1.4917 -0.0036,2.034647 -2.202464,2.50666 -1.543748,0.331385 -3.84603,1.0239 -5.116181,1.538922 -1.834705,0.743937 -2.984563,0.421405 -5.594391,-1.569208 C 32.128609,88.860717 27.183144,88.216856 25.242382,90.157618 23.754804,91.645196 21,89.562406 21,86.950135 21,85.121081 16.615727,81 14.66986,81 14.086628,81 12.392314,79.833922 10.904719,78.408715 L 8.2,75.81743 l 0,3.657952 c 0,2.011873 -0.27,3.927951 -0.6,4.257951 C 6.3443065,84.989027 7.0792843,75.371637 8.4380714,72.766935 9.7586083,70.235557 8.916103,67.708697 7.5100813,69.983688 6.678587,71.329074 3,71.294242 3,69.940983 3,69.358524 2.55,69.160081 2,69.5 c -1.83493421,1.134052 -1.07856514,9.036864 1.2943835,13.524177 2.494937,4.717998 4.6594306,6.21503 4.7845639,3.309156 0.049651,-1.153015 0.2736777,-1.346795 0.6037103,-0.522202 0.4114625,1.028047 0.916382,0.956721 2.3385873,-0.330358 2.993159,-2.708771 6.290487,-1.541668 7.117381,2.519227 0.525335,2.579935 0.332384,3.713313 -0.734004,4.31146 -1.964117,1.101693 -1.000792,2.343749 3.663227,4.723154 L 25,99.040648 25,96.180839 c 0,-3.954525 4.152735,-5.966008 7.622832,-3.692313 C 35.350676,94.275878 35.658301,96.208769 33.5,98 c -0.825,0.684689 -1.5,1.639789 -1.5,2.12244 0,1.1668 3.725805,1.13023 4.451325,-0.0437 z M 57.269032,83.307009 c 0.972967,-0.253543 2.322967,-0.236869 3,0.03705 C 60.946064,83.617986 60.15,83.825431 58.5,83.805051 56.85,83.784672 56.296064,83.560553 57.269032,83.307009 z M 32.062437,96.883335 c 0.897825,-1.6776 0.811817,-2.437652 -0.414628,-3.664097 -1.273952,-1.273952 -1.8214,-1.32006 -3.097621,-0.260891 C 27.697585,93.665945 27,95.314789 27,96.622445 c 0,3.070071 3.463485,3.24856 5.062437,0.26089 z M 17,88.968615 C 17,85.35985 14.561838,84.00959 12.239301,86.332128 10.765145,87.806283 10.784184,88.104045 12.47183,89.968872 15.159856,92.939108 17,92.532627 17,88.968615 z M 178.50543,80.75 c -0.81236,-6.251245 -4.85977,-15.756276 -6.70011,-15.734687 -3.63941,0.04269 -4.10364,1.727017 -1.43891,5.220657 2.74768,3.602397 3.3347,6.212683 1.63359,7.26403 -0.55,0.339919 -1,2.202231 -1,4.138472 0,3.365717 0.12766,3.492399 2.9048,2.882437 1.66631,-0.365983 3.18373,-0.186679 3.55902,0.420545 1.36847,2.214244 1.70044,0.878394 1.04161,-4.191454 z m -15.54815,1.829815 c 0.81364,-1.520291 1.04554,-3.751264 0.62367,-6 C 162.83477,72.602334 161,71.698833 161,75.30887 c 0,1.269879 -0.61274,3.146847 -1.36165,4.171041 C 158.10236,81.580495 158.6037,85 160.44765,85 c 0.66792,0 1.79725,-1.089083 2.50963,-2.420185 z M 78.75,83.369714 c 3.17118,-0.849843 2.793844,-2.010945 -0.89316,-2.748346 -3.189543,-0.637909 -6.31166,0.833701 -5.286813,2.491939 0.632517,1.023433 2.957824,1.11991 6.179973,0.256407 z m 8.499631,-6.236048 C 87.88293,74.677121 87.694476,72.875928 86.552327,70.469028 85.691496,68.654962 84.703423,64.45589 84.35661,61.137759 83.735131,55.191771 83.686222,55.112756 80.964222,55.657156 77.673536,56.315293 72.868205,53.175485 70.998236,49.145369 L 69.770787,46.5 68.803993,49 c -1.537566,3.975936 -1.171486,18.224044 0.627204,24.411323 1.436222,4.940428 1.896409,5.554197 3.85,5.134887 C 74.501539,78.284281 77.075,78.68368 79,79.433762 c 5.363727,2.089993 7.25371,1.563043 8.249631,-2.300096 z M 69,79 c 0,-0.55 -0.926558,-1 -2.059017,-1 -1.132459,0 -1.780902,0.45 -1.440983,1 0.339919,0.55 1.266476,1 2.059017,1 C 68.351558,80 69,79.55 69,79 z m 23.212553,0.454114 C 92.51279,79.153876 91.68779,75.536733 90.379219,71.416018 84.975551,54.399759 89.814597,35.08577 102.48363,23.103927 105.51763,20.234492 108,17.698805 108,17.469066 c 0,-0.830576 -5.94378,-3.46781 -7.70034,-3.416614 -1.554618,0.04531 -1.493299,0.266158 0.45034,1.621972 C 101.9875,16.53766 103,17.81744 103,18.51838 103,19.920279 96.491625,26 94.990884,26 93.6425,26 91,31.476801 91,34.271439 c 0,1.44735 -1.752747,4.200027 -4.5,7.06722 -2.475,2.583053 -4.5,5.363558 -4.5,6.1789 C 82,48.432163 81.042395,49 79.5,49 77.384343,49 77,48.534983 77,45.975249 77,43.668981 76.406164,42.724722 74.5,42 72.891801,41.388564 71.971028,40.238052 71.918781,38.774751 71.845534,36.723273 71.702732,36.794458 70.463885,39.5 c -2.023071,4.418223 -1.878353,4.889991 3.058118,9.969247 3.782552,3.891959 5.039915,4.60194 7.689204,4.341776 3.546577,-0.348278 4.502401,1.380035 4.689113,8.478815 0.05482,2.084411 0.944154,5.459411 1.97629,7.5 1.183236,2.339325 1.695523,4.910977 1.3865,6.960162 -0.361168,2.394973 -0.109469,3.25 0.956724,3.25 0.795758,0 1.692481,-0.245649 1.992719,-0.545886 z m 28.513737,-1.038513 c -1.52554,-0.827379 -3.29568,-1.181735 -3.93363,-0.78746 -1.34539,0.831498 1.53122,2.213501 4.70734,2.261536 1.64195,0.02483 1.50343,-0.239067 -0.77371,-1.474076 z M 105.21397,73.25 c 0.25763,-2.6125 1.43988,-6.747023 2.62723,-9.187829 2.28423,-4.695676 2.7244,-7.594576 1.28796,-8.482345 -0.47896,-0.296014 -1.13758,-1.871937 -1.46361,-3.502052 -0.55229,-2.761465 -0.83424,-2.924659 -4.12916,-2.389967 C 101.23436,50.061375 100,49.866969 100,49.130842 100,47.714574 94.523208,47.64962 91.934259,49.035184 89.127137,50.53751 89.215356,63.2882 92.091804,71.805828 L 94.183609,78 l 5.280966,0 5.280965,0 0.46843,-4.75 z m 5.06426,1.422925 c 0.29695,-1.829891 0.21879,-4.867391 -0.17369,-6.75 L 109.39095,64.5 108.15764,69.343096 C 106.95784,74.054578 107.31283,78 108.93655,78 c 0.44097,0 1.04472,-1.497184 1.34168,-3.327075 z M 132,73.240547 c 0,-0.417699 -0.9,-1.321513 -2,-2.008474 -2.77134,-1.730728 -2.54721,-5.643506 0.43519,-7.597653 1.58693,-1.039795 2.54486,-2.731603 2.75,-4.856821 0.32986,-3.417169 2.35671,-4.590515 5.62322,-3.255288 0.93038,0.380301 4.39159,0.80615 7.69159,0.94633 3.3,0.14018 9.15,0.5721 13,0.959823 6.59226,0.663888 6.8835,0.609046 5,-0.941524 -5.25942,-4.329751 -12.03835,-6.816686 -19.85879,-7.285447 -17.61759,-1.056007 -28.97044,5.971367 -27.14093,16.800136 0.98407,5.824673 2.77584,6.926225 12.74972,7.838334 0.9625,0.08802 1.75,-0.181717 1.75,-0.599416 z m 23.12817,-3.480031 c 1.49735,-2.797822 -1.63987,-5.751207 -6.85178,-6.450269 -4.93128,-0.661424 -6.33429,1.008917 -2.26368,2.695017 2.08936,0.865443 2.98729,1.927317 2.98729,3.532723 0,3.868345 4.09736,4.01713 6.12817,0.222529 z M 66,66.5 C 66,61.996492 65.539487,61.472013 62.581787,62.606989 60.782318,63.29751 60.416457,66 62.122445,66 c 0.751384,0 0.689996,0.521069 -0.185698,1.576215 -1.084129,1.306295 -1.062285,1.731788 0.127555,2.484688 C 65.040116,71.943919 66,71.075445 66,66.5 z M 10.77705,66.217145 C 11.731524,64.966444 12.331059,57 11.47071,57 11.043158,57 4,67.777358 4,68.431593 4,69.762571 9.4238771,67.990282 10.77705,66.217145 z M 16,65 c 1.375,-1.075541 2.975875,-1.965534 3.5575,-1.977764 0.581624,-0.01223 2.489987,-2.054523 4.240806,-4.53843 5.192366,-7.366467 17.648047,-13.962358 28.69083,-15.193194 2.755975,-0.307183 5.76093,-1.209103 6.677677,-2.004267 1.268142,-1.099956 2.149348,-1.187508 3.684258,-0.366049 1.109596,0.593837 2.60953,1.067599 3.333188,1.052803 1.726397,-0.0353 -4.833719,-5.696413 -8.684259,-7.494166 -2.47849,-1.157165 -2.633866,-1.407454 -0.893802,-1.439791 1.158408,-0.02153 4.226748,1.580019 6.818532,3.558993 2.591783,1.978974 4.818064,3.441474 4.947291,3.25 0.129226,-0.191474 0.704107,-1.467972 1.277513,-2.836663 0.963864,-2.300695 0.670868,-2.727993 -3.881818,-5.661124 C 59.844451,27.534201 55.166269,25.500398 54.301269,26.365398 53.952238,26.714429 53.666667,28.35 53.666667,30 c 0,1.926103 -0.508752,3 -1.421231,3 -1.104069,0 -1.270421,-0.892641 -0.745436,-4 0.535601,-3.170196 0.36858,-4 -0.805113,-4 -2.016428,0 -2.70035,2.191486 -2.010532,6.442335 0.526604,3.245078 0.368142,3.55632 -1.803513,3.542352 -1.369777,-0.0088 -1.904159,-0.32731 -1.258355,-0.75 0.617368,-0.404078 1.118504,-2.647187 1.113636,-4.984687 -0.0085,-4.089329 -0.126561,-4.249789 -3.122487,-4.244423 -1.7125,0.0031 -4.913636,0.54199 -7.113636,1.197606 -3.507579,1.045284 -3.692237,1.238173 -1.5,1.566864 3.073954,0.460889 9.823384,7.233397 7.199017,7.22363 -0.934459,-0.0035 -2.465587,-1.353477 -3.402507,-3 C 37.762086,30.175802 36.276903,29 35.015126,29 c -2.268307,0 -2.847653,0.952668 -3.344718,5.5 -0.710446,6.499428 -3.113927,9.058021 -12.821537,13.648995 L 13,50.915074 l 0,6.460675 c 0,3.553372 -0.273145,7.17248 -0.606989,8.042464 C 11.57929,67.538735 12.958911,67.378775 16,65 z m 0.376957,-3.331787 C 16.719631,60.660729 17,58.76644 17,57.458682 c 0,-2.514094 3.073426,-5.889412 8.027187,-8.81567 l 2.987188,-1.764576 -2.980386,4.416094 c -1.639212,2.428851 -3.779946,5.030086 -4.757187,5.780521 -0.977241,0.750435 -0.687528,0.142319 0.643808,-1.351369 2.639984,-2.961922 2.463648,-4.456361 -0.288383,-2.444027 C 19.685252,53.9721 18.846895,55.65495 18.76921,57.019323 18.691525,58.383695 17.981303,60.4 17.190939,61.5 15.953691,63.221957 15.84053,63.245342 16.376957,61.668213 z M 30,45.10638 C 30,43.739912 32.421041,42 34.322445,42 c 1.529123,0 1.686096,0.284782 0.767241,1.391935 C 33.809391,44.934596 30,46.217778 30,45.10638 z M 46,38.269697 C 50.791565,36.207841 55.5,36.074173 55.5,38 c 0,1.165345 -1.450173,1.530764 -6.5,1.63789 L 42.5,39.775779 46,38.269697 z M 54,38 c 0,-0.55 -0.423442,-1 -0.940983,-1 -0.517541,0 -1.219098,0.45 -1.559017,1 -0.339919,0.55 0.08352,1 0.940983,1 C 53.298442,39 54,38.55 54,38 z M 10.218511,54.267243 C 11.623838,51.64526 13.105474,48.375 13.511036,47 l 0.737386,-2.5 -2.719225,2.5 c -3.2199508,2.960357 -5.0120948,6.219014 -6.0388144,10.980381 -0.6438857,2.985992 -0.5428527,3.308055 0.711248,2.267244 0.8039578,-0.667226 2.611554,-3.358398 4.0168804,-5.980382 z m 27.108214,3.092568 c 1.554699,-1.297896 3.354699,-2.374032 4,-2.391412 0.645301,-0.01738 2.453377,-1.157441 4.017945,-2.533466 2.32239,-2.042523 2.621209,-2.771121 1.627556,-3.968399 C 45.29102,46.440805 43.686154,46.614317 37.688075,49.470298 33.437798,51.494063 24,58.996412 24,60.3513 c 0,0.195313 2.3625,0.133086 5.25,-0.138282 3.520495,-0.330857 6.181207,-1.270788 8.076725,-2.853207 z M 54.756322,59.25 C 54.982011,58.5625 54.616276,58 53.943576,58 53.270876,58 52.209004,57.300508 51.583861,56.445574 50.167733,54.508903 47,55.541867 47,57.940322 c 0,0.94949 0.321327,2.047672 0.71406,2.440405 1.128604,1.128604 6.588355,0.25197 7.042262,-1.130727 z M 186.75883,57.75 C 186.04476,55.561382 174.69605,46.862089 169.1954,44.286849 163.26078,41.508435 148.82247,39.860198 147.60959,41.822674 146.84157,43.065358 150.76465,48 152.52061,48 c 0.63797,0 3.81932,1.298336 7.06967,2.88519 3.25034,1.586855 8.11432,3.162443 10.80883,3.501308 2.69451,0.338865 5.5306,1.1402 6.30241,1.780746 1.15414,0.957852 5.24662,2.112605 9.63181,2.717757 0.45834,0.06325 0.64981,-0.447501 0.4255,-1.135001 z m -71.74377,-7.106989 c 0.0305,-12.457703 6.0174,-22.184766 16.67035,-27.084874 4.56214,-2.098479 4.70082,-2.275636 2.64482,-3.378615 -1.74026,-0.933596 -3.47234,-0.761692 -8.75,0.868412 C 119.31241,22.983866 119,23.228583 119,26.202323 119,29.769647 114.55764,38 112.63216,38 c -0.70594,0 -2.34041,1.125 -3.63216,2.5 -2.72656,2.902291 -4.63462,3.140643 -7.12192,0.889663 -1.5679,-1.41893 -2.278576,-1.448646 -5.979014,-0.25 -2.681536,0.868603 -4.491805,2.1647 -5.007938,3.585532 -0.777731,2.140968 -0.637701,2.201808 3.699444,1.607336 2.870562,-0.393454 5.374041,-0.154245 6.892888,0.658619 1.31182,0.702063 3.24426,1.05181 4.29431,0.777214 1.81537,-0.474728 4.22223,1.892652 4.22223,4.152967 0,2.769529 2.05207,5.995918 3.46799,5.45258 1.14347,-0.438793 1.53583,-2.145829 1.54707,-6.7309 z M 66.881685,46.417727 67,43.335455 61.25,43.739551 c -3.1625,0.222254 -6.341022,0.593598 -7.063382,0.82521 -2.046481,0.656169 -0.547887,2.112985 2.87851,2.798265 1.878351,0.37567 2.938524,1.118683 2.681294,1.879161 -0.233999,0.691797 0.964829,2.221626 2.664063,3.399621 L 65.5,54.783616 66.131685,52.141808 c 0.347427,-1.452995 0.684927,-4.028831 0.75,-5.724081 z m 55.144765,1.036048 c 2.36459,-4.132875 4.16208,-5.974626 7.05364,-7.227344 6.13268,-2.656874 6.25592,-5.742041 0.34202,-8.562182 -4.32971,-2.064695 -3.92414,-2.101203 -6.50721,0.585751 -3.04217,3.164522 -5.59849,9.345806 -6.41016,15.5 -0.94831,7.190257 1.30762,7.069232 5.52171,-0.296225 z M 81,46.459875 c 0,-0.847069 1.883766,-3.279534 4.186147,-5.405478 2.880326,-2.6596 4.24999,-4.787521 4.390813,-6.821599 0.301983,-4.361912 1.785104,-6.531175 7.385223,-10.801881 C 99.732983,21.317878 102,19.416128 102,19.204807 102,18.993485 100.9875,17.975925 99.75,16.943562 95.200569,13.148278 86.030555,15.609678 80.577993,22.08968 74.177831,29.695841 71.96411,38.840057 76,41 c 1.109322,0.593691 2,2.093823 2,3.368517 0,1.263982 0.3,2.59815 0.666667,2.964816 C 79.827887,48.494554 81,48.055786 81,46.459875 z M 21.604379,45.391941 C 27.143616,43.0775 29.997298,39.357779 29.998779,34.45 29.99945,32.2225 30.5625,29.782855 31.25,29.028567 c 0.6875,-0.754288 -0.129126,-0.506788 -1.814725,0.55 -7.128348,4.469127 -8.91346,6.520427 -11.897355,13.671433 -1.759346,4.216332 -1.378443,4.416967 4.066459,2.141941 z M 146.29668,44.531425 C 145.30851,43.173709 144.05,42.050391 143.5,42.035163 142.30942,42.0022 136,45.745906 136,46.485302 136,46.768386 138.72101,47 142.04668,47 l 6.04669,0 -1.79669,-2.468575 z M 143.12326,39.5 c -0.0319,-1.812156 -3.46486,-1.753319 -4.80716,0.08239 -2.08864,2.856388 -1.55244,3.519784 1.75434,2.170479 C 141.75917,41.063791 143.13294,40.05 143.12326,39.5 z M 108,39.5 C 109.29175,38.125 110.90848,37 111.59275,37 113.60174,37 117,30.561014 117,26.754411 c 0,-4.218252 1.41998,-5.544689 7.71723,-7.20883 L 129.5,18.281664 124.62803,17.508998 c -3.08637,-0.489481 -6.92481,-0.313261 -10.4731,0.480811 -4.75925,1.065075 -6.43185,2.10757 -11.12803,6.935888 C 98.566975,29.511111 93,37.644667 93,39.57537 c 0,0.212503 1.929949,0.12184 4.288776,-0.201473 3.244464,-0.444704 4.613524,-0.196548 5.622444,1.01913 1.77693,2.141066 2.3295,2.044096 5.08878,-0.893027 z m 49.55008,-5.581027 c 0.38652,-0.625414 1.78115,-0.803219 3.30901,-0.421876 2.41769,0.603437 2.30281,0.3557 -1.35909,-2.93094 -5.4887,-4.926235 -8.77836,-6.574919 -14.46227,-7.248094 C 139.82042,22.70015 133,23.587842 133,24.884798 c 0,0.436795 1.125,1.306756 2.5,1.933248 1.375,0.626492 2.5,1.795432 2.5,2.597645 0,1.096901 0.83321,1.323356 3.36027,0.913271 2.55408,-0.41447 3.81365,-0.06041 5.25,1.475761 1.64035,1.754348 3.33458,2.32255 9.08071,3.045445 0.65504,0.08241 1.49164,-0.33663 1.8591,-0.931195 z M 72.76605,31.201851 C 72.981127,30.556619 71.996752,29.500012 70.57855,28.853836 67.552988,27.475297 67.143482,25 69.940983,25 c 2.943441,0 3.246142,-1.47563 0.778197,-3.79362 L 68.5,19.122041 l -3.256617,3.879605 -3.256618,3.879606 4.256618,3.011957 c 4.353681,3.080639 5.833065,3.377448 6.522667,1.308642 z m 1.780154,-4.347426 c 0.374538,-1.180067 2.487175,-4.105067 4.694747,-6.5 L 83.25472,16 78.87736,16.118315 c -2.407548,0.06507 -5.654082,0.402573 -7.214519,0.75 L 68.825682,17.5 l 2.587159,2.424314 c 3.302135,3.094287 3.28022,4.863635 -0.07066,5.704651 -2.505626,0.628873 -2.551943,0.744486 -0.80887,2.019052 2.524126,1.845686 3.21882,1.708303 4.012891,-0.793592 z M 64.490006,22.010431 c 1.575304,-1.644263 2.561982,-3.291776 2.192618,-3.66114 C 65.741125,17.407792 53.02324,19.82971 50,21.52623 l -2.5,1.402899 3,0.105721 c 1.65,0.05815 3.9,0.492464 5,0.96515 3.655103,1.570652 6.096807,1.030281 8.990006,-1.989569 z M 199.15789,109 c 0,-1.375 0.22698,-1.9375 0.50439,-1.25 0.27741,0.6875 0.27741,1.8125 0,2.5 -0.27741,0.6875 -0.50439,0.125 -0.50439,-1.25 z" + id="path2991" + inkscape:connector-curvature="0" /> + <path + style="fill:#0c0f05" + d="m 126.57143,185.42857 c -2.28586,-2.28586 -1.928,-3.06124 0.42857,-0.92857 1.1,0.99549 2,1.96523 2,2.15499 0,0.74314 -0.92728,0.27487 -2.42857,-1.22642 z m -10.02116,-15.48146 c -1.62236,-0.48454 -3.15088,-0.67984 -3.39671,-0.434 -0.24584,0.24583 -1.43567,-1.68703 -2.64408,-4.29525 -1.24251,-2.68182 -3.89427,-6.03306 -6.10329,-7.71322 -5.577807,-4.24242 -11.228357,-11.01581 -10.116901,-12.12726 0.259938,-0.25994 1.169044,0.22381 2.020235,1.075 0.85119,0.85119 2.367262,1.59248 3.369047,1.6473 1.362759,0.0746 1.238629,0.26376 -0.49292,0.75126 l -2.314349,0.65158 3.064349,2.93583 c 2.026589,1.9416 3.085819,2.44915 3.127739,1.49874 0.0349,-0.7904 0.47036,-0.42459 0.96777,0.81291 0.59366,1.47695 1.74808,2.25 3.35997,2.25 2.40612,0 2.42477,-0.0618 0.92595,-3.06621 -0.947,-1.89832 -2.06048,-2.8625 -2.92335,-2.53138 C 104.62718,151.69656 104,151.50135 104,150.96862 104,150.43588 104.45,150 105,150 c 0.55,0 1,-0.45 1,-1 0,-0.55 -0.9,-1 -2,-1 -1.1,0 -1.9044,-0.3375 -1.78755,-0.75 0.45735,-1.61455 -2.352043,-5.28247 -3.512623,-4.58605 -0.683967,0.41042 -0.594628,-0.0257 0.207791,-1.01437 0.983319,-1.21156 1.091038,-2.05092 0.35736,-2.7846 -1.578229,-1.57823 -5.244069,0.75731 -5.36833,3.4202 -0.06781,1.45319 -0.445851,0.92528 -1.09934,-1.53518 -1.12222,-4.22528 -1.077905,-4.21465 -9.297308,-2.23 -6.560737,1.58415 -9.199546,1.84621 -8.164108,0.81077 0.368075,-0.36807 2.130575,-0.82099 3.916667,-1.00648 1.786093,-0.1855 6.135811,-1.12185 9.666042,-2.08078 C 96.533949,134.17492 98.163322,132 92.097685,132 c -2.237941,0 -5.987941,-0.50791 -8.333334,-1.12869 -3.799034,-1.00553 -4.673543,-0.88563 -8.014351,1.09878 -4.286674,2.54624 -4.383937,2.77846 -2,4.77516 1.160858,0.97229 0.81818,0.91353 -1.017897,-0.17454 -2.33318,-1.38265 -3.38817,-1.45443 -6.717253,-0.45701 -2.172146,0.65079 -3.712535,1.56644 -3.423086,2.03478 0.984572,1.59307 -2.080429,0.85116 -5.591764,-1.35353 l -3.5,-2.19758 6.199061,-0.81239 c 3.409483,-0.44681 8.325468,-1.72387 10.924411,-2.83791 l 4.72535,-2.02552 -3.674411,-2.49682 C 69.653485,125.05147 68,123.74336 68,123.51781 c 0,-0.22555 2.545448,0.46567 5.65655,1.53605 3.111103,1.07038 5.836544,1.94614 6.056537,1.94614 0.219992,0 -0.390306,-1.33786 -1.356217,-2.97301 -1.722237,-2.91552 -1.708825,-3.02379 0.693464,-5.59807 L 81.5,115.80387 l -7,0.65892 c -10.766697,1.0135 -12.760102,1.51888 -11.583408,2.93671 1.078271,1.29924 -1.591851,8.6005 -3.145261,8.6005 -0.446588,0 0.04892,-1.6875 1.101129,-3.75 l 1.913107,-3.75 -4.787796,0 c -3.057905,0 -5.458026,-0.60172 -6.642783,-1.66539 -1.020244,-0.91596 -3.547458,-1.97947 -5.616033,-2.36336 -2.068575,-0.38389 -4.007633,-1.09696 -4.309017,-1.58461 C 40.149796,112.81532 38,114.09912 38,116.9349 c 0,4.00852 1.289106,7.04019 4.42405,10.4043 2.253349,2.41807 3.232096,2.77147 6.598629,2.3826 2.174063,-0.25113 4.618219,-1.00881 5.431459,-1.68374 0.81324,-0.67493 2.056248,-0.99512 2.76224,-0.71155 0.806898,0.32411 0.63369,0.54492 -0.466378,0.59454 -0.9625,0.0434 -1.75,0.50856 -1.75,1.03364 0,0.52507 -1.571062,1.24942 -3.49125,1.60965 -1.920187,0.36023 -3.269566,1.01365 -2.99862,1.45205 1.425232,2.30607 -3.802331,-0.73113 -7.140529,-4.14863 -3.659045,-3.74597 -3.878692,-4.32626 -4.036672,-10.66464 -0.142429,-5.71447 -0.443936,-6.74627 -2.044227,-6.99571 -1.513664,-0.23593 -1.798998,-0.96208 -1.473524,-3.75 C 34.197611,103.1816 34.058588,103 31.168423,103 c -1.677714,0 -3.328504,0.45 -3.668423,1 -0.339919,0.55 -1.096576,1 -1.681462,1 -0.685234,0 -0.634008,-0.51742 0.144041,-1.45491 1.002284,-1.20768 0.466031,-1.80343 -3.15573,-3.50586 -2.39976,-1.128018 -6.499296,-4.012093 -9.11008,-6.409053 -2.761327,-2.535173 -5.0152584,-3.923867 -5.3884921,-3.319963 -0.3528856,0.570981 -0.6416102,3.055985 -0.6416102,5.522231 0,3.685689 0.5054825,4.918885 2.8389823,6.926075 2.322556,1.99778 3.580736,2.34729 6.916667,1.92141 L 21.5,104.15935 l -4,1.34347 c -2.2,0.73891 -3.775,1.38484 -3.5,1.43538 2.635678,0.48448 8.040698,2.98032 6.5,3.00146 -2.874289,0.0394 -9.463171,-3.96935 -11.8797229,-7.22782 -1.4203688,-1.91522 -2.100033,-4.419918 -2.1708454,-7.999998 -0.077124,-3.899159 -0.7763678,-6.191485 -2.7762599,-9.101389 -1.4702445,-2.139251 -2.6532836,-4.389251 -2.6289758,-5 0.024308,-0.610749 0.893801,0.496628 1.9322071,2.460839 1.038406,1.964211 2.5935178,4.156811 3.455804,4.872445 C 7.7749052,89.058077 8,88.929906 8,87.051016 c 0,-1.81313 0.2266463,-1.964541 1.3059539,-0.872445 0.7182751,0.726786 1.6080681,2.119136 1.9773191,3.09411 0.917874,2.423568 3.597042,3.283157 5.849193,1.876666 C 18.15961,90.507885 19,90.388721 19,90.884537 c 0,0.495817 -0.703522,1.171452 -1.563382,1.501411 -2.150082,0.825064 -1.014805,2.278435 3.631231,4.648666 L 25,99.040648 25,96.127313 c 0,-1.854135 0.636247,-3.155558 1.75,-3.57957 1.403147,-0.534186 1.502248,-0.41665 0.5,0.593011 -1.722759,1.735502 -1.57058,5.52225 0.25,6.220872 3.662349,1.405374 6.834671,-3.040686 4.332618,-6.072235 -1.120911,-1.358124 -1.105669,-1.539627 0.09594,-1.142493 2.77286,0.916434 3.619037,3.590537 1.779405,5.623307 C 32.768583,98.808207 32,99.959548 32,100.32874 c 0,1.22189 3.031392,0.6968 5.566392,-0.964198 1.372813,-0.899502 2.740893,-1.39059 3.040177,-1.091307 0.299284,0.299284 -0.32147,0.81889 -1.379452,1.154681 C 35.812869,100.51156 33.334725,109 36.432612,109 c 0.787937,0 1.702495,0.85032 2.032351,1.88961 0.716903,2.25876 3.899278,2.98747 11.440601,2.61969 5.10927,-0.24917 5.204183,-0.21804 1.094436,0.35894 -7.339953,1.03047 -2.80413,2.41322 5.309119,1.61849 13.280906,-1.30092 23.155404,-3.4537 28.190881,-6.146 12.841595,-6.86596 12.708691,-6.82355 23,-7.33944 9.85447,-0.49399 9.96402,-0.52676 7.52749,-2.25129 -4.63285,-3.279056 -32.71643,-1.860358 -43.372425,2.19104 C 68.030457,103.31912 68,103.31272 68,101.17285 c 0,-1.554257 1.456205,-2.024487 9.75,-3.148414 5.3625,-0.726696 16.025711,-1.409171 23.69603,-1.516613 l 13.94602,-0.195348 2.37767,2.825701 c 3.4404,4.088684 8.42172,5.299804 16.5763,4.030254 8.38078,-1.30476 14.11517,-4.427338 18.35728,-9.996169 6.12737,-8.043697 3.94914,-15.605544 -5.96012,-20.690949 -3.13046,-1.606543 -4.13508,-2.439431 -2.49318,-2.066996 3.86963,0.877755 3.67083,-1.886777 -0.2827,-3.931224 -1.66798,-0.862547 -2.76642,-1.999103 -2.44098,-2.52568 C 141.85176,63.430835 142.34303,63 142.61803,63 c 0.275,0 0.25417,0.397775 -0.0463,0.883944 -0.30047,0.486169 0.79797,1.440764 2.44098,2.12132 1.7127,0.709426 2.98729,1.986709 2.98729,2.993612 0,2.945924 2.66625,4.474222 5.52961,3.169585 3.22536,-1.469573 3.15548,-4.484406 -0.16447,-7.095881 C 151.91597,63.932661 151.16253,63 151.69083,63 153.38372,63 157,67.558499 157,69.692479 c 0,1.134967 -1.0125,2.744463 -2.25,3.576657 l -2.25,1.513079 2.47442,2.662226 c 2.30083,2.475466 2.5639,2.539849 3.75,0.917762 C 159.90132,76.752697 160,76.748571 160,78.30887 160,79.238992 159.55,80 159,80 c -1.28652,0 -1.26473,3.059179 0.0356,5 0.85771,1.28016 1.29514,1.154004 2.98469,-0.860784 2.10584,-2.511236 2.59509,-7.655089 0.96437,-10.139216 -0.87528,-1.333333 -1.0941,-1.333333 -1.96938,0 -0.79972,1.218232 -0.98756,1.077348 -1,-0.75 -0.0195,-2.865539 1.43199,-2.87718 3.42799,-0.02749 3.03177,4.328461 1.17233,12.333892 -3.11474,13.409879 -1.80078,0.451966 -2.32856,1.2751 -2.32856,3.631632 0,1.727247 -1.10691,4.498439 -2.55538,6.397477 -1.40546,1.842652 -2.23509,3.868512 -1.84363,4.501912 0.47718,0.77209 0.0575,0.98053 -1.27358,0.63246 -1.09193,-0.28555 -2.8039,0.0794 -3.80439,0.81095 -1.70561,1.24718 -1.64985,1.39446 0.89406,2.36166 4.47997,1.70328 8.67625,1.19771 12.16866,-1.46608 1.80099,-1.37368 3.46969,-3.51118 3.70821,-4.749999 L 165.72764,96.5 l 0.13618,2.295455 c 0.16702,2.815365 -3.71735,6.878695 -7.47805,7.822575 -1.53256,0.38465 -5.44937,0.14935 -8.70402,-0.52289 -5.61517,-1.1598 -6.03927,-1.1079 -8.29965,1.01562 -1.31015,1.23083 -2.3821,2.55767 -2.3821,2.94854 0,1.14917 5.20712,4.2268 8.47908,5.01149 l 3.02092,0.72449 -2.88197,0.10236 C 144.50527,116.0082 138,112.52462 138,110.74718 c 0,-0.59933 0.74724,-1.91539 1.66054,-2.92457 2.16307,-2.39017 1.02008,-3.45375 -2.15631,-2.00649 -3.12786,1.42515 -3.27729,4.73209 -0.35443,7.84333 1.95181,2.07761 1.99277,2.34861 0.44478,2.94263 -0.93775,0.35985 -2.69266,0.13724 -3.89979,-0.49469 -2.0637,-1.08034 -2.03054,-1.11672 0.55521,-0.60912 2.94412,0.57794 3.81659,-0.875 1.14178,-1.90142 -1.15878,-0.44467 -1.49842,-1.55765 -1.21534,-3.9825 l 0.39289,-3.36536 -6.53467,-0.61738 c -13.00233,-1.22845 -21.57712,-0.79467 -23.36602,1.18204 -2.42475,2.67932 -0.29762,4.18635 5.90892,4.18635 3.38232,0 5.6092,0.5201 6.42244,1.5 0.68469,0.825 2.00378,1.5 2.93132,1.5 0.92753,0 2.55993,0.65168 3.62755,1.44818 1.63518,1.21992 1.23186,1.20889 -2.55887,-0.07 -2.475,-0.835 -4.9275,-1.93668 -5.45,-2.44817 C 115.0275,112.41849 112.2701,112 109.42244,112 c -5.81685,0 -7.99853,-1.60955 -6.89489,-5.08679 0.64859,-2.04353 0.31897,-1.97348 -5.167386,1.09821 -3.22309,1.80453 -7.660164,4.20071 -9.860164,5.32483 -4.869503,2.48813 -8.5,6.14438 -8.5,8.56028 0,1.89443 2.403731,4.41308 5.128145,5.37333 3.701205,1.30452 5.322132,-5.00984 2.177922,-8.48415 -1.547181,-1.70962 -1.550479,-1.81673 -0.03807,-1.23636 1.883969,0.72294 2.827381,3.10059 2.950659,7.43644 0.08318,2.9255 0.17244,2.97592 4.183167,2.36259 5.136428,-0.78547 5.285926,-0.93094 3.25871,-3.17099 -2.101653,-2.3223 -2.143074,-5.77825 -0.07875,-6.5704 2.439984,-0.93631 3.117175,-0.66206 1.168213,0.47311 -2.37974,1.38607 -2.198071,3.15033 0.594543,5.77386 2.785571,2.6169 5.381301,1.99734 6.753561,-1.61198 0.66585,-1.75131 0.56939,-2.94034 -0.3266,-4.02624 -1.053,-1.27617 -1.01373,-1.45661 0.2285,-1.05003 1.9271,0.63073 2.50765,4.51768 0.95432,6.38933 -1.01625,1.2245 -0.49396,1.44496 3.42324,1.44496 4.66697,0 5.54429,-0.67815 3.50957,-2.71287 -0.61207,-0.61207 -0.81052,-1.60207 -0.44098,-2.2 1.1226,-1.8164 2.21733,-1.21965 2.13325,1.16287 -0.0687,1.9473 0.49237,2.29137 4.1706,2.5575 4.89387,0.35408 5.54154,-1.04295 1.5,-3.23553 -1.5125,-0.82054 -2.16705,-1.50991 -1.45455,-1.53193 0.7125,-0.022 2.42046,1.08496 3.79546,2.45996 2.68271,2.68272 5.92467,3.28311 6.74963,1.25 0.39816,-0.98126 0.70669,-0.96639 1.43511,0.0692 0.57455,0.81682 2.41244,1.19764 4.82614,1 4.85311,-0.39739 4.63358,-2.36464 -0.24505,-2.19592 -2.33216,0.0807 -3.09655,-0.17337 -2.21073,-0.73468 2.15213,-1.36373 6.49538,-1.02562 7.85399,0.6114 1.58235,1.90661 3.4143,1.91065 4.99086,0.011 0.67967,-0.81894 1.63477,-1.24239 2.12245,-0.94098 0.48768,0.3014 0.88669,0.12254 0.88669,-0.39747 0,-0.52001 1.96424,-1.24003 4.36497,-1.60004 2.40074,-0.36001 5.21324,-1.28329 6.25,-2.05172 1.8403,-1.36399 1.83758,-1.43551 -0.11497,-3.01414 -1.9562,-1.58158 -1.95073,-1.59312 0.25,-0.52664 2.84088,1.37669 4.78829,0.38032 9.54294,-4.88251 C 172.80982,104.20474 177,97.119504 177,95.065518 177,94.014167 171.87071,91 170.0816,91 c -0.55975,0 -1.68908,1.2375 -2.50963,2.75 -0.82054,1.5125 -1.50991,2.212594 -1.53193,1.555764 -0.022,-0.65683 1.01695,-2.423063 2.30883,-3.924962 l 2.34887,-2.730726 3.65113,2.256521 c 3.99825,2.471055 4.59664,1.710475 2.66058,-3.381739 -0.81813,-2.151838 -1.31628,-2.431014 -2.86186,-1.603846 -3.32941,1.781848 -5.36024,-0.738986 -4.57109,-5.67403 0.37019,-2.315074 1.29192,-4.72282 2.04829,-5.350548 1.75187,-1.45392 1.72743,-0.983657 -0.18698,3.598175 -1.91265,4.577614 -1.25329,6.755386 1.91943,6.339621 1.30059,-0.170435 3.17394,0.359641 4.163,1.177945 1.70616,1.411599 1.76965,1.170621 1.23917,-4.703557 C 178.28385,76.042564 174.04685,64 172.66963,64 c -0.24256,0 -1.60077,0.601686 -3.01824,1.337081 -2.08842,1.083485 -2.34854,1.60506 -1.37145,2.75 0.66317,0.777105 0.30899,0.571465 -0.78708,-0.456979 -1.20533,-1.130955 -1.55493,-2.034357 -0.88467,-2.286063 6.0652,-2.277701 5.2187,-5.81006 -1.21846,-5.0845 -2.44979,0.276127 -5.02234,-0.0011 -5.88978,-0.634636 C 158.24327,58.707044 158.56167,58.5 161.2299,58.5 c 5.00768,0 4.6385,-1.682212 -1.13525,-5.172896 -12.9104,-7.805343 -33.29995,-6.30168 -40.15023,2.960948 C 118.63793,58.054623 117.24343,61.3 116.84552,63.5 l -0.72346,4 0.32545,-4 c 0.179,-2.2 0.66052,-5.125 1.07004,-6.5 0.71616,-2.404557 0.6739,-2.432955 -1.10692,-0.743848 -1.01833,0.965883 -2.66641,3.665883 -3.66241,6 -1.4884,3.488049 -1.72304,3.70957 -1.31752,1.243848 0.39125,-2.378971 -0.0136,-1.964952 -1.95579,2 -1.34705,2.75 -2.45497,6.636425 -2.46204,8.636501 -0.0118,3.336856 0.25493,3.677738 3.23713,4.136962 2.1089,0.324745 3.86387,-0.04042 4.99839,-1.040033 1.38534,-1.220615 2.21593,-1.306486 4,-0.413542 2.12661,1.064388 2.09894,1.094651 -0.49839,0.545124 -4.21264,-0.891285 -3.33354,1.378923 1,2.582407 4.85057,1.347071 5.52757,1.318124 4.61706,-0.197419 -0.53797,-0.895455 -0.28469,-0.872021 0.89299,0.08262 0.97903,0.793608 2.52299,1.053631 3.81719,0.642866 1.60688,-0.510004 1.96977,-0.360563 1.39251,0.573455 -0.59722,0.966328 0.0837,1.122937 2.89718,0.666368 2.19407,-0.356049 3.44331,-0.217294 3.09646,0.343927 -0.86056,1.392409 -9.11883,1.11345 -15.96339,-0.539235 C 113.32076,79.786504 99.143306,79.577068 91.799221,81.096019 82.257535,83.069492 68.598786,87.207987 63.5,89.670465 60.75,90.998587 59.373508,91.391055 60.44113,90.542616 62.300342,89.065099 62.253923,89 59.341168,89 56.523355,89 49.14769,93.333982 47.540821,95.93395 47.178451,96.520278 46.431155,97 45.880163,97 44.130916,97 54.01186,89.029305 56.304656,88.590838 57.512095,88.359932 61.2,87.585153 64.5,86.869107 l 6,-1.301901 -4.5,-0.633409 -4.5,-0.63341 4.75,-0.150193 c 4.473381,-0.141447 6.022882,-1.245476 3.733688,-2.660275 -0.558971,-0.345464 -0.755061,-1.050828 -0.435755,-1.567476 0.319306,-0.516648 -0.460854,-1.35703 -1.733688,-1.867515 C 66.54141,77.544442 66.0625,77.098249 66.75,77.063386 67.4375,77.028524 68,76.085877 68,74.968615 c 0,-2.079322 -0.408067,-2.340743 -5.354773,-3.430441 -2.21684,-0.488342 -2.740607,-1.065438 -2.34388,-2.582526 0.280991,-1.074511 0.103139,-2.205662 -0.395227,-2.513669 -1.754136,-1.084116 -0.873348,-3.030123 2.190688,-4.840094 2.539071,-1.499866 3.021911,-2.339639 2.680945,-4.662795 -0.228726,-1.558405 -0.06048,-2.613826 0.373874,-2.345379 0.799233,0.493953 1.222222,-0.936237 2.364237,-7.993847 l 0.631094,-3.900137 -6.22017,0.650137 C 58.505694,43.707439 54.856796,44 53.818125,44 52.23951,44 52.105266,44.328174 53,46 c 0.603726,1.128073 0.665708,2 0.142173,2 -0.510508,0 -1.187217,-0.675 -1.503799,-1.5 C 51.030883,44.916904 47,44.375981 47,45.877555 c 0,0.482656 0.665544,1.429908 1.478987,2.105005 1.981802,1.644751 0.62168,4.013323 -3.64046,6.339644 L 41.5,56.144408 l 3.775181,-3.1894 c 2.993136,-2.528702 3.537445,-3.475853 2.627555,-4.572204 C 45.16125,45.079515 36.529389,48.039375 28.75,54.950267 26.1375,57.271106 24,59.58566 24,60.093722 24,61.824883 35.383735,59.923171 37.160293,57.895227 38.073454,56.852852 39.411081,56 40.132799,56 c 0.721717,0 0.274164,0.727078 -0.994563,1.615729 -1.268728,0.888652 -1.931355,1.97674 -1.472507,2.417975 1.11076,1.068121 8.034467,1.599433 8.947301,0.6866 C 47.009197,60.324137 46.808333,60 46.166667,60 44.568818,60 44.695226,57.497829 46.363,56.1137 c 1.09724,-0.910628 1.276542,-0.678917 0.919587,1.188374 -0.58932,3.082827 1.935763,5.110924 5.3092,4.264245 1.980214,-0.497002 2.493269,-1.133063 2.106605,-2.611667 C 54.417258,57.879593 54.59511,57 55.09362,57 55.592129,57 56,57.8625 56,58.916667 c 0,1.054166 0.5625,2.112703 1.25,2.352304 0.6875,0.2396 -0.6625,0.766654 -3,1.171231 -4.754297,0.822878 -5.287759,1.616774 -2.064693,3.07267 1.201919,0.54292 2.353038,1.662128 2.558041,2.487128 0.254475,1.024091 0.02128,0.944773 -0.734998,-0.25 C 53.399099,66.7875 52.395914,66 51.779051,66 51.162187,66 49.809053,65.232183 48.772085,64.29374 45.991559,61.777398 30.150985,61.232775 22.704592,63.3975 13.435693,66.092042 7.3129808,73.525083 11.5,77 c 0.825,0.684689 1.5,1.718231 1.5,2.296759 0,0.578528 -1.096597,0.02167 -2.436882,-1.237463 L 8.1262358,75.769964 7.7378251,80.134982 7.3494144,84.5 7.1747072,80.20034 C 7.0786182,77.835527 7.6570529,74.63008 8.4601175,73.077124 10.158035,69.793714 9.5510353,68.638925 6.97339,70.248691 5.5961296,71.108804 4.7865426,71.067736 3.5930344,70.077212 1.7174163,68.520587 1.2654761,69.368624 0.70309413,75.5 l -0.3668879,4 -0.16810312,-4.527494 C 0.06396586,72.167795 0.61960712,69.560399 1.6283355,68.120238 2.5239201,66.841612 3.3733615,63.632774 3.5159832,60.989488 3.8530478,54.742486 8.0805849,46.994316 13.6356,42.442399 15.999802,40.505113 18.736466,37.553338 19.717075,35.8829 22.351009,31.396071 31.911292,25.379684 37.677679,24.580104 40.329955,24.212333 45.2,22.572433 48.5,20.935881 52.084743,19.158118 56.713985,17.770811 60,17.489522 l 5.5,-0.470811 -6.670459,1.412891 c -6.77351,1.43472 -12.141718,3.634484 -10.326878,4.231709 0.548535,0.180511 3.446734,0.961734 6.440441,1.736049 5.329987,1.37859 5.517022,1.353649 9,-1.200126 L 67.5,20.591261 l -2.835022,3.097832 -2.835022,3.097832 4.515197,3.106538 c 5.257479,3.61724 7.105683,3.93854 6.365098,1.106537 -0.287656,-1.1 -0.126697,-2 0.357688,-2 0.484386,0 1.538016,-1.271108 2.341402,-2.824684 0.803385,-1.553577 2.85318,-4.315338 4.555099,-6.137248 1.701918,-1.82191 2.917887,-3.489075 2.702151,-3.70481 C 81.957858,15.624525 76.597845,15.603002 71,16.286412 c -4.476169,0.54647 -4.941547,0.478942 -2.5,-0.362762 1.65,-0.568824 7.05,-1.223372 12,-1.454552 4.95,-0.231179 11.757514,-0.693497 15.12781,-1.027373 5.03801,-0.499086 6.85383,-0.236657 10.21016,1.475614 2.2453,1.145464 4.88778,2.119369 5.87219,2.164235 1.18216,0.05388 0.76024,0.534002 -1.24273,1.414146 -6.62791,2.912441 -12.981206,11.112693 -18.863718,24.347566 -0.572837,1.288807 -1.191524,1.893277 -1.374861,1.343266 C 89.343595,41.530785 96.225709,29.614291 101.95162,23.888376 105.27823,20.561769 108,17.662556 108,17.44568 c 0,-0.812565 -5.97076,-3.443637 -7.70034,-3.393228 -1.554618,0.04531 -1.493299,0.266158 0.45034,1.621972 1.2375,0.863236 2.25,2.018043 2.25,2.566237 0,0.548194 -1.54498,-0.181693 -3.433278,-1.621972 C 97.678419,15.17841 95.413966,14 94.534603,14 c -3.124582,0 -9.090011,3.151108 -12.871001,6.798827 -4.313493,4.161451 -9.076648,12.682409 -8.267733,14.790407 0.292685,0.762726 0.02575,1.279672 -0.5932,1.14877 -0.618945,-0.130902 -1.766052,1.389692 -2.549127,3.379098 -1.361145,3.457997 -1.299064,3.792805 1.411343,7.611579 3.130624,4.41083 7.252289,6.74977 10.22934,5.804891 2.479929,-0.787099 2.862729,-0.08557 3.559843,6.523878 0.399593,3.788612 0.287236,4.834769 -0.36973,3.44255 -0.519072,-1.1 -0.975396,-3.703333 -1.014053,-5.785184 -0.06358,-3.424322 -0.254688,-3.686494 -2.004544,-2.75 -2.990987,1.600728 -3.591959,1.351072 -8.455725,-3.512695 l -4.547878,-4.547878 -0.781069,2.797878 c -1.407722,5.042622 -0.785206,19.482754 1.076711,24.975849 1.727032,5.09515 1.809873,5.169082 5.179295,4.622301 2.269924,-0.368358 4.257887,-0.0094 5.89739,1.064832 3.760828,2.464189 7.213966,0.772058 7.747307,-3.796391 0.229236,-1.963581 0.107694,-3.907323 -0.270094,-4.319429 C 87.533889,71.837177 86.933752,70.375 86.578039,69 c -0.481847,-1.86257 -0.15391,-1.610751 1.286172,0.987636 1.28842,2.324739 1.756399,4.575419 1.403513,6.75 C 88.808786,79.565741 89.021955,80 90.869158,80 92.041121,80 92.993247,79.8875 92.984994,79.75 92.976741,79.6125 91.851802,75.9 90.48513,71.5 88.822438,66.146962 88.033208,61.349343 88.099816,57 c 0.151351,-9.88287 0.49917,-10.444492 6.705162,-10.826817 3.118521,-0.192118 5.898182,0.165496 6.744252,0.867676 0.7916,0.656971 2.52818,0.986336 3.85905,0.731923 2.5582,-0.489031 3.54712,0.754003 5.35193,6.727218 0.49855,1.65 1.54396,3 2.32312,3 1.04483,0 1.56866,-1.968578 1.99573,-7.5 0.97791,-12.665805 6.8382,-22.188056 16.10994,-26.17665 4.51265,-1.941293 4.8662,-2.309822 3.30854,-3.448804 -0.9592,-0.701389 -3.15105,-1.063992 -4.87077,-0.805785 -2.30576,0.346198 -2.61568,0.245988 -1.18032,-0.381643 1.8198,-0.795731 1.78726,-0.893687 -0.5,-1.50546 C 126.6009,17.321766 122.8,16.975102 119.5,16.911293 c -5.43647,-0.10512 -5.67127,-0.193779 -2.5,-0.943973 4.02522,-0.952204 11.77242,0.422015 17,3.015504 1.925,0.955025 6.12081,2.032427 9.32401,2.394227 6.73381,0.760578 11.44455,2.955178 17.43802,8.12387 5.27569,4.549683 7.14595,7.549281 4.23187,6.787233 -1.08427,-0.283544 -1.77098,-0.83983 -1.52601,-1.236192 1.02375,-1.656475 -8.26228,-9.131069 -13.73254,-11.05371 -6.49617,-2.28322 -8.67104,-2.421421 -14.15312,-0.899348 l -3.91777,1.08775 3.16777,2.479151 c 1.74227,1.363533 3.15409,3.234036 3.13736,4.156673 -0.0252,1.391633 -0.22588,1.336675 -1.17741,-0.322478 -1.82812,-3.187669 -4.07319,-4.508569 -7.21517,-4.245103 -4.31928,0.362187 -4.06,1.9718 0.70333,4.366318 2.95315,1.484541 4.30111,2.835198 4.49102,4.5 L 135.04272,37.5 133.66129,35.110071 c -1.52143,-2.632133 -5.21945,-5.019558 -7.8604,-5.074636 C 121.83603,29.952747 116,41.617964 116,49.625727 c 0,4.508295 0.69559,5.27868 2.83474,3.139535 0.6791,-0.679106 4.47517,-2.154118 8.43569,-3.277804 6.38336,-1.811095 7.30304,-2.380531 8.09998,-5.015262 C 137.48302,37.487813 138.30697,36 140.0623,36 c 1.00082,0 2.07184,0.408034 2.38006,0.906741 0.30822,0.498708 -0.32747,0.674557 -1.41265,0.390777 -1.43152,-0.37435 -2.29988,0.201341 -3.16382,2.097484 -0.65493,1.437398 -0.94131,2.86291 -0.63642,3.167805 0.94615,0.946149 7.95175,-2.460572 7.28348,-3.541851 C 144.16591,38.45943 144.33197,38 144.88197,38 c 0.55,0 1.30921,0.500325 1.68715,1.111833 0.43537,0.704441 2.38067,0.893185 5.30901,0.51511 2.64165,-0.34106 7.12297,-0.008 10.4595,0.777254 5.77443,1.359103 5.8318,1.35082 5.29973,-0.76511 -0.51648,-2.053963 -0.48161,-2.063804 0.87631,-0.247277 0.77781,1.040496 1.54293,2.173924 1.70027,2.51873 0.15733,0.344805 3.28347,2.750118 6.94697,5.34514 15.82503,11.209585 23.57036,27.551499 20.8112,43.909661 -0.90379,5.358262 -0.89721,7.601273 0.0289,9.836969 0.65977,1.59283 0.96499,3.48143 0.67826,4.19687 -0.28673,0.71545 -0.55685,0.31488 -0.60027,-0.89016 -0.0889,-2.46442 -2.079,-4.28103 -2.079,-1.89767 0,0.84116 -1.05951,3.90522 -2.35447,6.80901 -3.25421,7.29723 -3.71502,8.77964 -2.72916,8.77964 0.46949,0 1.57279,-1.0976 2.45178,-2.43912 0.9127,-1.39295 2.46323,-2.37396 3.61501,-2.2872 2.49587,0.18801 2.50887,0.84943 0.10842,5.51616 -4.03765,7.84962 -11.79274,12.46231 -19.26685,11.45983 -3.56422,-0.47807 -5.23275,0.76209 -2.93551,2.18186 1.64483,1.01656 2.17586,5.61305 1.10706,9.5823 -0.58335,2.16639 -2.73366,5.96385 -4.77846,8.4388 -2.0448,2.47494 -4.81003,5.9155 -6.14495,7.64567 -4.2303,5.48286 -9.60651,8.63672 -16.96381,9.95155 -6.6329,1.18536 -17.66718,0.53116 -15.3365,-0.90928 0.77973,-0.4819 0.57587,-1.88001 -0.68465,-4.69549 -2.18534,-4.8811 -6.64217,-7.05254 -16.08791,-7.83829 l -6.5,-0.5407 4.83577,4.45701 c 3.33388,3.07277 6.75023,5.06381 11,6.41079 6.28558,1.99224 6.02004,2.84838 -0.33577,1.08256 -5.1117,-1.42018 -5.50493,-1.26716 -5.16134,2.00838 0.17164,1.63634 0.16566,2.93649 -0.0133,2.88922 -0.17896,-0.0473 -1.65275,-0.4824 -3.2751,-0.96694 z M 119,168.0651 c 0,-0.5142 -0.43886,-2.0892 -0.97525,-3.5 C 116.49307,160.53647 112,161.60542 112,165.99845 c 0,0.45919 1.2375,1.28686 2.75,1.83927 3.60147,1.31537 4.25,1.35007 4.25,0.22738 z m 23,-1.18903 c 0,-0.61816 2.025,-2.9064 4.5,-5.08499 5.21194,-4.58773 5.55803,-5.75273 1.75,-5.89076 -1.5125,-0.0548 -3.875,-0.48542 -5.25,-0.95688 -1.7185,-0.58924 0.31342,-0.83133 6.5,-0.77444 4.95,0.0455 9.9,0.0118 11,-0.0749 1.97388,-0.15563 1.97465,-0.17686 0.0589,-1.62588 -1.6284,-1.23166 -1.67818,-1.4682 -0.30902,-1.4682 0.89767,0 1.91023,0.45 2.25015,1 1.09512,1.77194 3.34537,1.07467 7.06148,-2.18812 3.46842,-3.04532 4.23056,-4.29478 5.9156,-9.69805 0.69342,-2.22357 0.5492,-2.33777 -2.11647,-1.67587 -3.85504,0.95722 -7.18493,4.23381 -7.55606,7.43511 -0.21394,1.84535 -0.97398,2.722 -2.55455,2.94648 -1.2375,0.17575 -2.25,-0.12875 -2.25,-0.67667 0,-0.54793 -0.7875,-1.20203 -1.75,-1.45355 -1.31691,-0.34415 -1.19317,-0.48604 0.5,-0.57333 1.2375,-0.0638 2.25,0.334 2.25,0.884 0,0.55 0.72314,1 1.60699,1 1.08039,0 1.40018,-0.53892 0.97589,-1.64462 -0.34711,-0.90454 0.0726,-2.42217 0.93263,-3.37252 1.46748,-1.62155 1.04839,-1.75495 -6.80885,-2.16735 -6.01433,-0.31567 -9.55496,-1.05573 -12.57041,-2.62748 -2.35503,-1.22751 -6.05003,-2.19475 -8.41704,-2.20334 -2.48473,-0.009 -3.70318,-0.34294 -2.96394,-0.81228 2.54403,-1.61518 -5.22592,-4.14087 -10.73251,-3.4887 -2.79465,0.33098 -5.28077,0.92474 -5.52472,1.31945 -0.97842,1.58313 7.34465,4.2485 11.1884,3.58295 2.74458,-0.47522 3.3931,-0.37389 2.31356,0.36148 -2.49881,1.70216 -7.21014,1.16781 -12.8493,-1.45736 -6.30217,-2.93382 -6.2956,-2.93334 -12.9692,-0.95149 -4.74684,1.40966 -5.1815,1.7901 -5.1815,4.53518 0,3.15735 2.54017,7.92608 4.222,7.92608 0.54559,0 0.74845,-0.63461 0.45081,-1.41025 -0.35889,-0.93525 0.57504,-0.68263 2.77273,0.75 3.58815,2.33903 4.03169,3.52121 0.64011,1.70609 C 107.93854,147.43192 107,147.34668 107,147.85641 c 0,0.50972 1.12888,1.21011 2.50863,1.5564 C 112.14739,150.0751 118,147.70515 118,145.97432 118,145.43844 118.40787,145 118.90638,145 c 2.04394,0 -0.29109,3.87974 -2.69871,4.48401 -3.6661,0.92014 -0.96288,2.48536 4.29233,2.48536 4.68051,0 7.61572,-1.32725 5.08385,-2.29882 -2.85754,-1.09654 -1.90098,-5.50659 1.66615,-7.68151 1.7875,-1.08986 3.7,-1.96336 4.25,-1.94111 0.55,0.0223 -0.71551,0.94569 -2.81224,2.05208 -2.90109,1.53084 -3.73761,2.53451 -3.5,4.19938 0.41585,2.91369 4.99875,3.74316 10.56224,1.91169 4.59822,-1.51372 5.51988,-3.79834 2.67857,-6.63965 -0.86428,-0.86429 -1.17928,-1.57143 -0.7,-1.57143 1.49949,0 3.27143,2.31793 3.27143,4.27946 0,1.57246 0.53085,1.78491 3.25,1.30067 2.13217,-0.3797 0.17761,0.96876 -5.68272,3.92055 -4.91299,2.47463 -9.52549,4.49932 -10.25,4.49932 -2.32363,0 -1.40977,1.90081 1.68272,3.5 1.65,0.85325 3.00168,2.1023 3.00374,2.77568 0.002,0.67338 0.89544,2.68682 1.9853,4.47432 1.38998,2.27974 2.73231,3.25 4.49626,3.25 1.38309,0 2.5147,-0.50577 2.5147,-1.12393 z M 137.18195,161.5 c -0.62649,-1.375 -0.81122,-2.49649 -0.41051,-2.4922 0.40071,0.004 1.24872,1.12929 1.88447,2.5 0.63576,1.37071 0.82049,2.4922 0.41052,2.4922 -0.40997,0 -1.25798,-1.125 -1.88448,-2.5 z m 4.94472,0 c 0.88679,-1.1 1.81369,-2.65284 2.05976,-3.45075 0.28216,-0.91495 0.6883,-1.06096 1.09966,-0.39536 0.35875,0.58047 -0.56814,2.1333 -2.05976,3.45075 -1.88539,1.66525 -2.22057,1.78576 -1.09966,0.39536 z M 153.25,152.31067 c 0.9625,-0.25152 2.5375,-0.25152 3.5,0 0.9625,0.25153 0.175,0.45733 -1.75,0.45733 -1.925,0 -2.7125,-0.2058 -1.75,-0.45733 z m -3.5,-0.88763 c -0.4125,-0.416 -0.75,-1.07678 -0.75,-1.46839 0,-0.93776 5.91442,-3.37356 6.57863,-2.70935 0.28298,0.28298 -0.59851,0.79386 -1.95887,1.13529 -1.36035,0.34142 -2.61881,1.33584 -2.79657,2.2098 -0.17775,0.87397 -0.66069,1.24866 -1.07319,0.83265 z M 104,141.78152 C 104,139.48168 107.02665,136 109.02591,136 c 2.39098,0 9.97409,3.88461 9.97409,5.10944 0,0.83091 -3.82872,-0.84023 -5,-2.18238 -2.27465,-2.60649 -8,-1.83263 -8,1.08131 0,1.03048 -0.45,2.15171 -1,2.49163 -0.55,0.33992 -1,0.0166 -1,-0.71848 z m 50.5,23.16674 c 4.38173,-1.9809 9.25266,-5.56245 8.48506,-6.23899 -0.26678,-0.23513 -2.56484,-0.69939 -5.10679,-1.03168 -4.42275,-0.57816 -4.84252,-0.40629 -9.75,3.99189 -2.82055,2.52783 -5.12827,4.95801 -5.12827,5.40041 0,1.21253 6.96878,-0.0731 11.5,-2.12163 z m -41.61011,-5.58094 C 111.73637,157.97742 108,157.44555 108,158.67126 c 0,0.36919 0.74331,1.4926 1.65179,2.49647 1.26327,1.39589 1.97181,1.55962 3.01233,0.69606 1.02811,-0.85326 1.08328,-1.46323 0.22577,-2.49647 z M 149,134.08179 C 149,131.46163 150.02473,129 151.11546,129 c 0.49582,0 0.37666,0.84039 -0.26481,1.86753 -1.62572,2.6032 -0.37949,5.13247 2.52887,5.13247 4.57642,0 14.51591,-3.75287 19.32391,-7.29616 C 182.63349,121.3858 185.1315,117 179.36955,117 c -1.38182,0 -3.18741,-0.675 -4.01241,-1.5 -0.825,-0.825 -1.27966,-1.5 -1.01036,-1.5 0.26931,0 1.20145,-0.27314 2.07143,-0.60699 1.00214,-0.38456 1.58179,-0.0661 1.58179,0.86916 0,2.1096 7.03353,3.13287 8.8752,1.2912 1.9623,-1.9623 0.66215,-4.55337 -2.2848,-4.55337 -3.53566,0 -3.90877,-1.34609 -1.50319,-5.42323 2.5447,-4.31295 3.57741,-4.76268 1.43847,-0.62643 C 182.59041,108.69275 182.61122,109 184.8,109 c 0.99,0 2.37029,0.5625 3.06732,1.25 1.82255,1.79764 3.49865,-0.83978 6.76482,-10.644744 3.54791,-10.65075 3.63362,-19.705616 0.26532,-28.031049 -2.78369,-6.880428 -5.10653,-8.63741 -4.22326,-3.194437 C 191.40893,72.907336 190.36762,77 188.48095,77 187.54325,77 187,77.97821 187,79.666667 c 0,3.381548 -0.53162,2.783224 -1.35246,-1.522159 -0.50675,-2.657957 -0.34393,-3.241979 0.78325,-2.809441 2.34043,0.89811 3.87667,-2.006144 3.30715,-6.252191 -0.28755,-2.143893 -0.10648,-4.31434 0.4024,-4.823214 1.27144,-1.271444 -0.10146,-4.48856 -1.66023,-3.890404 -0.69399,0.26631 -3.22342,-0.127726 -5.62096,-0.875634 -2.88117,-0.898779 -3.57399,-1.382514 -2.04341,-1.426728 1.27366,-0.03679 3.15885,0.384321 4.18931,0.935808 1.11406,0.596228 2.10273,0.631926 2.43885,0.08806 C 188.23393,57.81248 177.0177,47.871759 171.23291,44.723285 164.22013,40.90645 153.73188,39.527907 147.2086,41.565604 145.65367,42.051322 149.67077,48 151.5537,48 c 0.64767,0 4.33686,1.58052 8.19819,3.512266 4.20554,2.103942 7.76792,3.274127 8.88436,2.918365 1.7486,-0.557208 1.75691,-0.505751 0.13443,0.832852 -1.6163,1.333512 -1.55798,1.583916 0.89234,3.831635 4.70894,4.319587 9.97773,13.499797 11.28593,19.664338 2.08898,9.843716 -1.32265,22.109134 -8.63016,31.026994 -5.85655,7.14715 -12.43429,10.83547 -28.22229,15.82503 -1.09758,0.34688 -0.9886,0.77653 0.5,1.9712 1.81837,1.45933 1.80581,1.48046 -0.28076,0.47249 C 143.1144,127.47482 139.10715,127 135.41075,127 l -6.72073,0 1.90499,2.14123 c 1.04775,1.17768 3.70499,2.95611 5.90499,3.95206 l 4,1.81083 2.22844,-2.70206 2.22844,-2.70206 -0.60344,3.25 c -0.556,2.99452 -0.39709,3.25 2.02156,3.25 1.92103,0 2.625,-0.51443 2.625,-1.91821 z m 7.2152,-7.90987 C 159.72637,123.14895 166.76977,120 170.02024,120 171.10911,120 172,119.35156 172,118.55902 c 0,-0.79254 0.40803,-1.69316 0.90674,-2.00138 0.49871,-0.30822 0.66127,0.37831 0.36124,1.52561 -0.30003,1.14731 -1.04556,2.22154 -1.65674,2.38718 -0.61118,0.16564 -3.0312,0.82285 -5.37782,1.46047 -2.34662,0.63763 -5.78103,2.48902 -7.63202,4.11421 -1.85098,1.62519 -3.88418,2.95489 -4.51821,2.95489 -0.63403,0 0.32538,-1.27264 2.13201,-2.82808 z M 186.13618,99.5 c -0.0899,-1.1 -0.41331,-3.125 -0.71864,-4.5 -0.47917,-2.157871 -0.40012,-2.25702 0.57762,-0.724498 0.62302,0.976526 0.9464,3.001526 0.71863,4.5 -0.26992,1.775778 -0.47105,2.028068 -0.57761,0.724498 z M 185.232,87 c 0,-1.925 0.2058,-2.7125 0.45733,-1.75 0.25152,0.9625 0.25152,2.5375 0,3.5 C 185.4378,89.7125 185.232,88.925 185.232,87 z M 183.1072,70.261051 C 180.18061,67.334451 178.75946,62 180.90638,62 c 0.49851,0 0.67123,0.899204 0.38383,1.998231 C 180.66373,66.393904 183.44829,71 185.52305,71 c 0.81232,0 1.51248,-0.7875 1.5559,-1.75 0.0443,-0.981198 0.29501,-1.217407 0.57077,-0.537676 0.27051,0.666778 0.0582,1.987136 -0.47174,2.934128 -0.86471,1.545143 -1.28238,1.402997 -4.07078,-1.385401 z M 173.5,56 c -1.63041,-0.70061 -1.68751,-0.872418 -0.30902,-0.929715 C 174.12102,55.031628 175.16008,55.45 175.5,56 c 0.71066,1.149879 0.67591,1.149879 -2,0 z m -61.79558,75.47866 c 6.96937,-1.38673 12.88698,-2.73673 13.15025,-3 C 125.11793,128.2154 122.08993,128 118.12576,128 c -7.04534,0 -19.415463,3.0417 -20.678002,5.08453 -0.808779,1.30863 0.154401,1.20014 14.256662,-1.60587 z m 78.74134,-5.86949 c 3.4083,-2.59964 7.38621,-9.11053 6.25644,-10.2403 -0.39055,-0.39055 -1.74981,0.26668 -3.02059,1.46052 -1.27078,1.19384 -2.98438,2.17061 -3.808,2.17061 -1.33384,0 -2.89416,1.6777 -7.79137,8.37749 -1.34443,1.83929 -1.2453,1.90512 1.91649,1.27276 1.83384,-0.36676 4.735,-1.73525 6.44703,-3.04108 z M 78.75,83.369714 c 3.17118,-0.849843 2.793844,-2.010945 -0.89316,-2.748346 -3.189543,-0.637909 -6.31166,0.833701 -5.286813,2.491939 0.632517,1.023433 2.957824,1.11991 6.179973,0.256407 z m 23.25299,-4.971478 c 3.3402,-0.55281 3.51077,-0.780704 3.67034,-4.903755 0.092,-2.378201 1.31081,-6.713274 2.70838,-9.633496 2.34969,-4.909691 2.43099,-5.530075 1.07966,-8.238877 C 108.65762,54.010947 108,51.81178 108,50.735071 c 0,-1.688339 -0.47215,-1.869077 -3.43208,-1.31379 -2.63551,0.494423 -3.65066,0.253287 -4.37383,-1.038944 -1.139772,-2.036661 -6.523385,-1.299292 -9.378473,1.284527 -3.194713,2.891176 -2.111362,15.116245 2.355723,26.583136 1.129267,2.898799 2.411726,3.210748 8.83165,2.148236 z M 66.625,67.875 C 66.28125,66.15625 66,63.90625 66,62.875 c 0,-2.463052 -1.500504,-2.374496 -4.118034,0.243034 -1.580825,1.580825 -1.801966,2.313375 -0.871885,2.888197 0.685382,0.423589 0.93694,1.270474 0.559017,1.881966 C 60.495557,69.625224 61.871709,71 64.684017,71 67.024585,71 67.195095,70.725476 66.625,67.875 z M 8.2996599,68.302646 C 10.059847,67.369101 11.95,66.575 12.5,66.537977 14.332608,66.414615 22,61.973233 22,61.035046 c 0,-0.508369 2.281924,-3.17052 5.070942,-5.915892 5.783884,-5.693371 16.780672,-10.847866 25.240074,-11.830714 2.853941,-0.331582 6.29658,-1.319629 7.650308,-2.195659 C 61.315052,40.216752 62.146396,39.95 61.808755,40.5 c -0.34533,0.562525 0.634785,1.0901 2.240389,1.205955 2.135993,0.154125 2.713683,-0.160442 2.295581,-1.25 C 66.037438,39.65518 65.185725,39 64.452028,39 c -0.733697,0 -1.608924,-0.444846 -1.944949,-0.988546 -0.81956,-1.326075 2.533084,-0.100888 4.627485,1.691065 1.449903,1.240525 1.763585,1.028407 2.776629,-1.877612 1.349908,-3.872349 0.359416,-4.913109 -9.37848,-9.854439 L 54.565427,24.94247 53.72773,27.206978 c -0.460733,1.24548 -0.630083,3.058425 -0.376333,4.028766 C 53.605147,32.206085 53.453035,33 53.013369,33 51.765631,33 51.1584,30.622215 51.692553,27.827974 c 0.321262,-1.680573 -0.0223,-2.740533 -1.011298,-3.120046 -1.883464,-0.722753 -2.912339,2.886651 -2.050791,7.194392 0.517075,2.585377 0.309443,3.095148 -1.255464,3.082367 -1.041661,-0.0085 -1.430552,-0.341843 -0.875,-0.75 0.55,-0.404078 1.023829,-2.701679 1.052953,-5.10578 l 0.05295,-4.371094 -6.189288,0.496817 c -7.395397,0.593631 -15.232939,4.486008 -19.530197,9.699327 -3.016348,3.659353 -6.584739,11.681059 -5.623725,12.642074 0.303293,0.303293 1.920914,-0.15674 3.594713,-1.022295 1.673798,-0.865555 3.403117,-1.545215 3.84293,-1.510356 0.439813,0.03486 -1.67534,1.280239 -4.70034,2.767511 -4.058717,1.995509 -5.58931,3.331673 -5.840811,5.09886 -0.187447,1.317101 -0.976538,3.030456 -1.753537,3.807455 C 8.7087909,59.434066 4,66.868895 4,68.430175 4,70.401229 4.3631141,70.390459 8.2996599,68.302646 z M 12.272364,61 c 0,-2.475 0.195016,-3.4875 0.433369,-2.25 0.238353,1.2375 0.238353,3.2625 0,4.5 -0.238353,1.2375 -0.433369,0.225 -0.433369,-2.25 z m 4.393672,-1 c 0.742026,-4.180464 0.928355,-4.499385 1.602441,-2.742744 0.283554,0.738931 -0.100776,2.445839 -0.854067,3.793128 C 16.090231,63.418727 16.065402,63.383878 16.666036,60 z M 20,52.622445 c 0,-0.207656 0.7875,-0.995156 1.75,-1.75 C 23.336056,49.628574 23.371426,49.663944 22.127555,51.25 20.821186,52.915748 20,53.445479 20,52.622445 z m 4,-1.920595 c 0,-0.897315 1.0125,-2.162794 2.25,-2.812175 l 2.25,-1.180693 -1.989343,2.395509 c -1.094139,1.31753 -2.106639,2.583009 -2.25,2.812176 C 24.117296,52.145833 24,51.599166 24,50.70185 z m 6.030409,-5.329405 c -0.04575,-1.696523 2.646795,-3.581852 4.577277,-3.205021 1.56352,0.3052 1.551674,0.456048 -0.143919,1.832576 -1.061497,0.861752 -1.528145,0.968127 -1.096708,0.25 0.413036,-0.6875 0.296778,-1.25 -0.258352,-1.25 -0.55513,0 -1.468003,0.7875 -2.028608,1.75 -0.560605,0.9625 -1.032966,1.2426 -1.04969,0.622445 z M 27,42.5 C 28.291745,41.125 29.573628,40 29.848628,40 30.123628,40 29.291745,41.125 28,42.5 26.708255,43.875 25.426372,45 25.151372,45 24.876372,45 25.708255,43.875 27,42.5 z M 48.077656,37.747835 C 52.889021,35.704443 55.5,35.797966 55.5,38.013695 c 0,1.141873 -1.357413,1.494529 -5.857558,1.521795 l -5.857558,0.03549 4.292772,-1.823144 z M 54.5,38 c 0.789166,-1.276897 -2.524143,-1.276897 -4.5,0 -1.173233,0.758201 -0.913783,0.97271 1.190983,0.984687 C 52.671024,38.993109 54.160081,38.55 54.5,38 z M 30.56151,34.356782 c 1.101492,-7.470809 4.229281,-8.431393 9.302063,-2.856782 1.751711,1.925 2.611516,3.497155 1.910678,3.493677 -0.700838,-0.0035 -2.040821,-1.353477 -2.977741,-3 -1.665426,-2.926785 -5.039886,-4.026937 -6.266094,-2.042891 -0.32319,0.522933 -0.648374,2.566878 -0.72263,4.542101 -0.07426,1.975224 -0.546164,3.845422 -1.048684,4.155996 -0.540166,0.333841 -0.620941,-1.420759 -0.197592,-4.292101 z M 59,35 C 58.098708,34.41754 57.975367,34.024514 58.690983,34.015313 59.346024,34.006891 60.160081,34.45 60.5,35 c 0.767305,1.241525 0.421123,1.241525 -1.5,0 z M 8.5716344,57.886524 C 11.408168,53.393164 15,45.483246 15,43.730003 15,41.71968 9.028876,48.306124 7.1041398,52.439526 2.8291116,61.62022 3.8417968,65.379071 8.5716344,57.886524 z M 146.29668,44.531425 C 145.30851,43.173709 144.05,42.050391 143.5,42.035163 142.30942,42.0022 136,45.745906 136,46.485302 136,46.768386 138.72101,47 142.04668,47 l 6.04669,0 -1.79669,-2.468575 z M 64.75,139.33772 c 0.6875,-0.27741 1.8125,-0.27741 2.5,0 0.6875,0.27741 0.125,0.50439 -1.25,0.50439 -1.375,0 -1.9375,-0.22698 -1.25,-0.50439 z m -13.9375,-6.02083 c 0.721875,-0.28887 1.584375,-0.25335 1.916667,0.0789 0.332291,0.33229 -0.258334,0.56864 -1.3125,0.52522 -1.164943,-0.048 -1.4019,-0.28494 -0.604167,-0.60416 z M 152.55887,113.5318 c 2.53959,-1.92085 4.02496,-1.9402 2.44113,-0.0318 -0.68469,0.825 -1.9508,1.5 -2.81357,1.5 -1.2558,0 -1.18151,-0.29285 0.37244,-1.4682 z m -93.289838,-1.22479 c 0.972967,-0.25354 2.322967,-0.23687 3,0.037 0.677032,0.27393 -0.119032,0.48137 -1.769032,0.46099 -1.65,-0.0204 -2.203936,-0.2445 -1.230968,-0.49804 z m 4.814301,-0.66337 C 64.3125,111.44764 66.075,110.99827 68,110.64504 c 2.462425,-0.45185 3.055325,-0.35075 2,0.34104 -1.355636,0.88866 -6.908426,1.50578 -5.916667,0.65756 z M 25.26375,110.28242 c 1.520062,-0.22986 3.770062,-0.22371 5,0.0136 1.229937,0.23736 -0.01375,0.42542 -2.76375,0.41792 -2.75,-0.008 -3.756313,-0.20172 -2.23625,-0.43157 z M 199.15789,109 c 0,-1.375 0.22698,-1.9375 0.50439,-1.25 0.27741,0.6875 0.27741,1.8125 0,2.5 -0.27741,0.6875 -0.50439,0.125 -0.50439,-1.25 z M 56.083333,103.69734 c 0.229167,-0.16646 1.562165,-1.01655 2.962217,-1.88909 2.386029,-1.48702 2.554468,-1.46805 2.687851,0.30266 C 61.844661,103.58792 61.198499,104 58.771184,104 57.0637,104 55.854167,103.8638 56.083333,103.69734 z M 64.5,101 c -0.375437,-1.182897 -0.457612,-2.375721 -0.182612,-2.650721 0.275,-0.275 0.807175,0.467824 1.182612,1.650721 0.375437,1.1829 0.457612,2.37572 0.182612,2.65072 C 65.407612,102.92572 64.875437,102.1829 64.5,101 z m 63.75,0.31067 c 0.9625,-0.25152 2.5375,-0.25152 3.5,0 0.9625,0.25153 0.175,0.45733 -1.75,0.45733 -1.925,0 -2.7125,-0.2058 -1.75,-0.45733 z m -6.79545,-2.765215 C 119.02838,96.119293 118.09323,92 119.96862,92 c 0.53273,0 0.71334,0.665222 0.40134,1.478272 -0.33085,0.862203 0.69204,2.737576 2.45447,4.5 1.66195,1.66195 2.58588,3.021728 2.05319,3.021728 -0.53269,0 -2.07307,-1.104545 -3.42307,-2.454545 z m 16.24891,1.40507 c 2.31191,-0.456689 5.12441,-1.323217 6.25,-1.925618 1.1256,-0.602401 2.04654,-0.83148 2.04654,-0.509064 0,1.085405 -6.91059,3.485147 -9.71788,3.374587 -2.12882,-0.0838 -1.79506,-0.30454 1.42134,-0.939905 z m 19.07403,-0.507229 c 1.22238,-0.856187 2.25804,-2.318687 2.30146,-3.25 0.0527,-1.131069 0.25282,-1.259045 0.60262,-0.385432 C 160.257,97.244998 157.32145,101 155.62251,101 c -0.58714,0 -0.0674,-0.70052 1.15498,-1.556704 z M 35.5,91.469004 c -1.65,-1.352488 -4.35,-2.528729 -6,-2.613869 -2.966575,-0.153074 -2.969797,-0.159399 -0.289138,-0.567613 1.76488,-0.268758 3.98735,0.454582 6.368838,2.072845 2.011887,1.367112 4.391999,2.252853 5.289138,1.968314 C 42.27808,91.88172 42.295925,91.958136 41,92.890355 c -1.988874,1.430689 -2.03519,1.418719 -5.5,-1.421351 z m 114.10497,0.173662 c 0.42388,-1.819311 0.22281,-3.131069 -0.55347,-3.610836 -0.9004,-0.556478 -0.80505,-0.912424 0.36465,-1.361282 1.20758,-0.46339 1.58021,0.03808 1.56854,2.110837 -0.008,1.495238 -0.47209,3.393615 -1.03038,4.218615 -0.74614,1.102596 -0.83869,0.74299 -0.34934,-1.357334 z m -79.79247,0.67422 c 0.721875,-0.288871 1.584375,-0.253344 1.916667,0.07895 0.332291,0.332292 -0.258334,0.568641 -1.3125,0.52522 -1.164943,-0.04798 -1.4019,-0.284941 -0.604167,-0.604167 z M 104.5,91.969164 c 3.3,-0.416454 7.78265,-1.704883 9.96144,-2.863176 2.17879,-1.158294 5.32879,-2.075616 7,-2.038494 2.57814,0.05727 2.31872,0.261154 -1.71205,1.345566 -2.61284,0.702941 -5.57327,2.022569 -6.57874,2.932507 -1.3428,1.21521 -3.53286,1.618109 -8.24939,1.517609 L 98.5,92.726352 l 6,-0.757188 z m 55.61428,0.101463 c -0.85973,-0.531342 -0.96201,-1.0467 -0.29014,-1.461939 0.57071,-0.352721 1.33882,-0.154032 1.7069,0.441531 0.91846,1.486099 0.188,2.012205 -1.41676,1.020408 z M 44.75,90.968838 c 1.267593,-0.50951 2.25,-1.765942 2.25,-2.877597 0,-1.085264 0.479314,-2.269439 1.065143,-2.631501 0.692581,-0.428039 0.431143,-1.358857 -0.747443,-2.661179 -1.441621,-1.592973 -2.686151,-1.904422 -6.080943,-1.521779 -2.398702,0.270368 -4.548128,0.02843 -4.907065,-0.552347 -0.377357,-0.610576 -0.148374,-0.730408 0.559604,-0.292854 0.659073,0.40733 1.836186,0.211212 2.615807,-0.435816 1.071311,-0.889109 2.257129,-0.89931 4.855509,-0.04177 1.890909,0.624056 4.720824,0.853305 6.288702,0.509441 2.009674,-0.440757 2.439088,-0.336202 1.455539,0.3544 -1.19353,0.838041 -1.19353,1.04543 0,1.435084 0.767331,0.250512 0.344942,0.27805 -0.938642,0.06119 -1.495372,-0.252635 -2.093134,-0.0049 -1.66391,0.689605 0.368433,0.596138 0.130794,1.733444 -0.528087,2.527347 -0.658881,0.793903 -0.90738,2.200714 -0.55222,3.126245 0.73526,1.916056 -0.969678,3.33495 -3.921994,3.263986 -1.830292,-0.04399 -1.809078,-0.124815 0.25,-0.952463 z m 37.033522,0.292758 c 2.905937,-0.202642 7.405937,-0.200512 10,0.0047 C 94.377585,91.471575 92,91.637373 86.5,91.634769 81,91.632166 78.877585,91.464237 81.783522,91.261596 z m 44.466478,0.0099 c 2.0625,-0.215745 5.4375,-0.215745 7.5,0 2.0625,0.215744 0.375,0.392262 -3.75,0.392262 -4.125,0 -5.8125,-0.176518 -3.75,-0.392262 z M 22.230053,89.75 c -0.55816,-0.6875 -1.178875,-2.134174 -1.379367,-3.214832 -0.200492,-1.080657 -1.890463,-2.993157 -3.755491,-4.25 C 15.230166,81.028326 14.186255,80 14.775391,80 16.643682,80 22,85.107419 22,86.888894 22,87.830002 22.54,89.14 23.2,89.8 c 0.66,0.66 0.9401,1.2 0.622445,1.2 -0.317656,0 -1.034232,-0.5625 -1.592392,-1.25 z M 72.5,88.526995 c 1.65,-0.733463 3.367439,-1.10703 3.816531,-0.830147 1.146608,0.706928 0.667784,0.936454 -3.316531,1.589795 l -3.5,0.573923 3,-1.333571 z M 142.5,89 c 1.1,-0.472686 2.675,-0.859429 3.5,-0.859429 0.94548,0 0.76064,0.317714 -0.5,0.859429 -1.1,0.472686 -2.675,0.859429 -3.5,0.859429 -0.94548,0 -0.76064,-0.317714 0.5,-0.859429 z M 17.116001,87.717776 C 17.052201,86.737552 15.9875,85.528576 14.75,85.031162 13.493434,84.526084 13.162289,84.105547 14,84.078699 c 2.508483,-0.08039 4.223956,1.555057 3.714394,3.541128 -0.43542,1.697098 -0.493687,1.706635 -0.598393,0.09795 z M 93.8125,86.316886 c 0.721875,-0.288871 1.584375,-0.253344 1.916667,0.07895 0.332291,0.332292 -0.258334,0.568641 -1.3125,0.52522 -1.164943,-0.04798 -1.4019,-0.284941 -0.604167,-0.604167 z M 136,86.058292 c 1.925,-0.39144 4.625,-1.033463 6,-1.426716 l 2.5,-0.715006 -2.5,1.506279 c -1.375,0.828454 -4.075,1.470477 -6,1.426717 l -3.5,-0.07956 3.5,-0.71171 z M 101,84.5 c 1.375,-0.786021 3.4,-1.41084 4.5,-1.388487 1.30958,0.02661 0.79177,0.50593 -1.5,1.388487 -4.626947,1.781829 -6.116985,1.781829 -3,0 z M 56.75,83.337719 c 0.6875,-0.277412 1.8125,-0.277412 2.5,0 0.6875,0.277413 0.125,0.504386 -1.25,0.504386 -1.375,0 -1.9375,-0.226973 -1.25,-0.504386 z m 89,0 c 0.6875,-0.277412 1.8125,-0.277412 2.5,0 0.6875,0.277413 0.125,0.504386 -1.25,0.504386 -1.375,0 -1.9375,-0.226973 -1.25,-0.504386 z M 65.25,80.779505 C 64.0125,80.182682 63,79.302764 63,78.824133 c 0,-0.478632 1.125,-0.133111 2.5,0.767824 3.667615,2.403114 3.538837,3.014835 -0.25,1.187548 z M 56.5,79 c 0.339919,-0.55 0.06648,-1 -0.60765,-1 -0.674126,0 -0.990091,-0.235592 -0.702145,-0.523539 0.851826,-0.851826 3.848511,0.651879 3.245034,1.628324 C 58.130939,79.597153 57.431966,80 56.881966,80 56.331966,80 56.160081,79.55 56.5,79 z M 148,78 c -1.375,-1.075541 -2.00724,-1.965534 -1.40499,-1.977764 C 147.19727,76.010006 148.50451,76.9 149.5,78 c 2.28016,2.519549 1.72106,2.519549 -1.5,0 z M 30.75,77.9199 c -1.917149,-1.116637 -2.319739,-3.449749 -0.761454,-4.412822 0.573245,-0.354285 0.730608,0.06122 0.374574,0.989028 -0.366083,0.953997 0.143223,2.173361 1.261455,3.020134 2.178152,1.64939 1.668266,1.884729 -0.874575,0.40366 z M 46,78 c 0,-0.55 0.701558,-1 1.559017,-1 0.857459,0 1.280902,0.45 0.940983,1 -0.339919,0.55 -1.041476,1 -1.559017,1 C 46.423442,79 46,78.55 46,78 z m 85,0 c 0,-0.55 0.47656,-1 1.05902,-1 0.58246,0 0.7809,0.45 0.44098,1 -0.33992,0.55 -0.81648,1 -1.05902,1 C 131.19844,79 131,78.55 131,78 z m 7.75,-2.705733 c 1.2375,-0.238353 3.2625,-0.238353 4.5,0 1.2375,0.238353 0.225,0.433369 -2.25,0.433369 -2.475,0 -3.4875,-0.195016 -2.25,-0.433369 z m -27.86884,-3.512849 c 0.46036,-2.776922 0.60121,-2.917763 0.91609,-0.916083 0.20464,1.300934 -0.0402,2.777573 -0.544,3.281419 -0.55478,0.554777 -0.70153,-0.378117 -0.37209,-2.365336 z m 11.78249,1.983895 c -1.61483,-1.019543 3.35434,-0.82919 5.83635,0.223571 1.58845,0.673751 1.31346,0.813621 -1.33635,0.679715 -1.83499,-0.09273 -3.85999,-0.499208 -4.5,-0.903286 z m 9.23323,0.319578 c 1.12792,-0.714179 0.98351,-1.14264 -0.75,-2.225234 C 129.9661,71.122244 129,70.163681 129,69.729516 c 0,-0.434165 1.35097,0.209424 3.00215,1.430198 2.84056,2.100112 2.61522,3.80966 -0.50215,3.80966 -0.55,0 -0.3714,-0.398017 0.39688,-0.884483 z M 33.25,72.310674 c 0.9625,-0.251527 2.5375,-0.251527 3.5,0 0.9625,0.251528 0.175,0.457323 -1.75,0.457323 -1.925,0 -2.7125,-0.205795 -1.75,-0.457323 z M 47.474609,72.2844 c 2.736035,-0.226781 5.621715,-0.946045 6.412622,-1.598364 1.149675,-0.948224 1.339436,-0.885271 0.946386,0.313964 -0.358256,1.093076 -2.097891,1.526685 -6.412621,1.598364 -5.346077,0.08881 -5.43797,0.05833 -0.946387,-0.313964 z M 138.8125,69.316886 c 0.72187,-0.288871 1.58437,-0.253344 1.91667,0.07895 0.33229,0.332292 -0.25834,0.568641 -1.3125,0.52522 -1.16495,-0.04798 -1.4019,-0.284941 -0.60417,-0.604167 z M 129,66.289111 c 0,-0.574322 0.7875,-1.661822 1.75,-2.416666 1.61876,-1.269516 1.63998,-1.222451 0.28297,0.627555 -0.80687,1.1 -1.59437,2.1875 -1.75,2.416667 C 129.12734,67.145833 129,66.863433 129,66.289111 z m 16.25,-3.978437 c 0.9625,-0.251527 2.5375,-0.251527 3.5,0 0.9625,0.251528 0.175,0.457323 -1.75,0.457323 -1.925,0 -2.7125,-0.205795 -1.75,-0.457323 z M 134,58.559017 c 0,-1.342541 0.36858,-2.668775 0.81906,-2.947187 0.45048,-0.278413 0.6244,0.82003 0.3865,2.440983 C 134.68102,61.626701 134,61.912657 134,58.559017 z m 9.75,-1.291222 c 2.3375,-0.210535 6.1625,-0.210535 8.5,0 2.3375,0.210535 0.425,0.382791 -4.25,0.382791 -4.675,0 -6.5875,-0.172256 -4.25,-0.382791 z M 52,56.073324 c 0,-0.509672 -0.7875,-1.132471 -1.75,-1.383998 -1.31691,-0.344145 -1.19317,-0.486031 0.5,-0.573325 C 52.134889,54.044602 53,54.57674 53,55.5 53,56.325 52.775,57 52.5,57 52.225,57 52,56.582996 52,56.073324 z m 7.5,-3.838637 c -0.55,-0.404078 -1.583079,-1.774033 -2.295731,-3.044345 -1.224951,-2.183493 -1.179304,-2.247349 0.835646,-1.16898 1.172258,0.627373 1.871741,1.400315 1.554407,1.717649 -0.317333,0.317334 -0.07577,1.180875 0.536799,1.91898 1.219112,1.46894 0.935756,1.727861 -0.631121,0.576696 z M 121.60495,48.75 c 2.60206,-4.498826 4.89688,-6.784734 8.63529,-8.601742 4.03415,-1.960748 4.13473,-1.966538 1.89898,-0.109329 C 130.84078,41.117518 129.21308,42 128.5221,42 c -0.69098,0 -2.44751,1.8 -3.9034,4 -2.39264,3.615524 -4.768,5.782997 -3.01375,2.75 z m -44.526003,-1.5 c 0.04716,-1.045438 0.282017,-1.246741 0.583334,-0.5 C 77.939693,47.4375 78.766667,48 79.5,48 c 0.733333,0 1.560307,-0.5625 1.837719,-1.25 0.301317,-0.746741 0.536171,-0.545438 0.583334,0.5 C 81.976138,48.471053 81.244361,49 79.5,49 77.755639,49 77.023862,48.471053 77.078947,47.25 z M 82,44.650194 c 0,-0.231096 1.180406,-1.193606 2.623124,-2.138911 1.442718,-0.945305 2.317655,-1.224479 1.944306,-0.620387 C 85.853975,43.045291 82,45.373573 82,44.650194 z M 74.25,41.779505 C 73.0125,41.182682 72,40.091114 72,39.353799 c 0,-0.89859 0.824242,-0.623903 2.5,0.83315 3.494482,3.038413 3.44194,3.373112 -0.25,1.592556 z m 26.88922,-0.812774 C 99.840785,39.885029 99.246142,39 99.817787,39 c 0.571643,0 1.714353,0.675 2.539353,1.5 1.67837,1.678371 4.64286,2.020088 4.64286,0.535184 0,-0.530649 1.0125,-1.491722 2.25,-2.135718 2.20475,-1.147353 2.20125,-1.117895 -0.17431,1.464817 -2.87189,3.122313 -4.74138,3.264224 -7.93647,0.602448 z M 94.8125,40.316886 c 0.721875,-0.288871 1.584375,-0.253344 1.916667,0.07895 0.332291,0.332292 -0.258334,0.568641 -1.3125,0.52522 -1.164943,-0.04798 -1.4019,-0.284941 -0.604167,-0.604167 z M 88.25,38.421259 C 89.2125,37.277952 90,35.22646 90,33.862389 c 0,-1.364071 0.699825,-3.353638 1.555166,-4.421259 1.502282,-1.875121 1.519285,-1.866853 0.5,0.243129 C 91.474825,30.885601 91,32.953356 91,34.279271 c 0,1.325915 -1.0125,3.267998 -2.25,4.315741 -2.247729,1.903065 -2.248234,1.90289 -0.5,-0.173753 z m 26.39654,-4.024499 c 1.88626,-2.473014 2.68022,-4.614497 2.53121,-6.827196 -0.25118,-3.729554 1.82425,-5.997487 6.32225,-6.908675 2.23663,-0.453087 2.49108,-0.381289 1,0.282162 -1.1,0.48944 -2.7875,1.138356 -3.75,1.442035 C 119.54405,22.765575 119,23.972867 119,26.268447 119,29.50373 114.45598,38 112.72567,38 c -0.4551,0 0.40929,-1.621458 1.92087,-3.60324 z M 155,35.890355 c -1.26612,-0.910777 -1.22714,-0.991244 0.25,-0.516072 0.9625,0.309621 1.75,0.127071 1.75,-0.405668 0,-0.532738 1.2375,-0.907333 2.75,-0.832433 2.35784,0.116762 2.42915,0.197981 0.5,0.569551 -1.2375,0.238353 -2.25,0.852071 -2.25,1.363818 0,1.223853 -1.14459,1.155485 -3,-0.179196 z m -8.67394,-2.473387 c -1.59608,-1.596078 -3.29865,-2.395893 -4.45593,-2.093258 -1.03009,0.269375 -1.62071,0.08174 -1.31249,-0.416969 0.90646,-1.466693 4.08648,-1.040474 5.56953,0.746487 0.75463,0.909276 2.72223,2.241662 4.37244,2.960858 2.68475,1.170069 2.75891,1.311748 0.70494,1.346772 -1.2625,0.02153 -3.45782,-1.123222 -4.87849,-2.54389 z M 68,26.5 c 0,-0.825 0.435877,-1.5 0.968615,-1.5 0.532739,0 0.709594,0.675 0.393011,1.5 C 69.045044,27.325 68.609167,28 68.393011,28 68.176855,28 68,27.325 68,26.5 z M 94.44113,25.555166 C 95.508751,24.699825 96.821251,24 97.357796,24 98.628339,24 98.061032,24.4619 95,25.919712 92.642732,27.042357 92.610824,27.021544 94.44113,25.555166 z M 70.521341,21.023581 c -0.983749,-1.08703 -2.248022,-1.692501 -2.809496,-1.345491 -0.5848,0.361426 -0.716079,0.137778 -0.307337,-0.523582 1.041677,-1.685468 1.87886,-1.389302 3.892177,1.376917 2.156155,2.962473 1.714163,3.243031 -0.775344,0.492156 z M 99,22.622445 c 0,-0.207656 0.7875,-0.995156 1.75,-1.75 1.58606,-1.243871 1.62143,-1.208501 0.37756,0.377555 C 99.821186,22.915748 99,23.445479 99,22.622445 z" + id="path2989" + inkscape:connector-curvature="0" /> + </g> +</svg> diff --git a/_static/nibabel.css b/_static/nibabel.css new file mode 100644 index 0000000000..b8d762deba --- /dev/null +++ b/_static/nibabel.css @@ -0,0 +1,42 @@ +@import url("./sphinxdoc.css"); + +body { + background-color: #E5E2E2; +} + +div.sphinxsidebar { + position: relative; +} + +div.sphinxsidebar h4, div.sphinxsidebar h3 { + background-color: #2F83C8; +} + +h1,h2,h3,h4,h5 { + color: #2F83C8; +} + +h1 { margin-top: 10px; font-size: 200%; } +h2 { font-size: 160%; } +h3 { font-size: 140%; } +h4 { font-size: 120%; } +h5 { font-size: 110%; } +h6 { font-size: 100%; } + +table { + margin: 0 0 0 0; +} + +div.footer { + background-color: #CEC890; +} + + +div.body { + background-color: white; +} + +.sphinxsidebarwrapper { + /* don't let anything exceed sidebar boundaries */ + overflow: hidden; +} diff --git a/_static/nipy-logo-bg-138x120.png b/_static/nipy-logo-bg-138x120.png new file mode 100644 index 0000000000000000000000000000000000000000..73c4ffc124c4947de986d04bfe27ae6538958c78 GIT binary patch literal 29906 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 V+>L!kn0NpH002ovPDHLkV1kB7Xk7pR literal 0 HcmV?d00001 diff --git a/_static/nipy.css b/_static/nipy.css new file mode 100644 index 0000000000..7aa01b7316 --- /dev/null +++ b/_static/nipy.css @@ -0,0 +1,507 @@ +/** + * Alternate Sphinx design + * Originally created by Armin Ronacher for Werkzeug, adapted by Georg Brandl. + */ + +body { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', 'Verdana', sans-serif; + font-size: 14px; + letter-spacing: -0.01em; + line-height: 150%; + text-align: center; + /*background-color: #AFC1C4; */ + background-color: #BFD1D4; + color: black; + padding: 0; + border: 1px solid #aaa; + + margin: 0px 80px 0px 80px; + min-width: 740px; +} + +a { + color: #CA7900; + text-decoration: none; +} + +a:hover { + color: #2491CF; +} + +pre { + font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.95em; + letter-spacing: 0.015em; + padding: 0.5em; + border: 1px solid #ccc; + background-color: #f8f8f8; +} + +td.linenos pre { + padding: 0.5em 0; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +cite, code, tt { + font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.95em; + letter-spacing: 0.01em; +} + +hr { + border: 1px solid #abc; + margin: 2em; +} + +tt { + background-color: #f2f2f2; + border-bottom: 1px solid #ddd; + color: #333; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; + border: 0; +} + +tt.descclassname { + background-color: transparent; + border: 0; +} + +tt.xref { + background-color: transparent; + font-weight: bold; + border: 0; +} + +a tt { + background-color: transparent; + font-weight: bold; + border: 0; + color: #CA7900; +} + +a tt:hover { + color: #2491CF; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.refcount { + color: #060; +} + +dt:target, +.highlight { + background-color: #fbe54e; +} + +dl.class, dl.function { + border-top: 2px solid #888; +} + +dl.method, dl.attribute { + border-top: 1px solid #aaa; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +pre { + line-height: 120%; +} + +pre a { + color: inherit; + text-decoration: underline; +} + +.first { + margin-top: 0 !important; +} + +div.document { + background-color: white; + text-align: left; + background-image: url(contents.png); + background-repeat: repeat-x; +} + +/* +div.documentwrapper { + width: 100%; +} +*/ + +div.clearer { + clear: both; +} + +div.related h3 { + display: none; +} + +div.related ul { + background-image: url(navigation.png); + height: 2em; + list-style: none; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 0; + padding-left: 10px; +} + +div.related ul li { + margin: 0; + padding: 0; + height: 2em; + float: left; +} + +div.related ul li.right { + float: right; + margin-right: 5px; +} + +div.related ul li a { + margin: 0; + padding: 0 5px 0 5px; + line-height: 1.75em; + color: #EE9816; +} + +div.related ul li a:hover { + color: #3CA8E7; +} + +div.body { + margin: 0; + padding: 0.5em 20px 20px 20px; +} + +div.bodywrapper { + margin: 0 240px 0 0; + border-right: 1px solid #ccc; +} + +div.body a { + text-decoration: underline; +} + +div.sphinxsidebar { + margin: 0; + padding: 0.5em 15px 15px 0; + width: 210px; + float: right; + text-align: left; +/* margin-left: -100%; */ +} + +div.sphinxsidebar h4, div.sphinxsidebar h3 { + margin: 1em 0 0.5em 0; + font-size: 0.9em; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border: 1px solid #86989B; + background-color: #AFC1C4; +} + +div.sphinxsidebar ul { + padding-left: 1.5em; + margin-top: 7px; + list-style: none; + padding: 0; + line-height: 130%; +} + +div.sphinxsidebar ul ul { + list-style: square; + margin-left: 20px; +} + +p { + margin: 0.8em 0 0.5em 0; +} + +p.rubric { + font-weight: bold; +} + +h1 { + margin: 0; + padding: 0.7em 0 0.3em 0; + font-size: 1.5em; + color: #11557C; +} + +h2 { + margin: 1.3em 0 0.2em 0; + font-size: 1.35em; + padding: 0; +} + +h3 { + margin: 1em 0 -0.3em 0; + font-size: 1.2em; +} + +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + color: black!important; +} + +h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { + display: none; + margin: 0 0 0 0.3em; + padding: 0 0.2em 0 0.2em; + color: #aaa!important; +} + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, +h5:hover a.anchor, h6:hover a.anchor { + display: inline; +} + +h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, +h5 a.anchor:hover, h6 a.anchor:hover { + color: #777; + background-color: #eee; +} + +table { + border-collapse: collapse; + margin: 0 -0.5em 0 -0.5em; +} + +table td, table th { + padding: 0.2em 0.5em 0.2em 0.5em; +} + +div.footer { + background-color: #E3EFF1; + color: #86989B; + padding: 3px 8px 3px 0; + clear: both; + font-size: 0.8em; + text-align: right; +} + +div.footer a { + color: #86989B; + text-decoration: underline; +} + +div.pagination { + margin-top: 2em; + padding-top: 0.5em; + border-top: 1px solid black; + text-align: center; +} + +div.sphinxsidebar ul.toc { + margin: 1em 0 1em 0; + padding: 0 0 0 0.5em; + list-style: none; +} + +div.sphinxsidebar ul.toc li { + margin: 0.5em 0 0.5em 0; + font-size: 0.9em; + line-height: 130%; +} + +div.sphinxsidebar ul.toc li p { + margin: 0; + padding: 0; +} + +div.sphinxsidebar ul.toc ul { + margin: 0.2em 0 0.2em 0; + padding: 0 0 0 1.8em; +} + +div.sphinxsidebar ul.toc ul li { + padding: 0; +} + +div.admonition, div.warning { + font-size: 0.9em; + margin: 1em 0 0 0; + border: 1px solid #86989B; + background-color: #f7f7f7; +} + +div.admonition p, div.warning p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} + +div.admonition pre, div.warning pre { + margin: 0.4em 1em 0.4em 1em; +} + +div.admonition p.admonition-title, +div.warning p.admonition-title { + margin: 0; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border-bottom: 1px solid #86989B; + font-weight: bold; + background-color: #AFC1C4; +} + +div.warning { + border: 1px solid #940000; +} + +div.warning p.admonition-title { + background-color: #CF0000; + border-bottom-color: #940000; +} + +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + +div.versioninfo { + margin: 1em 0 0 0; + border: 1px solid #ccc; + background-color: #DDEAF0; + padding: 8px; + line-height: 1.3em; + font-size: 0.9em; +} + + +a.headerlink { + color: #c60f0f!important; + font-size: 1em; + margin-left: 6px; + padding: 0 4px 0 4px; + text-decoration: none!important; + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +a.headerlink:hover { + background-color: #ccc; + color: white!important; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +img.inheritance { + border: 0px +} + +form.pfform { + margin: 10px 0 20px 0; +} + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} diff --git a/_static/plot_directive.css b/_static/plot_directive.css new file mode 100644 index 0000000000..d45593c93c --- /dev/null +++ b/_static/plot_directive.css @@ -0,0 +1,16 @@ +/* + * plot_directive.css + * ~~~~~~~~~~~~ + * + * Stylesheet controlling images created using the `plot` directive within + * Sphinx. + * + * :copyright: Copyright 2020-* by the Matplotlib development team. + * :license: Matplotlib, see LICENSE for details. + * + */ + +img.plot-directive { + border: 0; + max-width: 100%; +} diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..7107cec93a979b9a5f64843235a16651d563ce2d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu>-2 m3q%Vub%g%s<8sJhVPMczOq}xhg9DJoz~JfX=d#Wzp$Pyb1r*Kz literal 0 HcmV?d00001 diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 0000000000..691aeb82d0 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,74 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #208050 } /* Literal.Number.Bin */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/reggie.png b/_static/reggie.png new file mode 100644 index 0000000000000000000000000000000000000000..78620d945eeacd2cc7c1795981a1caf1f722e015 GIT binary patch literal 13454 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%0Dg3 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 literal 0 HcmV?d00001 diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 0000000000..7918c3fab3 --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,574 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + // array of [docname, title, anchor, descr, score, filename] + let results = []; + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + results.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // lookup as object + objectTerms.forEach((term) => + results.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + results = results.reverse(); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 0000000000..8a96c69a19 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '<p class="highlight-link">' + + '<a href="javascript:SphinxHighlight.hideSearchWords()">' + + _("Hide Search Matches") + + "</a></p>" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/_static/sphinxdoc.css b/_static/sphinxdoc.css new file mode 100644 index 0000000000..1e9ffe0a40 --- /dev/null +++ b/_static/sphinxdoc.css @@ -0,0 +1,354 @@ +/* + * sphinxdoc.css_t + * ~~~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- sphinxdoc theme. Originally created by + * Armin Ronacher for Werkzeug. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; + font-size: 14px; + letter-spacing: -0.01em; + line-height: 150%; + text-align: center; + background-color: #BFD1D4; + color: black; + padding: 0; + border: 1px solid #aaa; + + margin: 0px 80px 0px 80px; + min-width: 740px; +} + +div.document { + background-color: white; + text-align: left; + background-image: url(contents.png); + background-repeat: repeat-x; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 calc(230px + 10px) 0 0; + border-right: 1px solid #ccc; +} + +div.body { + margin: 0; + padding: 0.5em 20px 20px 20px; +} + +div.related { + font-size: 1em; +} + +div.related ul { + background-image: url(navigation.png); + height: 2em; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} + +div.related ul li { + margin: 0; + padding: 0; + height: 2em; + float: left; +} + +div.related ul li.right { + float: right; + margin-right: 5px; +} + +div.related ul li a { + margin: 0; + padding: 0 5px 0 5px; + line-height: 1.75em; + color: #EE9816; +} + +div.related ul li a:hover { + color: #3CA8E7; +} + +div.sphinxsidebarwrapper { + padding: 0; +} + +div.sphinxsidebar { + padding: 0.5em 15px 15px 0; + width: calc(230px - 20px); + float: right; + font-size: 1em; + text-align: left; +} + +div.sphinxsidebar h3, div.sphinxsidebar h4 { + margin: 1em 0 0.5em 0; + font-size: 1em; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border: 1px solid #86989B; + background-color: #AFC1C4; +} + +div.sphinxsidebar h3 a { + color: white; +} + +div.sphinxsidebar ul { + padding-left: 1.5em; + margin-top: 7px; + padding: 0; + line-height: 130%; +} + +div.sphinxsidebar ul ul { + margin-left: 20px; +} + +div.footer { + background-color: #E3EFF1; + color: #86989B; + padding: 3px 8px 3px 0; + clear: both; + font-size: 0.8em; + text-align: right; +} + +div.footer a { + color: #86989B; + text-decoration: underline; +} + +/* -- body styles ----------------------------------------------------------- */ + +p { + margin: 0.8em 0 0.5em 0; +} + +a { + color: #CA7900; + text-decoration: none; +} + +a:hover { + color: #2491CF; +} + +a:visited { + color: #551A8B; +} + +div.body a { + text-decoration: underline; +} + +h1 { + margin: 0; + padding: 0.7em 0 0.3em 0; + font-size: 1.5em; + color: #11557C; +} + +h2 { + margin: 1.3em 0 0.2em 0; + font-size: 1.35em; + padding: 0; +} + +h3 { + margin: 1em 0 -0.3em 0; + font-size: 1.2em; +} + +div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { + color: black!important; +} + +h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { + display: none; + margin: 0 0 0 0.3em; + padding: 0 0.2em 0 0.2em; + color: #aaa!important; +} + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, +h5:hover a.anchor, h6:hover a.anchor { + display: inline; +} + +h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, +h5 a.anchor:hover, h6 a.anchor:hover { + color: #777; + background-color: #eee; +} + +a.headerlink { + color: #c60f0f!important; + font-size: 1em; + margin-left: 6px; + padding: 0 4px 0 4px; + text-decoration: none!important; +} + +a.headerlink:hover { + background-color: #ccc; + color: white!important; +} + +cite, code, code { + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 0.95em; + letter-spacing: 0.01em; +} + +code { + background-color: #f2f2f2; + border-bottom: 1px solid #ddd; + color: #333; +} + +code.descname, code.descclassname, code.xref { + border: 0; +} + +hr { + border: 1px solid #abc; + margin: 2em; +} + +a code { + border: 0; + color: #CA7900; +} + +a code:hover { + color: #2491CF; +} + +pre { + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 0.95em; + letter-spacing: 0.015em; + line-height: 120%; + padding: 0.5em; + border: 1px solid #ccc; +} + +pre a { + color: inherit; + text-decoration: underline; +} + +td.linenos pre { + padding: 0.5em 0; +} + +div.quotebar { + background-color: #f8f8f8; + max-width: 250px; + float: right; + padding: 2px 7px; + border: 1px solid #ccc; +} + +nav.contents, +aside.topic, +div.topic { + background-color: #f8f8f8; +} + +table { + border-collapse: collapse; + margin: 0 -0.5em 0 -0.5em; +} + +table td, table th { + padding: 0.2em 0.5em 0.2em 0.5em; +} + +div.admonition, div.warning { + font-size: 0.9em; + margin: 1em 0 1em 0; + border: 1px solid #86989B; + background-color: #f7f7f7; + padding: 0; +} + +div.admonition p, div.warning p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} + +div.admonition pre, div.warning pre { + margin: 0.4em 1em 0.4em 1em; +} + +div.admonition p.admonition-title, +div.warning p.admonition-title { + margin: 0; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border-bottom: 1px solid #86989B; + font-weight: bold; + background-color: #AFC1C4; +} + +div.warning { + border: 1px solid #940000; +} + +div.warning p.admonition-title { + background-color: #CF0000; + border-bottom-color: #940000; +} + +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + +div.versioninfo { + margin: 1em 0 0 0; + border: 1px solid #ccc; + background-color: #DDEAF0; + padding: 8px; + line-height: 1.3em; + font-size: 0.9em; +} + +.viewcode-back { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} + +div.code-block-caption { + background-color: #ddd; + color: #222; + border: 1px solid #ccc; +} \ No newline at end of file diff --git a/api.html b/api.html new file mode 100644 index 0000000000..9b9bedc4ca --- /dev/null +++ b/api.html @@ -0,0 +1,362 @@ +<!DOCTYPE html> + +<html lang="en" data-content_root="./"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" /> + + <title>Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +

+ + + + +
+
+
+
+ +
+

API DocumentationΒΆ

+ + + + + + +

nibabel

Read and write access to common neuroimaging file formats, including: ANALYZE_ (plain, SPM99, SPM2 and later), GIFTI_, NIfTI1_, NIfTI2_, `CIFTI-2`_, MINC1_, MINC2_, `AFNI BRIK/HEAD`_, ECAT_ and Philips PAR/REC.

+
+

File FormatsΒΆ

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

analyze

Read / write access to the basic Mayo Analyze format

spm2analyze

Read / write access to SPM2 version of analyze image format

spm99analyze

Read / write access to SPM99 version of analyze image format

cifti2

CIFTI-2 format IO

gifti

GIfTI format IO

freesurfer

Reading functions for freesurfer files

minc1

Read MINC1 format images

minc2

Preliminary MINC2 support

nicom

DICOM reader

nifti1

Read / write access to NIfTI1 image format

nifti2

Read / write access to NIfTI2 image format

ecat

Read ECAT format images

parrec

Read images in PAR/REC format

streamlines

Multiformat-capable streamline format read / write interface

+
+
+

Image UtilitiesΒΆ

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

eulerangles

Module implementing Euler angle rotations and their conversions

funcs

Processor functions for images

imageclasses

Define supported image classes and names

imageglobals

Defaults for images and headers

loadsave

Utilities to load and save image objects

orientations

Utilities for calculating and applying affine orientations

quaternions

Functions to operate on, or return, quaternions

spatialimages

A simple spatial image class

volumeutils

Utility functions for analyze-like formats

+
+
+

Float / integer conversionΒΆ

+ + + + + + + + + +

arraywriters

Array writer objects

casting

Utilities for casting numpy values in various ways

+
+
+

System utilitiesΒΆ

+ + + + + + + + + +

data

Utilities to find files from NIPY data packages

environment

Settings from the system environment relevant to NIPY

+
+
+

Miscellaneous HelpersΒΆ

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

arrayproxy

Array proxy base class

affines

Utility routines for working with points and affine transforms

batteryrunners

Battery runner classes and Report classes

data

Utilities to find files from NIPY data packages

dft

DICOM filesystem tools

fileholders

Fileholder class

filename_parser

Create filename pairs, triplets etc, with expected extensions

fileslice

Utilities for getting array slices out of file-like objects

onetime

Descriptor support for NIPY

openers

Context manager openers for various fileobject types

optpkg

Routines to support optional packages

rstutils

ReStructured Text utilities

tmpdirs

Contexts for with statement providing temporary directories

tripwire

Class to raise error for missing modules or other misfortunes

wrapstruct

Class to wrap numpy structured array

+
+
+

Alphabetical API referenceΒΆ

+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/changelog.html b/changelog.html new file mode 100644 index 0000000000..f4411b4dd3 --- /dev/null +++ b/changelog.html @@ -0,0 +1,2064 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

NiBabel Development ChangelogΒΆ

+

NiBabel is the successor to the much-loved PyNifti package. Here we list the +releases for both packages.

+

The full VCS changelog is available here:

+
+
+
+

Nibabel releasesΒΆ

+

Most work on NiBabel so far has been by Matthew Brett (MB), Chris Markiewicz +(CM), Michael Hanke (MH), Marc-Alexandre CΓ΄tΓ© (MC), Ben Cipollini (BC), Paul +McCarthy (PM), Chris Cheng (CC), Yaroslav Halchenko (YOH), Satra Ghosh (SG), +Eric Larson (EL), Demian Wassermann, Stephan Gerhard and Ross Markello (RM).

+

References like β€œpr/298” refer to github pull request numbers.

+
+

5.2.0 (Monday 11 December 2023)ΒΆ

+

New feature release in the 5.2.x series.

+

This release requires a minimum Python of 3.8 and NumPy 1.20, and has been +tested up to Python 3.12 and NumPy 1.26.

+
+

New featuresΒΆ

+
    +
  • Add generic Pointset and regularly spaced +NDGrid data structures in preparation for coordinate +transformation and resampling (pr/1251) (CM, reviewed by Oscar Esteban)

  • +
+
+
+

EnhancementsΒΆ

+
    +
  • Add copy() method to +ArrayProxy (pr/1255) (CM, reviewed by Paul McCarthy)

  • +
  • Permit to_xml() to pass keyword +arguments to tostring() (pr/1258) +(CM)

  • +
  • Allow user expansion (e.g., ~/...) in strings passed to functions that +accept paths (pr/1260) (Reinder Vos de Wael, reviewed by CM)

  • +
  • Expand CIFTI-2 brain structures to permit synonyms (pr/1256) (CM, reviewed +by Mathias Goncalves)

  • +
  • Annotate SpatialImage as accepting +affine=None argument (pr/1253) (Blake Dewey, reviewed by CM)

  • +
  • Warn on invalid MINC2 spacing declarations, treat as missing (pr/1237) +(Peter Suter, reviewed by CM)

  • +
  • Refactor find_private_element() for improved +readability and maintainability (pr/1228) (MB, reviewed by CM)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Resolve test failure related to randomly generated invalid case (pr/1221) (CM)

  • +
+
+
+

DocumentationΒΆ

+
    +
  • Remove references to NiPy data packages from documentation (pr/1275) +(Dimitri Papadopoulos, reviewed by CM, MB)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Quality of life improvements for CI, including color output and OIDC publishing +(pr/1282) (CM)

  • +
  • Patch for NumPy 2.0 pre-release compatibility (pr/1250) (Mathieu +Scheltienne and EL, reviewed by CM)

  • +
  • Add spellchecking to tox, CI and pre-commit (pr/1266) (CM)

  • +
  • Add py312-dev-x64 environment to Tox to test NumPy 2.0 pre-release +compatibility (pr/1267) (CM, reviewed by EL)

  • +
  • Resurrect tox configuration to cover development workflows and CI checks +(pr/1262) (CM)

  • +
  • Updates for Python 3.12 support (pr/1247, pr/1261, pr/1273) (CM)

  • +
  • Remove uses of deprecated numpy.compat.py3k module (pr/1243) (Eric +Larson, reviewed by CM)

  • +
  • Various fixes for typos and style issues detected by Codespell, pyupgrade and +refurb (pr/1263, pr/1269, pr/1270, pr/1271, pr/1276) (Dimitri Papadopoulos, +reviewed by CM)

  • +
  • Use stable argsorts in PARREC tests to ensure consistent behavior on systems +with AVX512 SIMD instructions and numpy 1.25 (pr/1234) (CM)

  • +
  • Resolve CodeCov submission failures (pr/1224) (CM)

  • +
  • Link to logo with full URL to avoid broken links in PyPI (pr/1218) (CM, +reviewed by Zvi Baratz)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • The nibabel.pydicom_compat module is deprecated and will be removed +in NiBabel 7.0. (pr/1280)

  • +
  • The int_to_float() and as_int() +functions are no longer needed to work around NumPy deficiencies and have been +deprecated (pr/1272) (CM, reviewed by EL)

  • +
+
+
+
+

5.1.0 (Monday 3 April 2023)ΒΆ

+

New feature release in the 5.1.x series.

+
+

EnhancementsΒΆ

+ +
+
+

Bug fixesΒΆ

+
    +
  • Require explicit overrides to write GIFTI files that contain data arrays +with data types not permitted by the GIFTI standard (pr/1199) (CM, reviewed +by Alexis Thual)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Move compression detection logic into a private nibabel._compression +module, resolving unexpected errors from pyzstd. (pr/1212) (CM)

  • +
  • Improved consistency of docstring formatting (pr/1200) (Zvi Baratz, reviewed +by CM)

  • +
  • Modernized README text (pr/1195) (Zvi Baratz, reviewed by CM)

  • +
  • Updated README badges to include package distributions (pr/1192) (Horea +Christian, reviewed by CM)

  • +
  • Removed all dependencies on distutils and setuptools (pr/1190) (CM, +reviewed by Zvi Baratz)

  • +
  • Add a _version.pyi stub to allow mypy to run without building nibabel +(pr/1210) (CM)

  • +
+
+
+
+

5.0.1 (Sunday 12 February 2023)ΒΆ

+

Bug-fix release in the 5.0.x series.

+
+

Bug fixesΒΆ

+
    +
  • Support ragged voxel arrays in +ParcelsAxis (pr/1194) (Michiel Cottaar, +reviewed by CM)

  • +
  • Return to cwd on exception in InTemporaryDirectory +(pr/1184) (CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Add py.typed to module root to enable use of types in downstream +projects (CM, reviewed by Fernando PΓ©rez-Garcia)

  • +
  • Cache git-archive separately from Python packages in GitHub Actions +(pr/1186) (CM, reviewed by Zvi Baratz)

  • +
+
+
+
+

5.0.0 (Monday 9 January 2023)ΒΆ

+

New feature release in the 5.0.x series.

+
+

New featuresΒΆ

+ +
+
+

EnhancementsΒΆ

+
    +
  • Support multiline header fields in TCKFile +(pr/1175) (CM, reviewed by Matt Cieslak)

  • +
  • Make layout order an initialization parameter of +ArrayProxy (pr/1131) (CM, reviewed by MB)

  • +
  • Initial support for type annotations. (pr/1115, pr/1178) (CM, reviewed by +Zvi Baratz)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Handle extension/file-format mismatches implemented incompletely in pr/1013 +(pr/1138) (CM, reviewed by Thomas Phil)

  • +
  • Improve handling of invalid TCK files, which could sometimes cause an +infinite loop (pr/1140) (Anibal Solon, reviewed by CM)

  • +
  • Clean up ECAT test case that left filehandle open and failed to use class +variables (pr/1155) (Dimitri Papadopoulos, reviewed by CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Simplify TCK reading code by assuming files are open in binary mode +(pr/1142) (Anibal Solon, reviewed by MC, CM)

  • +
  • Code support for tests covering deprecated functionality (pr/1159) (CM)

  • +
  • Miscellaneous code cleanups (pr/1148, pr/1149, pr/1153, pr/1154, pr/1156) +(Dimitri Papadopoulos, reviewed by CM)

  • +
  • Update CI to build, test and deploy PyPI artifacts (pr/1134) (CM, reviewed +by MB)

  • +
  • Transition from setup.cfg to pyproject.toml package configuration +(pr/1133) (CM, reviewed by MB)

  • +
  • Addressed race conditions preventing running tests with pytest-xdist. +(pr/1157, pr/1158) (CM, reviewed by Christian Haselgrove)

  • +
  • Apply blue and isort auto-formatters and provide pre-commit configuration +to reduce human burden of style guidelines. (pr/1124, pr/1165, pr/1169) +(CM and Zvi Baratz)

  • +
  • Manage versioning with setuptools_scm (pr/1171) (CM, reviewed by Zvi Baratz)

  • +
  • Reduce installed package size by excluding very large test file (pr/1176) +(CM, reviewed by Zvi Baratz)

  • +
+
+
+

API changes and deprecationsΒΆ

+ +
+
+
+

4.0.2 (Wednesday 31 August 2022)ΒΆ

+

Bug-fix release in the 4.0.x series.

+
+

Bug fixesΒΆ

+
    +
  • Make GiftiMetaData.data a list proxy, deprecate (pr/1127) (CM, reviewed +by Hao-Ting Wang)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Finalize deprecation of ArrayWriter.to_fileobj(nan2zero=...) argument +(pr/1126) (CM)

  • +
+
+
+
+

4.0.1 (Saturday 18 June 2022)ΒΆ

+

Bug-fix release in the 4.0.x series.

+
+

Bug fixesΒΆ

+
    +
  • Finalize 4.0 deprecations, converting tests expecting DeprecationWarning to +expected ExpiredDeprecationError (pr/1117) (CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Suppress new numpy warning on nan-to-int cast (pr/1118) (CM, reviewed by MB)

  • +
+
+
+
+

4.0.0 (Saturday 18 June 2022)ΒΆ

+

New feature release in the 4.0.x series.

+
+

New featuresΒΆ

+
    +
  • nib-convert CLI tool to make image type and data dtype conversion accessible +via the command line. (pr/1113) (CM, reviewed by Ariel Rokem)

  • +
  • Add 'mask', 'compat' and 'smallest' dtype aliases to NIfTI images +to allow for dtype specifications that can depend on the contents of the data. +'mask' is a synonym for uint8. 'compat' will find the nearest +Analyze-compatible (therefore widely supported) dtype that will not truncate +the data. 'smallest' attempts to find the smallest integer dtype that will +contain the data. (pr/1096) (CM, reviewed by Chris Rorden and Josh Teves)

  • +
  • Add dtype arguments to Cifti2Image (pr/1111) (CM)

  • +
  • Allow dtypes to be passed to Analyze-like images at __init__() and +to_filename() to provide better control over output images. (pr/1082) +(CM, following discussions with Chris Rorden, Josh Teves, Jerome Dockes, and MB)

  • +
  • Allow compressed GIFTI images (MB, reviewed by CM)

  • +
  • Add zstd compression support (pr/1005) (Andrew Van, reviewed by CM)

  • +
  • Support ExternalFileBinary GIFTI data arrays (PM, reviewed by CM)

  • +
+
+
+

EnhancementsΒΆ

+
    +
  • Document InTemporaryDirectory as non-thread-safe (pr/1103) (Jacob Roberts, +reviewed by MB)

  • +
  • Unify Caret-XML-style metadata structure (GiftiMetaData, Cifti2MetaData) +as dict-like (pr/1091) (CM, reviewed by Josh Teves and Hao-Ting Wang)

  • +
  • Add __repr__ methods to GIFTI objects (pr/1092) (CM, +reviewed by Josh Teves and Hao-Ting Wang)

  • +
  • Create gzip header deterministically by default (pr/1024) (CM, reviewed by YOH)

  • +
  • Provide clear error message when files with zip extensions don’t match +file contents (pr/1013) (JΓ©rΓ΄me DockΓ¨s, reviewed by CM)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Re-import externals/netcdf.py from scipy to resolve numpy API change (pr/1110) +(CM)

  • +
  • Resize ArraySequence.data without helper function to avoid reference increment +(pr/1093) (MC, reviewed by CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Update submodule URLs to use https over git protocol (pr/1097) (CM)

  • +
  • Published BIAP 9: CoordinateImage API (pr/1084) (CM)

  • +
  • Drop uses of deprecated distutils (pr/1073) (CM, reviewed by MB)

  • +
  • Suppress LGTM false alarm β€œClear-text logging of sensitive information” +(pr/1052) (Dimitri Papadopoulos, reviewed by CM)

  • +
  • Test on Python 3.10 (pr/1047) (CM)

  • +
  • Fix typos found by codespell (pr/1040, pr/1044) +(Dimitri Papadopoulos, reviewed by CM)

  • +
  • Run stable tests weekly, pre-release tests nightly (pr/1025) (CM)

  • +
  • Documentation updates to establish/clarify governance and decision +making (pr/1019, pr/1020, pr/1022, pr/1018, pr/1017, pr/1016) (MB and CM)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • Writing NIfTIs with 64-bit integer dtypes is getting harder. +Passing (u)int64 arrays to Nifti1Image and subclasses will warn unless +a header or dtype option is passed; in the future this will become an +error. +Additionally, passing int or 'int' to set_data_dtype() now raises +an error, requiring an explicit numpy dtype to make 64-bit integer images. +(pr/1082) (CM, following discussions with Chris Rorden, Josh Teves, Jerome Dockes, +and MB)

  • +
  • Drop support for Python 3.6, Numpy < 1.17 (pr/1079) (CM)

  • +
  • Fully removed the following APIs, which have raised errors on use +since 3.0 (pr/980) (CM, reviewed by Jonathan Daniel)

    +
    +
      +
    • nibabel.trackvis

    • +
    • nibabel.volumeutils.calculate_scale

    • +
    • nibabel.volumeutils.can_cast

    • +
    • nibabel.volumeutils.scale_min_max

    • +
    • nibabel.dataobj_images.DataobjImage.get_shape

    • +
    • nibabel.minc1.MincImage (use Minc1Image)

    • +
    • nibabel.minc1.MincFile (use Minc1File)

    • +
    • nibabel.filebasedimages.FileBasedImage.from_files

    • +
    • nibabel.filebasedimages.FileBasedImage.filespec_to_files

    • +
    • nibabel.filebasedimages.FileBasedImage.to_filespec

    • +
    • nibabel.filebasedimages.FileBasedImage.to_files

    • +
    • nibabel.arrayproxy.ArrayProxy.header

    • +
    • keep_file_open=="auto" parameter to load method (now must be boolean)

    • +
    +
    +
  • +
+
+
+
+

3.2.2 (Monday 7 February 2022)ΒΆ

+

Bug fix release in the 3.2.x series.

+
+

Bug fixesΒΆ

+
    +
  • Reshape CIFTI-2 affines to 4x4 when encoded as row-major sequence (pr/1059) +(Andrew Van, reviewed by CM)

  • +
  • Suggest nibabel.save() on calls to deprecated giftiio.write() (pr/1055) +(Anibal Solon, reviewed by CM)

  • +
  • Various bugs and style issues detected by LGTM (pr/1043, pr/1048) +(Dimitri Papadopoulos, reviewed by CM)

  • +
  • Resolve unclosed file warning in GiftiImage (pr/1038) (Lea Waller, reviewed by CM)

  • +
  • Fix typos preventing deprecation warnings from being raised (pr/991) +(Jonathan Daniel, reviewed by MB)

  • +
  • Work around numpy SystemError to maintain expected error types (pr/1051) (CM)

  • +
  • Use more constrained mock when testing optpkg (pr/983) (CM, reviewed by YOH)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Add setuptools requirement to match usage (pr/1009) +(TomΓ‘Ε‘ Hrnčiar, reviewed by CM)

  • +
  • Fix grammar of headings in CoC (pr/996) (MB, reviewed by CM, Ariel Rokem)

  • +
  • Set minimum pydicom to 1.0.0 (pr/1050) (CM)

  • +
  • Submit coverage to codecov via pinned PyPI package (pr/1008) (CM)

  • +
  • Upgrade versioneer to 0.19 (pr/967) (CM)

  • +
  • Migrate to GitHub actions (pr/972) (CM, reviewed by Serge Koudoro)

  • +
+
+
+
+

3.2.1 (Saturday 28 November 2020)ΒΆ

+

Bug fix release in the 3.2.x series.

+
+

MaintenanceΒΆ

+
    +
  • Drop references to builtin types in Numpy namespace like np.float +(pr/964) (EL, reviewed by CM)

  • +
  • Ensure compatibility with Python 3.9 (pr/963) (CM)

  • +
+
+
+
+

3.2.0 (Tuesday 20 October 2020)ΒΆ

+

New feature release in the 3.2.x series.

+
+

New featuresΒΆ

+
    +
  • nib-stats CLI tool to expose new nibabel.imagestats API. Initial +implementation of volume calculations, a la fslstats -V. (Julian Klug, +reviewed by CM and GitHub user 0rC0)

  • +
  • nib-roi CLI tool to crop images and/or flip axes (pr/947) (CM, reviewed +by Chris Cheng and Mathias Goncalves)

  • +
  • Parser for Siemens β€œASCCONV” text format (pr/896) (Brendan Moloney and MB, +reviewed by CM)

  • +
+
+
+

EnhancementsΒΆ

+
    +
  • Drop confusing mention of img.to_filename() in getting started guide +(pr/946) (Fernando PΓ©rez-Garcia, reviewed by MB, CM)

  • +
  • Implement to_bytes()/from_bytes() methods for Cifti2Image +(pr/938) (CM, reviewed by Mathias Goncalves)

  • +
  • Clean up of DICOM documentation (pr/910) (Jonathan Daniel, reviewed by MB)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Use canvas manager API to set title in OrthoSlicer3D (pr/958) (EL, +reviewed by CM)

  • +
  • Record units as seconds parrec2nii; previously set TR to seconds but +retained msec units (pr/931) (CM, reviewed by MB)

  • +
  • Reflect on-disk dimensions in NIfTI-2 view of CIFTI-2 images (pr/930) +(Mathias Goncalves and CM)

  • +
  • Fix outdated Python 2 and Sympy code in DICOM derivations (pr/911) (MB, +reviewed by CM)

  • +
  • Change string with invalid escape to raw string (pr/909) (EL, reviewed +by MB)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Fix typo in docs (pr/955) (Carl Gauthier, reviewed by CM)

  • +
  • Purge nose from nisext tests (pr/934) (MarkΓ©ta CalΓ‘bkovΓ‘, reviewed by CM)

  • +
  • Suppress expected warnings in tests (pr/949) (CM, reviewed by Dorota +Jarecka)

  • +
  • Various cleanups and modernizations (pr/916, pr/917, pr/918, pr/919) +(Jonathan Daniel, reviewed by CM)

  • +
  • SVG logo for improved appearance in with zooming (pr/914) (Jonathan Daniel, +reviewed by CM)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • Drop support for Numpy < 1.13 (pr/922) (CM)

  • +
  • Warn on use of onetime.setattr_on_read, which has been a deprecated +alias of auto_attr (pr/948) (CM, reviewed by Ariel Rokem)

  • +
+
+
+
+

3.1.1 (Friday 26 June 2020)ΒΆ

+

Bug-fix release in the 3.1.x series.

+

These are small compatibility fixes that support ARM64 architecture and +indexed_gzip>=1.3.0.

+
+

Bug fixesΒΆ

+
    +
  • Detect IndexedGzipFile as compressed file type (pr/925) (PM, reviewed by +CM)

  • +
  • Correctly cast nan when testing array_to_file, fixing ARM64 builds +(pr/862) (CM, reviewed by MB)

  • +
+
+
+
+

3.1.0 (Monday 20 April 2020)ΒΆ

+

New feature release in the 3.1.x series.

+
+

New featuresΒΆ

+
    +
  • Conformation function (processing.conform) and CLI tool +(nib-conform) to apply shape, orientation and zooms (pr/853) (Jakub +Kaczmarzyk, reviewed by CM, YOH)

  • +
  • Affine rescaling function (affines.rescale_affine) to update +dimensions and voxel sizes (pr/853) (CM, reviewed by Jakub Kaczmarzyk)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Delay import of h5py until needed (pr/889) (YOH, reviewed by CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Fix typo in documentation (pr/893) (Zvi Baratz, reviewed by CM)

  • +
  • Tests converted from nose to pytest (pr/865 + many sub-PRs) +(Dorota Jarecka, Krzyzstof Gorgolewski, Roberto Guidotti, Anibal Solon, +and Or Duek)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • kw_only_meth/kw_only_func decorators are deprecated (pr/848) +(RM, reviewed by CM)

  • +
+
+
+
+

2.5.2 (Wednesday 8 April 2020)ΒΆ

+

Bug-fix release in the 2.5.x series. This is an extended-support series, +providing bug fixes for Python 2.7 and 3.4.

+

This and all future releases in the 2.5.x series will be incompatible with +Python 3.9. The last compatible series of numpy and scipy are 1.16.x and +1.2.x, respectively.

+

If you are able to upgrade to Python 3, it is recommended to upgrade to +NiBabel 3.

+
+

Bug fixesΒΆ

+
    +
  • Change strings with invalid escapes to raw strings (pr/827) (EL, reviewed +by CM)

  • +
  • Re-import externals/netcdf.py from scipy to resolve numpy deprecation +(pr/821) (CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Set maximum numpy to 1.16.x, maximum scipy to 1.2.x (pr/901) (CM)

  • +
+
+
+
+

3.0.2 (Monday 9 March 2020)ΒΆ

+
+

Bug fixesΒΆ

+
    +
  • Attempt to find versioneer version when building docs (pr/894) (CM)

  • +
  • Delay import of h5py until needed (backport of pr/889) (YOH, reviewed by CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Fix typo in documentation (backport of pr/893) (Zvi Baratz, reviewed by CM)

  • +
  • Set minimum matplotlib to 1.5.3 to ensure wheels are available on all +supported Python versions. (backport of pr/887) (CM)

  • +
  • Remove pyproject.toml for now. (issue/859) (CM)

  • +
+
+
+
+

3.0.1 (Monday 27 January 2020)ΒΆ

+
+

Bug fixesΒΆ

+
    +
  • Test failed by using array method on tuple. (pr/860) (Ben Darwin, reviewed by +CM)

  • +
  • Validate ExpiredDeprecationErrors, promoted by 3.0 release from +DeprecationWarnings. (pr/857) (CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Remove logic accommodating numpy without float16 types. (pr/866) (CM)

  • +
  • Accommodate new numpy dtype strings. (pr/858) (CM)

  • +
+
+
+
+

3.0.0 (Wednesday 18 December 2019)ΒΆ

+
+

New featuresΒΆ

+
    +
  • ArrayProxy __array__() now accepts a dtype parameter, allowing +numpy.array(dataobj, dtype=...) calls, as well as casting directly +with a dtype (for example, numpy.float32(dataobj)) to control the +output type. Scale factors (slope, intercept) are applied, but may be +cast to narrower types, to control memory usage. This is now the basis +of img.get_fdata(), which will scale data in single precision if +the output type is float32. (pr/844) (CM, reviewed by Alejandro +de la Vega, Ross Markello)

  • +
  • GiftiImage method agg_data() to return usable data arrays (pr/793) +(Hao-Ting Wang, reviewed by CM)

  • +
  • Accept os.PathLike objects in place of filenames (pr/610) (Cameron +Riddell, reviewed by MB, CM)

  • +
  • Function to calculate obliquity of affines (pr/815) (Oscar Esteban, +reviewed by MB)

  • +
+
+
+

EnhancementsΒΆ

+
    +
  • Improve testing of data scaling in ArrayProxy API (pr/847) (CM, reviewed +by Alejandro de la Vega)

  • +
  • Document SpatialImage.slicer interface (pr/846) (CM)

  • +
  • get_fdata(dtype=np.float32) will attempt to avoid casting data to +np.float64 when scaling parameters would otherwise promote the data +type unnecessarily. (pr/833) (CM, reviewed by Ross Markello)

  • +
  • ArraySequence now supports a large set of Python operators to combine +or update in-place. (pr/811) (MC, reviewed by Serge Koudoro, Philippe Poulin, +CM, MB)

  • +
  • Warn, rather than fail, on DICOMs with unreadable Siemens CSA tags (pr/818) +(Henry Braun, reviewed by CM)

  • +
  • Improve clarity of coordinate system tutorial (pr/823) (Egor Panfilov, +reviewed by MB)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Sliced Tractograms no longer apply_affine to the original +Tractogram’s streamlines. (pr/811) (MC, reviewed by Serge Koudoro, +Philippe Poulin, CM, MB)

  • +
  • Change strings with invalid escapes to raw strings (pr/827) (EL, reviewed +by CM)

  • +
  • Re-import externals/netcdf.py from scipy to resolve numpy deprecation +(pr/821) (CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Remove replicated metadata for packaged data from MANIFEST.in (pr/845) (CM)

  • +
  • Support Python >=3.5.1, including Python 3.8.0 (pr/787) (CM)

  • +
  • Manage versioning with slightly customized Versioneer (pr/786) (CM)

  • +
  • Reference Nipy Community Code and Nibabel Developer Guidelines in +GitHub community documents (pr/778) (CM, reviewed by MB)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • Fully remove deprecated checkwarns and minc modules. (pr/852) (CM)

  • +
  • The keep_file_open argument to file load operations and ArrayProxys +no longer accepts the value "auto", raising a ValueError. (pr/852) +(CM)

  • +
  • Deprecate ArraySequence.data in favor of ArraySequence.get_data(), +which will return a copy. ArraySequence.data now returns a read-only +view. (pr/811) (MC, reviewed by Serge Koudoro, Philippe Poulin, CM, MB)

  • +
  • Deprecate DataobjImage.get_data() API, to be removed in nibabel 5.0 +(pr/794, pr/809) (CM, reviewed by MB)

  • +
+
+
+
+

2.5.1 (Monday 23 September 2019)ΒΆ

+
+

EnhancementsΒΆ

+
    +
  • Ignore endianness in nib-diff if values match (pr/799) (YOH, reviewed +by CM)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Correctly handle Philips DICOMs w/ derived volume (pr/795) (Mathias +Goncalves, reviewed by CM)

  • +
  • Raise CSA tag limit to 1000, parametrize for future relaxing (pr/798, +backported to 2.5.x in pr/800) (Henry Braun, reviewed by CM, MB)

  • +
  • Coerce data types to match NIfTI intent codes when writing GIFTI data +arrays (pr/806) (CM, reported by Tom Holroyd)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Require h5py 2.10 for Windows + Python < 3.6 to resolve unexpected dtypes +in Minc2 data (pr/804) (CM, reviewed by YOH)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • Deprecate nicom.dicomwrappers.Wrapper.get_affine() in favor of affine +property; final removal in nibabel 4.0 (pr/796) (YOH, reviewed by CM)

  • +
+
+
+
+

2.5.0 (Sunday 4 August 2019)ΒΆ

+

The 2.5.x series is the last with support for either Python 2 or Python 3.4. +Extended support for this series 2.5 will last through December 2020.

+

Thanks for the test ECAT file and fix provided by Andrew Crabb.

+
+

EnhancementsΒΆ

+
    +
  • Add SerializableImage class with to/from_bytes methods (pr/644) (CM, +reviewed by MB)

  • +
  • Check CIFTI-2 data shape matches shape described by header (pr/774) +(Michiel Cottaar, reviewed by CM)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Handle stricter numpy casting rules in tests (pr/768) (CM) +reviewed by PM)

  • +
  • TRK header fields flipped in files written on big-endian systems +(pr/782) (CM, reviewed by YOH, MB)

  • +
  • Load multiframe ECAT images with Python 3 (CM and Andrew Crabb)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Fix CodeCov paths on Appveyor for more accurate coverage (pr/769) (CM)

  • +
  • Move to setuptools and reduce use nisext functions (pr/764) (CM, +reviewed by YOH)

  • +
  • Better handle test setup/teardown (pr/785) (CM, reviewed by YOH)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • Effect threatened warnings and set some deprecation timelines (pr/755) (CM) +* Trackvis methods now default to v2 formats +* nibabel.trackvis scheduled for removal in nibabel 4.0 +* nibabel.minc and nibabel.MincImage will be removed in nibabel 3.0

  • +
+
+
+
+

2.4.1 (Monday 27 May 2019)ΒΆ

+

Contributions from Egor Pafilov, Jath Palasubramaniam, Richard Nemec, and +Dave Allured.

+
+

EnhancementsΒΆ

+
    +
  • Enable mmap, keep_file_open options when loading any +DataobjImage (pr/759) (CM, reviewed by PM)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Ensure loaded GIFTI files expose writable data arrays (pr/750) (CM, +reviewed by PM)

  • +
  • Safer warning registry manipulation when checking for overflows (pr/753) +(CM, reviewed by MB)

  • +
  • Correctly write .annot files with duplicate labels (pr/763) (Richard Nemec +with CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Fix typo in coordinate systems doc (pr/751) (Egor Panfilov, reviewed by +CM)

  • +
  • Replace invalid MINC1 test file with fixed file (pr/754) (Dave Allured +with CM)

  • +
  • Update Sphinx config to support recent Sphinx/numpydoc (pr/749) (CM, +reviewed by PM)

  • +
  • Pacify FutureWarning and DeprecationWarning from h5py, numpy +(pr/760) (CM)

  • +
  • Accommodate Python 3.8 deprecation of collections.MutableMapping +(pr/762) (Jath Palasubramaniam, reviewed by CM)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • Deprecate keep_file_open == 'auto' (pr/761) (CM, reviewed by PM)

  • +
+
+
+
+

2.4.0 (Monday 1 April 2019)ΒΆ

+
+

New featuresΒΆ

+
    +
  • Alternative Axis-based interface for manipulating CIFTI-2 headers +(pr/641) (Michiel Cottaar, reviewed by Demian Wassermann, CM, SG)

  • +
+
+
+

EnhancementsΒΆ

+
    +
  • Accept TCK files produced by tools with other delimiter/EOF defaults +(pr/720) (Soichi Hayashi, reviewed by CM, MB, MC)

  • +
  • Allow BrainModels or Parcels to contain a single vertex in CIFTI +(pr/739) (Michiel Cottaar, reviewed by CM)

  • +
  • Support for NIFTI_XFORM_TEMPLATE_OTHER xform code (pr/743) (CM)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Skip refcheck in ArraySequence construction/extension (pr/719) (Ariel +Rokem, reviewed by CM, MC)

  • +
  • Use safe resizing for ArraySequence extension (pr/724) (CM, reviewed +by MC)

  • +
  • Fix typo in error message (pr/726) (Jon Haitz Legarreta GorroΓ±o, +reviewed by CM)

  • +
  • Support DICOM slice sorting in Python 3 (pr/728) (Samir Reddigari, +reviewed by CM)

  • +
  • Correctly reorient dim_info when reorienting NIfTI images +(Konstantinos Raktivan, CM, reviewed by CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Import updates to reduce upstream deprecation warnings (pr/711, +pr/705, pr/738) (EL, YOH, reviewed by CM)

  • +
  • Delay import of nibabel.testing, nose and mock to speed up +import (pr/699) (CM)

  • +
  • Increase coverage testing, drop coveralls (pr/722, pr/732) (CM)

  • +
  • Add Zenodo metadata, sorted by commits (pr/732) (CM + others)

  • +
  • Update author listing and copyrights (pr/742) (MB, reviewed by CM)

  • +
+
+
+
+

2.3.3 (Wednesday 16 January 2019)ΒΆ

+
+

MaintenanceΒΆ

+
    +
  • Restore six dependency (pr/714) (CM, reviewed by Gael Varoquaux, MB)

  • +
+
+
+
+

2.3.2 (Wednesday 2 January 2019)ΒΆ

+
+

EnhancementsΒΆ

+
    +
  • Enable toggling crosshair with Ctrl-x in OrthoSlicer3D viewer (pr/701) +(Miguel Estevan Moreno, reviewed by CM)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Read .PAR files corresponding to ADC maps (pr/685) (Gregory R. Lee, reviewed +by CM)

  • +
  • Increase maximum number of items read from Siemens CSA format (Igor Solovey, +reviewed by CM, MB)

  • +
  • Check boolean dtypes with numpy.issubdtype(..., np.bool_) (pr/707) +(Jon Haitz Legarreta GorroΓ±o, reviewed by CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Fix small typos in parrec2nii help text (pr/682) (Thomas Roos, reviewed by +MB)

  • +
  • Remove deprecated calls to numpy.asscalar (pr/686) (CM, reviewed by +Gregory R. Lee)

  • +
  • Update QA directives to accommodate Flake8 3.6 (pr/695) (CM)

  • +
  • Update DOI links to use https://doi.org (pr/703) (Katrin Leinweber, +reviewed by CM)

  • +
  • Remove deprecated calls to numpy.fromstring (pr/700) (Ariel Rokem, +reviewed by CM, MB)

  • +
  • Drop distutils support, require bz2file for Python 2.7 (pr/700) +(CM, reviewed by MB)

  • +
  • Replace mutable bytes hack, disabled in numpy pre-release, with +bytearray/readinto strategy (pr/700) (Ariel Rokem, CM, reviewed by +CM, MB)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • Add Opener.readinto method to read file contents into pre-allocated buffers +(pr/700) (Ariel Rokem, reviewed by CM, MB)

  • +
+
+
+
+

2.3.1 (Tuesday 16 October 2018)ΒΆ

+
+

New featuresΒΆ

+
    +
  • nib-diff command line tool for comparing image files (pr/617, pr/672, +pr/678) (CC, reviewed by YOH, Pradeep Raamana and CM)

  • +
+
+
+

EnhancementsΒΆ

+
    +
  • Speed up reading of numeric arrays in CIFTI2 (pr/655) (Michiel Cottaar, +reviewed by CM)

  • +
  • Add ndim property to ArrayProxy and DataobjImage (pr/674) (CM, +reviewed by MB)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Deterministic deduction of slice ordering in degenerate cases (pr/647) +(YOH, reviewed by CM)

  • +
  • Allow 0ms TR in MGH files (pr/653) (EL, reviewed by CM)

  • +
  • Allow for PPC64 little-endian long doubles (pr/658) (MB, reviewed by CM)

  • +
  • Correct construction of FreeSurfer annotation labels (pr/666) (CM, reviewed +by EL, Paul D. McCarthy)

  • +
  • Fix logic for persisting filehandles with indexed-gzip (pr/679) (Paul D. +McCarthy, reviewed by CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Fix semantic error in coordinate systems documentation (pr/646) (Ariel +Rokem, reviewed by CM, MB)

  • +
  • Test on Python 3.7, minor associated fixes (pr/651) (CM, reviewed by Gregory +R. Lee, MB)

  • +
+
+
+
+

2.3 (Tuesday 12 June 2018)ΒΆ

+
+

New featuresΒΆ

+
    +
  • TRK <=> TCK streamlines conversion CLI tools (pr/606) (MC, reviewed by CM)

  • +
  • Image slicing for SpatialImages (pr/550) (CM)

  • +
+
+
+

EnhancementsΒΆ

+
    +
  • Simplfiy MGHImage and add footer fields (pr/569) (CM, reviewed by MB)

  • +
  • Force sform/qform codes to be ints, rather than numpy types (pr/575) (Paul +McCarthy, reviewed by MB, CM)

  • +
  • Auto-fill color table in FreeSurfer annotation file (pr/592) (PM, +reviewed by CM, MB)

  • +
  • Set default intent code for CIFTI2 images (pr/604) (Mathias Goncalves, +reviewed by CM, SG, MB, Tim Coalson)

  • +
  • Raise informative error on empty files (pr/611) (Pradeep Raamana, reviewed +by CM, MB)

  • +
  • Accept degenerate filenames such as .nii (pr/621) (Dimitri +Papadopoulos-Orfanos, reviewed by Yaroslav Halchenko)

  • +
  • Take advantage of IndexedGzipFile drop_handles flag to release +filehandles by default (pr/614) (PM, reviewed by CM, MB)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Preserve first point of LazyTractogram +(pr/588) (MC, reviewed by Nil Goyette, CM, MB)

  • +
  • Stop adding extraneous metadata padding (pr/593) (Jon Stutters, reviewed by +CM, MB)

  • +
  • Accept lower-case orientation codes in TRK files (pr/600) (Kesshi Jordan, +MB, reviewed by MB, MC, CM)

  • +
  • Annotation file reading (pr/592) (PM, reviewed by CM, MB)

  • +
  • Fix buffer size calculation in ArraySequence (pr/597) (Serge Koudoro, +reviewed by MC, MB, Eleftherios Garyfallidis, CM)

  • +
  • Resolve UnboundLocalError in Python 3 (pr/607) (Jakub Kaczmarzyk, +reviewed by MB, CM)

  • +
  • Do not crash on non-ImportError failures in optional imports (pr/618) +(Yaroslav Halchenko, reviewed by CM)

  • +
  • Return original array from get_fdata for array image, if no cast +required (pr/638, MB, reviewed by CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Use SSH address to use key-based auth (pr/587) (CM, reviewed by MB)

  • +
  • Fix doctests for numpy 1.14 array printing (pr/591) (MB, reviewed by CM)

  • +
  • Refactor for pydicom 1.0 API changes (pr/599) (MB, reviewed by CM)

  • +
  • Increase test coverage, remove unreachable code (pr/602) (CM, reviewed by +Yaroslav Halchenko, MB)

  • +
  • Move nib-ls and other programs to a new cmdline module (pr/601, pr/615) +(Chris Cheng, reviewed by MB, Yaroslav Halchenko)

  • +
  • Remove deprecated numpy indexing (EL, reviewed by CM)

  • +
  • Update documentation to encourage get_fdata over get_data (pr/637, +MB, reviewed by CM)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • Support for keep_file_open = 'auto' as a parameter to Opener() will +be deprecated in 2.4, for removal in 3.0. Accordingly, support for +openers.KEEP_FILE_OPEN_DEFAULT = 'auto' will be dropped on the same +schedule.

  • +
  • Drop-in support for indexed_gzip < 0.7 has been removed.

  • +
+
+
+
+

2.2.1 (Wednesday 22 November 2017)ΒΆ

+
+

Bug fixesΒΆ

+
    +
  • Set L/R labels in orthoview correctly (pr/564) (CM)

  • +
  • Defer use of ufunc / memmap test - allows β€œfreezing” (pr/572) (MB, reviewed +by SG)

  • +
  • Fix doctest failures with pre-release numpy (pr/582) (MB, reviewed by CM)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Update documentation around NIfTI qform/sform codes (pr/576) (PM, +reviewed by MB, CM) + (pr/580) (Bennet Fauber, reviewed by PM)

  • +
  • Skip precision test on macOS, newer numpy (pr/583) (MB, reviewed by CM)

  • +
  • Simplify AppVeyor script, removing conda (pr/584) (MB, reviewed by CM)

  • +
+
+
+
+

2.2 (Friday 13 October 2017)ΒΆ

+
+

New featuresΒΆ

+
    +
  • CIFTI support (pr/249) (SG, Michiel Cottaar, BC, CM, Demian Wassermann, MB)

  • +
  • Support for MRtrix TCK streamlines file format (pr/486) (MC, reviewed by +MB, Arnaud Bore, J-Donald Tournier, Jean-Christophe Houde)

  • +
  • Added get_fdata() as default method to retrieve scaled floating point +data from DataobjImages (pr/551) (MB, reviewed by CM, SG)

  • +
+
+
+

EnhancementsΒΆ

+
    +
  • Support for alternative header field name variants in .PAR files +(pr/507) (Gregory R. Lee)

  • +
  • Various enhancements to streamlines API by MC: support for reading TRK +version 1 (pr/512); concatenation of tractograms using +/+= operators +(pr/495); function to concatenate multiple ArraySequence objects (pr/494)

  • +
  • Support for numpy 1.12 (pr/500, pr/502) (MC, MB)

  • +
  • Allow dtype specifiers as fileslice input (pr/485) (MB)

  • +
  • Support β€œheaderless” ArrayProxy specification, enabling memory-efficient +ArrayProxy reshaping (pr/521) (CM)

  • +
  • Allow unknown NIfTI intent codes, add FSL codes (pr/528) (PM)

  • +
  • Improve error handling for img.__getitem__ (pr/533) (Ariel Rokem)

  • +
  • Delegate reorientation to SpatialImage classes (pr/544) (Mark Hymers, CM, +reviewed by MB)

  • +
  • Enable using indexed_gzip to reduce memory usage when reading from +gzipped NIfTI and MGH files (pr/552) (PM, reviewed by MB, CM)

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Miscellaneous MINC reader fixes (pr/493) (Robert D. Vincent, reviewed by CM, +MB)

  • +
  • Fix corner case in wrapstruct.get (pr/516) (PM, reviewed by +CM, MB)

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Fix documentation errors (pr/517, pr/536) (Fernando Perez, Venky Reddy)

  • +
  • Documentation update (pr/514) (Ivan Gonzalez)

  • +
  • Update testing to use pre-release builds of dependencies (pr/509) (MB)

  • +
  • Better warnings when nibabel not on path (pr/503) (MB)

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • header argument to ArrayProxy.__init__ is renamed to spec

  • +
  • Deprecation of header property of ArrayProxy object, for removal in +3.0

  • +
  • wrapstruct.get now returns entries evaluating False, instead of None

  • +
  • DataobjImage.get_data to be deprecated April 2018, scheduled for removal +April 2020

  • +
+
+
+
+

2.1 (Monday 22 August 2016)ΒΆ

+
+

New featuresΒΆ

+
    +
  • New API for managing streamlines and their different file formats. This +adds a new module nibabel.streamlines that will eventually deprecate +the current trackvis reader found in nibabel.trackvis (pr/391) (MC, +reviewed by Jean-Christophe Houde, Bago Amirbekian, Eleftherios +Garyfallidis, Samuel St-Jean, MB);

  • +
  • A prototype image viewer using matplotlib (pr/404) (EL, based on a +proto-prototype by Paul Ivanov) (Reviewed by Gregory R. Lee, MB);

  • +
  • Functions for image resampling and smoothing using scipy ndimage (pr/255) +(MB, reviewed by EL, BC);

  • +
  • Add ability to write FreeSurfer morphology data (pr/414) (CM, BC, reviewed +by BC);

  • +
  • Read and write support for DICOM tags in NIfTI Extended Header using +pydicom (pr/296) (Eric Kastman).

  • +
+
+
+

EnhancementsΒΆ

+
    +
  • Extensions to FreeSurfer module to fix reading and writing of FreeSurfer +geometry data (pr/460) (Alexandre Gramfort, Jaakko LeppΓ€kangas, reviewed +by EL, CM, MB);

  • +
  • Various improvements to PAR / REC handling by Gregory R. Lee: supporting +multiple TR values (pr/429); output of volume labels (pr/427); fix for +some diffusion files (pr/426); option for more sophisticated sorting of +volumes (pr/409);

  • +
  • Original trackvis reader will now allow final streamline to have fewer +points than the number declared in the header, with strict=False +argument to read function;

  • +
  • Helper function to return voxel sizes from an affine matrix (pr/413);

  • +
  • Fixes to DICOM multiframe reading to avoid assumptions on the position of +the multiframe index (pr/439) (Eric M. Baker);

  • +
  • More robust handling of β€œCSA” private information in DICOM files (pr/393) +(Brendan Moloney);

  • +
  • More explicit error when trying to read image from non-existent file +(pr/455) (Ariel Rokem);

  • +
  • Extension to nib-ls command to show image statistics (pr/437) and other +header files (pr/348) (Yarik Halchenko).

  • +
+
+
+

Bug fixesΒΆ

+
    +
  • Fixes to rotation order to generate affine matrices of PAR / REC files (MB, +Gregory R Lee).

  • +
+
+
+

MaintenanceΒΆ

+
    +
  • Dropped support for Pythons 2.6 and 3.2;

  • +
  • Comprehensive refactor and generalization of surface / GIFTI file support +with improved API and extended tests (pr/352-355, pr/360, pr/365, pr/403) +(BC, reviewed by CM, MB);

  • +
  • Refactor of image classes (pr/328, pr/329) (BC, reviewed by CM);

  • +
  • Better Appveyor testing on new Python versions (pr/446) (Ariel Rokem);

  • +
  • Fix shebang lines in scripts for correct install into virtualenvs via pip +(pr/434);

  • +
  • Various fixes for numpy, matplotlib, and PIL / Pillow compatibility (CM, +Ariel Rokem, MB);

  • +
  • Improved test framework for warnings (pr/345) (BC, reviewed by CM, MB);

  • +
  • New decorator to specify start and end versions for deprecation warnings +(MB, reviewed by CM);

  • +
  • Write qform affine matrix to NIfTI images output by parrec2nii (pr/478) +(Jasper J.F. van den Bosch, reviewed by Gregory R. Lee, MB).

  • +
+
+
+

API changes and deprecationsΒΆ

+
    +
  • Minor API breakage in original (rather than new) trackvis reader. We are now +raising a DataError if there are too few streamlines in the file, +instead of a HeaderError. We are raising a DataError if the track +is truncated when strict=True (the default), rather than a TypeError +when trying to create the points array.

  • +
  • Change sform code that parrec2nii script writes to NIfTI images; change +from 2 (β€œaligned”) to 1 (β€œscanner”);

  • +
  • Deprecation of get_header, get_affine method of image objects for +removal in version 4.0;

  • +
  • Removed broken from_filespec method from image objects, and deprecated +from_filespec method of ECAT image objects for removal in 4.0;

  • +
  • Deprecation of class_map instance in imageclasses module in favor of +new image class attributes, for removal in 4.0;

  • +
  • Deprecation of ext_map instance in imageclasses module in favor of +new image loading API, for removal in 4.0;

  • +
  • Deprecation of Header class in favor of SpatialHeader, for removal +in 4.0;

  • +
  • Deprecation of BinOpener class in favor of more generic Opener +class, for removal in 4.0;

  • +
  • Deprecation of GiftiMetadata methods get_metadata and get_rgba; +GiftiDataArray methods get_metadata, get_labeltable, +set_labeltable; GiftiImage methods get_meta, set_meta. All +these deprecated in favor of corresponding properties, for removal in 4.0;

  • +
  • Deprecation of giftiio read and write functions in favor of +nibabel load and save functions, for removal in 4.0;

  • +
  • Deprecation of gifti.data_tag function, for removal in 4.0;

  • +
  • Deprecation of write-access to GiftiDataArray.num_dim, and new error +when trying to set invalid values for num_dim. We will remove +write-access in 4.0;

  • +
  • Deprecation of GiftiDataArray.from_array in favor of GiftiDataArray +constructor, for removal in 4.0;

  • +
  • Deprecation of GiftiDataArray to_xml_open, to_xml_close methods in +favor of to_xml method, for removal in 4.0;

  • +
  • Deprecation of parse_gifti_fast.Outputter class in favor of +GiftiImageParser, for removal in 4.0;

  • +
  • Deprecation of parse_gifti_fast.parse_gifti_file function in favor of +GiftiImageParser.parse method, for removal in 4.0;

  • +
  • Deprecation of loadsave functions guessed_image_type and +which_analyze_type, in favor of new API where each image class tests the +file for compatibility during load, for removal in 4.0.

  • +
+
+
+
+

2.0.2 (Monday 23 November 2015)ΒΆ

+
    +
  • Fix for integer overflow on large images (pr/325) (MB);

  • +
  • Fix for Freesurfer nifti files with unusual dimensions (pr/332) (Chris +Markiewicz);

  • +
  • Fix typos on benchmarks and tests (pr/336, pr/340, pr/347) (Chris +Markiewicz);

  • +
  • Fix Windows install script (pr/339) (MB);

  • +
  • Support for Python 3.5 (pr/363) (MB) and numpy 1.10 (pr/358) (Chris +Markiewicz);

  • +
  • Update pydicom imports to permit version 1.0 (pr/379) (Chris Markiewicz);

  • +
  • Workaround for Python 3.5.0 gzip regression (pr/383) (Ben Cipollini).

  • +
  • tripwire.TripWire object now raises subclass of AttributeError when trying +to get an attribute, rather than a direct subclass of Exception. This +prevents Python 3.5 triggering the tripwire when doing inspection prior to +running doctests.

  • +
  • Minor API change for tripwire.TripWire object; code that checked for +AttributeError will now also catch TripWireError.

  • +
+
+
+

2.0.1 (Saturday 27 June 2015)ΒΆ

+

Contributions from Ben Cipollini, Chris Markiewicz, Alexandre Gramfort, +Clemens Bauer, github user freec84.

+
    +
  • Bugfix release with minor new features;

  • +
  • Added axis parameter to concat_images (pr/298) (Ben Cipollini);

  • +
  • Fix for unsigned integer data types in ECAT images (pr/302) (MB, test data +and issue report from Github user freec84);

  • +
  • Added new ECAT and Freesurfer data files to automated testing;

  • +
  • Fix for Freesurfer labels error on early numpies (pr/307) (Alexandre +Gramfort);

  • +
  • Fixes for PAR / REC header parsing (pr/312) (MB, issue reporting and test +data by Clemens C. C. Bauer);

  • +
  • Workaround for reading Freesurfer ico7 surface files (pr/315) (Chris +Markiewicz);

  • +
  • Changed to github pages for doc hosting;

  • +
  • Changed docs to point to neuroimaging@python.org mailing list.

  • +
+
+
+

2.0.0 (Tuesday 9 December 2014)ΒΆ

+

This release had large contributions from Eric Larson, Brendan Moloney, +Nolan Nichols, Basile Pinsard, Chris Johnson and Nikolaas N. Oosterhof.

+
    +
  • New feature, bugfix release with minor API breakage;

  • +
  • Minor API breakage: default write of NIfTI / Analyze image data offset +value. The data offset is the number of bytes from the beginning of file +to skip before reading the image data. Nibabel behavior changed from +keeping the value as read from file, to setting the offset to zero on +read, and setting the offset when writing the header. The value of the +offset will now be the minimum value necessary to make room for the header +and any extensions when writing the file. You can override the default +offset by setting value explicitly to some value other than zero. To read +the original data offset as read from the header, use the offset +property of the image dataobj attribute;

  • +
  • Minor API breakage: data scaling in NIfTI / Analyze now set to NaN when +reading images. Data scaling refers to the data intercept and slope +values in the NIfTI / Analyze header. To read the original data scaling +you need to look at the slope and inter properties of the image +dataobj attribute. You can set scaling explicitly by setting the +slope and intercept values in the header to values other than NaN;

  • +
  • New API for managing image caching; images have an in_memory property +that is true if the image data has been loaded into cache, or is already +an array in memory; get_data has new keyword argument caching to +specify whether the cache should be filled by get_data;

  • +
  • Images now have properties dataobj, affine, header. We will +slowly phase out the get_affine and get_header image methods;

  • +
  • The image dataobj can be sliced using an efficient algorithm to avoid +reading unnecessary data from disk. This makes it possible to do very +efficient reads of single volumes from a time series;

  • +
  • NIfTI2 read / write support;

  • +
  • Read support for MINC2;

  • +
  • Much extended read support for PAR / REC, largely due to work from Eric +Larson and Gregory R. Lee on new code, advice and code review. Thanks also +to Jeff Stevenson and Bennett Landman for helpful discussion;

  • +
  • parrec2nii script outputs images in LAS voxel orientation, which +appears to be necessary for compatibility with FSL dtifit / +fslview diffusion analysis pipeline;

  • +
  • Preliminary support for Philips multiframe DICOM images (thanks to Nolan +Nichols, Ly Nguyen and Brendan Moloney);

  • +
  • New function to save Freesurfer annotation files (by Github user ohinds);

  • +
  • Method to return MGH format vox2ras_tkr affine (Eric Larson);

  • +
  • A new API for reading unscaled data from NIfTI and other images, using +img.dataobj.get_unscaled(). Deprecate previous way of doing this, +which was to read data with the read_img_data function;

  • +
  • Fix for bug when replacing NaN values with zero when writing floating +point data as integers. If the input floating point data range did not +include zero, then NaN would not get written to a value corresponding to +zero in the output;

  • +
  • Improvements and bug fixes to image orientation calculation and DICOM +wrappers by Brendan Moloney;

  • +
  • Bug fixes writing GIfTI files. We were using a base64 encoding that didn’t +match the spec, and the wrong field name for the endian code. Thanks to +Basile Pinsard and Russ Poldrack for diagnosis and fixes;

  • +
  • Bug fix in freesurfer.read_annot with orig_ids=False when annot +contains vertices with no label (Alexandre Gramfort);

  • +
  • More tutorials in the documentation, including introductory tutorial on +DICOM, and on coordinate systems;

  • +
  • Lots of code refactoring, including moving to common code-base for Python +2 and Python 3;

  • +
  • New mechanism to add images for tests via git submodules.

  • +
+
+
+

1.3.0 (Tuesday 11 September 2012)ΒΆ

+

Special thanks to Chris Johnson, Brendan Moloney and JB Poline.

+
    +
  • New feature and bugfix release

  • +
  • Add ability to write Freesurfer triangle files (Chris Johnson)

  • +
  • Relax threshold for detecting rank deficient affines in orientation +detection (JB Poline)

  • +
  • Fix for DICOM slice normal numerical error (issue #137) (Brendan Moloney)

  • +
  • Fix for Python 3 error when writing zero bytes for offset padding

  • +
+
+
+

1.2.2 (Wednesday 27 June 2012)ΒΆ

+
    +
  • Bugfix release

  • +
  • Fix longdouble tests for Debian PPC (thanks to Yaroslav Halchecko for +finding and diagnosing these errors)

  • +
  • Generalize longdouble tests in the hope of making them more robust

  • +
  • Disable saving of float128 nifti type unless platform has real IEEE +binary128 longdouble type.

  • +
+
+
+

1.2.1 (Wednesday 13 June 2012)ΒΆ

+

Particular thanks to Yaroslav Halchecko for fixes and cleanups in this +release.

+
    +
  • Bugfix release

  • +
  • Make compatible with pydicom 0.9.7

  • +
  • Refactor, rename nifti diagnostic script to nib-nifti-dx

  • +
  • Fix a bug causing an error when analyzing affines for orientation, when the +affine contained all 0 columns

  • +
  • Add missing dicomfs script to installation list and rename to +nib-dicomfs

  • +
+
+
+

1.2.0 (Sunday 6 May 2012)ΒΆ

+

This release had large contributions from Krish Subramaniam, Alexandre +Gramfort, Cindee Madison, FΓ©lix C. Morency and Christian Haselgrove.

+
    +
  • New feature and bugfix release

  • +
  • Freesurfer format support by Krish Subramaniam and Alexandre Gramfort.

  • +
  • ECAT read write support by Cindee Madison and FΓ©lix C. Morency.

  • +
  • A DICOM fuse filesystem by Christian Haselgrove.

  • +
  • Much work on making data scaling on read and write more robust to rounding +error and overflow (MB).

  • +
  • Import of nipy functions for working with affine transformation matrices.

  • +
  • Added methods for working with nifti sform and qform fields by Bago +Amirbekian and MB, with useful discussion by Brendan Moloney.

  • +
  • Fixes to read / write of RGB analyze images by Bago Amirbekian.

  • +
  • Extensions to concat_images by Yannick Schwartz.

  • +
  • A new nib-ls script to display information about neuroimaging files, and +various other useful fixes by Yaroslav Halchenko.

  • +
+
+
+

1.1.0 (Thursday 28 April 2011)ΒΆ

+

Special thanks to Chris Burns, Jarrod Millman and Yaroslav Halchenko.

+
    +
  • New feature release

  • +
  • Python 3.2 support

  • +
  • Substantially enhanced gifti reading support (Stephan Gerhard)

  • +
  • Refactoring of trackvis read / write to allow reading and writing of voxel +points and mm points in tracks. Deprecate use of negative voxel sizes; +set voxel_order field in trackvis header. Thanks to Chris Filo +Gorgolewski for pointing out the problem and Ruopeng Wang in the trackvis +forum for clarifying the coordinate system of trackvis files.

  • +
  • Added routine to give approximate array orientation in form such as β€˜RAS’ +or β€˜LPS’

  • +
  • Fix numpy dtype hash errors for numpy 1.2.1

  • +
  • Other bug fixes as for 1.0.2

  • +
+
+
+

1.0.2 (Thursday 14 April 2011)ΒΆ

+
    +
  • Bugfix release

  • +
  • Make inference of data type more robust to changes in numpy dtype hashing

  • +
  • Fix incorrect thresholds in quaternion calculation (thanks to Yarik H for +pointing this one out)

  • +
  • Make parrec2nii pass over errors more gracefully

  • +
  • More explicit checks for missing or None field in trackvis and other +classes - thanks to Marc-Alexandre Cote

  • +
  • Make logging and error level work as expected - thanks to Yarik H

  • +
  • Loading an image does not change qform or sform - thanks to Yarik H

  • +
  • Allow 0 for nifti scaling as for spec - thanks to Yarik H

  • +
  • nifti1.save now correctly saves single or pair images

  • +
+
+
+

1.0.1 (Wednesday 23 Feb 2011)ΒΆ

+
    +
  • Bugfix release

  • +
  • Fix bugs in tests for data package paths

  • +
  • Fix leaks of open filehandles when loading images (thanks to Gael +Varoquaux for the report)

  • +
  • Skip rw tests for SPM images when scipy not installed

  • +
  • Fix various windows-specific file issues for tests

  • +
  • Fix incorrect reading of byte-swapped trackvis files

  • +
  • Workaround for odd numpy dtype comparisons leading to header errors for +some loaded images (thanks to Cindee Madison for the report)

  • +
+
+
+

1.0.0 (Thursday, 13, Oct 2010)ΒΆ

+
    +
  • This is the first public release of the NiBabel package.

  • +
  • NiBabel is a complete rewrite of the PyNifti package in pure python. It was +designed to make the code simpler and easier to work with. Like PyNifti, +NiBabel has fairly comprehensive NIfTI read and write support.

  • +
  • Extended support for SPM Analyze images, including orientation affines from +matlab .mat files.

  • +
  • Basic support for simple MINC 1.0 files (MB). Please let us know if you +have MINC files that we don’t support well.

  • +
  • Support for reading and writing PAR/REC images (MH)

  • +
  • parrec2nii script to convert PAR/REC images to NIfTI format (MH)

  • +
  • Very preliminary, limited and highly experimental DICOM reading support (MB, +Ian Nimmo Smith).

  • +
  • Some functions (nibabel.funcs) for basic image shape changes, including +the ability to transform to the image with data closest to the canonical +image orientation (first axis left-to-right, second back-to-front, third +down-to-up) (MB, Jonathan Taylor)

  • +
  • Gifti format read and write support (preliminary) (Stephen Gerhard)

  • +
  • Added utilities to use nipy-style data packages, by rip then edit of nipy +data package code (MB)

  • +
  • Some improvements to release support (Jarrod Millman, MB, Fernando Perez)

  • +
  • Huge downward step in the quality and coverage by the docs, caused by MB, +mostly fixed by a lot of good work by MH.

  • +
  • NiBabel will not work with Python < 2.5, and we haven’t even tested it with +Python 3. We will get to it soon…

  • +
+
+
+
+

PyNifti releasesΒΆ

+

Modifications are done by Michael Hanke, if not indicated otherwise. β€˜Closes’ +statement IDs refer to the Debian bug tracking system and can be queried by +visiting the URL:

+
http://bugs.debian.org/<bug id>
+
+
+
+

0.20100706.1 (Tue, 6 Jul 2010)ΒΆ

+
    +
  • Bugfix: NiftiFormat.vx2s() used the qform not the sform. Thanks to Tom +Holroyd for reporting.

  • +
+
+
+

0.20100412.1 (Mon, 12 Apr 2010)ΒΆ

+
    +
  • Bugfix: Unfortunate interaction between Python garbage collection and C +library caused memory problems. Thanks to Yaroslav Halchenko for the +diagnose and fix.

  • +
+
+
+

0.20090303.1 (Tue, 3 Mar 2009)ΒΆ

+
    +
  • Bugfix: Updating the NIfTI header from a dictionary was broken.

  • +
  • Bugfix: Removed left-over print statement in extension code.

  • +
  • Bugfix: Prevent saving of bogus β€˜None.nii’ images when the filename +was previously assign, before calling NiftiImage.save() (Closes: #517920).

  • +
  • Bugfix: Extension length was to short for all edata whose length matches +n*16-8, for all integer n.

  • +
+
+
+

0.20090205.1 (Thu, 5 Feb 2009)ΒΆ

+
    +
  • This release is the first in a series that aims stabilize the API and +finally result in PyNIfTI 1.0 with full support of the NIfTI1 standard.

  • +
  • The whole package was restructured. The included renaming +nifti.nifti(image,format,clibs) to nifti.(image,format,clibs). Redirect +modules make sure that existing user code will not break, but they will +issue a DeprecationWarning and will be removed with the release of PyNIfTI +1.0.

  • +
  • Added a special extension that can embed any serializable Python object +into the NIfTI file header. The contents of this extension is +automatically expanded upon request into the .meta attribute of each +NiftiImage. When saving files to disk the content of the dictionary is also +automatically dumped into this extension. +Embedded meta data is not loaded automatically, since this has security +implications, because code from the file header is actually executed. +The documentation explicitly mentions this risk.

  • +
  • Added NiftiExtensions. This is a container-like +handler to access and manipulate NIfTI1 header extensions.

  • +
  • Exposed MemMappedNiftiImage in the root module.

  • +
  • Moved cropImage() into the utils module.

  • +
  • From now on Sphinx is used to generate the documentation. This includes a +module reference that replaces that old API reference.

  • +
  • Added methods vx2q() and +vx2s() to convert voxel indices into +coordinates defined by qform or sform respectively.

  • +
  • Updating the cal_min and cal_max values in the NIfTI header when +saving a file is now conditional, but remains enabled by default.

  • +
  • Full set of methods to query and modify axis units. This includes +expanding the previous xyzt_units field in the header dictionary into +editable xyz_unit and time_unit fields. The former xyzt_units field +is no longer available. See: +getXYZUnit(), +setXYZUnit(), +getTimeUnit(), +setTimeUnit(), +xyz_unit, +time_unit

  • +
  • Full set of methods to query and manuipulate qform and sform codes. See: +getQFormCode(), +setQFormCode(), +getSFormCode(), +setSFormCode(), +qform_code, +sform_code

  • +
  • Each image instance is now able to generate a human-readable dump of its +most important header information via __str__().

  • +
  • NiftiImage objects can now be pickled.

  • +
  • Switched to NumPy’s distutils for building the package. Cleaned and +simplified the build procedure. Added optimization flags to SWIG call.

  • +
  • nifti.image.NiftiImage.filename can now also be used to assign a +filename.

  • +
  • Introduced nifti.__version__ as canonical version string.

  • +
  • Removed updateQFormFromQuarternion() from the list of public methods of +NiftiFormat. This is an internal method that +should not be used in user code. However, a redirect to the new method +will remain in-place until PyNIfTI 1.0.

  • +
  • Bugfix: getScaledData() returns a +unmodified data array if slope is set to zero (as required by the NIfTI +standard). Thanks to Thomas Ross for reporting.

  • +
  • Bugfix: Unicode filenames are now handled properly, as long as they do not +contain pure-unicode characters (since the NIfTI library does not support +them). Thanks to GaΓ«l Varoquaux for reporting this issue.

  • +
+
+
+

0.20081017.1 (Fri, 17 Oct 2008)ΒΆ

+
    +
  • Updated included minimal copy of the nifticlibs to version 1.1.0.

  • +
  • Few changes to the Makefiles to enhance Posix compatibility. Thanks to +Chris Burns.

  • +
  • When building on non-Debian systems, only add include and library paths +pointing to the local nifticlibs copy, when it is actually built. +On Debian system the local copy is still not used at all, as a proper +nifticlibs package is guaranteed to be available.

  • +
  • Added minimal setup_egg.py for setuptools users. Thanks to GaΓ«l Varoquaux.

  • +
  • PyNIfTI now does a proper wrapping of the image data with NumPy arrays, +which no longer leads to accidental memory leaks, when accessing array +data that has not been copied before (e.g. via the data property of +NiftiImage). Thanks to GaΓ«l Varoquaux for mentioning this possibility.

  • +
+
+
+

0.20080710.1 (Thu, 7 Jul 2008)ΒΆ

+
    +
  • Bugfix: Pointer bug introduced by switch to new NumPy API in 0.20080624 +Thanks to Christopher Burns for fixing it.

  • +
  • Bugfix: Honored DeprecationWarning: sync() -> flush() for memory mapped +arrays. Again thanks to Christopher Burns.

  • +
  • More unit tests and other improvements (e.g. fixed circular imports) done +by Christopher Burns.

  • +
+
+
+

0.20080630.1 (Tue, 30 Jun 2008)ΒΆ

+
    +
  • Bugfix: NiftiImage caused a memory leak by not calling the NiftiFormat +destructor.

  • +
  • Bugfix: Merged bashism-removal patch from Debian packaging.

  • +
+
+
+

0.20080624.1 (Tue, 24 Jun 2008)ΒΆ

+
    +
  • Converted all documentation (including docstrings) into the restructured +text format.

  • +
  • Improved Makefile.

  • +
  • Included configuration and Makefile support for profiling, API doc +generation (via epydoc) and code quality checks (with PyLint).

  • +
  • Consistently import NumPy as N.

  • +
  • Bugfix: Proper handling of [qs]form codes, which previously have not been +handled at all. Thanks to Christopher Burns for pointing it out.

  • +
  • Bugfix: Make NiftiFormat work without setFilename(). Thanks to Benjamin +Thyreau for reporting.

  • +
  • Bugfix: setPixDims() stored meaningless values.

  • +
  • Use new NumPy API and replace deprecated function calls +(PyArray_FromDimsAndData).

  • +
  • Initial support for memory mapped access to uncompressed NIfTI files +(MemMappedNiftiImage).

  • +
  • Add a proper Makefile and setup.cfg for compiling PyNIfTI under Windows +with MinGW.

  • +
  • Include a minimal copy of the most recent nifticlibs (just libniftiio and +znzlib; version 1.0), to lower the threshold to build PyNIfTI on systems +that do not provide a developer package for those libraries.

  • +
+
+
+

0.20070930.1 (Sun, 30 Sep 2007)ΒΆ

+ +
+
+

0.20070917.1 (Mon, 17 Sep 2007)ΒΆ

+
    +
  • Bugfix: Can now update NIfTI header data when no filename is set +(Closes: #442175).

  • +
  • Unloading of image data without a filename set is no checked and prevented +as it would damage data integrity and the image data could not be +recovered.

  • +
  • Added β€˜pixdim’ property (Yaroslav Halchenko).

  • +
+
+
+

0.20070905.1 (Wed, 5 Sep 2007)ΒΆ

+
    +
  • Fixed a bug in the qform/quaternion handling that caused changes to the +qform to vanish when saving to file (Yaroslav Halchenko).

  • +
  • Added more unit tests.

  • +
  • β€˜dim’ vector in the NIfTI header is now guaranteed to only contain +non-zero elements. This caused problems with some applications.

  • +
+
+
+

0.20070803.1 (Fri, 3 Aug 2007)ΒΆ

+
    +
  • Does not depend on SciPy anymore.

  • +
  • Initial steps towards a unittest suite.

  • +
  • pynifti_pst can now print the peristimulus signal matrix for a single +voxel (onsets x time) for easier processing of this information in +external applications.

  • +
  • utils.getPeristimulusTimeseries() can now be used to compute mean and +variance of the signal (among others).

  • +
  • pynifti_pst is able to compute more than just the mean peristimulus +timeseries (e.g. variance and standard deviation).

  • +
  • Set default image description when saving a file if none is present.

  • +
  • Improved documentation.

  • +
+
+
+

0.20070425.1 (Wed, 25 Apr 2007)ΒΆ

+
    +
  • Improved documentation. Added note about the special usage of the header +property. Also added notes about the relevant properties in the docstring +of the corresponding accessor methods.

  • +
  • Added property and accessor methods to access/modify the repetition time +of timeseries (dt).

  • +
  • Added functions to manipulate the pixdim values.

  • +
  • Added utils.py with some utility functions.

  • +
  • Added functions/property to determine the bounding box of an image.

  • +
  • Fixed a bug that caused a corrupted sform matrix when converting a NumPy +array and a header dictionary into a NIfTI image.

  • +
  • Added script to compute peristimulus timeseries (pynifti_pst).

  • +
  • Package now depends on python-scipy.

  • +
+
+
+

0.20070315.1 (Thu, 15 Mar 2007)ΒΆ

+
    +
  • Removed functionality for β€œNiftiImage.save() raises an IOError +exception when writing the image file fails.” (Yaroslav Halchenko)

  • +
  • Added ability to force a filetype when setting the filename or saving +a file.

  • +
  • Reverse the order of the β€˜header’ and β€˜load’ argument in the NiftiImage +constructor. β€˜header’ is now first as it seems to be used more often.

  • +
  • Improved the source code documentation.

  • +
  • Added getScaledData() method to NiftiImage that returns a copy of the data +array that is scaled with the slope and intercept stored in the NIfTI +header.

  • +
+
+
+

0.20070301.2 (Thu, 1 Mar 2007)ΒΆ

+
    +
  • Fixed wrong link to the source tarball in README.html.

  • +
+
+
+

0.20070301.1 (Thu, 1 Mar 2007)ΒΆ

+
    +
  • Initial upload to the Debian archive. (Closes: #413049)

  • +
  • NiftiImage.save() raises an IOError exception when writing the image file +fails.

  • +
  • Added extent, volextent, and timepoints properties to NiftiImage +class (Yaroslav Halchenko).

  • +
+
+
+

0.20070220.1 (Tue, 20 Feb 2007)ΒΆ

+
    +
  • NiftiFile class is renamed to NiftiImage.

  • +
  • SWIG-wrapped libniftiio functions are no available in the nifticlib +module.

  • +
  • Fixed broken NiftiImage from Numpy array constructor.

  • +
  • Added initial documentation in README.html.

  • +
  • Fulfilled a number of Yarik’s wishes ;)

  • +
+
+
+

0.20070214.1 (Wed, 14 Feb 2007)ΒΆ

+
    +
  • Does not depend on libfslio anymore.

  • +
  • Up to seven-dimensional dataset are supported (as much as NIfTI can do).

  • +
  • The complete NIfTI header dataset is modifiable.

  • +
  • Most image properties are accessible via class attributes and accessor +methods.

  • +
  • Improved documentation (but still a long way to go).

  • +
+
+
+

0.20061114 (Tue, 14 Nov 2006)ΒΆ

+
    +
  • Initial release.

  • +
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/coordinate_systems.html b/coordinate_systems.html new file mode 100644 index 0000000000..91a3a856e6 --- /dev/null +++ b/coordinate_systems.html @@ -0,0 +1,928 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Coordinate systems and affinesΒΆ

+

A nibabel (and nipy) image is the association of three things:

+
    +
  • The image data array: a 3D or 4D array of image data

  • +
  • An affine array that tells you the position of the image array data in +a reference space.

  • +
  • image metadata (data about the data) describing the image, usually in the +form of an image header.

  • +
+

This document describes how the affine array describes the position of the +image data in a reference space. On the way we will define what we mean by +reference space, and the reference spaces that Nibabel uses.

+
+

Introducing SomeoneΒΆ

+

We have scanned someone called β€œSomeone”, and we have a two MRI images of +their brain, a single EPI volume, and a structural scan. In general we never +use the person’s name in the image filenames, but we make an +exception in this case:

+ +

We can load up the EPI image to get the image data array:

+
>>> import nibabel as nib
+>>> epi_img = nib.load('downloads/someones_epi.nii.gz')
+>>> epi_img_data = epi_img.get_fdata()
+>>> epi_img_data.shape
+(53, 61, 33)
+
+
+

Then we have a look at slices over the first, second and third dimensions of +the array.

+
>>> import matplotlib.pyplot as plt
+>>> def show_slices(slices):
+...    """ Function to display row of image slices """
+...    fig, axes = plt.subplots(1, len(slices))
+...    for i, slice in enumerate(slices):
+...        axes[i].imshow(slice.T, cmap="gray", origin="lower")
+>>>
+>>> slice_0 = epi_img_data[26, :, :]
+>>> slice_1 = epi_img_data[:, 30, :]
+>>> slice_2 = epi_img_data[:, :, 16]
+>>> show_slices([slice_0, slice_1, slice_2])
+>>> plt.suptitle("Center slices for EPI image")  
+
+
+

(png, hires.png, pdf)

+
+_images/coordinate_systems-2.png +
+

We collected an anatomical image in the same session. We can load that image +and look at slices in the three axes:

+
>>> anat_img = nib.load('downloads/someones_anatomy.nii.gz')
+>>> anat_img_data = anat_img.get_fdata()
+>>> anat_img_data.shape
+(57, 67, 56)
+>>> show_slices([anat_img_data[28, :, :],
+...              anat_img_data[:, 33, :],
+...              anat_img_data[:, :, 28]])
+>>> plt.suptitle("Center slices for anatomical image")  
+
+
+
+_images/coordinate_systems-3_00.png +
+

(png, hires.png, pdf)ΒΆ

+
+
+
+_images/coordinate_systems-3_01.png +
+

(png, hires.png, pdf)ΒΆ

+
+
+

As is usually the case, we had a different field of view for the anatomical +scan, and so the anatomical image has a different shape, size, and orientation +in the magnet.

+
+
+

Voxel coordinates are coordinates in the image data arrayΒΆ

+

As y’all know, a voxel is a pixel with volume.

+

In the code above, slice_0 from the EPI data is a 2D slice from a 3D +image. The plot of the EPI slices displays the slices in grayscale (graded +between black for the minimum value, white for the maximum). Each pixel in +the slice grayscale image also represents a voxel, because this 2D image +represents a slice from the 3D image with a certain thickness.

+

The 3D array is therefore also a voxel array. As for any array, we can select +particular values by indexing. For example, we can get the value for the +middle voxel in the EPI data array like this:

+
>>> n_i, n_j, n_k = epi_img_data.shape
+>>> center_i = (n_i - 1) // 2  # // for integer division
+>>> center_j = (n_j - 1) // 2
+>>> center_k = (n_k - 1) // 2
+>>> center_i, center_j, center_k
+(26, 30, 16)
+>>> center_vox_value = epi_img_data[center_i, center_j, center_k]
+>>> center_vox_value
+81.5492877960205...
+
+
+

The values (26, 30, 16) are indices into the data array epi_img_data. (26, +30, 16) is therefore a β€˜voxel coordinate’ - a coordinate into the voxel array.

+

A coordinate is a set of numbers giving positions relative to a set of axes. +In this case 26 is a position on the first array axis, where the axis is of +length epi_img_data.shape[0], and therefore goes from 0 to 52 +(epi_img_data.shape == (53, 61, 33)). Similarly 30 gives a position on +the second axis (0 to 60) and 16 is the position on the third axis (0 to 32).

+
+
+

Voxel coordinates and points in spaceΒΆ

+

The voxel coordinate tells us almost nothing about where the data came from +in terms of position in the scanner. For example, let’s say we have the voxel +coordinate (26, 30, 16). Without more information we have no idea whether +this voxel position is on the left or right of the brain, or came from the +left or right of the scanner.

+

This is because the scanner allows us to collect voxel data in almost any +arbitrary position and orientation within the magnet.

+

In the case of Someone’s EPI, we took transverse slices at a moderate angle to +the floor to ceiling direction. This localizer image from the scanner console +has a red box that shows the position of the slice block for +someones_epi.nii.gz and a blue box for the slice block of +someones_anatomy.nii.gz:

+_images/localizer.png +

The localizer is oriented to the magnet, so that the left and right borders of +the image are parallel to the floor of the scanner room, with the left border +being towards the floor and the right border towards the ceiling.

+

You will see from the labels on the localizer that the center of the EPI voxel +data block (at 26, 30, 16 in epi_img_data) is not quite at the center of +magnet bore (the magnet isocenter).

+

We have an anatomical and an EPI scan, and later on we will surely want to be +able to relate the data from someones_epi.nii.gz to +someones_anatomy.nii.gz. We can’t easily do this at the moment, because +we collected the anatomical image with a different field of view and +orientation to the EPI image, so the voxel coordinates in the EPI image refer +to different locations in the magnet to the voxel coordinates in the +anatomical image.

+

We solve this problem by keeping track of the relationship of voxel +coordinates to some reference space. In particular, the affine array +stores the relationship between voxel coordinates in the image data array and +coordinates in the reference space. We store the relationship of voxel +coordinates from someones_epi.nii.gz and the reference space, and also the +(different) relationship of voxel coordinates in someones_anatomy.nii.gz +to the same reference space. Because we know the relationship of (voxel +coordinates to the reference space) for both images, we can use this +information to relate voxel coordinates in someones_epi.nii.gz to spatially +equivalent voxel coordinates in someones_anatomy.nii.gz.

+
+
+

The scanner-subject reference spaceΒΆ

+

What does β€œspace” mean in the phrase β€œreference space”? The space is defined +by an ordered set of axes. For our 3D spatial world, it is a set of 3 +independent axes.

+

We can decide what space we want to use, by choosing these axes. We need to +choose the origin of the axes, their direction and their units.

+

To start with, we define a set of three orthogonal scanner axes.

+
+

The scanner axesΒΆ

+
    +
  • The origin of the axes is at the magnet isocenter. This is coordinate (0, 0, +0) in our reference space. All three axes pass through the isocenter.

  • +
  • The units for all three axes are millimeters.

  • +
  • Imagine an observer standing behind the scanner looking through the magnet +bore towards the end of the scanner bed. Imagine a line traveling towards +the observer through the center of the magnet bore, parallel to the bed, +with the zero point at the magnet isocenter, and positive values closer to +the observer. Call this line the scanner-bore axis.

  • +
  • Draw a line traveling from the scanner room floor up through the magnet +isocenter towards the ceiling, at right angles to the scanner bore axis. +0 is at isocenter and positive values are towards the ceiling. Call this +the scanner-floor/ceiling axis.

  • +
  • Draw a line at right angles to the other two lines, traveling from the +observer’s left, parallel to the floor, and through the magnet isocenter to +the observer’s right. 0 is at isocenter and positive values are to the +right. Call this the scanner-left/right.

  • +
+

If we make the axes have order (scanner left-right; scanner floor-ceiling; +scanner bore) then we have an ordered set of 3 axes and therefore the +definition of a 3D space. Call the first axis the β€œX” axis, the second β€œY” +and the third β€œZ”. A coordinate of \((x, y, z) = (10, -5, -3)\) in this space +refers to the point in space 10mm to the (fictional observer’s) right of +isocenter, 5mm towards the floor from the isocenter, and 3mm towards the foot +of the scanner bed. This reference space is sometimes known as β€œscanner XYZ”. +It was the standard reference space for the predecessor to DICOM, called ACR / +NEMA 2.0.

+
+
+

From scanner to subjectΒΆ

+

If the subject is lying in the usual position for a brain scan, face up +and head first in the scanner, then scanner-left/right is also the left-right +axis of the subject’s head, scanner-floor/ceiling is the posterior-anterior +axis of the head and scanner-bore is the inferior-superior axis of the head.

+

Sometimes the subject is not lying in the standard position. For example, the +subject may be lying with their face pointing to the right (in terms of the +scanner-left/right axis). In that case β€œscanner XYZ” will not tell us about +the subject’s left and right, but only the scanner left and right. We might +prefer to know where we are in terms of the subject’s left and right.

+

To deal with this problem, most reference spaces use subject- or patient- +centered scanner coordinate systems. In these systems, the axes are still the +scanner axes above, but the ordering and direction of the axes comes from the +position of the subject. The most common subject-centered scanner coordinate +system in neuroimaging is called β€œscanner RAS” (right, anterior, superior). +Here the scanner axes are reordered and flipped so that the first axis is the +scanner axis that is closest to the left to right axis of the subject, the +second is the closest scanner axis to the posterior-anterior axis of the +subject, and the third is the closest scanner axis to the inferior-superior +axis of the subject. For example, if the subject was lying face to the right +in the scanner, then the first (X) axis of the reference system would be +scanner-floor/ceiling, but reversed so that positive values are towards the +floor. This axis goes from left to right in the subject, with positive values +to the right. The second (Y) axis would be scanner-left/right +(posterior-anterior in the subject), and the Z axis would be scanner-bore +(inferior-superior).

+
+
+

Naming reference spacesΒΆ

+

Reading names of reference spaces can be confusing because of different +meanings that authors use for the same terms, such as β€˜left’ and β€˜right’.

+

We are using the term β€œRAS” to mean that the axes are (in terms of the +subject): left to Right; posterior to Anterior; and inferior to Superior, +respectively. Although it is common to call this convention β€œRAS”, it is not +quite universal, because some use β€œR”, β€œA” and β€œS” in β€œRAS” to mean that the +axes starts on the right, anterior, superior of the subject, rather than +ending on the right, anterior, superior. In other words, they would use +β€œRAS” to refer to a coordinate system we would call β€œLPI”. To be safe, we’ll +call our interpretation of the RAS convention β€œRAS+”, meaning that Right, +Anterior, Superior are all positive values on these axes.

+

Some people also use β€œright” to mean the right hand side when an observer +looks at the front of the scanner, from the foot the scanner bed. +Unfortunately, this means that you have to read coordinate system definitions +carefully if you are not familiar with a particular convention. We nibabel / +nipy folks agree with most of our brain imaging friends and many of our +enemies in that we always use β€œright” to mean the subject’s right.

+
+
+
+

Voxel coordinates are in voxel spaceΒΆ

+

We have not yet made this explicit, but voxel coordinates are also in a space. +In this case the space is defined by the three voxel axes (first axis, second +axis, third axis), where 0, 0, 0 is the center of the first voxel in the +array and the units on the axes are voxels. Voxel coordinates are therefore +defined in a reference space called voxel space.

+
+
+

The affine matrix as a transformation between spacesΒΆ

+

We have voxel coordinates (in voxel space). We want to get scanner RAS+ +coordinates corresponding to the voxel coordinates. We need a coordinate +transform to take us from voxel coordinates to scanner RAS+ coordinates.

+

In general, we have some voxel space coordinate \((i, j, k)\), and we want to +generate the reference space coordinate \((x, y, z)\).

+

Imagine we had solved this, and we had a coordinate transform function \(f\) +that accepts a voxel coordinate and returns a coordinate in the reference +space:

+
+\[(x, y, z) = f(i, j, k)\]
+

\(f\) accepts a coordinate in the input space and returns a coordinate in the +output space. In our case the input space is voxel space and the output +space is scanner RAS+.

+

In theory \(f\) could be a complicated non-linear function, but in practice, we +know that the scanner collects data on a regular grid. This means that the +relationship between \((i, j, k)\) and \((x, y, z)\) is linear (actually +affine), and can be encoded with linear (actually affine) transformations +comprising translations, rotations and zooms (wikipedia linear transform, +wikipedia affine transform).

+

Scaling (zooming) in three dimensions can be represented by a diagonal 3 by 3 +matrix. Here’s how to zoom the first dimension by \(p\), the second by \(q\) and +the third by \(r\) units:

+
+\[\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} = +\begin{bmatrix} +p i\\ +q j\\ +r k\\ +\end{bmatrix} = +\begin{bmatrix} +p & 0 & 0 \\ +0 & q & 0 \\ +0 & 0 & r \\ +\end{bmatrix} +\begin{bmatrix} +i\\ +j\\ +k\\ +\end{bmatrix}\end{split}\]
+

A rotation in three dimensions can be represented as a 3 by 3 rotation +matrix (wikipedia rotation matrix). For example, here is a rotation by +\(\theta\) radians around the third array axis:

+
+\[\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} = +\begin{bmatrix} +\cos(\theta) & -\sin(\theta) & 0 \\ +\sin(\theta) & \cos(\theta) & 0 \\ +0 & 0 & 1 \\ +\end{bmatrix} +\begin{bmatrix} +i\\ +j\\ +k\\ +\end{bmatrix}\end{split}\]
+

This is a rotation by \(\phi\) radians around the second array axis:

+
+\[\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} = +\begin{bmatrix} +\cos(\phi) & 0 & \sin(\phi) \\ +0 & 1 & 0 \\ +-\sin(\phi) & 0 & \cos(\phi) \\ +\end{bmatrix} +\begin{bmatrix} +i\\ +j\\ +k\\ +\end{bmatrix}\end{split}\]
+

A rotation of \(\gamma\) radians around the first array axis:

+
+\[\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} = +\begin{bmatrix} +1 & 0 & 0 \\ +0 & \cos(\gamma) & -\sin(\gamma) \\ +0 & \sin(\gamma) & \cos(\gamma) \\ +\end{bmatrix} +\begin{bmatrix} +i\\ +j\\ +k\\ +\end{bmatrix}\end{split}\]
+

Zoom and rotation matrices can be combined by matrix multiplication.

+

Here’s a scaling of \(p, q, r\) units followed by a rotation of \(\theta\) radians +around the third axis followed by a rotation of \(\phi\) radians around the +second axis:

+
+\[\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} = +\begin{bmatrix} +\cos(\phi) & 0 & \sin(\phi) \\ +0 & 1 & 0 \\ +-\sin(\phi) & 0 & \cos(\phi) \\ +\end{bmatrix} +\begin{bmatrix} +\cos(\theta) & -\sin(\theta) & 0 \\ +\sin(\theta) & \cos(\theta) & 0 \\ +0 & 0 & 1 \\ +\end{bmatrix} +\begin{bmatrix} +p & 0 & 0 \\ +0 & q & 0 \\ +0 & 0 & r \\ +\end{bmatrix} +\begin{bmatrix} +i\\ +j\\ +k\\ +\end{bmatrix}\end{split}\]
+

This can also be written:

+
+\[ \begin{align}\begin{aligned}\begin{split}M = +\begin{bmatrix} +\cos(\phi) & 0 & \sin(\phi) \\ +0 & 1 & 0 \\ +-\sin(\phi) & 0 & \cos(\phi) \\ +\end{bmatrix} +\begin{bmatrix} +\cos(\theta) & -\sin(\theta) & 0 \\ +\sin(\theta) & \cos(\theta) & 0 \\ +0 & 0 & 1 \\ +\end{bmatrix} +\begin{bmatrix} +p & 0 & 0 \\ +0 & q & 0 \\ +0 & 0 & r \\ +\end{bmatrix}\end{split}\\\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} = M +\begin{bmatrix} +i\\ +j\\ +k\\ +\end{bmatrix}\end{split}\end{aligned}\end{align} \]
+

This might be obvious because the matrix multiplication is the result of +applying each transformation in turn on the coordinates output from the +previous transformation. Combining the transformations into a single matrix +\(M\) works because matrix multiplication is associative – \(ABCD = (ABC)D\).

+

A translation in three dimensions can be represented as a length 3 vector to +be added to the length 3 coordinate. For example, a translation of \(a\) units +on the first axis, \(b\) on the second and \(c\) on the third might be written +as:

+
+\[\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} = +\begin{bmatrix} +i\\ +j\\ +k\\ +\end{bmatrix} + +\begin{bmatrix} +a \\ +b \\ +c \\ +\end{bmatrix}\end{split}\]
+

We can write our function \(f\) as a combination of matrix multiplication by +some 3 by 3 rotation / zoom matrix \(M\) followed by addition of a 3 by 1 +translation vector \((a, b, c)\)

+
+\[\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} = M +\begin{bmatrix} +i\\ +j\\ +k\\ +\end{bmatrix} + +\begin{bmatrix} +a\\ +b\\ +c\\ +\end{bmatrix}\end{split}\]
+

We could record the parameters necessary for \(f\) as the 3 by 3 matrix, \(M\) +and the 3 by 1 vector \((a, b, c)\).

+

In fact, the 4 by 4 image affine array does include exactly this +information. If \(m_{i,j}\) is the value in row \(i\) column \(j\) of matrix \(M\), +then the image affine matrix \(A\) is:

+
+\[\begin{split}A = +\begin{bmatrix} +m_{1,1} & m_{1,2} & m_{1,3} & a \\ +m_{2,1} & m_{2,2} & m_{2,3} & b \\ +m_{3,1} & m_{3,2} & m_{3,3} & c \\ +0 & 0 & 0 & 1 \\ +\end{bmatrix}\end{split}\]
+

Why the extra row of \([0, 0, 0, 1]\)? We need this row because we have +rephrased the combination of rotations / zooms and translations as a +transformation in homogeneous coordinates (see wikipedia homogeneous +coordinates). This is a trick that allows us to put the translation part +into the same matrix as the rotations / zooms, so that both translations and +rotations / zooms can be applied by matrix multiplication. In order to make +this work, we have to add an extra 1 to our input and output coordinate +vectors:

+
+\[\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +1\\ +\end{bmatrix} = +\begin{bmatrix} +m_{1,1} & m_{1,2} & m_{1,3} & a \\ +m_{2,1} & m_{2,2} & m_{2,3} & b \\ +m_{3,1} & m_{3,2} & m_{3,3} & c \\ +0 & 0 & 0 & 1 \\ +\end{bmatrix} +\begin{bmatrix} +i\\ +j\\ +k\\ +1\\ +\end{bmatrix}\end{split}\]
+

This results in the same transformation as applying \(M\) and \((a, b, c)\) +separately. One advantage of encoding transformations this way is that we can +combine two sets of [rotations, zooms, translations] by matrix multiplication +of the two corresponding affine matrices.

+

In practice, although it is common to combine 3D transformations using 4 by 4 +affine matrices, we usually apply the transformations by breaking up the +affine matrix into its component \(M\) matrix and \((a, b, c)\) vector and doing:

+
+\[\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} = M +\begin{bmatrix} +i\\ +j\\ +k\\ +\end{bmatrix} + +\begin{bmatrix} +a\\ +b\\ +c\\ +\end{bmatrix}\end{split}\]
+

As long as the last row of the 4 by 4 is \([0, 0, 0, 1]\), applying the +transformations in this way is mathematically the same as using the full 4 by +4 form, without the inconvenience of adding the extra 1 to our input and +output vectors.

+
+
+

The inverse of the affine gives the mapping from scanner to voxelΒΆ

+

The affine arrays we have described so far have another pleasant property β€” +they are usually invertible. As y’all know, the inverse of a matrix \(A\) is +the matrix \(A^{-1}\) such that \(I = A^{-1} A\), where \(I\) is the identity +matrix. Put another way:

+
+\[ \begin{align}\begin{aligned}\begin{split}\begin{bmatrix} +x\\ +y\\ +z\\ +1\\ +\end{bmatrix} = A +\begin{bmatrix} +i\\ +j\\ +k\\ +1\\ +\end{bmatrix}\end{split}\\\begin{split}A^{-1}\begin{bmatrix} +x\\ +y\\ +z\\ +1\\ +\end{bmatrix} = A^{-1} A +\begin{bmatrix} +i\\ +j\\ +k\\ +1\\ +\end{bmatrix}\end{split}\\\begin{split}\begin{bmatrix} +i\\ +j\\ +k\\ +1\\ +\end{bmatrix} = A^{-1} +\begin{bmatrix} +x\\ +y\\ +z\\ +1\\ +\end{bmatrix}\end{split}\end{aligned}\end{align} \]
+

That means that the inverse of the affine matrix gives the transformation from +scanner RAS+ coordinates to voxel coordinates in the image data.

+

Now imagine we have affine array \(A\) for someones_epi.nii.gz, and affine array +\(B\) for someones_anatomy.nii.gz. \(A\) gives the mapping from voxels in the +image data array of someones_epi.nii.gz to millimeters in scanner RAS+. \(B\) +gives the mapping from voxels in image data array of +someones_anatomy.nii.gz to the same scanner RAS+. Now let’s say we have +a particular voxel coordinate \((i, j, k)\) in the data array of +someones_epi.nii.gz, and we want to find the voxel in +someones_anatomy.nii.gz that is in the same spatial position. Call this +matching voxel coordinate \((i', j', k')\) . We first apply the transform from +someones_epi.nii.gz voxels to scanner RAS+ (\(A\)) and then apply the transform +from scanner RAS+ to voxels in someones_anatomy.nii.gz (\(B^{-1}\)):

+
+\[\begin{split}\begin{bmatrix} +i'\\ +j'\\ +k'\\ +1\\ +\end{bmatrix} = B^{-1} A +\begin{bmatrix} +i\\ +j\\ +k\\ +1\\ +\end{bmatrix}\end{split}\]
+
+
+

The affine by exampleΒΆ

+

We can get the affine from the nibabel image object. Here is the affine for +the EPI scan:

+
>>> # Set numpy to print 3 decimal points and suppress small values
+>>> import numpy as np
+>>> np.set_printoptions(precision=3, suppress=True)
+>>> # Print the affine
+>>> epi_img.affine
+array([[  3.   ,   0.   ,   0.   , -78.   ],
+       [  0.   ,   2.866,  -0.887, -76.   ],
+       [  0.   ,   0.887,   2.866, -64.   ],
+       [  0.   ,   0.   ,   0.   ,   1.   ]])
+
+
+

As you see, the last row is \([0, 0, 0, 1]\)

+
+

Applying the affineΒΆ

+

To make the affine simpler to apply, we split it into \(M\) and \((a, b, c)\):

+
>>> M = epi_img.affine[:3, :3]
+>>> abc = epi_img.affine[:3, 3]
+
+
+

Then we can define our function \(f\):

+
>>> def f(i, j, k):
+...    """ Return X, Y, Z coordinates for i, j, k """
+...    return M.dot([i, j, k]) + abc
+
+
+

The labels on the localizer image give the impression +that the center voxel of someones_epi.nii.gz was a little above the magnet +isocenter. Now we can check:

+
>>> epi_vox_center = (np.array(epi_img_data.shape) - 1) / 2.
+>>> f(epi_vox_center[0], epi_vox_center[1], epi_vox_center[2])
+array([ 0.   , -4.205,  8.453])
+
+
+

That means the center of the image field of view is at the isocenter of the +magnet on the left to right axis, and is around 4.2mm posterior to the +isocenter and ~8.5 mm above the isocenter.

+

The parameters in the affine array can therefore give the position of any +voxel coordinate, relative to the scanner RAS+ reference space.

+

We get the same result from applying the affine directly instead of using \(M\) +and \((a, b, c)\) in our function. As above, we need to add a 1 +to the end of the vector to apply the 4 by 4 affine matrix.

+
>>> epi_img.affine.dot(list(epi_vox_center) + [1])
+array([ 0.   , -4.205,  8.453,  1.   ])
+
+
+

In fact nibabel has a function apply_affine that applies an affine to an +\((i, j, k)\) point by splitting the affine into \(M\) and \(abc\) then multiplying +and adding as above:

+
>>> from nibabel.affines import apply_affine
+>>> apply_affine(epi_img.affine, epi_vox_center)
+array([ 0.   , -4.205,  8.453])
+
+
+

Now we can apply the affine, we can use matrix inversion on the anatomical +affine to map between voxels in the EPI image and voxels in the anatomical +image.

+
>>> import numpy.linalg as npl
+>>> epi_vox2anat_vox = npl.inv(anat_img.affine).dot(epi_img.affine)
+
+
+

What is the voxel coordinate in the anatomical corresponding to the voxel +center of the EPI image?

+
>>> apply_affine(epi_vox2anat_vox, epi_vox_center)
+array([28.364, 31.562, 36.165])
+
+
+

The voxel coordinate of the center voxel of the anatomical image is:

+
>>> anat_vox_center = (np.array(anat_img_data.shape) - 1) / 2.
+>>> anat_vox_center
+array([28. , 33. , 27.5])
+
+
+

The voxel location in the anatomical image that matches the center voxel of +the EPI image is nearly exactly half way across the first axis, a voxel or two +back from the anatomical voxel center on the second axis, and about 9 voxels +above the anatomical voxel center. We can check the localizer image by eye to see whether this makes sense, by seeing how the +red EPI field of view center relates to the blue anatomical field of view +center and the blue anatomical image field of view.

+
+
+

The affine as a series of transformationsΒΆ

+

You can think of the image affine as a combination of a series of +transformations to go from voxel coordinates to mm coordinates in terms of the +magnet isocenter. Here is the EPI affine broken down into a series of +transformations, with the results shown on the localizer image:

+_images/illustrating_affine.png +

We start by putting the voxel grid onto the isocenter coordinate +system, so a translation of one voxel equates to a translation of one +millimeter in the isocenter coordinate system. Our EPI image would then have +the black bounding box in the image above. Next we scale the voxels to +millimeters by scaling by the voxel size (green bounding box). We could do +this with an affine:

+
>>> scaling_affine = np.array([[3, 0, 0, 0],
+...                            [0, 3, 0, 0],
+...                            [0, 0, 3, 0],
+...                            [0, 0, 0, 1]])
+
+
+

After applying this affine, when we move one voxel in any direction, we are +moving 3 millimeters in that direction:

+
>>> one_vox_axis_0 = [1, 0, 0]
+>>> apply_affine(scaling_affine, one_vox_axis_0)
+array([3, 0, 0])
+
+
+

Next we rotate the scaled voxels around the first axis by 0.3 radians (see +rotate around first axis):

+
>>> cos_gamma = np.cos(0.3)
+>>> sin_gamma = np.sin(0.3)
+>>> rotation_affine = np.array([[1, 0, 0, 0],
+...                            [0, cos_gamma, -sin_gamma, 0],
+...                            [0, sin_gamma, cos_gamma, 0],
+...                            [0, 0, 0, 1]])
+>>> affine_so_far = rotation_affine.dot(scaling_affine)
+>>> affine_so_far
+array([[ 3.   ,  0.   ,  0.   ,  0.   ],
+       [ 0.   ,  2.866, -0.887,  0.   ],
+       [ 0.   ,  0.887,  2.866,  0.   ],
+       [ 0.   ,  0.   ,  0.   ,  1.   ]])
+
+
+

The EPI voxel block coordinates transformed by affine_so_far are at the +position of the yellow box on the figure.

+

Finally we translate the 0, 0, 0 coordinate at the bottom, posterior, left +corner of our array to be at its final position relative to the isocenter, +which is -78, -76, -64:

+
>>> translation_affine = np.array([[1, 0, 0, -78],
+...                                [0, 1, 0, -76],
+...                                [0, 0, 1, -64],
+...                                [0, 0, 0, 1]])
+>>> whole_affine = translation_affine.dot(affine_so_far)
+>>> whole_affine
+array([[  3.   ,   0.   ,   0.   , -78.   ],
+       [  0.   ,   2.866,  -0.887, -76.   ],
+       [  0.   ,   0.887,   2.866, -64.   ],
+       [  0.   ,   0.   ,   0.   ,   1.   ]])
+
+
+

This brings the affine-transformed voxel coordinates to the red box on the +figure, matching the position on the localizer.

+
+
+
+

Other reference spacesΒΆ

+

The scanner RAS+ reference space is a β€œreal-world” space, in the sense that a +coordinate in this space refers to a position in the real world, in a +particular scanner in a particular room.

+

Imagine that we used some fancy software to register someones_epi.nii.gz +to a template image, such as the Montreal Neurological Institute (MNI) +template brain. The registration has moved the voxels around in complicated +ways β€” the image has changed shape to match the template brain. We +probably do not want to know how the voxel locations relate to the original +scanner, but how they relate to the template brain. So, what reference space +should we use?

+

In this case we use a space defined in terms of the template brain β€” the MNI +reference space.

+
    +
  • The origin (0, 0, 0) point is defined to be the point that the anterior +commissure of the MNI template brain crosses the midline (the AC point).

  • +
  • Axis units are millimeters.

  • +
  • The Y axis follows the midline of the MNI brain between the left and right +hemispheres, going from posterior (negative) to anterior (positive), passing +through the AC point. The template defines this line.

  • +
  • The Z axis is at right angles to the Y axis, going from inferior (negative) +to superior (positive), with the superior part of the line passing between +the two hemispheres.

  • +
  • The X axis is a line going from the left side of the brain (negative) to +right side of the brain (positive), passing through the AC point, and at +right angles to the Y and Z axes.

  • +
+

These axes are defined with reference to the template. The exact position of +the Y axis, for example, is somewhat arbitrary, as is the definition of the +origin. Left and right are left and right as defined by the template. These +are the axes and the space that MNI defines for its template.

+

A coordinate in this reference system gives a position relative to the +particular brain template. It is not a real-world space because it does not +refer to any particular place but to a position relative to a template.

+

The axes are still left to right, posterior to anterior and inferior to +superior in terms of the template subject. This is still an RAS+ space β€” +the MNI RAS+ space.

+

An image aligned to this template will therefore have an affine giving the +relationship between voxels in the aligned image and the MNI RAS+ space.

+

There are other reference spaces. For example, we might align an image to the +Talairach atlas brain. This brain has a different shape and size than the MNI +brain. The origin is the AC point, but the Y axis passes through the point +that the posterior commissure crosses the midline (the PC point), giving a +slightly different trajectory from the MNI Y axis. Like the MNI RAS+ space, +the Talairach axes also run left to right, posterior to anterior and inferior +superior, so this is the Talairach RAS+ space.

+

There are conventions other than RAS+ for the reference space. For example, +DICOM files map input voxel coordinates to coordinates in scanner LPS+ space. +Scanner LPS+ space uses the same scanner axes and isocenter as scanner RAS+, +but the X axis goes from right to the subject’s Left, the Y axis goes from +anterior to Posterior, and the Z axis goes from inferior to Superior. A +positive X coordinate in this space would mean the point was to the subject’s +left compared to the magnet isocenter.

+
+
+

Nibabel always uses an RAS+ output spaceΒΆ

+

Nibabel images always use RAS+ output coordinates, regardless of the preferred +output coordinates of the underlying format. For example, we convert affines +for DICOM images to output RAS+ coordinates instead of LPS+ coordinates. We +chose this convention because it is the most popular in neuroimaging; for +example, it is the standard used by NIfTI and MINC formats.

+

Nibabel does not enforce a particular RAS+ space. For example, NIfTI images +contain codes that specify whether the affine maps to scanner or MNI or +Talairach RAS+ space. For the moment, you have to consult the specifics of +each format to find which RAS+ space the affine maps to.

+

See also Radiological vs neurological conventions

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/add_image_format.html b/devel/add_image_format.html new file mode 100644 index 0000000000..85e38a97d1 --- /dev/null +++ b/devel/add_image_format.html @@ -0,0 +1,262 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

How to add a new image format to nibabelΒΆ

+

These are some work-in-progress notes in the hope that they will help adding a +new image format to NiBabel.

+
+

PhilosophyΒΆ

+

As usual, the general idea is to make your image as explicit and transparent +as possible.

+

From the Zen of Python (import this), these guys spring to mind:

+
    +
  • Explicit is better than implicit.

  • +
  • Errors should never pass silently.

  • +
  • In the face of ambiguity, refuse the temptation to guess.

  • +
  • Now is better than never.

  • +
  • If the implementation is hard to explain, it’s a bad idea.

  • +
+

So far we have tried to make the nibabel version of the image as close as +possible to the way the user of the particular format is expecting to see it.

+

For example, the NIfTI format documents describe the image with the first +dimension of the image data array being the fastest varying in memory (and on +disk). Numpy defaults to having the last dimension of the array being the +fastest varying in memory. We chose to have the first dimension vary fastest +in memory to match the conventions in the NIfTI specification.

+
+
+

Helping us to review your codeΒΆ

+

You are likely to know the image format much much better than the rest of us +do, but to help you with the code, we will need to learn. The following will +really help us get up to speed:

+
    +
  1. Links in the code or in the docs to the information on the file format. +For example, you’ll see the canonical links for the NIfTI 2 format at the +top of the nifti2 file, in the module docstring;

  2. +
  3. Example files in the format; see Adding test data;

  4. +
  5. Good test coverage. The tests help us see how you are expecting the code +and the format to be used. We recommend writing the tests first; the tests +do an excellent job in helping us and you see how the API is going to work.

  6. +
+
+
+

The format can be read-onlyΒΆ

+

Read-only access to a format is better than no access to a format, and often +much better. For example, we can read but not write PAR / REC and MINC files. +Having the code to read the files makes it easier to work with these files in +Python, and easier for someone else to add the ability to write the format +later.

+
+
+

The image APIΒΆ

+

An image should conform to the image API. See the module docstring for +spatialimages for a description of the API.

+

You should test whether your image does conform to the API by adding a test +class for your image in nibabel.tests.test_image_api. For example, the +API test for the PAR / REC image format looks like:

+
class TestPARRECAPI(LoadImageAPI):
+    def loader(self, fname):
+        return parrec.load(fname)
+
+    example_images = PARREC_EXAMPLE_IMAGES
+
+
+

where your work is to define the EXAMPLE_IMAGES list β€” see the +nibabel.tests.test_parrec file for the PAR / REC example images +definition.

+
+
+

Where to start with the codeΒΆ

+

There is no API requirement that a new image format inherit from the general +SpatialImage class, but in fact all our image +formats do inherit from this class. We strongly suggest you do the same, to +get many simple methods implemented for free. You can always override the +ones you don’t want.

+

There is also a generic header class you might consider building on to contain +your image metadata β€” Header. See that +class for the header API.

+

The API does not require it, but if it is possible, it may be good to +implement the image data as loaded from disk as an array proxy. See the +docstring of arrayproxy for a description of the API, and see the +module code for an implementation of the API. You may be able to use the +unmodified ArrayProxy class for your image type.

+

If you write a new array proxy class, add tests for the API of the class in +nibabel.tests.test_proxy_api. See +TestPARRECAPI for an example.

+

A nibabel image is the association of:

+
    +
  1. The image array data (as implemented by an array proxy or a numpy array);

  2. +
  3. An affine relating the image array coordinates to an RAS+ world (see +Coordinate systems and affines);

  4. +
  5. Image metadata in the form of a header.

  6. +
+

Your new image constructor may well be the default from +SpatialImage, which looks like this:

+
def __init__(self, dataobj, affine, header=None,
+             extra=None, file_map=None):
+
+
+

Your job when loading a file is to create:

+
    +
  1. dataobj - an array or array proxy;

  2. +
  3. affine - 4 by 4 array relating array coordinates to world coordinates;

  4. +
  5. header - a metadata container implementing at least get_data_dtype, +get_data_shape.

  6. +
+

You will likely implement this logic in the from_file_map method of the +image class. See PARRECImage for an example.

+
+
+

A recipe for writing a new image formatΒΆ

+
    +
  1. Find one or more examples images;

  2. +
  3. Put them in nibabel/tests/data or a data submodule (see +Adding test data);

  4. +
  5. Create a file nibabel/tests/test_my_format_name_here.py;

  6. +
  7. Use some program that can read the format correctly to fill out the needed +fields for an EXAMPLE_IMAGES list (see +nibabel.tests.test_parrec.py for example);

  8. +
  9. Add a test class using your EXAMPLE_IMAGES to +nibabel.tests.test_image_api, using the PARREC image test class as +an example. Now you have some failing tests β€” good job!;

  10. +
  11. If you can, extract the metadata information from the test file, so it is +small enough to fit as a small test file into nibabel/tests/data (don’t +forget the license);

  12. +
  13. Write small maybe private functions to extract the header metadata from +your new test file, testing these functions in +test_my_format_name_here.py. See parrec for examples;

  14. +
  15. When that is working, try sub-classing Header, and working out how +to make the __init__ and from_fileboj methods for that class. Test +in test_my_format_name_here.py;

  16. +
  17. When that is working, try sub-classing SpatialImage and working +out how to load the file with the from_file_map class;

  18. +
  19. Now try seeing if you can get your test_image_api.py tests to pass;

  20. +
  21. Consider adding more test data files, maybe to a test data repository +submodule (Adding test data). Check you can read these files correctly +(see nibabel.tests.test_parrec_data for an example).

  22. +
  23. Ask for advice as early and as often as you can, either with a +work-in-progress pull request (the easiest way for us to review) or on +the mailing list or via github issues.

  24. +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/add_test_data.html b/devel/add_test_data.html new file mode 100644 index 0000000000..2f1a5f6986 --- /dev/null +++ b/devel/add_test_data.html @@ -0,0 +1,243 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Adding test dataΒΆ

+
    +
  1. We really, really like test images, but

  2. +
  3. We are rather conservative about the size of our code repository.

  4. +
+

So, we have two different ways of adding test data.

+
    +
  1. Small, open licensed files can go in the nibabel/tests/data directory +(see below);

  2. +
  3. Larger files or files with extra licensing terms can go in their own git +repositories and be added as submodules to the nibabel-data directory.

  4. +
+
+

Small filesΒΆ

+

Small files are around 50K or less when compressed. By β€œcompressed”, we mean, +compressed with zlib, which is what git uses when storing the file in the +repository. You can check the exact length directly with Python and a script +like:

+
import sys
+import zlib
+
+for fname in sys.argv[1:]:
+    with open(fname, 'rb') as fobj:
+        contents = fobj.read()
+    compressed = zlib.compress(contents)
+    print(fname, len(compressed) / 1024.)
+
+
+

One way of making files smaller when compressed is to set uninteresting values +to zero or some other number so that the compression algorithm can be more +effective.

+

Please don’t compress the file yourself before committing to a git repo unless +there’s a really good reason; git will do this for you when adding to the +repository, and it’s a shame to make git compress a compressed file.

+
+
+

Files with open licensesΒΆ

+

We very much prefer files with completely open licenses such as the PDDL +1.0 or the CC0 license.

+

The files in the nibabel/tests/data will get distributed with the nibabel +source code, and this can easily get installed without the user having an +opportunity to review the full license. We don’t think this is compatible +with extra license terms like agreeing to cite the people who provided the +data or agreeing not to try and work out the identity of the person who has +been scanned, because it would be too easy to miss these requirements when +using nibabel. It is fine to use files with these kind of licenses, but they +should go in their own repository to be used as a submodule, so they do not +need to be distributed with nibabel.

+
+
+

Adding the file to nibabel/tests/dataΒΆ

+

If the file is less then about 50K compressed, and the license is open, then +you might want to commit the file under nibabel/tests/data.

+

Put the license for any new files in the COPYING file at the top level of the +nibabel repo. You’ll see some examples in that file already.

+
+
+

Adding as a submodule to nibabel-dataΒΆ

+

Make a new git repository with the data.

+

There are example repos at

+ +

Despite the fact that both the examples are on github, Bitbucket is good for +repos like this because they don’t enforce repository size limits.

+

Don’t forget to include a LICENSE and README file in the repo.

+

When all is done, and the repository is safely on the internet and accessible, +add the repo as a submodule to the nitests-data directory, with something +like this:

+
git submodule add https://bitbucket.org/nipy/rosetta-samples.git nitests-data/rosetta-samples
+
+
+

You should now have a checked out copy of the rosetta-samples repository +in the nibabel-data/rosetta-samples directory. Commit the submodule that +is now in your git staging area.

+

If you are writing tests using files from this repository, you should use the +needs_nibabel_data decorator to skip the tests if the data has not been +checked out into the submodules. See nibabel/tests/test_parrec_data.py +for an example. For our example repository above it might look something +like:

+
from .nibabel_data import get_nibabel_data, needs_nibabel_data
+
+ROSETTA_DATA = pjoin(get_nibabel_data(), 'rosetta-samples')
+
+@needs_nibabel_data('rosetta-samples')
+def test_something():
+    # Some test using the data
+
+
+
+

Using submodules for testsΒΆ

+

Tests run via nibabel on travis start with an automatic checkout of all +submodules in the project, so all test data submodules get checked out by +default.

+

If you are running the tests locally, you may well want to do:

+
git submodule update --init
+
+
+

from the root nibabel directory. This will checkout all the test data +repositories.

+
+
+

How much data should go in a single submodule?ΒΆ

+

The limiting factor is how long it takes travis-ci to checkout the data for +the tests. Up to a hundred megabytes in one repository should be OK. The joy +of submodules is we can always drop a submodule, split the repository into two +and add only one back, so you aren’t committing us to anything awful if you +accidentally put some very large files into your own data repository.

+
+
+

If in doubtΒΆ

+

If you are not sure, try us with a pull request to nibabel github, or on the +nipy mailing list, we will try to help.

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/advanced_testing.html b/devel/advanced_testing.html new file mode 100644 index 0000000000..fd39392284 --- /dev/null +++ b/devel/advanced_testing.html @@ -0,0 +1,135 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Advanced TestingΒΆ

+
+

SetupΒΆ

+

Before running advanced tests, please update all submodules of nibabel, by +running git submodule update --init

+
+
+

Long-running testsΒΆ

+

Long-running tests are not enabled by default, and can be resource-intensive. To run these tests:

+
    +
  • Set environment variable NIPY_EXTRA_TESTS=slow;

  • +
  • Run pytest nibabel.

  • +
+

Note that some tests may require a machine with >4GB of RAM.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0000.html b/devel/biaps/biap_0000.html new file mode 100644 index 0000000000..a13b5b11e0 --- /dev/null +++ b/devel/biaps/biap_0000.html @@ -0,0 +1,368 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP 0 - Purpose and processΒΆ

+
+
Author:
+

Jarrod Millman <millman@berkeley.edu>

+
+
Status:
+

Draft

+
+
Type:
+

Process

+
+
Created:
+

2020-06-25

+
+
+
+

What is a BIAP?ΒΆ

+

BIAP stands for Nibabel Enhancement Proposal. BIAPs are the primary +mechanisms for proposing major new features, for collecting community input on +an issue, and for documenting the design decisions that have gone into +Nibabel. A BIAP should provide a concise technical specification of the +feature and a rationale for the feature. The BIAP author is responsible for +building consensus within the community and documenting dissenting opinions.

+

Because the BIAPs are maintained as text files in a versioned +repository, their revision history is the historical record of the +feature proposal [1].

+
+

TypesΒΆ

+

There are three kinds of BIAPs:

+
    +
  1. A Standards Track BIAP describes a new feature or implementation +for Nibabel.

  2. +
  3. An Informational BIAP describes a Nibabel design issue, or provides +general guidelines or information to the Python community, but does not +propose a new feature. Informational BIAPs do not necessarily represent a +Nibabel community consensus or recommendation, so users and implementers are +free to ignore Informational BIAPs or follow their advice.

  4. +
  5. A Process BIAP describes a process surrounding Nibabel, or +proposes a change to (or an event in) a process. Process BIAPs are +like Standards Track BIAPs but apply to areas other than the Nibabel +language itself. They may propose an implementation, but not to +Nibabel’s codebase; they require community consensus. Examples include +procedures, guidelines, changes to the decision-making process, and +changes to the tools or environment used in Nibabel development. +Any meta-BIAP is also considered a Process BIAP.

  6. +
+
+
+
+

BIAP WorkflowΒΆ

+

The BIAP process begins with a new idea for Nibabel. It is highly +recommended that a single BIAP contain a single key proposal or new +idea. Small enhancements or patches often don’t need +a BIAP and can be injected into the Nibabel development workflow with a +pull request to the Nibabel repo. The more focused the +BIAP, the more successful it tends to be. +If in doubt, split your BIAP into several well-focused ones.

+

Each BIAP must have a championβ€”someone who writes the BIAP using the style +and format described below, shepherds the discussions in the appropriate +forums, and attempts to build community consensus around the idea. The BIAP +champion (a.k.a. Author) should first attempt to ascertain whether the idea is +suitable for a BIAP. Posting to the Nibabel discussion mailing list is the +best way to go about doing this.

+

The proposal should be submitted as a draft BIAP via a GitHub pull request +to the doc/source/devel/biaps directory with the name biap_<n>.rst +where <n> is an appropriately assigned four-digit number (e.g., +biap_0000.rst). The draft must use the BIAP X β€” Template and Instructions file.

+

Once the PR for the BIAP is in place, a post should be made to the +mailing list containing the sections up to β€œBackward compatibility”, +with the purpose of limiting discussion there to usage and impact. +Discussion on the pull request will have a broader scope, also including +details of implementation.

+

At the earliest convenience, the PR should be merged (regardless of +whether it is accepted during discussion). Additional PRs may be made +by the Author to update or expand the BIAP, or by maintainers to set +its status, discussion URL, etc.

+

Standards Track BIAPs consist of two parts, a design document and a +reference implementation. It is generally recommended that at least a +prototype implementation be co-developed with the BIAP, as ideas that sound +good in principle sometimes turn out to be impractical when subjected to the +test of implementation. Often it makes sense for the prototype implementation +to be made available as PR to the Nibabel repo (making sure to appropriately +mark the PR as a WIP).

+
+

Review and ResolutionΒΆ

+

BIAPs are discussed on the mailing list. The possible paths of the +status of BIAPs are as follows:

+../../_images/biap_flowchart.png +

All BIAPs should be created with the Draft status.

+

Eventually, after discussion, there may be a consensus that the BIAP +should be accepted – see the next section for details. At this point +the status becomes Accepted.

+

Once a BIAP has been Accepted, the reference implementation must be +completed. When the reference implementation is complete and incorporated +into the main source code repository, the status will be changed to Final.

+

To allow gathering of additional design and interface feedback before +committing to long term stability for a language feature or standard library +API, a BIAP may also be marked as β€œProvisional”. This is short for +β€œProvisionally Accepted”, and indicates that the proposal has been accepted for +inclusion in the reference implementation, but additional user feedback is +needed before the full design can be considered β€œFinal”. Unlike regular +accepted BIAPs, provisionally accepted BIAPs may still be Rejected or Withdrawn +even after the related changes have been included in a Python release.

+

Wherever possible, it is considered preferable to reduce the scope of a +proposal to avoid the need to rely on the β€œProvisional” status (e.g. by +deferring some features to later BIAPs), as this status can lead to version +compatibility challenges in the wider Nibabel ecosystem.

+

A BIAP can also be assigned status Deferred. The BIAP author or a +core developer can assign the BIAP this status when no progress is being made +on the BIAP.

+

A BIAP can also be Rejected. Perhaps after all is said and done it +was not a good idea. It is still important to have a record of this +fact. The Withdrawn status is similarβ€”it means that the BIAP author +themselves has decided that the BIAP is actually a bad idea, or has +accepted that a competing proposal is a better alternative.

+

When a BIAP is Accepted, Rejected, or Withdrawn, the BIAP should be +updated accordingly. In addition to updating the status field, at the very +least the Resolution header should be added with a link to the relevant +thread in the mailing list archives.

+

BIAPs can also be Superseded by a different BIAP, rendering the +original obsolete. The Replaced-By and Replaces headers +should be added to the original and new BIAPs respectively.

+

Process BIAPs may also have a status of Active if they are never +meant to be completed, e.g. BIAP 0 (this BIAP).

+
+
+

How a BIAP becomes AcceptedΒΆ

+

A BIAP is Accepted by consensus of all interested contributors. We +need a concrete way to tell whether consensus has been reached. When +you think a BIAP is ready to accept, send an email to the +Nibabel discussion mailing list with a subject like:

+
+

Proposal to accept BIAP #<number>: <title>

+
+

In the body of your email, you should:

+
    +
  • link to the latest version of the BIAP,

  • +
  • briefly describe any major points of contention and how they were +resolved,

  • +
  • include a sentence like: β€œIf there are no substantive objections +within 7 days from this email, then the BIAP will be accepted; see +BIAP 0 for more details.”

  • +
+

After you send the email, you should make sure to link to the email +thread from the Discussion section of the BIAP, so that people can +find it later.

+

Generally the BIAP author will be the one to send this email, but +anyone can do it – the important thing is to make sure that everyone +knows when a BIAP is on the verge of acceptance, and give them a final +chance to respond. If there’s some special reason to extend this final +comment period beyond 7 days, then that’s fine, just say so in the +email. You shouldn’t do less than 7 days, because sometimes people are +travelling or similar and need some time to respond.

+

In general, the goal is to make sure that the community has consensus, +not provide a rigid policy for people to try to game. When in doubt, +err on the side of asking for more feedback and looking for +opportunities to compromise.

+

If the final comment period passes without any substantive objections, +then the BIAP can officially be marked Accepted. You should send a +followup email notifying the list (celebratory emoji optional but +encouraged), and then update the BIAP by setting its :Status: to +Accepted, and its :Resolution: header to a link to your followup +email.

+

If there are substantive objections, then the BIAP remains in +Draft state, discussion continues as normal, and it can be +proposed for acceptance again later once the objections are resolved.

+

In unusual cases, disagreements about the direction or approach may +require escalation to the Nibabel Steering Council who +then decide whether a controversial BIAP is Accepted.

+
+
+

MaintenanceΒΆ

+

In general, Standards track BIAPs are no longer modified after they have +reached the Final state as the code and project documentation are considered +the ultimate reference for the implemented feature. +However, finalized Standards track BIAPs may be updated as needed.

+

Process BIAPs may be updated over time to reflect changes +to development practices and other details. The precise process followed in +these cases will depend on the nature and purpose of the BIAP being updated.

+
+
+
+

Format and TemplateΒΆ

+

BIAPs are UTF-8 encoded text files using the reStructuredText format. Please +see the BIAP X β€” Template and Instructions file and the reStructuredTextPrimer for more +information. We use Sphinx to convert BIAPs to HTML for viewing on the web +[2].

+
+

Header PreambleΒΆ

+

Each BIAP must begin with a header preamble. The headers +must appear in the following order. Headers marked with * are +optional. All other headers are required.

+
  :Author: <list of authors' real names and optionally, email addresses>
+  :Status: <Draft | Active | Accepted | Deferred | Rejected |
+           Withdrawn | Final | Superseded>
+  :Type: <Standards Track | Process>
+  :Created: <date created on, in dd-mmm-yyyy format>
+* :Requires: <BIAP numbers>
+* :Nibabel-Version: <version number>
+* :Replaces: <BIAP number>
+* :Replaced-By: <BIAP number>
+* :Resolution: <url>
+
+
+

The Author header lists the names, and optionally the email addresses +of all the authors of the BIAP. The format of the Author header +value must be

+
+

Random J. User <address@dom.ain>

+
+

if the email address is included, and just

+
+

Random J. User

+
+

if the address is not given. If there are multiple authors, each should be on +a separate line.

+
+
+
+

References and FootnotesΒΆ

+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0001.html b/devel/biaps/biap_0001.html new file mode 100644 index 0000000000..d29bfa0c94 --- /dev/null +++ b/devel/biaps/biap_0001.html @@ -0,0 +1,412 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP1 - Towards immutable imagesΒΆ

+
+
Author:
+

Matthew Brett

+
+
Status:
+

Rejected

+
+
Type:
+

Standards

+
+
Created:
+

2011-03-23

+
+
+
+

ResolutionΒΆ

+

Retired as of nibabel 2.0 in favor of exposed dataobj property. See:

+ +

See image in_memory attribute and uncache method.

+

We haven’t implemented an is_as_loaded attribute yet.

+
+
+

BackgroundΒΆ

+

Nibabel implicitly has two types of images

+
    +
  • array images

  • +
  • proxy images

  • +
+
+

Array imagesΒΆ

+

Array images are the images you get from a typical constructor call:

+
import numpy as np
+import nibabel as nib
+arr = np.arange(24).reshape((2,3,4))
+img = nib.Nifti1Image(arr, np.eye(4))
+
+
+

img here is an array image, that is to say that, internally, the private +img._data attribute is reference to arr above. img.get_data() just +returns img._data. If you modify arr, you will modify the result of +img.get_data().

+
+
+

Proxy imagesΒΆ

+

Proxy images are what you get from a call to load:

+
px_img = nib.load('test.nii')
+
+
+

It’s a proxy image in the sense that, internally, px_arr._data is a proxy +object that does not yet contain an array, but can get an array by the +application of:

+
actual_arr = np.asarray(px_img._data)
+
+
+

This is in fact what px_img.get_data() does. Actually, +px_img.get_data() also stores the read array in px_img._data, so that:

+
px_img = nib.load('test.nii')
+assert not isinstance(px_img._data, np.ndarray) # it's a proxy
+actual_arr = px_img.get_data()
+assert isinstance(px_img._data, np.ndarray) # it's an array now
+
+
+

So, at this point, if you change actual_arr you’ll also be changing +px_img._data and therefore the result of px_img.get_data().

+

In other words, actual_arr = px_img.get_data() turns the proxy image into an +array image.

+
+
+

Issues for designΒΆ

+

The code at the moment is a little bit confusing because:

+
    +
  • there isn’t an explicit API to check if you have an array image or a proxy +image and

  • +
  • there isn’t anywhere in the docs that you can go and see this distinction.

  • +
+
+
+

Use casesΒΆ

+
+

Loading images, minimizing memoryΒΆ

+

I want to load lots of images, or several large images. I’m going to do +something with the image data. I want to minimize memory use. This tempts me +to do something like this:

+
large_img1 = nib.load('large1.nii')
+large_img2 = nib.load('large2.nii')
+li1_mean = large_img1.get_data().mean()
+li2_mean = large_img2.get_data().mean()
+
+
+

The problem with the current design is that, after the li1_mean = line, +large_img1 got unproxied, and there’s a huge array inside it.

+
+
+

Loading images, maximizing speedΒΆ

+

On the other hand, I might want to do the same thing, but each call to unproxy +the data (loading off disk, applying scalefactors) will be expensive. So, when +I do li1_mean = large_img1.get_data().mean() I want any subsequent call to +to large_img1.get_data() to be much faster. This is the case at the moment, +at the expense of the memory hit above.

+
+
+

Loading images, assert not modifiedΒΆ

+

In pipelines in particular, we frequently want to load images, maybe have a +look at some parameters, and then pass that image filename to some other +program such as SPM or FSL. At the moment we’ve got a problem:

+
img = nib.load('test.nii')
+# do stuff
+run_spm_thing_on(img) # is 'img' the same as test.nii?
+
+
+

The problem is that when the routine run_spn_thing receives img, it +can know that img has a filename, test.nii, but it can’t currently +know if img is the same object that it was when it was loaded. That is, +it can’t know whether test.img still corresponds to img or not. In +practice that means that run_spm_thing will need to save every img to +another file before passing that filename to the SPM routine, just in case +img has been modified. So, we would like a dirty bit for the image, +something like:

+
# Not implemented yet
+if not img.is_as_loaded():
+    save(img, 'some_filename.nii')
+
+
+

The last line, like it or not, modifies img in-place.

+
+
+
+

Array images, proxy images, copy, viewΒΆ

+

With thanks to Roberto Viviani for some clarifying thoughts on the nipy +mailing list.

+

At the moment, img.get_data() always returns a reference to an array. +That is, whenever you call:

+
data = img.get_data()
+
+
+

Then, if you modify data you will modify the next result of +img.get_data().

+

In particular, the interface currently intends that there should be no +functional difference between proxied images and non-proxied images. The +proposal below exposes a functional difference between them.

+
+

When do you want a copy and when do you want a view?ΒΆ

+

This is a discussion of this proposal:

+
img.get_data(copy=True|False)
+
+
+

compared to:

+
img.get_data(unproxy=True|False)
+
+
+

Summary:

+
    +
  • array images - you nearly always want a view

  • +
  • proxy images - you may want a copy, but you want a copy only because you +want to leave the image as a proxy. You might want to leave the image as a +proxy because you want to be sure the image corresponds to the file, or save +memory.

  • +
+

For array images, it doesn’t make sense to return a copy from +img.get_data(), because it buys you nothing that you would not get from +data = img.get_data().copy(). This is because you can’t save memory (the +image already contains the whole array), and it won’t help you be sure that +the image has not been modified compared to the original array, because there +may be references to the array that existed before the image was made, that +can be used to modify the data. So, for array images, you always want a +reference, or you want to do a manual copy, as above.

+

For proxied images, it does make sense to get a copy, because a) you want to +preserve memory by not unproxying the image, and / or b) you want to be able +to be sure that the file associated with the image still corresponds to the +data.

+

For the img.get_data(copy=False) proposal, on a proxied image, the +copy=False call, in order to return a view, must implicitly unproxy the +image.

+

Similarly, img.get_data(unproxy=False) must implicitly copy the image.

+

It seems to me (MB) that an implicit copy is familiar to a numpy user, but the +implicit unproxying may be less obvious.

+

My (MBs) reasons then for preferring β€˜unproxy’ to β€˜copy=True’ or β€˜copy=False’ +or get_data_copy() is that β€˜unproxy’ is closer to how I think the user would +think about deciding what they wanted to do.

+

The unproxy=False case covers the situation where you want to preserve +memory. It doesn’t fully cover the cases where we want to keep track of when +the image data has been modified.

+

Here there are three cases:

+
    +
  • array image, instantiated with an array; the image data can be modified +using the array reference passed into the image - we can’t know whether the +data has been modified without doing hashing or similar.

  • +
  • proxy image; the array data is still in the file, so we know it corresponds +to the file.

  • +
  • proxy images that have been converted to array images, but have not passed +out a reference to the data. Let’s call these shy unproxied images. For +example, with an API like this:

    +
    img = load('test.nii')
    +data = img.get_data(copy=True)
    +
    +
    +

    the img is now an array image, but there’s no public reference to the +internal array object. Someone could get one by cheating with ref = +img._data, but, we don’t need to worry about that - following Python’s β€œmess +around if you like but take the consequences” philosophy.

    +
  • +
+
+
+
+

ProposalΒΆ

+

An is_proxy property:

+
img.is_proxy
+
+
+

This is just for clarity.

+

Allow the user to specify what unproxying they want with a kwarg to +get_data():

+
arr = large_img1.get_data(unproxy=False)
+
+
+
    +
  • for proxied images, unproxy=False would leave the underlying array data +as a pointer to the file. The returned arr would be therefore a copy of +the data as loaded from file, and arr[0] = 99 would have no effect on +the data in the image. unproxy=True would convert the proxy image into +an array image (load the data into memory, return reference). Here arr[0] += 99 would affect the data in the image

  • +
  • for array images, unproxy would always be ignored.

  • +
+

Thus unproxy=True in fact means, +unproxy_if_this_is_a_proxy_do_nothing_otherwise.

+

The default would continue to be unproxy=True so that the proxied image +would continue, by default, to behave the same way as an unproxied image +(get_data returns a view).

+

If img.is_proxy is True, then we know that the array data has not changed. +We then need to be sure that the header and affine data haven’t +changed. We might be able to do this with default copy kwargs to the +get_header and get_affine methods:

+
hdr = img.get_header(copy=True) # will be default
+aff = img.get_affine(copy=True) # will be default
+
+
+

We could also do that by caching the original header and affine, but the +header in particular can be rather large.

+

For the next version of nibabel, for backwards compatibility, we’ll set +copy=False to be the default, but warn about the upcoming change. After +that we’ll set copy=True as the default.

+

Now we can know whether the image has been modified, because if get_header +and get_affine have only been called with copy=True and img.is_proxy +== True - then it must be the same as when loaded.

+

This leads to an is_as_loaded property:

+
if img.is_as_loaded:
+    fname = img.get_filename()
+else:
+    fname = 'tempname.nii'
+    save(img, 'tempname.nii')
+
+
+
+
+

QuestionsΒΆ

+

Should there also be a set_header and set_affine method?

+

The header may conflict with the affine. So, would we need something like:

+
img.set_header(hdr, hdr_affine_from='affine')
+
+
+

or some other nasty syntax. Or can we avoid this and just do:

+
img2 = nib.Nifti1Image(img.get_data(), new_affine, new_header)
+
+
+

?

+

How about the names in the proposal? is_proxy; unproxy=True?

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0002.html b/devel/biaps/biap_0002.html new file mode 100644 index 0000000000..a810d17526 --- /dev/null +++ b/devel/biaps/biap_0002.html @@ -0,0 +1,281 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP2 - SlicecopyΒΆ

+
+
Author:
+

Matthew Brett

+
+
Status:
+

Rejected

+
+
Type:
+

Standards

+
+
Created:
+

2011-03-26

+
+
+
+

StatusΒΆ

+

Alternative implementation as of Nibabel 2.0 with image proxy slicing : see +http://nipy.org/nibabel/images_and_memory.html#saving-time-and-memory

+
+
+

BackgroundΒΆ

+

Please see https://github.com/nipy/nibabel/issues#issue/9 for motivation.

+

Sometimes we have a biiig images and we don’t want to load the whole array into +memory. In this case it is useful to be able to load as a proxy:

+
img = load('my_huge_image.nii')
+
+
+

and then take out individual slices, as in something very approximately like:

+
slice0 = img.get_slice(0)
+
+
+
+

QuestionsΒΆ

+
+

Should slice0 be a copy or a view?ΒΆ

+

As from the previous discussion - BIAP1 - Towards immutable images - an image may be a proxy +or an array.

+

If the image is an array, the most natural thing to return is a view. That is, +modifying slice0 will modify the underlying array in img.

+

If the image is a proxy, it would be self-defeating to return a view, because +that would involve reading the whole image into memory, exactly what we are +trying to avoid. So, for a proxied image, we’d nearly always want to return a +copy.

+
+
+

What slices should the slicing allow?ΒΆ

+

The img.get_slice(0) syntax needs us to know what slice 0 is. In a nifti +image of 3 dimensions, the first is fastest changing on disk. To be useful +0 will probably refer to the slowest changing on disk. Otherwise we’ll +have to load nearly the whole image anyway. So, for a nifti, 0 should be the +first slice in the last dimension.

+

For Minc on the other hand, you can and I (MB) think always do get C ordered +arrays back, so that the slowest changing dimension in the image array is the +first. Actually, I don’t know how to read a Minc file slice by slice, but the +general point is that, to know which slice is worth reading, you need to know +the relationship of the image array dimensions to fastest / slowest on disk.

+

We could always solve this by assuming that we always want to do this for +Analyze / Nifti1 files (Fortran ordered). It’s a little ugly of course.

+

Note that taking the slowest changing slice in a nifti image would be the +equivalent of taking a slice from the last dimension:

+
arr = img.get_data()
+slice0 = arr[...,0]
+
+
+

In general, we can get contiguous data off disk for the same data as contiguous +data in memory (perhaps obviously). So, all of these are contiguous in the +Fortran ordering case:

+
arr[...,0:5]
+arr[:,:,0]
+arr[:,0:,0]
+arr[0:,:,0]
+arr[:,1,0]
+arr[1,1,1]
+
+
+

That is, in general, : up until the first specified dimension, then +contiguous slices, followed by integer slices. So, all of these can be read +directly off disk as slices. Obviously the rules are the reverse for c-ordered +arrays.

+
+
+
+

Option 1: fancy slice objectΒΆ

+

It’s option 1 because it’s the first one I thought of:

+
slice0 = img.slicecopy[...,0]
+
+
+

Here we solve the copy or view problem with β€˜always copy’. We solve the β€˜what +slicing to allow’ by letting the object decide how to do the slicing. We could +obviously just do the full load (deproxy the image) and return a copy of the +sliced array, as in:

+
class SomeImage:
+    class Slicer:
+        def __init__(self, parent):
+            self.parent = parent
+        def __getitem__(self, slicedef):
+            data = parent._data
+            if is_proxy(data) and iscontinguous(slicedef, order='F'):
+                return read_off_disk_somehow(slicedef, data)
+            data = parent.get_data(unproxy=True)
+            return data.__getitem__(slicedef)
+    def __init__(self, stuff):
+        self.slicecopy = Slicer(self)
+
+
+

The problem with this is that:

+
slice0 = img.slicecopy[...,1]
+
+
+

might unproxy the image. At the moment, it’s rather hidden whether the image +is proxied or not on the basis that it’s an optimization that should be +transparent.

+
+
+

Option 2: not-fancy method callΒΆ

+
slice0 = img.get_slice(0, copy=True)
+
+
+

β€˜slice or view’ solved with explicit keyword. β€˜which slice’ solved by assuming +you always mean one slice in the last dimension. Or we could also allow:

+
slices = img.get_slices(slice(0,3), copy=True)
+
+
+

This is ugly, but fairly clear. This simple β€˜I mean the last dimension’ might +be annoying because it assumes the last dimension is the slowest changing, and +it does not get to optimize the more complex contiguous cases above. So we +could even allow full slicing with stuff like:

+
slice = img.get_slices((slice(None), slice(None), slice(3)), copy=True)
+
+
+

Again - this looks a lot more ugly than the slicecopy syntax above.

+

Now, when would you choose copy=True? I think, when the image is a proxy. +Otherwise you’d want a view. Probably. So what you mean, probably, is +something like this:

+
slices = img.get_slices(slicedef, copy_if='is_proxy')
+
+
+

But, we’ve established that for some slices, you’re going to have to load the +whole image anyway. So in fact probably what you want is to:

+
    +
  1. Take a view if this image is not a proxy

  2. +
  3. Take a copy if we can read this directly off disk

  4. +
  5. Unproxy the image if we have to read the whole thing off disk anyway to get +the slices we want, on the basis that we have to read the whole thing into +memory anyway, we might as well do that and save ourselves lots of disk +thrashing getting the individual slices.

  6. +
+

Of course that’s what option 1 boils down to. So I think I prefer version 1.

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0003.html b/devel/biaps/biap_0003.html new file mode 100644 index 0000000000..82219a2fde --- /dev/null +++ b/devel/biaps/biap_0003.html @@ -0,0 +1,840 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP3 - A JSON nifti header extensionΒΆ

+
+
Author:
+

Matthew Brett, Bob Dougherty

+
+
Status:
+

Draft

+
+
Type:
+

Standards

+
+
Created:
+

2011-03-26

+
+
+

The following Wiki documents should be merged with this one:

+ +
+

AbstractΒΆ

+

A draft specification of the JSON header for Nibabel.

+
+
+

BackgroundΒΆ

+

DICOM files in particular have a lot of information in them that we might want +to carry with the image. There are other image file types like Minc or Nrrd +that have information we’d like to support but can’t with standard nifti.

+

One obvious place to store this information is in a nifti header extension.

+
+

Nifti extension typesΒΆ

+

From adding nifti extensions:

+ +
+
+

AlternativesΒΆ

+

Summary: we need probably need our own extension format

+

There is a DICOM type extension - code 2. This might be OK for DICOM but:

+
    +
  1. We probably don’t want to have to dump the entire DICOM header for every +DICOM image. If we don’t that means we have to edit the DICOM header, and

  2. +
  3. The DICOM format is awful to work with, so it is not a pleasant prospect +making a new DICOM header for images (like Minc) that aren’t DICOM to start +with.

  4. +
  5. I (MB) can’t find any evidence that it’s being used in the wild.

  6. +
  7. It’s not completely clear what format the data should be in. See this +nifti thread.

  8. +
+

The AFNI extension format looks as if it is specific to AFNI.

+

The XCEDE format looks rather heavy. I’m (MB) trying to work out where the +most current schema is. Candidates are bxh-xcede-tools and the xcede +website. We’d need to validate the XML with the schema. It appears the +python standard library doesn’t support that so we’d need extra XML tools as a +dependency.

+

JIM is closed source.

+

fiswidgets seems to have been quiet recently. The link for code 12 is dead, I +had to go back to the http://www.archive.org to get an old copy +and that didn’t have the DTD or example links that we need to understand the +format.

+
+
+

Learning from NRRDsΒΆ

+

Gordon Kindlmann’s NRRD format has gone through a few versions and has +considerable use particularly by the 3D slicer team. I’ve tried to +summarize the NRRD innovations not properly covered by nifti in +[[nifti-nrrd]].

+
+
+
+

ProposalΒΆ

+

JSON, as y’all know, encodes strings, numbers, objects +and arrays, An object is like a Python dict, with strings as keys, and an +array is like a Python list.

+

In what follows, I will build dicts and lists corresponding to the objects and +arrays of the JSON header. In each case, the json.dumps of the given Python +object gives the corresponding JSON string.

+

I’ll use the term field to refer to a (key, value) pair from a Python dict / +JSON object.

+
+

General principlesΒΆ

+

We specify image axes by name in the header, and give the correspondence of the +names to the image array axes by the order of the names. This is the +axis_names field at the top level of the header.

+

If the user transposes or otherwise reorders the axes of the data array, the +header should change only in the ordering of the axis names in +axis_names. Call this the β€œaxis transpose” principle.

+

The JSON header should make sense as a key, value pair store for DICOM +fields using a standard way of selecting DICOM fields – the simple DICOM +principle.

+

The NIfTI image also contains the standard image metadata in the NIfTI header +C-struct (the standard NIfTI header). Nibabel and Nipy will write JSON +headers correctly, and so the information in the NIfTI C-struct should always +match the information in the JSON header. Other software may write the JSON +incorrectly, or copy the JSON header into another image to which it may not +apply, but other software should always set the C-struct correctly. For that +reason the C-struct always overrides the JSON header, unless the C-struct has +values implying β€œnot-set” or β€œdon’t know”. This is the C-struct primacy +principle.

+
+
+

See alsoΒΆ

+
    +
  • JSON-LD - provides a way of using json that can be +mapped into the Resource Description Framework (RDF). It is highly +recommended to take a look at the RDF Primer to get a sense of why we might want +to use JSON-LD/RDF, but essentially it boils down to a couple points:

    +
      +
    • JSON keys are turned into URIs

    • +
    • URIs can dereference to a Web URL with additional documentation, such as a +definition, a pretty label (e.g., nipy_header_version has_label +"NIPY Header Version"), etc.

    • +
    • The URI link to documentation makes the meaning of your JSON keys +explicit, in a machine readable way (i.e., the json key becomes a +β€œresource” on the Web that avoids name clashes)

    • +
    • JSON-LD/RDF has a full query language called SPARQL and a python library called +RDFLib that acts as a +parser, serializer, database, and query engine.

    • +
    • In the example below, the @context section provides the namespace +prefix dcm as a placeholder for the URL +http://neurolex.org/wiki/Category:, thus dcm:Echo_Time +dereferences to http://neurolex.org/wiki/Category:Echo_Time where +additional documentation is provided:

      +
      {
      +  "@context": {
      +    "dcm": "http://neurolex.org/wiki/Category:#"
      +  },
      +  "dcm:Echo_Time": 45,
      +  "dcm:Repetition_Time": 2,
      +}
      +
      +
      +
    • +
    +
  • +
+
+
+

The header must contain the header versionΒΆ

+
>>> hdr = dict(nipy_header_version='1.0')
+
+
+

We chose the name β€œnipy_header_version” in the hope that this would not often +occur in an unrelated JSON file.

+
    +
  • First version will be β€œ1.0”.

  • +
  • Versioning will use Semantic Versioning of form +major.minor[.patch[-extra]] where major, minor, patch are +all integers, extra may be a string, and both patch and extra +are optional. Header versions with the same major value are forwards +compatible – that +is, a reader that can read a header with a particular major version should +be able to read any header with that major version. Specifically, any +changes to the header format within major version number should allow older +readers of that major version to read the header correctly, but can expand +on the information in the header, so that older readers can safely ignore +new information in the header.

  • +
  • All fields other than nipy_header_version are optional. The dict in +hdr above is therefore the minimal valid header.

  • +
+
+
+

The header will usually contain image metadata fieldsΒΆ

+

The base level header will usually also have image metadata fields giving +information about the whole image. A field is an β€œimage metadata field” if it +is defined at the top level of the header. For example:

+
>>> hdr = dict(nipy_header_version='1.0',
+...            Manufacturer="SIEMENS")
+
+
+

All image metadata fields are optional.

+

As for all keys in this standard, IM (Image Metadata) keys are case sensitive. +IM keys that begin with a capital letter must be from the DICOM data +dictionary standard short names (DICOM keyword). Call these β€œDICOM IM keys”. +This is to conform to the simple DICOM principle.

+

Keys beginning with β€œextended” will be read and written, but not further +processed by a header reader / writer. If you want to put extra fields into +the header that are outside this standard you could use a dict / object of +form:

+
>>> hdr = dict(nipy_header_version='1.0',
+...            extended=dict(my_field1=0.1, my_field2='a string'))
+
+
+

or:

+
>>> hdr = dict(nipy_header_version='1.0',
+...            extended_mysoft=dict(mysoft_one='expensive', mysoft_two=1000))
+
+
+

Values for DICOM IM keys are constrained by the DICOM standard. This standard +constrains values for (β€œnipy_header_version”, β€œaxis_names”, β€œaxis_metadata”). +Other values have no constraint.

+
+
+

QuestionsΒΆ

+
    +
  • Should all DICOM values be allowed?

  • +
  • Should DICOM values be allowed at this level that in fact refer to a +particular axis, and therefore might go in the axis_metadata elements?

  • +
  • How should we relate the DICOM standard values to JSON? For example, how +should we store dates and times? One option would be to use the new DICOM +JSON encoding for DICOM values, but omitting the tag and value +representation (VR). For example, the DICOM JSON spec has:

    +
    "00080070": {
    +    "vr": "LO",
    +    "Value": [ "SIEMENS" ]
    +},
    +
    +
    +

    but we might prefer:

    +
    "Manufacturer": "SIEMENS"
    +
    +
    +

    Using the DICOM data dictionary we can reconstruct the necessary tag and VR, +so our version is lossless if the DICOM keyword exists in the DICOM data +dictionary. Of course this may well not be true for private tags, or if the +keyword comes from a DICOM dictionary that is later than the one we are +using to look up the keyword. For the latter, we could make sure we’re +always using the latest dictionary. For the private tags, we might want to +recode these in any case, maybe using our own dictionary. Maybe it is +unlikely we will want to reconstruct the private tags of a DICOM file from +the JSON. Comments welcome.

    +
  • +
+
+
+

The header will usually contain axis namesΒΆ

+

axis_names is a list of strings corresponding to the axes of the image data +to which the header refers.

+
>>> hdr = dict(nipy_header_version='1.0',
+...            axis_names=["frequency", "phase", "slice", "time"])
+
+
+

The names must be valid Python identifiers (should not begin with a digit, nor +contain spaces etc).

+

There must be the same number of names as axes in the image to which the header +refers. For example, the header above is valid for a 4D image but invalid for a +3D or 5D image.

+

The names appear in fastest-slowest order in which the image data is stored on +disk. The first name in axis_names corresponds to the axis over which +the data on disk varies fastest, and the last corresponds to the axis over which +the data varies slowest.

+

For a NIfTI image, nibabel (and nipy) will create an image where the axes have +this same fastest to slowest ordering in memory. For example, let’s say the +read image is called img. img has shape (4, 5, 6, 10), and a 2-byte +datatype such as int16. In the case of the NIfTI default fastest-slowest ordered +array, the distance in memory between img[0, 0, 0, 0] and img[1, 0, 0, +0] is 2 bytes, and the distance between img[0, 0, 0, 0] and img[0, 0, 0, +1] is 4 * 5 * 6 * 2 = 240 bytes. The names in axis_names will then refer +to the first, second, third and fourth axes respectively. In the example above, +β€œfrequency” is the first axis and β€œtime” is the last.

+

axis_names is optional only if axis_metadata is empty or absent. +Otherwise, the set() of axis_names must be a superset of the union of +all axis names specified in the applies_to fields of axis_metadata +elements.

+
+
+

The header will often contain axis metadataΒΆ

+

axis_metadata is a list of axis metadata elements.

+

Each axis metadata element in the axis_metadata list gives data that +applies to a particular axis, or combination of axes. axis_metadata can +be empty:

+
>>> hdr['axis_metadata'] = []
+
+
+

We prefer you delete this section if it is empty, to avoid clutter, but hey, +mi casa, su casa.

+
+

The axis metadata elementΒΆ

+

An axis metadata element must contain a field applies_to, with a value that +is a list that contains one or more values from axis_names. From the above +example, the following would be valid axis metadata elements:

+
>>> hdr = dict(nipy_header_version='1.0',
+...            axis_names = ["frequency", "phase", "slice", "time"],
+...            axis_metadata = [
+...                dict(applies_to = ['time']),
+...                dict(applies_to = ['slice']),
+...                dict(applies_to = ['slice', 'time']),
+...            ])
+
+
+
+

Note

+

The applies_to field plays the role of a dictionary key for each axis +metadata element, where the rest of the fields in the element are a dict +giving the value. For example, in Python (but not in JSON, we could +represent the above as:

+
>>> hdr = dict(nipy_header_version='1.0',
+...            axis_names = ["frequency", "phase", "slice", "time"],
+...            axis_metadata = {
+...                'time': {},
+...                'slice': {},
+...                ('slice', 'time'): {},
+...            ])
+
+
+

We can’t do this in JSON because all object fields must be strings, so we +cannot represent the key ('slice', 'time') directly. The +applies_to field allows us to do that in JSON. See below for why we +might want to specify more than one axis.

+
+

As for image metadata keys, keys that begin with a capital letter are DICOM +standard keywords.

+

A single axis name for applies_to specifies that any axis metadata values in +the element apply to the named axis.

+

In this case, axis metadata values may be:

+
    +
  • a scalar. The value applies to every point along the corresponding image +axis OR

  • +
  • a vector of length N (where N is the length of the corresponding image +axis). Value \(v_i\) in the vector \(v\) corresponds to the image slice at +point \(i\) on the corresponding axis OR

  • +
  • an array of shape (1, …) where β€œβ€¦β€ can be any further shape, expressing +a vector or array that applies to all points on the given axis, OR

  • +
  • an array of shape (N, …) where β€œβ€¦β€ can be any further shape. The (N, +…) array N vectors or arrays with one (vector or array) corresponding to +each point in the image axis.

  • +
+

More than one axis name for applies_to specifies that any values in the +element apply to the combination of the given axes.

+

In the case of more than one axis for applies_to, the axis metadata values +apply to the Cartesian product of the image axis values. For example, if the +values of applies_to == ['slice', 'time'], and the slice and time axes +in the array are lengths (6, 10) respectively, then the values apply to all +combinations of the 6 possible values for slice indices and the 10 possible +values for the time indices (ie apply to all 6x10=60 values). The axis metadata +values in this case can be:

+
    +
  • a scalar. The value applies to every combination of (slice, time)

  • +
  • an array of shape (S, T) (where S is the length of the slice axis and T is +the length of the time axis). Value \(a_{i,j}\) in the array \(a\) corresponds +to the image slice at point \(i\) on the slice axis and \(j\) on the time axis.

  • +
  • an array of shape (S, T, …) where β€œβ€¦β€ can be any further shape. The (S, +T, …) case gives N vectors or arrays with one vector / array corresponding +to each combination of slice, time points in the image,

  • +
+

In contrast to the single axis case, we do not allow length 1 axes, to +indicate a value constant across an axis. For example, we do not allow shape +(1, T) arrays to indicate a value constant across slice but varying across +time, as this should be specified with the single time axis metadata element.

+

In general, for a given value applies_to, we can take the corresponding +axis lengths:

+
>>> shape_of_image = [4, 5, 6, 10]
+>>> image_names = ['frequency', 'phase', 'slice', 'time']
+>>> applies_to = ['slice', 'time']
+>>> axis_indices = [image_names.index(name) for name in applies_to]
+>>> axis_lengths = [shape_of_image[i] for i in axis_indices]
+>>> axis_lengths
+[6, 10]
+
+
+

The axis metadata value can therefore be of shape:

+
    +
  • () (a scalar) (a scalar value for every combination of points);

  • +
  • axis_lengths (a scalar value for each combination of points);

  • +
  • [1] + any_other_list if len(axis_lengths) == 1;

  • +
  • axis_lengths + any_other_list (an array or vector corresponding to each +combination of points, where the shape of the array or vector is given by +any_other_list)

  • +
+

For any unique ordered combination of axis names, there can only be on axis +metadata element. For example, this is valid:

+
>>> # VALID
+>>> hdr = dict(nipy_header_version='1.0',
+...            axis_names = ["frequency", "phase", "slice", "time"],
+...            axis_metadata = [
+...                dict(applies_to = ['time']),
+...                dict(applies_to = ['slice', 'time']),
+...                dict(applies_to = ['slice']),
+...            ])
+
+
+

This is not, because of the repeated combination of axis names:

+
>>> # NOT VALID because of repeated axis combination
+>>> hdr = dict(nipy_header_version='1.0',
+...            axis_names = ["frequency", "phase", "slice", "time"],
+...            axis_metadata = [
+...                dict(applies_to = ['time']),
+...                dict(applies_to = ['slice', 'time']),
+...                dict(applies_to = ['slice']),
+...                dict(applies_to = ['slice', 'time']),
+...            ])
+
+
+
+
+

The q_vector axis metadata fieldΒΆ

+

We define an axis metadata field q_vector which gives the q vector +corresponding to the diffusion gradients applied.

+

The q_vector should apply to (applies_to) one axis, where that axis is +the image volume axis. The q_vector is a dict / object with two fields, +spatial_axes and array.

+

If there are T volumes then the array will be of shape (T, 3). One row from +this array corresponds to the direction of the diffusion gradient with axes +oriented to the three spatial axes of the data. To preserve the axis +transpose principle, the spatial_axes field value is a list of the +spatial image axes to which the first, second and third column of the +array refer.

+

For example:

+
>>> import numpy as np
+>>> element = dict(applies_to=['time'],
+...                q_vector = dict(
+...                   spatial_axes = ['frequency', 'phase', 'slice'],
+...                   array = [[0, 0, 0],
+...                            [1000, 0, 0],
+...                            [0, 1000, 0],
+...                            [0, 0, 1000],
+...                            [0, 0, 0],
+...                            [1000, 0, 0],
+...                            [0, 1000, 0],
+...                            [0, 0, 1000],
+...                            [0, 0, 0],
+...                            [1000, 0, 0]
+...                           ]))
+>>> np.array(element['q_vector']['array']).shape
+(10, 3)
+
+
+

An individual (3,) vector is the unit vector expressing the direction of the +gradient, multiplied by the scalar b value of the gradient. In the example, +there are three b == 0 scans (corresponding to volumes 0, 4, 8), with the rest +having b value of 1000.

+

The first value corresponds to the direction along the first named image axis +(β€˜frequency’), the second value to direction along the second named axis +(β€˜phase’), and the third to direction along the β€˜slice’ axis.

+

Note that the q_vector is always specified in the axes of the image. This is +the same convention as FSL uses for its bvals and bvecs files.

+
+
+

acquisition_times fieldΒΆ

+

This gives a list of times of acquisition of each spatial unit of data.

+

acquisition_times can apply to (applies_to) slices or to volumes or to +both.

+

Units are milliseconds and can be expressed as integers or as floating point. +Milliseconds is a reasonable choice for units because a Python integer can +decode / encode any integer number in the JSON correctly, a signed 32-bit int +can encode to around 6000 hours, and a 32-bit float can encode to 23 hours +without loss of precision.

+
+
+
+

acquisition_times applying to slicesΒΆ

+

If acquisition_times applies to an image axis representing slices, then the +array should be of shape (S,) where S is the number of slices. Each value +\(a_i\) represents the time of acquisition of slice \(i\), relative to the start +of the volume, in milliseconds. For example, to specify an ascending +sequential slice acquisition scheme:

+
>>> element = dict(applies_to=['slice'],
+...                acquisition_times=[0, 20, 40, 60, 80, 100])
+
+
+

We use β€œslice” as the axis name here, but any name is valid.

+

NIfTI 1 and 2 can encode some slice acquisition times using a somewhat +complicated scheme, but they cannot - for example - encode multi-slice +acquisitions, and NIfTI slice time encoding is rarely set. According to the +C-struct primacy principle, if the slice timing is set, it overrides this +acquisition_times field. Slice timing is set in the C-struct if the +slice_code +in the C-struct is other than 0 (=unknown). The specific slice times from the +C-struct also depend on C-struct fields slice_start and slice_end.

+
+
+

acquisition_times applying to volumesΒΆ

+

When acquisition_times` applies to a volume axis, it is a list of times of +acquisition of each volume in milliseconds relative to the beginning of the +acquisition of the run.

+

These values can be useful for recording runs with missing or otherwise +not-continuous time data.

+

We use β€œtime” as the axis name, but any name is valid.

+
>>> element = dict(applies_to=['time'],
+...                acquisition_times=[0, 120, 240, 480, 600])
+
+
+

The NIfTI C-struct can encode a non-zero start point for volumes, using the +toffset +field. If this is not-zero, and not equal to the first value in +acquisition_times, JSON acquisition times applying to volumes are ignored. +The C-struct slice_code field (see above) is not relevant to volume times, +and can have any value.

+
+
+

acquisition_times applying to slices and volumesΒΆ

+

When acquisition_times` applies to both a slice and a volume axis, it is a +list of times of acquisition of each slice in each volume in milliseconds +relative to the beginning of the acquisition of the run.

+
>>> element = dict(applies_to=['slice', 'time'],
+...                acquisition_times = [[0, 100, 200],
+...                                     [10, 110, 210],
+...                                     [20, 120, 220],
+...                                     [30, 130, 230],
+...                                     [40, 140, 240]]
+...           )
+
+
+

This meaning becomes invalid with non-zero and conflicting values for +slice_code or toffset in the C-struct. Conflicting values are values +different from those implied from a strict per-volume repetition of the +acquisition times from slice_code, slice_start, slice_end, starting at +toffset.

+
+
+

axis_meanings fieldΒΆ

+

So far we are allowing any axis to be a slice or volume axis, but it might be +nice to check. One way of doing this is:

+
>>> element = dict(applies_to=['mytime'],
+...                axis_meanings=["volume", "time"],
+...                acquisition_times=[0, 120, 240, 480, 600])
+>>> element = dict(applies_to=['myslice'],
+...                axis_meanings=["slice"],
+...                acquisition_times=[0, 20, 40, 60, 80, 100])
+
+
+

In this case we can assert that acquisition_times applies to an axis with +meanings that include β€œslice” or that it applies to an axis with meaning +β€œvolume”. For example:

+
>>> # Should raise an error on reading full JSON
+>>> element = dict(applies_to=['myslice'],
+...                axis_meanings=["frequency"],
+...                acquisition_times=[0, 20, 40, 60, 80, 100])
+
+
+

Being able to specify meanings that apply to more than one axis might also +help for the situation where there is more than one frequency axis:

+
>>> hdr = dict(nipy_header_version='1.0',
+...            axis_names = ["frequency1", "frequency2", "slice", "time"],
+...            axis_metadata = [
+...                dict(applies_to = ["frequency1"],
+...                     axis_meanings = ["frequency"]),
+...                dict(applies_to = ["frequency2"],
+...                     axis_meanings = ["frequency"]),
+...                dict(applies_to = ['slice'],
+...                     axis_meanings = ["slice"]),
+...                dict(applies_to = ['time'],
+...                     axis_meanings = ["time", "volume"]),
+...            ])
+
+
+

We can also check that space axes really are space axes:

+
>>> hdr = dict(nipy_header_version='1.0',
+...            axis_names = ["frequency", "phase", "slice", "time"],
+...            axis_metadata = [
+...                dict(applies_to = ["frequency"],
+...                     axis_meanings = ["frequency", "space"]),
+...                dict(applies_to = ["phase"],
+...                     axis_meanings = ["phase", "space"]),
+...                dict(applies_to = ["slice"],
+...                     axis_meanings = ["slice", "space"]),
+...                dict(applies_to = ["time"],
+...                     axis_meanings = ["time", "volume"]),
+...                dict(applies_to=["time"],
+...                     q_vector = dict(
+...                        spatial_axes = ["frequency", "phase", "slice"],
+...                        array = [[0, 0, 0],
+...                                 [1000, 0, 0]]))
+...                ])
+
+
+

For the q_vector field, we can check that all of the spatial_axes axes +(β€œfrequency”, β€œphase”, β€œslice”) do in fact have meaning β€œspace”.

+

For this check to pass, either of these must be true:

+
    +
  • no axes are labeled with the meaning β€œspace” OR

  • +
  • the only three axes with label β€œspace” are those named in spatial_axes.

  • +
+
+

multi_affine fieldΒΆ

+
+
Use caseΒΆ
+

When doing motion correction on a 4D image, we calculate the required affine +transformation from, say, the second image to the first image; the +third image to the first image; etc. If there are N volumes in the 4D image, +we would need to store N-1 affine transformations. If we have registered to +the mean volume of the volume series instead of one of the volumes in the +volume series, then we need to store all N transforms.

+

We often want to store this set of required transformations with the image, +but NIfTI does not allow us to do that. SPM therefore stores these transforms +in a separate MATLAB-format .mat file. We currently don’t read these +transformations because we have no API in nibabel to present or store multiple +affines.

+
+
+
ImplementationΒΆ
+

Assume the 4D volume has T time points (volumes).

+

There are two ways we could implement the multi-affines. The first would be to +have (T x 3 x 4) array of affines, with one for each volume / time point, +and a spatial_axes field specifying the input axes for the affine. This +is the same general idea as the q_vector field:

+
>>> element = dict(applies_to=['time'],
+...                multi_affine = dict(
+...                    spatial_axes = ['frequency', 'phase', 'slice'],
+...                    array = [[[   2.86,   -0.7 ,    0.83,  -80.01],
+...                               [   0.71,    2.91,    0.01, -114.59],
+...                               [  -0.54,    0.13,    4.42,  -54.34]],
+...                              [[   2.87,   -0.38,    1.19,  -92.77],
+...                               [   0.31,    2.97,    0.45, -110.87],
+...                               [  -0.82,   -0.2 ,    4.32,  -33.89]],
+...                              [[   2.97,   -0.39,    0.31,  -78.95],
+...                               [   0.33,    2.9 ,    1.06, -116.99],
+...                               [  -0.29,   -0.68,    4.36,  -36.41]],
+...                              [[   2.93,   -0.5 ,    0.61,  -78.02],
+...                               [   0.4 ,    2.9 ,    0.99, -118.9 ],
+...                               [  -0.5 ,   -0.59,    4.35,  -33.61]],
+...                              [[   2.95,   -0.44,    0.49,  -77.86],
+...                               [   0.3 ,    2.78,    1.62, -125.83],
+...                               [  -0.46,   -1.03,    4.17,  -21.66]]]))
+>>> np.array(element['multi_affine']['array']).shape
+(5, 3, 4)
+
+
+

This obeys the axis transpose principle, because the spatial axes are +specified. If the user transposes the image, the order of axis names in +axis_names changes, but the correspondence between axis names and affine +columns is still correctly encoded in the spatial_axes.

+

Another option would be to partially follow the NRRD format in giving the column vectors +from the affine to the axis to which they apply, and split the translation +into a separate offset vector:

+
>>> hdr = dict(nipy_header_version='1.0',
+...            axis_names = ["time"],
+...            axis_metadata = [
+...                dict(applies_to=['time'],
+...                     output_vector=dict(
+...                        spatial_axis = ['frequency'],
+...                        array = [
+...                                 [ 2.86, 0.71, -0.54],
+...                                 [ 2.87, 0.31, -0.82],
+...                                 [ 2.97, 0.33, -0.29],
+...                                 [ 2.93, 0.4 , -0.5 ],
+...                                 [ 2.95, 0.3 , -0.46],
+...                                 ])),
+...                dict(applies_to=['time'],
+...                     output_vector=dict(
+...                        spatial_axis = ['phase'],
+...                        array = [
+...                                 [ -0.7 , 2.91,  0.13],
+...                                 [ -0.38, 2.97, -0.2 ],
+...                                 [ -0.39, 2.9 , -0.68],
+...                                 [ -0.5 , 2.9 , -0.59],
+...                                 [ -0.44, 2.78, -1.03],
+...                                 ])),
+...                dict(applies_to=['time'],
+...                     output_vector = dict(
+...                        spatial_axis = ['slice'],
+...                        array = [
+...                                 [ 0.83, 0.01, 4.42],
+...                                 [ 1.19, 0.45, 4.32],
+...                                 [ 0.31, 1.06, 4.36],
+...                                 [ 0.61, 0.99, 4.35],
+...                                 [ 0.49, 1.62, 4.17],
+...                                 ])),
+...                dict(applies_to=['time'],
+...                     output_offset = [
+...                              [ -80.01, -114.59, -54.34],
+...                              [ -92.77, -110.87, -33.89],
+...                              [ -78.95, -116.99, -36.41],
+...                              [ -78.02, -118.9,  -33.61],
+...                              [ -77.86, -125.83, -21.66],
+...                              ])],
+...           )
+>>> np.array(hdr['axis_metadata'][0]['output_vector']['array']).shape
+(5, 3)
+>>> np.array(hdr['axis_metadata'][1]['output_vector']['array']).shape
+(5, 3)
+>>> np.array(hdr['axis_metadata'][2]['output_vector']['array']).shape
+(5, 3)
+>>> np.array(hdr['axis_metadata'][3]['output_offset']).shape
+(5, 3)
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0004.html b/devel/biaps/biap_0004.html new file mode 100644 index 0000000000..aa1c2a589f --- /dev/null +++ b/devel/biaps/biap_0004.html @@ -0,0 +1,342 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP4 - Merging nibabel and dcmstackΒΆ

+
+
Author:
+

Brendan Moloney, Matthew Brett

+
+
Status:
+

Draft

+
+
Type:
+

Standards

+
+
Created:
+

2012-11-21

+
+
+

In which we set out what dcmstack does and how it might integrate with the +nibabel objects and functions.

+
+

MotivationΒΆ

+

It is very common to convert source DICOM images to another format, typically +Nifti, before doing any image processing. The Nifti format is significantly +easier to work with and has wide spread compatibility. However, the vast +amount of meta data stored in the source DICOM files will be lost.

+

After implementing this proposal, users will be able to preserve all of the +meta data from the DICOM files during conversion, including meta data from +private elements. The meta data will then be easily accessible through the +SpatialImage API:

+
>>> nii = nb.load('input.nii')
+>>> data = nii.get_data()
+>>> print data.shape
+(256, 256, 24, 8)
+>>> print nii.get_meta('RepetitionTime')
+3500.0
+>>> echo_times = [nii.get_meta('EchoTime', (0, 0, 0, idx))
+                  for idx in xrange(data.shape[-1])]
+>>> print echo_times
+[16.4, 32.8, 49.2, 65.6, 82.0, 98.4, 114.8, 131.2]
+>>> print nii.get_meta('AcquisitionTime', (0, 0, 1, 0))
+110455.370000
+>>> print nii.get_meta('AcquisitionTime', (0, 0, 2, 0))
+110457.272500
+>>> print nii.get_meta('AcquisitionTime', (0, 0, 1, 1))
+110455.387500
+
+
+
+
+

OverviewΒΆ

+

dcmstack reads a series of DICOM images, works out their relationship in terms +of slices and volumes, and compiles them into multidimensional volumes. It can +produce the corresponding data volume and affine, or a Nifti image (with any +additional header information set appropriately).

+

In the course of the read, dcmstack creates a DcmMeta object for +each input file. This object is an ordered mapping that can contain a copy +of all the meta data in the DICOM header. By default some filtering is +applied to reduce the chance of including PHI. The set of DcmMeta objects are +then merged together in the same order as the image data to create a single +DcmMeta object that summarizes all of the meta data for the series.

+

To summarize the meta data, each element is classified based on how the values +repeat (e.g. const, per_slice, per_volume, etc.). Each element has a name (the +keyword from the DICOM standard) and one or more values (the number of values +depends on the classification and the shape of the image). Each classification’s +meta data is stored stored in a separate nested dictionary.

+

While creating the Nifti image output, the DcmMeta is stored in a +DcmMetaExtension which can be added as a header extension. This extension +simply does a JSON encoding directly on the DcmMeta object.

+

When working with these images, it’s possible to keep track of the +meta-information in the DcmMetaExtension. For example, when taking slice out +of a 3D volume, we keep track of the information specific to the chosen +slice, and remove information for other slices. Or when merging 3D volumes to +a 4D time series, we want to merge together the meta data too.

+

At the moment, dcmstack only creates Nifti images. There’s no reason that this +should be so, and the relationship of dcmstack to other spatial images should be +more flexible.

+
+
+

IssuesΒΆ

+
+

DcmMetaExtension tied to NiftiExtensionΒΆ

+

At the moment, DcmMetaExtension inherits from the NiftiExtension, allowing +the data to be dumped out to JSON when writing into the extension part of a +Nifti header.

+

There’s no reason that the DcmMetaExtension should be tied to the Nifti +format.

+
+

PlanΒΆ

+

Refactor DcmMetaExtension to inherit from object. Maybe rename DcmMeta or +something. Make a NiftiExtension object when needed with a new object +wrapping the DcmMeta in the Extension API?

+
+
+

StatusΒΆ

+

Resolved. We now have a separate DcmMeta object which inherits from +OrderedDict and contains all of the functionality previously in +DcmMetaExtension except those related to acting as a Nifti1Extension. +The DcmMetaExtension now provides just the functionality for being +a Nifti1Extension.

+
+
+
+

Keeping track of metadata when manipulating imagesΒΆ

+

When slicing images, it is good to be able to keep track of the relevant DICOM +metadata for the particular slice. Or when merging images, it is good to be +able to compile the metadata across slices into the (e.g) volume metadata. Or, +say, when coregistering an image, it is good to be able to know that the +metadata that is per-slice no longer directly corresponds to a slice of the +data array.

+

At the moment, dcmstack deals with this by wrapping the image with DICOM meta +information in NiftiWrapper object : see +https://github.com/moloney/dcmstack/blob/d157741/src/dcmstack/dcmmeta.py#L1232. +This object accepts a Nifti image as input, that usually contains a +DcmMetaExtension, and has methods get_meta (to get metadata from extension), +split (for taking slice specific metadata into the split parts), meta_valid +to check the metadata against the Nifti information, and methods to remove / +replace the extension, save to a filename, and create the object with various +alternative classmethod constructors.

+

In particular, the meta_valid method needs to know about both the enclosed +image, and the enclosed meta data.

+

Can we put this stuff into the SpatialImage image object of nibabel, so we +don’t need this wrapper object?

+
+

PlanΒΆ

+

Put the DcmMeta data into the extra object that is input to the +SpatialImage and all other nibabel image types.

+

Add a get_meta method to SpatialImage that uses the to-be-defined API of the +extra object. Maybe, by default, this would just get keys out of the mapping.

+

Define an API for the extra object to give back metadata that is potentially +varying (per slice or volume). We also need a way to populate the extra object +when loading an image that has an associated DcmMeta object.

+

Use this API to get metadata. Try and make this work with functions outside the +SpatialImage such as four_to_three and three_to_four in nibabel.funcs. +These functions could use the extra API to get varying meta-information.

+

** TODO : specific proposal for SpatialImage and extra API changes **

+
+
+
+

Detecting slice or volume-specific data difficult for 3D and 4D DICOMSΒΆ

+

The DcmMeta object needs to be able to identify slice and volume specific +information when reading the DICOM, so that it can correctly split the resulting +metadata, or merge it.

+

This is easy for slice-by-slice DICOM files because anything that differs +between the slices is by definition slice-specific. For 3D and 4D data, such as +Siemens Mosaic, some of the fields in the private headers contains +slice-by-slice information for the volume contained. There’s not automatic way +of detecting slice-by-slice information in this case, so we have to specify +which fields are slice-by-slice when reading. That is, we need to specialize +the DICOM read for each type of volume-containing DICOM - such as Mosaic or the +Philips multi-frame format.

+
+

PlanΒΆ

+

Add create_dcmmeta method to the nibabel DICOM wrapper objects, that can be +specialized for each known DICOM format variation. Put the rules for slice +information etc into each class.

+

For the Siemens files, we will need to make a list of elements from the private +CSA headers that are known to be slice specific. For the multiframe DICOM files +we should be able to do this in a programmatic manner, since the varying data +should live in the PerFrameFunctionalSequence DICOM element. Each element that +is reclassified should be simplified with the DcmMeta.simplify method so that +it can be classified appropriately.

+
+
+
+

Meta data in nested DICOM sequences can not be independently classifiedΒΆ

+

The code for summarizing meta data only works on the top level of key/value +pairs. Any value that is a nested dataset is treated as a single entity, +which prevents us from classifying its individual elements differently.

+

In a DICOM data set, any element that is a sequence contains one or more +nested DICOM data sets. For most MRI images this is not an issue since +they rarely contain many sequences, and the ones they do are usually small +and relatively unimportant. However in multiframe DICOM files make heavy +use of nested sequences to store data.

+
+

PlanΒΆ

+

This same issue was solved for the translated Siemens CSA sub headers by +unpacking each nested dataset by joining the keys from each level with a +dotted notation. For example, in the CsaSeries subheader there is a nested +MrPhoenixProtocol dataset which has an element ulVersion so the key we +use after unpacking is CsaSeries.MrPhoenixProtocol.ulVersion.

+

We can take the same approach for DICOM sequence elements. One additional +consideration is that each of these element is actually a list of data sets, +so we would need to add an index number to the key somehow.

+

The alternative is to handle nested data sets recursively in the meta data +summarizing code. This would be fairly complex and you would no longer be +able to refer to each element with a single string, at least not without +some mini-language for traversing the nested datasets.

+
+
+
+

Improving access to varying meta data through the NiftiΒΆ

+

Currently, when accessing varying meta data through the get_meta method +you can only get one value at a time:

+
>>> echo_times = [nii.get_meta('EchoTime', (0, 0, 0, idx))
+                  for idx in xrange(data.shape[-1])]
+
+
+

You can easily get multiple values from the DcmMeta object itself, but +then you lose the capability to automatically check if the meta data is +valid in relation to the current image.

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0005.html b/devel/biaps/biap_0005.html new file mode 100644 index 0000000000..c71bcc478f --- /dev/null +++ b/devel/biaps/biap_0005.html @@ -0,0 +1,271 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP5 - A streamlines converterΒΆ

+
+
Author:
+

Marc-Alexandre CΓ΄tΓ©

+
+
Status:
+

Draft

+
+
Type:
+

Standards

+
+
Created:
+

2013-09-03

+
+
+

The first objective of this proposal is to add support to other streamlines +format. The second objective is to be able to easily convert from one file +format to another.

+
+

MotivationΒΆ

+

There are a couple of different formats for saving streamlines to a file. +Currently, NiBabel only support one of them: TRK from Trackvis. NiBabel could greatly benefit from supporting +other formats: +TCK +(MRtrix), +VTK +(Camino, MITK) +and more. Moreover, being able to move from one format to another would be +convenient. To ease the conversion process, a generic format from which to +inherit and some common header fields would be necessary. This is similar to +what NiBabel already has for neuroimages.

+

After implementing this proposal, users could load and use streamlines file like this:

+
>>> import nibabel as nib
+>>> f = nib.streamlines.load('my_trk.trk', lazy_load=False)
+>>> type(f)
+nibabel.streamlines.base_format.Streamlines
+>>> f.points
+[array([ [1, 1, 1],
+         [2, 2, 2],
+         [3, 3, 3] ]),
+ array([ [4, 4, 4],
+         [5, 5, 5] ])]
+>>> nib.streamlines.convert('my_trk.trk', 'my_tck.tck')
+>>> f2 = nib.streamlines.load('my_trk.tck', lazy_load=False)
+>>> type(f2)
+nibabel.streamlines.base_format.Streamlines
+>>> f2.points
+[array([ [1, 1, 1],
+         [2, 2, 2],
+         [3, 3, 3] ]),
+ array([ [4, 4, 4],
+         [5, 5, 5] ])]
+
+
+

Of course, similar functions will be available for β€˜scalars’ (per point) and β€˜properties’ (per streamline) as defined in the TrackVis format. A simple example to save three streamlines with no scalars nor properties would look like this:

+
>>> import nibabel as nib
+>>> points = [np.arange(1*3).reshape((1,3)),
+              np.arange(2*3).reshape((2,3)),
+              np.arange(5*3).reshape((5,3))]
+>>> streamlines = nib.streamlines.Streamlines(points)
+>>> nib.streamlines.save(streamlines, 'data1.trk')  # Default TRK header is used but updated with streamlines information.
+
+>>> FA = nib.load('FA.nii')
+>>> streamlines.header = nib.streamlines.header.from_nifti(FA)  # Uses information of the FA to create an header.
+>>> nib.streamlines.save(streamlines, 'data2.trk')  # Streamlines' header is used but also updated with streamlines information.
+
+>>> from nib.streamlines.header import VOXEL_ORDER, VOXEL_SIZES
+>>> hdr = nib.streamlines.TrkFile.get_empty_header()  # Default TRK header
+>>> hdr[VOXEL_ORDER] = "LAS"
+>>> hdr[VOXEL_SIZES] = (2, 2, 2)
+>>> streamlines.header = hdr
+>>> nib.streamlines.save(streamlines, 'data3.trk')  # Uses hdr to create a TRK header.
+
+
+
+
+

OverviewΒΆ

+

All code related to managing streamlines should be kept in a separate folder: +nibabel.streamlines. A first file, base_format.py, would contain base +classes acting as general interfaces from which new streamlines file format +will inherit.

+

Streamlines would be represented by its own class Streamlines which will +have three main properties: points, scalars and properties. +Streamlines objects can be iterate over producing tuple of points, +scalars and properties for each streamline.

+

The generic class StreamlinesFile would look like this:

+
class StreamlinesFile:
+    @classmethod
+    def get_magic_number(cls):
+        raise NotImplementedError()
+
+    @classmethod
+    def is_correct_format(cls, fileobj):
+        raise NotImplementedError()
+
+    @classmethod
+    def get_empty_header(cls):
+        raise NotImplementedError()
+
+    @classmethod
+    def load(cls, fileobj, lazy_load=True):
+        raise NotImplementedError()
+
+    @classmethod
+    def save(cls, streamlines, fileobj):
+        raise NotImplementedError()
+
+    @staticmethod
+    def pretty_print(streamlines):
+        raise NotImplementedError()
+
+
+

When inheriting from a base class, a specific streamline format class should know how to do its i/o, in particular how to iterate through the streamlines without loading the whole file into memory.

+

Once, the right interface is in place, the conversion part should be quite easy. Moreover, the conversion could be done without loading the input file entirely into memory thanks to generators. Actually, the convert function should looks like this:

+
def convert(in_fileobj, out_filename):
+    # Loading part
+    streamlines_file = detect_format(in_fileobj)
+    streamlines = streamlines_file.load(in_fileobj, lazy_load=True)
+
+    # Saving part
+    streamlines_file = detect_format(out_filename)
+    streamlines_file.save(streamlines, out_filename)
+
+
+

Of course, this implies some sort of general header compatibility between every format.

+
+
+

IssuesΒΆ

+ +
+
+

Future WorkΒΆ

+

A first interesting subclass would be the DynamicStreamlineFile offering +a way to append streamlines to an existing file when format permits it.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0006.html b/devel/biaps/biap_0006.html new file mode 100644 index 0000000000..a4f8874bc7 --- /dev/null +++ b/devel/biaps/biap_0006.html @@ -0,0 +1,362 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP6 - Identifying image axesΒΆ

+
+
Author:
+

Matthew Brett

+
+
Status:
+

Draft

+
+
Type:
+

Standards

+
+
Created:
+

2015-07-11

+
+
+
+

BackgroundΒΆ

+

Image axes can have meaningful labels.

+

For example in a typical 4D NIfTI file, as we move along the 4th dimension in +the image array, we are also moving in time. For example, this would be the +first volume (in time):

+
img = nibabel.load('my_4d.nii')
+data = img.get_data()
+vol0 = data[..., 0]
+
+
+

and this would be second volume in time:

+
vol1 = data[..., 1]
+
+
+

It would therefore be reasonable to label the 4th axis of this image as β€˜time’ +or β€˜t’.

+

We need to know which axis is the β€œtime” axis for many reasons, including +being able to select whole image volumes to align during motion correction, +and doing spatial smoothing, where we want to avoid smoothing along the time +dimension.

+

It is common to acquire MRI images one slice at a time. In a 3D or 4D NIfTI, +the 3rd axis often contains these slices. So this these would be the first +and second slices of data collected by the scanner:

+
slice0 = vol0[:, :, 0]
+slice1 = vol0[:, :, 1]
+
+
+

In this case we might refer to the 3rd axis as the β€œslice” axis. We might +care about knowing the β€œslice” axis, because we do processing specific to the +slice axis, such as slice-timing correction.

+

For an individual 2D slice, MRI physicists distinguish between the image axis +encoded during a single continual readout of the signal (frequency encoding +direction) and the image axis encoded in a series of stepwise changes in the +phase encode gradient (phase encoding direction). We care about the phase +encoding direction because we usually correct for image distortion only along +this direction.

+

Let us say that the first axis is the frequency encoding axis, and the second +is the phase encoding axis. Now we can label all four of our axes:

+
    +
  • β€œfrequency”;

  • +
  • β€œphase”;

  • +
  • β€œslice”;

  • +
  • β€œtime”.

  • +
+

In fact the NIfTI format can store this information. NIfTI specifies that the +fourth image dimension should have units in terms of time (seconds), frequency +(Hertz, radians per second) or concentration (parts per million), where the +value difference between elements on the fourth axis is in +img.header['pixdim'][4], and the units of this difference are available in +img.header['xyzt_units']. The field img.header['dim_info'] can +identify the frequency, phase and slice-encoding axes.

+
+

Time axis as the fourth axisΒΆ

+

In the NIfTI standard, time must be the fourth dimension.

+

In fact, the NIfTI standard specifies that the fourth axis must be time. If +we want to store more than one volume that do not differ across time, then we +have to set the 4th dimension to be length 1, and have 5th dimension have +length > 1. Quoting from the standard:

+
In NIFTI-1 files, dimensions 1,2,3 are for space, dimension 4 is for time,
+and dimension 5 is for storing multiple values at each spatiotemporal
+voxel.
+
+
+

This arrangement happens in practice. For example, SPM deformation fields +have three values for each voxel (x, y, z displacement), and have shape (I, J, +K, 1, 3):

+
In [7]: img = nib.load('y_highres001.nii')
+In [8]: img.shape
+Out[8]: (121, 145, 121, 1, 3)
+
+
+

So, for correctly written NIfTI images, we can identify time by the fact that +it is the fourth axis.

+

MGH format also appears to use the fourth dimension for time. The dimensions +are listed in order width, height, depth, nframes and β€œframes” is always +the slowest changing dimension in the image data buffer. Of course, in numpy, +this does not tell us which axis this must be in the returned array, but at +least the load_mgh.m MATLAB function (see MGH format) returns the frame +axis as the last axis, as does nibabel.

+

The ECAT and PAR / REC formats seem to be primarily based on and stored as +slices (2D arrays) which can then be concatenated to form volumes, implying a +slowest-changing axis of volume. Nibabel currently arranges PAR images with +volume as the 4th and last axis.

+

On the other hand, the MINC format:

+
    +
  1. gives specific names to the image data axes so we can directly find the +time axis

  2. +
  3. expects (given the common ordering of these names in MINC files) that the +time axis will be first:

    +
    In [31]: mnc2 = h5py.File('nibabel/tests/data/minc2_4d.mnc', 'r')['minc-2.0']
    +In [32]: mnc2['dimensions'].values()
    +Out[32]:
    +[<HDF5 dataset "time": shape (2,), type "<f8">,
    +<HDF5 dataset "xspace": shape (), type "<i4">,
    +<HDF5 dataset "yspace": shape (), type "<i4">,
    +<HDF5 dataset "zspace": shape (), type "<i4">]
    +
    +
    +
  4. +
+

This reflects MINC’s lineage as C-library, where the C convention is for the +first axis in an array is the slowest changing. arr[0] in a C-convention +4D array would be the first volume, where time (volume) is the slowest +changing axis.

+

MINC2 uses HDF5 storage, and HDF5 uses C storage order for standard contiguous +arrays on disk - see β€œ7.3.2.5. C versus Fortran Dataspaces” in chapter 7 of +the HDF5 user guide.

+

BrainVoyager STC files store data in (fastest to +slowest changing) order: columns (of slice); rows (of slice); time; slice. The +VTC stores the data in the (fast to slow) order: +time; Anterior->Posterior; Superior->Inferior; Left->Right.

+
+
+

Images can have more than four axesΒΆ

+

We’ve already seen the example of NIfTI images where the 4th axis is length 1 +and the 5th axis is length 3, encoding a deformation field.

+

This is a trick NIfTI uses to allow us to identify the β€œtime” axis.

+

We can also have (rarely) images of 5D, where the time axis has length > 1. +For example, some MR acquisitions take two echoes per time point, so we might +have an image of shape (64, 64, 32, 200, 2), where the fourth axis is time and +the fifth axis is echo number.

+
+
+

The current nibabel conventionΒΆ

+

The nibabel rule of thumb has been that, when we return an image array, it +should be in the order described in the format’s user documentation.

+

So, for NIfTI format images, the image dimension sizes are listed in fastest +to slowest changing order, implying that the expected array to be returned +will have that same axis order. Time is always the fourth (rather than the +first) dimension of a 4D NIfTI. Nibabel NIfTI images return the array in that +order, and the time / volume axis is the last in a 4D nibabel NIfTI image +array.

+

On the other hand MINC clearly expects that the axes will be returned in the +order the axes are listed in the MINC file. This is also (usually) the +slowest-to-fastest changing order in the underlying file, and by convention, +the first axis is the time axis. Nibabel MINC images return the array in this +same order with the time / volume axis first, but in general it returns the +array with the axes in the order listed in the MINC file.

+

We don’t currently have BrainVoyager support, so this will be a decision we +have to make before finalizing the API.

+
+
+

Distinguishing time and volumeΒΆ

+

A volume is a complete set of slices making up one brain image.

+

In NIfTI:

+
    +
  • 3D image: volume == image array i.e. arr[:, :, :];

  • +
  • > 3D image: volume == a single slice over the final dim > 3 dimensions +e.g.: arr[:, :, :, 2] (4D); arr[:, :, :, 0, 3] (5D).

  • +
+

We saw above that the MGH format refers to a volume (in our sense) as a +frame. ECAT has the same usage - a frame is a 3D volume. The fmristat +software uses frame in the same sense, e.g., line 32 of example.m.

+

Unfortunately DICOM appears to use β€œframe” to mean a 2D slice. For example, +here is the definition of a β€œmulti-frame image”:

+
3.8.9 Multi-frame image:
+    Image that contains multiple two-dimensional pixel planes.
+
+
+

From PS 3.3 of the 2011 DICOM standard.

+
+
+
+

Possible solutions to finding axesΒΆ

+

A general solution for finding axes would be to attach axis labels to the +returned image data array, or to the image object.

+

A less general solution would be to identify the time axis by convention - say +- by being the fourth axis in a 4D array.

+

Finding the time axis is an urgent problem, because we are currently +considering utility routines for (spatial) smoothing, and viewing images, that +need to know which axis is time.

+
+

General solution: associating axes and labelsΒΆ

+

Possible options:

+
    +
  • Add a property time_axis_index to the image class. This always returns 3 +(4th axis) for images other than MINC. For MINC, it returns the index of +the image dimension labeled time;

  • +
  • Add a property axis_labels to the image class. By default, most image +types return β€˜i’, β€˜j’, β€˜k’, β€˜time’. MINC returns the image dimension +labels;

  • +
  • Copy or depend on datarray (no other dependencies) or xray (depends on +Pandas). Use these to attach labels directly to the image data array axes. +These labels could then be preserved through operations like slicing.

  • +
+
+
+

Using convention : enforcing time as 4th axisΒΆ

+

This solution could be implemented as well as the solution using labels.

+

At the moment, we can always identify the time axis in the NIfTI file, because +it is the 4th axis in the returned image.

+

This is probably so for:

+
    +
  • PAR/REC

  • +
  • ECAT

  • +
  • MGH

  • +
+

but not so for MINC1 or MINC2, where time is typically (?always) the first +axis.

+

One option would be to make a new MINC1, MINC2 image class that reorders the +MINC axes to have time last. Call these new classes NiMINC1, NiMINC2.

+

In order to avoid surprise, we continue to return MINC1, MINC2 class images +from nibabel.load, but give a DeprecationWarning when doing this, saying +that the default load will change in future versions of nibabel, and +suggesting the as_niminc=True keyword-only argument to load, defaulting to +as_niminc=False (giving the current nibabel behavior).

+

In Nibabel 3.0, we require the as_niminc keyword argument.

+

In Nibabel 4.0, we default to as_niminc=True.

+

We would still have to deal with MINC1, MINC2 images in memory - and therefore +cannot in general assume that the fourth dimension of any image data array is +time. In order to deal with this, routines that need to know the time +dimension would have to check whether they were dealing with MINC1, MINC2, +which ends up being similar to the time_axis_index option above.

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0007.html b/devel/biaps/biap_0007.html new file mode 100644 index 0000000000..7f689a0805 --- /dev/null +++ b/devel/biaps/biap_0007.html @@ -0,0 +1,217 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP7 - Loading multiple imagesΒΆ

+
+
Author:
+

Matthew Brett

+
+
Status:
+

Draft

+
+
Type:
+

Standards

+
+
Created:
+

2015-07-18

+
+
+
+

BackgroundΒΆ

+
+

Some formats store images with different shapes in the same fileΒΆ

+

The ECAT file format can contain more than one type of image in a single image +file.

+

ECAT can store many frames in a single image file. Each frame has its own +subheader. The subheader specifies the 3D image size; each frame can +therefore have a different image size.

+

We currently raise an error if you try and load an ECAT file where the frames +do not have the same 3D dimensions.

+

It would be better if we could allow loading multiple images with different +image dimensions, from a single ECAT file.

+

Vista data format and Lipsia format are other formats that allow saving +multiple images with different image dimensions in the same file. We don’t +currently support Lipsia or Vista formats and it is not clear how we would do +that with the current load API.

+

We have had some discussion about saving multiple images into a +single HDF5 file - see https://github.com/nipy/nibabel/pull/215#issuecomment-122357444

+
+
+

It can be useful to load 4D images as multiple 3D imagesΒΆ

+

We sometimes want to load a 4D image as multiple 3D images.

+

When we are doing motion correction, we often want to split up a 4D image into +separate 3D images.

+

Motion estimation results in different affines for each volume in the 4D time +series. At the moment we have no API for returning these affines with a 4D +image. One way of doing that is to load the 4D image and affines as a +sequence of 3D images, each with their own affine.

+

We currently have a proposal open for a JSON header extension that can store +these 4D affines for a 4D NIfTI file.

+

SPM saves the affines in an associated .mat file, with one affine per +volume in the 4D image.

+
+
+
+

OptionsΒΆ

+
+
+

Return an image sequence from load for some file formatsΒΆ

+

We don’t currently load ECAT files from the top-level nibabel.load +function.

+

We do have nibabel.ecat.load, which raises an error for an ECAT file +having frames with different image dimensions.

+

We could therefore choose to return a sequence of images from nibabel.load +on an ECAT file, with one element per frame in the ECAT file.

+

Most ECAT images are 4D images, in the sense that the frames in the file do +all have the same image dimensions and data type, so this might be cumbersome +as a default.

+

We would have to work out how to deal with nibabel.ecat.load.

+

The same principles apply to the Lipsia / Vista formats, except we have no +backward-compatibility problems, and it seems to be more common for these +formats to mix image types in a single file.

+
+
+

Add a load_multi top-level functionΒΆ

+

nibabel.load_multi always returns an image sequence.

+

nibabel.load always returns a single image.

+

nibabel.load on ECAT (etc) files could first do load_multi, then check +the resulting image dimensions, raising an error if incompatible, +concatenating otherwise.

+

load_multi on current formats like NIfTI could return one image per +volume, where each volume might have its own affine, as loaded from the JSON +header extension or the SPM .mat file.

+
+
+

Next steps:ΒΆ

+
    +
  • Make sure there are use-cases where you could wish to call load vs. load_multi on the same image (perhaps a Nifti image with different affines for each volume)

  • +
  • Investigate AFNI file formats as a use-case for this.

  • +
  • Check the nilearn codebase, see if iter_img and slice_img functions might offer a post-load alternative. Also check if those functions could be deprecated in favor of slicing / iterating on dataobj

  • +
  • Create a new issue to implement getting an iterator on dataobj?

  • +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0008.html b/devel/biaps/biap_0008.html new file mode 100644 index 0000000000..a8cda73db8 --- /dev/null +++ b/devel/biaps/biap_0008.html @@ -0,0 +1,268 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP8 - Always load image data as floating pointΒΆ

+
+
Author:
+

Matthew Brett

+
+
Status:
+

Accepted

+
+
Type:
+

Standards

+
+
Created:
+

2018-04-18

+
+
+

get_fdata shipped as of nibabel 2.2.0.

+

See this mailing list thread for discussion on an earlier version of this proposal.

+
+

BackgroundΒΆ

+
+

SummaryΒΆ

+

The problem with our current get_data method is that the returned data +type is difficult to predict, and can switch between integer and floating +point types depending on values in the image header.

+

The underlying problem is that the author and the user of a given NIfTI image +would be unlikely to expect that the scalefactors of the NIfTI header (which +the user will probably not be aware of) will affect the calculations done on +the image data after loading into memory.

+
+
+

In detailΒΆ

+

At the moment, if you do this:

+
img = nib.load('my_image.nii')
+data = img.get_data()
+
+
+

then the data type (dtype) of the returned data array depends on the values in +the header of my_image.nii. Specifically, if the raw on-disk data type +is np.int16 (it often is) and the header scalefactor values are default (1 +for slope, 0 for intercept) then you will get back an array of the on-disk +data type - here np.int16.

+

This is very efficient in terms of memory, but it can be a real trap unless +you are careful.

+

For example, let’s say you had a pipeline where you did this:

+
sum = img.get_data().sum()
+
+
+

That would work fine most of the time, when the data on disk is +floating point, or the scalefactors are not default (1, 0). Then one +day, you get an image with int16 data type on disk and (1, 0) +scalefactors, and your sum calculation is now being done in int16, and +silently overflows. I (MB) ran into this when teaching - I had to cast some +image arrays to floating point to get sensible answers.

+
+
+

Current implementationΒΆ

+

get_data has the following implementation, at time of writing:

+
def get_data(self):
+    """ Return image data from image with any necessary scalng applied
+
+    If the image data is a array proxy (data not yet read from disk) then
+    read the data, and store in an internal cache.  Future calls to
+    ``get_data`` will return the cached copy.
+
+    Returns
+    -------
+    data : array
+        array of image data
+    """
+    if self._data_cache is None:
+        self._data_cache = np.asanyarray(self._dataobj)
+    return self._data_cache
+
+
+

Note that:

+
    +
  • self._dataobj may well be an array proxy object;

  • +
  • np.asanyarray forces the read of an array proxy object into a numpy +array;

  • +
  • the read also fills an internal cache.

  • +
+
+
+
+

Proposal - add, prefer get_fdata methodΒΆ

+

The future default behavior of nibabel should be to do the thing least likely +to trip you up by accident. But - we do not want the result of get_data +to change silently between nibabel versions.

+
    +
  • step 1: now - add get_fdata method:

    +
    def get_fdata(self, dtype=np.float64):
    +    """ Return floating point image data with necessary scalng applied.
    +
    +    If the image data is an array proxy (data not yet read from disk) then
    +    read the data from file, and retain the result in an internal cache.
    +    Future calls to ``get_fdata`` on the same image instance will return
    +    the cached copy.
    +
    +    Parameters
    +    ----------
    +    dtype : numpy dtype specifier
    +        A numpy dtype specifier specifying a floating point type.  Data is
    +        returned as this floating point type.  Default is ``np.float64``.
    +
    +    Returns
    +    -------
    +    fdata : array
    +        Array of image data of data type `dtype`.
    +    """
    +    dtype = np.dtype(dtype)
    +    if not issubclass(dtype, np.inexact):
    +        raise ValueError('{} should be floating point type'.format(dtype))
    +    if self._fdata_cache is None:
    +        self._fdata_cache = np.asanyarray(self._dataobj).astype(dtype)
    +    return self._fdata_cache
    +
    +
    +

    Change all instances of get_data in documentation to get_fdata.

    +

    Add warning about pending deprecation in get_data method, with +suggestion to use get_fdata or np.asanyarray(img.dataobj) if you +want the previous behavior, on the lines of:

    +
    We recommend you use the ``get_fdata`` method instead of the ``get_data``
    +method, because it is easier to predict the return data type.  We will
    +deprecate the ``get_data`` method around April 2018, and remove it around
    +April 2020.
    +
    +If you don't care about the predictability of the return data type, and
    +you want the minimum possible data size in memory, you can replicate the
    +array that would be returned by ``img.get_data()`` by using
    +``np.asanyarray(img.dataobj)``.
    +
    +
    +

    Add floating point cache self._fdata_cache to cache cleared by +uncache method.

    +
  • +
  • step 2: around one year from now - deprecate get_data method;

  • +
  • step 3: around three years from now - make get_data method raise an +error such as NotImplementedError with a helpful message, and remove +associated self._data_cache attribute. Leave this error in place for +a long time, to help people porting older code.

  • +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_0009.html b/devel/biaps/biap_0009.html new file mode 100644 index 0000000000..0c4dcbb497 --- /dev/null +++ b/devel/biaps/biap_0009.html @@ -0,0 +1,478 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP9 - The Coordinate Image APIΒΆ

+
+
Author:
+

Chris Markiewicz

+
+
Status:
+

Draft

+
+
Type:
+

Standards

+
+
Created:
+

2021-09-16

+
+
+
+

BackgroundΒΆ

+
+

Surface data is generally kept separate from geometric metadataΒΆ

+

In contrast to volumetric data, whose geometry can be fully encoded in the +shape of a data array and a 4x4 affine matrix, data sampled to a surface +require the location of each sample to be explicitly represented by a +coordinate. In practice, the most common approach is to have a geometry file +and a data file.

+

A geometry file consists of a vertex coordinate array and a triangle array +describing the adjacency of vertices, while a data file is an n-dimensional +array with one axis corresponding to vertex.

+

Keeping these files separate is a pragmatic optimization to avoid costly +reproductions of geometric data, but presents an administrative burden to +direct consumers of the data.

+
+
+

TerminologyΒΆ

+

For the purposes of this BIAP, the following terms are used:

+
    +
  • Coordinate - a triplet of floating point values in RAS+ space

  • +
  • Vertex - an index into a table of coordinates

  • +
  • Triangle (or face) - a triplet of adjacent vertices (A-B-C); +the normal vector for the face is (\(\overline{AB}\times\overline{AC}\))

  • +
  • Topology - vertex adjacency data, independent of vertex coordinates, +typically in the form of a list of triangles

  • +
  • Geometry - topology + a specific set of coordinates for a surface

  • +
  • Parcel - a subset of vertices; can be the full topology. Special cases include: +* Patch - a connected parcel +* Decimated mesh - a parcel that has a desired density of vertices

  • +
  • Parcel sequence - an ordered set of parcels

  • +
  • Data array - an n-dimensional array with one axis corresponding to the +vertices (typical) OR faces (more rare) in a patch sequence

  • +
+
+
+

Currently supported surface formatsΒΆ

+
    +
  • +
    FreeSurfer
    +
    +
    +
  • +
  • +
    GIFTI: GiftiImage
      +
    • Every image contains a collection of data arrays, which may be +coordinates, topology, or data (further subdivided by type and intent)

    • +
    +
    +
    +
  • +
  • +
    CIFTI-2: Cifti2Image
      +
    • Pure data array, with image header containing flexible axes

    • +
    • The BrainModelAxis is a subspace sequence including patches for +each hemisphere (cortex without the medial wall) and subcortical +structures defined by indices into three-dimensional array and an +affine matrix

    • +
    • Geometry referred to by an associated wb.spec file +(no current implementation in NiBabel)

    • +
    • Possible to have one with no geometric information, e.g., parcels x time

    • +
    +
    +
    +
  • +
+
+
+

Other relevant formatsΒΆ

+
    +
  • +
    MNE’s STC (source time course) format. Contains:
      +
    • Subject name (resolvable with a FreeSurfer SUBJECTS_DIR)

    • +
    • Index arrays into left and right hemisphere surfaces (subspace sequence)

    • +
    • Data, one of: +* ndarray of shape (n_verts, n_times) +* tuple of ndarrays of shapes (n_verts, n_sensors) and (n_sensors, n_times)

    • +
    • Time start

    • +
    • Time step

    • +
    +
    +
    +
  • +
+
+
+
+

Desiderata for an API supporting surfacesΒΆ

+

The following are provisional guiding principles:

+
    +
  1. A surface image (data array) should carry a reference to geometric metadata +that is easily transferred to a new image.

  2. +
  3. Partial images (data only or geometry only) should be possible. Absence of +components should have a well-defined signature, such as a property that is +None or a specific Exception is raised.

  4. +
  5. All arrays (coordinates, triangles, data arrays) should be proxied to +avoid excess memory consumption

  6. +
  7. Selecting among coordinates (e.g., gray/white boundary, inflated surface) +for a single topology should be possible.

  8. +
  9. Combining multiple brain structures (canonically, left and right hemispheres) +in memory should be easy; serializing to file may be format-specific.

  10. +
  11. Splitting a data array into independent patches that can be separately +operated on and serialized should be possible.

  12. +
+
+

Prominent use casesΒΆ

+

We consider the following use cases for working with surface data. +A good API will make retrieving the components needed for each use case +straightforward, as well as storing the results in new images.

+
    +
  • Arithmetic/modeling - per-vertex mathematical operations

  • +
  • Smoothing - topology/geometry-respecting smoothing

  • +
  • Plotting - paint the data array as a texture on a surface

  • +
  • Decimation - subsampling a topology (possibly a subset, possibly with +interpolated vertex locations)

  • +
  • Resampling to a geometrically-aligned surface +* Downsampling by decimating, smoothing, resampling +* Inter-subject resampling by using ?h.sphere.reg

  • +
  • Interpolation of per-vertex and per-face data arrays

  • +
+

When possible, we prefer to expose NumPy ndarrays and +allow use of numpy, scipy, scikit-learn. In some cases, it may +make sense for NiBabel to provide methods.

+
+
+
+

ProposalΒΆ

+

A CoordinateImage is an N-dimensional array, where one axis corresponds +to a sequence of points in one or more parcels.

+
class CoordinateImage:
+    """
+    Attributes
+    ----------
+    header : a file-specific header
+    coordaxis : ``CoordinateAxis``
+    dataobj : array-like
+    """
+
+class CoordinateAxis:
+    """
+    Attributes
+    ----------
+    parcels : list of ``Parcel`` objects
+    """
+
+    def load_structures(self, mapping):
+        """
+        Associate parcels to ``Pointset`` structures
+        """
+
+    def __getitem__(self, slicer):
+        """
+        Return a sub-sampled CoordinateAxis containing structures
+        matching the indices provided.
+        """
+
+    def get_indices(self, parcel, indices=None):
+        """
+        Return the indices in the full axis that correspond to the
+        requested parcel. If indices are provided, further subsample
+        the requested parcel.
+        """
+
+class Parcel:
+    """
+    Attributes
+    ----------
+    name : str
+    structure : ``Pointset``
+    indices : object that selects a subset of coordinates in structure
+    """
+
+
+

To describe coordinate geometry, the following structures are proposed:

+
class Pointset:
+    @property
+    def n_coords(self):
+        """ Number of coordinates """
+
+    def get_coords(self, name=None):
+        """ Nx3 array of coordinates in RAS+ space """
+
+
+class TriangularMesh(Pointset):
+    @property
+    def n_triangles(self):
+        """ Number of faces """
+
+    def get_triangles(self, name=None):
+        """ Mx3 array of indices into coordinate table """
+
+    def get_mesh(self, name=None):
+        return self.get_coords(name=name), self.get_triangles(name=name)
+
+    def get_names(self):
+        """ List of surface names that can be passed to
+        ``get_{coords,triangles,mesh}``
+        """
+
+    def decimate(self, *, n_coords=None, ratio=None):
+        """ Return a TriangularMesh with a smaller number of vertices that
+        preserves the geometry of the original """
+        # To be overridden when a format provides optimization opportunities
+
+
+class NdGrid(Pointset):
+    """
+    Attributes
+    ----------
+    shape : 3-tuple
+        number of coordinates in each dimension of grid
+    """
+    def get_affine(self, name=None):
+        """ 4x4 array """
+
+
+

The NdGrid class allows raveled volumetric data to be treated the same as +triangular mesh or other coordinate data.

+

Finally, a structure for containing a collection of related geometric files is +defined:

+
class GeometryCollection:
+    """
+    Attributes
+    ----------
+    structures : dict
+        Mapping from structure names to ``Pointset``
+    """
+
+    @classmethod
+    def from_spec(klass, pathlike):
+        """ Load a collection of geometries from a specification. """
+
+
+

The canonical example of a geometry collection is a left hemisphere mesh, +right hemisphere mesh.

+

Here we present common use cases:

+
+

ModelingΒΆ

+
from nilearn.glm.first_level import make_first_level_design_matrix, run_glm
+
+bold = CoordinateImage.from_filename("/data/func/hemi-L_bold.func.gii")
+dm = make_first_level_design_matrix(...)
+labels, results = run_glm(bold.get_fdata(), dm)
+betas = CoordinateImage(results["betas"], bold.coordaxis, bold.header)
+betas.to_filename("/data/stats/hemi-L_betas.mgz")
+
+
+

In this case, no reference to the surface structure is needed, as the operations +occur on a per-vertex basis. +The coordinate axis and header are preserved to ensure that any metadata is +not lost.

+

Here we assume that CoordinateImage is able to make the appropriate +translations between formats (GIFTI, MGH). This is not guaranteed in the final +API.

+
+
+

SmoothingΒΆ

+
bold = CoordinateImage.from_filename("/data/func/hemi-L_bold.func.gii")
+bold.coordaxis.load_structures({"lh": "/data/anat/hemi-L_midthickness.surf.gii"})
+# Not implementing networkx weighted graph here, so assume we have a function
+# that retrieves a graph for each structure
+graphs = get_graphs(bold.coordaxis)
+distances = distance_matrix(graphs['lh'])  # n_coords x n_coords matrix
+weights = normalize(gaussian(distances, sigma))
+# Wildly inefficient smoothing algorithm
+smoothed = CoordinateImage(weights @ bold.get_fdata(), bold.coordaxis, bold.header)
+smoothed.to_filename(f"/data/func/hemi-L_smooth-{sigma}_bold.func.gii")
+
+
+
+
+

PlottingΒΆ

+

Nilearn currently provides a +plot_surf function. +With the proposed API, we could interface as follows:

+
def plot_surf_img(img, surface="inflated"):
+    from nilearn.plotting import plot_surf
+    coords, triangles = img.coordaxis.parcels[0].get_mesh(name=surface)
+
+    data = img.get_fdata()
+
+    return plot_surf((triangles, coords), data)
+
+tstats = CoordinateImage.from_filename("/data/stats/hemi-L_contrast-taskVsBase_tstat.mgz")
+# Assume a GeometryCollection that reads a FreeSurfer subject directory
+fs_subject = FreeSurferSubject.from_spec("/data/subjects/fsaverage5")
+tstats.coordaxis.load_structures(fs_subject.get_structure("lh"))
+plot_surf_img(tstats)
+
+
+
+
+

Subsampling CIFTI-2ΒΆ

+
img = nb.load("sub-01_task-rest_bold.dtseries.nii")  # Assume CIFTI CoordinateImage
+parcel = nb.load("sub-fsLR_hemi-L_label-DLPFC_mask.label.gii") # GiftiImage
+structure = parcel.meta.metadata['AnatomicalStructurePrimary'] # "CortexLeft"
+vtx_idcs = np.where(parcel.agg_data())[0]
+dlpfc_idcs = img.coordaxis.get_indices(parcel=structure, indices=vtx_idcs)
+
+# Subsampled coordinate axes will override any duplicate information from header
+dlpfc_img = CoordinateImage(img.dataobj[dlpfc_idcs], img.coordaxis[dlpfc_idcs], img.header)
+
+# Now load geometry so we can plot
+wbspec = CaretSpec("fsLR.wb.spec")
+dlpfc_img.coordaxis.load_structures(wbspec)
+...
+
+
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/biap_template.html b/devel/biaps/biap_template.html new file mode 100644 index 0000000000..85cdb9aaac --- /dev/null +++ b/devel/biaps/biap_template.html @@ -0,0 +1,211 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BIAP X β€” Template and InstructionsΒΆ

+
+
Author:
+

<list of authors’ real names and optionally, email addresses>

+
+
Status:
+

<Draft | Active | Accepted | Deferred | Rejected | Withdrawn | Final | Superseded>

+
+
Type:
+

<Standards Track | Process>

+
+
Created:
+

<date created on, in yyyy-mm-dd format>

+
+
Resolution:
+

<url> (required for Accepted | Rejected | Withdrawn)

+
+
+
+

AbstractΒΆ

+

The abstract should be a short description of what the BIAP will achieve.

+

Note that the β€” in the title is an elongated dash, not -.

+
+
+

Motivation and ScopeΒΆ

+

This section describes the need for the proposed change. It should describe +the existing problem, who it affects, what it is trying to solve, and why. +This section should explicitly address the scope of and key requirements for +the proposed change.

+
+
+

Usage and ImpactΒΆ

+

This section describes how users of Nibabel will use features described in this +BIAP. It should be comprised mainly of code examples that wouldn’t be possible +without acceptance and implementation of this BIAP, as well as the impact the +proposed changes would have on the ecosystem. This section should be written +from the perspective of the users of Nibabel, and the benefits it will provide +them; and as such, it should include implementation details only if +necessary to explain the functionality.

+
+
+

Backward compatibilityΒΆ

+

This section describes the ways in which the BIAP breaks backward compatibility.

+

The mailing list post will contain the BIAP up to and including this section. +Its purpose is to provide a high-level summary to users who are not interested +in detailed technical discussion, but may have opinions around, e.g., usage and +impact.

+
+
+

Detailed descriptionΒΆ

+

This section should provide a detailed description of the proposed change. +It should include examples of how the new functionality would be used, +intended use-cases and pseudo-code illustrating its use.

+
+ +
+

ImplementationΒΆ

+

This section lists the major steps required to implement the BIAP. Where +possible, it should be noted where one step is dependent on another, and which +steps may be optionally omitted. Where it makes sense, each step should +include a link to related pull requests as the implementation progresses.

+

Any pull requests or development branches containing work on this BIAP should +be linked to from here. (A BIAP does not need to be implemented in a single +pull request if it makes sense to implement it in discrete phases).

+
+
+

AlternativesΒΆ

+

If there were any alternative solutions to solving the same problem, they should +be discussed here, along with a justification for the chosen approach.

+
+
+

DiscussionΒΆ

+

This section may just be a bullet list including links to any discussions +regarding the BIAP:

+
    +
  • This includes links to mailing list threads or relevant GitHub issues.

  • +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/biaps/index.html b/devel/biaps/index.html new file mode 100644 index 0000000000..cc78a18df6 --- /dev/null +++ b/devel/biaps/index.html @@ -0,0 +1,128 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

+
+
+ + + + + + + + \ No newline at end of file diff --git a/devel/bv_formats.html b/devel/bv_formats.html new file mode 100644 index 0000000000..b43f652d0d --- /dev/null +++ b/devel/bv_formats.html @@ -0,0 +1,197 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

BrainVoyager file formatsΒΆ

+

With notes on nibabel support.

+

PR for some BrainVoyager support at https://github.com/nipy/nibabel/pull/216.

+
+

OverviewΒΆ

+

See :

+
    +
  • All files are little-endian byte order regardless of byte-order on the +machine writing the data;

  • +
  • BV apparently provides a β€œBVQXtools” library for reading writing BV files in +MATLAB;

  • +
+
+
+

BV internal format axesΒΆ

+

BV files have a internal format that has axes named X, Y and Z. Quoting +from the VMR format definition:

+
BV X front -> back = Y in Tal space
+BV Y top -> bottom = Z in Tal space
+BV Z left -> right = X in Tal space
+
+
+

Put another way β€” the correspondence of BV XYZ to Talairach axes is:

+
    +
  • BV X -> Anterior to Posterior;

  • +
  • BV Y -> Superior to Inferior;

  • +
  • BV Z -> Left to Right.

  • +
+

or:

+
    +
  • BV X -> Talairach -Y;

  • +
  • BV Y -> Talairach -Z;

  • +
  • BV Z -> Talairach X;

  • +
+

Nice!

+
+
+

Types of BV filesΒΆ

+

There appear to be 38 BV file types at the time of writing of which 18 appear +to have a page of description on the BV file format index page.

+

Here are some examples of BV formats:

+
    +
  • FMR β€” β€œFMR project files are simple text files containing the information +defining a functional project created from raw MRI data”. This text file +contains meta-data about the functional time course data, stored in one or +more STC files. See the FMR format definition.

  • +
  • STC β€” β€œA STC file (STC = β€œslice time course”) contains the functional +data (time series) of a FMR project.” The time-course data of a 4D +(β€œsingle-slice”) format STC file are stored on disk in +fastest-to-slowest-changing order: columns, rows, time, slice. STC files +can also contain the data for one single slice (β€œmulti-slice format”), in +which case the data are in fast-to-slow order: columns, rows, time. This is +a raw data file where the relevant meta-data such as image size come from an +associated FMR format file. See STC format definition;

  • +
  • VTC β€” β€œA VTC file contains the functional data (time series) of one +experimental run (one functional scan) in the space of a 3D anatomical data +set (VMR), e.g. in Talairach space.”. See VTC format definition; +This is a different format to the STC (raw data in native-space) format. +The file is a header followed by ints or floats in +fastest-to-slowest-changing order of: time; BV X; BV Y; BV Z; where BV X, BV +Y, BV Z refer to the BV internal format axes, and therefore Talairach -Y, +-Z, X.

  • +
  • NR-VMP β€” β€œA native resolution volume map (NR-VMP) file contains +statistical results in 3D format.”. See NR-VMP format definition

  • +
  • AR-VMP β€” β€œAn anatomical-resolution VMP (volume map) file contains +statistical results in 3D format” at anatomical scan resolution. See +AR-VMP format definition;

  • +
  • VMR β€” β€˜high-resolution anatomical MR’ - see VMR format definition.

  • +
  • MSK β€” mask file. Only documentation appears to be +http://www.brainvoyager.com/ubb/Forum8/HTML/000087.html

  • +
  • SMP β€” β€˜surface map’. See SMP format definition. Contains one or more +β€œmaps”, where a map is a NrOfVertices (number of vertices) length vector +of float64 values.

  • +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/core_developer.html b/devel/core_developer.html new file mode 100644 index 0000000000..3ff6f065b6 --- /dev/null +++ b/devel/core_developer.html @@ -0,0 +1,256 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Core Developer GuideΒΆ

+

As a core developer, you should continue making pull requests +in accordance with the NiBabel Developer Guidelines. +You are responsible for shepherding other contributors through the review process. +You also have the ability to merge or approve other contributors’ pull requests.

+
+

ReviewingΒΆ

+
+

How to Conduct A Good ReviewΒΆ

+

Always be kind to contributors. Nearly all of Nibabel is +volunteer work, for which we are tremendously grateful. Provide +constructive criticism on ideas and implementations, and remind +yourself of how it felt when your own work was being evaluated as a +novice.

+

Nibabel strongly values mentorship in code review. New users +often need more handholding, having little to no git +experience. Repeat yourself liberally, and, if you don’t recognize a +contributor, point them to our development guide, or other GitHub +workflow tutorials around the web. Do not assume that they know how +GitHub works (e.g., many don’t realize that adding a commit +automatically updates a pull request). Gentle, polite, kind +encouragement can make the difference between a new core developer and +an abandoned pull request.

+

When reviewing, focus on the following:

+
    +
  1. API: The API is what users see when they first use +Nibabel. APIs are difficult to change once released, so +should be simple, consistent with other parts of the library, and +should avoid side-effects such as changing global state or modifying +input variables.

  2. +
  3. Documentation: Any new feature should have a tutorial +example that not only illustrates but explains it.

  4. +
  5. The algorithm: You should understand the code being modified or +added before approving it. (See Merge Only Changes You +Understand below.) Implementations should do what they claim, +and be simple, readable, and efficient.

  6. +
  7. Tests: All contributions to the library must be tested, and +each added line of code should be covered by at least one test. Good +tests not only execute the code, but explore corner cases. It is tempting +not to review tests, but please do so.

  8. +
+

Other changes may be nitpicky: spelling mistakes, formatting, +etc. Do not ask contributors to make these changes, and instead +make the changes by pushing to their branch, +or using GitHub’s suggestion +feature. +(The latter is preferred because it gives the contributor a choice in +whether to accept the changes.)

+

Please add a note to a pull request after you push new changes; GitHub +may not send out notifications for these.

+
+
+

Merge Only Changes You UnderstandΒΆ

+

Long-term maintainability is an important concern. Code doesn’t +merely have to work, but should be understood by multiple core +developers. Changes will have to be made in the future, and the +original contributor may have moved on.

+

Therefore, do not merge a code change unless you understand it. Ask +for help freely: we have a long history of consulting community +members, or even external developers, for added insight where needed, +and see this as a great learning opportunity.

+

While we collectively β€œown” any patches (and bugs!) that become part +of the code base, you are vouching for changes you merge. Please take +that responsibility seriously.

+
+
+
+

Closing issues and pull requestsΒΆ

+

Sometimes, an issue must be closed that was not fully resolved. This can be +for a number of reasons:

+
    +
  • the person behind the original post has not responded to calls for +clarification, and none of the core developers have been able to reproduce +their issue;

  • +
  • fixing the issue is difficult, and it is deemed too niche a use case to +devote sustained effort or prioritize over other issues; or

  • +
  • the use case or feature request is something that core developers feel +does not belong in Nibabel,

  • +
+

among others. Similarly, pull requests sometimes need to be closed without +merging, because:

+
    +
  • the pull request implements a niche feature that we consider not worth the +added maintenance burden;

  • +
  • the pull request implements a useful feature, but requires significant +effort to bring up to Nibabel’s standards, and the original +contributor has moved on, and no other developer can be found to make the +necessary changes; or

  • +
  • the pull request makes changes that make maintenance harder, such as +increasing the code complexity of a function significantly to implement a +marginal speedup,

  • +
+

among others.

+

All these may be valid reasons for closing, but we must be wary not to alienate +contributors by closing an issue or pull request without an explanation. When +closing, your message should:

+
    +
  • explain clearly how the decision was made to close. This is particularly +important when the decision was made in a community meeting, which does not +have as visible a record as the comments thread on the issue itself;

  • +
  • thank the contributor(s) for their work; and

  • +
  • provide a clear path for the contributor or anyone else to appeal the +decision.

  • +
+

These points help ensure that all contributors feel welcome and empowered to +keep contributing, regardless of the outcome of past contributions.

+
+
+

Further resourcesΒΆ

+

As a core member, you should be familiar with community and developer +resources such as:

+ +

Please do monitor any of the resources above that you find helpful.

+
+
+
+

AcknowledgmentsΒΆ

+

This document is based on the NetworkX Core Developer guide.

+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/data_pkg_discuss.html b/devel/data_pkg_discuss.html new file mode 100644 index 0000000000..43e722b483 --- /dev/null +++ b/devel/data_pkg_discuss.html @@ -0,0 +1,466 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Principles of data packageΒΆ

+
+

SummaryΒΆ

+

This is a discussion of data packages, as they are currently implemented in +nibabel / nipy.

+

This API proved to be very uncomfortable, and we intend to replace it fairly +soon. See data_packages.rst in the nibabel wiki for our current +thinking, not yet implemented.

+
+
+

MotivationΒΆ

+

When developing or using nipy, many data files can be useful.

+
    +
  1. small test data - very small data files required for routine code testing. +By small we mean less than 100K, and probably much less. They have to be +small because we keep them in the main code repository, and you therefore +always get them with any download.

  2. +
  3. large test data. These files can be much larger, and don’t come in the +standard repository. We use them for tests, but we skip the tests if the +data are not present.

  4. +
  5. template data - data files required for some algorithms to function, +such as templates or atlases

  6. +
  7. example data - data files for running examples.

  8. +
+

We need some standard way to provide the larger data sets. To do this, we are +here defining the idea of a data package. This document is a draft +specification of what a data package looks like and how to use it.

+
+
+

Separation of ideasΒΆ

+

This section needs some healthy beating to make the ideas clearer. However, in +the interests of the 0SAGA software model, here are some ideas that may be +separable.

+
+

PackageΒΆ

+

This idea is rather difficult to define, but is a bit like a data project, that +is a set of information that the packager believed had something in common. The +package then is an abstract idea, and what is in the package could change +completely over course of the life of the package. The package then is a little +bit like a namespace, having itself no content other than a string (the package +name) and the data it contains.

+
+
+

Package nameΒΆ

+

This is a string that gives a name to the package.

+
+
+

Package instantiationΒΆ

+

By instantiation we mean some particular actual set of data for a particular +package. By actual, we mean stuff that can be read as bytes. As we add and +remove data from the package, the instantiation changes. In version control, +the instantiation would be the particular state of the working tree at any +moment, whether this has been committed or not.

+

It might not be enjoyable, but we’ll call a package instantiation a pinstance.

+
+
+

Pinstance revisionΒΆ

+

A revision is an instantiation of the working tree that has a unique label - the +revision id.

+
+
+

Pinstance revision idΒΆ

+

The revision id is a string that identifies a particular pinstance. This is +the equivalent of the revision number in subversion, or the commit hash in +systems like git or mercurial. There is only one pinstance for any given +revision id, but there can be more than one revision id for a pinstance. For +example, you might have a revision of id β€˜200’, delete a file, restore the file, +call this revision id β€˜201’, but they might both refer to the same instantiation +of the package. Or they might not, that’s up to you, the author of the package.

+
+
+

Pinstance tagΒΆ

+

A tag is a memorable string that refers to a particular pinstance. It differs +from a revision id only in that there is not likely to be a tag for every +revision. It’s possible to imagine pinstances without a revision id but with a +tag, but perhaps it’s reasonable to restrict tags to refer to revisions. A +tag is equivalent to a tag name in git or mercurial - a memorable string that +refers to a static state of the data. An example might be a numbered version. +So, a package may have a revision uniquely identified by a revision id +af5bd6. We might decide to label this revision release-0.3 (the +equivalent of applying a git tag). release-0.3 is the tag and af5bd6 is +the revision id. Different sources of the same package might possibly produce +different tags [1]

+
+
+

Pinstance versionΒΆ

+

A pinstance might also have a version. A version is just a tag that can be +compared using some algorithm.

+
+
+

Package provider bundleΒΆ

+

Maybe we could call this a β€œprundle”.

+

The provider bundle is something that can deliver the bytes of a particular +pinstance. For example, if you have a package named β€œinteresting-images”, you +might have a revision of that package identified by revision id β€œf745dc2” and +tagged with β€œversion-0.2”. There might be a provider bundle of that +instantiation that is a zipfile interesting-images-version-0.2.zip. There +might also be a directory on an http server with the same contents +http://my.server.org/packages/interesting-images/version-9.2. The zipfile +and the http directory would both be provider bundles of the particular +instantiation. When I unpack the zipfile onto my hard disk, I might have a +directory /my/home/packages/interesting-images/version-0.2. Now this path +is a provider bundle.

+
+
+

Provider bundle formatΒΆ

+

In the example above, the zipfile, the http directory and the local path are +three different provider bundle formats delivering the same package +instantiation. Let’s call those formats:

+
    +
  • zipfile format

  • +
  • url-path format

  • +
  • local-path format

  • +
+
+
+

Pinstance releaseΒΆ

+

A release might be a package instantiation that one person has:

+
    +
  1. tagged

  2. +
  3. made available as one or more provider bundles

  4. +
+
+
+

Prundle discoveryΒΆ

+

We discover a package bundle when we ask a system (local or remote) whether +they have a package bundle at a given revision, tag, or bundle format. That +implies two discoveries - local discovery (is the package bundle on my local +system, if so where is it?); and remote discovery (is the package bundle on +your expensive server and if so, how do I get it?). For the Debian +distributions, the sources.list file identifies sources from which we can +query for software packages. Those would be sources for remote discovery in +our language.

+
+
+

Prundle discovery sourceΒΆ

+

A prundle discovery source is somewhere that can answer prundle discovery +queries.

+

One such thing might be a prundle registry, where an element in the registry +contains information about a particular prundle. At a first pass this might +contain:

+
    +
  • package name

  • +
  • bundle format

  • +
  • revision id (optional)

  • +
  • tag (optional)

  • +
+

Maybe it should also contain information about where the information came from.

+
+
+

Pinstance metadata queryΒΆ

+

We query a pinstance when we know that a particular system (local or remote) has +a package bundle of the pinstance we want. Then we get some information about +that pinstance.

+

By definition, different prundles relating to the same pinstance have the same +metadata.

+
+
+

Pinstance metadata query sourceΒΆ

+

A pinstance metadata query source is somewhere that can answer pinstance +metadata queries.

+

Obviously a source may well be both a prundle discovery source and a +pinstance metadata query source.

+
+
+

Pinstance installationΒΆ

+

We install a pinstance when we get some prundle containing the pinstance and +place it on local storage, such that we can discover the prundle on our own +(local) system. That is we take some prundle and convert it to a local-path +format bundle and we register this local-path format bundle to a discovery +source.

+
+
+

Data and metadataΒΆ

+
+
Pinstance data

is the bytes as they are arranged in a particular pinstance.

+
+
Pinstance metadata

is data about the pinstance. It might include information about what data +is in the package.

+
+
Prundle metadata

Information about the particular prundle format.

+
+
+
+
+
+

Comparative terminologyΒΆ

+

In which we compare the package terminology above to the terminology of Debian +packaging.

+
+

Compared to Debian packagingΒΆ

+
    +
  • A Debian distribution is a label - such as β€˜unstable’ or β€˜lenny’ - that refers to a +set of package revisions that go together. We have no equivalent.

  • +
  • A Debian repository is a set of packages within a distribution that go +together - e.g. β€˜main’ or β€˜contrib’. We probably don’t have an equivalent +(unless we consider Debian’s repository as being like a very large package +in our language).

  • +
  • A Debian source is a URI giving a location from which you can collect one or +more repositories. For example, the line: β€œhttp://www.example.com/packages +stable main contrib” in a β€œsources.list” file refers to the source +β€œhttp://www.example.com/packages” providing distribution β€œstable” and +repositories (within stable) of β€œmain” and β€œcontrib”. In our language the +combination of URI, distribution and repository would refer to a prundle +discovery source - that is - something that will answer queries about +bundles.

  • +
  • package probably means the same for us as for Debian - a name - like +β€œpython-numpy” - that refers to a set of files that go together and should be +installed together.

  • +
  • Debian packages have versions to reflect the different byte contents. For +example there might be a .deb file (see below) β€œsome-package-0.11_3-i386.deb” +for one distribution, and another (with different contents) for another +distribution - say β€œsome-package-0.12_9-i386.deb”. The β€œ0.11_3” and β€œ0.12_9” +parts of the deb filename are what we would call package instantiation tags.

  • +
  • A Debian deb file is an archive in a particular format that unpacks to provide +the files for a particular package version. We’d call the deb file a package +bundle, that is in bundle format β€œdeb-format”.

  • +
+
+
+
+

DesiderataΒΆ

+

We want to build a package system that is very simple (β€˜S’ in 0SAGA). For the +moment, the main problems we want to solve are: creation of a package +instantiation, installation of package instantiations, local discovery of +package instantiations. For now we are not going to try and solve queries.

+

At least local discovery should be so simple that it can be implemented in any +language, and should not require a particular tool to be installed. We hope we +can write a spec that makes all of (creation, installation, local discovery) +clearly defined, so that it would be simple to write an implementation. +Obviously we’re going to end up writing our own implementation, or adapting +someone else’s. datapkg looks like the best candidate at the moment.

+
+
+

IssuesΒΆ

+

From a brief scan of the debian package management documentation.

+
+

Dependency managementΒΆ

+

(no plan at the moment)

+
+
+

Authentication and validationΒΆ

+
    +
  • Authentication - using signatures to confirm that you made this package.

  • +
  • Verification - verify that the contents have not been corrupted or changed +since the original instantiation.

  • +
+

For dependency and validation, see the Debian secure apt page. One related +proposal would be:

+
    +
  • Each package instantiation would carry a table of checksums for the files +within. Someone using this instantiation would check the checksums to confirm +that they had the intended content.

  • +
  • Authentication would involve some kind of signing of the table of checksums, +as in the Release.gpg file in Debian distributions (Debian secure apt +again). This involves taking a checksum of the table of checksums, then using +our trusted private key to encrypt this checksum, generating a digital +signature. The signature is the thing we provide to the user. The user then +gets our public key or has it already; they use the key to decrypt the +signature to get the checksum, and they check the resulting checksum against +the actual checksum of the checksum table. The property of the public/private +key pair is that it is very hard to go backwards. To explain, here’s an +example. Imagine someone we don’t like has made a version of the package +instantiation, but wants to persuade the world that we made it. Their +contents will have different checksums, and therefore a different checksum for +the checksum table. Let’s say the checksum of the new checksum table is X. +They know that you, the user, will use your own copy of our public key, and +they can’t get at that. Their job then, is to make a new encrypted checksum +(the signature) that will decrypt with our real public key, to equal X. +That’s going backwards from the desired result X to the signature, and that +is very hard, if they don’t have our private key.

  • +
+
+
+
+

Differences from code packagesΒΆ

+

The obvious differences are:

+
    +
  1. Data packages can be very large

  2. +
  3. We have less need for full history tracking (probably)

  4. +
+

The size of data packages probably mean that using git itself will not work +well. git stores (effectively) all previous versions of the files in the +repository, as zlib compressed blobs. The working tree is an uncompressed +instantiation of the current state. Thus, if we have, over time, had 4 +different versions of a large file with little standard diff relationship to one +another, the repository will have four zlib compressed versions of the file in +the .git/objects database, and one uncompressed version in the working tree. +The files in data packages may or may not compress well.

+

In contrast to the full git model, we may want to avoid duplicates of the data. +We probably won’t by default want to keep all previous versions of the data +together at least locally.

+

We probably do want to be able to keep track of which files are the same across +different instantiations of the package, in the case where we already have one +instantiation on local disk, and we are asking for another, with some shared +files. We might well want to avoid downloading duplicate data in that case.

+

Maybe the way to think of it is of the different costs that become important as +files get larger. So the cost for holding a full history becomes very large, +whereas the benefit decreases a little bit (compared to code).

+
+
+

Some usecasesΒΆ

+
+

DiscoveryΒΆ

+
from ourpkg import default_registry
+
+my_pkg_path = default_registry.pathfor('mypkg', '0.3')
+if mypkg_path is None:
+    raise RuntimeError('It looks like mypkg version 0.3 is not installed')
+
+
+

Footnotes

+ +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/devdiscuss.html b/devel/devdiscuss.html new file mode 100644 index 0000000000..69e4fd99ff --- /dev/null +++ b/devel/devdiscuss.html @@ -0,0 +1,133 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

+
+
+ + + + +
+
+
+ +
+
+
+
+ + + \ No newline at end of file diff --git a/devel/devguide.html b/devel/devguide.html new file mode 100644 index 0000000000..38ba938df4 --- /dev/null +++ b/devel/devguide.html @@ -0,0 +1,312 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

NiBabel Developer GuidelinesΒΆ

+

Also see Developer documentation page

+
+

NiBabel source codeΒΆ

+ +
+
+

DocumentationΒΆ

+
+

Code DocumentationΒΆ

+

Please write documentation using Numpy documentation conventions:

+
+
+
+
+
+

Git RepositoryΒΆ

+
+

LayoutΒΆ

+

The main release branch is called master. This is a merge-only branch. +Features finished or updated by some developer are merged from the +corresponding branch into master. At a certain point the current state of +master is tagged – a release is done.

+

Only usable feature should end-up in master. Ideally master should be +releasable at all times.

+

Additionally, there are distribution branches. They are prefixed dist/ +and labeled after the packaging target (e.g. debian for a Debian package). +If necessary, there can be multiple branches for each distribution target.

+
+
dist/debian/proper

Official Debian packaging

+
+
dist/debian/dev

Debian packaging of unofficial development snapshots. They do not go into the +main Debian archive, but might be distributed through other channels (e.g. +NeuroDebian).

+
+
+

Releases are merged into the packaging branches, packaging is updated if +necessary and the branch gets tagged when a package version is released. +Maintenance (as well as backport) releases or branches off from the respective +packaging tag.

+

There might be additional branches for each developer, prefixed with initials. +Alternatively, several GitHub (or elsewhere) clones might be used.

+
+
+

CommitsΒΆ

+

Please prefix all commit summaries with one (or more) of the following labels. +This should help others to easily classify the commits into meaningful +categories:

+
+
    +
  • BF : bug fix

  • +
  • RF : refactoring

  • +
  • NF : new feature

  • +
  • BW : addresses backward-compatibility

  • +
  • OPT : optimization

  • +
  • BK : breaks something and/or tests fail

  • +
  • PL : making pylint happier

  • +
  • DOC: for all kinds of documentation related commits

  • +
  • TEST: for adding or changing tests

  • +
+
+
+
+

MergesΒΆ

+

For easy tracking of what changes were absorbed during merge, we +advise that you enable merge summaries within git:

+
+

git-config merge.summary true

+
+

See Configure git for more detail.

+
+
+
+

TestingΒΆ

+

NiBabel uses tox to organize our testing and development workflows. +tox runs tests in isolated environments that we specify, +ensuring that we are able to test across many different environments, +and those environments do not depend on our local configurations.

+

If you have the pipx tool installed, then you may simply:

+
pipx run tox
+
+
+

Alternatively, you can install tox and run it:

+
python -m pip install tox
+tox
+
+
+

This will run the tests in several configurations, with multiple sets of +optional dependencies. +If you have multiple versions of Python installed in your path, it will +repeat the process for each version of Python iin our supported range. +It may be useful to pick a particular version for rapid development:

+
tox -e py311-full-x64
+
+
+

This will run the environment using the Python 3.11 interpreter, with the +full set of optional dependencies that are available for 64-bit +interpreters. If you are using 32-bit Python, replace -x64 with -x86.

+
+
+

Style guideΒΆ

+

To ensure code consistency and readability, NiBabel has adopted the following +tools:

+
    +
  • blue - An auto-formatter that aims to reduce diffs to relevant lines

  • +
  • isort_ - An import sorter that groups stdlib, third-party and local imports.

  • +
  • flake8 - A style checker that can catch (but generally not fix) common +errors in code.

  • +
  • codespell - A spell checker targeted at source code.

  • +
  • pre-commit_ - A pre-commit hook manager that runs the above and various +other checks/fixes.

  • +
+

While some amount of personal preference is involved in selecting and +configuring auto-formatters, their value lies in largely eliminating the +need to think or argue about style. +With pre-commit turned on, you can write in the style that works for you, +and the NiBabel style will be adopted prior to the commit.

+

To apply our style checks uniformly, simply run:

+
tox -e style,spellcheck
+
+
+

To fix any issues found:

+
tox -e style-fix
+tox -e spellcheck -- -w
+
+
+

Occasionally, codespell has a false positive. To ignore the suggestion, add +the intended word to tool.codespell.ignore-words-list in pyproject.toml. +However, the ignore list is a blunt instrument and could cause a legitimate +misspelling to be missed. Consider choosing a word that does not trigger +codespell before adding it to the ignore list.

+
+

Pre-commit hooksΒΆ

+

NiBabel uses pre-commit_ to help committers validate their changes +before committing. To enable these, you can use pipx:

+
pipx run pre-commit install
+
+
+

Or install and run:

+
python -m pip install pre-commit
+pre-commit install
+
+
+
+
+
+

ChangelogΒΆ

+

The changelog is located in the toplevel directory of the source tree in the +Changelog file. The content of this file should be formatted as restructured +text to make it easy to put it into manual appendix and on the website.

+

This changelog should neither replicate the VCS commit log nor the +distribution packaging changelogs (e.g. debian/changelog). It should be +focused on the user perspective and is intended to list rather macroscopic +and/or important changes to the module, like feature additions or bugfixes in +the algorithms with implications to the performance or validity of results.

+

It may list references to 3rd party bugtrackers, in case the reported bugs +match the criteria listed above.

+
+
+

Community guidelinesΒΆ

+

Please see our community guidelines. +Other projects call these guidelines the β€œcode of conduct”.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/governance.html b/devel/governance.html new file mode 100644 index 0000000000..5caafcd960 --- /dev/null +++ b/devel/governance.html @@ -0,0 +1,298 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Governance and Decision MakingΒΆ

+
+

AbstractΒΆ

+

Nibabel is a consensus-based community project. Anyone with an interest in the +project can join the community, contribute to the project design, and +participate in the decision making process. This document describes how that +participation takes place, how to find consensus, and how deadlocks are +resolved.

+
+
+

Roles And ResponsibilitiesΒΆ

+
+

The CommunityΒΆ

+

The Nibabel community consists of anyone using or working with the project +in any way.

+
+
+

ContributorsΒΆ

+

Any community member can become a contributor by interacting directly with the +project in concrete ways, such as:

+
    +
  • proposing a change to the code or documentation via a GitHub pull request;

  • +
  • reporting issues on our +GitHub issues page;

  • +
  • discussing the design of the library, website, or tutorials on the +mailing list, +or in existing issues and pull requests; or

  • +
  • reviewing +open pull requests,

  • +
+

among other possibilities. By contributing to the project, community members +can directly help to shape its future.

+

Contributors should read the NiBabel Developer Guidelines and our Community guidelines.

+
+
+

Core DevelopersΒΆ

+

Core developers are community members that have demonstrated continued +commitment to the project through ongoing contributions. They +have shown they can be trusted to maintain Nibabel with care. Becoming a +core developer allows contributors to merge approved pull requests, cast votes +for and against merging a pull request, and be involved in deciding major +changes to the API, and thereby more easily carry on with their project related +activities.

+

Core developers:

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

Name

GitHub user

Chris Markiewicz

effigies

Matthew Brett

matthew-brett

Oscar Esteban

oesteban

+

Core developers also appear as team members on the Nibabel Core Team page and can +be messaged @nipy/nibabel-core-developers. We expect core developers to +review code contributions while adhering to the Core Developer Guide.

+

New core developers can be nominated by any existing core developer. Discussion +about new core developer nominations is one of the few activities that takes +place on the project’s private management list. The decision to invite a new +core developer must be made by β€œlazy consensus”, meaning unanimous agreement by +all responding existing core developers. Invitation must take place at least +one week after initial nomination, to allow existing members time to voice any +objections.

+
+
+

Steering CouncilΒΆ

+

The Steering Council (SC) members are current or former core developers who +have additional responsibilities to ensure the smooth running of the project. +SC members are expected to participate in strategic planning, approve changes +to the governance model, and make decisions about funding granted to the +project itself. (Funding to community members is theirs to pursue and manage.) +The purpose of the SC is to ensure smooth progress from the big-picture +perspective. Changes that impact the full project require analysis informed by +long experience with both the project and the larger ecosystem. When the core +developer community (including the SC members) fails to reach such a consensus +in a reasonable timeframe, the SC is the entity that resolves the issue.

+

The steering council is:

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

Name

GitHub user

Chris Markiewicz

effigies

Matthew Brett

matthew-brett

Michael Hanke

mih

Yaroslav Halchenko

yarikoptic

+

Steering Council members also appear as team members on the Nibabel Steering +Council Team page and +can be messaged @nipy/nibabel-steering-council.

+
+
+
+

Decision Making ProcessΒΆ

+

Decisions about the future of the project are made through discussion with all +members of the community. All non-sensitive project management discussion takes +place on the project +mailing list +and the issue tracker. +Occasionally, sensitive discussion may occur on a private list.

+

Decisions should be made in accordance with our Community guidelines.

+

Nibabel uses a consensus seeking process for making decisions. The group +tries to find a resolution that has no open objections among core developers. +Core developers are expected to distinguish between fundamental objections to a +proposal and minor perceived flaws that they can live with, and not hold up the +decision making process for the latter. If no option can be found without +an objection, the decision is escalated to the SC, which will itself use +consensus seeking to come to a resolution. In the unlikely event that there is +still a deadlock, the proposal will move forward if it has the support of a +simple majority of the SC. Any proposal must be described by a Nibabel Enhancement Proposals (BIAPs).

+

Decisions (in addition to adding core developers and SC membership as above) +are made according to the following rules:

+
    +
  • Minor documentation changes, such as typo fixes, or addition / correction +of a sentence (but no change of the Nibabel landing page or the β€œabout” +page), require approval by a core developer and no disagreement or +requested changes by a core developer on the issue or pull request page (lazy +consensus). We expect core developers to give β€œreasonable time” to others to +give their opinion on the pull request if they’re not confident others would +agree.

  • +
  • Code changes and major documentation changes require agreement by one +core developer and no disagreement or requested changes by a core developer +on the issue or pull-request page (lazy consensus).

  • +
  • Changes to the API principles require a Enhancement Proposals (BIAPs) and follow the +decision-making process outlined above.

  • +
  • Changes to this governance model or our mission and values require +a Enhancement Proposals (BIAPs) and follow the decision-making process outlined above, unless +there is unanimous agreement from core developers on the change.

  • +
+

If an objection is raised on a lazy consensus, the proposer can appeal to the +community and core developers and the change can be approved or rejected by +escalating to the SC, and if necessary, a BIAP (see below).

+
+
+

Enhancement Proposals (BIAPs)ΒΆ

+

Any proposals for enhancements of Nibabel should be written as a formal BIAP +following the template BIAP X β€” Template and Instructions. The BIAP must be made public and +discussed before any vote is taken. The discussion must be summarized by a key +advocate of the proposal in the appropriate section of the BIAP. Once this +summary is made public and after sufficient time to allow the core team to +understand it, they vote.

+

The workflow of a BIAP is detailed in BIAP 0 - Purpose and process.

+

A list of all existing BIAPs is available here.

+
+
+

AcknowledgmentsΒΆ

+

Many thanks to Jarrod Millman, Dan Schult and the Scikit-Image team for the +draft on which we based this document.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/image_design.html b/devel/image_design.html new file mode 100644 index 0000000000..73efba85fd --- /dev/null +++ b/devel/image_design.html @@ -0,0 +1,92 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

The nibabel image objectΒΆ

+

The latest version of this page is now at Nibabel images.

+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/index.html b/devel/index.html new file mode 100644 index 0000000000..0e7c86120e --- /dev/null +++ b/devel/index.html @@ -0,0 +1,187 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

+
+
+ + + + + + + + \ No newline at end of file diff --git a/devel/make_release.html b/devel/make_release.html new file mode 100644 index 0000000000..b00fdebc17 --- /dev/null +++ b/devel/make_release.html @@ -0,0 +1,425 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

A guide to making a nibabel releaseΒΆ

+

This is a guide for developers who are doing a nibabel release.

+

The general idea of these instructions is to go through the following steps:

+
    +
  • Make sure that the code is in the right state for release;

  • +
  • update release-related docs such as the Changelog;

  • +
  • update various documents giving dependencies, dates and so on;

  • +
  • check all standard and release-specific tests pass;

  • +
  • make the release commit and release tag;

  • +
  • check Windows binary builds and slow / big memory tests;

  • +
  • push source and windows builds to pypi;

  • +
  • push docs;

  • +
  • push release commit and tag to github;

  • +
  • announce.

  • +
+

We leave pushing the tag to the last possible moment, because it’s very bad +practice to change a git tag once it has reached the public servers (in our +case, github). So we want to make sure of the contents of the release before +pushing the tag.

+
+

Release checklistΒΆ

+
    +
  • Review the open list of nibabel issues. Check whether there are +outstanding issues that can be closed, and whether there are any issues that +should delay the release. Label them !

  • +
  • Review and update the release notes. Review and update the Changelog +file. Get a partial list of contributors with something like:

    +
    git log 2.0.0.. | grep '^Author' | cut -d' ' -f 2- | sort | uniq
    +
    +
    +

    where 2.0.0 was the last release tag name.

    +

    Then manually go over git shortlog 2.0.0.. to make sure the release +notes are as complete as possible and that every contributor was recognized.

    +
  • +
  • Look at doc/source/index.rst and add any authors not yet acknowledged. +You might want to use the following to list authors by the date of their +contributions:

    +
    git log --format="%aN <%aE>" --reverse | perl -e 'my %dedupe; while (<STDIN>) { print unless $dedupe{$_}++}'
    +
    +
    +

    (From: +http://stackoverflow.com/questions/6482436/list-of-authors-in-git-since-a-given-commit#6482473)

    +

    Consider any updates to the AUTHOR file.

    +
  • +
  • Use the opportunity to update the .mailmap file if there are any +duplicate authors listed from git shortlog -nse.

  • +
  • Check the copyright year in doc/source/conf.py

  • +
  • Refresh the README.rst text from the LONG_DESCRIPTION in info.py +by running make refresh-readme.

    +

    Check the output of:

    +
    rst2html.py README.rst > ~/tmp/readme.html
    +
    +
    +

    because this will be the output used by pypi

    +
  • +
  • Check the dependencies listed in nibabel/info.py (e.g. +NUMPY_MIN_VERSION) and in doc/source/installation.rst and in +requirements.txt and .travis.yml. They should at least match. Do +they still hold? Make sure nibabel on travis is testing the minimum +dependencies specifically.

  • +
  • Do a final check on the nipy buildbot. Use the try_branch.py +scheduler available in nibotmi to test particular schedulers.

  • +
  • Make sure all tests pass (from the nibabel root directory):

    +
    pytest --doctest-modules nibabel
    +
    +
    +
  • +
  • Make sure you are set up to use the try_branch.py - see +https://github.com/nipy/nibotmi/blob/master/install.rst#trying-a-set-of-changes-on-the-buildbots

  • +
  • Make sure all your changes are committed or removed, because +try_branch.py pushes up the changes in the working tree;

  • +
  • The following checks get run with the nibabel-release-checks, as in:

    +
    try_branch.py nibabel-release-checks
    +
    +
    +

    Beware: this build does not usually error, even if the steps do not give the +expected output. You need to check the output manually by going to +https://nipy.bic.berkeley.edu/builders/nibabel-release-checks after the +build has finished.

    +
      +
    • Make sure all tests pass from sdist:

      +
      make sdist-tests
      +
      +
      +

      and the three ways of installing (from tarball, repo, local in repo):

      +
      make check-version-info
      +
      +
      +

      The last may not raise any errors, but you should detect in the output +lines of this form:

      +
      {'sys_version': '2.6.6 (r266:84374, Aug 31 2010, 11:00:51) \n[GCC 4.0.1 (Apple Inc. build 5493)]', 'commit_source': 'archive substitution', 'np_version': '1.5.0', 'commit_hash': '25b4125', 'pkg_path': '/var/folders/jg/jgfZ12ZXHwGSFKD85xLpLk+++TI/-Tmp-/tmpGPiD3E/pylib/nibabel', 'sys_executable': '/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python', 'sys_platform': 'darwin'}
      +/var/folders/jg/jgfZ12ZXHwGSFKD85xLpLk+++TI/-Tmp-/tmpGPiD3E/pylib/nibabel/__init__.pyc
      +{'sys_version': '2.6.6 (r266:84374, Aug 31 2010, 11:00:51) \n[GCC 4.0.1 (Apple Inc. build 5493)]', 'commit_source': 'installation', 'np_version': '1.5.0', 'commit_hash': '25b4125', 'pkg_path': '/var/folders/jg/jgfZ12ZXHwGSFKD85xLpLk+++TI/-Tmp-/tmpGPiD3E/pylib/nibabel', 'sys_executable': '/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python', 'sys_platform': 'darwin'}
      +/Users/mb312/dev_trees/nibabel/nibabel/__init__.pyc
      +{'sys_version': '2.6.6 (r266:84374, Aug 31 2010, 11:00:51) \n[GCC 4.0.1 (Apple Inc. build 5493)]', 'commit_source': 'repository', 'np_version': '1.5.0', 'commit_hash': '25b4125', 'pkg_path': '/Users/mb312/dev_trees/nibabel/nibabel', 'sys_executable': '/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python', 'sys_platform': 'darwin'}
      +
      +
      +
    • +
    • Check the setup.py file is picking up all the library code and scripts, +with:

      +
      make check-files
      +
      +
      +

      Look for output at the end about missed files, such as:

      +
      Missed script files:  /Users/mb312/dev_trees/nibabel/bin/nib-dicomfs, /Users/mb312/dev_trees/nibabel/bin/nifti1_diagnose.py
      +
      +
      +

      Fix setup.py to carry across any files that should be in the +distribution.

      +
    • +
    • Check the documentation doctests:

      +
      make -C doc doctest
      +
      +
      +

      This should also be tested by nibabel on travis.

      +
    • +
    • Check everything compiles without syntax errors:

      +
      python -m compileall .
      +
      +
      +
    • +
    • Check that nibabel correctly generates a source distribution:

      +
      make source-release
      +
      +
      +
    • +
    +
  • +
  • Edit nibabel/info.py to set _version_extra to ''; commit;

  • +
  • You may have virtualenvs for different Python versions. Check the tests +pass for different configurations. The long-hand way looks like this:

    +
    workon python26
    +make distclean
    +make sdist-tests
    +deactivate
    +
    +
    +

    etc for the different virtualenvs;

    +
  • +
  • Check on different platforms, particularly windows and PPC. Look at the +nipy buildbot automated test runs for this;

  • +
  • Force build of your release candidate branch with the slow and big-memory +tests on the zibi buildslave:

    +
    try_branch.py nibabel-py2.7-osx-10.10
    +
    +
    +

    Check the build web-page for errors:

    + +
  • +
  • Force builds of your local branch on the win32 and amd64 binaries on +buildbot:

    +
    try_branch.py nibabel-bdist32-27
    +try_branch.py nibabel-bdist32-33
    +try_branch.py nibabel-bdist32-34
    +try_branch.py nibabel-bdist32-35
    +try_branch.py nibabel-bdist64-27
    +
    +
    +

    Check the builds completed without error on their respective web-pages:

    + +
  • +
  • Make sure you have travis-ci building set up for your own repo. Make a new +release-check (or similar) branch, and push the code in its current +state to a branch that will build, e.g:

    +
    git branch -D release-check # in case branch already exists
    +git co -b release-check
    +# You might need the --force flag here
    +git push your-github-user release-check -u
    +
    +
    +
  • +
  • Once everything looks good, you are ready to upload the source release to +PyPi. See setuptools intro. Make sure you have a file +\$HOME/.pypirc, of form:

    +
    [distutils]
    +index-servers =
    +    pypi
    +    warehouse
    +
    +[pypi]
    +username:your.pypi.username
    +password:your-password
    +
    +[warehouse]
    +repository: https://upload.pypi.io/legacy/
    +username:your.pypi.username
    +password:your-password
    +
    +
    +
  • +
  • Clean:

    +
    make distclean
    +# Check no files outside version control that you want to keep
    +git status
    +# Nuke
    +git clean -fxd
    +
    +
    +
  • +
  • When ready:

    +
    python setup.py register
    +python setup.py sdist --formats=gztar,zip
    +# -s flag to sign the release
    +twine upload -r warehouse -s dist/nibabel*
    +
    +
    +
  • +
  • Tag the release with signed tag of form 2.0.0:

    +
    git tag -s 2.0.0
    +
    +
    +
  • +
  • Push the tag and any other changes to trunk with:

    +
    git push origin 2.0.0
    +git push
    +
    +
    +
  • +
  • Now the version number is OK, push the docs to github pages with:

    +
    make upload-html
    +
    +
    +
  • +
  • Finally (for the release uploads) upload the Windows binaries you built with +try_branch.py above;

  • +
  • Set up maintenance / development branches

    +

    If this is this is a full release you need to set up two branches, one for +further substantial development (often called β€˜trunk’) and another for +maintenance releases.

    +
      +
    • Branch to maintenance:

      +
      git co -b maint/2.0.x
      +
      +
      +

      Set _version_extra back to .dev and bump _version_micro by 1. +Thus the maintenance series will have version numbers like - say - +β€˜2.0.1.dev’ until the next maintenance release - say β€˜2.0.1’. Commit. +Don’t forget to push upstream with something like:

      +
      git push upstream-remote maint/2.0.x --set-upstream
      +
      +
      +
    • +
    • Start next development series:

      +
      git co main-master
      +
      +
      +

      then restore .dev to _version_extra, and bump _version_minor +by 1. Thus the development series (β€˜trunk’) will have a version number +here of β€˜2.1.0.dev’ and the next full release will be β€˜2.1.0’.

      +

      Next merge the maintenance branch with the β€œours” strategy. This just +labels the maintenance info.py edits as seen but discarded, so we can +merge from maintenance in future without getting spurious merge conflicts:

      +
      git merge -s ours maint/2.0.x
      +
      +
      +
    • +
    +

    If this is just a maintenance release from maint/2.0.x or similar, just +tag and set the version number to - say - 2.0.2.dev.

    +
  • +
  • Push the main branch:

    +
    git push upstream-remote main-master
    +
    +
    +
  • +
  • Make next development release tag

    +
    +

    After each release the master branch should be tagged +with an annotated (or/and signed) tag, naming the intended +next version, plus an β€˜upstream/’ prefix and β€˜dev’ suffix. +For example β€˜upstream/1.0.0.dev’ means β€œdevelopment start +for upcoming version 1.0.0.

    +

    This tag is used in the Makefile rules to create development snapshot +releases to create proper versions for those. The version derives its name +from the last available annotated tag, the number of commits since that, +and an abbreviated SHA1. See the docs of git describe for more info.

    +

    Please take a look at the Makefile rules devel-src, devel-dsc and +orig-src.

    +
    +
  • +
  • Go to: https://github.com/nipy/nibabel/tags and select the new tag, to fill +in the release notes. Copy the relevant part of the Changelog into the +release notes. Click on β€œPublish release”. This will cause Zenodo to +generate a new release β€œupload”, including a DOI. After a few minutes, go +to https://zenodo.org/deposit and click on the new release upload. Click on +the β€œView” button and click on the DOI badge at the right to display the +text for adding a DOI badge in various formats. Copy the DOI Markdown text. +The markdown will look something like this:

    +
    [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.60847.svg)](https://doi.org/10.5281/zenodo.60847)
    +
    +
    +

    Go back to the Github release page for this release, click β€œEdit release”. +and copy the DOI into the release notes. Click β€œUpdate release”.

    +

    See: https://guides.github.com/activities/citable-code

    +
  • +
  • Announce to the mailing lists.

  • +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/modified_images.html b/devel/modified_images.html new file mode 100644 index 0000000000..96f2474851 --- /dev/null +++ b/devel/modified_images.html @@ -0,0 +1,224 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Keeping track of whether images have been modified since loadΒΆ

+
+

SummaryΒΆ

+

This is a discussion of a missing feature in nibabel: the ability to keep +track of whether an image object in memory still corresponds to an image file +(or files) on disk.

+
+
+

MotivationΒΆ

+

We may need to know whether the image in memory corresponds to the image file +on disk.

+

For example, we often need to get filenames for images when passing +images to external programs. Imagine a realignment, in this case, in nipy +(the package):

+
import nipy
+img1 = nibabel.load('meanfunctional.nii')
+img2 = nibabel.load('anatomical.nii')
+realigner = nipy.interfaces.fsl.flirt()
+params = realigner.run(source=img1, target=img2)
+
+
+

In nipy.interfaces.fsl.flirt.run there may at some point be calls like:

+
source_filename = nipy.as_filename(source_img)
+target_filename = nipy.as_filename(target_img)
+
+
+

As the authors of the flirt.run method, we need to make sure that the +source_filename corresponds to the source_img.

+

Of course, in the general case, if source_img has no corresponding +filename (from source_img.get_filename(), then we will have to save a copy +to disk, maybe with a temporary filename, and return that temporary name as +source_filename.

+

In our particular case, source_img does have a filename +(meanfunctional.nii). We would like to return that as +source_filename. The question is, how can we be sure that the user has +done nothing to source_img to make it diverge from its original state? +Could source_img have diverged, in memory, from the state recorded in +meantunctional.nii?

+

If the image and file have not diverged, we return meanfunctional.nii as +the source_filename, otherwise we will have to do something like:

+
import tempfile
+fname = tempfile.mkstemp('.nii')
+img = source_img.to_filename(fname)
+
+
+

and return fname as source_filename.

+

Another situation where we might like to pass around image objects that are +known to correspond to images on disk is when working in parallel. A set of +nodes may have fast common access to a filesystem on which the images are +stored. If a master is farming out images to nodes, a master node +distribution jobs to workers might want to check if the image was identical to +something on file and pass around a lightweight (proxied) image (with the data +not loaded into memory), relying on the node pulling the image from disk when +it uses it.

+
+
+

Possible implementationΒΆ

+

One implementation is to have dirty flag, which, if set, would tell +you that the image might not correspond to the disk file. We set this +flag when anyone asks for the data, on the basis that the user may then +do something to the data and you can’t know if they have:

+
img = nibabel.load('some_image.nii')
+data = img.get_fdata()
+data[:] = 0
+img2 = nibabel.load('some_image.nii')
+assert not np.all(img2.get_fdata() == img.get_fdata())
+
+
+

The image consists of the data, the affine and a header. In order to +keep track of the header and affine, we could cache them when loading +the image:

+
img = nibabel.load('some_image.nii')
+hdr = img.header
+assert img._cache['header'] == img.header
+hdr.set_data_dtype(np.complex64)
+assert img._cache['header'] != img.header
+
+
+

When we need to know whether the image object and image file correspond, we +could check the current header and current affine (the header may be separate +from the affine for an SPM Analyze image) against their cached copies, if they +are the same and the β€˜dirty’ flag has not been set by a previous call to +get_fdata(), we know that the image file does correspond to the image +object.

+

This may be OK for small bits of memory like the affine and the header, +but would quickly become prohibitive for larger image metadata such as +large nifti header extensions. We could just always assume that images +with large header extensions are not the same as for on disk.

+

The user might be able to override the result of these checks directly:

+
img = nibabel.load('some_image.nii')
+assert img.is_dirty == False
+hdr = img.header
+hdr.set_data_dtype(np.complex64)
+assert img.is_dirty == True
+img.is_dirty == False
+
+
+

The checks are magic behind the scenes stuff that do some safe optimization +(in the sense that we are not re-saving the data if that is not necessary), +but drops back to the default (re-saving the data) if there is any +uncertainty, or the cost is too high to be able to check.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/roadmap.html b/devel/roadmap.html new file mode 100644 index 0000000000..168db947f1 --- /dev/null +++ b/devel/roadmap.html @@ -0,0 +1,208 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

RoadmapΒΆ

+

The roadmap is intended for larger, fundamental changes to the project that are +likely to take months or years of developer time. Smaller-scoped items will +continue to be tracked on our issue tracker.

+

The scope of these improvements means that these changes may be controversial, +are likely to involve significant discussion among the core development team, +and may require the creation of one or more BIAPs (niBabel Increased +Awesomeness Proposals).

+
+

BackgroundΒΆ

+

Nibabel is a workbench that provides a Python API for working with images in +many formats. It is also a base library for tools implementing higher level +processing.

+

Nibabel’s success depends on:

+
    +
  • How easy it is to express common imaging tasks in the API.

  • +
  • The range of tasks it can perform.

  • +
+

An expressive, broad API will increase adoption and make it easier to teach.

+
+

Expressive APIΒΆ

+
+

Axis and tick labelsΒΆ

+

Brain images typically have three or four axes, whose meanings depend on the +way the image was acquired. Axes have natural labels, expressing meaning, +such as β€œtime” or β€œslice”, and they may have tick labels such as acquisition +time. The scanner captures this information, but typical image formats cannot +store it, so it is easy to lose metadata and make analysis errors; see +BIAP6 - Identifying image axes.

+

We plan to expand Nibabel’s API to encode axis and tick labels by integrating +the Xarray package. Xarray simplifies HDF5 +serialization, and visualization.

+

An API for labels is not useful if we cannot read labels from the scanner +data, or save them with the image. We plan to:

+
    +
  • Develop HDF5 equivalents of standard image formats, for serialization of +data with labels.

  • +
  • Expand the current standard image format, NIfTI, to store labels in a JSON +addition to image metadata: BIAP3 - A JSON nifti header extension.

  • +
  • Read image metadata from DICOM, the standard scanner format.

  • +
+

Reading and attaching DICOM data will start with code integrated from +Dcmstack, by Brendan Moloney; see: +BIAP4 - Merging nibabel and dcmstack.

+

DICOM metadata is often hidden inside β€œprivate” DICOM elements that need +specialized parsers. We want to expand these parsers to preserve full metadata +and build a normalization layer to abstract vendor-specific storage locations +for metadata elements that describe the same thing.

+
+
+

API for surface dataΒΆ

+

Neuroimaging data often refers to locations on the brain surface. There are +three common formats for such data: GIFTI, CIFTI and Freesurfer. Nibabel can +read these formats, but lacks a standard API for reading and storing surface +data with metadata; see +nipy/nibabel#936, +nilearn/nilearn#2171. +We plan to develop a standard API, apply it to the standard formats, +and design an efficient general HDF5 storage container for serializing surface +data and metadata.

+
+
+
+

RangeΒΆ

+
+

Spatial transformsΒΆ

+

Neuroimaging toolboxes include spatial registration methods to align the +objects and features present in two or more images. Registration methods +estimate and store spatial transforms. There is no standard or compatible +format to store and reuse these transforms, across packages.

+

Because Nibabel is a workbench, we want to extend its support to read +transforms calculated with AFNI, FreeSurfer, FSL, ITK/ANTs, NiftyReg, and SPM.

+

We have developed the NiTransforms project for this task; we plan to complete +and integrate NiTransforms into Nibabel. This will make transforms more +accessible to researchers, and therefore easier to work with, and reason about.

+
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/scaling.html b/devel/scaling.html new file mode 100644 index 0000000000..e2c37432fc --- /dev/null +++ b/devel/scaling.html @@ -0,0 +1,171 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Scalefactors and interceptsΒΆ

+

SPM Analyze and nifti1 images have scalefactors. nifti1 images also have +intercepts. If A is an array in memory, and S is the array that will +be written to disk, then:

+
R = (A - intercept) / scalefactor
+
+
+

and R == S if R is already the data dtype we need to write.

+

If we load the image from disk, we exactly recover S (and R). To get +something approximating A (say Aprime) we apply the intercept and +scalefactor:

+
Aprime = (S * scalefactor) + intercept
+
+
+

In a perfect world A would be exactly the same as Aprime. However +scalefactor and intercept are floating point values. With floating +point, if r = (a - b) / c; p = (r * c) + b it is not necessarily true that +p == a. For example:

+
>>> import numpy as np
+>>> a = 10
+>>> b = np.e
+>>> c = np.pi
+>>> r = (a - b) / c
+>>> p = (r * c) + b
+>>> p == a
+False
+
+
+

So there will be some error in this reconstruction, even when R is the same +type as S.

+

More common is the situation where R is a different type from S. If +R is of type r_dtype, S is of type s_dtype and +cast_function(R, dtype) is some function that casts R to the desired +type dtype, then:

+
R = (A - intercept) / scalefactor
+S = cast_function(R, s_dtype)
+R_prime = cast_function(S, r_dtype)
+A_prime = (R_prime * scalefactor) + intercept
+
+
+

The type of R will depend on what numpy did for upcasting A, intercept, +scalefactor.

+

In order that cast_function(S, r_dtype) can best reverse cast_function(R, +s_dtype), the second needs to know the type of R, which is not stored. The +type of R depends on the types of A and of intercept, scalefactor. +We don’t know the type of A because it is not stored.

+

R is likely to be a floating point type because of the application of +scalefactor and intercept. If (intercept, scalefactor) are not the identity +(0, 1), then we can ensure that R is at minimum the type of the intercept, +scalefactor by making these be at least 1D arrays, so that floating point +types will upcast in R = (A - intercept) / scalefactor.

+

The cast of R to S and back to R_prime can lose resolution if the +types of R and S have different resolution.

+

Our job is to select:

+
    +
  • scalefactor

  • +
  • intercept

  • +
  • cast_function

  • +
+

such that we minimize some measure of difference between A and +A_prime.

+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/devel/spm_use.html b/devel/spm_use.html new file mode 100644 index 0000000000..e68ad18367 --- /dev/null +++ b/devel/spm_use.html @@ -0,0 +1,391 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Image use-cases in SPMΒΆ

+

SPM uses a vol struct as a structure characterizing an object. This +is a Matlab struct. A struct is like a Python dictionary, where +field names (strings) are associated with values. There are various +functions operating on vol structs, so the vol struct is rather like an +object, where the methods are implemented as functions. Actually, the +distinction between methods and functions in Matlab is fairly subtle - +their call syntax is the same for example.

+
>> fname = 'some_image.nii';
+>> vol = spm_vol(fname) % the vol struct
+
+vol =
+
+      fname: 'some_image.nii'
+        mat: [4x4 double]
+        dim: [91 109 91]
+         dt: [2 0]
+      pinfo: [3x1 double]
+          n: [1 1]
+    descrip: 'NIFTI-1 Image'
+    private: [1x1 nifti]
+
+>> vol.mat % the 'affine'
+
+ans =
+
+    -2     0     0    92
+     0     2     0  -128
+     0     0     2   -74
+     0     0     0     1
+
+>> help spm_vol
+  Get header information etc for images.
+  FORMAT V = spm_vol(P)
+  P - a matrix of filenames.
+  V - a vector of structures containing image volume information.
+  The elements of the structures are:
+        V.fname - the filename of the image.
+        V.dim   - the x, y and z dimensions of the volume
+        V.dt    - A 1x2 array.  First element is datatype (see spm_type).
+                  The second is 1 or 0 depending on the endian-ness.
+        V.mat   - a 4x4 affine transformation matrix mapping from
+                  voxel coordinates to real world coordinates.
+        V.pinfo - plane info for each plane of the volume.
+               V.pinfo(1,:) - scale for each plane
+               V.pinfo(2,:) - offset for each plane
+                  The true voxel intensities of the jth image are given
+                  by: val*V.pinfo(1,j) + V.pinfo(2,j)
+               V.pinfo(3,:) - offset into image (in bytes).
+                  If the size of pinfo is 3x1, then the volume is assumed
+                  to be contiguous and each plane has the same scalefactor
+                  and offset.
+ ____________________________________________________________________________
+
+  The fields listed above are essential for the mex routines, but other
+  fields can also be incorporated into the structure.
+
+  The images are not memory mapped at this step, but are mapped when
+  the mex routines using the volume information are called.
+
+  Note that spm_vol can also be applied to the filename(s) of 4-dim
+  volumes. In that case, the elements of V will point to a series of 3-dim
+  images.
+
+  This is a replacement for the spm_map_vol and spm_unmap_vol stuff of
+  MatLab4 SPMs (SPM94-97), which is now obsolete.
+ _______________________________________________________________________
+  Copyright (C) 2005 Wellcome Department of Imaging Neuroscience
+
+
+>> spm_type(vol.dt(1))
+
+ans =
+
+uint8
+
+>> vol.private
+
+ans =
+
+NIFTI object: 1-by-1
+            dat: [91x109x91 file_array]
+            mat: [4x4 double]
+     mat_intent: 'MNI152'
+           mat0: [4x4 double]
+    mat0_intent: 'MNI152'
+        descrip: 'NIFTI-1 Image'
+
+
+

So, in our (provisional) terms:

+
    +
  • vol.mat == img.affine

  • +
  • vol.dim == img.shape

  • +
  • vol.dt(1) (vol.dt[0] in Python) is equivalent to +img.get_data_dtype()

  • +
  • vol.fname == img.get_filename()

  • +
+

SPM abstracts the implementation of the image to the vol.private +member, that is not in fact required by the image interface.

+

Images in SPM are always 3D. Note this behavior:

+
>> fname = 'functional_01.nii';
+>> vol = spm_vol(fname)
+
+vol =
+
+191x1 struct array with fields:
+    fname
+    mat
+    dim
+    dt
+    pinfo
+    n
+    descrip
+    private
+
+
+

That is, one vol struct per 3D volume in a 4D dataset.

+
+

SPM image methods / functionsΒΆ

+

Some simple ones:

+
>> fname = 'some_image.nii';
+>> vol = spm_vol(fname);
+>> img_arr = spm_read_vols(vol);
+>> size(img_arr) % just loads in scaled data array
+
+ans =
+
+    91   109    91
+
+>> spm_type(vol.dt(1)) % the disk-level (IO) type is uint8
+
+ans =
+
+uint8
+
+>> class(img_arr) % always double regardless of IO type
+
+ans =
+
+double
+
+>> new_fname = 'another_image.nii';
+>> new_vol = vol;  % matlab always copies
+>> new_vol.fname = new_fname;
+>> spm_write_vol(new_vol, img_arr)
+
+ans =
+
+      fname: 'another_image.nii'
+        mat: [4x4 double]
+        dim: [91 109 91]
+         dt: [2 0]
+      pinfo: [3x1 double]
+          n: [1 1]
+    descrip: 'NIFTI-1 Image'
+    private: [1x1 nifti]
+
+
+

Creating an image from scratch, and writing plane by plane (slice by slice):

+
>> new_vol = struct();
+>> new_vol.fname = 'yet_another_image.nii';
+>> new_vol.dim = [91 109 91];
+>> new_vol.dt = [spm_type('float32') 0]; % little endian (0)
+>> new_vol.mat = vol.mat;
+>> new_vol.pinfo = [1 0 0]';
+>> new_vol = spm_create_vol(new_vol);
+>> for vox_z = 1:new_vol.dim(3)
+new_vol = spm_write_plane(new_vol, img_arr(:,:,vox_z), vox_z);
+end
+
+
+

I think it’s true that writing the plane does not change the image +scalefactors, so it’s only practical to use spm_write_plane for data +for which you already know the dynamic range across the volume.

+

Simple resampling from an image:

+
>> fname = 'some_image.nii';
+>> vol = spm_vol(fname);
+>> % for voxel coordinate 10,15,20 (1-based)
+>> hold_val = 3; % third order spline resampling
+>> val = spm_sample_vol(vol, 10, 15, 20, hold_val)
+
+val =
+
+    0.0510
+
+>> img_arr = spm_read_vols(vol);
+>> img_arr(10, 15, 20)  % same as simple indexing for integer coordinates
+
+ans =
+
+    0.0510
+
+>> % more than one point
+>> x = [10, 10.5]; y = [15, 15.5]; z = [20, 20.5];
+>> vals = spm_sample_vol(vol, x, y, z, hold_val)
+
+vals =
+
+    0.0510    0.0531
+
+>> % you can also get the derivatives, by asking for more output args
+>> [vals, dx, dy, dz] = spm_sample_vol(vol, x, y, z, hold_val)
+
+vals =
+
+    0.0510    0.0531
+
+
+dx =
+
+    0.0033    0.0012
+
+
+dy =
+
+    0.0033    0.0012
+
+
+dz =
+
+    0.0020   -0.0017
+
+
+

This is to speed up optimization in registration - where the optimizer +needs the derivatives.

+

spm_sample_vol always works in voxel coordinates. If you want some +other coordinates, you would transform them yourself. For example, +world coordinates according to the affine looks like:

+
>> wc = [-5, -12, 32];
+>> vc = inv(vol.mat) * [wc 1]'
+
+vc =
+
+   48.5000
+   58.0000
+   53.0000
+    1.0000
+
+>> vals = spm_sample_vol(vol, vc(1), vc(2), vc(3), hold_val)
+
+vals =
+
+    0.6792
+
+
+

Odder sampling, often used, can be difficult to understand:

+
>> slice_mat = eye(4);
+>> out_size = vol.dim(1:2);
+>> slice_no = 4; % slice we want to fetch
+>> slice_mat(3,4) = slice_no;
+>> arr_slice = spm_slice_vol(vol, slice_mat, out_size, hold_val);
+>> img_slice_4 = img_arr(:,:,slice_no);
+>> all(arr_slice(:) == img_slice_4(:))
+
+ans =
+
+     1
+
+
+

This is the simplest use - but in general any affine transform can go in +slice_mat above, giving optimized (for speed) sampling of slices +from volumes, as long as the transform is an affine.

+

Miscellaneous functions operating on vol structs:

+
    +
  • spm_conv_vol - convolves volume with separable functions in x, y, z

  • +
  • spm_render_vol - does a projection of a volume onto a surface

  • +
  • spm_vol_check - takes array of vol structs and checks for sameness of +image dimensions and mat (affines) across the list.

  • +
+

And then, many SPM functions accept vol structs as arguments.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/dicom/dcm2nii_algorithms.html b/dicom/dcm2nii_algorithms.html new file mode 100644 index 0000000000..8fe3558a50 --- /dev/null +++ b/dicom/dcm2nii_algorithms.html @@ -0,0 +1,202 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

dcm2nii algorithmsΒΆ

+

dcm2nii is an open source DICOM to nifti conversion program, written +by Chris Rorden, in Delphi (object orientated pascal). It’s part of +Chris’ popular mricron collection of programs. The source appears to +be best found on the mricron NITRC site. It’s BSD licensed.

+

These are working notes looking at Chris’ algorithms for working with +DICOM.

+
+

Compiling dcm2niiΒΆ

+

Follow the download / install instructions at the +http://www.lazarus.freepascal.org/ site. I was on a Mac, and followed the +instructions here: +http://wiki.lazarus.freepascal.org/Installing_Lazarus_on_MacOS_X . Default +build with version 0.9.28.2 gave an error linking against Carbon, so I needed to +download a snapshot of fixed Lazarus 0.9.28.3 from +http://www.hu.freepascal.org/lazarus . Open <mricron>/dcm2nii/dcm2nii.lpi +using the Lazarus GUI. Follow instructions for compiler setup in the mricron +Readme.txt; in particular I set other compiler options to:

+
-k-macosx_version_min -k10.5
+-XR/Developer/SDKs/MacOSX10.5.sdk/
+
+
+

Further inspiration for building also came from the debian/rules file in +Michael Hanke’s mricron debian package: +http://neuro.debian.net/debian/pool/main/m/mricron/

+
+
+

Some tag modificationsΒΆ

+

Note - Chris tells me that dicomfastread.pas was an attempt to do a fast +dicom read that is not yet fully compatible, and that the algorithm used is in +fact dicomcompat.pas.

+

Looking in the source file <mricron>/dcm2nii/dicomfastread.pas.

+

Named fields here are as from DICOM fields

+
    +
  • If β€˜MOSAIC’ is the last string in β€˜ImageType’, this is a mosaic

  • +
  • β€˜DateTime’ field is combination of β€˜StudyDate’ and β€˜StudyTime’; fixes +in file dicomtypes.pas for different scanner date / time formats.

  • +
  • AcquisitionNumber read as normal, but then set to 1, if this a mosaic +image, as set above.

  • +
  • If β€˜EchoNumbers’ > 0 and < 16, add β€˜EchoNumber’ * 100 to the +β€˜AcquisitionNumber’ - presumably to identify different echos from the +same series as being different series.

  • +
  • If β€˜ScanningSequence’ sequence contains β€˜RM’, add 100 to the +β€˜SeriesNumber’ - maybe to differentiate research and not-research +scans with the same acquisition number.

  • +
  • is_4D flag labeling DICOM file as a 4D file:

    +
    +
      +
    • There’s a Philips private tag (2001, 1018) - labeled β€˜Number of +Slices MR’ by pydicom call this NS

    • +
    • If NS>0 and β€˜NumberofTemporalPositions’ > 0, and +β€˜NumberOfFrames’ is > 1

    • +
    +
    +
  • +
+
+
+

Sorting slices into volumesΒΆ

+

Looking in the source file <mricron>/dcm2nii/sortdicom.pas.

+

In function ShellSortDCM:

+

Sort compares two dicom images, call them dcm1 and dcm2. Tests are:

+
    +
  1. Are the two images β€˜repeats’ - defined by same β€˜InstanceNumber’ +(0020, 0013), and β€˜AcquisitionNumber’ (0020, 0012) and β€˜SeriesNumber’ +(0020, 0011) and a combination of β€˜StudyDate’ and β€˜StudyTime’)? Then +report an error about files having the same index, flag repeated values.

  2. +
  3. Is dcm1 less than dcm2, defined with comparisons in the +following order:

    +
      +
    1. StudyDate/Time

    2. +
    3. SeriesNumber

    4. +
    5. AcquisitionNumber

    6. +
    7. InstanceNumber

    8. +
    +

    This should obviously only ever be > or <, not ==, because of the +first check.

    +
  4. +
+

Next remove repeated values as found in the first step above.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/dicom/dicom.html b/dicom/dicom.html new file mode 100644 index 0000000000..f1b1d247b8 --- /dev/null +++ b/dicom/dicom.html @@ -0,0 +1,160 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

+
+
+ + + + + + + + \ No newline at end of file diff --git a/dicom/dicom_fields.html b/dicom/dicom_fields.html new file mode 100644 index 0000000000..19ecea7a4a --- /dev/null +++ b/dicom/dicom_fields.html @@ -0,0 +1,180 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

DICOM fieldsΒΆ

+

In which we pick out some interesting fields in the DICOM header.

+

We’re getting the information mainly from the standard DICOM object +definitions

+

We won’t talk about the orientation, patient position-type fields here +because we’ve covered those somewhat in DICOM voxel to patient coordinate system mapping.

+
+

Fields for ordering DICOM files into imagesΒΆ

+

You’ll see some discussion of this in SPM DICOM conversion.

+

Section 7.3.1: general series module

+
    +
  • Modality (0008,0060) - Type of equipment that originally acquired the +data used to create the images in this Series. See C.7.3.1.1.1 for +Defined Terms.

  • +
  • Series Instance UID (0020,000E) - Unique identifier of the Series.

  • +
  • Series Number (0020,0011) - A number that identifies this Series.

  • +
  • Series Time (0008,0031) - Time the Series started.

  • +
+

Section C.7.6.1:

+
    +
  • Instance Number (0020,0013) - A number that identifies this image.

  • +
  • Acquisition Number (0020,0012) - A number identifying the single +continuous gathering of data over a period of time that resulted in +this image.

  • +
  • Acquisition Time (0008,0032) - The time the acquisition of data that +resulted in this image started

  • +
+

Section C.7.6.2.1.2:

+

Slice Location (0020,1041) is defined as the relative position of the +image plane expressed in mm. This information is relative to an +unspecified implementation specific reference point.

+

Section C.8.3.1 MR Image Module

+
    +
  • Slice Thickness (0018,0050) - Nominal reconstructed slice thickness, +in mm.

  • +
+

Section C.8.3.1 MR Image Module

+
    +
  • Spacing Between Slices (0018,0088) - Spacing between slices, in +mm. The spacing is measured from the center-tocenter of each slice.

  • +
  • Temporal Position Identifier (0020,0100) - Temporal order of a dynamic +or functional set of Images.

  • +
  • Number of Temporal Positions (0020,0105) - Total number of temporal +positions prescribed.

  • +
  • Temporal Resolution (0020,0110) - Time delta between Images in a +dynamic or functional set of images

  • +
+
+
+

Multi-frame imagesΒΆ

+

An image for which the pixel data is a continuous stream of sequential frames.

+

Section C.7.6.6: Multi-Frame Module

+
    +
  • Number of Frames (0028,0008) - Number of frames in a Multi-frame +Image.

  • +
  • Frame Increment Pointer (0028,0009) - Contains the Data Element Tag of +the attribute that is used as the frame increment in Multi-frame pixel +data.

  • +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/dicom/dicom_info.html b/dicom/dicom_info.html new file mode 100644 index 0000000000..8dd42e9f31 --- /dev/null +++ b/dicom/dicom_info.html @@ -0,0 +1,160 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

DICOM informationΒΆ

+

DICOM is a large and sometimes confusing imaging data format.

+

In the other pages in this series we try and document our understanding of +various aspects of DICOM relevant to converting to formats such as NIfTI .

+

There are a large number of DICOM image conversion programs already, +partly because it is a complicated format with features that vary from +manufacturer to manufacturer.

+

We use the excellent PyDICOM as our back-end for reading DICOM.

+

Here is a selected list of other tools and relevant resources:

+
    +
  • Grassroots DICOM : GDCM . It is C++ code wrapped with swig and so +callable from Python. ITK apparently uses it for DICOM conversion. +BSD license.

  • +
  • dcm2nii - a BSD licensed converter by Chris Rorden. As usual, Chris +has done an excellent job of documentation, and it is well +battle-tested. There’s a nice set of example data to test against and +a list of other DICOM software. The MRIcron install page points to +the source code. Chris has also put effort into extracting diffusion +parameters from the DICOM images.

  • +
  • SPM8 - SPM has a stable and robust general DICOM conversion tool +implemented in the spm_dicom_convert.m and spm_dicom_headers.m +scripts. The conversions don’t try to get the diffusion parameters. +The code is particularly useful because it has been well-tested and is +written in Matlab - and so is relatively easy to read. GPL license. +We’ve described some of the algorithms that SPM uses for DICOM +conversion in SPM DICOM conversion.

  • +
  • DICOM2Nrrd: a command line converter to convert DICOM images to Nrrd +format. You can call the command from within the Slicer GUI. It +does have algorithms for getting diffusion information from the DICOM +headers, and has been tested with Philips, GE and Siemens data. It’s +not clear whether it yet supports the Siemens mosaic format. BSD style +license.

  • +
  • The famous Philips cookbook: https://www.archive.org/details/DicomCookbook

  • +
  • http://dicom.online.fr/fr/dicomlinks.htm

  • +
+
+
+

Sample imagesΒΆ

+ +
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/dicom/dicom_intro.html b/dicom/dicom_intro.html new file mode 100644 index 0000000000..82c861d6f7 --- /dev/null +++ b/dicom/dicom_intro.html @@ -0,0 +1,1009 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Introduction to DICOMΒΆ

+

DICOM defines standards for storing data in memory and on disk, and for +communicating this data between machines over a network.

+

We are interested here in DICOM data. Specifically we are interested in DICOM +files.

+

DICOM files are binary dumps of the objects in memory that DICOM sends across +the network.

+

We need to understand the format that DICOM uses to send messages across the +network to understand the terms the DICOM uses when storing data in files.

+

For example, I hope, by the time you reach the end of this document, you will +understand the following complicated and confusing statement from section 7 of +the DICOM standards document PS 3.10:

+
+

7 DICOM File Format

+

The DICOM File Format provides a means to encapsulate in a file the Data Set +representing a SOP Instance related to a DICOM IOD. As shown in Figure 7-1, +the byte stream of the Data Set is placed into the file after the DICOM File +Meta Information. Each file contains a single SOP Instance.

+
+
+

DICOM is messagesΒΆ

+

The fundamental task of DICOM is to allow different computers to send messages +to one another. These messages can contain data, and the data is very often +medical images.

+

The messages are in the form of requests for an operation, or responses to those requests.

+

Let’s call the requests and the responses - services.

+

Every DICOM message starts with a stream of bytes containing information about +the service. This part of the message is called the DICOM Message Service +Element or DIMSE. Depending on what the DIMSE was, there may follow some data +related to the request.

+

For example, there is a DICOM service called β€œC-ECHO”. This asks for a response +from another computer to confirm it has seen the echo request. There is no +associated data following the β€œC-ECHO” DIMSE part. So, the full message is the +DIMSE β€œC-ECHO”.

+

There is another DICOM service called β€œC-STORE”. This is a request for the +other computer to store some data, such as an image. The data to be stored +follows the β€œC-STORE” DIMSE part.

+

We go into more detail on this later in the page.

+

Both the DIMSE and the subsequent data have a particular binary format - +consisting of DICOM elements (see below).

+

Here we will cover:

+
    +
  • what DICOM elements are;

  • +
  • how DICOM elements are arranged to form complicated data structures such as images;

  • +
  • how the service part and the data part go together to form whole messages

  • +
  • how these parts relate to DICOM files.

  • +
+
+
+

The DICOM standardΒΆ

+

The documents defining the standard are:

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

Number

Name

PS 3.1

Introduction and Overview

PS 3.2

Conformance

PS 3.3

Information Object Definitions

PS 3.4

Service Class Specifications

PS 3.5

Data Structure and Encoding

PS 3.6

Data Dictionary

PS 3.7

Message Exchange

PS 3.8

Network Communication Support for Message Exchange

PS 3.9

Retired

PS 3.10

Media Storage / File Format for Media Interchange

PS 3.11

Media Storage Application Profiles

PS 3.12

Media Formats / Physical Media for Media Interchange

PS 3.13

Retired

PS 3.14

Grayscale Standard Display Function

PS 3.15

Security and System Management Profiles

PS 3.16

Content Mapping Resource

PS 3.17

Explanatory Information

PS 3.18

Web Access to DICOM Persistent Objects (WADO)

PS 3.19

Application Hosting

PS 3.20

Transformation of DICOM to and from HL7 Standards

+
+
+

DICOM data formatΒΆ

+

DICOM data is stored in memory and on disk as a sequence of DICOM elements +(section 7 of PS 3.5).

+
+

DICOM elementsΒΆ

+

A DICOM element is made up of three or four fields. These are (Attribute Tag, +[Value Representation, ], Value Length, Value Field), where Value +Representation may be present or absent, depending on the type of β€œValue +Representation Encoding” (see below)

+
+

Attribute TagΒΆ

+

The attribute tag is a pair of 16-bit unsigned integers of form (Group number, +Element number). The tag uniquely identifies the element.

+

The Element number is badly named, because the element number does not give a +unique number for the element, but only for the element within the group (given +by the Group number).

+

The (Group number, Element number) are nearly always written as hexadecimal +numbers in the following format: (0010, 0010). The decimal representation +of hexadecimal 0010 is 16, so this tag refers to group number 16, element number +16. If you look this tag up in the DICOM data dictionary (PS 3.6) you’ll see +this must be the element called β€œPatientName”.

+

These tag groups have special meanings:

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

Tag group

Meaning

0000

Command elements

0002

File meta elements

0004

Directory structuring elements

0006

(not used)

+

See Annex E (command dictionary) of PS 3.7 for details on group 0000. See +sections 7 and 8 of PS 3.6 for details of groups 2 and 4 respectively.

+

Tags in groups 0000, 0002, 0004 are therefore not data elements, but Command +elements; File meta elements; directory structuring elements.

+

Tags with groups from 0008 are data element tags.

+
+
Standard attribute tagsΒΆ
+

Standard tags are tags with an even group number (see below). There is a full +list of all standard data element tags in the DICOM data dictionary in section +6 of DICOM standard PS 3.6.

+

Even numbered groups are defined in the DICOM standard data dictionary. Odd +numbered groups are β€œprivate”, are not defined in the standard data dictionary +and can be used by manufacturers as they wish (see below).

+

Quoting from section 7.1 of PS 3.5:

+
+

Two types of Data Elements are defined:

+

β€”Standard Data Elements have an even Group Number that is not (0000,eeee), +(0002,eeee), (0004,eeee), or (0006,eeee).

+
+
+

Note: Usage of these groups is reserved for DIMSE Commands (see PS 3.7) and +DICOM File Formats.

+

β€”Private Data Elements have an odd Group Number that is not (0001,eeee), +(0003,eeee), (0005,eeee), (0007,eeee), or (FFFF,eeee). Private Data Elements +are discussed further in Section 7.8.

+
+
+
+
Private attribute tagsΒΆ
+

Private attribute tags are tags with an odd group number. A private element is +an element with a private tag.

+

Private elements still use the (Tag, [Value Representation, ] Value Length, +Value Field) DICOM data format.

+

The same odd group may be used by different manufacturers in different ways.

+

To try and avoid collisions of private tags from different manufacturers, there +is a mechanism by which a manufacturer can tell other users of a DICOM dataset +that it has reserved a block in the (Group number, Element number) space for +their own use. To do this they write a β€œPrivate Creator” element where the tag +is of the form (gggg, 00xx), the Value Representation (see below) is β€œLO” +(Long String) and the Value Field is a string identifying what the space is +reserved for. Here gggg is the odd group we are reserving a portion of and +the xx is the block of elements we are reserving. A tag of (gggg, 00xx) +reserves the 256 elements in the range (gggg, xx00) to (gggg, xxFF).

+

For example, here is a real data element from a Siemens DICOM dataset:

+
(0019, 0010) Private Creator                     LO: 'SIEMENS MR HEADER'
+
+
+

This reserves the tags from (0019, 1000) to (0019, 10FF) for information +on the β€œSIEMENS MR HEADER”

+

The odd group gggg must be greater than 0008 and the block reservation +xx must be greater than or equal to 0010 and less than 0100.

+

Here is the start of the relevant section from PS 3.5:

+
+

7.8.1 PRIVATE DATA ELEMENT TAGS

+

It is possible that multiple implementers may define Private Elements with the +same (odd) group number. To avoid conflicts, Private Elements shall be +assigned Private Data Element Tags according to the following rules.

+

a) Private Creator Data Elements numbered (gggg,0010-00FF) (gggg is odd) shall +be used to reserve a block of Elements with Group Number gggg for use by an +individual implementer. The implementer shall insert an identification code +in the first unused (unassigned) Element in this series to reserve a block of +Private Elements. The VR of the private identification code shall be LO (Long +String) and the VM shall be equal to 1.

+

b) Private Creator Data Element (gggg,0010), is a Type 1 Data Element that +identifies the implementer reserving element (gggg,1000-10FF), Private Creator +Data Element (gggg,0011) identifies the implementer reserving elements +(gggg,1100-11FF), and so on, until Private Creator Data Element (gggg,00FF) +identifies the implementer reserving elements (gggg,FF00- FFFF).

+

c) Encoders of Private Data Elements shall be able to dynamically assign +private data to any available (unreserved) block(s) within the Private group, +and specify this assignment through the blocks corresponding Private Creator +Data Element(s). Decoders of Private Data shall be able to accept reserved +blocks with a given Private Creator identification code at any position within +the Private group specified by the blocks corresponding Private Creator Data +Element.

+
+
+
+
+

Value RepresentationΒΆ

+

Value Representation is often abbreviated to VR.

+

The VR is a two byte character string giving the code for the encoding of the +subsequent data in the Value Field (see below).

+

The VR appears in DICOM data that has β€œExplicit Value Representation”, and is +absent for data with β€œImplicit Value Representation”. β€œImplicit Value +Representation” uses the fact that the DICOM data dictionary gives VR values for +each tag in the standard DICOM data dictionary, so the VR value is implied by +the tag value, given the data dictionary.

+

Most DICOM data uses β€œExplicit Value Representation” because the DICOM data +dictionary only gives VRs for standard (even group number, not private) data +elements. Each manufacturer writes their own private data elements, and the VR +of these elements is not defined in the standard, and therefore may not be known +to software not from that manufacturer.

+

The VR codes have to be one of the values from this table (section 6.2 of DICOM +standard PS 3.5):

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

Value Representation

Description

AE

Application Entity

AS

Age String

AT

Attribute Tag

CS

Code String

DA

Date

DS

Decimal String

DT

Date/Time

FL

Floating Point Single (4 bytes)

FD

Floating Point Double (8 bytes)

IS

Integer String

LO

Long String

LT

Long Text

OB

Other Byte

OF

Other Float

OW

Other Word

PN

Person Name

SH

Short String

SL

Signed Long

SQ

Sequence of Items

SS

Signed Short

ST

Short Text

TM

Time

UI

Unique Identifier

UL

Unsigned Long

UN

Unknown

US

Unsigned Short

UT

Unlimited Text

+
+
+

Value lengthΒΆ

+

Value length gives the length of the data contained in the Value Field tag, or +is a flag specifying the Value Field is of undefined length, and thus must be +terminated later in the data stream with a special Item or Sequence Delimitation +tag.

+

Quoting from section 7.1.1 of PS 3.5:

+
+

Value Length: Either:

+

a 16 or 32-bit (dependent on VR and whether VR is explicit or implicit) +unsigned integer containing the Explicit Length of the Value Field as the +number of bytes (even) that make up the Value. It does not include the +length of the Data Element Tag, Value Representation, and Value Length +Fields.

+

a 32-bit Length Field set to Undefined Length (FFFFFFFFH). Undefined +Lengths may be used for Data Elements having the Value Representation +(VR) Sequence of Items (SQ) and Unknown (UN). For Data Elements with +Value Representation OW or OB Undefined Length may be used depending +on the negotiated Transfer Syntax (see Section 10 and Annex A).

+
+
+
+

Value fieldΒΆ

+

An even number of bytes storing the value(s) of the data element. The exact +format of this data depends on the Value Representation (see above) and the +Value Multiplicity (see next section).

+
+
+
+

Data element tags and data dictionariesΒΆ

+

We can look up data element tags in a data dictionary.

+

As we’ve seen, data element tags with even group numbers are standard data +element tags. We can look these up in the standard data dictionary in section 6 +of PS 3.6.

+

Data element tags with odd group numbers are private data element tags. These +can be used by manufacturers for information that may be specific to the +manufacturer. To look up these tags, we need the private data dictionary of the +manufacturer.

+

A data dictionary lists (Attribute tag, Attribute name, Attribute Keyword, Value +Representation, Value Multiplicity) for all tags.

+

For example, here is an excerpt from the table in PS 3.6 section 6:

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

Tag

Name

Keyword

VR

VM

(0010,0010)

Patient’s Name

PatientName

PN

1

(0010,0020)

Patient ID

PatientID

LO

1

(0010,0021)

Issuer of Patient ID

IssuerOfPatientID

LO

1

(0010,0022)

Type of Patient ID

TypeOfPatientID

CS

1

(0010,0024)

Issuer of Patient ID Qualifiers Sequence

IssuerOfPatientIDQualifiersSequence

SQ

1

(0010,0030)

Patient’s Birth Date

PatientBirthDate

DA

1

(0010,0032)

Patient’s Birth Time

PatientBirthTime

TM

1

+

The β€œName” column gives a standard name for the tag. β€œKeyword” gives a shorter +equivalent to the name without spaces that can be used as a variable or +attribute name in code.

+
+

Value Representation in the data dictionaryΒΆ

+

The β€œVR” column in the data dictionary gives the Value Representation. There is +usually only one possible VR for each tag [1].

+

If a particular stream of data elements is using β€œImplicit Value Representation +Encoding” then the data elements consist of (tag, Value Length, Value Field) and +the Value Representation is implicit. In this case we have to get the Value +Representation from the data dictionary. If a stream is using β€œExplicit Value +Representation Encoding”, the elements consist of (tag, Value Representation, +Value Length, Value Field) and the Value Representation is therefore already +specified along with the data.

+
+
+

Value Multiplicity in the data dictionaryΒΆ

+

The β€œVM” column in the dictionary gives the Value Multiplicity for this tag. +Quoting from PS 3.5 section 6.4:

+
+

The Value Multiplicity of a Data Element specifies the number of Values that +can be encoded in the Value Field of that Data Element. The VM of each Data +Element is specified explicitly in PS 3.6. If the number of Values that may +be encoded in an element is variable, it shall be represented by two numbers +separated by a dash; e.g., β€œ1-10” means that there may be 1 to 10 Values in +the element.

+
+

The most common values for Value Multiplicity in the standard data dictionary +are (in decreasing frequency) β€˜1’, β€˜1-n’, β€˜3’, β€˜2’, β€˜1-2’, β€˜4’ with other values +being less common.

+

The data dictionary is the only way to know the Value Multiplicity of a +particular tag. This means that we need the manufacturer’s private data +dictionary to know the Value Multiplicity of private attribute tags.

+
+
+
+

DICOM data structuresΒΆ

+
+

A data setΒΆ

+

A DICOM data set is a ordered list of data elements. The order of the list is +the order of the tags of the data elements. Here is the definition from section +3.10 of PS 3.5:

+
+

DATA SET: Exchanged information consisting of a structured set of Attribute +values directly or indirectly related to Information Objects. The value of +each Attribute in a Data Set is expressed as a Data Element. A collection +of Data Elements ordered by increasing Data Element Tag number that is an +encoding of the values of Attributes of a real world object.

+
+
+
+

Background - the DICOM worldΒΆ

+

DICOM has abstract definitions of a set of entities (objects) in the β€œReal +World”. These real world objects have relationships between them. Section 7 of +PS 3.3 has the title β€œDICOM model of the real world”. Examples of Real World +entities are Patient, Study, Series.

+

Here is a selected list of real world entities compiled from section 7 of PS +3.3:

+
    +
  • Patient

  • +
  • Visit

  • +
  • Study

  • +
  • Modality Performed Procedure Steps

  • +
  • Frame of Reference

  • +
  • Equipment

  • +
  • Series

  • +
  • Registration

  • +
  • Fiducials

  • +
  • Image

  • +
  • Presentation State

  • +
  • SR Document

  • +
  • Waveform

  • +
  • MR Spectroscopy

  • +
  • Raw Data

  • +
  • Encapsulated Document

  • +
  • Real World Value Mapping

  • +
  • Stereometric Relationship

  • +
  • Surface

  • +
  • Measurements

  • +
+

DICOM refers to its model of the entities and their relationships in the real +world as the DICOM Application Model. PS 3.3:

+
+

3.8.5 DICOM application model: an Entity-Relationship diagram used to model +the relationships between Real-World Objects which are within the area of +interest of the DICOM Standard.

+
+
+
+

DICOM Entities and Information Object DefinitionsΒΆ

+

This is rather confusing.

+

PS 3.3 gives definitions of fundamental DICOM objects called Information Object +Definitions (IODs). Here is the definition of an IOD from section 3.8.7 of PS +3.3:

+
+

3.8.7 Information object definition (IOD): a data abstraction of a class of +similar Real-World Objects which defines the nature and Attributes relevant +to the class of Real-World Objects represented.

+
+

IODs give lists of attributes (data elements) that refer to one or more objects +in the DICOM Real World.

+

A single IOD is the usual atom of data sent in a single DICOM message.

+

An IOD that contains attributes (data elements) for only one object in the DICOM +Real World is a Normalized IOD. From PS 3.3:

+
+

3.8.10 Normalized IOD: an Information Object Definition which represents a +single entity in the DICOM Application Model. Such an IOD includes +Attributes which are only inherent in the Real-World Object that the IOD +represents.

+
+

Annex B of PS 3.3 defines the normalized IODs.

+

Many DICOM Real World objects do not have corresponding normalized IODs, +presumably because there is no common need to send data only corresponding to - +say - a patient - without also sending related information like - say - an +image. If you do want to send information relating to a patient with +information relating to an image, you need a composite IOD.

+

An IOD that contains attributes from more than one object in the DICOM Real +World is a Composite IOD. PS 3.3 again:

+
+

3.8.2 Composite IOD: an Information Object Definition which represents parts +of several entities in the DICOM Application Model. Such an IOD includes +Attributes which are not inherent in the Real-World Object that the IOD +represents but rather are inherent in related Real-World Objects

+
+

Annex A of PS 3.3 defines the composite IODs.

+

DICOM MR or CT image IODs are classic examples of composite IODs, because they +contain information not just about the image itself, but also information about +the patient, the study, the series, the frame of reference and the equipment.

+

The term Information Entity (IE) refers to a part of a composite IOD that +relates to a single DICOM Real World object. PS 3.3:

+
+

3.8.6 Information entity: that portion of information defined by a Composite +IOD which is related to one specific class of Real-World Object. There is a +one-to-one correspondence between Information Entities and entities in the +DICOM Application Model.

+
+

IEs are names of DICOM Real World objects that label parts of a composite IOD. +IEs have no intrinsic content, but serve as meaningful labels for a group of +modules (see below) that refer to the same Real World object.

+

Annex A 1.2, PS 3.3 lists all the IEs used in composite IODs.

+

For example, section A.4 in PD 3.3 defines the composite IOD for an MR Image - +the Magnetic Resonance Image Object Definition. The definition looks like this +(table A.4-1 of PS 3.3)

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

IE

Module

Reference

Usage

Patient

Patient

C.7.1.1

M

Clinical Trial Subject

C.7.1.3

U

Study

General Study

C.7.2.1

M

Patient Study

C.7.2.2

U

Clinical Trial Study

C.7.2.3

U

Series

General Series

C.7.3.1

M

Clinical Trial Series

C.7.3.2

U

Frame of Reference

Frame of Reference

C.7.4.1

M

Equipment

General Equipment

C.7.5.1

M

Image

General Image

C.7.6.1

M

Image Plane

C.7.6.2

M

Image Pixel

C.7.6.3

M

Contrast/bolus

C.7.6.4

C - Required if contrast media was used in this image

Device

C.7.6.12

U

Specimen

C.7.6.22

U

MR Image

C.8.3.1

M

Overlay Plane

C.9.2

U

VOI LUT

C.11.2

U

SOP Common

C.12.1

M

+

As you can see, the MR Image IOD is composite and composed of Patient, Study, +Series, Frame of Reference, Equipment and Image IEs.

+

The module heading defines which modules make up the information relevant to +the IE.

+

A module is a named and defined grouping of attributes (data elements) with +related meaning. PS 3.3:

+
+

3.8.8 Module: A set of Attributes within an Information Entity or Normalized +IOD which are logically related to each other.

+
+

Grouping attributes into modules simplifies the definition of multiple composite +IODs. For example, the composite IODs for a CT image and an MR Image both have +modules for Patient, Clinical Trial Subject, etc.

+

Annex C of PS 3.3 defines all the modules used for the IOD definitions. For +example, from the table above, we see that the β€œPatient” module is at section +C.7.1.1 of PS 3.3. This section gives a table of all the attributes (data +elements) in this module.

+

The last column in the table above records whether the particular module is +Mandatory, Conditional or User Option (defined in section A 1.3 of PS 3.3)

+

Lastly module definitions may make use of Attribute macros. Attribute macros +are very much like modules, in that they are a named group of attributes that +often occur together in module definitions, or definitions of other macros. +From PS 3.3:

+
+

3.11.1 Attribute Macro: a set of Attributes that are described in a single +table that is referenced by multiple Modules or other tables.

+
+

For example, here is the Patient Orientation Macro definition table from section +10.12 in PS 3.3:

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

Attribute Name

Tag

Type

Attribute Description

Patient Orientation Code Sequence

(0054,0410)

1

Sequence that describes the orientation of the patient with respect to gravity. See C.8.11.5.1.2 for further explanation. Only a single Item shall be included in this Sequence.

>Include β€˜Code Sequence Macro’ Table 8.8-1.

Baseline Context ID 19

>Patient Orientation Modifier Code Sequence

(0054,0412)

1C

Patient orientation modifier. Required if needed to fully specify the orientation of the patient with respect to gravity. Only a single Item shall be included in this Sequence.

>>Include β€˜Code Sequence Macro’ Table 8.8-1.

Baseline Context ID 20

Patient Gantry Relationship Code Sequence

(0054,0414)

3

Sequence that describes the orientation of the patient with respect to the head of the table. See Section C.8.4.6.1.3 for further explanation. Only a single Item is permitted in this Sequence.

>Include β€˜Code Sequence Macro’ Table 8.8-1.

Baseline Context ID 21

+

As you can see, this macro specifies some tags that should appear when this +macro is β€œIncluded” - and also includes other macros.

+
+
+
+

DICOM services (DIMSE)ΒΆ

+

We now go back to messages.

+

The DICOM application sending the message is called the Service Class User +(SCU). We might also call this the client.

+

The DICOM application receiving the message is called the Service Class Provider +(SCP). We might also call this the server - for this particular message.

+

Quoting from PS 3.7 section 6.3:

+
+

A Message is composed of a Command Set followed by a conditional Data Set +(see PS 3.5 for the definition of a Data Set). The Command Set is used to +indicate the operations/notifications to be performed on or with the Data +Set.

+
+

The command set consists of command elements (elements with group number 0000).

+

Valid sequences of command elements in the command set form valid DICOM Message +Service Elements (DIMSEs). Sections 9 and 10 of PS 3.7 define the valid DIMSEs.

+

For example, there is a DIMSE service called β€œC-ECHO” that requests confirmation +from the responding application that the echo message arrived.

+

The definition of the DIMSE services specifies, for a particular DIMSE service, +whether the DIMSE command set should be followed by a data set.

+

In particular, the data set will be a full Information Object Definition’s worth +of data.

+

Of most interest to us, the β€œC-STORE” service command set should always be +followed by a data set conforming to an image data IOD.

+
+
+

DICOM service object pairs (SOPs)ΒΆ

+

As we’ve seen, some DIMSE services should be followed by particular types of +data.

+

For example, the β€œC-STORE” DIMSE command set should be followed by an IOD of +data to store, but the β€œC-ECHO” has no data object following.

+

The association of a particular type of DIMSE (command set) with the associated +IOD’s-worth of data is a Service Object Pair. The DIMSE is the β€œService” and the +data IOD is the β€œObject”. Thus the combination of a β€œC-STORE” DIMSE and an β€œMR +Image” IOD would be a SOP. Services that do not have data following are a +particular type of SOP where the Object is null. For example, the β€œC-ECHO” +service is the entire contents of a Verification SOP (PS 3.4, section A.4).

+

DICOM defines which pairings are possible, by listing them all as Service Object +Pair classes (SOP classes).

+

Usually a SOP class describes the pairing of exactly one DIMSE service with one +defined IOD. For example, the β€œMR Image storage” SOP class pairs the β€œC-STORE” +DIMSE with the β€œMR Image” IOD.

+

Sometimes a SOP class describes the pairings of one of several possible DIMSEs +with a particular IOP. For example, the β€œModality Performed Procedure Step” SOP +class describes the pairing of either (β€œN-CREATE”, Modality Performed +Procedure Step IOD) or (β€œN-SET”, Modality Performed Procedure Step IOD) (see +PS 3.4 F.7.1). For this reason a SOP class is best described as the pairing of +a DIMSE service group with an IOD, where the DIMSE service group usually +contains just one DIMSE service, but sometimes has more. For example, the β€œMR +Image Storage” SOP class has a DIMSE service group of one element [β€œC-STORE”]. +The β€œModality Performed Procedure Step” SOP class has a DIMSE service group with +two elements: [β€œN-CREATE”, β€œN-SET”].

+

From PS 3.4:

+
+

6.4 DIMSE SERVICE GROUP

+

DIMSE Service Group specifies one or more operations/notifications defined +in PS 3.7 which are applicable to an IOD.

+

DIMSE Service Groups are defined in this Part of the DICOM Standard, in the +specification of a Service - Object Pair Class.

+

6.5 SERVICE-OBJECT PAIR (SOP) CLASS

+

A Service-Object Pair (SOP) Class is defined by the union of an IOD and a +DIMSE Service Group. The SOP Class definition contains the rules and +semantics which may restrict the use of the services in the DIMSE Service +Group and/or the Attributes of the IOD.

+
+

The Annexes of PS 3.4 define the SOP classes.

+

A pairing of actual data of form (DIMSE group, IOD) that conforms to the SOP +class definition, is a SOP class instance. That is, the instance comprises the +actual values of the service and data elements being transmitted.

+

For example, there is a SOP class called β€œMR Image Storage”. This is the +association of the β€œC-STORE” DIMSE command with the β€œMR Image” IOD. A +particular β€œC-STORE” request command set along with the particular β€œMR Image” +IOD data set would be an instance of the MR Image SOP class.

+
+
+

DICOM filesΒΆ

+

Now let us return to the confusing definition of the DICOM file format from +section 7 of PS 3.10:

+
+

7 DICOM File Format

+

The DICOM File Format provides a means to encapsulate in a file the Data Set +representing a SOP Instance related to a DICOM IOD. As shown in Figure 7-1, +the byte stream of the Data Set is placed into the file after the DICOM File +Meta Information. Each file contains a single SOP Instance.

+
+

The DICOM file Meta Information is:

+
    +
  • File preamble - 128 bytes, content unspecified

  • +
  • DICOM prefix - 4 bytes β€œDICM” character string

  • +
  • 5 meta information elements (group 0002) as defined in table 7.1 of PS 3.10

  • +
+

There follows the IOD dataset part of the SOP instance. In the case of a file +storing an MR Image, this dataset will be of IOD type β€œMR Image”

+

Footnotes

+ +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/dicom/dicom_mosaic.html b/dicom/dicom_mosaic.html new file mode 100644 index 0000000000..bd154bba00 --- /dev/null +++ b/dicom/dicom_mosaic.html @@ -0,0 +1,232 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Siemens mosaic formatΒΆ

+

Siemens mosaic format is a way of storing a 3D image in a DICOM image +file. The simplest DICOM images only knows how to store 2D files. For +example, a 3D image in DICOM is usually stored as a series of 2D slices, +each slices as a separate DICOM image. . Mosaic format stores the 3D +image slices as a 2D grid - or mosaic.

+

For example here are the pixel data as loaded directly from a DICOM image +with something like:

+
import matplotlib.pylab as plt
+import dicom
+dcm_data = dicom.read_file('my_file.dcm')
+plt.imshow(dcm_data.pixel_array)
+
+
+../_images/mosaic_grid.png +
+

Getting the slices from the mosaicΒΆ

+

The apparent image in the DICOM file is a 2D array that consists of blocks, +that are the output 2D slices. Let’s call the original array the slab, and +the contained slices slices. The slices are of pixel dimension +n_slice_rows x n_slice_cols. The slab is of pixel dimension +n_slab_rows x n_slab_cols. Because the arrangement of blocks in the +slab is defined as being square, the number of blocks per slab row and slab +column is the same. Let n_blocks be the number of blocks contained in the +slab. There is also n_slices - the number of slices actually collected, +some number <= n_blocks. We have the value n_slices from the +β€˜NumberOfImagesInMosaic’ field of the Siemens private (CSA) header. +n_row_blocks and n_col_blocks are therefore given by +ceil(sqrt(n_slices)), and n_blocks is n_row_blocks ** 2. Also +n_slice_rows == n_slab_rows / n_row_blocks, etc. Using these numbers we +can therefore reconstruct the slices from the 2D DICOM pixel array.

+
+
+

DICOM orientation for mosaicΒΆ

+

See DICOM patient coordinate system and DICOM voxel to patient coordinate system mapping. We want a 4 x 4 +affine \(A\) that will take us from (transposed) voxel coordinates in the +DICOM image to mm in the DICOM patient coordinate system. See (i, j), columns, rows in DICOM for +what we mean by transposed voxel coordinates.

+

We can think of the affine \(A\) as the (3,3) component, \(RS\), and a (3,1) +translation vector \(\mathbf{t}\). \(RS\) can in turn be thought of as the +dot product of a (3,3) rotation matrix \(R\) and a scaling matrix \(S\), +where S = diag(s) and \(\mathbf{s}\) is a (3,) vector of voxel sizes. +\(\mathbf{t}\) is a (3,1) translation vector, defining the coordinate in +millimeters of the first voxel in the voxel volume (the voxel given by +voxel_array[0,0,0]).

+

In the case of the mosaic, we have the first two columns of \(R\) from the +\(F\) - the left/right flipped version of the ImageOrientationPatient +DICOM field described in DICOM affines again. To make a full +rotation matrix, we can generate the last column from the cross product +of the first two. However, Siemens defines, in its private +CSA header, a SliceNormalVector which gives the third column, +but possibly with a z flip, so that \(R\) is orthogonal, but not a +rotation matrix (it has a determinant of < 0).

+

The first two values of \(\mathbf{s}\) (\(s_1, s_2\)) are given by the +PixelSpacing field. We get \(s_3\) (the slice scaling +value) from SpacingBetweenSlices.

+

The SPM DICOM conversion code has a comment saying that mosaic DICOM images +have an incorrect ImagePositionPatient field. The +ImagePositionPatient field usually gives the \(\mathbf{t}\) vector. +The comments imply that Siemens has derived ImagePositionPatient +from the (correct) position of the center of the first slice (once the +mosaic has been unpacked), but has then adjusted the vector to point to +the top left voxel, where the slice size used for this adjustment is the +size of the mosaic, before it has been unpacked. Let’s call the correct +position in millimeters of the center of the first slice \(\mathbf{c} = +[c_x, c_y, c_z]\). We have the derived \(RS\) matrix from the calculations +above. The unpacked (eventual, real) slice dimensions are \((rd_{rows}, +rd_{cols})\) and the mosaic dimensions are \((md_{rows}, md_{cols})\). The +ImagePositionPatient vector \(\mathbf{i}\) resulted from:

+
+\[\begin{split}\mathbf{i} = \mathbf{c} + RS + \begin{bmatrix} -(md_{rows}-1) / 2\\ + -(md_{cols}-1) / 2\\ + 0 \end{bmatrix}\end{split}\]
+

To correct the faulty translation, we reverse it, and add the correct +translation for the unpacked slice size \((rd_{rows}, rd_{cols})\), giving +the true image position \(\mathbf{t}\):

+
+\[\begin{split}\mathbf{t} = \mathbf{i} - + (RS \begin{bmatrix} -(md_{rows}-1) / 2\\ + -(md_{cols}-1) / 2\\ + 0 \end{bmatrix}) + + (RS \begin{bmatrix} -(rd_{rows}-1) / 2\\ + -(rd_{cols}-1) / 2\\ + 0 \end{bmatrix})\end{split}\]
+

Because of the final zero in the voxel translations, this simplifies to:

+
+\[\begin{split}\mathbf{t} = \mathbf{i} + + Q \begin{bmatrix} (md_{rows} - rd_{rowss}) / 2 \\ + (md_{cols} - rd_{cols}) / 2 \end{bmatrix}\end{split}\]
+

where:

+
+\[\begin{split}Q = \begin{bmatrix} rs_{11} & rs_{12} \\ + rs_{21} & rs_{22} \\ + rs_{31} & rs_{32} \end{bmatrix}\end{split}\]
+
+
+

Data scalingΒΆ

+

SPM gets the DICOM scaling, offset for the image (β€˜RescaleSlope’, +β€˜RescaleIntercept’). It writes these scalings into the nifti header. +Then it writes the raw image data (unscaled) to disk. Obviously these +will have the current scalings applied when the nifti image is read again.

+

A comment in the code here says that the data are not scaled by the +maximum amount. I assume by this they mean that the DICOM scaling may +not be the maximum scaling, whereas the standard SPM image write is, +hence the difference, because they are using the DICOM scaling rather +then their own. The comment continues by saying that the scaling as +applied (the DICOM - not maximum - scaling) can lead to rounding errors +but that it will get around some unspecified problems.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/dicom/dicom_niftiheader.html b/dicom/dicom_niftiheader.html new file mode 100644 index 0000000000..df6c2eacc8 --- /dev/null +++ b/dicom/dicom_niftiheader.html @@ -0,0 +1,183 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

DICOM Tags in the NIfTI HeaderΒΆ

+

NIfTI images include an extended header (see the NIfTI Extensions Standard) +to store, amongst others, DICOM tags and attributes. When NiBabel loads a NIfTI +file containing DICOM information (a NIfTI extension with ecode == 2), it +parses it and returns a pydicom dataset as the content of the NIfTI extension. +This can be read and written to in order to facilitate communication with +software that uses specific DICOM codes found in the NIfTI header.

+

For example, the commercial PMOD software stores the Frame Start and Duration +times of images using the DICOM tags (0055, 1001) and (0055, 1004). Here’s an +example of an image created in PMOD with those stored times accessed through +nibabel.

+
>> import nibabel as nib
+>> nim = nib.load('pmod_pet.nii')
+>> dcmext = nim.header.extensions[0]
+>> dcmext
+Nifti1Extension('dicom', '(0054, 1001) Units                               CS: 'Bq/ml'
+(0055, 0010) Private Creator                     LO: 'PMOD_1'
+(0055, 1001) [Frame Start Times Vector]          FD: [0.0, 30.0, 60.0, ..., 13720.0, 14320.0]
+(0055, 1004) [Frame Durations (ms) Vector]       FD: [30000.0, 30000.0, 30000.0,600000.0, 600000.0]'))
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Tag

Name

Value

(0054, 1001)

Units

CS: β€˜Bq/ml’

(0055, 0010)

Private Creator

LO: β€˜PMOD_1’

(0055, 1001)

[Frame Start Times Vector]

FD: [0.0, 30.0, 60.0, …, 13720.0, 14320.0

(0055, 1004)

[Frame Durations (ms) Vector]

FD: [30000.0, 30000.0, 30000.0, …, 600000.0, 600000.0

+

Access each value as you would with pydicom:

+
>> ds = dcmext.get_content()
+>> start_times = ds[0x0055, 0x1001].value
+>> durations   = ds[0x0055, 0x1004].value
+
+
+

Creating a PMOD-compatible header is just as easy:

+
>> nim = nib.load('pet.nii')
+>> nim.header.extensions
+[]
+>> from dicom.dataset import Dataset
+>> ds = Dataset()
+>> ds.add_new((0x0054,0x1001),'CS','Bq/ml')
+>> ds.add_new((0x0055,0x0010),'LO','PMOD_1')
+>> ds.add_new((0x0055,0x1001),'FD',[0.,30.,60.,13720.,14320.])
+>> ds.add_new((0x0055,0x1004),'FD',[30000.,30000.,30000.,600000.,600000.])
+>> dcmext = nib.nifti1.Nifti1DicomExtension(2,ds)  # Use DICOM ecode 2
+>> nim.header.extensions.append(dcmext)
+>> nib.save(nim,'pet_withdcm.nii')
+
+
+

Be careful! Many imaging tools don’t maintain information in the extended +header, so it’s possible [likely] that this information may be lost during +routine use. You’ll have to keep track, and re-write the information if +required.

+

Optional Dependency Note: If pydicom is not installed, nibabel uses a generic +nibabel.nifti1.Nifti1Extension header instead of parsing DICOM data.

+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/dicom/dicom_orientation.html b/dicom/dicom_orientation.html new file mode 100644 index 0000000000..bc834e9c9a --- /dev/null +++ b/dicom/dicom_orientation.html @@ -0,0 +1,461 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Defining the DICOM orientationΒΆ

+
+

DICOM patient coordinate systemΒΆ

+

First we define the standard DICOM patient-based coordinate system. +This is what DICOM means by x, y and z axes in its orientation +specification. From section C.7.6.2.1.1 of the DICOM object +definitions (2009):

+
+

If Anatomical Orientation Type (0010,2210) is absent or has a value +of BIPED, the x-axis is increasing to the left hand side of the +patient. The y-axis is increasing to the posterior side of the +patient. The z-axis is increasing toward the head of the patient.

+
+

(we’ll ignore the quadupeds for now).

+

In a way it’s funny to call this the β€˜patient-based’ coordinate system. +β€˜Doctor-based coordinate system’ is a better name. Think of a doctor +looking at the patient from the foot of the scanner bed. Imagine the +doctor’s right hand held in front of her like Spiderman about to shoot a +web, with her palm towards the patient, defining a right-handed +coordinate system. Her thumb points to her right (the patient’s left), +her index finger points down, and the middle finger points at the +patient.

+
+
+

DICOM pixel dataΒΆ

+
+
C.7.6.3.1.4 - Pixel Data

Pixel Data (7FE0,0010) for this image. The order of pixels sent for +each image plane is left to right, top to bottom, i.e., the upper +left pixel (labeled 1,1) is sent first followed by the remainder of +row 1, followed by the first pixel of row 2 (labeled 2,1) then the +remainder of row 2 and so on.

+
+
+

The resulting pixel array then has size (β€˜Rows’, β€˜Columns’), with +row-major storage (rows first, then columns). We’ll call this the DICOM +pixel array.

+
+
+

Pixel spacingΒΆ

+
+
Section 10.7.1.3: Pixel Spacing

The first value is the row spacing in mm, that is the spacing between +the centers of adjacent rows, or vertical spacing. The second value +is the column spacing in mm, that is the spacing between the centers +of adjacent columns, or horizontal spacing.

+
+
+
+
+

DICOM voxel to patient coordinate system mappingΒΆ

+

See:

+ +

See wikipedia direction cosine for a definition of direction cosines.

+

From section C.7.6.2.1.1 of the DICOM object definitions (2009):

+
+

The Image Position (0020,0032) specifies the x, y, and z coordinates +of the upper left hand corner of the image; it is the center of the +first voxel transmitted. Image Orientation (0020,0037) specifies the +direction cosines of the first row and the first column with respect +to the patient. These Attributes shall be provide as a pair. Row +value for the x, y, and z axes respectively followed by the Column +value for the x, y, and z axes respectively.

+
+

From Section C.7.6.1.1.1 we see that the β€˜positive row axis’ is left to +right, and is the direction of the rows, given by the direction of last +pixel in the first row from the first pixel in that row. Similarly the +β€˜positive column axis’ is top to bottom and is the direction of the +columns, given by the direction of the last pixel in the first column +from the first pixel in that column.

+

Let’s rephrase: the first three values of β€˜Image Orientation Patient’ +are the direction cosine for the β€˜positive row axis’. That is, they +express the direction change in (x, y, z), in the DICOM patient +coordinate system (DPCS), as you move along the row. That is, as you +move from one column to the next. That is, as the column array index +changes. Similarly, the second triplet of values of β€˜Image Orientation +Patient’ (img_ornt_pat[3:] in Python), are the direction cosine for +the β€˜positive column axis’, and express the direction you move, in the +DPCS, as you move from row to row, and therefore as the row index +changes.

+

Further down section C.7.6.2.1.1 (RCS below is the reference coordinate +system - see DICOM object definitions section 3.17.1):

+
+

The Image Plane Attributes, in conjunction with the Pixel Spacing +Attribute, describe the position and orientation of the image slices +relative to the patient-based coordinate system. In each image frame +the Image Position (Patient) (0020,0032) specifies the origin of the +image with respect to the patient-based coordinate system. RCS and +the Image Orientation (Patient) (0020,0037) attribute values specify +the orientation of the image frame rows and columns. The mapping of +pixel location (i, j) to the RCS is calculated as follows:

+
+\[\begin{split}\begin{bmatrix} P_x\\ + P_y\\ + P_z\\ + 1 \end{bmatrix} = +\begin{bmatrix} X_x\Delta{i} & Y_x\Delta{j} & 0 & S_x \\ + X_y\Delta{i} & Y_y\Delta{j} & 0 & S_y \\ + X_z\Delta{i} & Y_z\Delta{j} & 0 & S_z \\ + 0 & 0 & 0 & 1 \end{bmatrix} +\begin{bmatrix} i\\ + j\\ + 0\\ + 1 \end{bmatrix} += M +\begin{bmatrix} i\\ + j\\ + 0\\ + 1 \end{bmatrix}\end{split}\]
+

Where:

+
    +
  1. \(P_{xyz}\) : The coordinates of the voxel (i,j) in the frame’s +image plane in units of mm.

  2. +
  3. \(S_{xyz}\) : The three values of the Image Position (Patient) +(0020,0032) attributes. It is the location in mm from the origin +of the RCS.

  4. +
  5. \(X_{xyz}\) : The values from the row (X) direction cosine of the +Image Orientation (Patient) (0020,0037) attribute.

  6. +
  7. \(Y_{xyz}\) : The values from the column (Y) direction cosine of the +Image Orientation (Patient) (0020,0037) attribute.

  8. +
  9. \(i\) : Column index to the image plane. The first column is index +zero.

  10. +
  11. \(\Delta{i}\): Column pixel resolution of the Pixel Spacing +(0028,0030) attribute in units of mm.

  12. +
  13. \(j\) : Row index to the image plane. The first row index is zero.

  14. +
  15. \(\Delta{j}\) - Row pixel resolution of the Pixel Spacing +(0028,0030) attribute in units of mm.

  16. +
+
+
+
+

(i, j), columns, rows in DICOMΒΆ

+

We stop to ask ourselves, what does DICOM mean by voxel (i, j)?

+

Isn’t that obvious? Oh dear, no it isn’t. See the +DICOM voxel to patient coordinate system mapping formula above. In particular, you’ll see:

+
    +
  • \(i\) : Column index to the image plane. The first column is index zero.

  • +
  • \(j\) : Row index to the image plane. The first row index is zero.

  • +
+

That is, if we have the DICOM pixel data as defined above, and +we call that pixel_array, then voxel (i, j) in the notation above is +given by pixel_array[j, i].

+

What does this mean? It means that, if we want to apply the formula +above to array indices in pixel_array, we first have to apply a +column / row flip to the indices. Say \(M_{pixar}\) (sorry) is the affine +to go from array indices in pixel_array to mm in the DPCS. Then, +given \(M\) above:

+
+\[\begin{split}M_{pixar} = M \left(\begin{smallmatrix}0 & 1 & 0 & 0\\1 & 0 & 0 & 0\\0 & 0 & 1 & 0\\0 & 0 & 0 & 1\end{smallmatrix}\right)\end{split}\]
+
+
+

DICOM affines againΒΆ

+

The (i, j), columns, rows in DICOM is rather confusing, so we’re going to rephrase +the affine mapping; we’ll use \(r\) for the row index (instead of \(j\) +above), and \(c\) for the column index (instead of \(i\)).

+

Next we define a flipped version of β€˜ImageOrientationPatient’, \(F\), that +has flipped columns. Thus if the vector of 6 values in +β€˜ImageOrientationPatient’ are \((i_1 .. i_6)\), then:

+
+\[\begin{split}F = \begin{bmatrix} i_4 & i_1 \\ + i_5 & i_2 \\ + i_6 & i_3 \end{bmatrix}\end{split}\]
+

Now the first column of F contains what the DICOM docs call the β€˜column +(Y) direction cosine’, and second column contains the β€˜row (X) direction +cosine’. We prefer to think of these as (respectively) the row index +direction cosine and the column index direction cosine.

+

Now we can rephrase the DICOM affine mapping with:

+
+
+

DICOM affine formulaΒΆ

+
+\[\begin{split}\begin{bmatrix} P_x\\ + P_y\\ + P_z\\ + 1 \end{bmatrix} = +\begin{bmatrix} F_{11}\Delta{r} & F_{12}\Delta{c} & 0 & S_x \\ + F_{21}\Delta{r} & F_{22}\Delta{c} & 0 & S_y \\ + F_{31}\Delta{r} & F_{32}\Delta{c} & 0 & S_z \\ + 0 & 0 & 0 & 1 \end{bmatrix} +\begin{bmatrix} r\\ + c\\ + 0\\ + 1 \end{bmatrix} += A +\begin{bmatrix} r\\ + c\\ + 0\\ + 1 \end{bmatrix}\end{split}\]
+

Where:

+
    +
  • \(P_{xyz}\) : The coordinates of the voxel (c, r) in the frame’s image +plane in units of mm.

  • +
  • \(S_{xyz}\) : The three values of the Image Position (Patient) +(0020,0032) attributes. It is the location in mm from the origin of +the RCS.

  • +
  • \(F_{:,1}\) : The values from the column (Y) direction cosine of the +Image Orientation (Patient) (0020,0037) attribute - see above.

  • +
  • \(F_{:,2}\) : The values from the row (X) direction cosine of the Image +Orientation (Patient) (0020,0037) attribute - see above.

  • +
  • \(r\) : Row index to the image plane. The first row index is zero.

  • +
  • \(\Delta{r}\) - Row pixel resolution of the Pixel Spacing (0028,0030) +attribute in units of mm.

  • +
  • \(c\) : Column index to the image plane. The first column is index zero.

  • +
  • \(\Delta{c}\): Column pixel resolution of the Pixel Spacing (0028,0030) +attribute in units of mm.

  • +
+

For later convenience we also define values useful for 3D volumes:

+
    +
  • \(s\) : Slice index to the slice plane. The first slice index is zero.

  • +
  • \(\Delta{s}\) - Spacing in mm between slices.

  • +
+
+
+

Getting a 3D affine from a DICOM slice or list of slicesΒΆ

+

Let us say, we have a single DICOM file, or a list of DICOM files that +we believe to be a set of slices from the same volume. We’ll call the +first the single slice case, and the second, multi slice.

+

In the multi slice case, we can assume that the +β€˜ImageOrientationPatient’ field is the same for all the slices.

+

We want to get the affine transformation matrix \(A\) that maps from voxel +coordinates in the DICOM file(s), to mm in the DICOM patient coordinate system.

+

By voxel coordinates, we mean coordinates of form \((r, c, s)\) - the row, +column and slice indices - as for the DICOM affine formula.

+

In the single slice case, the voxel coordinates are just the indices +into the pixel array, with the third (slice) coordinate always being 0.

+

In the multi-slice case, we have arranged the slices in ascending or +descending order, where slice numbers range from 0 to \(N-1\) - where \(N\) +is the number of slices - and the slice coordinate is a number on this +scale.

+

We know, from DICOM affine formula, that the first, second and +fourth columns in \(A\) are given directly by the (flipped) +β€˜ImageOrientationPatient’, β€˜PixelSpacing’ and β€˜ImagePositionPatient’ +field of the first (or only) slice.

+

Our job then is to fill the first three rows of the third column of \(A\). +Let’s call this the vector \(\mathbf{k}\) with values \(k_1, k_2, k_3\).

+
+

DICOM affine DefinitionsΒΆ

+

See also the definitions in DICOM affine formula. In addition

+
    +
  • \(T^1\) is the 3 element vector of the β€˜ImagePositionPatient’ field of +the first header in the list of headers for this volume.

  • +
  • \(T^N\) is the β€˜ImagePositionPatient’ vector for the last header in the +list for this volume, if there is more than one header in the volume.

  • +
  • vector \(\mathbf{n} = (n_1, n_2, n_3)\) is the result of taking the +cross product of the two columns of \(F\) from +DICOM affine formula.

  • +
+
+
+

DerivationsΒΆ

+

For the single slice case we just fill \(\mathbf{k}\) with \(\mathbf{n} \cdot +\Delta{s}\) - on the basis that the Z dimension should be +right-handed orthogonal to the X and Y directions.

+

For the multi-slice case, we can fill in \(\mathbf{k}\) by using the information +from \(T^N\), because \(T^N\) is the translation needed to take the +first voxel in the last (slice index = \(N-1\)) slice to mm space. So:

+
+\[\begin{split}\left(\begin{smallmatrix}T^N\\1\end{smallmatrix}\right) = A \left(\begin{smallmatrix}0\\0\\N - 1\\1\end{smallmatrix}\right)\end{split}\]
+

From this it follows that:

+
+\[\begin{Bmatrix}k_{{1}} : \frac{T^{N}_{{1}} - T^{1}_{{1}}}{N - 1}, & k_{{2}} : \frac{T^{N}_{{2}} - T^{1}_{{2}}}{N - 1}, & k_{{3}} : \frac{T^{N}_{{3}} - T^{1}_{{3}}}{N - 1}\end{Bmatrix}\]
+

and therefore:

+
+
+

3D affine formulaeΒΆ

+
+\[ \begin{align}\begin{aligned}\begin{split}A_{multi} = \left(\begin{smallmatrix}F_{{11}} \Delta{r} & F_{{12}} \Delta{c} & \frac{T^{N}_{{1}} - T^{1}_{{1}}}{N - 1} & T^{1}_{{1}}\\F_{{21}} \Delta{r} & F_{{22}} \Delta{c} & \frac{T^{N}_{{2}} - T^{1}_{{2}}}{N - 1} & T^{1}_{{2}}\\F_{{31}} \Delta{r} & F_{{32}} \Delta{c} & \frac{T^{N}_{{3}} - T^{1}_{{3}}}{N - 1} & T^{1}_{{3}}\\0 & 0 & 0 & 1\end{smallmatrix}\right)\end{split}\\\begin{split}A_{single} = \left(\begin{smallmatrix}F_{{11}} \Delta{r} & F_{{12}} \Delta{c} & \Delta{s} n_{{1}} & T^{1}_{{1}}\\F_{{21}} \Delta{r} & F_{{22}} \Delta{c} & \Delta{s} n_{{2}} & T^{1}_{{2}}\\F_{{31}} \Delta{r} & F_{{32}} \Delta{c} & \Delta{s} n_{{3}} & T^{1}_{{3}}\\0 & 0 & 0 & 1\end{smallmatrix}\right)\end{split}\end{aligned}\end{align} \]
+

See derivations/spm_dicom_orient.py for the derivations and +some explanations.

+

For a single slice \(N=1\) the affine matrix is \(A_{single}\). In this +case, the slice spacing \(\Delta{s}\) may be obtained by the Spacing +Between Slices (0018,0088) attribute in units of mm, if it exists.

+
+
+
+

Working out the Z coordinates for a set of slicesΒΆ

+

We may have the problem (see e.g. Sorting files into volumes) of trying +to sort a set of slices into anatomical order. For this we want to use +the orientation information to tell us where the slices are in space, +and therefore, what order they should have.

+

To do this sorting, we need something that is proportional, plus a +constant, to the voxel coordinate for the slice (the value for the slice +index).

+

Our DICOM might have the β€˜SliceLocation’ field (0020,1041). +β€˜SliceLocation’ seems to be proportional to slice location, at least for +some GE and Philips DICOMs I was looking at. But, there is a more +reliable way (that doesn’t depend on this field), and uses only the very +standard β€˜ImageOrientationPatient’ and β€˜ImagePositionPatient’ fields.

+

Consider the case where we have a set of slices, of unknown order, from +the same volume.

+

Now let us say we have one of these slices - slice \(i\). We have the +affine for this slice from the calculations above, for a single slice +(\(A_{single}\)).

+

Now let’s say we have another slice \(j\) from the same volume. It will +have the same affine, except that the β€˜ImagePositionPatient’ field will +change to reflect the different position of this slice in space. Let us +say that there a translation of \(d\) slices between \(i\) and \(j\). If +\(A_i\) (\(A\) for slice \(i\)) is \(A_{single}\) then \(A_j\) for \(j\) is given +by:

+
+\[\begin{split}A_j = A_{single} \left(\begin{smallmatrix}1 & 0 & 0 & 0\\0 & 1 & 0 & 0\\0 & 0 & 1 & d\\0 & 0 & 0 & 1\end{smallmatrix}\right)\end{split}\]
+

and β€˜ImagePositionPatient’ for \(j\) is:

+
+\[\begin{split}T^j = \left(\begin{smallmatrix}T^{1}_{{1}} + \Delta{s} d n_{{1}}\\T^{1}_{{2}} + \Delta{s} d n_{{2}}\\T^{1}_{{3}} + \Delta{s} d n_{{3}}\end{smallmatrix}\right)\end{split}\]
+

Remember that the third column of \(A\) gives the vector resulting from a +unit change in the slice voxel coordinate. So, the +β€˜ImagePositionPatient’ of slice - say slice \(j\) - can be thought of the +addition of two vectors \(T^j = \mathbf{a} + \mathbf{b}\), where +\(\mathbf{a}\) is the position of the first voxel in some slice (here +slice 1, therefore \(\mathbf{a} = T^1\)) and \(\mathbf{b}\) is \(d\) times the +third column of \(A\). Obviously \(d\) can be negative or positive. This +leads to various ways of recovering something that is proportional to +\(d\) plus a constant. The algorithm suggested in this ITK post on +ordering slices - and the one used by SPM - is to take the inner +product of \(T^j\) with the unit vector component of third column of +\(A_j\) - in the descriptions here, this is the vector \(\mathbf{n}\):

+
+\[T^j \cdot \mathbf{c} = \left(\begin{smallmatrix}T^{1}_{{1}} n_{{1}} + T^{1}_{{2}} n_{{2}} + T^{1}_{{3}} n_{{3}} + \Delta{s} d n_{{1}}^{2} + \Delta{s} d n_{{2}}^{2} + \Delta{s} d n_{{3}}^{2}\end{smallmatrix}\right)\]
+

This is the distance of β€˜ImagePositionPatient’ along the slice direction +cosine.

+

The unknown \(T^1\) terms pool into a constant, and the operation has the +neat feature that, because the \(n_{123}^2\) terms, by definition, sum to 1, +the whole can be expressed as \(\lambda + \Delta{s} d\) - i.e. it is +equal to the slice voxel size (\(\Delta{s}\)) multiplied by \(d\), +plus a constant.

+

Again, see derivations/spm_dicom_orient.py for the derivations.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/dicom/siemens_csa.html b/dicom/siemens_csa.html new file mode 100644 index 0000000000..08bb1812cc --- /dev/null +++ b/dicom/siemens_csa.html @@ -0,0 +1,248 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Siemens format DICOM with CSA headerΒΆ

+

Recent Siemens DICOM images have useful information stored in a private +header. We’ll call this the CSA header.

+
+

CSA headerΒΆ

+

See this Siemens Syngo DICOM conformance statement, and a GDCM +Siemens header dump.

+

The CSA header is stored in DICOM private tags. In the images we are +looking at, there are several relevant tags:

+
(0029, 1008) [CSA Image Header Type]             OB: 'IMAGE NUM 4 '
+(0029, 1009) [CSA Image Header Version]          OB: '20100114'
+(0029, 1010) [CSA Image Header Info]             OB: Array of 11560 bytes
+(0029, 1018) [CSA Series Header Type]            OB: 'MR'
+(0029, 1019) [CSA Series Header Version]         OB: '20100114'
+(0029, 1020) [CSA Series Header Info]            OB: Array of 80248 bytes
+
+
+

In our case we want to read the β€˜CSAImageHeaderInfo’.

+

From the SPM (SPM8) code spm_dicom_headers.m

+

The CSAImageHeaderInfo and the CSA Series Header Info fields are of the +same format. The fields can be of two types, CSA1 and CSA2.

+

Both are always little-endian, whatever the machine endian is.

+

The CSA2 format begins with the string β€˜SV10’, the CSA1 format does +not.

+

The code below keeps track of the position within the CSA header +stream. We’ll call this csa_position. At this point (after +reading the 8 bytes of the header), csa_position == 8. There’s a +variable that sets the last byte position in the file that is sensibly +still CSA header, and we’ll call that csa_max_pos.

+
+
+

CSA1ΒΆ

+
+

Start headerΒΆ

+
    +
  1. n_tags, uint32, number of tags. Number of tags should apparently be +between 1 and 128. If this is not true we just abort and move to +csa_max_pos.

  2. +
  3. unused, uint32, apparently has value 77

  4. +
+
+
+

Each tagΒΆ

+
    +
  1. name : S64, null terminated string 64 bytes

  2. +
  3. vm : int32

  4. +
  5. vr : S4, first 3 characters only

  6. +
  7. syngodt : int32

  8. +
  9. nitems : int32

  10. +
  11. xx : int32 - apparently either 77 or 205

  12. +
+

nitems gives the number of items in the tag. The items follow +directly after the tag.

+
+
+

Each itemΒΆ

+
    +
  1. xx : int32 * 4 . The first of these seems to be the length of the +item in bytes, modified as below.

  2. +
+

At this point SPM does a check, by calculating the length of this item +item_len with xx[0] - the nitems of the first read tag. +If item_len is less than 0 or greater than +csa_max_pos-csa_position (the remaining number of bytes to read in +the whole header) then we break from the item reading loop, +setting the value below to β€˜β€™.

+

Then we calculate item_len rounded up to the nearest 4 byte boundary +tp get next_item_pos.

+
    +
  1. value : uint8, item_len.

  2. +
+

We set the stream position to next_item_pos.

+
+
+
+

CSA2ΒΆ

+
+

Start headerΒΆ

+
    +
  1. hdr_id : S4 == β€˜SV10’

  2. +
  3. unused1 : uint8, 4

  4. +
  5. n_tags, uint32, number of tags. Number of tags should apparently be +between 1 and 128. If this is not true we just abort and move to +csa_max_pos.

  6. +
  7. unused2, uint32, apparently has value 77

  8. +
+
+
+

Each tagΒΆ

+
    +
  1. name : S64, null terminated string 64 bytes

  2. +
  3. vm : int32

  4. +
  5. vr : S4, first 3 characters only

  6. +
  7. syngodt : int32

  8. +
  9. nitems : int32

  10. +
  11. xx : int32 - apparently either 77 or 205

  12. +
+

nitems gives the number of items in the tag. The items follow +directly after the tag.

+
+
+

Each itemΒΆ

+
    +
  1. xx : int32 * 4 . The first of these seems to be the length of the +item in bytes, modified as below.

  2. +
+

Now there’s a different length check from CSA1. item_len is given +just by xx[1]. If item_len > csa_max_pos - csa_position +(the remaining bytes in the header), then we just read the remaining +bytes in the header (as above) into value below, as uint8, move the +filepointer to the next 4 byte boundary, and give up reading.

+
    +
  1. value : uint8, item_len.

  2. +
+

We set the stream position to the next 4 byte boundary.

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/dicom/spm_dicom.html b/dicom/spm_dicom.html new file mode 100644 index 0000000000..9bc2f27afb --- /dev/null +++ b/dicom/spm_dicom.html @@ -0,0 +1,409 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

SPM DICOM conversionΒΆ

+

These are some notes on the algorithms that SPM uses to convert from +DICOM to nifti. There are other notes in Siemens mosaic format.

+

The relevant SPM files are spm_dicom_headers.m, +spm_dicom_dict.mat and spm_dicom_convert.m. These notes refer +the version in SPM8, as of around January 2010.

+
+

spm_dicom_dict.matΒΆ

+

This is obviously a Matlab .mat file. It contains variables +group and element, and values, where values is a struct +array, one element per (group, element) pair, with fields name and +vr (the last a cell array).

+
+
+

spm_dicom_headers.mΒΆ

+

Reads the given DICOM files into a struct. It looks like this was +written by John Ahsburner (JA). Relevant fixes are:

+
+

File openingΒΆ

+

When opening the DICOM file, SPM (subfunction readdicomfile)

+
    +
  1. opens as little endian

  2. +
  3. reads 4 characters starting at pos 128

  4. +
  5. checks if these are DICM; if so then continues file read; +otherwise, tests to see if this is what SPM calls truncated DICOM +file format - lacking 128 byte lead in and DICM string:

    +
      +
    1. Seeks to beginning of file

    2. +
    3. Reads two unsigned short values into group and tag

    4. +
    5. If the (group, element) pair exist in +spm_dicom_dict.mat, then set file pointer to 0 and continue +read with read_dicom subfunction..

    6. +
    7. If group == 8 and element == 0, this is apparently the +signature for a β€˜GE Twin+excite’ for which JA notes there is no +documentation; set file pointer to 0 and continue read with +read_dicom subfunction.

    8. +
    9. Otherwise - crash out with error saying that this is not DICOM file.

    10. +
    +
  6. +
+
+
+

tag read for Philips IntegraΒΆ

+

The read_dicom subfunction reads a tag, then has a loop during which +the tag is processed (by setting values into the return structure). At +the end of the loop, it reads the next tag. The loop breaks when the +current tag is empty, or is the item delimitation tag (group=FFFE, +element=E00D).

+

After it has broken out of the loop, if the last tag was (FFFE, E00D) +(item delimitation tag), and the tag length was not 0, then SPM sets the +file pointer back by 4 bytes from the current position. JA comments +that he didn’t find that in the standard, but that it seemed to be +needed for the Philips Integra.

+
+
+

Tag lengthΒΆ

+

Tag lengths as read in read_tag subfunction. If current format is +explicit (as in β€˜explicit little endian’):

+
    +
  1. For VR of x00x00, then group, element must be (FFFE, E00D) (item +delimitation tag). JA comments that GE β€˜ImageDelimitationItem’ has +no VR, just 4 0 bytes. In this case the tag length is zero, and we +read another two bytes ahead.

  2. +
+

There’s a check for not-even tag length. If not even:

+
    +
  1. 4294967295 appears to be OK - and decoded as Inf for tag length.

  2. +
  3. 13 appears to mean 10 and is reset to be 10

  4. +
  5. Any other odd number is not valid and gives a tag length of 0

  6. +
+
+
+

SQ VR type (Sequence of items type)ΒΆ

+

tag length of 13 set to tag length 10.

+
+
+
+

spm_dicom_convert.mΒΆ

+

Written by John Ashburner and Jesper Andersson.

+
+

File categorizationΒΆ

+

SPM makes a special case of Siemens β€˜spectroscopy images’. These are +images that have β€˜SOPClassUID’ == β€˜1.3.12.2.1107.5.9.1’ and the private +tag of (29, 1210); for these it pulls out the affine, and writes a +volume of ones corresponding to the acquisition planes.

+

For images that are not spectroscopy:

+
    +
  • Discards images that do not have any of (β€˜MR’, β€˜PT’, β€˜CT’) in β€˜Modality’ field.

  • +
  • Discards images lacking any of β€˜StartOfPixelData’, β€˜SamplesperPixel’, +β€˜Rows’, β€˜Columns’, β€˜BitsAllocated’, β€˜BitsStored’, β€˜HighBit’, +β€˜PixelRespresentation’

  • +
  • Discards images lacking any of β€˜PixelSpacing’, β€˜ImagePositionPatient’, +β€˜ImageOrientationPatient’ - presumably on the basis that SPM cannot +reconstruct the affine.

  • +
  • Fields β€˜SeriesNumber’, β€˜AcquisitionNumber’ and β€˜InstanceNumber’ are +set to 1 if absent.

  • +
+

Next SPM distinguishes between Siemens mosaic format and standard DICOM.

+

Mosaic images are those with the Siemens private tag:

+
(0029, 1009) [CSA Image Header Version]          OB: '20100114'
+
+
+

and a readable CSA header (see Siemens mosaic format), and with +non-empty fields from that header of β€˜AcquisitionMatrixText’, +β€˜NumberOfImagesInMosaic’, and with non-zero β€˜NumberOfImagesInMosaic’. The +rest are standard DICOM.

+

For converting mosaic format, see Siemens mosaic format. The rest of this +page refers to standard (slice by slice) DICOMs.

+
+
+

Sorting files into volumesΒΆ

+
+

First passΒΆ

+

Take first header, put as start of first volume. For each subsequent header:

+
    +
  1. Get ICE_Dims if present. Look for Siemens β€˜CSAImageHeaderInfo’, +check it has a β€˜name’ field, then pull dimensions out of β€˜ICE_Dims’ +field in form of 9 integers separated by β€˜_’, where β€˜X’ in this +string replaced by β€˜-1’ - giving β€˜ICE1’

  2. +
+

Then, for each currently identified volume:

+
    +
  1. If we have ICE1 above, and we do have β€˜CSAIMageHeaderInfo’, with a +β€˜name’, in the first header in this volume, then extract ICE dims in +the same way as above, for the first header in this volume, and check +whether all but ICE1[6:8] are the same as ICE2. Set flag that all +ICE dims are identical for this volume. Set this flag to True if we +did not have ICE1 or CSA information.

  2. +
  3. Match the current header to the current volume iff the following match:

    +
      +
    1. SeriesNumber

    2. +
    3. Rows

    4. +
    5. Columns

    6. +
    7. ImageOrientationPatient (to tolerance of sum squared difference 1e-4)

    8. +
    9. PixelSpacing (to tolerance of sum squared difference 1e-4)

    10. +
    11. ICE dims as defined above

    12. +
    13. ImageType (iff imagetype exists in both)

    14. +
    15. SequenceName (iff sequencename exists in both)

    16. +
    17. SeriesInstanceUID (iff exists in both)

    18. +
    19. EchoNumbers (iff exists in both)

    20. +
    +
  4. +
  5. If the current header matches the current volume, insert it there, +otherwise make a new volume for this header

  6. +
+
+
+

Second passΒΆ

+

We now have a list of volumes, where each volume is a list of headers +that may match.

+

For each volume:

+
    +
  1. Estimate the z direction cosine by (effectively) finding the cross +product of the x and y direction cosines contained in +β€˜ImageOrientationPatient’ - call this z_dir_cos

  2. +
  3. For each header in this volume, get the z coordinate by taking the +dot product of the β€˜ImagePositionPatient’ vector and z_dir_cos +(see Working out the Z coordinates for a set of slices).

  4. +
  5. Sort the headers according to this estimated z coordinate.

  6. +
  7. If this volume is more than one slice, and there are any slices with +the same z coordinate (as defined above), run the +Possible volume resort on this volume - on the basis that it may +have caught more than one volume-worth of slices. Return one or more +volume’s worth of lists.

  8. +
+
+
+

Final checkΒΆ

+

For each volume, recalculate z coordinate as above. Calculate the z +gaps. Subtract the mean of the z gaps from all z gaps. If the average of the +(gap-mean(gap)) is greater than 1e-4, then print a warning that there +are missing DICOM files.

+
+
+

Possible volume resortΒΆ

+

This step happens if there were volumes with slices having the same z +coordinate in the Second pass step above. The resort is on the +set of DICOM headers that were in the volume, for which there were +slices with identical z coordinates. We’ll call the list of headers +that the routine is still working on - work_list.

+
    +
  1. If there is no β€˜InstanceNumber’ field for the first header in +work_list, bail out.

  2. +
  3. Print a message about the β€˜AcquisitionNumber’ not changing from +volume to volume. This may be a relic from previous code, because +this version of SPM does not use the β€˜AcquisitionNumber’ field except +for making filenames.

  4. +
  5. Calculate the z coordinate as for Second pass, for each +DICOM header.

  6. +
  7. Sort the headers by β€˜InstanceNumber’

  8. +
  9. If any headers have the same β€˜InstanceNumber’, then discard all but +the first header with the same number. At this point the remaining +headers in work_list will have different β€˜InstanceNumber’s, but +may have the same z coordinate.

  10. +
  11. Now sort by z coordinate

  12. +
  13. If there are N headers, make a N length vector of flags +is_processed, for which all values == False

  14. +
  15. Make an output list of header lists, call it hdr_vol_out, set to empty.

  16. +
  17. While there are still any False elements in is_processed:

    +
      +
    1. Find first header for which corresponding is_processed is +False - call this hdr_to_check

    2. +
    3. Collect indices (in work_list) of headers which have the same +z coordinate as hdr_to_check, call this list +z_same_indices.

    4. +
    5. Sort work_list[z_same_indices] by β€˜InstanceNumber’

    6. +
    7. For each index in z_same_indices such that i indexes the +indices, and zsind is z_same_indices[i]: append header +corresponding to zsind to hdr_vol_out[i]. This assumes +that the original work_list contained two or more volumes, +each with an identical set of z coordinates.

    8. +
    9. Set corresponding is_processed flag to True for all z_same_indices.

    10. +
    +
  18. +
  19. Finally, if the headers in work_list have β€˜InstanceNumber’s that +cannot be sorted to a sequence ascending in units of 1, or if any +of the lists in hdr_vol_out have different lengths, emit a +warning about missing DICOM files.

  20. +
+
+
+
+

Writing DICOM volumesΒΆ

+

This means - writing DICOM volumes from standard (slice by slice) DICOM +datasets rather than Siemens mosaic format.

+
+

Making the affineΒΆ

+

We need the (4,4) affine \(A\) going from voxel (array) coordinates in the +DICOM pixel data, to mm coordinates in the DICOM patient coordinate system.

+

This section tries to explain how SPM achieves this, but I don’t +completely understand their method. See Getting a 3D affine from a DICOM slice or list of slices for +what I believe to be a simpler explanation.

+

First define the constants, matrices and vectors as in +DICOM affine Definitions.

+

\(N\) is the number of slices in the volume.

+

Then define the following matrices:

+
+\[ \begin{align}\begin{aligned}\begin{split}R = \left(\begin{smallmatrix}1 & a & 1 & 0\\1 & b & 0 & 1\\1 & c & 0 & 0\\1 & d & 0 & 0\end{smallmatrix}\right)\end{split}\\\begin{split}L = \left(\begin{smallmatrix}T^{1}_{{1}} & e & F_{{11}} \Delta{r} & F_{{12}} \Delta{c}\\T^{1}_{{2}} & f & F_{{21}} \Delta{r} & F_{{22}} \Delta{c}\\T^{1}_{{3}} & g & F_{{31}} \Delta{r} & F_{{32}} \Delta{c}\\1 & h & 0 & 0\end{smallmatrix}\right)\end{split}\end{aligned}\end{align} \]
+

For a volume with more than one slice (header), then \(a=1; b=1, c=N, d=1\). \(e, f, g\) are the values from \(T^N\), +and \(h == 1\).

+

For a volume with only one slice (header) \(a=0, b=0, c=1, d=0\) and \(e, +f, g, h\) are \(n_1 \Delta{s}, n_2 \Delta{s}, n_3 \Delta{s}, 0\).

+

The full transform appears to be \(A_{spm} = R L^{-1}\).

+

Now, SPM, don’t forget, is working in terms of Matlab array indexing, +which starts at (1,1,1) for a three dimensional array, whereas DICOM +expects a (0,0,0) start (see DICOM affine formula). In this +particular part of the SPM DICOM code, somewhat confusingly, the (0,0,0) +to (1,1,1) indexing is dealt with in the \(A\) transform, rather than the +analyze_to_dicom transformation used by SPM in other places. So, the +transform \(A_{spm}\) goes from (1,1,1) based voxel indices to mm. To +get the (0, 0, 0)-based transform we want, we need to pre-apply the +transform to take 0-based voxel indices to 1-based voxel indices:

+
+\[\begin{split}A = R L^{-1} \left(\begin{smallmatrix}1 & 0 & 0 & 1\\0 & 1 & 0 & 1\\0 & 0 & 1 & 1\\0 & 0 & 0 & 1\end{smallmatrix}\right)\end{split}\]
+

This formula with the definitions above result in the single and multi +slice formulae in 3D affine formulae.

+

See derivations/spm_dicom_orient.py for the derivations and +some explanations.

+
+
+

Writing the voxel dataΒΆ

+

Just apply scaling and offset from β€˜RescaleSlope’ and β€˜RescaleIntercept’ +for each slice and write volume.

+
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/genindex.html b/genindex.html new file mode 100644 index 0000000000..a84bbaa2f4 --- /dev/null +++ b/genindex.html @@ -0,0 +1,4080 @@ + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Index

+ +
+ _ + | A + | B + | C + | D + | E + | F + | G + | H + | I + | K + | L + | M + | N + | O + | P + | Q + | R + | S + | T + | U + | V + | W + | X + | Z + +
+

_

+ + +
+ +

A

+ + + +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

K

+ + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

O

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ +

W

+ + + +
+ +

X

+ + + +
+ +

Z

+ + +
+ + + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gettingstarted.html b/gettingstarted.html new file mode 100644 index 0000000000..9ed3eb383c --- /dev/null +++ b/gettingstarted.html @@ -0,0 +1,209 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Getting StartedΒΆ

+

NiBabel supports an ever growing collection of neuroimaging file formats. Every +file format format has its own features and peculiarities that need to be taken +care of to get the most out of it. To this end, NiBabel offers both high-level +format-independent access to neuroimages, as well as an API with various levels +of format-specific access to all available information in a particular file +format. The following examples show some of NiBabel’s capabilities and give +you an idea of the API.

+

For more detail on the API, see Nibabel images.

+

When loading an image, NiBabel tries to figure out the image format from the +filename. An image in a known format can easily be loaded by simply passing its +filename to the load function.

+

To start the code examples, we load some useful libraries:

+
>>> import os
+>>> import numpy as np
+
+
+

Then we fine the nibabel directory containing the example data:

+
>>> from nibabel.testing import data_path
+
+
+

There is a NIfTI file in this directory called example4d.nii.gz:

+
>>> example_filename = os.path.join(data_path, 'example4d.nii.gz')
+
+
+

Now we can import nibabel and load the image:

+
>>> import nibabel as nib
+>>> img = nib.load(example_filename)
+
+
+

A NiBabel image knows about its shape:

+
>>> img.shape
+(128, 96, 24, 2)
+
+
+

It also records the data type of the data as stored on disk. In this case the +data on disk are 16 bit signed integers:

+
>>> img.get_data_dtype() == np.dtype(np.int16)
+True
+
+
+

The image has an affine transformation that determines the world-coordinates of +the image elements (see Coordinate systems and affines):

+
>>> img.affine.shape
+(4, 4)
+
+
+

This information is available without the need to load anything of the main +image data into the memory. Of course there is also access to the image data as +a NumPy array

+
>>> data = img.get_fdata()
+>>> data.shape
+(128, 96, 24, 2)
+>>> type(data)
+<... 'numpy.ndarray'>
+
+
+

The complete information embedded in an image header is available via a +format-specific header object.

+
>>> hdr = img.header
+
+
+

In case of this NIfTI file it allows accessing all NIfTI-specific information, +e.g.

+
>>> hdr.get_xyzt_units()
+('mm', 'sec')
+
+
+

Corresponding β€œsetter” methods allow modifying a header, while ensuring its +compliance with the file format specifications.

+

In some situations we need even more flexibility and, for those with great +courage, NiBabel also offers access to the raw header information

+
>>> raw = hdr.structarr
+>>> raw['xyzt_units']
+array(10, dtype=uint8)
+
+
+

This lowest level of the API is designed for people who know the file format +well enough to work with its internal data, and comes without any safety-net.

+

Creating a new image in some file format is also easy. At a minimum it only +needs some image data and an image coordinate transformation (affine):

+
>>> import numpy as np
+>>> data = np.ones((32, 32, 15, 100), dtype=np.int16)
+>>> img = nib.Nifti1Image(data, np.eye(4))
+>>> img.get_data_dtype() == np.dtype(np.int16)
+True
+>>> img.header.get_xyzt_units()
+('unknown', 'unknown')
+
+
+

In this case, we used the identity matrix as the affine transformation. The +image header is initialized from the provided data array (i.e. shape, dtype) +and all other values are set to reasonable defaults.

+

Saving this new image to a file is trivial:

+
>>> nib.save(img, os.path.join('build', 'test4d.nii.gz'))  
+
+
+

This short introduction only gave a quick overview of NiBabel’s capabilities. +Please have a look at the API Documentation for more details about supported file +formats and their features.

+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/configure_git.html b/gitwash/configure_git.html new file mode 100644 index 0000000000..f20929e1d7 --- /dev/null +++ b/gitwash/configure_git.html @@ -0,0 +1,272 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Configure gitΒΆ

+
+

OverviewΒΆ

+

Your personal git configurations are saved in the .gitconfig file in +your home directory.

+

Here is an example .gitconfig file:

+
[user]
+        name = Your Name
+        email = you@yourdomain.example.com
+
+[alias]
+        ci = commit -a
+        co = checkout
+        st = status
+        stat = status
+        br = branch
+        wdiff = diff --color-words
+
+[core]
+        editor = vim
+
+[merge]
+        summary = true
+
+
+

You can edit this file directly or you can use the git config --global +command:

+
git config --global user.name "Your Name"
+git config --global user.email you@yourdomain.example.com
+git config --global alias.ci "commit -a"
+git config --global alias.co checkout
+git config --global alias.st "status -a"
+git config --global alias.stat "status -a"
+git config --global alias.br branch
+git config --global alias.wdiff "diff --color-words"
+git config --global core.editor vim
+git config --global merge.summary true
+
+
+

To set up on another computer, you can copy your ~/.gitconfig file, +or run the commands above.

+
+
+

In detailΒΆ

+
+

user.name and user.emailΒΆ

+

It is good practice to tell git who you are, for labeling any changes +you make to the code. The simplest way to do this is from the command +line:

+
git config --global user.name "Your Name"
+git config --global user.email you@yourdomain.example.com
+
+
+

This will write the settings into your git configuration file, which +should now contain a user section with your name and email:

+
[user]
+      name = Your Name
+      email = you@yourdomain.example.com
+
+
+

Of course you’ll need to replace Your Name and you@yourdomain.example.com +with your actual name and email address.

+
+
+

AliasesΒΆ

+

You might well benefit from some aliases to common commands.

+

For example, you might well want to be able to shorten git checkout +to git co. Or you may want to alias git diff --color-words +(which gives a nicely formatted output of the diff) to git wdiff

+

The following git config --global commands:

+
git config --global alias.ci "commit -a"
+git config --global alias.co checkout
+git config --global alias.st "status -a"
+git config --global alias.stat "status -a"
+git config --global alias.br branch
+git config --global alias.wdiff "diff --color-words"
+
+
+

will create an alias section in your .gitconfig file with contents +like this:

+
[alias]
+        ci = commit -a
+        co = checkout
+        st = status -a
+        stat = status -a
+        br = branch
+        wdiff = diff --color-words
+
+
+
+
+

EditorΒΆ

+

You may also want to make sure that your editor of choice is used

+
git config --global core.editor vim
+
+
+
+
+

MergingΒΆ

+

To enforce summaries when doing merges (~/.gitconfig file again):

+
[merge]
+   log = true
+
+
+

Or from the command line:

+
git config --global merge.log true
+
+
+
+
+

Fancy log outputΒΆ

+

This is a very nice alias to get a fancy log output; it should go in the +alias section of your .gitconfig file:

+
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)[%an]%Creset' --abbrev-commit --date=relative
+
+
+

You use the alias with:

+
git lg
+
+
+

and it gives graph / text output something like this (but with color!):

+
* 6d8e1ee - (HEAD, origin/my-fancy-feature, my-fancy-feature) NF - a fancy file (45 minutes ago) [Matthew Brett]
+*   d304a73 - (origin/placeholder, placeholder) Merge pull request #48 from hhuuggoo/master (2 weeks ago) [Jonathan Terhorst]
+|\
+| * 4aff2a8 - fixed bug 35, and added a test in test_bugfixes (2 weeks ago) [Hugo]
+|/
+* a7ff2e5 - Added notes on discussion/proposal made during Data Array Summit. (2 weeks ago) [Corran Webster]
+* 68f6752 - Initial implementation of AxisIndexer - uses 'index_by' which needs to be changed to a call on an Axes object - this is all very sketchy right now. (2 weeks ago) [Corr
+*   376adbd - Merge pull request #46 from terhorst/master (2 weeks ago) [Jonathan Terhorst]
+|\
+| * b605216 - updated joshu example to current api (3 weeks ago) [Jonathan Terhorst]
+| * 2e991e8 - add testing for outer ufunc (3 weeks ago) [Jonathan Terhorst]
+| * 7beda5a - prevent axis from throwing an exception if testing equality with non-axis object (3 weeks ago) [Jonathan Terhorst]
+| * 65af65e - convert unit testing code to assertions (3 weeks ago) [Jonathan Terhorst]
+| *   956fbab - Merge remote-tracking branch 'upstream/master' (3 weeks ago) [Jonathan Terhorst]
+| |\
+| |/
+
+
+

Thanks to Yury V. Zaytsev for posting it.

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/development_workflow.html b/gitwash/development_workflow.html new file mode 100644 index 0000000000..d767f09d1f --- /dev/null +++ b/gitwash/development_workflow.html @@ -0,0 +1,506 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Development workflowΒΆ

+

You already have your own forked copy of the nibabel repository, by +following Making your own copy (fork) of nibabel. You have Set up your fork. You have configured +git by following Configure git. Now you are ready for some real work.

+
+

Workflow summaryΒΆ

+

In what follows we’ll refer to the upstream nibabel master branch, as +β€œtrunk”.

+
    +
  • Don’t use your master branch for anything. Consider deleting it.

  • +
  • When you are starting a new set of changes, fetch any changes from trunk, +and start a new feature branch from that.

  • +
  • Make a new branch for each separable set of changes β€” β€œone task, one +branch” (ipython git workflow).

  • +
  • Name your branch for the purpose of the changes - e.g. +bugfix-for-issue-14 or refactor-database-code.

  • +
  • If you can possibly avoid it, avoid merging trunk or any other branches into +your feature branch while you are working.

  • +
  • If you do find yourself merging from trunk, consider Rebasing on trunk

  • +
  • Ask on the nibabel mailing list if you get stuck.

  • +
  • Ask for code review!

  • +
+

This way of working helps to keep work well organized, with readable history. +This in turn makes it easier for project maintainers (that might be you) to see +what you’ve done, and why you did it.

+

See linux git workflow and ipython git workflow for some explanation.

+
+
+

Consider deleting your master branchΒΆ

+

It may sound strange, but deleting your own master branch can help reduce +confusion about which branch you are on. See deleting master on github for +details.

+
+
+

Update the mirror of trunkΒΆ

+

First make sure you have done Linking your repository to the upstream repo.

+

From time to time you should fetch the upstream (trunk) changes from github:

+
git fetch upstream
+
+
+

This will pull down any commits you don’t have, and set the remote branches to +point to the right commit. For example, β€˜trunk’ is the branch referred to by +(remote/branchname) upstream/master - and if there have been commits since +you last checked, upstream/master will change after you do the fetch.

+
+
+

Make a new feature branchΒΆ

+

When you are ready to make some changes to the code, you should start a new +branch. Branches that are for a collection of related edits are often called +β€˜feature branches’.

+

Making an new branch for each set of related changes will make it easier for +someone reviewing your branch to see what you are doing.

+

Choose an informative name for the branch to remind yourself and the rest of us +what the changes in the branch are for. For example add-ability-to-fly, or +buxfix-for-issue-42.

+
# Update the mirror of trunk
+git fetch upstream
+# Make new feature branch starting at current trunk
+git branch my-new-feature upstream/master
+git checkout my-new-feature
+
+
+

Generally, you will want to keep your feature branches on your public github +fork of nibabel. To do this, you git push this new branch up to your +github repo. Generally (if you followed the instructions in these pages, and by +default), git will have a link to your github repo, called origin. You push +up to your own repo on github with:

+
git push origin my-new-feature
+
+
+

In git >= 1.7 you can ensure that the link is correctly set by using the +--set-upstream option:

+
git push --set-upstream origin my-new-feature
+
+
+

From now on git will know that my-new-feature is related to the +my-new-feature branch in the github repo.

+
+
+

The editing workflowΒΆ

+
+

OverviewΒΆ

+
# hack hack
+git add my_new_file
+git commit -am 'NF - some message'
+git push
+
+
+
+
+

In more detailΒΆ

+
    +
  1. Make some changes

  2. +
  3. See which files have changed with git status (see git status). +You’ll see a listing like this one:

    +
    # On branch ny-new-feature
    +# Changed but not updated:
    +#   (use "git add <file>..." to update what will be committed)
    +#   (use "git checkout -- <file>..." to discard changes in working directory)
    +#
    +#  modified:   README
    +#
    +# Untracked files:
    +#   (use "git add <file>..." to include in what will be committed)
    +#
    +#  INSTALL
    +no changes added to commit (use "git add" and/or "git commit -a")
    +
    +
    +
  4. +
  5. Check what the actual changes are with git diff (git diff).

  6. +
  7. Add any new files to version control git add new_file_name (see +git add).

  8. +
  9. To commit all modified files into the local copy of your repo,, do +git commit -am 'A commit message'. Note the -am options to +commit. The m flag just signals that you’re going to type a +message on the command line. The a flag β€” you can just take on +faith β€” or see why the -a flag? β€” and the helpful use-case +description in the tangled working copy problem. The git commit manual +page might also be useful.

  10. +
  11. To push the changes up to your forked repo on github, do a git +push (see git push).

  12. +
+
+
+
+

Ask for your changes to be reviewed or mergedΒΆ

+

When you are ready to ask for someone to review your code and consider a merge:

+
    +
  1. Go to the URL of your forked repo, say +https://github.com/your-user-name/nibabel.

  2. +
  3. Use the β€˜Switch Branches’ dropdown menu near the top left of the page to +select the branch with your changes:

    +../_images/branch_dropdown.png +
  4. +
  5. Click on the β€˜Pull request’ button:

    +../_images/pull_button.png +

    Enter a title for the set of changes, and some explanation of what you’ve +done. Say if there is anything you’d like particular attention for - like a +complicated change or some code you are not happy with.

    +

    If you don’t think your request is ready to be merged, just say so in your +pull request message. This is still a good way of getting some preliminary +code review.

    +
  6. +
+
+
+

Some other things you might want to doΒΆ

+
+

Delete a branch on githubΒΆ

+
git checkout master
+# delete branch locally
+git branch -D my-unwanted-branch
+# delete branch on github
+git push origin :my-unwanted-branch
+
+
+

(Note the colon : before test-branch. See also: +https://github.com/guides/remove-a-remote-branch

+
+
+

Several people sharing a single repositoryΒΆ

+

If you want to work on some stuff with other people, where you are all +committing into the same repository, or even the same branch, then just +share it via github.

+

First fork nibabel into your account, as from Making your own copy (fork) of nibabel.

+

Then, go to your forked repository github page, say +https://github.com/your-user-name/nibabel

+

Click on the β€˜Admin’ button, and add anyone else to the repo as a +collaborator:

+
+
../_images/pull_button.png +
+

Now all those people can do:

+
git clone git@githhub.com:your-user-name/nibabel.git
+
+
+

Remember that links starting with git@ use the ssh protocol and are +read-write; links starting with git:// are read-only.

+

Your collaborators can then commit directly into that repo with the +usual:

+
git commit -am 'ENH - much better code'
+git push origin master # pushes directly into your repo
+
+
+
+
+

Explore your repositoryΒΆ

+

To see a graphical representation of the repository branches and +commits:

+
gitk --all
+
+
+

To see a linear list of commits for this branch:

+
git log
+
+
+

You can also look at the network graph visualizer for your github +repo.

+

Finally the Fancy log output lg alias will give you a reasonable text-based +graph of the repository.

+
+
+

Rebasing on trunkΒΆ

+

Let’s say you thought of some work you’d like to do. You +Update the mirror of trunk and Make a new feature branch called +cool-feature. At this stage trunk is at some commit, let’s call it E. Now +you make some new commits on your cool-feature branch, let’s call them A, B, +C. Maybe your changes take a while, or you come back to them after a while. In +the meantime, trunk has progressed from commit E to commit (say) G:

+
      A---B---C cool-feature
+     /
+D---E---F---G trunk
+
+
+

At this stage you consider merging trunk into your feature branch, and you +remember that this here page sternly advises you not to do that, because the +history will get messy. Most of the time you can just ask for a review, and not +worry that trunk has got a little ahead. But sometimes, the changes in trunk +might affect your changes, and you need to harmonize them. In this situation +you may prefer to do a rebase.

+

rebase takes your changes (A, B, C) and replays them as if they had been made to +the current state of trunk. In other words, in this case, it takes the +changes represented by A, B, C and replays them on top of G. After the rebase, +your history will look like this:

+
              A'--B'--C' cool-feature
+             /
+D---E---F---G trunk
+
+
+

See rebase without tears for more detail.

+

To do a rebase on trunk:

+
# Update the mirror of trunk
+git fetch upstream
+# go to the feature branch
+git checkout cool-feature
+# make a backup in case you mess up
+git branch tmp cool-feature
+# rebase cool-feature onto trunk
+git rebase --onto upstream/master upstream/master cool-feature
+
+
+

In this situation, where you are already on branch cool-feature, the last +command can be written more succinctly as:

+
git rebase upstream/master
+
+
+

When all looks good you can delete your backup branch:

+
git branch -D tmp
+
+
+

If it doesn’t look good you may need to have a look at +Recovering from mess-ups.

+

If you have made changes to files that have also changed in trunk, this may +generate merge conflicts that you need to resolve - see the git rebase man +page for some instructions at the end of the β€œDescription” section. There is +some related help on merging in the git user manual - see resolving a merge.

+
+
+

Recovering from mess-upsΒΆ

+

Sometimes, you mess up merges or rebases. Luckily, in git it is +relatively straightforward to recover from such mistakes.

+

If you mess up during a rebase:

+
git rebase --abort
+
+
+

If you notice you messed up after the rebase:

+
# reset branch back to the saved point
+git reset --hard tmp
+
+
+

If you forgot to make a backup branch:

+
# look at the reflog of the branch
+git reflog show cool-feature
+
+8630830 cool-feature@{0}: commit: BUG: io: close file handles immediately
+278dd2a cool-feature@{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d
+26aa21a cool-feature@{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj
+...
+
+# reset the branch to where it was before the botched rebase
+git reset --hard cool-feature@{2}
+
+
+
+
+

Rewriting commit historyΒΆ

+
+

Note

+

Do this only for your own feature branches.

+
+

There’s an embarrassing typo in a commit you made? Or perhaps the you +made several false starts you would like the posterity not to see.

+

This can be done via interactive rebasing.

+

Suppose that the commit history looks like this:

+
git log --oneline
+eadc391 Fix some remaining bugs
+a815645 Modify it so that it works
+2dec1ac Fix a few bugs + disable
+13d7934 First implementation
+6ad92e5 * masked is now an instance of a new object, MaskedConstant
+29001ed Add pre-nep for a copule of structured_array_extensions.
+...
+
+
+

and 6ad92e5 is the last commit in the cool-feature branch. Suppose we +want to make the following changes:

+
    +
  • Rewrite the commit message for 13d7934 to something more sensible.

  • +
  • Combine the commits 2dec1ac, a815645, eadc391 into a single one.

  • +
+

We do as follows:

+
# make a backup of the current state
+git branch tmp HEAD
+# interactive rebase
+git rebase -i 6ad92e5
+
+
+

This will open an editor with the following text in it:

+
pick 13d7934 First implementation
+pick 2dec1ac Fix a few bugs + disable
+pick a815645 Modify it so that it works
+pick eadc391 Fix some remaining bugs
+
+# Rebase 6ad92e5..eadc391 onto 6ad92e5
+#
+# Commands:
+#  p, pick = use commit
+#  r, reword = use commit, but edit the commit message
+#  e, edit = use commit, but stop for amending
+#  s, squash = use commit, but meld into previous commit
+#  f, fixup = like "squash", but discard this commit's log message
+#
+# If you remove a line here THAT COMMIT WILL BE LOST.
+# However, if you remove everything, the rebase will be aborted.
+#
+
+
+

To achieve what we want, we will make the following changes to it:

+
r 13d7934 First implementation
+pick 2dec1ac Fix a few bugs + disable
+f a815645 Modify it so that it works
+f eadc391 Fix some remaining bugs
+
+
+

This means that (i) we want to edit the commit message for +13d7934, and (ii) collapse the last three commits into one. Now we +save and quit the editor.

+

Git will then immediately bring up an editor for editing the commit +message. After revising it, we get the output:

+
[detached HEAD 721fc64] FOO: First implementation
+ 2 files changed, 199 insertions(+), 66 deletions(-)
+[detached HEAD 0f22701] Fix a few bugs + disable
+ 1 files changed, 79 insertions(+), 61 deletions(-)
+Successfully rebased and updated refs/heads/my-feature-branch.
+
+
+

and the history looks now like this:

+
0f22701 Fix a few bugs + disable
+721fc64 ENH: Sophisticated feature
+6ad92e5 * masked is now an instance of a new object, MaskedConstant
+
+
+

If it went wrong, recovery is again possible as explained above.

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/following_latest.html b/gitwash/following_latest.html new file mode 100644 index 0000000000..9355c52616 --- /dev/null +++ b/gitwash/following_latest.html @@ -0,0 +1,149 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Following the latest sourceΒΆ

+

These are the instructions if you just want to follow the latest +nibabel source, but you don’t need to do any development for now.

+

The steps are:

+
    +
  • Install git

  • +
  • get local copy of the git repository from github

  • +
  • update local copy from time to time

  • +
+
+

Get the local copy of the codeΒΆ

+

From the command line:

+
git clone git://github.com/nipy/nibabel.git
+
+
+

You now have a copy of the code tree in the new nibabel directory.

+
+
+

Updating the codeΒΆ

+

From time to time you may want to pull down the latest code. Do this with:

+
cd nibabel
+git pull
+
+
+

The tree in nibabel will now have the latest changes from the initial +repository.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/forking_hell.html b/gitwash/forking_hell.html new file mode 100644 index 0000000000..282039b462 --- /dev/null +++ b/gitwash/forking_hell.html @@ -0,0 +1,146 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Making your own copy (fork) of nibabelΒΆ

+

You need to do this only once. The instructions here are very similar +to the instructions at https://help.github.com/articles/fork-a-repo/ β€” +please see that page for more detail. We’re repeating some of it here just to +give the specifics for the nibabel project, and to suggest some default names.

+
+

Set up and configure a github accountΒΆ

+

If you don’t have a github account, go to the github page, and make one.

+

You then need to configure your account to allow write access β€” see +the Generating SSH keys help on github help.

+
+
+

Create your own forked copy of nibabelΒΆ

+
    +
  1. Log into your github account.

  2. +
  3. Go to the nibabel github home at nibabel github.

  4. +
  5. Click on the fork button:

    +../_images/forking_button.png +

    Now, after a short pause and some β€˜Hardcore forking action’, you +should find yourself at the home page for your own forked copy of nibabel.

    +
  6. +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/git_development.html b/gitwash/git_development.html new file mode 100644 index 0000000000..12713efb5e --- /dev/null +++ b/gitwash/git_development.html @@ -0,0 +1,146 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

+
+
+ + + + + + + + \ No newline at end of file diff --git a/gitwash/git_install.html b/gitwash/git_install.html new file mode 100644 index 0000000000..454c6d4b21 --- /dev/null +++ b/gitwash/git_install.html @@ -0,0 +1,148 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Install gitΒΆ

+
+

OverviewΒΆ

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

Debian / Ubuntu

sudo apt-get install git-core

Fedora

sudo yum install git-core

Windows

Download and install msysGit

OS X

Use the git-osx-installer

+
+
+

In detailΒΆ

+

See the git page for the most recent information.

+

Have a look at the github install help pages available from github help

+

There are good instructions here: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/git_intro.html b/gitwash/git_intro.html new file mode 100644 index 0000000000..cc79dccaa2 --- /dev/null +++ b/gitwash/git_intro.html @@ -0,0 +1,121 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

IntroductionΒΆ

+

These pages describe a git and github workflow for the nibabel +project.

+

There are several different workflows here, for different ways of +working with nibabel.

+

This is not a comprehensive git reference, it’s just a workflow for our +own project. It’s tailored to the github hosting service. You may well +find better or quicker ways of getting stuff done with git, but these +should get you started.

+

For general resources for learning git, see git resources.

+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/git_resources.html b/gitwash/git_resources.html new file mode 100644 index 0000000000..409b019d24 --- /dev/null +++ b/gitwash/git_resources.html @@ -0,0 +1,177 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

git resourcesΒΆ

+
+

Tutorials and summariesΒΆ

+ +
+
+

Advanced git workflowΒΆ

+

There are many ways of working with git; here are some posts on the +rules of thumb that other projects have come up with:

+
    +
  • Linus Torvalds on git management

  • +
  • Linus Torvalds on linux git workflow . Summary; use the git tools +to make the history of your edits as clean as possible; merge from +upstream edits as little as possible in branches where you are doing +active development.

  • +
+
+
+

Manual pages onlineΒΆ

+

You can get these on your own machine with (e.g) git help push or +(same thing) git push --help, but, for convenience, here are the +online manual pages for some common commands:

+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/index.html b/gitwash/index.html new file mode 100644 index 0000000000..0b3412f703 --- /dev/null +++ b/gitwash/index.html @@ -0,0 +1,146 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

+
+
+ + + + + + + + \ No newline at end of file diff --git a/gitwash/maintainer_workflow.html b/gitwash/maintainer_workflow.html new file mode 100644 index 0000000000..c245ddf181 --- /dev/null +++ b/gitwash/maintainer_workflow.html @@ -0,0 +1,206 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Maintainer workflowΒΆ

+

This page is for maintainers β€” those of us who merge our own or other +peoples’ changes into the upstream repository.

+

Being as how you’re a maintainer, you are completely on top of the basic stuff +in Development workflow.

+

The instructions in Linking your repository to the upstream repo add a remote that has read-only +access to the upstream repo. Being a maintainer, you’ve got read-write access.

+

It’s good to have your upstream remote have a scary name, to remind you that +it’s a read-write remote:

+
git remote add upstream-rw git@github.com:nipy/nibabel.git
+git fetch upstream-rw
+
+
+
+

Integrating changesΒΆ

+

Let’s say you have some changes that need to go into trunk +(upstream-rw/master).

+

The changes are in some branch that you are currently on. For example, you are +looking at someone’s changes like this:

+
git remote add someone git://github.com/someone/nibabel.git
+git fetch someone
+git branch cool-feature --track someone/cool-feature
+git checkout cool-feature
+
+
+

So now you are on the branch with the changes to be incorporated upstream. The +rest of this section assumes you are on this branch.

+
+

A few commitsΒΆ

+

If there are only a few commits, consider rebasing to upstream:

+
# Fetch upstream changes
+git fetch upstream-rw
+# rebase
+git rebase upstream-rw/master
+
+
+

Remember that, if you do a rebase, and push that, you’ll have to close any +github pull requests manually, because github will not be able to detect the +changes have already been merged.

+
+
+

A long series of commitsΒΆ

+

If there are a longer series of related commits, consider a merge instead:

+
git fetch upstream-rw
+git merge --no-ff upstream-rw/master
+
+
+

The merge will be detected by github, and should close any related pull requests +automatically.

+

Note the --no-ff above. This forces git to make a merge commit, rather than +doing a fast-forward, so that these set of commits branch off trunk then rejoin +the main history with a merge, rather than appearing to have been made directly +on top of trunk.

+
+
+

Check the historyΒΆ

+

Now, in either case, you should check that the history is sensible and you have +the right commits:

+
git log --oneline --graph
+git log -p upstream-rw/master..
+
+
+

The first line above just shows the history in a compact way, with a text +representation of the history graph. The second line shows the log of commits +excluding those that can be reached from trunk (upstream-rw/master), and +including those that can be reached from current HEAD (implied with the .. +at the end). So, it shows the commits unique to this branch compared to trunk. +The -p option shows the diff for these commits in patch form.

+
+
+

Push to trunkΒΆ

+
git push upstream-rw my-new-feature:master
+
+
+

This pushes the my-new-feature branch in this repository to the master +branch in the upstream-rw repository.

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/patching.html b/gitwash/patching.html new file mode 100644 index 0000000000..192b783c13 --- /dev/null +++ b/gitwash/patching.html @@ -0,0 +1,252 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Making a patchΒΆ

+

You’ve discovered a bug or something else you want to change +in nibabel .. β€” excellent!

+

You’ve worked out a way to fix it β€” even better!

+

You want to tell us about it β€” best of all!

+

The easiest way is to make a patch or set of patches. Here +we explain how. Making a patch is the simplest and quickest, +but if you’re going to be doing anything more than simple +quick things, please consider following the +Git for development model instead.

+
+

Making patchesΒΆ

+
+

OverviewΒΆ

+
# tell git who you are
+git config --global user.email you@yourdomain.example.com
+git config --global user.name "Your Name Comes Here"
+# get the repository if you don't have it
+git clone git://github.com/nipy/nibabel.git
+# make a branch for your patching
+cd nibabel
+git branch the-fix-im-thinking-of
+git checkout the-fix-im-thinking-of
+# hack, hack, hack
+# Tell git about any new files you've made
+git add somewhere/tests/test_my_bug.py
+# commit work in progress as you go
+git commit -am 'BF - added tests for Funny bug'
+# hack hack, hack
+git commit -am 'BF - added fix for Funny bug'
+# make the patch files
+git format-patch -M -C master
+
+
+

Then, send the generated patch files to the nibabel +mailing list β€” where we will thank you warmly.

+
+
+

In detailΒΆ

+
    +
  1. Tell git who you are so it can label the commits you’ve +made:

    +
    git config --global user.email you@yourdomain.example.com
    +git config --global user.name "Your Name Comes Here"
    +
    +
    +
  2. +
  3. If you don’t already have one, clone a copy of the +nibabel repository:

    +
    git clone git://github.com/nipy/nibabel.git
    +cd nibabel
    +
    +
    +
  4. +
  5. Make a β€˜feature branch’. This will be where you work on +your bug fix. It’s nice and safe and leaves you with +access to an unmodified copy of the code in the main +branch:

    +
    git branch the-fix-im-thinking-of
    +git checkout the-fix-im-thinking-of
    +
    +
    +
  6. +
  7. Do some edits, and commit them as you go:

    +
    # hack, hack, hack
    +# Tell git about any new files you've made
    +git add somewhere/tests/test_my_bug.py
    +# commit work in progress as you go
    +git commit -am 'BF - added tests for Funny bug'
    +# hack hack, hack
    +git commit -am 'BF - added fix for Funny bug'
    +
    +
    +

    Note the -am options to commit. The m flag just +signals that you’re going to type a message on the command +line. The a flag β€” you can just take on faith β€” +or see why the -a flag?.

    +
  8. +
  9. When you have finished, check you have committed all your +changes:

    +
    git status
    +
    +
    +
  10. +
  11. Finally, make your commits into patches. You want all the +commits since you branched from the master branch:

    +
    git format-patch -M -C master
    +
    +
    +

    You will now have several files named for the commits:

    +
    0001-BF-added-tests-for-Funny-bug.patch
    +0002-BF-added-fix-for-Funny-bug.patch
    +
    +
    +

    Send these files to the nibabel mailing list.

    +
  12. +
+

When you are done, to switch back to the main copy of the +code, just return to the master branch:

+
git checkout master
+
+
+
+
+
+

Moving from patching to developmentΒΆ

+

If you find you have done some patches, and you have one or +more feature branches, you will probably want to switch to +development mode. You can do this with the repository you +have.

+

Fork the nibabel repository on github β€” Making your own copy (fork) of nibabel. +Then:

+
# checkout and refresh master branch from main repo
+git checkout master
+git pull origin master
+# rename pointer to main repository to 'upstream'
+git remote rename origin upstream
+# point your repo to default read / write to your fork on github
+git remote add origin git@github.com:your-user-name/nibabel.git
+# push up any branches you've made and want to keep
+git push origin the-fix-im-thinking-of
+
+
+

Then you can, if you want, follow the +Development workflow.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gitwash/set_up_fork.html b/gitwash/set_up_fork.html new file mode 100644 index 0000000000..2d9d09662b --- /dev/null +++ b/gitwash/set_up_fork.html @@ -0,0 +1,182 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Set up your forkΒΆ

+

First you follow the instructions for Making your own copy (fork) of nibabel.

+
+

OverviewΒΆ

+
git clone git@github.com:your-user-name/nibabel.git
+cd nibabel
+git remote add upstream git://github.com/nipy/nibabel.git
+
+
+
+
+

In detailΒΆ

+
+

Clone your forkΒΆ

+
    +
  1. Clone your fork to the local computer with git clone +git@github.com:your-user-name/nibabel.git

  2. +
  3. Investigate. Change directory to your new repo: cd nibabel. Then +git branch -a to show you all branches. You’ll get something +like:

    +
    * master
    +remotes/origin/master
    +
    +
    +

    This tells you that you are currently on the master branch, and +that you also have a remote connection to origin/master. +What remote repository is remote/origin? Try git remote -v to +see the URLs for the remote. They will point to your github fork.

    +

    Now you want to connect to the upstream nibabel github repository, so +you can merge in changes from trunk.

    +
  4. +
+
+
+

Linking your repository to the upstream repoΒΆ

+
cd nibabel
+git remote add upstream git://github.com/nipy/nibabel.git
+
+
+

upstream here is just the arbitrary name we’re using to refer to the +main nibabel repository at nibabel github.

+

Note that we’ve used git:// for the URL rather than git@. The +git:// URL is read only. This means we that we can’t accidentally +(or deliberately) write to the upstream repo, and we are only going to +use it to merge into our own code.

+

Just for your own satisfaction, show yourself that you now have a new +β€˜remote’, with git remote -v show, giving you something like:

+
upstream     git://github.com/nipy/nibabel.git (fetch)
+upstream     git://github.com/nipy/nibabel.git (push)
+origin       git@github.com:your-user-name/nibabel.git (fetch)
+origin       git@github.com:your-user-name/nibabel.git (push)
+
+
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/image_orientation.html b/image_orientation.html new file mode 100644 index 0000000000..f51b4d0395 --- /dev/null +++ b/image_orientation.html @@ -0,0 +1,188 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Image voxel orientationΒΆ

+

It is sometimes useful to know the approximate world-space orientations of the +image voxel axes.

+

See Coordinate systems and affines for background on voxel and world axes.

+

For example, let’s say we had an image with an identity affine:

+
>>> import numpy as np
+>>> import nibabel as nib
+>>> affine = np.eye(4)  # identity affine
+>>> voxel_data = np.random.normal(size=(10, 11, 12))
+>>> img = nib.Nifti1Image(voxel_data, affine)
+
+
+

Because the affine is an identity affine, the voxel axes align with the world +axes. By convention, nibabel world axes are always in RAS+ orientation (left +to Right, posterior to Anterior, inferior to Superior).

+

Let’s say we took a single line of voxels along the first voxel axis:

+
>>> single_line_axis_0 = voxel_data[:, 0, 0]
+
+
+

The first voxel axis is aligned to the left to Right world axes. This means +that the first voxel is towards the left of the world, and the last voxel is +towards the right of the world.

+

Here is a single line in the second axis:

+
>>> single_line_axis_1 = voxel_data[0, :, 0]
+
+
+

The first voxel in this line is towards the posterior of the world, and the +last towards the anterior.

+
>>> single_line_axis_2 = voxel_data[0, 0, :]
+
+
+

The first voxel in this line is towards the inferior of the world, and the +last towards the superior.

+

This image therefore has RAS+ voxel axes.

+

In other cases, it is not so obvious what the orientations of the axes are. +For example, here is our example NIfTI 1 file again:

+
>>> import os
+>>> from nibabel.testing import data_path
+>>> example_file = os.path.join(data_path, 'example4d.nii.gz')
+>>> img = nib.load(example_file)
+
+
+

Here is the affine (to two digits decimal precision):

+
>>> np.set_printoptions(precision=2, suppress=True)
+>>> img.affine
+array([[ -2.  ,   0.  ,   0.  , 117.86],
+       [ -0.  ,   1.97,  -0.36, -35.72],
+       [  0.  ,   0.32,   2.17,  -7.25],
+       [  0.  ,   0.  ,   0.  ,   1.  ]])
+
+
+

What are the orientations of the voxel axes here?

+

Nibabel has a routine to tell you, called aff2axcodes.

+
>>> nib.aff2axcodes(img.affine)
+('L', 'A', 'S')
+
+
+

The voxel orientations are nearest to:

+
    +
  1. First voxel axis goes from right to Left;

  2. +
  3. Second voxel axis goes from posterior to Anterior;

  4. +
  5. Third voxel axis goes from inferior to Superior.

  6. +
+

Sometimes you may want to rearrange the image voxel axes to make them as close +as possible to RAS+ orientation. We refer to this voxel orientation as +canonical voxel orientation, because RAS+ is our canonical world +orientation. Rearranging the voxel axes means reversing and / or reordering +the voxel axes.

+

You can do the arrangement with as_closest_canonical:

+
>>> canonical_img = nib.as_closest_canonical(img)
+>>> canonical_img.affine
+array([[   2.  ,    0.  ,    0.  , -136.14],
+       [   0.  ,    1.97,   -0.36,  -35.72],
+       [  -0.  ,    0.32,    2.17,   -7.25],
+       [   0.  ,    0.  ,    0.  ,    1.  ]])
+>>> nib.aff2axcodes(canonical_img.affine)
+('R', 'A', 'S')
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/images_and_memory.html b/images_and_memory.html new file mode 100644 index 0000000000..0ef8b342e1 --- /dev/null +++ b/images_and_memory.html @@ -0,0 +1,333 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Images and memoryΒΆ

+

We saw in Nibabel images that images loaded from disk are usually +proxy images. Proxy images are images that have a dataobj property that +is not a numpy array, but an array proxy that can fetch the array data from +disk.

+
>>> import os
+>>> import numpy as np
+>>> from nibabel.testing import data_path
+>>> example_file = os.path.join(data_path, 'example4d.nii.gz')
+
+
+
>>> import nibabel as nib
+>>> img = nib.load(example_file)
+>>> img.dataobj
+<nibabel.arrayproxy.ArrayProxy object at ...>
+
+
+

Nibabel does not load the image array from the proxy when you load the +image. It waits until you ask for the array data. The standard way to ask +for the array data is to call the get_fdata() method:

+
>>> data = img.get_fdata()
+>>> data.shape
+(128, 96, 24, 2)
+
+
+

We also saw in Proxies and caching that this call to get_fdata() will +(by default) load the array data into an internal image cache. The image +returns the cached copy on the next call to get_fdata():

+
>>> data_again = img.get_fdata()
+>>> data is data_again
+True
+
+
+

This behavior is convenient if you want quick and repeated access to the image +array data. The down-side is that the image keeps a reference to the image +data array, so the array can’t be cleared from memory until the image object +gets deleted. You might prefer to keep loading the array from disk instead of +keeping the cached copy in the image.

+

This page describes ways of using the image array proxies to save memory and +time.

+
+

Using in_memory to check the state of the cacheΒΆ

+

You can use the in_memory property to check if the image has cached the +array.

+

The in_memory property is always True for array images, because the image +data is always an array in memory:

+
>>> array_data = np.arange(24, dtype=np.int16).reshape((2, 3, 4))
+>>> affine = np.diag([1, 2, 3, 1])
+>>> array_img = nib.Nifti1Image(array_data, affine)
+>>> array_img.in_memory
+True
+
+
+

For a proxy image, the in_memory property is False when the array is not +in cache, and True when it is in cache:

+
>>> img = nib.load(example_file)
+>>> img.in_memory
+False
+>>> data = img.get_fdata()
+>>> img.in_memory
+True
+
+
+
+
+

Using uncacheΒΆ

+

As y’all know, the proxy image has the array in cache, get_fdata() returns +the cached array:

+
>>> data_again = img.get_fdata()
+>>> data_again is data  # same array returned from cache
+True
+
+
+

You can uncache a proxy image with the uncache() method:

+
>>> img.uncache()
+>>> img.in_memory
+False
+>>> data_once_more = img.get_fdata()
+>>> data_once_more is data  # a new copy read from disk
+False
+
+
+

uncache() has no effect if the image is an array image, or if the cache is +already empty.

+

You need to be careful when you modify arrays returned by get_fdata() on +proxy images, because uncache will then change the result you get back +from get_fdata():

+
>>> proxy_img = nib.load(example_file)
+>>> data = proxy_img.get_fdata()  # array cached and returned
+>>> data[0, 0, 0, 0]
+0.0
+>>> data[0, 0, 0, 0] = 99  # modify returned array
+>>> data_again = proxy_img.get_fdata()  # return cached array
+>>> data_again[0, 0, 0, 0]  # cached array modified
+99.0
+
+
+

So far the proxy image behaves the same as an array image. uncache() has +no effect on an array image, but it does have an effect on the returned array +of a proxy image:

+
>>> proxy_img.uncache()  # cached array discarded from proxy image
+>>> data_once_more = proxy_img.get_fdata()  # new copy of array loaded
+>>> data_once_more[0, 0, 0, 0]  # array modifications discarded
+0.0
+
+
+
+
+

Saving memoryΒΆ

+
+

Uncache the arrayΒΆ

+

If you do not want the image to keep the array in its internal cache, you can +use the uncache() method:

+
>>> img.uncache()
+
+
+
+
+

Use the array proxy instead of get_fdata()ΒΆ

+

The dataobj property of a proxy image is an array proxy. We can ask the +proxy to return the array directly by passing dataobj to the numpy +asarray function:

+
>>> proxy_img = nib.load(example_file)
+>>> data_array = np.asarray(proxy_img.dataobj)
+>>> type(data_array)
+<... 'numpy.ndarray'>
+
+
+

This also works for array images, because np.asarray returns the array:

+
>>> array_img = nib.Nifti1Image(array_data, affine)
+>>> data_array = np.asarray(array_img.dataobj)
+>>> type(data_array)
+<... 'numpy.ndarray'>
+
+
+

If you want to avoid caching you can avoid get_fdata() and always use +np.asarray(img.dataobj).

+
+
+

Use the caching keyword to get_fdata()ΒΆ

+

The default behavior of the get_fdata() function is to always fill the +cache, if it is empty. This corresponds to the default 'fill' value +to the caching keyword. So, this:

+
>>> proxy_img = nib.load(example_file)
+>>> data = proxy_img.get_fdata()  # default caching='fill'
+>>> proxy_img.in_memory
+True
+
+
+

is the same as this:

+
>>> proxy_img = nib.load(example_file)
+>>> data = proxy_img.get_fdata(caching='fill')
+>>> proxy_img.in_memory
+True
+
+
+

Sometimes you may want to avoid filling the cache, if it is empty. In this +case, you can use caching='unchanged':

+
>>> proxy_img = nib.load(example_file)
+>>> data = proxy_img.get_fdata(caching='unchanged')
+>>> proxy_img.in_memory
+False
+
+
+

caching='unchanged' will leave the cache full if it is already full.

+
>>> data = proxy_img.get_fdata(caching='fill')
+>>> proxy_img.in_memory
+True
+>>> data = proxy_img.get_fdata(caching='unchanged')
+>>> proxy_img.in_memory
+True
+
+
+

See the get_fdata() docstring for more detail.

+
+
+
+

Saving time and memoryΒΆ

+

You can use the array proxy to get slices of data from disk in an efficient +way.

+

The array proxy API allows you to do slicing on the proxy. In most cases this +will mean that you only load the data from disk that you actually need, often +saving both time and memory.

+

For example, let us say you only wanted the second volume from the example +dataset. You could do this:

+
>>> proxy_img = nib.load(example_file)
+>>> data = proxy_img.get_fdata()
+>>> data.shape
+(128, 96, 24, 2)
+>>> vol1 = data[..., 1]
+>>> vol1.shape
+(128, 96, 24)
+
+
+

The problem is that you had to load the whole data array into memory before +throwing away the first volume and keeping the second.

+

You can use array proxy slicing to do this more efficiently:

+
>>> proxy_img = nib.load(example_file)
+>>> vol1 = proxy_img.dataobj[..., 1]
+>>> vol1.shape
+(128, 96, 24)
+
+
+

The slicing call in proxy_img.dataobj[..., 1] will only load the data from +disk that you need to fill the memory of vol1.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000000..60510c6eee --- /dev/null +++ b/index.html @@ -0,0 +1,343 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

NiBabelΒΆ

+

Read and write access to common neuroimaging file formats, including: +ANALYZE (plain, SPM99, SPM2 and later), GIFTI, NIfTI1, NIfTI2, CIFTI-2, +MINC1, MINC2, AFNI BRIK/HEAD, ECAT and Philips PAR/REC. +In addition, NiBabel also supports FreeSurfer’s MGH, geometry, annotation and +morphometry files, and provides some limited support for DICOM.

+

NiBabel’s API gives full or selective access to header information (metadata), +and image data is made available via NumPy arrays. For more information, see +NiBabel’s documentation site and API reference.

+
+

InstallationΒΆ

+

To install NiBabel’s current release with pip, run:

+
pip install nibabel
+
+
+

To install the latest development version, run:

+
pip install git+https://github.com/nipy/nibabel
+
+
+

When working on NiBabel itself, it may be useful to install in β€œeditable” mode:

+
git clone https://github.com/nipy/nibabel.git
+pip install -e ./nibabel
+
+
+

For more information on previous releases, see the release archive or +development changelog.

+
+
+

TestingΒΆ

+

During development, we recommend using tox to run nibabel tests:

+
git clone https://github.com/nipy/nibabel.git
+cd nibabel
+tox
+
+
+

To test an installed version of nibabel, install the test dependencies +and run pytest_:

+
pip install nibabel[test]
+pytest --pyargs nibabel
+
+
+

For more information, consult the developer guidelines.

+
+
+

Mailing ListΒΆ

+

Please send any questions or suggestions to the neuroimaging mailing list.

+
+
+

LicenseΒΆ

+

NiBabel is licensed under the terms of the MIT license. +Some code included with NiBabel is licensed under the BSD license. +For more information, please see the COPYING file.

+
+
+

CitationΒΆ

+

NiBabel releases have a Zenodo Digital Object Identifier (DOI) badge at +the top of the release notes. Click on the badge for more information.

+
+
+

DocumentationΒΆ

+ +

See also the Developer documentation page for development +discussions, release procedure and more.

+
+
+

Authors and ContributorsΒΆ

+

Most work on NiBabel so far has been by Matthew Brett, Chris Markiewicz, +Michael Hanke, Marc-Alexandre CΓ΄tΓ©, Ben Cipollini, Paul McCarthy and +Chris Cheng. The authors are grateful to the following people who have +contributed code and discussion (in rough order of appearance):

+
    +
  • Yaroslav O. Halchenko

  • +
  • Chris Burns

  • +
  • GaΓ«l Varoquaux

  • +
  • Ian Nimmo-Smith

  • +
  • Jarrod Millman

  • +
  • Bertrand Thirion

  • +
  • Thomas Ballinger

  • +
  • Cindee Madison

  • +
  • Valentin Haenel

  • +
  • Alexandre Gramfort

  • +
  • Christian Haselgrove

  • +
  • Krish Subramaniam

  • +
  • Yannick Schwartz

  • +
  • Bago Amirbekian

  • +
  • Brendan Moloney

  • +
  • FΓ©lix C. Morency

  • +
  • JB Poline

  • +
  • Basile Pinsard

  • +
  • Satrajit Ghosh

  • +
  • Eric Larson

  • +
  • Nolan Nichols

  • +
  • Ly Nguyen

  • +
  • Philippe Gervais

  • +
  • Demian Wassermann

  • +
  • Justin Lecher

  • +
  • Oliver P. Hinds

  • +
  • Nikolaas N. Oosterhof

  • +
  • Kevin S. Hahn

  • +
  • Michiel Cottaar

  • +
  • Erik Kastman

  • +
  • Github user freec84

  • +
  • Peter Fischer

  • +
  • Clemens C. C. Bauer

  • +
  • Samuel St-Jean

  • +
  • Gregory R. Lee

  • +
  • Eric M. Baker

  • +
  • Ariel Rokem

  • +
  • Eleftherios Garyfallidis

  • +
  • Jaakko LeppΓ€kangas

  • +
  • Syam Gadde

  • +
  • Robert D. Vincent

  • +
  • Ivan Gonzalez

  • +
  • Demian Wassermann

  • +
  • Paul McCarthy

  • +
  • Fernando PΓ©rez GarcΓ­a

  • +
  • Venky Reddy

  • +
  • Mark Hymers

  • +
  • Jasper J.F. van den Bosch

  • +
  • Bennet Fauber

  • +
  • Kesshi Jordan

  • +
  • Jon Stutters

  • +
  • Serge Koudoro

  • +
  • Christopher P. Cheng

  • +
  • Mathias Goncalves

  • +
  • Jakub Kaczmarzyk

  • +
  • Dimitri Papadopoulos Orfanos

  • +
  • Ross Markello

  • +
  • Miguel Estevan Moreno

  • +
  • Thomas Roos

  • +
  • Igor Solovey

  • +
  • Jon Haitz Legarreta GorroΓ±o

  • +
  • Katrin Leinweber

  • +
  • Soichi Hayashi

  • +
  • Samir Reddigari

  • +
  • Konstantinos Raktivan

  • +
  • Matt Cieslak

  • +
  • Egor Panfilov

  • +
  • Jath Palasubramaniam

  • +
  • Henry Braun

  • +
  • Oscar Esteban

  • +
  • Cameron Riddell

  • +
  • Hao-Ting Wang

  • +
  • Dorota Jarecka

  • +
  • Chris Gorgolewski

  • +
  • Benjamin C Darwin

  • +
  • Zvi Baratz

  • +
  • Roberto Guidotti

  • +
  • Or Duek

  • +
  • Anibal SΓ³lon

  • +
  • Jonathan Daniel

  • +
  • MarkΓ©ta CalΓ‘bkovΓ‘

  • +
  • Carl Gauthier

  • +
  • Julian Klug

  • +
  • Lea Waller

  • +
  • TomΓ‘Ε‘ Hrnčiar

  • +
  • Andrew Van

  • +
  • JΓ©rΓ΄me DockΓ¨s

  • +
  • Jacob Roberts

  • +
  • Horea Christian

  • +
  • Fabian Perez

  • +
  • Mathieu Scheltienne

  • +
  • Reinder Vos de Wael

  • +
  • Peter Suter

  • +
  • Blake Dewey

  • +
+
+
+

License repriseΒΆ

+

NiBabel is free-software (beer and speech) and covered by the MIT License. +This applies to all source code, documentation, examples and snippets inside +the source distribution (including this website). Please see the +appendix of the manual for the copyright statement and the +full text of the license.

+
+
+

Download and InstallationΒΆ

+

Please find detailed download and installation instructions in the manual.

+
+
+

SupportΒΆ

+

If you have problems installing the software or questions about usage, +documentation or anything else related to NiBabel, you can post to the NiPy +mailing list.

+
+
Mailing list:
+

neuroimaging@python.org [subscription, archive]

+
+
+

We recommend that anyone using NiBabel subscribes to the mailing list. The +mailing list is the preferred way to announce changes and additions to the +project. You can also search the mailing list archive using the mailing list +archive search located in the sidebar of the NiBabel home page.

+
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/installation.html b/installation.html new file mode 100644 index 0000000000..584ad79253 --- /dev/null +++ b/installation.html @@ -0,0 +1,235 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

InstallationΒΆ

+

NiBabel is a pure Python package, +and it should be easy to get NiBabel running on any system. +For the most popular platforms and operating systems +there should be packages in the respective native packaging format +(DEB, RPM or installers). +On other systems you can install NiBabel using pip.

+
+

Installer and packagesΒΆ

+
+

pip and the Python package indexΒΆ

+

If you are not using a Linux package manager, then best way to install NiBabel +is via pip. If you don’t have pip already, follow the pip install +instructions.

+

Then open a terminal (Terminal.app on OSX, cmd or Powershell on +Windows), and type:

+
pip install nibabel
+
+
+

This will download and install NiBabel.

+

If you really like doing stuff manually, you can install NiBabel by downloading +the source from NiBabel pypi . Go to the pypi page and select the source +distribution you want. Download the distribution, unpack it, and then, from +the unpacked directory, run:

+
pip install .
+
+
+

If you get permission errors, this may be because pip is trying to install +to the system directories. You can solve this error by using sudo, but we +strongly suggest you either do an install into your β€œuser” directories, like +this:

+
pip install --user .
+
+
+

or you work inside a virtualenv.

+
+
+

Debian/UbuntuΒΆ

+

Our friends at NeuroDebian have packaged NiBabel at NiBabel NeuroDebian. +Please follow the instructions on the NeuroDebian website on how to access +their repositories. Once this is done, installing NiBabel is:

+
apt-get update
+apt-get install python-nibabel
+
+
+
+
+
+

Install a development versionΒΆ

+

If you want to test the latest development version of nibabel, or you’d like to +help by contributing bug-fixes or new features (excellent!), then this section +is for you.

+
+

RequirementsΒΆ

+ +
+
+

Get the development sourcesΒΆ

+

You can download a tarball of the latest development snapshot (i.e. the current +state of the master branch of the NiBabel source code repository) from the +NiBabel github page.

+

If you want to have access to the full NiBabel history and the latest +development code, do a full clone (AKA checkout) of the NiBabel +repository:

+
git clone https://github.com/nipy/nibabel.git
+
+
+
+
+

InstallationΒΆ

+

Just install the modules by invoking:

+
pip install .
+
+
+

See pip and the Python package index for advice on what to do for permission errors.

+
+
+

Validating your installΒΆ

+

For a basic test of your installation, fire up Python and try importing the +module to see if everything is fine. It should look something like this:

+
Python 3.8.5 (default, Sep  4 2020, 07:30:14)
+[GCC 7.3.0] :: Anaconda, Inc. on linux
+Type "help", "copyright", "credits" or "license" for more information.
+>>> import nibabel
+>>>
+
+
+

To run the nibabel test suite, from the terminal run +pytest --pyargs nibabel or +python -c "import nibabel; nibabel.test().

+

To run an extended test suite that validates nibabel for long-running and +resource-intensive cases, please see Advanced Testing.

+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/legal.html b/legal.html new file mode 100644 index 0000000000..a565a01984 --- /dev/null +++ b/legal.html @@ -0,0 +1,323 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

+
+
+ + + + +
+
+
+
+ + + + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/manual.html b/manual.html new file mode 100644 index 0000000000..e33bc13b3f --- /dev/null +++ b/manual.html @@ -0,0 +1,395 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

NiBabel ManualΒΆ

+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/neuro_radio_conventions.html b/neuro_radio_conventions.html new file mode 100644 index 0000000000..42e70d93c5 --- /dev/null +++ b/neuro_radio_conventions.html @@ -0,0 +1,254 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Radiological vs neurological conventionsΒΆ

+

It is relatively common to talk about images being in β€œradiological” compared +to β€œneurological” convention, but the terms can be used in different and +confusing ways.

+

See Coordinate systems and affines for background on voxel space, reference space +and affines.

+
+

Neurological and radiological display conventionΒΆ

+

Radiologists like looking at their images with the patient’s left on the right +of the image. If they are looking at a brain image, it is as if they were +looking at the brain slice from the point of view of the patient’s feet. +Neurologists like looking at brain images with the patient’s right on the +right of the image. This perspective is as if the neurologist is looking at +the slice from the top of the patient’s head. The convention is one of image +display. The image can have any voxel arrangement on disk or memory, and any +output reference space; it is only necessary for the software displaying the +image to know the reference space and the (probably affine) mapping between +voxel space and reference space; then the software can work out which voxels +are on the left or right of the subject and flip the images to the taste of +the viewer. We could unpack these uses as neurological display convention +and radiological display convention.

+

Here is a very nice graphic by Chris Rorden showing these display +conventions, where the 3D rendering behind the sections shows the directions +that the neurologist and radiologist are thinking of:

+_images/rorden_radio_neuro.jpg +

In the image above, the subject has a stroke in left temporal lobe, causing a +dark area on the MRI.

+
+
+

Alignment of world and voxel axesΒΆ

+

As we will see in the next section, radiological and neurological are +sometimes used to refer to particular alignments of the voxel input axes to +scanner RAS+ output axes. If we look at the affine mapping between voxel space +and scanner RAS+, we may find that moving along the first voxel axis by one +unit results in a equivalent scanner RAS+ movement that is mainly left to +right. This can happen with a diagonal 3x3 part of the affine mapping to +scanner RAS+ (see Coordinate systems and affines):

+
>>> import numpy as np
+>>> from nibabel.affines import apply_affine
+>>> diag_affine = np.array([[3., 0,  0,  0],
+...                         [0,  3., 0,  0],
+...                         [0,  0, 4.5, 0],
+...                         [0,  0,  0,  1]])
+>>> ijk = [1, 0, 0] # moving one unit on the first voxel axis
+>>> apply_affine(diag_affine, ijk)
+array([3., 0., 0.])
+
+
+

In this case the voxel axes are aligned to the output axes, in the sense that +moving in a positive direction on the first voxel axis results in increasing +values on the β€œR+” output axis, and similarly for the second voxel axis with +output β€œA+” and the third voxel axis with output β€œS+”.

+

Some people therefore refer to this alignment of voxel and RAS+ axes as +RAS voxel axes.

+
+
+

Neurological / radiological voxel layoutΒΆ

+

Very confusingly, some people refer to images with RAS voxel axes as having +β€œneurological” voxel layout. This is because the simplest way to display +slices from this voxel array will result in the left of the subject appearing +towards the left hand side of the screen and therefore neurological display +convention. If we take a slice \(k\) over the third axis of the image data array +(img_data[:, :, k]), the resulting slice will have a first array axis +going from left to right in terms of spatial position and the second array +axis going from posterior to anterior. If we display this image with the +first axis going from left to right on screen and the second from bottom to +top, it will have the subject’s right towards the right of the screen, and +anterior towards the top of the screen, as neurologists like it. Here we are +showing the middle slice of an image with RAS voxel axes:

+
>>> import nibabel as nib
+>>> import matplotlib.pyplot as plt
+>>> img = nib.load('downloads/someones_anatomy.nii.gz')
+>>> # The 3x3 part of the affine is diagonal with all +ve values
+>>> img.affine
+array([[  2.75,   0.  ,   0.  , -78.  ],
+       [  0.  ,   2.75,   0.  , -91.  ],
+       [  0.  ,   0.  ,   2.75, -91.  ],
+       [  0.  ,   0.  ,   0.  ,   1.  ]])
+>>> img_data = img.get_fdata()
+>>> a_slice = img_data[:, :, 28]
+>>> # Need transpose to put first axis left-right, second bottom-top
+>>> plt.imshow(a_slice.T, cmap="gray", origin="lower")  
+
+
+
+_images/neuro_radio_conventions-2_00.png +
+

(png, hires.png, pdf)ΒΆ

+
+
+
+_images/neuro_radio_conventions-2_01.png +
+

(png, hires.png, pdf)ΒΆ

+
+
+

This slice does have the voxels from the right of isocenter towards the right +of the screen, neurology style.

+

Similarly, an β€œLAS” alignment of voxel axes to RAS+ axes would result in an +image with the left of the subject towards the right of the screen, as +radiologists like it. β€œLAS” voxel axes can also be called β€œradiological” +voxel layout for this reason [1].

+

Over time it has become more common for the scanner to generate images with +almost any orientation of the voxel axes relative to the reference axes. +Maybe for this reason, the terms β€œradiological” and β€œneurological” are less +commonly used as applied to voxel layout. We nipyers try to avoid the +terms neurological or radiological for voxel layout because they can make it +harder to separate the idea of voxel and reference space axes and the affine +as a mapping between them.

+

Footnotes

+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/nibabel_images.html b/nibabel_images.html new file mode 100644 index 0000000000..f2d5d19070 --- /dev/null +++ b/nibabel_images.html @@ -0,0 +1,529 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Nibabel imagesΒΆ

+

A nibabel image object is the association of three things:

+
    +
  • an N-D array containing the image data;

  • +
  • a (4, 4) affine matrix mapping array coordinates to coordinates in some +RAS+ world coordinate space (Coordinate systems and affines);

  • +
  • image metadata in the form of a header.

  • +
+
+

The image objectΒΆ

+

First we load some libraries we are going to need for the examples:

+
>>> import os
+>>> import numpy as np
+
+
+

There is an example image in the nibabel distribution.

+
>>> from nibabel.testing import data_path
+>>> example_file = os.path.join(data_path, 'example4d.nii.gz')
+
+
+

We load the file to create a nibabel image object:

+
>>> import nibabel as nib
+>>> img = nib.load(example_file)
+
+
+

The object img is an instance of a nibabel image. In fact it is an +instance of a nibabel nibabel.nifti1.Nifti1Image:

+
>>> img
+<nibabel.nifti1.Nifti1Image object at ...>
+
+
+

As with any Python object, you can inspect img to see what attributes it +has. We recommend using IPython tab completion for this, but here are some +examples of interesting attributes:

+

dataobj is the object pointing to the image array data:

+
>>> img.dataobj
+<nibabel.arrayproxy.ArrayProxy object at ...>
+
+
+

See Array proxies and proxy images for more on why this is an array proxy.

+

affine is the affine array relating array coordinates from the image data +array to coordinates in some RAS+ world coordinate system +(Coordinate systems and affines):

+
>>> # Set numpy to print only 2 decimal digits for neatness
+>>> np.set_printoptions(precision=2, suppress=True)
+
+
+
>>> img.affine
+array([[ -2.  ,   0.  ,   0.  , 117.86],
+       [ -0.  ,   1.97,  -0.36, -35.72],
+       [  0.  ,   0.32,   2.17,  -7.25],
+       [  0.  ,   0.  ,   0.  ,   1.  ]])
+
+
+

header contains the metadata for this image. In this case it is +specifically NIfTI metadata:

+
>>> img.header
+<nibabel.nifti1.Nifti1Header object at ...>
+
+
+
+
+

The image headerΒΆ

+

The header of an image contains the image metadata. The information in the +header will differ between different image formats. For example, the header +information for a NIfTI1 format file differs from the header information for a +MINC format file.

+

Our image is a NIfTI1 format image, and it therefore has a NIfTI1 format +header:

+
>>> header = img.header
+>>> print(header)                           
+<class 'nibabel.nifti1.Nifti1Header'> object, endian='<'
+sizeof_hdr      : 348
+data_type       : b''
+db_name         : b''
+extents         : 0
+session_error   : 0
+regular         : b'r'
+dim_info        : 57
+dim             : [  4 128  96  24   2   1   1   1]
+intent_p1       : 0.0
+intent_p2       : 0.0
+intent_p3       : 0.0
+intent_code     : none
+datatype        : int16
+bitpix          : 16
+slice_start     : 0
+pixdim          : [   -1.      2.      2.      2.2  2000.      1.      1.      1. ]
+vox_offset      : 0.0
+scl_slope       : nan
+scl_inter       : nan
+slice_end       : 23
+slice_code      : unknown
+xyzt_units      : 10
+cal_max         : 1162.0
+cal_min         : 0.0
+slice_duration  : 0.0
+toffset         : 0.0
+glmax           : 0
+glmin           : 0
+descrip         : b'FSL3.3\x00 v2.25 NIfTI-1 Single file format'
+aux_file        : b''
+qform_code      : scanner
+sform_code      : scanner
+quatern_b       : -1.94510681403e-26
+quatern_c       : -0.996708512306
+quatern_d       : -0.081068739295
+qoffset_x       : 117.855102539
+qoffset_y       : -35.7229423523
+qoffset_z       : -7.24879837036
+srow_x          : [  -2.      0.      0.    117.86]
+srow_y          : [ -0.     1.97  -0.36 -35.72]
+srow_z          : [ 0.    0.32  2.17 -7.25]
+intent_name     : b''
+magic           : b'n+1'
+
+
+

The header of any image will normally have the following methods:

+
    +
  • get_data_shape() to get the output shape of the image data array:

    +
    >>> print(header.get_data_shape())
    +(128, 96, 24, 2)
    +
    +
    +
  • +
  • get_data_dtype() to get the numpy data type in which the image data is +stored (or will be stored if you save the image):

    +
    >>> print(header.get_data_dtype())
    +int16
    +
    +
    +
  • +
  • get_zooms() to get the voxel sizes in millimeters:

    +
    >>> print(header.get_zooms())
    +(2.0, 2.0, 2.19999..., 2000.0)
    +
    +
    +

    The last value of header.get_zooms() is the time between scans in +milliseconds; this is the equivalent of voxel size on the time axis.

    +
  • +
+
+
+

The image data arrayΒΆ

+

The image data array is a little more complicated, because the image array can +be stored in the image object as a numpy array or stored on disk for you to +access later via an array proxy.

+
+

Array proxies and proxy imagesΒΆ

+

When you load an image from disk, as we did here, the data is likely to be +accessible via an array proxy. An array proxy is not the array itself but +something that represents the array, and can provide the array when we ask for +it.

+

Our image does have an array proxy, as we have already seen:

+
>>> img.dataobj
+<nibabel.arrayproxy.ArrayProxy object at ...>
+
+
+

The array proxy allows us to create the image object without immediately +loading all the array data from disk.

+

Images with an array proxy object like this one are called proxy images +because the image data is not yet an array, but the array proxy points to +(proxies) the array data on disk.

+

You can test if the image has a array proxy like this:

+
>>> nib.is_proxy(img.dataobj)
+True
+
+
+
+
+

Array imagesΒΆ

+

We can also create images from numpy arrays. For example:

+
>>> array_data = np.arange(24, dtype=np.int16).reshape((2, 3, 4))
+>>> affine = np.diag([1, 2, 3, 1])
+>>> array_img = nib.Nifti1Image(array_data, affine)
+
+
+

In this case the image array data is already a numpy array, and there is no +version of the array on disk. The dataobj property of the image is the +array itself rather than a proxy for the array:

+
>>> array_img.dataobj
+array([[[ 0,  1,  2,  3],
+        [ 4,  5,  6,  7],
+        [ 8,  9, 10, 11]],
+
+       [[12, 13, 14, 15],
+        [16, 17, 18, 19],
+        [20, 21, 22, 23]]], dtype=int16)
+>>> array_img.dataobj is array_data
+True
+
+
+

dataobj is an array, not an array proxy, so:

+
>>> nib.is_proxy(array_img.dataobj)
+False
+
+
+
+
+

Getting the image data the easy wayΒΆ

+

For either type of image (array or proxy) you can always get the data with the +get_fdata() method.

+

For the array image, get_fdata() just returns the data array, if it’s already the required floating point type (default 64-bit float). If it isn’t that type, get_fdata() casts it to one:

+
>>> image_data = array_img.get_fdata()
+>>> image_data.shape
+(2, 3, 4)
+>>> image_data.dtype == np.dtype(np.float64)
+True
+
+
+

The cast to floating point means the array is not the one attached to the image:

+
>>> image_data is array_img.dataobj
+False
+
+
+

Here’s an image backed by a floating point array:

+
>>> farray_img = nib.Nifti1Image(image_data.astype(np.float64), affine)
+>>> farray_data = farray_img.get_fdata()
+>>> farray_data.dtype == np.dtype(np.float64)
+True
+
+
+

There was no cast, so the array returned is exactly the array attached to the +image:

+
>>> farray_data is farray_img.dataobj
+True
+
+
+

For the proxy image, the get_fdata() method fetches the array data from +disk using the proxy, and returns the array.

+
>>> image_data = img.get_fdata()
+>>> image_data.shape
+(128, 96, 24, 2)
+
+
+

The image dataobj property is still a proxy object:

+
>>> img.dataobj
+<nibabel.arrayproxy.ArrayProxy object at ...>
+
+
+
+
+

Proxies and cachingΒΆ

+

You may not want to keep loading the image data off disk every time +you call get_fdata() on a proxy image. By default, when you call +get_fdata() the first time on a proxy image, the image object keeps a +cached copy of the loaded array. The next time you call img.get_fdata(), +the image returns the array from cache rather than loading it from disk again.

+
>>> data_again = img.get_fdata()
+
+
+

The returned data is the same (cached) copy we returned before:

+
>>> data_again is image_data
+True
+
+
+

See Images and memory for more details on managing image memory and +controlling the image cache.

+
+
+

Image slicingΒΆ

+

At times it is useful to manipulate an image’s shape while keeping it in the +same coordinate system. +The slicer attribute provides an array-slicing interface to produce new +images with an appropriately adjusted header, such that the data at a given +RAS+ location is unchanged.

+
>>> cropped_img = img.slicer[32:-32, ...]
+>>> cropped_img.shape
+(64, 96, 24, 2)
+
+
+

The data is identical to cropping the data block directly:

+
>>> np.array_equal(cropped_img.get_fdata(), img.get_fdata()[32:-32, ...])
+True
+
+
+

However, unused data did not need to be loaded into memory or scaled. +Additionally, the image affine was adjusted so that the X-translation is +32 voxels (64mm) less:

+
>>> cropped_img.affine
+array([[ -2.  ,   0.  ,   0.  ,  53.86],
+       [ -0.  ,   1.97,  -0.36, -35.72],
+       [  0.  ,   0.32,   2.17,  -7.25],
+       [  0.  ,   0.  ,   0.  ,   1.  ]])
+
+
+
>>> img.affine - cropped_img.affine
+array([[ 0.,  0.,  0., 64.],
+       [ 0.,  0.,  0.,  0.],
+       [ 0.,  0.,  0.,  0.],
+       [ 0.,  0.,  0.,  0.]])
+
+
+

Another use for the slicer object is to choose specific volumes from a +time series:

+
>>> vol0 = img.slicer[..., 0]
+>>> vol0.shape
+(128, 96, 24)
+
+
+

Or a selection of volumes:

+
>>> img.slicer[..., :1].shape
+(128, 96, 24, 1)
+>>> img.slicer[..., :2].shape
+(128, 96, 24, 2)
+
+
+

It is also possible to use an integer step when slicing, downsampling +the image without filtering. +Note that this will induce artifacts in the frequency spectrum +(aliasing) along any axis that is down-sampled.

+
>>> downsampled = vol0.slicer[::2, ::2, ::2]
+>>> downsampled.header.get_zooms()
+(4.0, 4.0, 4.399998)
+
+
+

Finally, an image can be flipped along an axis, maintaining an appropriate +affine matrix:

+
>>> nib.orientations.aff2axcodes(img.affine)
+('L', 'A', 'S')
+>>> ras = img.slicer[::-1]
+>>> nib.orientations.aff2axcodes(ras.affine)
+('R', 'A', 'S')
+>>> ras.affine
+array([[  2.  ,   0.  ,   0.  , 117.86],
+       [  0.  ,   1.97,  -0.36, -35.72],
+       [ -0.  ,   0.32,   2.17,  -7.25],
+       [  0.  ,   0.  ,   0.  ,   1.  ]])
+
+
+
+
+
+

Loading and savingΒΆ

+

The save and load functions in nibabel should do all the work for you:

+
>>> nib.save(array_img, 'my_image.nii')
+>>> img_again = nib.load('my_image.nii')
+>>> img_again.shape
+(2, 3, 4)
+
+
+

You can also use the to_filename method:

+
>>> array_img.to_filename('my_image_again.nii')
+>>> img_again = nib.load('my_image_again.nii')
+>>> img_again.shape
+(2, 3, 4)
+
+
+

You can get and set the filename with get_filename() and +set_filename():

+
>>> img_again.set_filename('another_image.nii')
+>>> img_again.get_filename()
+'another_image.nii'
+
+
+
+
+

Details of files and imagesΒΆ

+

If an image can be loaded or saved on disk, the image will have an attribute +called file_map. img.file_map is a dictionary where the keys are the +names of the files that the image uses to load / save on disk, and the values +are FileHolder objects, that usually contain the filenames that the image +has been loaded from or saved to. In the case of a NiFTI1 single file, this +is just a single image file with a .nii or .nii.gz extension:

+
>>> list(img_again.file_map)
+['image']
+>>> img_again.file_map['image'].filename
+'another_image.nii'
+
+
+

Other file types need more than one file to make up the image. The NiFTI1 +pair type is one example. NIfTI pair images have one file containing the +header information and another containing the image array data:

+
>>> pair_img = nib.Nifti1Pair(array_data, np.eye(4))
+>>> nib.save(pair_img, 'my_pair_image.img')
+>>> sorted(pair_img.file_map)
+['header', 'image']
+>>> pair_img.file_map['header'].filename
+'my_pair_image.hdr'
+>>> pair_img.file_map['image'].filename
+'my_pair_image.img'
+
+
+

The older Analyze format also has a separate header and image file:

+
>>> ana_img = nib.AnalyzeImage(array_data, np.eye(4))
+>>> sorted(ana_img.file_map)
+['header', 'image']
+
+
+

It is the contents of the file_map that gets changed when you use +set_filename or to_filename:

+
>>> ana_img.set_filename('analyze_image.img')
+>>> ana_img.file_map['image'].filename
+'analyze_image.img'
+>>> ana_img.file_map['header'].filename
+'analyze_image.hdr'
+
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/nifti_images.html b/nifti_images.html new file mode 100644 index 0000000000..3d270288d0 --- /dev/null +++ b/nifti_images.html @@ -0,0 +1,591 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Working with NIfTI imagesΒΆ

+

This page describes some features of the nibabel implementation of the NIfTI +format. Generally all these features apply equally to the NIfTI 1 and the +NIfTI 2 format, but we will note the differences when they come up. NIfTI 1 +is much more common than NIfTI 2.

+
+

PreliminariesΒΆ

+

We first set some display parameters to print out numpy arrays in a compact +form:

+
>>> import numpy as np
+>>> # Set numpy to print only 2 decimal digits for neatness
+>>> np.set_printoptions(precision=2, suppress=True)
+
+
+
+
+

Example NIfTI imagesΒΆ

+
>>> import os
+>>> import nibabel as nib
+>>> from nibabel.testing import data_path
+
+
+

This is the example NIfTI 1 image:

+
>>> example_ni1 = os.path.join(data_path, 'example4d.nii.gz')
+>>> n1_img = nib.load(example_ni1)
+>>> n1_img
+<nibabel.nifti1.Nifti1Image object at ...>
+
+
+

Here is the NIfTI 2 example image:

+
>>> example_ni2 = os.path.join(data_path, 'example_nifti2.nii.gz')
+>>> n2_img = nib.load(example_ni2)
+>>> n2_img
+<nibabel.nifti2.Nifti2Image object at ...>
+
+
+
+
+

The NIfTI headerΒΆ

+

The NIfTI 1 header is a small C structure of size 352 bytes. It contains the +following fields:

+
>>> n1_header = n1_img.header
+>>> print(n1_header)                     
+<class 'nibabel.nifti1.Nifti1Header'> object, endian='<'
+sizeof_hdr      : 348
+data_type       : b''
+db_name         : b''
+extents         : 0
+session_error   : 0
+regular         : b'r'
+dim_info        : 57
+dim             : [  4 128  96  24   2   1   1   1]
+intent_p1       : 0.0
+intent_p2       : 0.0
+intent_p3       : 0.0
+intent_code     : none
+datatype        : int16
+bitpix          : 16
+slice_start     : 0
+pixdim          : [   -1.      2.      2.      2.2  2000.      1.      1.      1. ]
+vox_offset      : 0.0
+scl_slope       : nan
+scl_inter       : nan
+slice_end       : 23
+slice_code      : unknown
+xyzt_units      : 10
+cal_max         : 1162.0
+cal_min         : 0.0
+slice_duration  : 0.0
+toffset         : 0.0
+glmax           : 0
+glmin           : 0
+descrip         : b'FSL3.3\x00 v2.25 NIfTI-1 Single file format'
+aux_file        : b''
+qform_code      : scanner
+sform_code      : scanner
+quatern_b       : -1.94510681403e-26
+quatern_c       : -0.996708512306
+quatern_d       : -0.081068739295
+qoffset_x       : 117.855102539
+qoffset_y       : -35.7229423523
+qoffset_z       : -7.24879837036
+srow_x          : [  -2.      0.      0.    117.86]
+srow_y          : [ -0.     1.97  -0.36 -35.72]
+srow_z          : [ 0.    0.32  2.17 -7.25]
+intent_name     : b''
+magic           : b'n+1'
+
+
+

The NIfTI 2 header is similar, but of length 540 bytes, with fewer fields:

+
>>> n2_header = n2_img.header
+>>> print(n2_header)                     
+    <class 'nibabel.nifti2.Nifti2Header'> object, endian='<'
+    sizeof_hdr      : 540
+    magic           : b'n+2'
+    eol_check       : [13 10 26 10]
+    datatype        : int16
+    bitpix          : 16
+    dim             : [ 4 32 20 12  2  1  1  1]
+    intent_p1       : 0.0
+    intent_p2       : 0.0
+    intent_p3       : 0.0
+    pixdim          : [   -1.      2.      2.      2.2  2000.      1.      1.      1. ]
+    vox_offset      : 0
+    scl_slope       : nan
+    scl_inter       : nan
+    cal_max         : 1162.0
+    cal_min         : 0.0
+    slice_duration  : 0.0
+    toffset         : 0.0
+    slice_start     : 0
+    slice_end       : 23
+    descrip         : b'FSL3.3\x00 v2.25 NIfTI-1 Single file format'
+    aux_file        : b''
+    qform_code      : scanner
+    sform_code      : scanner
+    quatern_b       : -1.94510681403e-26
+    quatern_c       : -0.996708512306
+    quatern_d       : -0.081068739295
+    qoffset_x       : 117.855102539
+    qoffset_y       : -35.7229423523
+    qoffset_z       : -7.24879837036
+    srow_x          : [  -2.      0.      0.    117.86]
+    srow_y          : [ -0.     1.97  -0.36 -35.72]
+    srow_z          : [ 0.    0.32  2.17 -7.25]
+    slice_code      : unknown
+    xyzt_units      : 10
+    intent_code     : none
+    intent_name     : b''
+    dim_info        : 57
+    unused_str      : b''
+
+
+

You can get and set individual fields in the header using dict (mapping-type) +item access. For example:

+
>>> n1_header['cal_max']
+array(1162., dtype=float32)
+>>> n1_header['cal_max'] = 1200
+>>> n1_header['cal_max']
+array(1200., dtype=float32)
+
+
+

Check the attributes of the header for get_ / set_ methods to get and +set various combinations of NIfTI header fields.

+

The get_ / set_ methods should check and apply valid combinations of +values from the header, whereas you can do anything you like with the dict / +mapping item access. It is safer to use the get_ / set_ methods and +use the mapping item access only if the get_ / set_ methods will not +do what you want.

+
+
+

The NIfTI affinesΒΆ

+

Like other nibabel image types, NIfTI images have an affine relating the voxel +coordinates to world coordinates in RAS+ space:

+
>>> n1_img.affine
+array([[ -2.  ,   0.  ,   0.  , 117.86],
+       [ -0.  ,   1.97,  -0.36, -35.72],
+       [  0.  ,   0.32,   2.17,  -7.25],
+       [  0.  ,   0.  ,   0.  ,   1.  ]])
+
+
+

Unlike other formats, the NIfTI header format can specify this affine in one +of three ways β€” the sform affine, the qform affine and the fall-back +header affine.

+

Nibabel uses an algorithm to chose which of +these three it will use for the overall image affine.

+
+

The sform affineΒΆ

+

The header stores the three first rows of the 4 by 4 affine in the header +fields srow_x, srow_y, srow_z. The header does not store the +fourth row because it is always [0, 0, 0, 1] (see +Coordinate systems and affines).

+

You can get the sform affine specifically with the get_sform() method of +the image or the header.

+

For example:

+
>>> print(n1_header['srow_x'])
+[ -2.     0.     0.   117.86]
+>>> print(n1_header['srow_y'])
+[ -0.     1.97  -0.36 -35.72]
+>>> print(n1_header['srow_z'])
+[ 0.    0.32  2.17 -7.25]
+>>> print(n1_header.get_sform())
+[[ -2.     0.     0.   117.86]
+ [ -0.     1.97  -0.36 -35.72]
+ [  0.     0.32   2.17  -7.25]
+ [  0.     0.     0.     1.  ]]
+
+
+

This affine is valid only if the sform_code is not zero.

+
>>> print(n1_header['sform_code'])
+1
+
+
+

The different sform code values specify which RAS+ space the sform affine +refers to, with these interpretations:

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

Code

Label

Meaning

0

unknown

sform not defined

1

scanner

RAS+ in scanner coordinates

2

aligned

RAS+ aligned to some other scan

3

talairach

RAS+ in Talairach atlas space

4

mni

RAS+ in MNI atlas space

+

In our case the code is 1, meaning β€œscanner” alignment.

+

You can get the affine and the code using the coded=True argument to +get_sform():

+
>>> print(n1_header.get_sform(coded=True))
+(array([[ -2.  ,   0.  ,   0.  , 117.86],
+       [ -0.  ,   1.97,  -0.36, -35.72],
+       [  0.  ,   0.32,   2.17,  -7.25],
+       [  0.  ,   0.  ,   0.  ,   1.  ]]), 1)
+
+
+

You can set the sform with the set_sform() method of the header and +the image.

+
>>> n1_header.set_sform(np.diag([2, 3, 4, 1]))
+>>> n1_header.get_sform()
+array([[2., 0., 0., 0.],
+       [0., 3., 0., 0.],
+       [0., 0., 4., 0.],
+       [0., 0., 0., 1.]])
+
+
+

Set the affine and code using the code parameter to set_sform():

+
>>> n1_header.set_sform(np.diag([3, 4, 5, 1]), code='mni')
+>>> n1_header.get_sform(coded=True)
+(array([[3., 0., 0., 0.],
+       [0., 4., 0., 0.],
+       [0., 0., 5., 0.],
+       [0., 0., 0., 1.]]), 4)
+
+
+
+
+

The qform affineΒΆ

+

This affine can be calculated from a combination of the voxel sizes (entries 1 +through 4 of the pixdim field), a sign flip called qfac stored in +entry 0 of pixdim, and a quaternion that can be +reconstructed from fields quatern_b, quatern_c, quatern_d.

+

See the code for the get_qform() method for details.

+

You can get and set the qform affine using the equivalent methods to those for +the sform: get_qform(), set_qform().

+
>>> n1_header.get_qform(coded=True)
+(array([[ -2.  ,   0.  ,  -0.  , 117.86],
+       [  0.  ,   1.97,  -0.36, -35.72],
+       [  0.  ,   0.32,   2.17,  -7.25],
+       [  0.  ,   0.  ,   0.  ,   1.  ]]), 1)
+
+
+

The qform also has a corresponding qform_code with the same interpretation +as the sform_code.

+
+
+

The fall-back header affineΒΆ

+

This is the affine of last resort, constructed only from the pixdim voxel +sizes. The NIfTI specification says that this should set the +first voxel in the image as [0, 0, 0] in world coordinates, but we nibabblers +follow SPM in preferring to set the central voxel to have [0, 0, 0] world +coordinate. The NIfTI spec also implies that the image should be assumed to be +in RAS+ voxel orientation for this affine (see Coordinate systems and affines). +Again like SPM, we prefer to assume LAS+ voxel orientation by default.

+

You can always get the fall-back affine with get_base_affine():

+
>>> n1_header.get_base_affine()
+array([[ -2. ,   0. ,   0. , 127. ],
+       [  0. ,   2. ,   0. , -95. ],
+       [  0. ,   0. ,   2.2, -25.3],
+       [  0. ,   0. ,   0. ,   1. ]])
+
+
+
+
+

Choosing the image affineΒΆ

+

Given there are three possible affines defined in the NIfTI header, nibabel +has to chose which of these to use for the image affine.

+

The algorithm is defined in the get_best_affine() method. It is:

+
    +
  1. If sform_code != 0 (β€˜unknown’) use the sform affine; else

  2. +
  3. If qform_code != 0 (β€˜unknown’) use the qform affine; else

  4. +
  5. Use the fall-back affine.

  6. +
+
+
+

Default sform and qform codesΒΆ

+

If you create a new image, e.g.:

+
>>> data = np.random.random((20, 20, 20))
+>>> xform = np.eye(4) * 2
+>>> img = nib.nifti1.Nifti1Image(data, xform)
+
+
+

The sform and qform codes will be initialised to 2 (aligned) and 0 (unknown) +respectively:

+
>>> img.get_sform(coded=True) 
+(array([[2., 0., 0., 0.],
+       [0., 2., 0., 0.],
+       [0., 0., 2., 0.],
+       [0., 0., 0., 1.]]), 2)
+>>> img.get_qform(coded=True)
+(None, 0)
+
+
+

This is based on the assumption that the affine you specify for a newly +created image will align the image to some known coordinate system. According +to the NIfTI specification, the qform is intended to encode a +transformation into scanner coordinates - for a programmatically created +image, we have no way of knowing what the scanner coordinate system is; +furthermore, the qform cannot be used to store an arbitrary affine transform, +as it is unable to encode shears. So the provided affine will be stored in the +sform, and the qform will be left uninitialised.

+

If you create a new image and specify an existing header, e.g.:

+
>>> example_ni1 = os.path.join(data_path, 'example4d.nii.gz')
+>>> n1_img = nib.load(example_ni1)
+>>> new_header = header=n1_img.header.copy()
+>>> new_data = np.random.random(n1_img.shape[:3])
+>>> new_img = nib.nifti1.Nifti1Image(data, None, header=new_header)
+
+
+

then the newly created image will inherit the same sform and qform codes that +are in the provided header. However, if you create a new image with both an +affine and a header specified, e.g.:

+
>>> xform = np.eye(4)
+>>> new_img = nib.nifti1.Nifti1Image(data, xform, header=new_header)
+
+
+

then the sform and qform codes will only be preserved if the provided affine +is the same as the affine in the provided header. If the affines do not match, +the sform and qform codes will be set to their default values of 2 and 0 +respectively. This is done on the basis that, if you are changing the affine, +you are likely to be changing the space to which the affine is pointing. So +the original sform and qform codes can no longer be assumed to be valid.

+

If you wish to set the sform and qform affines and/or codes to some other +value, you can always set them after creation using the set_sform and +set_qform methods, as described above.

+
+
+
+

Data scalingΒΆ

+

NIfTI uses a simple scheme for data scaling.

+

By default, nibabel will take care of this scaling for you, but there may be +times that you want to control the data scaling yourself. If so, the next +section describes how the scaling works and the nibabel implementation of +same.

+

There are two scaling fields in the header called scl_slope and +scl_inter.

+

The output data from a NIfTI image comes from:

+
    +
  1. Loading the binary data from the image file;

  2. +
  3. Casting the numbers to the binary format given in the header and returned +by get_data_dtype();

  4. +
  5. Reshaping to the output image shape;

  6. +
  7. Multiplying the result by the header scl_slope value, if +both of scl_slope and scl_inter are defined;

  8. +
  9. Adding the value header scl_inter value to the result, if both of +scl_slope and scl_inter are defined;

  10. +
+

β€˜Defined’ means, the value is not NaN (not a number).

+

All this gets built into the array proxy when you load a NIfTI image.

+

When you load an image, the header scaling values automatically get set to NaN +(undefined) to mark the fact that the scaling values have been consumed by the +read. The scaling values read from the header on load only appear in the +array proxy object.

+

To see how this works, let’s make a new image with some scaling:

+
>>> array_data = np.arange(24, dtype=np.int16).reshape((2, 3, 4))
+>>> affine = np.diag([1, 2, 3, 1])
+>>> array_img = nib.Nifti1Image(array_data, affine)
+>>> array_header = array_img.header
+
+
+

The default scaling values are NaN (undefined):

+
>>> array_header['scl_slope']
+array(nan, dtype=float32)
+>>> array_header['scl_inter']
+array(nan, dtype=float32)
+
+
+

You can get the scaling values with the get_slope_inter() method:

+
>>> array_header.get_slope_inter()
+(None, None)
+
+
+

None corresponds to the NaN scaling value (undefined).

+

We can set them in the image header, so they get saved to the header when the +image is written. We can do this by setting the fields directly, or with +set_slope_inter():

+
>>> array_header.set_slope_inter(2, 10)
+>>> array_header.get_slope_inter()
+(2.0, 10.0)
+>>> array_header['scl_slope']
+array(2., dtype=float32)
+>>> array_header['scl_inter']
+array(10., dtype=float32)
+
+
+

Setting the scale factors in the header has no effect on the image data before +we save and load again:

+
>>> array_img.get_fdata()
+array([[[ 0.,  1.,  2.,  3.],
+        [ 4.,  5.,  6.,  7.],
+        [ 8.,  9., 10., 11.]],
+
+       [[12., 13., 14., 15.],
+        [16., 17., 18., 19.],
+        [20., 21., 22., 23.]]])
+
+
+

Now we save the image and load it again:

+
>>> nib.save(array_img, 'scaled_image.nii')
+>>> scaled_img = nib.load('scaled_image.nii')
+
+
+

The data array has the scaling applied:

+
>>> scaled_img.get_fdata()
+array([[[10., 12., 14., 16.],
+        [18., 20., 22., 24.],
+        [26., 28., 30., 32.]],
+
+       [[34., 36., 38., 40.],
+        [42., 44., 46., 48.],
+        [50., 52., 54., 56.]]])
+
+
+

The header for the loaded image has had the scaling reset to undefined, to +mark the fact that the scaling has been β€œconsumed” by the load:

+
>>> scaled_img.header.get_slope_inter()
+(None, None)
+
+
+

The original slope and intercept are still accessible in the array proxy +object:

+
>>> scaled_img.dataobj.slope
+2.0
+>>> scaled_img.dataobj.inter
+10.0
+
+
+

If the header scaling is undefined when we save the image, nibabel will try to +find an optimum slope and intercept to best preserve the precision of the data +in the output data type. Because nibabel will set the scaling to undefined +when loading the image, or creating a new image, this is the default behavior.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/notebooks/index.html b/notebooks/index.html new file mode 100644 index 0000000000..8fac4d5259 --- /dev/null +++ b/notebooks/index.html @@ -0,0 +1,108 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

IPython notebooks for Nibabel projectΒΆ

+
+

Rotation matrix orthogonalityΒΆ

+

See ATA error calculations and Cross +product error. You can use the IPython notebook +viewer to view these files; copy the URL and paste into the Notebook viewer +URL box.

+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..de2091efc26170df91aa61f5ee1cd9f0a71afb14 GIT binary patch literal 13919 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 literal 0 HcmV?d00001 diff --git a/old/ioimplementation.html b/old/ioimplementation.html new file mode 100644 index 0000000000..5f2ebc6930 --- /dev/null +++ b/old/ioimplementation.html @@ -0,0 +1,212 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Relationship between images and io implementationsΒΆ

+
+

Summary and sign-offΒΆ

+

These were some meditations about splitting the image into two API parts.

+

The first part would be the lower level IO implementation. This part is +rather like a fusion of the Header and ArrayProxy objects +in current nibabel. It takes care of lower level details like i/o data dtype, +shape, offset, and it might help with slicing to get the data. On top of that +would be a high level interface implementing load, save, filename, +data. The top-level image also had the novel idea of a mode parameter +which, if 'r', would raise an error on attempting to save.

+
+
+

ImagesΒΆ

+

An image houses the association of the:

+
    +
  • data array

  • +
  • affine

  • +
  • output space

  • +
  • metadata

  • +
  • mode

  • +
+

These are straightforward attributes, and have no necessary relationship +to stuff on disk.

+

By β€˜β€™disk’’, we mean, file-like objects - not necessarily on disk.

+

The io implementation manages the relationship of images and stuff on +disk.

+

Specifically, it manages load of images from disk, and save of +images to disk.

+

The user does not see the io implementation unless they ask to. In +standard use of images they will not need to do this.

+
+
+

IO implementationsΒΆ

+

By use case.

+
Creating array image, saving
+
+>>> import tempfile
+>>> from nibabel.images import Image
+>>> from nibabel import load, save
+>>> fp, fname = tempfile.mkstemp('.nii')
+>>> data = np.arange(24).reshape((2,3,4))
+>>> img = Image(data)
+>>> img.filename is None
+True
+>>> img.save()
+Traceback (most recent call last):
+   ...
+ImageError: no filespec to save to
+>>> save(img)
+Traceback (most recent call last):
+   ...
+ImageError: no filespec to save to
+>>> img2 = save(img, 'some_image.nii') # type guessed from filename
+>>> img2.filename == fname
+True
+>>> img.filename is None # still
+True
+>>> img.filename = 'some_filename.nii' # read only property
+Traceback (most recent call last):
+   ...
+AttributeError: can't set attribute
+
+Load, futz, save
+
+>>> img3 = load(fname, mode='r')
+>>> img3.filename == fname
+True
+>>> np.all(img3.data == data)
+True
+>>> img3.data[0,0] = 99
+>>> img3.save()
+Traceback (most recent call last):
+   ...
+ImageError: trying to write to read only image
+>>> img3.mode = 'rw'
+>>> img3.save()
+>>> load(img4)
+>>> img4.mode # 'r' is the default
+'r'
+>>> mod_data = data.copy()
+>>> mod_data[0,0] = 99
+>>> np.all(img4.data = mod_data)
+True
+
+Prepare image for later writing
+
+>>> img5 = Image(np.zeros(2,3,4))
+>>> fp, fname2 = tempfile.mkstemp('.nii')
+>>> img5.set_filespec(fname2)
+>>> # then do some things to the image
+>>> img5.save()
+
+This is an example where you do need the io API
+
+>>> from nibabel.ioimps import guessed_imp
+>>> fp, fname3 = tempfile.mkstemp('.nii')
+>>> ioimp = guessed_imp(fname3)
+>>> ioimp.set_data_dtype(np.float64)
+>>> ioimp.set_data_shape((2,3,4)) # set_data_shape method
+>>> slice_def = (slice(None), slice(None), 0)
+>>> ioimp.write_slice(data[slice_def], slice_def) # write_slice method
+>>> slice_def = (2, 3, 1)
+>>> ioimp.write_slice(data[slice_def], slice_def) # write_slice method
+Traceback (most recent call last):
+   ...
+ImageIOError: data write is not contiguous
+
+
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/py-modindex.html b/py-modindex.html new file mode 100644 index 0000000000..34cbdfe66b --- /dev/null +++ b/py-modindex.html @@ -0,0 +1,596 @@ + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Python Module Index

+ +
+ n +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ n
+ nibabel +
    + nibabel._compression +
    + nibabel.affines +
    + nibabel.analyze +
    + nibabel.arrayproxy +
    + nibabel.arraywriters +
    + nibabel.batteryrunners +
    + nibabel.benchmarks +
    + nibabel.benchmarks.bench_array_to_file +
    + nibabel.benchmarks.bench_arrayproxy_slicing +
    + nibabel.benchmarks.bench_fileslice +
    + nibabel.benchmarks.bench_finite_range +
    + nibabel.benchmarks.bench_load_save +
    + nibabel.benchmarks.butils +
    + nibabel.brikhead +
    + nibabel.caret +
    + nibabel.casting +
    + nibabel.cifti2 +
    + nibabel.cifti2.cifti2 +
    + nibabel.cifti2.cifti2_axes +
    + nibabel.cifti2.parse_cifti2 +
    + nibabel.cmdline +
    + nibabel.cmdline.conform +
    + nibabel.cmdline.convert +
    + nibabel.cmdline.dicomfs +
    + nibabel.cmdline.diff +
    + nibabel.cmdline.ls +
    + nibabel.cmdline.nifti_dx +
    + nibabel.cmdline.parrec2nii +
    + nibabel.cmdline.roi +
    + nibabel.cmdline.stats +
    + nibabel.cmdline.tck2trk +
    + nibabel.cmdline.trk2tck +
    + nibabel.cmdline.utils +
    + nibabel.data +
    + nibabel.dataobj_images +
    + nibabel.deprecated +
    + nibabel.deprecator +
    + nibabel.dft +
    + nibabel.ecat +
    + nibabel.environment +
    + nibabel.eulerangles +
    + nibabel.filebasedimages +
    + nibabel.fileholders +
    + nibabel.filename_parser +
    + nibabel.fileslice +
    + nibabel.fileutils +
    + nibabel.freesurfer +
    + nibabel.freesurfer.io +
    + nibabel.freesurfer.mghformat +
    + nibabel.funcs +
    + nibabel.gifti +
    + nibabel.gifti.gifti +
    + nibabel.gifti.parse_gifti_fast +
    + nibabel.gifti.util +
    + nibabel.imageclasses +
    + nibabel.imageglobals +
    + nibabel.imagestats +
    + nibabel.loadsave +
    + nibabel.minc1 +
    + nibabel.minc2 +
    + nibabel.mriutils +
    + nibabel.nicom +
    + nibabel.nicom.ascconv +
    + nibabel.nicom.csareader +
    + nibabel.nicom.dicomreaders +
    + nibabel.nicom.dicomwrappers +
    + nibabel.nicom.dwiparams +
    + nibabel.nicom.structreader +
    + nibabel.nicom.utils +
    + nibabel.nifti1 +
    + nibabel.nifti2 +
    + nibabel.onetime +
    + nibabel.openers +
    + nibabel.optpkg +
    + nibabel.orientations +
    + nibabel.parrec +
    + nibabel.pointset +
    + nibabel.processing +
    + nibabel.pydicom_compat +
    + nibabel.quaternions +
    + nibabel.rstutils +
    + nibabel.spaces +
    + nibabel.spatialimages +
    + nibabel.spm2analyze +
    + nibabel.spm99analyze +
    + nibabel.streamlines +
    + nibabel.streamlines.array_sequence +
    + nibabel.streamlines.header +
    + nibabel.streamlines.tck +
    + nibabel.streamlines.tractogram +
    + nibabel.streamlines.tractogram_file +
    + nibabel.streamlines.trk +
    + nibabel.streamlines.utils +
    + nibabel.tmpdirs +
    + nibabel.tripwire +
    + nibabel.viewers +
    + nibabel.volumeutils +
    + nibabel.wrapstruct +
    + nibabel.xmlutils +
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/index.html b/reference/index.html new file mode 100644 index 0000000000..1a5a02fd45 --- /dev/null +++ b/reference/index.html @@ -0,0 +1,3323 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

API ReferenceΒΆ

+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel._compression.html b/reference/nibabel._compression.html new file mode 100644 index 0000000000..24798d28fc --- /dev/null +++ b/reference/nibabel._compression.html @@ -0,0 +1,116 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

_compressionΒΆ

+

Constants and types for dealing transparently with compression

+ + + +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.affines.html b/reference/nibabel.affines.html new file mode 100644 index 0000000000..abe1c104c8 --- /dev/null +++ b/reference/nibabel.affines.html @@ -0,0 +1,554 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

affinesΒΆ

+

Utility routines for working with points and affine transforms

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

AffineError

Errors in calculating or using affines

append_diag(aff,Β steps[,Β starts])

Add diagonal elements steps and translations starts to affine

apply_affine(aff,Β pts[,Β inplace])

Apply affine matrix aff to points pts

dot_reduce(*args)

Apply numpy dot product function from right to left on arrays

from_matvec(matrix[,Β vector])

Combine a matrix and vector into an homogeneous affine

obliquity(affine)

Estimate the obliquity an affine's axes represent

rescale_affine(affine,Β shape,Β zooms[,Β new_shape])

Return a new affine matrix with updated voxel sizes (zooms)

to_matvec(transform)

Split a transform into its matrix and vector components

voxel_sizes(affine)

Return voxel size for each input axis given affine

+
+

AffineErrorΒΆ

+
+
+class nibabel.affines.AffineErrorΒΆ
+

Bases: ValueError

+

Errors in calculating or using affines

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

append_diagΒΆ

+
+
+nibabel.affines.append_diag(aff, steps, starts=())ΒΆ
+

Add diagonal elements steps and translations starts to affine

+

Typical use is in expanding 4x4 affines to larger dimensions. Nipy is the +main consumer because it uses NxM affines, whereas we generally only use +4x4 affines; the routine is here for convenience.

+
+
Parameters:
+
+
aff2D array

N by M affine matrix

+
+
stepsscalar or sequence

diagonal elements to append.

+
+
startsscalar or sequence

elements to append to last column of aff, representing translations +corresponding to the steps. If empty, expands to a vector of zeros +of the same length as steps

+
+
+
+
Returns:
+
+
aff_plus2D array

Now P by Q where L = len(steps) and P == N+L, Q=N+L

+
+
+
+
+

Examples

+
>>> aff = np.eye(4)
+>>> aff[:3,:3] = np.arange(9).reshape((3,3))
+>>> append_diag(aff, [9, 10], [99,100])
+array([[  0.,   1.,   2.,   0.,   0.,   0.],
+       [  3.,   4.,   5.,   0.,   0.,   0.],
+       [  6.,   7.,   8.,   0.,   0.,   0.],
+       [  0.,   0.,   0.,   9.,   0.,  99.],
+       [  0.,   0.,   0.,   0.,  10., 100.],
+       [  0.,   0.,   0.,   0.,   0.,   1.]])
+
+
+
+ +
+
+

apply_affineΒΆ

+
+
+nibabel.affines.apply_affine(aff, pts, inplace=False)ΒΆ
+

Apply affine matrix aff to points pts

+

Returns result of application of aff to the right of pts. The +coordinate dimension of pts should be the last.

+

For the 3D case, aff will be shape (4,4) and pts will have final axis +length 3 - maybe it will just be N by 3. The return value is the +transformed points, in this case:

+
res = np.dot(aff[:3,:3], pts.T) + aff[:3,3:4]
+transformed_pts = res.T
+
+
+

This routine is more general than 3D, in that aff can have any shape +(N,N), and pts can have any shape, as long as the last dimension is for +the coordinates, and is therefore length N-1.

+
+
Parameters:
+
+
aff(N, N) array-like

Homogeneous affine, for 3D points, will be 4 by 4. Contrary to first +appearance, the affine will be applied on the left of pts.

+
+
pts(…, N-1) array-like

Points, where the last dimension contains the coordinates of each +point. For 3D, the last dimension will be length 3.

+
+
inplacebool, optional

If True, attempt to apply the affine directly to pts. +If False, or in-place application fails, a freshly allocated +array will be returned.

+
+
+
+
Returns:
+
+
transformed_pts(…, N-1) array

transformed points

+
+
+
+
+

Examples

+
>>> aff = np.array([[0,2,0,10],[3,0,0,11],[0,0,4,12],[0,0,0,1]])
+>>> pts = np.array([[1,2,3],[2,3,4],[4,5,6],[6,7,8]])
+>>> apply_affine(aff, pts) 
+array([[14, 14, 24],
+       [16, 17, 28],
+       [20, 23, 36],
+       [24, 29, 44]]...)
+
+
+

Just to show that in the simple 3D case, it is equivalent to:

+
>>> (np.dot(aff[:3,:3], pts.T) + aff[:3,3:4]).T 
+array([[14, 14, 24],
+       [16, 17, 28],
+       [20, 23, 36],
+       [24, 29, 44]]...)
+
+
+

But pts can be a more complicated shape:

+
>>> pts = pts.reshape((2,2,3))
+>>> apply_affine(aff, pts) 
+array([[[14, 14, 24],
+        [16, 17, 28]],
+
+       [[20, 23, 36],
+        [24, 29, 44]]]...)
+
+
+
+ +
+
+

dot_reduceΒΆ

+
+
+nibabel.affines.dot_reduce(*args)ΒΆ
+

Apply numpy dot product function from right to left on arrays

+

For passed arrays \(A, B, C, ... Z\) returns \(A \dot B \dot C ... +\dot Z\) where β€œ.” is the numpy array dot product.

+
+
Parameters:
+
+
**argsarrays

Arrays that can be passed to numpy dot function

+
+
+
+
Returns:
+
+
dot_productarray

If there are N arguments, result of arg[0].dot(arg[1].dot(arg[2].dot +...  arg[N-2].dot(arg[N-1])))...

+
+
+
+
+
+ +
+
+

from_matvecΒΆ

+
+
+nibabel.affines.from_matvec(matrix, vector=None)ΒΆ
+

Combine a matrix and vector into an homogeneous affine

+

Combine a rotation / scaling / shearing matrix and translation vector into +a transform in homogeneous coordinates.

+
+
Parameters:
+
+
matrixarray-like

An NxM array representing the the linear part of the transform. +A transform from an M-dimensional space to an N-dimensional space.

+
+
vectorNone or array-like, optional

None or an (N,) array representing the translation. None corresponds to +an (N,) array of zeros.

+
+
+
+
Returns:
+
+
xformarray

An (N+1, M+1) homogeneous transform matrix.

+
+
+
+
+
+

See also

+
+
to_matvec
+
+
+

Examples

+
>>> from_matvec(np.diag([2, 3, 4]), [9, 10, 11])
+array([[ 2,  0,  0,  9],
+       [ 0,  3,  0, 10],
+       [ 0,  0,  4, 11],
+       [ 0,  0,  0,  1]])
+
+
+

The vector argument is optional:

+
>>> from_matvec(np.diag([2, 3, 4]))
+array([[2, 0, 0, 0],
+       [0, 3, 0, 0],
+       [0, 0, 4, 0],
+       [0, 0, 0, 1]])
+
+
+
+ +
+
+

obliquityΒΆ

+
+
+nibabel.affines.obliquity(affine)ΒΆ
+

Estimate the obliquity an affine’s axes represent

+

The term obliquity is defined here as the rotation of those axes with +respect to the cardinal axes. +This implementation is inspired by AFNI’s implementation. +For further details about obliquity, check AFNI’s documentation.

+
+
Parameters:
+
+
affine2D array-like

Affine transformation array. Usually shape (4, 4), but can be any 2D +array.

+
+
+
+
Returns:
+
+
angles1D array-like

The obliquity of each axis with respect to the cardinal axes, in radians.

+
+
+
+
+
+ +
+
+

rescale_affineΒΆ

+
+
+nibabel.affines.rescale_affine(affine, shape, zooms, new_shape=None)ΒΆ
+

Return a new affine matrix with updated voxel sizes (zooms)

+

This function preserves the rotations and shears of the original +affine, as well as the RAS location of the central voxel of the +image.

+
+
Parameters:
+
+
affine(N, N) array-like

NxN transform matrix in homogeneous coordinates representing an affine +transformation from an (N-1)-dimensional space to an (N-1)-dimensional +space. An example is a 4x4 transform representing rotations and +translations in 3 dimensions.

+
+
shape(N-1,) array-like

The extent of the (N-1) dimensions of the original space

+
+
zooms(N-1,) array-like

The size of voxels of the output affine

+
+
new_shape(N-1,) array-like, optional

The extent of the (N-1) dimensions of the space described by the +new affine. If None, use shape.

+
+
+
+
Returns:
+
+
affine(N, N) array

A new affine transform with the specified voxel sizes

+
+
+
+
+
+ +
+
+

to_matvecΒΆ

+
+
+nibabel.affines.to_matvec(transform)ΒΆ
+

Split a transform into its matrix and vector components

+

The transformation must be represented in homogeneous coordinates and is +split into its rotation matrix and translation vector components.

+
+
Parameters:
+
+
transformarray-like

NxM transform matrix in homogeneous coordinates representing an affine +transformation from an (N-1)-dimensional space to an (M-1)-dimensional +space. An example is a 4x4 transform representing rotations and +translations in 3 dimensions. A 4x3 matrix can represent a +2-dimensional plane embedded in 3 dimensional space.

+
+
+
+
Returns:
+
+
matrix(N-1, M-1) array

Matrix component of transform

+
+
vector(M-1,) array

Vector component of transform

+
+
+
+
+
+

See also

+
+
from_matvec
+
+
+

Examples

+
>>> aff = np.diag([2, 3, 4, 1])
+>>> aff[:3,3] = [9, 10, 11]
+>>> to_matvec(aff)
+(array([[2, 0, 0],
+       [0, 3, 0],
+       [0, 0, 4]]), array([ 9, 10, 11]))
+
+
+
+ +
+
+

voxel_sizesΒΆ

+
+
+nibabel.affines.voxel_sizes(affine)ΒΆ
+

Return voxel size for each input axis given affine

+

The affine is the mapping between array (voxel) coordinates and mm +(world) coordinates.

+

The voxel size for the first voxel (array) axis is the distance moved in +world coordinates when moving one unit along the first voxel (array) axis. +This is the distance between the world coordinate of voxel (0, 0, 0) and +the world coordinate of voxel (1, 0, 0). The world coordinate vector of +voxel coordinate vector (0, 0, 0) is given by v0 = affine.dot((0, 0, 0, +1)[:3]. The world coordinate vector of voxel vector (1, 0, 0) is +v1_ax1 = affine.dot((1, 0, 0, 1))[:3]. The final 1 in the voxel +vectors and the [:3] at the end are because the affine works on +homogeneous coordinates. The translations part of the affine is trans = +affine[:3, 3], and the rotations, zooms and shearing part of the affine +is rzs = affine[:3, :3]. Because of the final 1 in the input voxel +vector, v0 == rzs.dot((0, 0, 0)) + trans, and v1_ax1 == rzs.dot((1, +0, 0)) + trans, and the difference vector is rzs.dot((0, 0, 0)) - +rzs.dot((1, 0, 0)) == rzs.dot((1, 0, 0)) == rzs[:, 0]. The distance +vectors in world coordinates between (0, 0, 0) and (1, 0, 0), (0, 1, 0), +(0, 0, 1) are given by rzs.dot(np.eye(3)) = rzs. The voxel sizes are +the Euclidean lengths of the distance vectors. So, the voxel sizes are +the Euclidean lengths of the columns of the affine (excluding the last row +and column of the affine).

+
+
Parameters:
+
+
affine2D array-like

Affine transformation array. Usually shape (4, 4), but can be any 2D +array.

+
+
+
+
Returns:
+
+
vox_sizes1D array

Voxel sizes for each input axis of affine. Usually 1D array length 3, +but in general has length (N-1) where input affine is shape (M, N).

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.analyze.html b/reference/nibabel.analyze.html new file mode 100644 index 0000000000..13cb8a37ce --- /dev/null +++ b/reference/nibabel.analyze.html @@ -0,0 +1,993 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

analyzeΒΆ

+

Read / write access to the basic Mayo Analyze format

+
+

The Analyze header formatΒΆ

+

This is a binary header format and inherits from WrapStruct

+

Apart from the attributes and methods of WrapStruct:

+

Class attributes are:

+
.default_x_flip
+
+
+

with methods:

+
.get/set_data_shape
+.get/set_data_dtype
+.get/set_zooms
+.get/set_data_offset
+.get_base_affine()
+.get_best_affine()
+.data_to_fileobj
+.data_from_fileobj
+
+
+

and class methods:

+
.from_header(hdr)
+
+
+

More sophisticated headers can add more methods and attributes.

+
+

NotesΒΆ

+

This - basic - analyze header cannot encode full affines (only +diagonal affines), and cannot do integer scaling.

+

The inability to store affines means that we have to guess what orientation the +image has. Most Analyze images are stored on disk in (fastest-changing to +slowest-changing) R->L, P->A and I->S order. That is, the first voxel is the +rightmost, most posterior and most inferior voxel location in the image, and +the next voxel is one voxel towards the left of the image.

+

Most people refer to this disk storage format as β€˜radiological’, on the basis +that, if you load up the data as an array img_arr where the first axis is +the fastest changing, then take a slice in the I->S axis - img_arr[:,:,10] +- then the right part of the brain will be on the left of your displayed slice. +Radiologists like looking at images where the left of the brain is on the right +side of the image.

+

Conversely, if the image has the voxels stored with the left voxels first - +L->R, P->A, I->S, then this would be β€˜neurological’ format. Neurologists like +looking at images where the left side of the brain is on the left of the image.

+

When we are guessing at an affine for Analyze, this translates to the problem +of whether the affine should consider proceeding within the data down an X line +as being from left to right, or right to left.

+

By default we assume that the image is stored in R->L format. We encode this +choice in the default_x_flip flag that can be True or False. True means +assume radiological.

+

If the image is 3D, and the X, Y and Z zooms are x, y, and z, then:

+
if default_x_flip is True::
+    affine = np.diag((-x,y,z,1))
+else:
+    affine = np.diag((x,y,z,1))
+
+
+

In our implementation, there is no way of saving this assumed flip into the +header. One way of doing this, that we have not used, is to allow negative +zooms, in particular, negative X zooms. We did not do this because the image +can be loaded with and without a default flip, so the saved zoom will not +constrain the affine.

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

AnalyzeHeader([binaryblock,Β endianness,Β check])

Class for basic analyze header

AnalyzeImage(dataobj,Β affine[,Β header,Β ...])

Class for basic Analyze format image

+
+

AnalyzeHeaderΒΆ

+
+
+class nibabel.analyze.AnalyzeHeader(binaryblock=None, endianness=None, check=True)ΒΆ
+

Bases: LabeledWrapStruct, SpatialHeader

+

Class for basic analyze header

+

Implements zoom-only setting of affine transform, and no image +scaling

+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> hdr1 = AnalyzeHeader() # an empty header
+>>> hdr1.endianness == native_code
+True
+>>> hdr1.get_data_shape()
+(0,)
+>>> hdr1.set_data_shape((1,2,3)) # now with some content
+>>> hdr1.get_data_shape()
+(1, 2, 3)
+
+
+

We can set the binary block directly via this initialization. +Here we get it from the header we have just made

+
>>> binblock2 = hdr1.binaryblock
+>>> hdr2 = AnalyzeHeader(binblock2)
+>>> hdr2.get_data_shape()
+(1, 2, 3)
+
+
+

Empty headers are native endian by default

+
>>> hdr2.endianness == native_code
+True
+
+
+

You can pass valid opposite endian headers with the +endianness parameter. Even empty headers can have +endianness

+
>>> hdr3 = AnalyzeHeader(endianness=swapped_code)
+>>> hdr3.endianness == swapped_code
+True
+
+
+

If you do not pass an endianness, and you pass some data, we +will try to guess from the passed data.

+
>>> binblock3 = hdr3.binaryblock
+>>> hdr4 = AnalyzeHeader(binblock3)
+>>> hdr4.endianness == swapped_code
+True
+
+
+
+
+__init__(binaryblock=None, endianness=None, check=True)ΒΆ
+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> hdr1 = AnalyzeHeader() # an empty header
+>>> hdr1.endianness == native_code
+True
+>>> hdr1.get_data_shape()
+(0,)
+>>> hdr1.set_data_shape((1,2,3)) # now with some content
+>>> hdr1.get_data_shape()
+(1, 2, 3)
+
+
+

We can set the binary block directly via this initialization. +Here we get it from the header we have just made

+
>>> binblock2 = hdr1.binaryblock
+>>> hdr2 = AnalyzeHeader(binblock2)
+>>> hdr2.get_data_shape()
+(1, 2, 3)
+
+
+

Empty headers are native endian by default

+
>>> hdr2.endianness == native_code
+True
+
+
+

You can pass valid opposite endian headers with the +endianness parameter. Even empty headers can have +endianness

+
>>> hdr3 = AnalyzeHeader(endianness=swapped_code)
+>>> hdr3.endianness == swapped_code
+True
+
+
+

If you do not pass an endianness, and you pass some data, we +will try to guess from the passed data.

+
>>> binblock3 = hdr3.binaryblock
+>>> hdr4 = AnalyzeHeader(binblock3)
+>>> hdr4.endianness == swapped_code
+True
+
+
+
+ +
+
+as_analyze_map()ΒΆ
+

Return header as mapping for conversion to Analyze types

+

Collect data from custom header type to fill in fields for Analyze and +derived header types (such as Nifti1 and Nifti2).

+

When Analyze types convert another header type to their own type, they +call this this method to check if there are other Analyze / Nifti +fields that the source header would like to set.

+
+
Returns:
+
+
analyze_mapmapping

Object that can be used as a mapping thus:

+
for key in analyze_map:
+    value = analyze_map[key]
+
+
+

where key is the name of a field that can be set in an Analyze +header type, such as Nifti1, and value is a value for the +field. For example, analyze_map might be a something like +dict(regular='y', slice_duration=0.3) where regular is a +field present in both Analyze and Nifti1, and slice_duration is +a field restricted to Nifti1 and Nifti2. If a particular Analyze +header type does not recognize the field name, it will throw away +the value without error. See Analyze.from_header().

+
+
+
+
+

Notes

+

You can also return a Nifti header with the relevant fields set.

+

Your header still needs methods get_data_dtype, get_data_shape +and get_zooms, for the conversion, and these get called after +using the analyze map, so the methods will override values set in the +map.

+
+ +
+
+data_from_fileobj(fileobj)ΒΆ
+

Read scaled data array from fileobj

+

Use this routine to get the scaled image data from an image file +fileobj, given a header self. β€œScaled” means, with any header +scaling factors applied to the raw data in the file. Use +raw_data_from_fileobj to get the raw data.

+
+
Parameters:
+
+
fileobjfile-like

Must be open, and implement read and seek methods

+
+
+
+
Returns:
+
+
arrndarray

scaled data array

+
+
+
+
+

Notes

+

We use the header to get any scale or intercept values to apply to the +data. Raw Analyze files don’t have scale factors or intercepts, but +this routine also works with formats based on Analyze, that do have +scaling, such as SPM analyze formats and NIfTI.

+
+ +
+
+data_to_fileobj(data, fileobj, rescale=True)ΒΆ
+

Write data to fileobj, maybe rescaling data, modifying self

+

In writing the data, we match the header to the written data, by +setting the header scaling factors, iff rescale is True. Thus we +modify self in the process of writing the data.

+
+
Parameters:
+
+
dataarray-like

data to write; should match header defined shape

+
+
fileobjfile-like object

Object with file interface, implementing write and +seek

+
+
rescale{True, False}, optional

Whether to try and rescale data to match output dtype specified by +header. If True and scaling needed and header cannot scale, then +raise HeaderTypeError.

+
+
+
+
+

Examples

+
>>> from nibabel.analyze import AnalyzeHeader
+>>> hdr = AnalyzeHeader()
+>>> hdr.set_data_shape((1, 2, 3))
+>>> hdr.set_data_dtype(np.float64)
+>>> from io import BytesIO
+>>> str_io = BytesIO()
+>>> data = np.arange(6).reshape(1,2,3)
+>>> hdr.data_to_fileobj(data, str_io)
+>>> data.astype(np.float64).tobytes('F') == str_io.getvalue()
+True
+
+
+
+ +
+
+classmethod default_structarr(endianness=None)ΒΆ
+

Return header data for empty header with given endianness

+
+ +
+
+default_x_flip: bool = TrueΒΆ
+
+ +
+
+classmethod from_header(header=None, check=True)ΒΆ
+

Class method to create header from another header

+
+
Parameters:
+
+
headerHeader instance or mapping

a header of this class, or another class of header for +conversion to this type

+
+
check{True, False}

whether to check header for integrity

+
+
+
+
Returns:
+
+
hdrheader instance

fresh header instance of our own class

+
+
+
+
+
+ +
+
+get_base_affine()ΒΆ
+

Get affine from basic (shared) header fields

+

Note that we get the translations from the center of the +image.

+

Examples

+
>>> hdr = AnalyzeHeader()
+>>> hdr.set_data_shape((3, 5, 7))
+>>> hdr.set_zooms((3, 2, 1))
+>>> hdr.default_x_flip
+True
+>>> hdr.get_base_affine() # from center of image
+array([[-3.,  0.,  0.,  3.],
+       [ 0.,  2.,  0., -4.],
+       [ 0.,  0.,  1., -3.],
+       [ 0.,  0.,  0.,  1.]])
+
+
+
+ +
+
+get_best_affine()ΒΆ
+

Get affine from basic (shared) header fields

+

Note that we get the translations from the center of the +image.

+

Examples

+
>>> hdr = AnalyzeHeader()
+>>> hdr.set_data_shape((3, 5, 7))
+>>> hdr.set_zooms((3, 2, 1))
+>>> hdr.default_x_flip
+True
+>>> hdr.get_base_affine() # from center of image
+array([[-3.,  0.,  0.,  3.],
+       [ 0.,  2.,  0., -4.],
+       [ 0.,  0.,  1., -3.],
+       [ 0.,  0.,  0.,  1.]])
+
+
+
+ +
+
+get_data_dtype()ΒΆ
+

Get numpy dtype for data

+

For examples see set_data_dtype

+
+ +
+
+get_data_offset()ΒΆ
+

Return offset into data file to read data

+

Examples

+
>>> hdr = AnalyzeHeader()
+>>> hdr.get_data_offset()
+0
+>>> hdr['vox_offset'] = 12
+>>> hdr.get_data_offset()
+12
+
+
+
+ +
+
+get_data_shape()ΒΆ
+

Get shape of data

+

Examples

+
>>> hdr = AnalyzeHeader()
+>>> hdr.get_data_shape()
+(0,)
+>>> hdr.set_data_shape((1,2,3))
+>>> hdr.get_data_shape()
+(1, 2, 3)
+
+
+

Expanding number of dimensions gets default zooms

+
>>> hdr.get_zooms()
+(1.0, 1.0, 1.0)
+
+
+
+ +
+
+get_slope_inter()ΒΆ
+

Get scalefactor and intercept

+

These are not implemented for basic Analyze

+
+ +
+
+get_zooms()ΒΆ
+

Get zooms from header

+
+
Returns:
+
+
ztuple

tuple of header zoom values

+
+
+
+
+

Examples

+
>>> hdr = AnalyzeHeader()
+>>> hdr.get_zooms()
+(1.0,)
+>>> hdr.set_data_shape((1,2))
+>>> hdr.get_zooms()
+(1.0, 1.0)
+>>> hdr.set_zooms((3, 4))
+>>> hdr.get_zooms()
+(3.0, 4.0)
+
+
+
+ +
+
+classmethod guessed_endian(hdr)ΒΆ
+

Guess intended endianness from mapping-like hdr

+
+
Parameters:
+
+
hdrmapping-like

hdr for which to guess endianness

+
+
+
+
Returns:
+
+
endianness{β€˜<’, β€˜>’}

Guessed endianness of header

+
+
+
+
+

Examples

+

Zeros header, no information, guess native

+
>>> hdr = AnalyzeHeader()
+>>> hdr_data = np.zeros((), dtype=header_dtype)
+>>> AnalyzeHeader.guessed_endian(hdr_data) == native_code
+True
+
+
+

A valid native header is guessed native

+
>>> hdr_data = hdr.structarr.copy()
+>>> AnalyzeHeader.guessed_endian(hdr_data) == native_code
+True
+
+
+

And, when swapped, is guessed as swapped

+
>>> sw_hdr_data = hdr_data.byteswap(swapped_code)
+>>> AnalyzeHeader.guessed_endian(sw_hdr_data) == swapped_code
+True
+
+
+

The algorithm is as follows:

+

First, look at the first value in the dim field; this +should be between 0 and 7. If it is between 1 and 7, then +this must be a native endian header.

+
>>> hdr_data = np.zeros((), dtype=header_dtype) # blank binary data
+>>> hdr_data['dim'][0] = 1
+>>> AnalyzeHeader.guessed_endian(hdr_data) == native_code
+True
+>>> hdr_data['dim'][0] = 6
+>>> AnalyzeHeader.guessed_endian(hdr_data) == native_code
+True
+>>> hdr_data['dim'][0] = -1
+>>> AnalyzeHeader.guessed_endian(hdr_data) == swapped_code
+True
+
+
+

If the first dim value is zeros, we need a tie breaker. +In that case we check the sizeof_hdr field. This should +be 348. If it looks like the byteswapped value of 348, +assumed swapped. Otherwise assume native.

+
>>> hdr_data = np.zeros((), dtype=header_dtype) # blank binary data
+>>> AnalyzeHeader.guessed_endian(hdr_data) == native_code
+True
+>>> hdr_data['sizeof_hdr'] = 1543569408
+>>> AnalyzeHeader.guessed_endian(hdr_data) == swapped_code
+True
+>>> hdr_data['sizeof_hdr'] = -1
+>>> AnalyzeHeader.guessed_endian(hdr_data) == native_code
+True
+
+
+

This is overridden by the dim[0] value though:

+
>>> hdr_data['sizeof_hdr'] = 1543569408
+>>> hdr_data['dim'][0] = 1
+>>> AnalyzeHeader.guessed_endian(hdr_data) == native_code
+True
+
+
+
+ +
+
+has_data_intercept = FalseΒΆ
+
+ +
+
+has_data_slope = FalseΒΆ
+
+ +
+
+classmethod may_contain_header(binaryblock)ΒΆ
+
+ +
+
+raw_data_from_fileobj(fileobj)ΒΆ
+

Read unscaled data array from fileobj

+
+
Parameters:
+
+
fileobjfile-like

Must be open, and implement read and seek methods

+
+
+
+
Returns:
+
+
arrndarray

unscaled data array

+
+
+
+
+
+ +
+
+set_data_dtype(datatype)ΒΆ
+

Set numpy dtype for data from code or dtype or type

+

Examples

+
>>> hdr = AnalyzeHeader()
+>>> hdr.set_data_dtype(np.uint8)
+>>> hdr.get_data_dtype()
+dtype('uint8')
+>>> hdr.set_data_dtype(np.dtype(np.uint8))
+>>> hdr.get_data_dtype()
+dtype('uint8')
+>>> hdr.set_data_dtype('implausible') 
+Traceback (most recent call last):
+   ...
+HeaderDataError: data dtype "implausible" not recognized
+>>> hdr.set_data_dtype('none') 
+Traceback (most recent call last):
+   ...
+HeaderDataError: data dtype "none" known but not supported
+>>> hdr.set_data_dtype(np.void) 
+Traceback (most recent call last):
+   ...
+HeaderDataError: data dtype "<type 'numpy.void'>" known but not supported
+
+
+
+ +
+
+set_data_offset(offset)ΒΆ
+

Set offset into data file to read data

+
+ +
+
+set_data_shape(shape)ΒΆ
+

Set shape of data

+

If ndims == len(shape) then we set zooms for dimensions higher than +ndims to 1.0

+
+
Parameters:
+
+
shapesequence

sequence of integers specifying data array shape

+
+
+
+
+
+ +
+
+set_slope_inter(slope, inter=None)ΒΆ
+

Set slope and / or intercept into header

+

Set slope and intercept for image data, such that, if the image +data is arr, then the scaled image data will be (arr * +slope) + inter

+

In this case, for Analyze images, we can’t store the slope or the +intercept, so this method only checks that slope is None or NaN or +1.0, and that inter is None or NaN or 0.

+
+
Parameters:
+
+
slopeNone or float

If float, value must be NaN or 1.0 or we raise a HeaderTypeError

+
+
interNone or float, optional

If float, value must be 0.0 or we raise a HeaderTypeError

+
+
+
+
+
+ +
+
+set_zooms(zooms)ΒΆ
+

Set zooms into header fields

+

See docstring for get_zooms for examples

+
+ +
+
+sizeof_hdr = 348ΒΆ
+
+ +
+
+template_dtype = dtype([('sizeof_hdr', '<i4'), ('data_type', 'S10'), ('db_name', 'S18'), ('extents', '<i4'), ('session_error', '<i2'), ('regular', 'S1'), ('hkey_un0', 'S1'), ('dim', '<i2', (8,)), ('vox_units', 'S4'), ('cal_units', 'S8'), ('unused1', '<i2'), ('datatype', '<i2'), ('bitpix', '<i2'), ('dim_un0', '<i2'), ('pixdim', '<f4', (8,)), ('vox_offset', '<f4'), ('funused1', '<f4'), ('funused2', '<f4'), ('funused3', '<f4'), ('cal_max', '<f4'), ('cal_min', '<f4'), ('compressed', '<i4'), ('verified', '<i4'), ('glmax', '<i4'), ('glmin', '<i4'), ('descrip', 'S80'), ('aux_file', 'S24'), ('orient', 'S1'), ('originator', 'S10'), ('generated', 'S10'), ('scannum', 'S10'), ('patient_id', 'S10'), ('exp_date', 'S10'), ('exp_time', 'S10'), ('hist_un0', 'S3'), ('views', '<i4'), ('vols_added', '<i4'), ('start_field', '<i4'), ('field_skip', '<i4'), ('omax', '<i4'), ('omin', '<i4'), ('smax', '<i4'), ('smin', '<i4')])ΒΆ
+
+ +
+ +
+
+

AnalyzeImageΒΆ

+
+
+class nibabel.analyze.AnalyzeImage(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Bases: SpatialImage

+

Class for basic Analyze format image

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+ImageArrayProxyΒΆ
+

alias of ArrayProxy

+
+ +
+
+files_types: tuple[tuple[str, str], ...] = (('image', '.img'), ('header', '.hdr'))ΒΆ
+
+ +
+
+classmethod from_file_map(file_map, *, mmap=True, keep_file_open=None)ΒΆ
+

Class method to create image from mapping in file_map

+
+
Parameters:
+
+
file_mapdict

Mapping with (kay, value) pairs of (file_type, FileHolder +instance giving file-likes for each file needed for this image +type.

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_map refers to an open file handle, this setting has no +effect. The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
Returns:
+
+
imgAnalyzeImage instance
+
+
+
+
+ +
+
+get_data_dtype()ΒΆ
+
+ +
+
+header_classΒΆ
+

alias of AnalyzeHeader

+
+ +
+
+makeable: bool = TrueΒΆ
+
+ +
+
+rw: bool = TrueΒΆ
+
+ +
+
+set_data_dtype(dtype)ΒΆ
+
+ +
+
+to_file_map(file_map=None, dtype=None)ΒΆ
+

Write image to file_map or contained self.file_map

+
+
Parameters:
+
+
file_mapNone or mapping, optional

files mapping. If None (default) use object’s file_map +attribute instead

+
+
dtypedtype-like, optional

The on-disk data type to coerce the data array.

+
+
+
+
+
+ +
+
+valid_exts: tuple[str, ...] = ('.img', '.hdr')ΒΆ
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.arrayproxy.html b/reference/nibabel.arrayproxy.html new file mode 100644 index 0000000000..5971b8d96b --- /dev/null +++ b/reference/nibabel.arrayproxy.html @@ -0,0 +1,432 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

arrayproxyΒΆ

+

Array proxy base class

+

The proxy API is - at minimum:

+
    +
  • The object has a read-only attribute shape

  • +
  • read only is_proxy attribute / property set to True

  • +
  • the object returns the data array from np.asarray(prox)

  • +
  • returns array slice from prox[<slice_spec>] where <slice_spec> is any +ndarray slice specification that does not use numpy β€˜advanced indexing’.

  • +
  • modifying no object outside obj will affect the result of +np.asarray(obj). Specifically:

    +
      +
    • Changes in position (obj.tell()) of passed file-like objects will +not affect the output of from np.asarray(proxy).

    • +
    • if you pass a header into the __init__, then modifying the original +header will not affect the result of the array return.

    • +
    +
  • +
+

See nibabel.tests.test_proxy_api for proxy API conformance checks.

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

ArrayLike(*args,Β **kwargs)

Protocol for numpy ndarray-like objects

ArrayProxy(file_like,Β spec,Β *[,Β mmap,Β ...])

Class to act as proxy for the array that can be read from a file

get_obj_dtype(obj)

Get the effective dtype of an array-like object

is_proxy(obj)

Return True if obj is an array proxy

reshape_dataobj(obj,Β shape)

Use obj reshape method if possible, else numpy reshape function

+
+

ArrayLikeΒΆ

+
+
+class nibabel.arrayproxy.ArrayLike(*args, **kwargs)ΒΆ
+

Bases: Protocol

+

Protocol for numpy ndarray-like objects

+

This is more stringent than numpy.typing.ArrayLike, but guarantees +access to shape, ndim and slicing.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+property ndim: intΒΆ
+
+ +
+
+shape: tuple[int, ...]ΒΆ
+
+ +
+ +
+
+

ArrayProxyΒΆ

+
+
+class nibabel.arrayproxy.ArrayProxy(file_like, spec, *, mmap=True, order=None, keep_file_open=None)ΒΆ
+

Bases: ArrayLike

+

Class to act as proxy for the array that can be read from a file

+

The array proxy allows us to freeze the passed fileobj and header such that +it returns the expected data array.

+

This implementation assumes a contiguous array in the file object, with one +of the numpy dtypes, starting at a given file position offset with +single slope and intercept scaling to produce output values.

+

The class __init__ requires a spec which defines how the data will be +read and rescaled. The spec may be a tuple of length 2 - 5, containing the +shape, storage dtype, offset, slope and intercept, or a header object +with methods:

+
    +
  • get_data_shape

  • +
  • get_data_dtype

  • +
  • get_data_offset

  • +
  • get_slope_inter

  • +
+

A header should also have a β€˜copy’ method. This requirement will go away +when the deprecated β€˜header’ property goes away.

+

This implementation allows us to deal with Analyze and its variants, +including Nifti1, and with the MGH format.

+

Other image types might need more specific classes to implement the API. +See nibabel.minc1, nibabel.ecat and nibabel.parrec for +examples.

+

Initialize array proxy instance

+
+
Parameters:
+
+
file_likeobject

File-like object or filename. If file-like object, should implement +at least read and seek.

+
+
specobject or tuple

Tuple must have length 2-5, with the following values:

+
    +
  1. shape: tuple - tuple of ints describing shape of data;

  2. +
  3. storage_dtype: dtype specifier - dtype of array inside proxied +file, or input to numpy.dtype to specify array dtype;

  4. +
  5. offset: int - offset, in bytes, of data array from start of file +(default: 0);

  6. +
  7. slope: float - scaling factor for resulting data (default: 1.0);

  8. +
  9. inter: float - intercept for rescaled data (default: 0.0).

  10. +
+

OR

+

Header object implementing get_data_shape, get_data_dtype, +get_data_offset, get_slope_inter

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading data. +If False, do not try numpy memmap for data array. If one of +{β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A mmap value of +True gives the same behavior as mmap='c'. If file_like +cannot be memory-mapped, ignore mmap value and read array from +file.

+
+
order{None, β€˜F’, β€˜C’}, optional, keyword only

order controls the order of the data array layout. Fortran-style, +column-major order may be indicated with β€˜F’, and C-style, row-major +order may be indicated with β€˜C’. None gives the default order, that +comes from the _default_order class variable.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_like is an open file handle, this setting has no +effect. The default value (None) will result in the value of +KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
+
+
+__init__(file_like, spec, *, mmap=True, order=None, keep_file_open=None)ΒΆ
+

Initialize array proxy instance

+
+
Parameters:
+
+
file_likeobject

File-like object or filename. If file-like object, should implement +at least read and seek.

+
+
specobject or tuple

Tuple must have length 2-5, with the following values:

+
    +
  1. shape: tuple - tuple of ints describing shape of data;

  2. +
  3. storage_dtype: dtype specifier - dtype of array inside proxied +file, or input to numpy.dtype to specify array dtype;

  4. +
  5. offset: int - offset, in bytes, of data array from start of file +(default: 0);

  6. +
  7. slope: float - scaling factor for resulting data (default: 1.0);

  8. +
  9. inter: float - intercept for rescaled data (default: 0.0).

  10. +
+

OR

+

Header object implementing get_data_shape, get_data_dtype, +get_data_offset, get_slope_inter

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading data. +If False, do not try numpy memmap for data array. If one of +{β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A mmap value of +True gives the same behavior as mmap='c'. If file_like +cannot be memory-mapped, ignore mmap value and read array from +file.

+
+
order{None, β€˜F’, β€˜C’}, optional, keyword only

order controls the order of the data array layout. Fortran-style, +column-major order may be indicated with β€˜F’, and C-style, row-major +order may be indicated with β€˜C’. None gives the default order, that +comes from the _default_order class variable.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_like is an open file handle, this setting has no +effect. The default value (None) will result in the value of +KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
+
+ +
+
+copy() SelfΒΆ
+

Create a new ArrayProxy for the same file and parameters

+

If the proxied file is an open file handle, the new ArrayProxy +will share a lock with the old one.

+
+ +
+
+property dtypeΒΆ
+
+ +
+
+get_unscaled()ΒΆ
+

Read data from file

+

This is an optional part of the proxy API

+
+ +
+
+property interΒΆ
+
+ +
+
+property is_proxyΒΆ
+
+ +
+
+property ndimΒΆ
+
+ +
+
+property offsetΒΆ
+
+ +
+
+reshape(shape)ΒΆ
+

Return an ArrayProxy with a new shape, without modifying data

+
+ +
+
+property shapeΒΆ
+
+ +
+
+property slopeΒΆ
+
+ +
+ +
+
+

get_obj_dtypeΒΆ

+
+
+nibabel.arrayproxy.get_obj_dtype(obj)ΒΆ
+

Get the effective dtype of an array-like object

+
+ +
+
+

is_proxyΒΆ

+
+
+nibabel.arrayproxy.is_proxy(obj)ΒΆ
+

Return True if obj is an array proxy

+
+ +
+
+

reshape_dataobjΒΆ

+
+
+nibabel.arrayproxy.reshape_dataobj(obj, shape)ΒΆ
+

Use obj reshape method if possible, else numpy reshape function

+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.arraywriters.html b/reference/nibabel.arraywriters.html new file mode 100644 index 0000000000..cd6dab4d5e --- /dev/null +++ b/reference/nibabel.arraywriters.html @@ -0,0 +1,790 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

arraywritersΒΆ

+

Array writer objects

+

Array writers have init signature:

+
def __init__(self, array, out_dtype=None)
+
+
+

and methods

+
    +
  • scaling_needed() - returns True if array requires scaling for write

  • +
  • finite_range() - returns min, max of self.array

  • +
  • to_fileobj(fileobj, offset=None, order=’F’)

  • +
+

They must have attributes / properties of:

+
    +
  • array

  • +
  • out_dtype

  • +
  • has_nan

  • +
+

They may have attributes:

+
    +
  • slope

  • +
  • inter

  • +
+

They are designed to write arrays to a fileobj with reasonable memory +efficiency.

+

Array writers may be able to scale the array or apply an intercept, or do +something else to make sense of conversions between float and int, or between +larger ints and smaller.

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

ArrayWriter(array[,Β out_dtype])

Initialize array writer

ScalingError

SlopeArrayWriter(array[,Β out_dtype,Β ...])

ArrayWriter that can use scalefactor for writing arrays

SlopeInterArrayWriter(array[,Β out_dtype,Β ...])

Array writer that can use slope and intercept to scale array

WriterError

get_slope_inter(writer)

Return slope, intercept from array writer object

make_array_writer(data,Β out_type[,Β ...])

Make array writer instance for array data and output type out_type

+
+

ArrayWriterΒΆ

+
+
+class nibabel.arraywriters.ArrayWriter(array, out_dtype=None, **kwargs)ΒΆ
+

Bases: object

+

Initialize array writer

+
+
Parameters:
+
+
arrayarray-like

array-like object

+
+
out_dtypeNone or dtype

dtype with which array will be written. For this class, +out_dtype` needs to be the same as the dtype of the input array +or a swapped version of the same.

+
+
**kwargskeyword arguments

This class processes only:

+
    +
  • nan2zero : bool, optional +Whether to set NaN values to 0 when writing integer output. +Defaults to True. If False, NaNs get converted with numpy +astype, and the behavior is undefined. Ignored for floating +point output.

  • +
  • check_scaling : bool, optional +If True, check if scaling needed and raise error if so. Default +is True

  • +
+
+
+
+
+

Examples

+
>>> arr = np.array([0, 255], np.uint8)
+>>> aw = ArrayWriter(arr)
+>>> aw = ArrayWriter(arr, np.int8) 
+Traceback (most recent call last):
+    ...
+WriterError: Scaling needed but cannot scale
+>>> aw = ArrayWriter(arr, np.int8, check_scaling=False)
+
+
+
+
+__init__(array, out_dtype=None, **kwargs)ΒΆ
+

Initialize array writer

+
+
Parameters:
+
+
arrayarray-like

array-like object

+
+
out_dtypeNone or dtype

dtype with which array will be written. For this class, +out_dtype` needs to be the same as the dtype of the input array +or a swapped version of the same.

+
+
**kwargskeyword arguments

This class processes only:

+
    +
  • nan2zero : bool, optional +Whether to set NaN values to 0 when writing integer output. +Defaults to True. If False, NaNs get converted with numpy +astype, and the behavior is undefined. Ignored for floating +point output.

  • +
  • check_scaling : bool, optional +If True, check if scaling needed and raise error if so. Default +is True

  • +
+
+
+
+
+

Examples

+
>>> arr = np.array([0, 255], np.uint8)
+>>> aw = ArrayWriter(arr)
+>>> aw = ArrayWriter(arr, np.int8) 
+Traceback (most recent call last):
+    ...
+WriterError: Scaling needed but cannot scale
+>>> aw = ArrayWriter(arr, np.int8, check_scaling=False)
+
+
+
+ +
+
+property arrayΒΆ
+

Return array from arraywriter

+
+ +
+
+finite_range()ΒΆ
+

Return (maybe cached) finite range of data array

+
+ +
+
+property has_nanΒΆ
+

True if array has NaNs

+
+ +
+
+property out_dtypeΒΆ
+

Return out_dtype from arraywriter

+
+ +
+
+scaling_needed()ΒΆ
+

Checks if scaling is needed for input array

+

Raises WriterError if no scaling possible.

+

The rules are in the code, but:

+
    +
  • If numpy will cast, return False (no scaling needed)

  • +
  • If input or output is an object or structured type, raise

  • +
  • If input is complex, raise

  • +
  • If the output is float, return False

  • +
  • If the input array is all zero, return False

  • +
  • By now we are casting to (u)int. If the input type is a float, return +True (we do need scaling)

  • +
  • Now input and output types are (u)ints. If the min and max in the +data are within range of the output type, return False

  • +
  • Otherwise return True

  • +
+
+ +
+
+to_fileobj(fileobj, order='F')ΒΆ
+

Write array into fileobj

+
+
Parameters:
+
+
fileobjfile-like object
+
order{β€˜F’, β€˜C’}

order (Fortran or C) to which to write array

+
+
+
+
+
+ +
+ +
+
+

ScalingErrorΒΆ

+
+
+class nibabel.arraywriters.ScalingErrorΒΆ
+

Bases: WriterError

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

SlopeArrayWriterΒΆ

+
+
+class nibabel.arraywriters.SlopeArrayWriter(array, out_dtype=None, calc_scale=True, scaler_dtype=<class 'numpy.float32'>, **kwargs)ΒΆ
+

Bases: ArrayWriter

+

ArrayWriter that can use scalefactor for writing arrays

+

The scalefactor allows the array writer to write floats to int output +types, and rescale larger ints to smaller. It can therefore lose +precision.

+

It extends the ArrayWriter class with attribute:

+
    +
  • slope

  • +
+

and methods:

+
    +
  • reset() - reset slope to default (not adapted to self.array)

  • +
  • calc_scale() - calculate slope to best write self.array

  • +
+

Initialize array writer

+
+
Parameters:
+
+
arrayarray-like

array-like object

+
+
out_dtypeNone or dtype

dtype with which array will be written. For this class, +out_dtype` needs to be the same as the dtype of the input array +or a swapped version of the same.

+
+
calc_scale{True, False}, optional

Whether to calculate scaling for writing array on initialization. +If False, then you can calculate this scaling with +obj.calc_scale() - see examples

+
+
scaler_dtypedtype-like, optional

specifier for numpy dtype for scaling

+
+
**kwargskeyword arguments

This class processes only:

+
    +
  • nan2zero : bool, optional +Whether to set NaN values to 0 when writing integer output. +Defaults to True. If False, NaNs get converted with numpy +astype, and the behavior is undefined. Ignored for floating +point output.

  • +
+
+
+
+
+

Examples

+
>>> arr = np.array([0, 254], np.uint8)
+>>> aw = SlopeArrayWriter(arr)
+>>> aw.slope
+1.0
+>>> aw = SlopeArrayWriter(arr, np.int8)
+>>> aw.slope
+2.0
+>>> aw = SlopeArrayWriter(arr, np.int8, calc_scale=False)
+>>> aw.slope
+1.0
+>>> aw.calc_scale()
+>>> aw.slope
+2.0
+
+
+
+
+__init__(array, out_dtype=None, calc_scale=True, scaler_dtype=<class 'numpy.float32'>, **kwargs)ΒΆ
+

Initialize array writer

+
+
Parameters:
+
+
arrayarray-like

array-like object

+
+
out_dtypeNone or dtype

dtype with which array will be written. For this class, +out_dtype` needs to be the same as the dtype of the input array +or a swapped version of the same.

+
+
calc_scale{True, False}, optional

Whether to calculate scaling for writing array on initialization. +If False, then you can calculate this scaling with +obj.calc_scale() - see examples

+
+
scaler_dtypedtype-like, optional

specifier for numpy dtype for scaling

+
+
**kwargskeyword arguments

This class processes only:

+
    +
  • nan2zero : bool, optional +Whether to set NaN values to 0 when writing integer output. +Defaults to True. If False, NaNs get converted with numpy +astype, and the behavior is undefined. Ignored for floating +point output.

  • +
+
+
+
+
+

Examples

+
>>> arr = np.array([0, 254], np.uint8)
+>>> aw = SlopeArrayWriter(arr)
+>>> aw.slope
+1.0
+>>> aw = SlopeArrayWriter(arr, np.int8)
+>>> aw.slope
+2.0
+>>> aw = SlopeArrayWriter(arr, np.int8, calc_scale=False)
+>>> aw.slope
+1.0
+>>> aw.calc_scale()
+>>> aw.slope
+2.0
+
+
+
+ +
+
+calc_scale(force=False)ΒΆ
+

Calculate / set scaling for floats/(u)ints to (u)ints

+
+ +
+
+reset()ΒΆ
+

Set object to values before any scaling calculation

+
+ +
+
+scaling_needed()ΒΆ
+

Checks if scaling is needed for input array

+

Raises WriterError if no scaling possible.

+

The rules are in the code, but:

+
    +
  • If numpy will cast, return False (no scaling needed)

  • +
  • If input or output is an object or structured type, raise

  • +
  • If input is complex, raise

  • +
  • If the output is float, return False

  • +
  • If the input array is all zero, return False

  • +
  • If there is no finite value, return False (the writer will strip the +non-finite values)

  • +
  • By now we are casting to (u)int. If the input type is a float, return +True (we do need scaling)

  • +
  • Now input and output types are (u)ints. If the min and max in the +data are within range of the output type, return False

  • +
  • Otherwise return True

  • +
+
+ +
+
+property slopeΒΆ
+

get/set slope

+
+ +
+
+to_fileobj(fileobj, order='F')ΒΆ
+

Write array into fileobj

+
+
Parameters:
+
+
fileobjfile-like object
+
order{β€˜F’, β€˜C’}

order (Fortran or C) to which to write array

+
+
+
+
+
+ +
+ +
+
+

SlopeInterArrayWriterΒΆ

+
+
+class nibabel.arraywriters.SlopeInterArrayWriter(array, out_dtype=None, calc_scale=True, scaler_dtype=<class 'numpy.float32'>, **kwargs)ΒΆ
+

Bases: SlopeArrayWriter

+

Array writer that can use slope and intercept to scale array

+

The writer can subtract an intercept, and divided by a slope, in order to +be able to convert floating point values into a (u)int range, or to convert +larger (u)ints to smaller.

+

It extends the ArrayWriter class with attributes:

+
    +
  • inter

  • +
  • slope

  • +
+

and methods:

+
    +
  • reset() - reset inter, slope to default (not adapted to self.array)

  • +
  • calc_scale() - calculate inter, slope to best write self.array

  • +
+

Initialize array writer

+
+
Parameters:
+
+
arrayarray-like

array-like object

+
+
out_dtypeNone or dtype

dtype with which array will be written. For this class, +out_dtype` needs to be the same as the dtype of the input array +or a swapped version of the same.

+
+
calc_scale{True, False}, optional

Whether to calculate scaling for writing array on initialization. +If False, then you can calculate this scaling with +obj.calc_scale() - see examples

+
+
scaler_dtypedtype-like, optional

specifier for numpy dtype for slope, intercept

+
+
**kwargskeyword arguments

This class processes only:

+
    +
  • nan2zero : bool, optional +Whether to set NaN values to 0 when writing integer output. +Defaults to True. If False, NaNs get converted with numpy +astype, and the behavior is undefined. Ignored for floating +point output.

  • +
+
+
+
+
+

Examples

+
>>> arr = np.array([0, 255], np.uint8)
+>>> aw = SlopeInterArrayWriter(arr)
+>>> aw.slope, aw.inter
+(1.0, 0.0)
+>>> aw = SlopeInterArrayWriter(arr, np.int8)
+>>> (aw.slope, aw.inter) == (1.0, 128)
+True
+>>> aw = SlopeInterArrayWriter(arr, np.int8, calc_scale=False)
+>>> aw.slope, aw.inter
+(1.0, 0.0)
+>>> aw.calc_scale()
+>>> (aw.slope, aw.inter) == (1.0, 128)
+True
+
+
+
+
+__init__(array, out_dtype=None, calc_scale=True, scaler_dtype=<class 'numpy.float32'>, **kwargs)ΒΆ
+

Initialize array writer

+
+
Parameters:
+
+
arrayarray-like

array-like object

+
+
out_dtypeNone or dtype

dtype with which array will be written. For this class, +out_dtype` needs to be the same as the dtype of the input array +or a swapped version of the same.

+
+
calc_scale{True, False}, optional

Whether to calculate scaling for writing array on initialization. +If False, then you can calculate this scaling with +obj.calc_scale() - see examples

+
+
scaler_dtypedtype-like, optional

specifier for numpy dtype for slope, intercept

+
+
**kwargskeyword arguments

This class processes only:

+
    +
  • nan2zero : bool, optional +Whether to set NaN values to 0 when writing integer output. +Defaults to True. If False, NaNs get converted with numpy +astype, and the behavior is undefined. Ignored for floating +point output.

  • +
+
+
+
+
+

Examples

+
>>> arr = np.array([0, 255], np.uint8)
+>>> aw = SlopeInterArrayWriter(arr)
+>>> aw.slope, aw.inter
+(1.0, 0.0)
+>>> aw = SlopeInterArrayWriter(arr, np.int8)
+>>> (aw.slope, aw.inter) == (1.0, 128)
+True
+>>> aw = SlopeInterArrayWriter(arr, np.int8, calc_scale=False)
+>>> aw.slope, aw.inter
+(1.0, 0.0)
+>>> aw.calc_scale()
+>>> (aw.slope, aw.inter) == (1.0, 128)
+True
+
+
+
+ +
+
+property interΒΆ
+

get/set inter

+
+ +
+
+reset()ΒΆ
+

Set object to values before any scaling calculation

+
+ +
+
+to_fileobj(fileobj, order='F')ΒΆ
+

Write array into fileobj

+
+
Parameters:
+
+
fileobjfile-like object
+
order{β€˜F’, β€˜C’}

order (Fortran or C) to which to write array

+
+
+
+
+
+ +
+ +
+
+

WriterErrorΒΆ

+
+
+class nibabel.arraywriters.WriterErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

get_slope_interΒΆ

+
+
+nibabel.arraywriters.get_slope_inter(writer)ΒΆ
+

Return slope, intercept from array writer object

+
+
Parameters:
+
+
writerArrayWriter instance
+
+
+
Returns:
+
+
slopescalar

slope in writer or 1.0 if not present

+
+
interscalar

intercept in writer or 0.0 if not present

+
+
+
+
+

Examples

+
>>> arr = np.arange(10)
+>>> get_slope_inter(ArrayWriter(arr))
+(1.0, 0.0)
+>>> get_slope_inter(SlopeArrayWriter(arr))
+(1.0, 0.0)
+>>> get_slope_inter(SlopeInterArrayWriter(arr))
+(1.0, 0.0)
+
+
+
+ +
+
+

make_array_writerΒΆ

+
+
+nibabel.arraywriters.make_array_writer(data, out_type, has_slope=True, has_intercept=True, **kwargs)ΒΆ
+

Make array writer instance for array data and output type out_type

+
+
Parameters:
+
+
dataarray-like

array for which to create array writer

+
+
out_typedtype-like

input to numpy dtype to specify array writer output type

+
+
has_slope{True, False}

If True, array write can use scaling to adapt the array to out_type

+
+
has_intercept{True, False}

If True, array write can use intercept to adapt the array to out_type

+
+
**kwargsother keyword arguments

to pass to the arraywriter class

+
+
+
+
Returns:
+
+
writerarraywriter instance

Instance of array writer, with class adapted to has_intercept and +has_slope.

+
+
+
+
+

Examples

+
>>> aw = make_array_writer(np.arange(10), np.uint8, True, True)
+>>> type(aw) == SlopeInterArrayWriter
+True
+>>> aw = make_array_writer(np.arange(10), np.uint8, True, False)
+>>> type(aw) == SlopeArrayWriter
+True
+>>> aw = make_array_writer(np.arange(10), np.uint8, False, False)
+>>> type(aw) == ArrayWriter
+True
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.batteryrunners.html b/reference/nibabel.batteryrunners.html new file mode 100644 index 0000000000..67e4f367b9 --- /dev/null +++ b/reference/nibabel.batteryrunners.html @@ -0,0 +1,449 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

batteryrunnersΒΆ

+

Battery runner classes and Report classes

+

These classes / objects are for generic checking / fixing batteries

+

The BatteryRunner class will run a series of checks on a single +object.

+

A check is a callable, of signature func(obj, fix=False) which +returns a tuple (obj, Report) for func(obj, False) or +func(obj, True), where the obj may be a modified object, or a +different object, if fix==True.

+

To run checks only, and return problem report objects:

+
>>> from nibabel.batteryrunners import BatteryRunner, Report
+>>> def chk(obj, fix=False): # minimal check
+...     return obj, Report()
+>>> btrun = BatteryRunner((chk,))
+>>> reports = btrun.check_only('a string')
+
+
+

To run checks and fixes, returning fixed object and problem report +sequence, with possible fix messages:

+
>>> fixed_obj, report_seq = btrun.check_fix('a string')
+
+
+

Reports are iterable things, where the elements in the iterations are +Problems, with attributes error, problem_level, +problem_msg, and possibly empty fix_msg. The problem_level +is an integer, giving the level of problem, from 0 (no problem) to 50 +(very bad problem). The levels follow the log levels from the logging +module (e.g 40 equivalent to β€œerror” level, 50 to β€œcritical”). The +error can be one of None if no error to suggest, or an Exception +class that the user might consider raising for this situation. The +problem_msg and fix_msg are human readable strings that should +explain what happened.

+
+

More about checksΒΆ

+

Checks are callables returning objects and reports, like chk below, +such that:

+
obj, report = chk(obj, fix=False)
+obj, report = chk(obj, fix=True)
+
+
+

For example, for the Analyze header, we need to check the datatype:

+
def chk_datatype(hdr, fix=True):
+    rep = Report(hdr, HeaderDataError)
+    code = int(hdr['datatype'])
+    try:
+        dtype = AnalyzeHeader._data_type_codes.dtype[code]
+    except KeyError:
+        rep.problem_level = 40
+        rep.problem_msg = 'data code not recognized'
+    else:
+        if dtype.type is np.void:
+            rep.problem_level = 40
+            rep.problem_msg = 'data code not supported'
+        else:
+            return hdr, rep
+    if fix:
+        rep.fix_problem_msg = 'not attempting fix'
+    return hdr, rep
+
+
+

or the bitpix:

+
def chk_bitpix(hdr, fix=True):
+    rep = Report(HeaderDataError)
+    code = int(hdr['datatype'])
+    try:
+        dt = AnalyzeHeader._data_type_codes.dtype[code]
+    except KeyError:
+        rep.problem_level = 10
+        rep.problem_msg = 'no valid datatype to fix bitpix'
+        return hdr, rep
+    bitpix = dt.itemsize * 8
+    if bitpix == hdr['bitpix']:
+        return hdr, rep
+    rep.problem_level = 10
+    rep.problem_msg = 'bitpix does not match datatype')
+    if fix:
+        hdr['bitpix'] = bitpix # inplace modification
+        rep.fix_msg = 'setting bitpix to match datatype'
+    return hdr, ret
+
+
+

or the pixdims:

+
def chk_pixdims(hdr, fix=True):
+    rep = Report(hdr, HeaderDataError)
+    if not np.any(hdr['pixdim'][1:4] < 0):
+        return hdr, rep
+    rep.problem_level = 40
+    rep.problem_msg = 'pixdim[1,2,3] should be positive'
+    if fix:
+        hdr['pixdim'][1:4] = np.abs(hdr['pixdim'][1:4])
+        rep.fix_msg = 'setting to abs of pixdim values'
+    return hdr, rep
+
+
+
+ + + + + + + + + +

BatteryRunner(checks)

Class to run set of checks

Report([error,Β problem_level,Β problem_msg,Β ...])

Initialize report with values

+
+

BatteryRunnerΒΆ

+
+
+class nibabel.batteryrunners.BatteryRunner(checks)ΒΆ
+

Bases: object

+

Class to run set of checks

+

Initialize instance from sequence of checks

+
+
Parameters:
+
+
checkssequence

sequence of checks, where checks are callables matching +signature obj, rep = chk(obj, fix=False). Checks are run +in the order they are passed.

+
+
+
+
+

Examples

+
>>> def chk(obj, fix=False): # minimal check
+...     return obj, Report()
+>>> btrun = BatteryRunner((chk,))
+
+
+
+
+__init__(checks)ΒΆ
+

Initialize instance from sequence of checks

+
+
Parameters:
+
+
checkssequence

sequence of checks, where checks are callables matching +signature obj, rep = chk(obj, fix=False). Checks are run +in the order they are passed.

+
+
+
+
+

Examples

+
>>> def chk(obj, fix=False): # minimal check
+...     return obj, Report()
+>>> btrun = BatteryRunner((chk,))
+
+
+
+ +
+
+check_fix(obj)ΒΆ
+

Run checks, with fixes, on obj returning obj, reports

+
+
Parameters:
+
+
objanything

object on which to run checks, fixes

+
+
+
+
Returns:
+
+
objanything

possibly modified or replaced obj, after fixes

+
+
reportssequence

sequence of reports on checks, fixes

+
+
+
+
+
+ +
+
+check_only(obj)ΒΆ
+

Run checks on obj returning reports

+
+
Parameters:
+
+
objanything

object on which to run checks

+
+
+
+
Returns:
+
+
reportssequence

sequence of report objects reporting on result of running +checks (without fixes) on obj

+
+
+
+
+
+ +
+ +
+
+

ReportΒΆ

+
+
+class nibabel.batteryrunners.Report(error=<class 'Exception'>, problem_level=0, problem_msg='', fix_msg='')ΒΆ
+

Bases: object

+

Initialize report with values

+
+
Parameters:
+
+
errorNone or Exception

Error to raise if raising error for this check. If None, +no error can be raised for this check (it was probably +normal).

+
+
problem_levelint

level of problem. From 0 (no problem) to 50 (severe +problem). If the report originates from a fix, then this +is the level of the problem remaining after the fix. +Default is 0

+
+
problem_msgstring

String describing problem detected. Default is β€˜β€™

+
+
fix_msgstring

String describing any fix applied. Default is β€˜β€™.

+
+
+
+
+

Examples

+
>>> rep = Report()
+>>> rep.problem_level
+0
+>>> rep = Report(TypeError, 10)
+>>> rep.problem_level
+10
+
+
+
+
+__init__(error=<class 'Exception'>, problem_level=0, problem_msg='', fix_msg='')ΒΆ
+

Initialize report with values

+
+
Parameters:
+
+
errorNone or Exception

Error to raise if raising error for this check. If None, +no error can be raised for this check (it was probably +normal).

+
+
problem_levelint

level of problem. From 0 (no problem) to 50 (severe +problem). If the report originates from a fix, then this +is the level of the problem remaining after the fix. +Default is 0

+
+
problem_msgstring

String describing problem detected. Default is β€˜β€™

+
+
fix_msgstring

String describing any fix applied. Default is β€˜β€™.

+
+
+
+
+

Examples

+
>>> rep = Report()
+>>> rep.problem_level
+0
+>>> rep = Report(TypeError, 10)
+>>> rep.problem_level
+10
+
+
+
+ +
+
+log_raise(logger, error_level=40)ΒΆ
+

Log problem, raise error if problem >= error_level

+
+
Parameters:
+
+
loggerlog

log object, implementing log method

+
+
error_levelint, optional

If self.problem_level >= error_level, raise error

+
+
+
+
+
+ +
+
+property messageΒΆ
+

formatted message string, including fix message if present

+
+ +
+
+write_raise(stream, error_level=40, log_level=30)ΒΆ
+

Write report to stream

+
+
Parameters:
+
+
streamfile-like

implementing write method

+
+
error_levelint, optional

level at which to raise error for problem detected in +self

+
+
log_levelint, optional

Such that if log_level is >= self.problem_level we +write the report to stream, otherwise we write nothing.

+
+
+
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.benchmarks.html b/reference/nibabel.benchmarks.html new file mode 100644 index 0000000000..b6c3e796fd --- /dev/null +++ b/reference/nibabel.benchmarks.html @@ -0,0 +1,330 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

benchmarksΒΆ

+ + + +
+
+

Module: benchmarks.bench_array_to_fileΒΆ

+

Benchmarks for array_to_file routine

+

Run benchmarks with:

+
import nibabel as nib
+nib.bench()
+
+
+

Run this benchmark with:

+
pytest -c <path>/benchmarks/pytest.benchmark.ini <path>/benchmarks/bench_array_to_file.py
+
+
+ + + + + + +

bench_array_to_file()

+
+
+

Module: benchmarks.bench_arrayproxy_slicingΒΆ

+

Benchmarks for ArrayProxy slicing of gzipped and non-gzipped files

+

Run benchmarks with:

+
import nibabel as nib
+nib.bench()
+
+
+

Run this benchmark with:

+
pytest -c <path>/benchmarks/pytest.benchmark.ini <path>/benchmarks/bench_arrayproxy_slicing.py
+
+
+ + + + + + +

bench_arrayproxy_slicing()

+
+
+

Module: benchmarks.bench_filesliceΒΆ

+

Benchmarks for fileslicing

+
+

import nibabel as nib +nib.bench()

+
+

Run this benchmark with:

+
pytest -c <path>/benchmarks/pytest.benchmark.ini <path>/benchmarks/bench_fileslice.py
+
+
+ + + + + + + + + +

bench_fileslice([bytes,Β file_,Β gz,Β bz2,Β zst])

run_slices(file_like[,Β repeat,Β offset,Β order])

+
+
+

Module: benchmarks.bench_finite_rangeΒΆ

+

Benchmarks for finite_range routine

+

Run benchmarks with:

+
import nibabel as nib
+nib.bench()
+
+
+

Run this benchmark with:

+
pytest -c <path>/benchmarks/pytest.benchmark.ini <path>/benchmarks/bench_finite_range.py
+
+
+ + + + + + +

bench_finite_range()

+
+
+

Module: benchmarks.bench_load_saveΒΆ

+

Benchmarks for load and save of image arrays

+

Run benchmarks with:

+
import nibabel as nib
+nib.bench()
+
+
+

Run this benchmark with:

+
pytest -c <path>/benchmarks/pytest.benchmark.ini <path>/benchmarks/bench_load_save.py
+
+
+ + + + + + +

bench_load_save()

+
+
+

Module: benchmarks.butilsΒΆ

+

Benchmarking utilities

+ + + + + + +

print_git_title(title)

Prints title string with git hash if possible, and underline

+
+

bench_array_to_fileΒΆ

+
+
+nibabel.benchmarks.bench_array_to_file.bench_array_to_file()ΒΆ
+
+ +
+
+

bench_arrayproxy_slicingΒΆ

+
+
+nibabel.benchmarks.bench_arrayproxy_slicing.bench_arrayproxy_slicing()ΒΆ
+
+ +
+
+

bench_filesliceΒΆ

+
+
+nibabel.benchmarks.bench_fileslice.bench_fileslice(bytes=True, file_=True, gz=True, bz2=False, zst=True)ΒΆ
+
+ +
+
+

run_slicesΒΆ

+
+
+nibabel.benchmarks.bench_fileslice.run_slices(file_like, repeat=3, offset=0, order='F')ΒΆ
+
+ +
+
+

bench_finite_rangeΒΆ

+
+
+nibabel.benchmarks.bench_finite_range.bench_finite_range()ΒΆ
+
+ +
+
+

bench_load_saveΒΆ

+
+
+nibabel.benchmarks.bench_load_save.bench_load_save()ΒΆ
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.brikhead.html b/reference/nibabel.brikhead.html new file mode 100644 index 0000000000..49efdcee46 --- /dev/null +++ b/reference/nibabel.brikhead.html @@ -0,0 +1,701 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

brikheadΒΆ

+

Class for reading AFNI BRIK/HEAD datasets

+

See https://afni.nimh.nih.gov/pub/dist/doc/program_help/README.attributes.html +for information on what is required to have a valid BRIK/HEAD dataset.

+

Unless otherwise noted, descriptions AFNI attributes in the code refer to this +document.

+
+

NotesΒΆ

+

In the AFNI HEAD file, the first two values of the attribute DATASET_RANK +determine the shape of the data array stored in the corresponding BRIK file. +The first value, DATASET_RANK[0], must be set to 3 denoting a 3D image. The +second value, DATASET_RANK[1], determines how many β€œsub-bricks” (in AFNI +parlance) / volumes there are along the fourth (traditionally, but not +exclusively) time axis. Thus, DATASET_RANK[1] will (at least as far as I (RM) +am aware) always be >= 1. This permits sub-brick indexing common in AFNI +programs (e.g., example4d+orig’[0]’).

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

AFNIArrayProxy(file_like,Β header,Β *[,Β mmap,Β ...])

Proxy object for AFNI image array.

AFNIHeader(info)

Class for AFNI header

AFNIHeaderError

Error when reading AFNI HEAD file

AFNIImage(dataobj,Β affine[,Β header,Β extra,Β ...])

AFNI Image file

AFNIImageError

Error when reading AFNI BRIK files

parse_AFNI_header(fobj)

Parses fobj to extract information from HEAD file

+
+

AFNIArrayProxyΒΆ

+
+
+class nibabel.brikhead.AFNIArrayProxy(file_like, header, *, mmap=True, keep_file_open=None)ΒΆ
+

Bases: ArrayProxy

+

Proxy object for AFNI image array.

+
+
Attributes:
+
+
scalingnp.ndarray

Scaling factor (one factor per volume/sub-brick) for data. Default is +None

+
+
+
+
+

Initialize AFNI array proxy

+
+
Parameters:
+
+
file_likefile-like object

File-like object or filename. If file-like object, should implement +at least read and seek.

+
+
headerAFNIHeader object
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading data. +If False, do not try numpy memmap for data array. If one of +{β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A mmap value of +True gives the same behavior as mmap='c'. If file_like +cannot be memory-mapped, ignore mmap value and read array from +file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_like refers to an open file handle, this setting has no +effect. The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
+
+
+__init__(file_like, header, *, mmap=True, keep_file_open=None)ΒΆ
+

Initialize AFNI array proxy

+
+
Parameters:
+
+
file_likefile-like object

File-like object or filename. If file-like object, should implement +at least read and seek.

+
+
headerAFNIHeader object
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading data. +If False, do not try numpy memmap for data array. If one of +{β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A mmap value of +True gives the same behavior as mmap='c'. If file_like +cannot be memory-mapped, ignore mmap value and read array from +file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_like refers to an open file handle, this setting has no +effect. The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
+
+ +
+
+property scalingΒΆ
+
+ +
+ +
+
+

AFNIHeaderΒΆ

+
+
+class nibabel.brikhead.AFNIHeader(info)ΒΆ
+

Bases: SpatialHeader

+

Class for AFNI header

+

Initialize AFNI header object

+
+
Parameters:
+
+
infodict

Information from HEAD file as obtained by parse_AFNI_header()

+
+
+
+
+

Examples

+
>>> fname = os.path.join(datadir, 'example4d+orig.HEAD')
+>>> header = AFNIHeader(parse_AFNI_header(fname))
+>>> header.get_data_dtype().str
+'<i2'
+>>> header.get_zooms()
+(3.0, 3.0, 3.0, 3.0)
+>>> header.get_data_shape()
+(33, 41, 25, 3)
+
+
+
+
+__init__(info)ΒΆ
+

Initialize AFNI header object

+
+
Parameters:
+
+
infodict

Information from HEAD file as obtained by parse_AFNI_header()

+
+
+
+
+

Examples

+
>>> fname = os.path.join(datadir, 'example4d+orig.HEAD')
+>>> header = AFNIHeader(parse_AFNI_header(fname))
+>>> header.get_data_dtype().str
+'<i2'
+>>> header.get_zooms()
+(3.0, 3.0, 3.0, 3.0)
+>>> header.get_data_shape()
+(33, 41, 25, 3)
+
+
+
+ +
+
+copy()ΒΆ
+

Copy object to independent representation

+

The copy should not be affected by any changes to the original +object.

+
+ +
+
+classmethod from_fileobj(fileobj)ΒΆ
+
+ +
+
+classmethod from_header(header=None)ΒΆ
+
+ +
+
+get_affine()ΒΆ
+

Returns affine of dataset

+

Examples

+
>>> fname = os.path.join(datadir, 'example4d+orig.HEAD')
+>>> header = AFNIHeader(parse_AFNI_header(fname))
+>>> header.get_affine()
+array([[ -3.    ,  -0.    ,  -0.    ,  49.5   ],
+       [ -0.    ,  -3.    ,  -0.    ,  82.312 ],
+       [  0.    ,   0.    ,   3.    , -52.3511],
+       [  0.    ,   0.    ,   0.    ,   1.    ]])
+
+
+
+ +
+
+get_data_offset()ΒΆ
+

Data offset in BRIK file

+

Offset is always 0.

+
+ +
+
+get_data_scaling()ΒΆ
+

AFNI applies volume-specific data scaling

+

Examples

+
>>> fname = os.path.join(datadir, 'scaled+tlrc.HEAD')
+>>> header = AFNIHeader(parse_AFNI_header(fname))
+>>> header.get_data_scaling()
+array([3.883363e-08])
+
+
+
+ +
+
+get_slope_inter()ΒΆ
+

Use self.get_data_scaling() instead

+

Holdover because AFNIArrayProxy (inheriting from ArrayProxy) +requires this functionality so as to not error.

+
+ +
+
+get_space()ΒΆ
+

Return label for anatomical space to which this dataset is aligned.

+
+
Returns:
+
+
spacestr

AFNI β€œspace” designation; one of [ORIG, ANAT, TLRC, MNI]

+
+
+
+
+

Notes

+

There appears to be documentation for these spaces at +https://afni.nimh.nih.gov/pub/dist/atlases/elsedemo/AFNI_atlas_spaces.niml

+
+ +
+
+get_volume_labels()ΒΆ
+

Returns volume labels

+
+
Returns:
+
+
labelslist of str

Labels for volumes along fourth dimension

+
+
+
+
+

Examples

+
>>> header = AFNIHeader(parse_AFNI_header(os.path.join(datadir, 'example4d+orig.HEAD')))
+>>> header.get_volume_labels()
+['#0', '#1', '#2']
+
+
+
+ +
+ +
+
+

AFNIHeaderErrorΒΆ

+
+
+class nibabel.brikhead.AFNIHeaderErrorΒΆ
+

Bases: HeaderDataError

+

Error when reading AFNI HEAD file

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

AFNIImageΒΆ

+
+
+class nibabel.brikhead.AFNIImage(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Bases: SpatialImage

+

AFNI Image file

+

Can be loaded from either the BRIK or HEAD file (but MUST specify one!)

+

Examples

+
>>> import nibabel as nib
+>>> brik = nib.load(os.path.join(datadir, 'example4d+orig.BRIK.gz'))
+>>> brik.shape
+(33, 41, 25, 3)
+>>> brik.affine
+array([[ -3.    ,  -0.    ,  -0.    ,  49.5   ],
+       [ -0.    ,  -3.    ,  -0.    ,  82.312 ],
+       [  0.    ,   0.    ,   3.    , -52.3511],
+       [  0.    ,   0.    ,   0.    ,   1.    ]])
+>>> head = load(os.path.join(datadir, 'example4d+orig.HEAD'))
+>>> np.array_equal(head.get_fdata(), brik.get_fdata())
+True
+
+
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+ImageArrayProxyΒΆ
+

alias of AFNIArrayProxy

+
+ +
+
+files_types: tuple[ExtensionSpec, ...] = (('image', '.brik'), ('header', '.head'))ΒΆ
+
+ +
+
+classmethod filespec_to_file_map(filespec)ΒΆ
+

Make file_map from filename filespec

+

AFNI BRIK files can be compressed, but HEAD files cannot - see +afni.nimh.nih.gov/pub/dist/doc/program_help/README.compression.html. +Thus, if you have AFNI files my_image.HEAD and my_image.BRIK.gz and you +want to load the AFNI BRIK / HEAD pair, you can specify:

+
+
    +
  • The HEAD filename - e.g., my_image.HEAD

  • +
  • The BRIK filename w/o compressed extension - e.g., my_image.BRIK

  • +
  • The full BRIK filename - e.g., my_image.BRIK.gz

  • +
+
+
+
Parameters:
+
+
filespecstr

Filename that might be for this image file type.

+
+
+
+
Returns:
+
+
file_mapdict

dict with keys image and header where values are fileholder +objects for the respective BRIK and HEAD files

+
+
+
+
Raises:
+
+
ImageFileError

If filespec is not recognizable as being a filename for this +image type.

+
+
+
+
+
+ +
+
+classmethod from_file_map(file_map, *, mmap=True, keep_file_open=None)ΒΆ
+

Creates an AFNIImage instance from file_map

+
+
Parameters:
+
+
file_mapdict

dict with keys image, header and values being fileholder +objects for the respective BRIK and HEAD files

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{None, True, False}, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_like refers to an open file handle, this setting has no +effect. The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
+
+ +
+
+header_classΒΆ
+

alias of AFNIHeader

+
+ +
+
+makeable: bool = FalseΒΆ
+
+ +
+
+rw: bool = FalseΒΆ
+
+ +
+
+valid_exts: tuple[str, ...] = ('.brik', '.head')ΒΆ
+
+ +
+ +
+
+

AFNIImageErrorΒΆ

+
+
+class nibabel.brikhead.AFNIImageErrorΒΆ
+

Bases: ImageDataError

+

Error when reading AFNI BRIK files

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

parse_AFNI_headerΒΆ

+
+
+nibabel.brikhead.parse_AFNI_header(fobj)ΒΆ
+

Parses fobj to extract information from HEAD file

+
+
Parameters:
+
+
fobjfile-like object

AFNI HEAD file object or filename. If file object, should +implement at least read

+
+
+
+
Returns:
+
+
infodict

Dictionary containing AFNI-style key:value pairs from HEAD file

+
+
+
+
+

Examples

+
>>> fname = os.path.join(datadir, 'example4d+orig.HEAD')
+>>> info = parse_AFNI_header(fname)
+>>> print(info['BYTEORDER_STRING'])
+LSB_FIRST
+>>> print(info['BRICK_TYPES'])
+[1, 1, 1]
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.caret.html b/reference/nibabel.caret.html new file mode 100644 index 0000000000..4ff3353ebb --- /dev/null +++ b/reference/nibabel.caret.html @@ -0,0 +1,182 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

caretΒΆ

+ + + + + + +

CaretMetaData(*args,Β **kwargs)

A list of name-value pairs used in various Caret-based XML formats

+
+

CaretMetaDataΒΆ

+
+
+class nibabel.caret.CaretMetaData(*args, **kwargs)ΒΆ
+

Bases: XmlSerializable, MutableMapping

+

A list of name-value pairs used in various Caret-based XML formats

+
    +
  • Description - Provides a simple method for user-supplied metadata that +associates names with values.

  • +
  • Attributes: [NA]

  • +
  • Child Elements

    +
    +
      +
    • MD (0…N)

    • +
    +
    +
  • +
  • Text Content: [NA]

  • +
+

MD elements are a single metadata entry consisting of a name and a value.

+
+
Attributes:
+
+
datamapping of {name: value} pairs
+
>>> md = CaretMetaData()
+
>>> md[β€˜key’] = β€˜val’
+
>>> md
+
<CaretMetaData {β€˜key’: β€˜val’}>
+
>>> dict(md)
+
{β€˜key’: β€˜val’}
+
>>> md.to_xml()
+
b’<MetaData><MD><Name>key</Name><Value>val</Value></MD></MetaData>’
+
Objects may be constructed like any ``dict``:
+
>>> md = CaretMetaData(key=’val’)
+
>>> md.to_xml()
+
b’<MetaData><MD><Name>key</Name><Value>val</Value></MD></MetaData>’
+
+
+
+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.casting.html b/reference/nibabel.casting.html new file mode 100644 index 0000000000..02c3275a28 --- /dev/null +++ b/reference/nibabel.casting.html @@ -0,0 +1,838 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

castingΒΆ

+

Utilities for casting numpy values in various ways

+

Most routines work round some numpy oddities in floating point precision and +casting. Others work round numpy casting to and from python ints

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

CastingError

FloatingError

able_int_type(values)

Find the smallest integer numpy type to contain sequence values

as_int(x[,Β check])

Return python integer representation of number

best_float()

Floating point type with best precision

ceil_exact(val,Β flt_type)

Return nearest exact integer >= val in float type flt_type

float_to_int(arr,Β int_type[,Β nan2zero,Β infmax])

Convert floating point array arr to type int_type

floor_exact(val,Β flt_type)

Return nearest exact integer <= val in float type flt_type

floor_log2(x)

floor of log2 of abs(x)

have_binary128()

True if we have a binary128 IEEE longdouble

int_abs(arr)

Absolute values of array taking care of max negative int values

int_to_float(val,Β flt_type)

Convert integer val to floating point type flt_type

longdouble_lte_float64()

Return True if longdouble appears to have the same precision as float64

longdouble_precision_improved()

True if longdouble precision increased since initial import

ok_floats()

Return floating point types sorted by precision

on_powerpc()

True if we are running on a Power PC platform

shared_range(flt_type,Β int_type)

Min and max in float type that are >=min, <=max in integer type

type_info(np_type)

Return dict with min, max, nexp, nmant, width for numpy type np_type

ulp([val])

Return gap between val and nearest representable number of same type

+
+

CastingErrorΒΆ

+
+
+class nibabel.casting.CastingErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

FloatingErrorΒΆ

+
+
+class nibabel.casting.FloatingErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

able_int_typeΒΆ

+
+
+nibabel.casting.able_int_type(values)ΒΆ
+

Find the smallest integer numpy type to contain sequence values

+

Prefers uint to int if minimum is >= 0

+
+
Parameters:
+
+
valuessequence

sequence of integer values

+
+
+
+
Returns:
+
+
itypeNone or numpy type

numpy integer type or None if no integer type holds all values

+
+
+
+
+

Examples

+
>>> able_int_type([0, 1]) == np.uint8
+True
+>>> able_int_type([-1, 1]) == np.int8
+True
+
+
+
+ +
+
+

as_intΒΆ

+
+
+nibabel.casting.as_int(x, check=True)ΒΆ
+

Return python integer representation of number

+

as_int() is deprecated. Use int() instead.

+
    +
  • deprecated from version: 5.2.0

  • +
  • Will raise <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 7.0.0

  • +
+

This is useful because the numpy int(val) mechanism is broken for large +values in np.longdouble.

+

It is also useful to work around a numpy 1.4.1 bug in conversion of uints +to python ints.

+
+
Parameters:
+
+
xobject

integer, unsigned integer or floating point value

+
+
check{True, False}

If True, raise error for values that are not integers

+
+
+
+
Returns:
+
+
iint

Python integer

+
+
+
+
+

Examples

+
>>> as_int(2.0)
+2
+>>> as_int(-2.0)
+-2
+>>> as_int(2.1) 
+Traceback (most recent call last):
+    ...
+FloatingError: Not an integer: 2.1
+>>> as_int(2.1, check=False)
+2
+
+
+
+ +
+
+

best_floatΒΆ

+
+
+nibabel.casting.best_float()ΒΆ
+

Floating point type with best precision

+

This is nearly always np.longdouble, except on Windows, where np.longdouble +is Intel80 storage, but with float64 precision for calculations. In that +case we return float64 on the basis it’s the fastest and smallest at the +highest precision.

+

SPARC float128 also proved so slow that we prefer float64.

+
+
Returns:
+
+
best_typenumpy type

floating point type with highest precision

+
+
+
+
+

Notes

+

Needs to run without error for module import, because it is called in +ok_floats below, and therefore in setting module global OK_FLOATS.

+
+ +
+
+

ceil_exactΒΆ

+
+
+nibabel.casting.ceil_exact(val, flt_type)ΒΆ
+

Return nearest exact integer >= val in float type flt_type

+
+
Parameters:
+
+
valint

We have to pass val as an int rather than the floating point type +because large integers cast as floating point may be rounded by the +casting process.

+
+
flt_typenumpy type

numpy float type.

+
+
+
+
Returns:
+
+
ceil_valobject

value of same floating point type as val, that is the nearest exact +integer in this type such that floor_val >= val. Thus if val is +exact in flt_type, ceil_val == val.

+
+
+
+
+

Examples

+

Obviously 2 is within the range of representable integers for float32

+
>>> ceil_exact(2, np.float32)
+2.0
+
+
+

As is 2**24-1 (the number of significand digits is 23 + 1 implicit)

+
>>> ceil_exact(2**24-1, np.float32) == 2**24-1
+True
+
+
+

But 2**24+1 gives a number that float32 can’t represent exactly

+
>>> ceil_exact(2**24+1, np.float32) == 2**24+2
+True
+
+
+

As for the numpy ceil function, negatives ceil towards inf

+
>>> ceil_exact(-2**24-1, np.float32) == -2**24
+True
+
+
+
+ +
+
+

float_to_intΒΆ

+
+
+nibabel.casting.float_to_int(arr, int_type, nan2zero=True, infmax=False)ΒΆ
+

Convert floating point array arr to type int_type

+
    +
  • Rounds numbers to nearest integer

  • +
  • Clips values to prevent overflows when casting

  • +
  • Converts NaN to 0 (for nan2zero == True)

  • +
+

Casting floats to integers is delicate because the result is undefined +and platform specific for float values outside the range of int_type. +Define shared_min to be the minimum value that can be exactly +represented in both the float type of arr and int_type. Define +shared_max to be the equivalent maximum value. To avoid undefined +results we threshold arr at shared_min and shared_max.

+
+
Parameters:
+
+
arrarray-like

Array of floating point type

+
+
int_typeobject

Numpy integer type

+
+
nan2zero{True, False, None}

Whether to convert NaN value to zero. Default is True. If False, and +NaNs are present, raise CastingError. If None, do not check for NaN +values and pass through directly to the astype casting mechanism. +In this last case, the resulting value is undefined.

+
+
infmax{False, True}

If True, set np.inf values in arr to be int_type integer maximum +value, -np.inf as int_type integer minimum. If False, set +/- infs +to be shared_min, shared_max as defined above. Therefore False +gives faster conversion at the expense of infs that are further from +infinity.

+
+
+
+
Returns:
+
+
iarrndarray

of type int_type

+
+
+
+
+

Notes

+

Numpy relies on the C library to cast from float to int using the standard +astype method of the array.

+

Quoting from section F4 of the C99 standard:

+
+

If the floating value is infinite or NaN or if the integral part of the +floating value exceeds the range of the integer type, then the +β€œinvalid” floating-point exception is raised and the resulting value +is unspecified.

+
+

Hence we threshold at shared_min and shared_max to avoid casting to +values that are undefined.

+

See: https://en.wikipedia.org/wiki/C99 . There are links to the C99 +standard from that page.

+

Examples

+
>>> float_to_int([np.nan, np.inf, -np.inf, 1.1, 6.6], np.int16)
+array([     0,  32767, -32768,      1,      7], dtype=int16)
+
+
+
+ +
+
+

floor_exactΒΆ

+
+
+nibabel.casting.floor_exact(val, flt_type)ΒΆ
+

Return nearest exact integer <= val in float type flt_type

+
+
Parameters:
+
+
valint

We have to pass val as an int rather than the floating point type +because large integers cast as floating point may be rounded by the +casting process.

+
+
flt_typenumpy type

numpy float type.

+
+
+
+
Returns:
+
+
floor_valobject

value of same floating point type as val, that is the nearest exact +integer in this type such that floor_val <= val. Thus if val is +exact in flt_type, floor_val == val.

+
+
+
+
+

Examples

+

Obviously 2 is within the range of representable integers for float32

+
>>> floor_exact(2, np.float32)
+2.0
+
+
+

As is 2**24-1 (the number of significand digits is 23 + 1 implicit)

+
>>> floor_exact(2**24-1, np.float32) == 2**24-1
+True
+
+
+

But 2**24+1 gives a number that float32 can’t represent exactly

+
>>> floor_exact(2**24+1, np.float32) == 2**24
+True
+
+
+

As for the numpy floor function, negatives floor towards -inf

+
>>> floor_exact(-2**24-1, np.float32) == -2**24-2
+True
+
+
+
+ +
+
+

floor_log2ΒΆ

+
+
+nibabel.casting.floor_log2(x)ΒΆ
+

floor of log2 of abs(x)

+

Embarrassingly, from https://en.wikipedia.org/wiki/Binary_logarithm

+
+
Parameters:
+
+
xint
+
+
+
Returns:
+
+
LNone or int

floor of base 2 log of x. None if x == 0.

+
+
+
+
+

Examples

+
>>> floor_log2(2**9+1)
+9
+>>> floor_log2(-2**9+1)
+8
+>>> floor_log2(0.5)
+-1
+>>> floor_log2(0) is None
+True
+
+
+
+ +
+
+

have_binary128ΒΆ

+
+
+nibabel.casting.have_binary128()ΒΆ
+

True if we have a binary128 IEEE longdouble

+
+ +
+
+

int_absΒΆ

+
+
+nibabel.casting.int_abs(arr)ΒΆ
+

Absolute values of array taking care of max negative int values

+
+
Parameters:
+
+
arrarray-like
+
+
+
Returns:
+
+
abs_arrarray

array the same shape as arr in which all negative numbers have been +changed to positive numbers with the magnitude.

+
+
+
+
+

Examples

+

This kind of thing is confusing in base numpy:

+
>>> import numpy as np
+>>> np.abs(np.int8(-128))
+-128
+
+
+

int_abs fixes that:

+
>>> int_abs(np.int8(-128))
+128
+>>> int_abs(np.array([-128, 127], dtype=np.int8))
+array([128, 127], dtype=uint8)
+>>> int_abs(np.array([-128, 127], dtype=np.float32))
+array([128., 127.], dtype=float32)
+
+
+
+ +
+
+

int_to_floatΒΆ

+
+
+nibabel.casting.int_to_float(val, flt_type)ΒΆ
+

Convert integer val to floating point type flt_type

+

int_to_float(…, dt) is deprecated. Use dt() instead.

+
    +
  • deprecated from version: 5.2.0

  • +
  • Will raise <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 7.0.0

  • +
+

Why is this so complicated?

+

At least in numpy <= 1.6.1, numpy longdoubles do not correctly convert to +ints, and ints do not correctly convert to longdoubles. Specifically, in +both cases, the values seem to go through float64 conversion on the way, so +to convert better, we need to split into float64s and sum up the result.

+
+
Parameters:
+
+
valint

Integer value

+
+
flt_typeobject

numpy floating point type

+
+
+
+
Returns:
+
+
fnumpy scalar

of type flt_type

+
+
+
+
+

Examples

+
>>> int_to_float(1, np.float32)
+1.0
+
+
+
+ +
+
+

longdouble_lte_float64ΒΆ

+
+
+nibabel.casting.longdouble_lte_float64()ΒΆ
+

Return True if longdouble appears to have the same precision as float64

+
+ +
+
+

longdouble_precision_improvedΒΆ

+
+
+nibabel.casting.longdouble_precision_improved()ΒΆ
+

True if longdouble precision increased since initial import

+

This can happen on Windows compiled with MSVC. It may be because libraries +compiled with mingw (longdouble is Intel80) get linked to numpy compiled +with MSVC (longdouble is Float64)

+
+ +
+
+

ok_floatsΒΆ

+
+
+nibabel.casting.ok_floats()ΒΆ
+

Return floating point types sorted by precision

+

Remove longdouble if it has no higher precision than float64

+
+ +
+
+

on_powerpcΒΆ

+
+
+nibabel.casting.on_powerpc()ΒΆ
+

True if we are running on a Power PC platform

+

Has to deal with older Macs and IBM POWER7 series among others

+
+ +
+
+

shared_rangeΒΆ

+
+
+nibabel.casting.shared_range(flt_type, int_type)ΒΆ
+

Min and max in float type that are >=min, <=max in integer type

+

This is not as easy as it sounds, because the float type may not be able to +exactly represent the max or min integer values, so we have to find the +next exactly representable floating point value to do the thresholding.

+
+
Parameters:
+
+
flt_typedtype specifier

A dtype specifier referring to a numpy floating point type. For +example, f4, np.dtype('f4'), np.float32 are equivalent.

+
+
int_typedtype specifier

A dtype specifier referring to a numpy integer type. For example, +i4, np.dtype('i4'), np.int32 are equivalent

+
+
+
+
Returns:
+
+
mnobject

Number of type flt_type that is the minimum value in the range of +int_type, such that mn.astype(int_type) >= min of int_type

+
+
mxobject

Number of type flt_type that is the maximum value in the range of +int_type, such that mx.astype(int_type) <= max of int_type

+
+
+
+
+

Examples

+
>>> shared_range(np.float32, np.int32) == (-2147483648.0, 2147483520.0)
+True
+>>> shared_range('f4', 'i4') == (-2147483648.0, 2147483520.0)
+True
+
+
+
+ +
+
+

type_infoΒΆ

+
+
+nibabel.casting.type_info(np_type)ΒΆ
+

Return dict with min, max, nexp, nmant, width for numpy type np_type

+

Type can be integer in which case nexp and nmant are None.

+
+
Parameters:
+
+
np_typenumpy type specifier

Any specifier for a numpy dtype

+
+
+
+
Returns:
+
+
infodict

with fields min (minimum value), max (maximum value), nexp +(exponent width), nmant (significand precision not including +implicit first digit), minexp (minimum exponent), maxexp +(maximum exponent), width (width in bytes). (nexp, nmant, +minexp, maxexp) are None for integer types. Both min and +max are of type np_type.

+
+
+
+
Raises:
+
+
FloatingError

for floating point types we don’t recognize

+
+
+
+
+

Notes

+

You might be thinking that np.finfo does this job, and it does, except +for PPC long doubles (https://github.com/numpy/numpy/issues/2669) and +float96 on Windows compiled with Mingw. This routine protects against such +errors in np.finfo by only accepting values that we know are likely to +be correct.

+
+ +
+
+

ulpΒΆ

+
+
+nibabel.casting.ulp(val=1.0)ΒΆ
+

Return gap between val and nearest representable number of same type

+

This is the value of a unit in the last place (ULP), and is similar in +meaning to the MATLAB eps function.

+
+
Parameters:
+
+
valscalar, optional

scalar value of any numpy type. Default is 1.0 (float64)

+
+
+
+
Returns:
+
+
ulp_valscalar

gap between val and nearest representable number of same type

+
+
+
+
+

Notes

+

The wikipedia article on machine epsilon points out that the term epsilon +can be used in the sense of a unit in the last place (ULP), or as the +maximum relative rounding error. The MATLAB eps function uses the ULP +meaning, but this function is ulp rather than eps to avoid +confusion between different meanings of eps.

+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.cifti2.html b/reference/nibabel.cifti2.html new file mode 100644 index 0000000000..86432007f0 --- /dev/null +++ b/reference/nibabel.cifti2.html @@ -0,0 +1,2785 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

cifti2ΒΆ

+

CIFTI-2 format IO

+ + + + + + + + + +

cifti2

Read / write access to CIFTI-2 image format

cifti2_axes

Defines Axis objects to create, read, and manipulate CIFTI-2 files

+ + + +
+
+

Module: cifti2.cifti2ΒΆ

+

Read / write access to CIFTI-2 image format

+

Format of the NIFTI2 container format described here:

+
+
+

Definition of the CIFTI-2 header format and file extensions can be found at:

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

Cifti2BrainModel([index_offset,Β ...])

Element representing a mapping of the dimension to vertex or voxels.

Cifti2Header([matrix,Β version])

Class for CIFTI-2 header extension

Cifti2HeaderError

Error in CIFTI-2 header

Cifti2Image([dataobj,Β header,Β nifti_header,Β ...])

Class for single file CIFTI-2 format image

Cifti2Label([key,Β label,Β red,Β green,Β blue,Β ...])

CIFTI-2 label: association of integer key with a name and RGBA values

Cifti2LabelTable()

CIFTI-2 label table: a sequence of Cifti2Labels

Cifti2Matrix()

CIFTI-2 Matrix object

Cifti2MatrixIndicesMap(...[,Β ...])

Class for Matrix Indices Map

Cifti2MetaData(*args,Β **kwargs)

A list of name-value pairs

Cifti2NamedMap([map_name,Β metadata,Β label_table])

CIFTI-2 named map: association of name and optional data with a map index

Cifti2Parcel([name,Β voxel_indices_ijk,Β vertices])

CIFTI-2 parcel: association of a name with vertices and/or voxels

Cifti2Surface([brain_structure,Β ...])

Cifti surface: association of brain structure and number of vertices

Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ([...])

Matrix that translates voxel indices to spatial coordinates

Cifti2VertexIndices([indices])

CIFTI-2 vertex indices: vertex indices for an associated brain model

Cifti2Vertices([brain_structure,Β vertices])

CIFTI-2 vertices - association of brain structure and a list of vertices

Cifti2Volume([volume_dimensions,Β ...])

CIFTI-2 volume: information about a volume for mappings that use voxels

Cifti2VoxelIndicesIJK([indices])

CIFTI-2 VoxelIndicesIJK: Set of voxel indices contained in a structure

LimitedNifti2Header([binaryblock,Β ...])

Initialize header from binary data block and extensions

+
+
+

Module: cifti2.cifti2_axesΒΆ

+

Defines Axis objects to create, read, and manipulate CIFTI-2 files

+

These axes provide an alternative interface to the information in the CIFTI-2 header. +Each type of CIFTI-2 axes describing the rows/columns in a CIFTI-2 matrix is given a unique class:

+
    +
  • BrainModelAxis: each row/column is a voxel or vertex

  • +
  • ParcelsAxis: each row/column is a group of voxels and/or vertices

  • +
  • ScalarAxis: each row/column has a unique name (with optional meta-data)

  • +
  • LabelAxis: each row/column has a unique name and label table (with optional meta-data)

  • +
  • SeriesAxis: each row/column is a timepoint, which increases monotonically

  • +
+

All of these classes are derived from the Axis class.

+

After loading a CIFTI-2 file a tuple of axes describing the rows and columns can be obtained +from the cifti2.Cifti2Header.get_axis() method on the header object +(e.g. nibabel.load(<filename>).header.get_axis()). Inversely, a new +cifti2.Cifti2Header object can be created from existing Axis objects +using the cifti2.Cifti2Header.from_axes() factory method.

+

CIFTI-2 Axis objects of the same type can be concatenated using the β€˜+’-operator. +Numpy indexing also works on axes +(except for SeriesAxis objects, which have to remain monotonically increasing or decreasing).

+
+

Creating new CIFTI-2 axesΒΆ

+

New Axis objects can be constructed by providing a description for what is contained +in each row/column of the described tensor. For each Axis sub-class this descriptor is:

+
    +
  • BrainModelAxis: a CIFTI-2 structure name and a voxel or vertex index

  • +
  • ParcelsAxis: a name and a sequence of voxel and vertex indices

  • +
  • ScalarAxis: a name and optionally a dict of meta-data

  • +
  • LabelAxis: a name, dict of label index to name and colour, +and optionally a dict of meta-data

  • +
  • SeriesAxis: the time-point of each row/column is set by setting the start, stop, size, +and unit of the time-series

  • +
+

Several helper functions exist to create new BrainModelAxis axes:

+ +

A ParcelsAxis axis can be created from a sequence of BrainModelAxis axes using +ParcelsAxis.from_brain_models().

+
+
+

ExamplesΒΆ

+

We can create brain models covering the left cortex and left thalamus using:

+
>>> from nibabel import cifti2
+>>> import numpy as np
+>>> bm_cortex = cifti2.BrainModelAxis.from_mask([True, False, True, True],
+...                                             name='cortex_left')
+>>> bm_thal = cifti2.BrainModelAxis.from_mask(np.ones((2, 2, 2)), affine=np.eye(4),
+...                                           name='thalamus_left')
+
+
+

In this very simple case bm_cortex describes a left cortical surface skipping the second +out of four vertices. bm_thal contains all voxels in a 2x2x2 volume.

+

Brain structure names automatically get converted to valid CIFTI-2 identifiers using +BrainModelAxis.to_cifti_brain_structure_name(). +A 1-dimensional mask will be automatically interpreted as a surface element and a 3-dimensional +mask as a volume element.

+

These can be concatenated in a single brain model covering the left cortex and thalamus by +simply adding them together

+
>>> bm_full = bm_cortex + bm_thal
+
+
+

Brain models covering the full HCP grayordinate space can be constructed by adding all the +volumetric and surface brain models together like this (or by reading one from an already +existing HCP file).

+

Getting a specific brain region from the full brain model is as simple as:

+
>>> assert bm_full[bm_full.name == 'CIFTI_STRUCTURE_CORTEX_LEFT'] == bm_cortex
+>>> assert bm_full[bm_full.name == 'CIFTI_STRUCTURE_THALAMUS_LEFT'] == bm_thal
+
+
+

You can also iterate over all brain structures in a brain model:

+
>>> for idx, (name, slc, bm) in enumerate(bm_full.iter_structures()):
+...     print((str(name), slc))
+...     assert bm == bm_full[slc]
+...     assert bm == bm_cortex if idx == 0 else bm_thal
+('CIFTI_STRUCTURE_CORTEX_LEFT', slice(0, 3, None))
+('CIFTI_STRUCTURE_THALAMUS_LEFT', slice(3, None, None))
+
+
+

In this case there will be two iterations, namely: +(β€˜CIFTI_STRUCTURE_CORTEX_LEFT’, slice(0, <size of cortex mask>), bm_cortex) +and +(β€˜CIFTI_STRUCTURE_THALAMUS_LEFT’, slice(<size of cortex mask>, None), bm_thal)

+

ParcelsAxis can be constructed from selections of these brain models:

+
>>> parcel = cifti2.ParcelsAxis.from_brain_models([
+...        ('surface_parcel', bm_cortex[:2]),  # contains first 2 cortical vertices
+...        ('volume_parcel', bm_thal),  # contains thalamus
+...        ('combined_parcel', bm_full[[1, 8, 10]]),  # contains selected voxels/vertices
+...    ])
+
+
+

Time series are represented by their starting time (typically 0), step size +(i.e. sampling time or TR), and number of elements:

+
>>> series = cifti2.SeriesAxis(start=0, step=100, size=5000)
+
+
+

So a header for fMRI data with a TR of 100 ms covering the left cortex and thalamus with +5000 timepoints could be created with

+
>>> type(cifti2.Cifti2Header.from_axes((series, bm_cortex + bm_thal)))
+<class 'nibabel.cifti2.cifti2.Cifti2Header'>
+
+
+

Similarly the curvature and cortical thickness on the left cortex could be stored using a header +like:

+
>>> type(cifti2.Cifti2Header.from_axes((cifti2.ScalarAxis(['curvature', 'thickness']),
+...                                     bm_cortex)))
+<class 'nibabel.cifti2.cifti2.Cifti2Header'>
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

Axis()

Abstract class for any object describing the rows or columns of a CIFTI-2 vector/matrix

BrainModelAxis(name[,Β voxel,Β vertex,Β ...])

Each row/column in the CIFTI-2 vector/matrix represents a single vertex or voxel

LabelAxis(name,Β label[,Β meta])

Defines CIFTI-2 axis for label array.

ParcelsAxis(name,Β voxels,Β vertices[,Β ...])

Each row/column in the CIFTI-2 vector/matrix represents a parcel of voxels/vertices

ScalarAxis(name[,Β meta])

Along this axis of the CIFTI-2 vector/matrix each row/column has been given a unique name and optionally metadata

SeriesAxis(start,Β step,Β size[,Β unit])

Along this axis of the CIFTI-2 vector/matrix the rows/columns increase monotonously in time

from_index_mapping(mim)

Parses the MatrixIndicesMap to find the appropriate CIFTI-2 axis describing the rows or columns

to_header(axes)

Converts the axes describing the rows/columns of a CIFTI-2 vector/matrix to a Cifti2Header

+
+
+

Module: cifti2.parse_cifti2ΒΆ

+ + + + + + + + + +

Cifti2Extension([code,Β content])

+
Parameters:
+

+
+

Cifti2Parser([encoding,Β buffer_size,Β verbose])

Class to parse an XML string into a CIFTI-2 header object

+
+

Cifti2BrainModelΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2BrainModel(index_offset=None, index_count=None, model_type=None, brain_structure=None, n_surface_vertices=None, voxel_indices_ijk=None, vertex_indices=None)ΒΆ
+

Bases: XmlSerializable

+

Element representing a mapping of the dimension to vertex or voxels.

+

Mapping to vertices of voxels must be specified.

+
    +
  • Description - Maps a range of indices to surface vertices or voxels when +IndicesMapToDataType is β€œCIFTI_INDEX_TYPE_BRAIN_MODELS.”

  • +
  • Attributes

    +
    +
      +
    • IndexOffset - The matrix index of the first brainordinate of this +BrainModel. Note that matrix indices are zero-based.

    • +
    • IndexCount - Number of surface vertices or voxels in this brain +model, must be positive.

    • +
    • ModelType - Type of model representing the brain structure (surface +or voxels). Valid values are listed in the table below.

    • +
    • BrainStructure - Identifies the brain structure. Valid values for +BrainStructure are listed in the table below. However, if the needed +structure is not listed in the table, a message should be posted to +the CIFTI Forum so that a standardized name can be created for the +structure and added to the table.

    • +
    • SurfaceNumberOfVertices - When ModelType is CIFTI_MODEL_TYPE_SURFACE +this attribute contains the actual (or true) number of vertices in +the surface that is associated with this BrainModel. When this +BrainModel represents all vertices in the surface, this value is the +same as IndexCount. When this BrainModel represents only a subset of +the surface’s vertices, IndexCount will be less than this value.

    • +
    +
    +
  • +
  • Child Elements

    +
    +
      +
    • VertexIndices (0…1)

    • +
    • VoxelIndicesIJK (0…1)

    • +
    +
    +
  • +
  • Text Content: [NA]

  • +
  • Parent Element - MatrixIndicesMap

  • +
+

For ModelType values, see CIFTI_MODEL_TYPES module attribute.

+

For BrainStructure values, see CIFTI_BRAIN_STRUCTURES model attribute.

+
+
Attributes:
+
+
index_offsetint

Start of the mapping

+
+
index_countint

Number of elements in the array to be mapped

+
+
model_typestr

One of CIFTI_MODEL_TYPES

+
+
brain_structurestr

One of CIFTI_BRAIN_STRUCTURES

+
+
surface_number_of_verticesint

Number of vertices in the surface. Use only for surface-type structure

+
+
voxel_indices_ijkCifti2VoxelIndicesIJK, optional

Indices on the image towards where the array indices are mapped

+
+
vertex_indicesCifti2VertexIndices, optional

Indices of the vertices towards where the array indices are mapped

+
+
+
+
+
+
+__init__(index_offset=None, index_count=None, model_type=None, brain_structure=None, n_surface_vertices=None, voxel_indices_ijk=None, vertex_indices=None)ΒΆ
+
+ +
+
+property vertex_indicesΒΆ
+
+ +
+
+property voxel_indices_ijkΒΆ
+
+ +
+ +
+
+

Cifti2HeaderΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2Header(matrix=None, version='2.0')ΒΆ
+

Bases: FileBasedHeader, XmlSerializable

+

Class for CIFTI-2 header extension

+
+
+__init__(matrix=None, version='2.0')ΒΆ
+
+ +
+
+classmethod from_axes(axes)ΒΆ
+

Creates a new Cifti2 header based on the Cifti2 axes

+
+
Parameters:
+
+
axestuple of :class`.cifti2_axes.Axis`

sequence of Cifti2 axes describing each row/column of the matrix to be stored

+
+
+
+
Returns:
+
+
headerCifti2Header

new header describing the rows/columns in a format consistent with Cifti2

+
+
+
+
+
+ +
+
+get_axis(index)ΒΆ
+

Generates the Cifti2 axis for a given dimension

+
+
Parameters:
+
+
indexint

Dimension for which we want to obtain the mapping.

+
+
+
+
Returns:
+
+
axiscifti2_axes.Axis
+
+
+
+
+ +
+
+get_index_map(index)ΒΆ
+

Cifti2 Mapping class for a given index

+
+
Parameters:
+
+
indexint

Index for which we want to obtain the mapping. +Must be in the mapped_indices sequence.

+
+
+
+
Returns:
+
+
cifti2_mapCifti2MatrixIndicesMap

Returns the Cifti2MatrixIndicesMap corresponding to +the given index.

+
+
+
+
+
+ +
+
+property mapped_indicesΒΆ
+

List of matrix indices that are mapped

+
+ +
+
+classmethod may_contain_header(binaryblock)ΒΆ
+
+ +
+
+property number_of_mapped_indicesΒΆ
+

Number of mapped indices

+
+ +
+ +
+
+

Cifti2HeaderErrorΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2HeaderErrorΒΆ
+

Bases: Exception

+

Error in CIFTI-2 header

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

Cifti2ImageΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2Image(dataobj=None, header=None, nifti_header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Bases: DataobjImage, SerializableImage

+

Class for single file CIFTI-2 format image

+

Initialize image

+

The image is a combination of (dataobj, header), with optional metadata +in nifti_header (a NIfTI2 header). There may be more metadata in the +mapping extra. Filename / file-like objects can also go in the +file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that +returns an array from np.asanyarray. It should have a +shape attribute or property.

+
+
headerCifti2Header instance or sequence of cifti2_axes.Axis

Header with data for / from XML part of CIFTI-2 format. +Alternatively a sequence of cifti2_axes.Axis objects can be provided +describing each dimension of the array.

+
+
nifti_headerNone or mapping or NIfTI2 header instance, optional

Metadata for NIfTI2 component of this format.

+
+
extraNone or mapping

Extra metadata not captured by header or nifti_header.

+
+
file_mapmapping, optional

Mapping giving file information for this image format.

+
+
+
+
+
+
+__init__(dataobj=None, header=None, nifti_header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Initialize image

+

The image is a combination of (dataobj, header), with optional metadata +in nifti_header (a NIfTI2 header). There may be more metadata in the +mapping extra. Filename / file-like objects can also go in the +file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that +returns an array from np.asanyarray. It should have a +shape attribute or property.

+
+
headerCifti2Header instance or sequence of cifti2_axes.Axis

Header with data for / from XML part of CIFTI-2 format. +Alternatively a sequence of cifti2_axes.Axis objects can be provided +describing each dimension of the array.

+
+
nifti_headerNone or mapping or NIfTI2 header instance, optional

Metadata for NIfTI2 component of this format.

+
+
extraNone or mapping

Extra metadata not captured by header or nifti_header.

+
+
file_mapmapping, optional

Mapping giving file information for this image format.

+
+
+
+
+
+ +
+
+files_types: tuple[ExtensionSpec, ...] = (('image', '.nii'),)ΒΆ
+
+ +
+
+classmethod from_file_map(file_map, *, mmap=True, keep_file_open=None)ΒΆ
+

Load a CIFTI-2 image from a file_map

+
+
Parameters:
+
+
file_mapfile_map
+
+
+
Returns:
+
+
imgCifti2Image

Returns a Cifti2Image

+
+
+
+
+
+ +
+
+classmethod from_image(img)ΒΆ
+

Class method to create new instance of own class from img

+
+
Parameters:
+
+
imginstance

In fact, an object with the API of DataobjImage.

+
+
+
+
Returns:
+
+
cimginstance

Image, of our own class

+
+
+
+
+
+ +
+
+get_data_dtype()ΒΆ
+
+ +
+
+header_classΒΆ
+

alias of Cifti2Header

+
+ +
+
+makeable: bool = FalseΒΆ
+
+ +
+
+property nifti_headerΒΆ
+
+ +
+
+rw: bool = TrueΒΆ
+
+ +
+
+set_data_dtype(dtype)ΒΆ
+
+ +
+
+to_file_map(file_map=None, dtype=None)ΒΆ
+

Write image to file_map or contained self.file_map

+
+
Parameters:
+
+
file_mapNone or mapping, optional

files mapping. If None (default) use object’s file_map +attribute instead.

+
+
+
+
Returns:
+
+
None
+
+
+
+
+ +
+
+update_headers()ΒΆ
+

Harmonize NIfTI headers with image data

+

Ensures that the NIfTI-2 header records the data shape in the last three +dim fields. Per the spec:

+
+

Because the first four dimensions in NIfTI are reserved for space and time, the CIFTI +dimensions are stored in the NIfTI header in dim[5] and up, where dim[5] is the length +of the first CIFTI dimension (number of values in a row), dim[6] is the length of the +second CIFTI dimension, and dim[7] is the length of the third CIFTI dimension, if +applicable. The fields dim[1] through dim[4] will be 1; dim[0] will be 6 or 7, +depending on whether a third matrix dimension exists.

+
+
>>> import numpy as np
+>>> data = np.zeros((2,3,4))
+>>> img = Cifti2Image(data)  
+>>> img.shape == (2, 3, 4)
+True
+>>> img.update_headers()
+>>> img.nifti_header.get_data_shape() == (1, 1, 1, 1, 2, 3, 4)
+True
+>>> img.shape == (2, 3, 4)
+True
+
+
+
+ +
+
+valid_exts: tuple[str, ...] = ('.nii',)ΒΆ
+
+ +
+ +
+
+

Cifti2LabelΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2Label(key=0, label='', red=0.0, green=0.0, blue=0.0, alpha=0.0)ΒΆ
+

Bases: XmlSerializable

+

CIFTI-2 label: association of integer key with a name and RGBA values

+

For all color components, value is floating point with range 0.0 to 1.0.

+
    +
  • Description - Associates a label key value with a name and a display +color.

  • +
  • Attributes

    +
    +
      +
    • Key - Integer, data value which is assigned this name and color.

    • +
    • Red - Red color component for label. Value is floating point with +range 0.0 to 1.0.

    • +
    • Green - Green color component for label. Value is floating point with +range 0.0 to 1.0.

    • +
    • Blue - Blue color component for label. Value is floating point with +range 0.0 to 1.0.

    • +
    • Alpha - Alpha color component for label. Value is floating point with +range 0.0 to 1.0.

    • +
    +
    +
  • +
  • Child Elements: [NA]

  • +
  • Text Content - Name of the label.

  • +
  • Parent Element - LabelTable

  • +
+
+
Attributes:
+
+
keyint, optional

Integer, data value which is assigned this name and color.

+
+
labelstr, optional

Name of the label.

+
+
redfloat, optional

Red color component for label (between 0 and 1).

+
+
greenfloat, optional

Green color component for label (between 0 and 1).

+
+
bluefloat, optional

Blue color component for label (between 0 and 1).

+
+
alphafloat, optional

Alpha color component for label (between 0 and 1).

+
+
+
+
+
+
+__init__(key=0, label='', red=0.0, green=0.0, blue=0.0, alpha=0.0)ΒΆ
+
+ +
+
+property rgbaΒΆ
+

Returns RGBA as tuple

+
+ +
+ +
+
+

Cifti2LabelTableΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2LabelTableΒΆ
+

Bases: XmlSerializable, MutableMapping

+

CIFTI-2 label table: a sequence of Cifti2Labels

+
    +
  • Description - Used by NamedMap when IndicesMapToDataType is +β€œCIFTI_INDEX_TYPE_LABELS” in order to associate names and display colors +with label keys. Note that LABELS is the only mapping type that uses a +LabelTable. Display coloring of continuous-valued data is not specified +by CIFTI-2.

  • +
  • Attributes: [NA]

  • +
  • Child Elements

    +
    +
      +
    • Label (0…N)

    • +
    +
    +
  • +
  • Text Content: [NA]

  • +
  • Parent Element - NamedMap

  • +
+
+
+__init__()ΒΆ
+
+ +
+
+append(label)ΒΆ
+
+ +
+ +
+
+

Cifti2MatrixΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2MatrixΒΆ
+

Bases: XmlSerializable, MutableSequence

+

CIFTI-2 Matrix object

+

This is a list-like container where the elements are instances of +Cifti2MatrixIndicesMap.

+
    +
  • Description: contains child elements that describe the meaning of the +values in the matrix.

  • +
  • Attributes: [NA]

  • +
  • Child Elements

    +
    +
      +
    • MetaData (0 .. 1)

    • +
    • MatrixIndicesMap (1 .. N)

    • +
    +
    +
  • +
  • Text Content: [NA]

  • +
  • Parent Element: CIFTI

  • +
+

For each matrix (data) dimension, exactly one MatrixIndicesMap element must +list it in the AppliesToMatrixDimension attribute.

+
+
+__init__()ΒΆ
+
+ +
+
+get_axis(index)ΒΆ
+

Generates the Cifti2 axis for a given dimension

+
+
Parameters:
+
+
indexint

Dimension for which we want to obtain the mapping.

+
+
+
+
Returns:
+
+
axiscifti2_axes.Axis
+
+
+
+
+ +
+
+get_data_shape()ΒΆ
+

Returns data shape expected based on the CIFTI-2 header

+

Any dimensions omitted in the CIFTI-2 header will be given a default size of None.

+
+ +
+
+get_index_map(index)ΒΆ
+

Cifti2 Mapping class for a given index

+
+
Parameters:
+
+
indexint

Index for which we want to obtain the mapping. +Must be in the mapped_indices sequence.

+
+
+
+
Returns:
+
+
cifti2_mapCifti2MatrixIndicesMap

Returns the Cifti2MatrixIndicesMap corresponding to +the given index.

+
+
+
+
+
+ +
+
+insert(index, value)ΒΆ
+

S.insert(index, value) – insert value before index

+
+ +
+
+property mapped_indicesΒΆ
+

List of matrix indices that are mapped

+
+ +
+
+property metadataΒΆ
+
+ +
+ +
+
+

Cifti2MatrixIndicesMapΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap(applies_to_matrix_dimension, indices_map_to_data_type, number_of_series_points=None, series_exponent=None, series_start=None, series_step=None, series_unit=None, maps=[])ΒΆ
+

Bases: XmlSerializable, MutableSequence

+

Class for Matrix Indices Map

+
    +
  • Description - Provides a mapping between matrix indices and their +interpretation.

  • +
  • Attributes

    +
    +
      +
    • AppliesToMatrixDimension - Lists the dimension(s) of the matrix to +which this MatrixIndicesMap applies. The dimensions of the matrix +start at zero (dimension 0 describes the indices along the first +dimension, dimension 1 describes the indices along the second +dimension, etc.). If this MatrixIndicesMap applies to more than one +matrix dimension, the values are separated by a comma.

    • +
    • IndicesMapToDataType - Type of data to which the MatrixIndicesMap +applies.

    • +
    • NumberOfSeriesPoints - Indicates how many samples there are in a +series mapping type. For example, this could be the number of +timepoints in a timeseries.

    • +
    • SeriesExponent - Integer, SeriesStart and SeriesStep must be +multiplied by 10 raised to the power of the value of this attribute +to give the actual values assigned to indices (e.g., if SeriesStart +is β€œ5” and SeriesExponent is β€œ-3”, the value of the first series +point is 0.005).

    • +
    • SeriesStart - Indicates what quantity should be assigned to the first +series point.

    • +
    • SeriesStep - Indicates amount of change between each series point.

    • +
    • SeriesUnit - Indicates the unit of the result of multiplying +SeriesStart and SeriesStep by 10 to the power of SeriesExponent.

    • +
    +
    +
  • +
  • Child Elements

    +
    +
      +
    • BrainModel (0…N)

    • +
    • NamedMap (0…N)

    • +
    • Parcel (0…N)

    • +
    • Surface (0…N)

    • +
    • Volume (0…1)

    • +
    +
    +
  • +
  • Text Content: [NA]

  • +
  • Parent Element - Matrix

  • +
+
+
Attributes:
+
+
applies_to_matrix_dimensionlist of ints

Dimensions of this matrix that follow this mapping

+
+
indices_map_to_data_typestr one of CIFTI_MAP_TYPES

Type of mapping to the matrix indices

+
+
number_of_series_pointsint, optional

If it is a series, number of points in the series

+
+
series_exponentint, optional

If it is a series the exponent of the increment

+
+
series_startfloat, optional

If it is a series, starting time

+
+
series_stepfloat, optional

If it is a series, step per element

+
+
series_unitstr, optional

If it is a series, units

+
+
+
+
+
+
+__init__(applies_to_matrix_dimension, indices_map_to_data_type, number_of_series_points=None, series_exponent=None, series_start=None, series_step=None, series_unit=None, maps=[])ΒΆ
+
+ +
+
+property brain_modelsΒΆ
+
+ +
+
+insert(index, value)ΒΆ
+

S.insert(index, value) – insert value before index

+
+ +
+
+property named_mapsΒΆ
+
+ +
+
+property parcelsΒΆ
+
+ +
+
+property surfacesΒΆ
+
+ +
+
+property volumeΒΆ
+
+ +
+ +
+
+

Cifti2MetaDataΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2MetaData(*args, **kwargs)ΒΆ
+

Bases: CaretMetaData

+

A list of name-value pairs

+
    +
  • Description - Provides a simple method for user-supplied metadata that +associates names with values.

  • +
  • Attributes: [NA]

  • +
  • Child Elements

    +
    +
      +
    • MD (0…N)

    • +
    +
    +
  • +
  • Text Content: [NA]

  • +
  • Parent Elements - Matrix, NamedMap

  • +
+

MD elements are a single metadata entry consisting of a name and a value.

+
+
Attributes:
+
+
datalist of (name, value) tuples
+
+
+
+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+property dataΒΆ
+
+ +
+
+difference_update(metadata)ΒΆ
+

Remove metadata key-value pairs

+
+
Parameters:
+
+
metadatadict-like datatype
+
+
+
Returns:
+
+
None
+
+
+
+
+ +
+ +
+
+

Cifti2NamedMapΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2NamedMap(map_name=None, metadata=None, label_table=None)ΒΆ
+

Bases: XmlSerializable

+

CIFTI-2 named map: association of name and optional data with a map index

+

Associates a name, optional metadata, and possibly a LabelTable with an +index in a map.

+
    +
  • Description - Associates a name, optional metadata, and possibly a +LabelTable with an index in a map.

  • +
  • Attributes: [NA]

  • +
  • Child Elements

    +
    +
      +
    • MapName (1)

    • +
    • LabelTable (0…1)

    • +
    • MetaData (0…1)

    • +
    +
    +
  • +
  • Text Content: [NA]

  • +
  • Parent Element - MatrixIndicesMap

  • +
+
+
Attributes:
+
+
map_namestr

Name of map

+
+
metadataNone or Cifti2MetaData

Metadata associated with named map

+
+
label_tableNone or Cifti2LabelTable

Label table associated with named map

+
+
+
+
+
+
+__init__(map_name=None, metadata=None, label_table=None)ΒΆ
+
+ +
+
+property label_tableΒΆ
+
+ +
+
+property metadataΒΆ
+
+ +
+ +
+
+

Cifti2ParcelΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2Parcel(name=None, voxel_indices_ijk=None, vertices=None)ΒΆ
+

Bases: XmlSerializable

+

CIFTI-2 parcel: association of a name with vertices and/or voxels

+
    +
  • Description - Associates a name, plus vertices and/or voxels, with an +index.

  • +
  • Attributes

    +
    +
      +
    • Name - The name of the parcel

    • +
    +
    +
  • +
  • Child Elements

    +
    +
      +
    • Vertices (0…N)

    • +
    • VoxelIndicesIJK (0…1)

    • +
    +
    +
  • +
  • Text Content: [NA]

  • +
  • Parent Element - MatrixIndicesMap

  • +
+
+
Attributes:
+
+
namestr

Name of parcel

+
+
voxel_indices_ijkNone or Cifti2VoxelIndicesIJK

Voxel indices associated with parcel

+
+
verticeslist of Cifti2Vertices

Vertices associated with parcel

+
+
+
+
+
+
+__init__(name=None, voxel_indices_ijk=None, vertices=None)ΒΆ
+
+ +
+
+append_cifti_vertices(vertices)ΒΆ
+

Appends a Cifti2Vertices element to the Cifti2Parcel

+
+
Parameters:
+
+
verticesCifti2Vertices
+
+
+
+
+ +
+
+pop_cifti2_vertices(ith)ΒΆ
+

Pops the ith vertices element from the Cifti2Parcel

+
+ +
+
+property voxel_indices_ijkΒΆ
+
+ +
+ +
+
+

Cifti2SurfaceΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2Surface(brain_structure=None, surface_number_of_vertices=None)ΒΆ
+

Bases: XmlSerializable

+

Cifti surface: association of brain structure and number of vertices

+
    +
  • Description - Specifies the number of vertices for a surface, when +IndicesMapToDataType is β€œCIFTI_INDEX_TYPE_PARCELS.” This is separate from +the Parcel element because there can be multiple parcels on one surface, +and one parcel may involve multiple surfaces.

  • +
  • Attributes

    +
    +
      +
    • BrainStructure - A string from the BrainStructure list to identify +what surface structure this element refers to (usually left cortex, +right cortex, or cerebellum).

    • +
    • SurfaceNumberOfVertices - The number of vertices that this +structure’s surface contains.

    • +
    +
    +
  • +
  • Child Elements: [NA]

  • +
  • Text Content: [NA]

  • +
  • Parent Element - MatrixIndicesMap

  • +
+
+
Attributes:
+
+
brain_structurestr

Name of brain structure

+
+
surface_number_of_verticesint

Number of vertices on surface

+
+
+
+
+
+
+__init__(brain_structure=None, surface_number_of_vertices=None)ΒΆ
+
+ +
+ +
+
+

Cifti2TransformationMatrixVoxelIndicesIJKtoXYZΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(meter_exponent=None, matrix=None)ΒΆ
+

Bases: XmlSerializable

+

Matrix that translates voxel indices to spatial coordinates

+
    +
  • Description - Contains a matrix that translates Voxel IJK Indices to +spatial XYZ coordinates (+X=>right, +Y=>anterior, +Z=> superior). The +resulting coordinate is the center of the voxel.

  • +
  • Attributes

    +
    +
      +
    • MeterExponent - Integer, specifies that the coordinate result from +the transformation matrix should be multiplied by 10 to this power to +get the spatial coordinates in meters (e.g., if this is β€œ-3”, then +the transformation matrix is in millimeters).

    • +
    +
    +
  • +
  • Child Elements: [NA]

  • +
  • Text Content - Sixteen floating-point values, in row-major order, that +form a 4x4 homogeneous transformation matrix.

  • +
  • Parent Element - Volume

  • +
+
+
Attributes:
+
+
meter_exponentint

See attribute description above.

+
+
matrixarray-like shape (4, 4)

Affine transformation matrix from voxel indices to RAS space.

+
+
+
+
+
+
+__init__(meter_exponent=None, matrix=None)ΒΆ
+
+ +
+ +
+
+

Cifti2VertexIndicesΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2VertexIndices(indices=None)ΒΆ
+

Bases: XmlSerializable, MutableSequence

+

CIFTI-2 vertex indices: vertex indices for an associated brain model

+

The vertex indices (which are independent for each surface, and +zero-based) that are used in this brain model[.] The parent +BrainModel’s index_count indicates the number of indices.

+
    +
  • Description - Contains a list of vertex indices for a BrainModel with +ModelType equal to CIFTI_MODEL_TYPE_SURFACE.

  • +
  • Attributes: [NA]

  • +
  • Child Elements: [NA]

  • +
  • Text Content - The vertex indices (which are independent for each +surface, and zero-based) that are used in this brain model, with each +index separated by a whitespace character. The parent BrainModel’s +IndexCount attribute indicates the number of indices in this element’s +content.

  • +
  • Parent Element - BrainModel

  • +
+
+
+__init__(indices=None)ΒΆ
+
+ +
+
+insert(index, value)ΒΆ
+

S.insert(index, value) – insert value before index

+
+ +
+ +
+
+

Cifti2VerticesΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2Vertices(brain_structure=None, vertices=None)ΒΆ
+

Bases: XmlSerializable, MutableSequence

+

CIFTI-2 vertices - association of brain structure and a list of vertices

+
    +
  • Description - Contains a BrainStructure type and a list of vertex indices +within a Parcel.

  • +
  • Attributes

    +
    +
      +
    • BrainStructure - A string from the BrainStructure list to identify +what surface this vertex list is from (usually left cortex, right +cortex, or cerebellum).

    • +
    +
    +
  • +
  • Child Elements: [NA]

  • +
  • Text Content - Vertex indices (which are independent for each surface, +and zero-based) separated by whitespace characters.

  • +
  • Parent Element - Parcel

  • +
+

The class behaves like a list of Vertex indices (which are independent for +each surface, and zero-based)

+
+
Attributes:
+
+
brain_structurestr

A string from the BrainStructure list to identify what surface this +vertex list is from (usually left cortex, right cortex, or cerebellum).

+
+
+
+
+
+
+__init__(brain_structure=None, vertices=None)ΒΆ
+
+ +
+
+insert(index, value)ΒΆ
+

S.insert(index, value) – insert value before index

+
+ +
+ +
+
+

Cifti2VolumeΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2Volume(volume_dimensions=None, transform_matrix=None)ΒΆ
+

Bases: XmlSerializable

+

CIFTI-2 volume: information about a volume for mappings that use voxels

+
    +
  • Description - Provides information about the volume for any mappings that +use voxels.

  • +
  • Attributes

    +
    +
      +
    • VolumeDimensions - Three integer values separated by commas, the +lengths of the three volume file dimensions that are related to +spatial coordinates, in number of voxels. Voxel indices (which are +zero-based) that are used in the mapping that this element applies to +must be within these dimensions.

    • +
    +
    +
  • +
  • Child Elements

    +
    +
      +
    • TransformationMatrixVoxelIndicesIJKtoXYZ (1)

    • +
    +
    +
  • +
  • Text Content: [NA]

  • +
  • Parent Element - MatrixIndicesMap

  • +
+
+
Attributes:
+
+
volume_dimensionsarray-like shape (3,)

See attribute description above.

+
+
transformation_matrix_voxel_indices_ijk_to_xyzCifti2TransformationMatrixVoxelIndicesIJKtoXYZ

Matrix that translates voxel indices to spatial coordinates

+
+
+
+
+
+
+__init__(volume_dimensions=None, transform_matrix=None)ΒΆ
+
+ +
+ +
+
+

Cifti2VoxelIndicesIJKΒΆ

+
+
+class nibabel.cifti2.cifti2.Cifti2VoxelIndicesIJK(indices=None)ΒΆ
+

Bases: XmlSerializable, MutableSequence

+

CIFTI-2 VoxelIndicesIJK: Set of voxel indices contained in a structure

+
    +
  • Description - Identifies the voxels that model a brain structure, or +participate in a parcel. Note that when this is a child of BrainModel, +the IndexCount attribute of the BrainModel indicates the number of voxels +contained in this element.

  • +
  • Attributes: [NA]

  • +
  • Child Elements: [NA]

  • +
  • Text Content - IJK indices (which are zero-based) of each voxel in this +brain model or parcel, with each index separated by a whitespace +character. There are three indices per voxel. If the parent element is +BrainModel, then the BrainModel element’s IndexCount attribute indicates +the number of triplets (IJK indices) in this element’s content.

  • +
  • Parent Elements - BrainModel, Parcel

  • +
+

Each element of this sequence is a triple of integers.

+
+
+__init__(indices=None)ΒΆ
+
+ +
+
+insert(index, value)ΒΆ
+

S.insert(index, value) – insert value before index

+
+ +
+ +
+
+

LimitedNifti2HeaderΒΆ

+
+
+class nibabel.cifti2.cifti2.LimitedNifti2Header(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Bases: Nifti2Header

+

Initialize header from binary data block and extensions

+
+
+__init__(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Initialize header from binary data block and extensions

+
+ +
+ +
+
+

AxisΒΆ

+
+
+class nibabel.cifti2.cifti2_axes.AxisΒΆ
+

Bases: ABC

+

Abstract class for any object describing the rows or columns of a CIFTI-2 vector/matrix

+

Mainly used for type checking.

+

Base class for the following concrete CIFTI-2 axes:

+
    +
  • BrainModelAxis: each row/column is a voxel or vertex

  • +
  • ParcelsAxis: each row/column is a group of voxels and/or vertices

  • +
  • ScalarAxis: each row/column has a unique name with optional meta-data

  • +
  • LabelAxis: each row/column has a unique name and label table with optional meta-data

  • +
  • SeriesAxis: each row/column is a timepoint, which increases monotonically

  • +
+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+property sizeΒΆ
+
+ +
+ +
+
+

BrainModelAxisΒΆ

+
+
+class nibabel.cifti2.cifti2_axes.BrainModelAxis(name, voxel=None, vertex=None, affine=None, volume_shape=None, nvertices=None)ΒΆ
+

Bases: Axis

+

Each row/column in the CIFTI-2 vector/matrix represents a single vertex or voxel

+

This Axis describes which vertex/voxel is represented by each row/column.

+

New BrainModelAxis axes can be constructed by passing on the greyordinate brain-structure +names and voxel/vertex indices to the constructor or by one of the +factory methods:

+
    +
  • from_mask(): creates surface or volumetric BrainModelAxis axis +from respectively 1D or 3D masks

  • +
  • from_surface(): creates a surface BrainModelAxis axis

  • +
+

The resulting BrainModelAxis axes can be concatenated by adding them together.

+
+
Parameters:
+
+
namearray_like

brain structure name or (N, ) string array with the brain structure names

+
+
voxelarray_like, optional

(N, 3) array with the voxel indices (can be omitted for CIFTI-2 files only +covering the surface)

+
+
vertexarray_like, optional

(N, ) array with the vertex indices (can be omitted for volumetric CIFTI-2 files)

+
+
affinearray_like, optional

(4, 4) array mapping voxel indices to mm space (not needed for CIFTI-2 files only +covering the surface)

+
+
volume_shapetuple of three integers, optional

shape of the volume in which the voxels were defined (not needed for CIFTI-2 files only +covering the surface)

+
+
nverticesdict from string to integer, optional

maps names of surface elements to integers (not needed for volumetric CIFTI-2 files)

+
+
+
+
+
+
+__init__(name, voxel=None, vertex=None, affine=None, volume_shape=None, nvertices=None)ΒΆ
+

New BrainModelAxis axes can be constructed by passing on the greyordinate brain-structure +names and voxel/vertex indices to the constructor or by one of the +factory methods:

+
    +
  • from_mask(): creates surface or volumetric BrainModelAxis axis +from respectively 1D or 3D masks

  • +
  • from_surface(): creates a surface BrainModelAxis axis

  • +
+

The resulting BrainModelAxis axes can be concatenated by adding them together.

+
+
Parameters:
+
+
namearray_like

brain structure name or (N, ) string array with the brain structure names

+
+
voxelarray_like, optional

(N, 3) array with the voxel indices (can be omitted for CIFTI-2 files only +covering the surface)

+
+
vertexarray_like, optional

(N, ) array with the vertex indices (can be omitted for volumetric CIFTI-2 files)

+
+
affinearray_like, optional

(4, 4) array mapping voxel indices to mm space (not needed for CIFTI-2 files only +covering the surface)

+
+
volume_shapetuple of three integers, optional

shape of the volume in which the voxels were defined (not needed for CIFTI-2 files only +covering the surface)

+
+
nverticesdict from string to integer, optional

maps names of surface elements to integers (not needed for volumetric CIFTI-2 files)

+
+
+
+
+
+ +
+
+property affineΒΆ
+

Affine of the volumetric image in which the greyordinate voxels were defined

+
+ +
+
+classmethod from_index_mapping(mim)ΒΆ
+

Creates a new BrainModel axis based on a CIFTI-2 dataset

+
+
Parameters:
+
+
mimcifti2.Cifti2MatrixIndicesMap
+
+
+
Returns:
+
+
BrainModelAxis
+
+
+
+
+ +
+
+classmethod from_mask(mask, name='other', affine=None)ΒΆ
+

Creates a new BrainModelAxis axis describing the provided mask

+
+
Parameters:
+
+
maskarray_like

all non-zero voxels will be included in the BrainModelAxis axis +should be (Nx, Ny, Nz) array for volume mask or (Nvertex, ) array for surface mask

+
+
namestr, optional

Name of the brain structure (e.g. β€˜CortexRight’, β€˜thalamus_left’ or β€˜brain_stem’)

+
+
affinearray_like, optional

(4, 4) array with the voxel to mm transformation (defaults to identity matrix) +Argument will be ignored for surface masks

+
+
+
+
Returns:
+
+
BrainModelAxis which covers the provided mask
+
+
+
+
+ +
+
+classmethod from_surface(vertices, nvertex, name='Other')ΒΆ
+

Creates a new BrainModelAxis axis describing the vertices on a surface

+
+
Parameters:
+
+
verticesarray_like

indices of the vertices on the surface

+
+
nvertexint

total number of vertices on the surface

+
+
namestr

Name of the brain structure (e.g. β€˜CortexLeft’ or β€˜CortexRight’)

+
+
+
+
Returns:
+
+
BrainModelAxis which covers (part of) the surface
+
+
+
+
+ +
+
+get_element(index)ΒΆ
+

Describes a single element from the axis

+
+
Parameters:
+
+
indexint

Indexes the row/column of interest

+
+
+
+
Returns:
+
+
tuple with 3 elements
+
+
    +
  • +
    str, β€˜CIFTI_MODEL_TYPE_SURFACE’ for vertex or β€˜CIFTI_MODEL_TYPE_VOXELS’ for voxel
    +
    +
  • +
  • +
    vertex index if it is a surface element, otherwise array with 3 voxel indices
    +
    +
  • +
  • +
    structure.BrainStructure object describing the brain structure the element was taken from
    +
    +
  • +
+
+
+
+ +
+
+iter_structures()ΒΆ
+

Iterates over all brain structures in the order that they appear along the axis

+
+
Yields:
+
+
tuple with 3 elements:
+
+
    +
  • +
    CIFTI-2 brain structure name
    +
    +
  • +
  • +
    slice to select the data associated with the brain structure from the tensor
    +
    +
  • +
  • +
    brain model covering that specific brain structure
    +
    +
  • +
+
+
+
+ +
+
+property nameΒΆ
+

The brain structure to which the voxel/vertices of belong

+
+ +
+
+property surface_maskΒΆ
+

(N, ) boolean array which is true for any element on the surface

+
+ +
+
+static to_cifti_brain_structure_name(name)ΒΆ
+

Attempts to convert the name of an anatomical region in a format recognized by CIFTI-2

+

This function returns:

+
    +
  • the name if it is in the CIFTI-2 format already

  • +
  • if the name is a tuple the first element is assumed to be the structure name while +the second is assumed to be the hemisphere (left, right or both). The latter will default +to both.

  • +
  • names like left_cortex, cortex_left, LeftCortex, or CortexLeft will be converted to +CIFTI_STRUCTURE_CORTEX_LEFT

  • +
+

see nibabel.cifti2.tests.test_name() for examples of +which conversions are possible

+
+
Parameters:
+
+
name: iterable of 2-element tuples of integer and string

input name of an anatomical region

+
+
+
+
Returns:
+
+
CIFTI-2 compatible name
+
+
+
Raises:
+
+
ValueError: raised if the input name does not match a known anatomical structure in CIFTI-2
+
+
+
+
+ +
+
+to_mapping(dim)ΒΆ
+

Converts the brain model axis to a MatrixIndicesMap for storage in CIFTI-2 format

+
+
Parameters:
+
+
dimint

which dimension of the CIFTI-2 vector/matrix is described by this dataset (zero-based)

+
+
+
+
Returns:
+
+
cifti2.Cifti2MatrixIndicesMap
+
+
+
+
+ +
+
+property volume_maskΒΆ
+

(N, ) boolean array which is true for any element on the surface

+
+ +
+
+property volume_shapeΒΆ
+

Shape of the volumetric image in which the greyordinate voxels were defined

+
+ +
+ +
+
+

LabelAxisΒΆ

+
+
+class nibabel.cifti2.cifti2_axes.LabelAxis(name, label, meta=None)ΒΆ
+

Bases: Axis

+

Defines CIFTI-2 axis for label array.

+

Along this axis of the CIFTI-2 vector/matrix each row/column has been given a unique name, +label table, and optionally metadata

+
+
Parameters:
+
+
namearray_like

(N, ) string array with the parcel names

+
+
labelarray_like

single dictionary or (N, ) object array with dictionaries mapping +from integers to (name, (R, G, B, A)), where name is a string and R, G, B, and A are +floats between 0 and 1 giving the colour and alpha (i.e., transparency)

+
+
metaarray_like, optional

(N, ) object array with a dictionary of metadata for each row/column

+
+
+
+
+
+
+__init__(name, label, meta=None)ΒΆ
+
+
Parameters:
+
+
namearray_like

(N, ) string array with the parcel names

+
+
labelarray_like

single dictionary or (N, ) object array with dictionaries mapping +from integers to (name, (R, G, B, A)), where name is a string and R, G, B, and A are +floats between 0 and 1 giving the colour and alpha (i.e., transparency)

+
+
metaarray_like, optional

(N, ) object array with a dictionary of metadata for each row/column

+
+
+
+
+
+ +
+
+classmethod from_index_mapping(mim)ΒΆ
+

Creates a new Label axis based on a CIFTI-2 dataset

+
+
Parameters:
+
+
mimcifti2.Cifti2MatrixIndicesMap
+
+
+
Returns:
+
+
LabelAxis
+
+
+
+
+ +
+
+get_element(index)ΒΆ
+

Describes a single element from the axis

+
+
Parameters:
+
+
indexint

Indexes the row/column of interest

+
+
+
+
Returns:
+
+
tuple with 2 elements
+
+
    +
  • +
    unicode name of the row/column
    +
    +
  • +
  • +
    dictionary with the label table
    +
    +
  • +
  • +
    dictionary with the element metadata
    +
    +
  • +
+
+
+
+ +
+
+to_mapping(dim)ΒΆ
+

Converts the hcp_labels to a MatrixIndicesMap for storage in CIFTI-2 format

+
+
Parameters:
+
+
dimint

which dimension of the CIFTI-2 vector/matrix is described by this dataset (zero-based)

+
+
+
+
Returns:
+
+
cifti2.Cifti2MatrixIndicesMap
+
+
+
+
+ +
+ +
+
+

ParcelsAxisΒΆ

+
+
+class nibabel.cifti2.cifti2_axes.ParcelsAxis(name, voxels, vertices, affine=None, volume_shape=None, nvertices=None)ΒΆ
+

Bases: Axis

+

Each row/column in the CIFTI-2 vector/matrix represents a parcel of voxels/vertices

+

This Axis describes which parcel is represented by each row/column.

+

Individual parcels can be accessed based on their name, using +parcel = parcel_axis[name]

+

Use of this constructor is not recommended. New ParcelsAxis axes can be constructed more +easily from a sequence of BrainModelAxis axes using +from_brain_models()

+
+
Parameters:
+
+
namearray_like

(N, ) string array with the parcel names

+
+
voxelsarray_like

(N, ) object array each containing a sequence of voxels. +For each parcel the voxels are represented by a (M, 3) index array

+
+
verticesarray_like

(N, ) object array each containing a sequence of vertices. +For each parcel the vertices are represented by a mapping from brain structure name to +(M, ) index array

+
+
affinearray_like, optional

(4, 4) array mapping voxel indices to mm space (not needed for CIFTI-2 files only +covering the surface)

+
+
volume_shapetuple of three integers, optional

shape of the volume in which the voxels were defined (not needed for CIFTI-2 files only +covering the surface)

+
+
nverticesdict from string to integer, optional

maps names of surface elements to integers (not needed for volumetric CIFTI-2 files)

+
+
+
+
+
+
+__init__(name, voxels, vertices, affine=None, volume_shape=None, nvertices=None)ΒΆ
+

Use of this constructor is not recommended. New ParcelsAxis axes can be constructed more +easily from a sequence of BrainModelAxis axes using +from_brain_models()

+
+
Parameters:
+
+
namearray_like

(N, ) string array with the parcel names

+
+
voxelsarray_like

(N, ) object array each containing a sequence of voxels. +For each parcel the voxels are represented by a (M, 3) index array

+
+
verticesarray_like

(N, ) object array each containing a sequence of vertices. +For each parcel the vertices are represented by a mapping from brain structure name to +(M, ) index array

+
+
affinearray_like, optional

(4, 4) array mapping voxel indices to mm space (not needed for CIFTI-2 files only +covering the surface)

+
+
volume_shapetuple of three integers, optional

shape of the volume in which the voxels were defined (not needed for CIFTI-2 files only +covering the surface)

+
+
nverticesdict from string to integer, optional

maps names of surface elements to integers (not needed for volumetric CIFTI-2 files)

+
+
+
+
+
+ +
+
+property affineΒΆ
+

Affine of the volumetric image in which the greyordinate voxels were defined

+
+ +
+
+classmethod from_brain_models(named_brain_models)ΒΆ
+

Creates a Parcel axis from a list of BrainModelAxis axes with names

+
+
Parameters:
+
+
named_brain_modelsiterable of 2-element tuples of string and BrainModelAxis

list of (parcel name, brain model representation) pairs defining each parcel

+
+
+
+
Returns:
+
+
ParcelsAxis
+
+
+
+
+ +
+
+classmethod from_index_mapping(mim)ΒΆ
+

Creates a new Parcels axis based on a CIFTI-2 dataset

+
+
Parameters:
+
+
mimcifti2.Cifti2MatrixIndicesMap
+
+
+
Returns:
+
+
ParcelsAxis
+
+
+
+
+ +
+
+get_element(index)ΒΆ
+

Describes a single element from the axis

+
+
Parameters:
+
+
indexint

Indexes the row/column of interest

+
+
+
+
Returns:
+
+
tuple with 3 elements
+
+
    +
  • +
    unicode name of the parcel
    +
    +
  • +
  • +
    (M, 3) int array with voxel indices
    +
    +
  • +
  • +
    dict from string to (K, ) int array with vertex indices

    for a specific surface brain structure

    +
    +
    +
  • +
+
+
+
+ +
+
+to_mapping(dim)ΒΆ
+

Converts the Parcel to a MatrixIndicesMap for storage in CIFTI-2 format

+
+
Parameters:
+
+
dimint

which dimension of the CIFTI-2 vector/matrix is described by this dataset (zero-based)

+
+
+
+
Returns:
+
+
cifti2.Cifti2MatrixIndicesMap
+
+
+
+
+ +
+
+property volume_shapeΒΆ
+

Shape of the volumetric image in which the greyordinate voxels were defined

+
+ +
+ +
+
+

ScalarAxisΒΆ

+
+
+class nibabel.cifti2.cifti2_axes.ScalarAxis(name, meta=None)ΒΆ
+

Bases: Axis

+

Along this axis of the CIFTI-2 vector/matrix each row/column has been given +a unique name and optionally metadata

+
+
Parameters:
+
+
namearray_like

(N, ) string array with the parcel names

+
+
metaarray_like

(N, ) object array with a dictionary of metadata for each row/column. +Defaults to empty dictionary

+
+
+
+
+
+
+__init__(name, meta=None)ΒΆ
+
+
Parameters:
+
+
namearray_like

(N, ) string array with the parcel names

+
+
metaarray_like

(N, ) object array with a dictionary of metadata for each row/column. +Defaults to empty dictionary

+
+
+
+
+
+ +
+
+classmethod from_index_mapping(mim)ΒΆ
+

Creates a new Scalar axis based on a CIFTI-2 dataset

+
+
Parameters:
+
+
mimcifti2.Cifti2MatrixIndicesMap
+
+
+
Returns:
+
+
ScalarAxis
+
+
+
+
+ +
+
+get_element(index)ΒΆ
+

Describes a single element from the axis

+
+
Parameters:
+
+
indexint

Indexes the row/column of interest

+
+
+
+
Returns:
+
+
tuple with 2 elements
+
+
    +
  • +
    unicode name of the row/column
    +
    +
  • +
  • +
    dictionary with the element metadata
    +
    +
  • +
+
+
+
+ +
+
+to_mapping(dim)ΒΆ
+

Converts the hcp_labels to a MatrixIndicesMap for storage in CIFTI-2 format

+
+
Parameters:
+
+
dimint

which dimension of the CIFTI-2 vector/matrix is described by this dataset (zero-based)

+
+
+
+
Returns:
+
+
cifti2.Cifti2MatrixIndicesMap
+
+
+
+
+ +
+ +
+
+

SeriesAxisΒΆ

+
+
+class nibabel.cifti2.cifti2_axes.SeriesAxis(start, step, size, unit='SECOND')ΒΆ
+

Bases: Axis

+

Along this axis of the CIFTI-2 vector/matrix the rows/columns increase monotonously in time

+

This Axis describes the time point of each row/column.

+

Creates a new SeriesAxis axis

+
+
Parameters:
+
+
startfloat

starting time point

+
+
stepfloat

sampling time (TR)

+
+
sizeint

number of time points

+
+
unitstr

Unit of the step size (one of β€˜second’, β€˜hertz’, β€˜meter’, or β€˜radian’)

+
+
+
+
+
+
+__init__(start, step, size, unit='SECOND')ΒΆ
+

Creates a new SeriesAxis axis

+
+
Parameters:
+
+
startfloat

starting time point

+
+
stepfloat

sampling time (TR)

+
+
sizeint

number of time points

+
+
unitstr

Unit of the step size (one of β€˜second’, β€˜hertz’, β€˜meter’, or β€˜radian’)

+
+
+
+
+
+ +
+
+classmethod from_index_mapping(mim)ΒΆ
+

Creates a new SeriesAxis axis based on a CIFTI-2 dataset

+
+
Parameters:
+
+
mimcifti2.Cifti2MatrixIndicesMap
+
+
+
Returns:
+
+
SeriesAxis
+
+
+
+
+ +
+
+get_element(index)ΒΆ
+

Gives the time point of a specific row/column

+
+
Parameters:
+
+
indexint

Indexes the row/column of interest

+
+
+
+
Returns:
+
+
float
+
+
+
+
+ +
+
+size = NoneΒΆ
+
+ +
+
+property timeΒΆ
+
+ +
+
+to_mapping(dim)ΒΆ
+

Converts the SeriesAxis to a MatrixIndicesMap for storage in CIFTI-2 format

+
+
Parameters:
+
+
dimint

which dimension of the CIFTI-2 vector/matrix is described by this dataset (zero-based)

+
+
+
+
Returns:
+
+
cifti2.Cifti2MatrixIndicesMap
+
+
+
+
+ +
+
+property unitΒΆ
+
+ +
+ +
+
+

from_index_mappingΒΆ

+
+
+nibabel.cifti2.cifti2_axes.from_index_mapping(mim)ΒΆ
+

Parses the MatrixIndicesMap to find the appropriate CIFTI-2 axis describing the rows or columns

+
+
Parameters:
+
+
mimcifti2.Cifti2MatrixIndicesMap
+
+
+
Returns:
+
+
axissubclass of Axis
+
+
+
+
+ +
+
+

to_headerΒΆ

+
+
+nibabel.cifti2.cifti2_axes.to_header(axes)ΒΆ
+

Converts the axes describing the rows/columns of a CIFTI-2 vector/matrix to a Cifti2Header

+
+
Parameters:
+
+
axesiterable of Axis objects

one or more axes describing each dimension in turn

+
+
+
+
Returns:
+
+
headercifti2.Cifti2Header
+
+
+
+
+ +
+
+

Cifti2ExtensionΒΆ

+
+
+class nibabel.cifti2.parse_cifti2.Cifti2Extension(code=None, content=None)ΒΆ
+

Bases: Nifti1Extension

+
+
Parameters:
+
+
codeint or str

Canonical extension code as defined in the NIfTI standard, given +either as integer or corresponding label +(see extension_codes)

+
+
contentstr

Extension content as read from the NIfTI file header. This content is +converted into a runtime representation.

+
+
+
+
+
+
+__init__(code=None, content=None)ΒΆ
+
+
Parameters:
+
+
codeint or str

Canonical extension code as defined in the NIfTI standard, given +either as integer or corresponding label +(see extension_codes)

+
+
contentstr

Extension content as read from the NIfTI file header. This content is +converted into a runtime representation.

+
+
+
+
+
+ +
+
+code = 32ΒΆ
+
+ +
+ +
+
+

Cifti2ParserΒΆ

+
+
+class nibabel.cifti2.parse_cifti2.Cifti2Parser(encoding=None, buffer_size=3500000, verbose=0)ΒΆ
+

Bases: XmlParser

+

Class to parse an XML string into a CIFTI-2 header object

+
+
Parameters:
+
+
encodingstr

string containing xml document

+
+
buffer_size: None or int, optional

size of read buffer. None uses default buffer_size +from xml.parsers.expat.

+
+
verboseint, optional

amount of output during parsing (0=silent, by default).

+
+
+
+
+
+
+__init__(encoding=None, buffer_size=3500000, verbose=0)ΒΆ
+
+
Parameters:
+
+
encodingstr

string containing xml document

+
+
buffer_size: None or int, optional

size of read buffer. None uses default buffer_size +from xml.parsers.expat.

+
+
verboseint, optional

amount of output during parsing (0=silent, by default).

+
+
+
+
+
+ +
+
+CharacterDataHandler(data)ΒΆ
+

Collect character data chunks pending collation

+

The parser breaks the data up into chunks of size depending on the +buffer_size of the parser. A large bit of character data, with standard +parser buffer_size (such as 8K) can easily span many calls to this +function. We thus collect the chunks and process them when we hit start +or end tags.

+
+ +
+
+EndElementHandler(name)ΒΆ
+
+ +
+
+StartElementHandler(name, attrs)ΒΆ
+
+ +
+
+flush_chardata()ΒΆ
+

Collate and process collected character data

+
+ +
+
+property pending_dataΒΆ
+

True if there is character data pending for processing

+
+ +
+ +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.cmdline.html b/reference/nibabel.cmdline.html new file mode 100644 index 0000000000..5061170f12 --- /dev/null +++ b/reference/nibabel.cmdline.html @@ -0,0 +1,999 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

cmdlineΒΆ

+

Functionality to be exposed in the command line

+ + + +
+
+

Module: cmdline.conformΒΆ

+

Conform neuroimaging volume to arbitrary shape and voxel size.

+ + + + + + +

main([args])

Main program function.

+
+
+

Module: cmdline.convertΒΆ

+

Convert neuroimaging file to new parameters

+ + + + + + +

main([args])

Main program function.

+
+
+

Module: cmdline.dicomfsΒΆ

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

DICOMFS(*args,Β **kwargs)

FileHandle(fno)

dummy_fuse()

Dummy fuse "module" so that nose does not blow during doctests

fuse

alias of dummy_fuse

get_opt_parser()

main([args])

+
+
+

Module: cmdline.diffΒΆ

+

Quick summary of the differences among a set of neuroimaging files

+
+
Notes:
    +
  • difference in data types for header fields will be detected, but +endianness difference will not be detected. It is done so to compare files +with native endianness used in data files.

  • +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

are_values_different(*values)

Generically compare values, return True if different

diff(files[,Β header_fields,Β ...])

display_diff(files,Β diff)

Format header differences into a nice string

get_data_diff(files[,Β max_abs,Β max_rel,Β dtype])

Get difference between data

get_data_hash_diff(files[,Β dtype])

Get difference between md5 values of data

get_headers_diff(file_headers[,Β names])

Get difference between headers

get_opt_parser()

main([args,Β out])

Getting the show on the road

+
+
+

Module: cmdline.lsΒΆ

+

Output a summary table for neuroimaging files (resolution, dimensionality, etc.)

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

get_opt_parser()

main([args])

Show must go on

proc_file(f,Β opts)

+
+
+

Module: cmdline.nifti_dxΒΆ

+

Print nifti diagnostics for header files

+ + + + + + +

main([args])

Go go team

+
+
+

Module: cmdline.parrec2niiΒΆ

+

Code for PAR/REC to NIfTI converter command

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

error(msg,Β exit_code)

get_opt_parser()

main()

proc_file(infile,Β opts)

verbose(msg[,Β indent])

+
+
+

Module: cmdline.roiΒΆ

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

lossless_slice(img,Β slicers)

main([args])

parse_slice(crop[,Β allow_step])

sanitize(args)

+
+
+

Module: cmdline.statsΒΆ

+

Compute image statistics

+ + + + + + +

main([args])

Main program function.

+
+
+

Module: cmdline.tck2trkΒΆ

+

Convert tractograms (TCK -> TRK).

+ + + + + + + + + +

main()

parse_args()

+
+
+

Module: cmdline.trk2tckΒΆ

+

Convert tractograms (TRK -> TCK).

+ + + + + + + + + +

main()

parse_args()

+
+
+

Module: cmdline.utilsΒΆ

+

Helper utilities to be used in cmdline applications

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

ap(helplist,Β format_[,Β sep])

Little helper to enforce consistency

safe_get(obj,Β name)

A getattr which would return '-' if getattr fails

table2string(table[,Β out])

Given list of lists figure out their common widths and print to out

verbose(thing,Β msg)

Print s if thing is less than the verbose_level

+
+

mainΒΆ

+
+
+nibabel.cmdline.conform.main(args=None)ΒΆ
+

Main program function.

+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.convert.main(args=None)ΒΆ
+

Main program function.

+
+ +
+
+

DICOMFSΒΆ

+
+
+class nibabel.cmdline.dicomfs.DICOMFS(*args, **kwargs)ΒΆ
+

Bases: object

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+get_paths()ΒΆ
+
+ +
+
+getattr(path)ΒΆ
+
+ +
+
+match_path(path)ΒΆ
+
+ +
+
+open(path, flags)ΒΆ
+
+ +
+
+read(path, size, offset, fh)ΒΆ
+
+ +
+
+readdir(path, fh)ΒΆ
+
+ +
+
+release(path, flags, fh)ΒΆ
+
+ +
+ +
+
+

FileHandleΒΆ

+
+
+class nibabel.cmdline.dicomfs.FileHandle(fno)ΒΆ
+

Bases: object

+
+
+__init__(fno)ΒΆ
+
+ +
+ +
+
+

dummy_fuseΒΆ

+
+
+class nibabel.cmdline.dicomfs.dummy_fuseΒΆ
+

Bases: object

+

Dummy fuse β€œmodule” so that nose does not blow during doctests

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+FuseΒΆ
+

alias of object

+
+ +
+
+fuse_python_api = (0, 2)ΒΆ
+
+ +
+ +
+
+

fuseΒΆ

+
+
+nibabel.cmdline.dicomfs.fuseΒΆ
+

alias of dummy_fuse

+
+ +
+
+

get_opt_parserΒΆ

+
+
+nibabel.cmdline.dicomfs.get_opt_parser()ΒΆ
+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.dicomfs.main(args=None)ΒΆ
+
+ +
+
+

are_values_differentΒΆ

+
+
+nibabel.cmdline.diff.are_values_different(*values)ΒΆ
+

Generically compare values, return True if different

+

Note that comparison is targeting reporting of comparison of the headers +so has following specifics: +- even a difference in data types is considered a difference, i.e. 1 != 1.0 +- nans are considered to be the β€œsame”, although generally nan != nan

+
+ +
+
+

diffΒΆ

+
+
+nibabel.cmdline.diff.diff(files, header_fields='all', data_max_abs_diff=None, data_max_rel_diff=None, dtype=<class 'numpy.float64'>)ΒΆ
+
+ +
+
+

display_diffΒΆ

+
+
+nibabel.cmdline.diff.display_diff(files, diff)ΒΆ
+

Format header differences into a nice string

+
+
Parameters:
+
+
files: list of files that were compared so we can print their names
+
diff: dict of different valued header fields
+
+
+
Returns:
+
+
str

string-formatted table of differences

+
+
+
+
+
+ +
+
+

get_data_diffΒΆ

+
+
+nibabel.cmdline.diff.get_data_diff(files, max_abs=0, max_rel=0, dtype=<class 'numpy.float64'>)ΒΆ
+

Get difference between data

+
+
Parameters:
+
+
files: list of (str or ndarray)

If list of strings is provided – they must be existing file names

+
+
max_abs: float, optional

Maximal absolute difference to tolerate.

+
+
max_rel: float, optional

Maximal relative (abs(diff)/mean(diff)) difference to tolerate. +If max_abs is specified, then those data points with lesser than that +absolute difference, are not considered for relative difference testing

+
+
dtype: np, optional

Datatype to be used when extracting data from files

+
+
+
+
Returns:
+
+
diffs: OrderedDict

An ordered dict with a record per each file which has differences +with other files subsequent detected. Each record is a list of +difference records, one per each file pair. +Each difference record is an Ordered Dict with possible keys +β€˜abs’ or β€˜rel’ showing maximal absolute or relative differences +in the file or the record (β€˜CMP’: β€˜incompat’) if file shapes +are incompatible.

+
+
+
+
+
+ +
+
+

get_data_hash_diffΒΆ

+
+
+nibabel.cmdline.diff.get_data_hash_diff(files, dtype=<class 'numpy.float64'>)ΒΆ
+

Get difference between md5 values of data

+
+
Parameters:
+
+
files: list of actual files
+
+
+
Returns:
+
+
list

np.array: md5 values of respective files

+
+
+
+
+
+ +
+
+

get_headers_diffΒΆ

+
+
+nibabel.cmdline.diff.get_headers_diff(file_headers, names=None)ΒΆ
+

Get difference between headers

+
+
Parameters:
+
+
file_headers: list of actual headers (dicts) from files
+
names: list of header fields to test
+
+
+
Returns:
+
+
dict

str: list for each header field which differs, return list of +values per each file

+
+
+
+
+
+ +
+
+

get_opt_parserΒΆ

+
+
+nibabel.cmdline.diff.get_opt_parser()ΒΆ
+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.diff.main(args=None, out=None)ΒΆ
+

Getting the show on the road

+
+ +
+
+

get_opt_parserΒΆ

+
+
+nibabel.cmdline.ls.get_opt_parser()ΒΆ
+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.ls.main(args=None)ΒΆ
+

Show must go on

+
+ +
+
+

proc_fileΒΆ

+
+
+nibabel.cmdline.ls.proc_file(f, opts)ΒΆ
+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.nifti_dx.main(args=None)ΒΆ
+

Go go team

+
+ +
+
+

errorΒΆ

+
+
+nibabel.cmdline.parrec2nii.error(msg, exit_code)ΒΆ
+
+ +
+
+

get_opt_parserΒΆ

+
+
+nibabel.cmdline.parrec2nii.get_opt_parser()ΒΆ
+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.parrec2nii.main()ΒΆ
+
+ +
+
+

proc_fileΒΆ

+
+
+nibabel.cmdline.parrec2nii.proc_file(infile, opts)ΒΆ
+
+ +
+
+

verboseΒΆ

+
+
+nibabel.cmdline.parrec2nii.verbose(msg, indent=0)ΒΆ
+
+ +
+
+

lossless_sliceΒΆ

+
+
+nibabel.cmdline.roi.lossless_slice(img, slicers)ΒΆ
+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.roi.main(args=None)ΒΆ
+
+ +
+
+

parse_sliceΒΆ

+
+
+nibabel.cmdline.roi.parse_slice(crop, allow_step=True)ΒΆ
+
+ +
+
+

sanitizeΒΆ

+
+
+nibabel.cmdline.roi.sanitize(args)ΒΆ
+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.stats.main(args=None)ΒΆ
+

Main program function.

+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.tck2trk.main()ΒΆ
+
+ +
+
+

parse_argsΒΆ

+
+
+nibabel.cmdline.tck2trk.parse_args()ΒΆ
+
+ +
+
+

mainΒΆ

+
+
+nibabel.cmdline.trk2tck.main()ΒΆ
+
+ +
+
+

parse_argsΒΆ

+
+
+nibabel.cmdline.trk2tck.parse_args()ΒΆ
+
+ +
+
+

apΒΆ

+
+
+nibabel.cmdline.utils.ap(helplist, format_, sep=', ')ΒΆ
+

Little helper to enforce consistency

+
+ +
+
+

safe_getΒΆ

+
+
+nibabel.cmdline.utils.safe_get(obj, name)ΒΆ
+

A getattr which would return β€˜-’ if getattr fails

+
+ +
+
+

table2stringΒΆ

+
+
+nibabel.cmdline.utils.table2string(table, out=None)ΒΆ
+

Given list of lists figure out their common widths and print to out

+
+
Parameters:
+
+
tablelist of lists of strings

What is aimed to be printed

+
+
outNone or stream

Where to print. If None – will print and return string

+
+
+
+
Returns:
+
+
string if out was None
+
+
+
+
+ +
+
+

verboseΒΆ

+
+
+nibabel.cmdline.utils.verbose(thing, msg)ΒΆ
+

Print s if thing is less than the verbose_level

+
+ +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.data.html b/reference/nibabel.data.html new file mode 100644 index 0000000000..5cc2c090b3 --- /dev/null +++ b/reference/nibabel.data.html @@ -0,0 +1,546 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

dataΒΆ

+

Utilities to find files from NIPY data packages

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

Bomber(name,Β msg)

Class to raise an informative error when used

BomberError

Error when trying to access Bomber instance

DataError

Datasource(base_path)

Simple class to add base path to relative path

VersionedDatasource(base_path[,Β config_filename])

Datasource with version information in config file

datasource_or_bomber(pkg_def,Β **options)

Return a viable datasource or a Bomber

find_data_dir(root_dirs,Β *names)

Find relative path given path prefixes to search

get_data_path()

Return specified or guessed locations of NIPY data files

make_datasource(pkg_def,Β **kwargs)

Return datasource defined by pkg_def as found in data_path

+
+

BomberΒΆ

+
+
+class nibabel.data.Bomber(name, msg)ΒΆ
+

Bases: object

+

Class to raise an informative error when used

+
+
+__init__(name, msg)ΒΆ
+
+ +
+ +
+
+

BomberErrorΒΆ

+
+
+class nibabel.data.BomberErrorΒΆ
+

Bases: DataError, AttributeError

+

Error when trying to access Bomber instance

+

Should be instance of AttributeError to allow Python 3 inspect to do +various hasattr checks without raising an error

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

DataErrorΒΆ

+
+
+class nibabel.data.DataErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

DatasourceΒΆ

+
+
+class nibabel.data.Datasource(base_path)ΒΆ
+

Bases: object

+

Simple class to add base path to relative path

+

Initialize datasource

+
+
Parameters:
+
+
base_pathstr

path to prepend to all relative paths

+
+
+
+
+

Examples

+
>>> from os.path import join as pjoin
+>>> repo = Datasource(pjoin('a', 'path'))
+>>> fname = repo.get_filename('somedir', 'afile.txt')
+>>> fname == pjoin('a', 'path', 'somedir', 'afile.txt')
+True
+
+
+
+
+__init__(base_path)ΒΆ
+

Initialize datasource

+
+
Parameters:
+
+
base_pathstr

path to prepend to all relative paths

+
+
+
+
+

Examples

+
>>> from os.path import join as pjoin
+>>> repo = Datasource(pjoin('a', 'path'))
+>>> fname = repo.get_filename('somedir', 'afile.txt')
+>>> fname == pjoin('a', 'path', 'somedir', 'afile.txt')
+True
+
+
+
+ +
+
+get_filename(*path_parts)ΒΆ
+

Prepend base path to *path_parts

+

We make no check whether the returned path exists.

+
+
Parameters:
+
+
*path_partssequence of strings
+
+
+
Returns:
+
+
fnamestr

result of os.path.join(*path_parts), with +``self.base_path prepended

+
+
+
+
+
+ +
+
+list_files(relative=True)ΒΆ
+

Recursively list the files in the data source directory.

+
+
Parameters:
+
+
relative: bool, optional

If True, path returned are relative to the base path of +the data source.

+
+
+
+
Returns:
+
+
file_list: list of strings

List of the paths of all the files in the data source.

+
+
+
+
+
+ +
+ +
+
+

VersionedDatasourceΒΆ

+
+
+class nibabel.data.VersionedDatasource(base_path, config_filename=None)ΒΆ
+

Bases: Datasource

+

Datasource with version information in config file

+

Initialize versioned datasource

+

We assume that there is a configuration file with version +information in datasource directory tree.

+

The configuration file contains an entry like:

+
[DEFAULT]
+version = 0.3
+
+
+

The version should have at least a major and a minor version +number in the form above.

+
+
Parameters:
+
+
base_pathstr

path to prepend to all relative paths

+
+
config_filanameNone or str

relative path to configuration file containing version

+
+
+
+
+
+
+__init__(base_path, config_filename=None)ΒΆ
+

Initialize versioned datasource

+

We assume that there is a configuration file with version +information in datasource directory tree.

+

The configuration file contains an entry like:

+
[DEFAULT]
+version = 0.3
+
+
+

The version should have at least a major and a minor version +number in the form above.

+
+
Parameters:
+
+
base_pathstr

path to prepend to all relative paths

+
+
config_filanameNone or str

relative path to configuration file containing version

+
+
+
+
+
+ +
+ +
+
+

datasource_or_bomberΒΆ

+
+
+nibabel.data.datasource_or_bomber(pkg_def, **options)ΒΆ
+

Return a viable datasource or a Bomber

+

This is to allow module level creation of datasource objects. We +create the objects, so that, if the data exist, and are the correct +version, the objects are valid datasources, otherwise, they +raise an error on access, warning about the lack of data or the +version numbers.

+

The parameters are as for make_datasource in this module.

+
+
Parameters:
+
+
pkg_defdict

dict containing at least key β€˜relpath’. Can optionally have keys β€˜name’ +(package name), β€˜install hint’ (for helpful error messages) and β€˜min +version’ giving the minimum necessary version string for the package.

+
+
data_pathsequence of strings or None, optional
+
+
+
Returns:
+
+
dsdatasource or Bomber instance
+
+
+
+
+ +
+
+

find_data_dirΒΆ

+
+
+nibabel.data.find_data_dir(root_dirs, *names)ΒΆ
+

Find relative path given path prefixes to search

+

We raise a DataError if we can’t find the relative path

+
+
Parameters:
+
+
root_dirssequence of strings

sequence of paths in which to search for data directory

+
+
*namessequence of strings

sequence of strings naming directory to find. The name to search +for is given by os.path.join(*names)

+
+
+
+
Returns:
+
+
data_dirstr

full path (root path added to *names above)

+
+
+
+
+
+ +
+
+

get_data_pathΒΆ

+
+
+nibabel.data.get_data_path()ΒΆ
+

Return specified or guessed locations of NIPY data files

+

The algorithm is to return paths, extracted from strings, where +strings are found in the following order:

+
    +
  1. The contents of environment variable NIPY_DATA_PATH

  2. +
  3. Any section = DATA, key = path value in a config.ini +file in your nipy user directory (found with +get_nipy_user_dir())

  4. +
  5. Any section = DATA, key = path value in any files found +with a sorted(glob.glob(os.path.join(sys_dir, '*.ini'))) +search, where sys_dir is found with get_nipy_system_dir()

  6. +
  7. If sys.prefix is /usr, we add +/usr/local/share/nipy. We need this because Python 2.6 in +Debian / Ubuntu does default installs to /usr/local.

  8. +
  9. The result of get_nipy_user_dir()

  10. +
+

Therefore, any paths found in NIPY_DATA_PATH will be searched +before paths found in the user directory config.ini

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
pathssequence of paths
+
+
+
+

Notes

+

We have to add /usr/local/share/nipy if sys.prefix is /usr, +because Debian has patched distutils in Python 2.6 to do default +distutils installs there:

+ +

Examples

+
>>> pth = get_data_path()
+
+
+
+ +
+
+

make_datasourceΒΆ

+
+
+nibabel.data.make_datasource(pkg_def, **kwargs)ΒΆ
+

Return datasource defined by pkg_def as found in data_path

+

data_path is the only allowed keyword argument.

+

pkg_def is a dictionary with at least one key - β€˜relpath’. β€˜relpath’ is +a relative path with unix forward slash separators.

+

The relative path to the data is found with:

+
names = pkg_def['name'].split('/')
+rel_path = os.path.join(names)
+
+
+

We search for this relative path in the list of paths given by data_path. +By default data_path is given by get_data_path() in this module.

+

If we can’t find the relative path, raise a DataError

+
+
Parameters:
+
+
pkg_defdict

dict containing at least the key β€˜relpath’. β€˜relpath’ is the data path +of the package relative to data_path. It is in unix path format +(using forward slashes as directory separators). pkg_def can also +contain optional keys β€˜name’ (the name of the package), and / or a key +β€˜install hint’ that we use in the returned error message from trying to +use the resulting datasource

+
+
data_pathsequence of strings or None, optional

sequence of paths in which to search for data. If None (the +default), then use get_data_path()

+
+
+
+
Returns:
+
+
datasourceVersionedDatasource

An initialized VersionedDatasource instance

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.dataobj_images.html b/reference/nibabel.dataobj_images.html new file mode 100644 index 0000000000..53f45eb660 --- /dev/null +++ b/reference/nibabel.dataobj_images.html @@ -0,0 +1,509 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

dataobj_imagesΒΆ

+

File-based images that have data arrays

+

The class:DataObjImage class defines an image that extends the +FileBasedImage by adding an array-like object, named dataobj. +This can either be an actual numpy array, or an object that:

+
    +
  • returns an array from numpy.asanyarray(obj);

  • +
  • has an attribute or property shape.

  • +
+ + + + + + +

DataobjImage(dataobj[,Β header,Β extra,Β file_map])

Template class for images that have dataobj data stores

+
+

DataobjImageΒΆ

+
+
+class nibabel.dataobj_images.DataobjImage(dataobj: ArrayLike, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Bases: FileBasedImage

+

Template class for images that have dataobj data stores

+

Initialize dataobj image

+

The datobj image is a combination of (dataobj, header), with optional +metadata in extra, and filename / file-like objects contained in the +file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns +an array from np.asanyarray. It should have shape and +ndim attributes or properties

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj: ArrayLike, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Initialize dataobj image

+

The datobj image is a combination of (dataobj, header), with optional +metadata in extra, and filename / file-like objects contained in the +file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns +an array from np.asanyarray. It should have shape and +ndim attributes or properties

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+property dataobj: ArrayLikeΒΆ
+
+ +
+
+classmethod from_file_map(file_map: Mapping[str, FileHolder], *, mmap: bool | Literal['c', 'r'] = True, keep_file_open: bool | None = None) ArrayImgTΒΆ
+

Class method to create image from mapping in file_map

+
+
Parameters:
+
+
file_mapdict

Mapping with (kay, value) pairs of (file_type, FileHolder +instance giving file-likes for each file needed for this image +type.

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_map refers to an open file handle, this setting has no +effect. The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
Returns:
+
+
imgDataobjImage instance
+
+
+
+
+ +
+
+classmethod from_filename(filename: FileSpec, *, mmap: bool | ty.Literal['c', 'r'] = True, keep_file_open: bool | None = None) ArrayImgTΒΆ
+

Class method to create image from filename filename

+
+
Parameters:
+
+
filenamestr

Filename of image to load

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
Returns:
+
+
imgDataobjImage instance
+
+
+
+
+ +
+
+get_data(caching='fill')ΒΆ
+

Return image data from image with any necessary scaling applied

+

get_data() is deprecated in favor of get_fdata(), which has a more predictable return type. To obtain get_data() behavior going forward, use numpy.asanyarray(img.dataobj).

+
    +
  • deprecated from version: 3.0

  • +
  • Raises <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 5.0

  • +
+
+ +
+
+get_fdata(caching: ty.Literal['fill', 'unchanged'] = 'fill', dtype: npt.DTypeLike = <class 'numpy.float64'>) np.ndarray[ty.Any, np.dtype[np.floating]]ΒΆ
+

Return floating point image data with necessary scaling applied

+

The image dataobj property can be an array proxy or an array. An +array proxy is an object that knows how to load the image data from +disk. An image with an array proxy dataobj is a proxy image; an +image with an array in dataobj is an array image.

+

The default behavior for get_fdata() on a proxy image is to read +the data from the proxy, and store in an internal cache. Future calls +to get_fdata will return the cached array. This is the behavior +selected with caching == β€œfill”.

+

Once the data has been cached and returned from an array proxy, if you +modify the returned array, you will also modify the cached array +(because they are the same array). Regardless of the caching flag, +this is always true of an array image.

+
+
Parameters:
+
+
caching{β€˜fill’, β€˜unchanged’}, optional

See the Notes section for a detailed explanation. This argument +specifies whether the image object should fill in an internal +cached reference to the returned image data array. β€œfill” specifies +that the image should fill an internal cached reference if +currently empty. Future calls to get_fdata will return this +cached reference. You might prefer β€œfill” to save the image object +from having to reload the array data from disk on each call to +get_fdata. β€œunchanged” means that the image should not fill in +the internal cached reference if the cache is currently empty. You +might prefer β€œunchanged” to β€œfill” if you want to make sure that +the call to get_fdata does not create an extra (cached) +reference to the returned array. In this case it is easier for +Python to free the memory from the returned array.

+
+
dtypenumpy dtype specifier

A numpy dtype specifier specifying a floating point type. Data is +returned as this floating point type. Default is np.float64.

+
+
+
+
Returns:
+
+
fdataarray

Array of image data of data type dtype.

+
+
+
+
+
+

See also

+
+
uncache

empty the array data cache

+
+
+
+

Notes

+

All images have a property dataobj that represents the image array +data. Images that have been loaded from files usually do not load the +array data from file immediately, in order to reduce image load time +and memory use. For these images, dataobj is an array proxy; an +object that knows how to load the image array data from file.

+

By default (caching == β€œfill”), when you call get_fdata on a +proxy image, we load the array data from disk, store (cache) an +internal reference to this array data, and return the array. The next +time you call get_fdata, you will get the cached reference to the +array, so we don’t have to load the array data from disk again.

+

Array images have a dataobj property that already refers to an +array in memory, so there is no benefit to caching, and the caching +keywords have no effect.

+

For proxy images, you may not want to fill the cache after reading the +data from disk because the cache will hold onto the array memory until +the image object is deleted, or you use the image uncache method. +If you don’t want to fill the cache, then always use +get_fdata(caching='unchanged'); in this case get_fdata will not +fill the cache (store the reference to the array) if the cache is empty +(no reference to the array). If the cache is full, β€œunchanged” leaves +the cache full and returns the cached array reference.

+

The cache can effect the behavior of the image, because if the cache is +full, or you have an array image, then modifying the returned array +will modify the result of future calls to get_fdata(). For example +you might do this:

+
>>> import os
+>>> import nibabel as nib
+>>> from nibabel.testing import data_path
+>>> img_fname = os.path.join(data_path, 'example4d.nii.gz')
+
+
+
>>> img = nib.load(img_fname) # This is a proxy image
+>>> nib.is_proxy(img.dataobj)
+True
+
+
+

The array is not yet cached by a call to β€œget_fdata”, so:

+
>>> img.in_memory
+False
+
+
+

After we call get_fdata using the default caching == β€˜fill’, the +cache contains a reference to the returned array data:

+
>>> data = img.get_fdata()
+>>> img.in_memory
+True
+
+
+

We modify an element in the returned data array:

+
>>> data[0, 0, 0, 0]
+0.0
+>>> data[0, 0, 0, 0] = 99
+>>> data[0, 0, 0, 0]
+99.0
+
+
+

The next time we call β€˜get_fdata’, the method returns the cached +reference to the (modified) array:

+
>>> data_again = img.get_fdata()
+>>> data_again is data
+True
+>>> data_again[0, 0, 0, 0]
+99.0
+
+
+

If you had initially used caching == β€˜unchanged’ then the returned +data array would have been loaded from file, but not cached, and:

+
>>> img = nib.load(img_fname)  # a proxy image again
+>>> data = img.get_fdata(caching='unchanged')
+>>> img.in_memory
+False
+>>> data[0, 0, 0] = 99
+>>> data_again = img.get_fdata(caching='unchanged')
+>>> data_again is data
+False
+>>> data_again[0, 0, 0, 0]
+0.0
+
+
+
+ +
+
+property in_memory: boolΒΆ
+

True when any array data is in memory cache

+

There are separate caches for get_data reads and get_fdata reads. +This property is True if either of those caches are set.

+
+ +
+
+classmethod load(filename: FileSpec, *, mmap: bool | ty.Literal['c', 'r'] = True, keep_file_open: bool | None = None) ArrayImgTΒΆ
+

Class method to create image from filename filename

+
+
Parameters:
+
+
filenamestr

Filename of image to load

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
Returns:
+
+
imgDataobjImage instance
+
+
+
+
+ +
+
+property ndim: intΒΆ
+
+ +
+
+property shape: tuple[int, ...]ΒΆ
+
+ +
+
+uncache() NoneΒΆ
+

Delete any cached read of data from proxied data

+

Remember there are two types of images:

+
    +
  • array images where the data img.dataobj is an array

  • +
  • proxy images where the data img.dataobj is a proxy object

  • +
+

If you call img.get_fdata() on a proxy image, the result of reading +from the proxy gets cached inside the image object, and this cache is +what gets returned from the next call to img.get_fdata(). If you +modify the returned data, as in:

+
data = img.get_fdata()
+data[:] = 42
+
+
+

then the next call to img.get_fdata() returns the modified array, +whether the image is an array image or a proxy image:

+
assert np.all(img.get_fdata() == 42)
+
+
+

When you uncache an array image, this has no effect on the return of +img.get_fdata(), but when you uncache a proxy image, the result of +img.get_fdata() returns to its original value.

+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.deprecated.html b/reference/nibabel.deprecated.html new file mode 100644 index 0000000000..adf119eb23 --- /dev/null +++ b/reference/nibabel.deprecated.html @@ -0,0 +1,277 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

deprecatedΒΆ

+

Module to help with deprecating objects and classes

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

FutureWarningMixin(*args,Β **kwargs)

Insert FutureWarning for object creation

ModuleProxy(module_name)

Proxy for module that may not yet have been imported

VisibleDeprecationWarning

Deprecation warning that will be shown by default

alert_future_error(msg,Β version,Β *[,Β ...])

Warn or error with appropriate messages for changing functionality.

+
+

FutureWarningMixinΒΆ

+
+
+class nibabel.deprecated.FutureWarningMixin(*args: P.args, **kwargs: P.kwargs)ΒΆ
+

Bases: object

+

Insert FutureWarning for object creation

+

Examples

+
>>> class C: pass
+>>> class D(FutureWarningMixin, C):
+...     warn_message = "Please, don't use this class"
+
+
+

Record the warning

+
>>> with warnings.catch_warnings(record=True) as warns:
+...     d = D()
+...     warns[0].message.args[0]
+"Please, don't use this class"
+
+
+
+
+__init__(*args: P.args, **kwargs: P.kwargs) NoneΒΆ
+
+ +
+
+warn_message = 'This class will be removed in future versions'ΒΆ
+
+ +
+ +
+
+

ModuleProxyΒΆ

+
+
+class nibabel.deprecated.ModuleProxy(module_name: str)ΒΆ
+

Bases: object

+

Proxy for module that may not yet have been imported

+
+
Parameters:
+
+
module_namestr

Full module name e.g. nibabel.minc

+
+
+
+
+

Examples

+
+
::

arr = np.arange(24).reshape((2, 3, 4)) +nifti1 = ModuleProxy(β€˜nibabel.nifti1’) +nifti1_image = nifti1.Nifti1Image(arr, np.eye(4))

+
+
+

So, the nifti1 object is a proxy that will import the required module +when you do attribute access and return the attributes of the imported +module.

+
+
+__init__(module_name: str) NoneΒΆ
+
+ +
+ +
+
+

VisibleDeprecationWarningΒΆ

+
+
+class nibabel.deprecated.VisibleDeprecationWarningΒΆ
+

Bases: UserWarning

+

Deprecation warning that will be shown by default

+

Python >= 2.7 does not show standard DeprecationWarnings by default:

+

http://docs.python.org/dev/whatsnew/2.7.html#the-future-for-python-2-x

+

Use this class for cases where we do want to show deprecations by default.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

alert_future_errorΒΆ

+
+
+nibabel.deprecated.alert_future_error(msg: str, version: str, *, warning_class: type[Warning] = <class 'FutureWarning'>, error_class: type[Exception] = <class 'RuntimeError'>, warning_rec: str = '', error_rec: str = '', stacklevel: int = 2) NoneΒΆ
+

Warn or error with appropriate messages for changing functionality.

+
+
Parameters:
+
+
msgstr

Description of the condition that led to the alert

+
+
versionstr

NiBabel version at which the warning will become an error

+
+
warning_classsubclass of Warning, optional

Warning class to emit before version

+
+
error_classsubclass of Exception, optional

Error class to emit after version

+
+
warning_recstr, optional

Guidance for suppressing the warning and avoiding the future error

+
+
error_rec: str, optional

Guidance for resolving the error

+
+
stacklevel: int, optional

Warnings stacklevel to provide; note that this will be incremented by +1, so provide the stacklevel you would provide directly to warnings.warn()

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.deprecator.html b/reference/nibabel.deprecator.html new file mode 100644 index 0000000000..3ff0225474 --- /dev/null +++ b/reference/nibabel.deprecator.html @@ -0,0 +1,225 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

deprecatorΒΆ

+

Class for recording and reporting deprecations

+ + + + + + + + + +

Deprecator(version_comparator,Β int],Β ...)

Class to make decorator marking function or method as deprecated

ExpiredDeprecationError

Error for expired deprecation

+
+

DeprecatorΒΆ

+
+
+class nibabel.deprecator.Deprecator(version_comparator: ~typing.Callable[[str], int], warn_class: type[Warning] = <class 'DeprecationWarning'>, error_class: type[Exception] = <class 'nibabel.deprecator.ExpiredDeprecationError'>)ΒΆ
+

Bases: object

+

Class to make decorator marking function or method as deprecated

+

The decorated function / method will:

+
    +
  • Raise the given warning_class warning when the function / method gets +called, up to (and including) version until (if specified);

  • +
  • Raise the given error_class error when the function / method gets +called, when the package version is greater than version until (if +specified).

  • +
+
+
Parameters:
+
+
version_comparatorcallable

Callable accepting string as argument, and return 1 if string +represents a higher version than encoded in the version_comparator, 0 +if the version is equal, and -1 if the version is lower. For example, +the version_comparator may compare the input version string to the +current package version string.

+
+
warn_classclass, optional

Class of warning to generate for deprecation.

+
+
error_classclass, optional

Class of error to generate when version_comparator returns 1 for a +given argument of until in the __call__ method (see below).

+
+
+
+
+
+
+__init__(version_comparator: ~typing.Callable[[str], int], warn_class: type[Warning] = <class 'DeprecationWarning'>, error_class: type[Exception] = <class 'nibabel.deprecator.ExpiredDeprecationError'>) NoneΒΆ
+
+ +
+
+is_bad_version(version_str: str) boolΒΆ
+

Return True if version_str is too high

+

Tests version_str with self.version_comparator

+
+
Parameters:
+
+
version_strstr

String giving version to test

+
+
+
+
Returns:
+
+
is_badbool

True if version_str is for version below that expected by +self.version_comparator, False otherwise.

+
+
+
+
+
+ +
+ +
+
+

ExpiredDeprecationErrorΒΆ

+
+
+class nibabel.deprecator.ExpiredDeprecationErrorΒΆ
+

Bases: RuntimeError

+

Error for expired deprecation

+

Error raised when a called function or method has passed out of its +deprecation period.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.dft.html b/reference/nibabel.dft.html new file mode 100644 index 0000000000..91136f621c --- /dev/null +++ b/reference/nibabel.dft.html @@ -0,0 +1,269 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

dftΒΆ

+

DICOM filesystem tools

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

CachingError

error while caching

DFTError

base class for DFT exceptions

InstanceStackError(series,Β i,Β si)

bad series of instance numbers

VolumeError

unsupported volume parameter

clear_cache()

get_studies([base_dir,Β followlinks])

update_cache(base_dir[,Β followlinks])

+
+

CachingErrorΒΆ

+
+
+class nibabel.dft.CachingErrorΒΆ
+

Bases: DFTError

+

error while caching

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

DFTErrorΒΆ

+
+
+class nibabel.dft.DFTErrorΒΆ
+

Bases: Exception

+

base class for DFT exceptions

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

InstanceStackErrorΒΆ

+
+
+class nibabel.dft.InstanceStackError(series, i, si)ΒΆ
+

Bases: DFTError

+

bad series of instance numbers

+
+
+__init__(series, i, si)ΒΆ
+
+ +
+ +
+
+

VolumeErrorΒΆ

+
+
+class nibabel.dft.VolumeErrorΒΆ
+

Bases: DFTError

+

unsupported volume parameter

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

clear_cacheΒΆ

+
+
+nibabel.dft.clear_cache()ΒΆ
+
+ +
+
+

get_studiesΒΆ

+
+
+nibabel.dft.get_studies(base_dir=None, followlinks=False)ΒΆ
+
+ +
+
+

update_cacheΒΆ

+
+
+nibabel.dft.update_cache(base_dir, followlinks=False)ΒΆ
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.ecat.html b/reference/nibabel.ecat.html new file mode 100644 index 0000000000..d831264434 --- /dev/null +++ b/reference/nibabel.ecat.html @@ -0,0 +1,899 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

ecatΒΆ

+

Read ECAT format images

+

An ECAT format image consists of:

+
    +
  • a main header;

  • +
  • at least one matrix list (mlist);

  • +
+

ECAT thinks of memory locations in terms of blocks. One block is 512 +bytes. Thus block 1 starts at 0 bytes, block 2 at 512 bytes, and so on.

+

The matrix list is an array with one row per frame in the data.

+

Columns in the matrix list are:

+
    +
  • 0: Matrix identifier (frame number)

  • +
  • 1: matrix data start block number (subheader followed by image data)

  • +
  • 2: Last block number of matrix (image) data

  • +
  • 3: Matrix status

    +
    +
      +
    • 1: hxists - rw

    • +
    • 2: exists - ro

    • +
    • 3: matrix deleted

    • +
    +
    +
  • +
+

There is one sub-header for each image frame (or matrix in the terminology +above). A sub-header can also be called an image header. The sub-header is +one block (512 bytes), and the frame (image) data follows.

+

There is very little documentation of the ECAT format, and many of the comments +in this code come from a combination of trial and error and wild speculation.

+

XMedcon can read and write ECAT 6 format, and read ECAT 7 format: see +http://xmedcon.sourceforge.net and the ECAT files in the source of XMedCon, +currently libs/tpc/*ecat* and source/m-ecat*. Unfortunately XMedCon is +GPL and some of the header files are adapted from CTI files (called CTI code +below). It’s not clear what the licenses are for these files.

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

EcatHeader([binaryblock,Β endianness,Β check])

Class for basic Ecat PET header

EcatImage(dataobj,Β affine,Β header,Β ...[,Β ...])

Class returns a list of Ecat images, with one image(hdr/data) per frame

EcatImageArrayProxy(subheader)

Ecat implementation of array proxy protocol

EcatSubHeader(hdr,Β mlist,Β fileobj)

parses the subheaders in the ecat (.v) file there is one subheader for each frame in the ecat file

get_frame_order(mlist)

Returns the order of the frames stored in the file Sometimes Frames are not stored in the file in chronological order, this can be used to extract frames in correct order

get_series_framenumbers(mlist)

Returns framenumber of data as it was collected, as part of a series; not just the order of how it was stored in this or across other files

read_mlist(fileobj,Β endianness)

read (nframes, 4) matrix list array from fileobj

read_subheaders(fileobj,Β mlist,Β endianness)

Retrieve all subheaders and return list of subheader recarrays

+
+

EcatHeaderΒΆ

+
+
+class nibabel.ecat.EcatHeader(binaryblock=None, endianness=None, check=True)ΒΆ
+

Bases: WrapStruct, SpatialHeader

+

Class for basic Ecat PET header

+

Sub-parts of standard Ecat File

+
    +
  • main header

  • +
  • matrix list +which lists the information for each frame collected (can have 1 to many +frames)

  • +
  • subheaders specific to each frame with possibly-variable sized data +blocks

  • +
+

This just reads the main Ecat Header, it does not load the data or read the +mlist or any sub headers

+

Initialize Ecat header from bytes object

+
+
Parameters:
+
+
binaryblock{None, bytes} optional

binary block to set into header, By default, None in which case we +insert default empty header block

+
+
endianness{None, β€˜<’, β€˜>’, other endian code}, optional

endian code of binary block, If None, guess endianness +from the data

+
+
check{True, False}, optional

Whether to check and fix header for errors. No checks currently +implemented, so value has no effect.

+
+
+
+
+
+
+__init__(binaryblock=None, endianness=None, check=True)ΒΆ
+

Initialize Ecat header from bytes object

+
+
Parameters:
+
+
binaryblock{None, bytes} optional

binary block to set into header, By default, None in which case we +insert default empty header block

+
+
endianness{None, β€˜<’, β€˜>’, other endian code}, optional

endian code of binary block, If None, guess endianness +from the data

+
+
check{True, False}, optional

Whether to check and fix header for errors. No checks currently +implemented, so value has no effect.

+
+
+
+
+
+ +
+
+classmethod default_structarr(endianness=None)ΒΆ
+

Return header data for empty header with given endianness

+
+ +
+
+get_data_dtype()ΒΆ
+

Get numpy dtype for data from header

+
+ +
+
+get_filetype()ΒΆ
+

Type of ECAT Matrix File from code stored in header

+
+ +
+
+get_patient_orient()ΒΆ
+

gets orientation of patient based on code stored +in header, not always reliable

+
+ +
+
+classmethod guessed_endian(hdr)ΒΆ
+

Guess endian from MAGIC NUMBER value of header data

+
+ +
+
+template_dtype = dtype([('magic_number', 'S14'), ('original_filename', 'S32'), ('sw_version', '<u2'), ('system_type', '<u2'), ('file_type', '<u2'), ('serial_number', 'S10'), ('scan_start_time', '<u4'), ('isotope_name', 'S8'), ('isotope_halflife', '<f4'), ('radiopharmaceutical', 'S32'), ('gantry_tilt', '<f4'), ('gantry_rotation', '<f4'), ('bed_elevation', '<f4'), ('intrinsic_tilt', '<f4'), ('wobble_speed', '<u2'), ('transm_source_type', '<u2'), ('distance_scanned', '<f4'), ('transaxial_fov', '<f4'), ('angular_compression', '<u2'), ('coin_samp_mode', '<u2'), ('axial_samp_mode', '<u2'), ('ecat_calibration_factor', '<f4'), ('calibration_unitS', '<u2'), ('calibration_units_type', '<u2'), ('compression_code', '<u2'), ('study_type', 'S12'), ('patient_id', 'S16'), ('patient_name', 'S32'), ('patient_sex', 'S1'), ('patient_dexterity', 'S1'), ('patient_age', '<f4'), ('patient_height', '<f4'), ('patient_weight', '<f4'), ('patient_birth_date', '<u4'), ('physician_name', 'S32'), ('operator_name', 'S32'), ('study_description', 'S32'), ('acquisition_type', '<u2'), ('patient_orientation', '<u2'), ('facility_name', 'S20'), ('num_planes', '<u2'), ('num_frames', '<u2'), ('num_gates', '<u2'), ('num_bed_pos', '<u2'), ('init_bed_position', '<f4'), ('bed_position', '<f4', (15,)), ('plane_separation', '<f4'), ('lwr_sctr_thres', '<u2'), ('lwr_true_thres', '<u2'), ('upr_true_thres', '<u2'), ('user_process_code', 'S10'), ('acquisition_mode', '<u2'), ('bin_size', '<f4'), ('branching_fraction', '<f4'), ('dose_start_time', '<u4'), ('dosage', '<f4'), ('well_counter_corr_factor', '<f4'), ('data_units', 'S32'), ('septa_state', '<u2'), ('fill', 'S12')])ΒΆ
+
+ +
+ +
+
+

EcatImageΒΆ

+
+
+class nibabel.ecat.EcatImage(dataobj, affine, header, subheader, mlist, extra=None, file_map=None)ΒΆ
+

Bases: SpatialImage

+

Class returns a list of Ecat images, with one image(hdr/data) per frame

+

Initialize Image

+

The image is a combination of +(array, affine matrix, header, subheader, mlist) +with optional meta data in extra, and filename / file-like objects +contained in the file_map.

+
+
Parameters:
+
+
dataobjarray-like

image data

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coords and +world coords.

+
+
headerNone or header instance

meta data for this image format

+
+
subheaderNone or subheader instance

meta data for each sub-image for frame in the image

+
+
mlistNone or array

Matrix list array giving offset and order of data in file

+
+
extraNone or mapping, optional

metadata associated with this image that cannot be +stored in header or subheader

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Examples

+
>>> import os
+>>> import nibabel as nib
+>>> nibabel_dir = os.path.dirname(nib.__file__)
+>>> from nibabel import ecat
+>>> ecat_file = os.path.join(nibabel_dir,'tests','data','tinypet.v')
+>>> img = ecat.load(ecat_file)
+>>> frame0 = img.get_frame(0)
+>>> frame0.shape == (10, 10, 3)
+True
+>>> data4d = img.get_fdata()
+>>> data4d.shape == (10, 10, 3, 1)
+True
+
+
+
+
+__init__(dataobj, affine, header, subheader, mlist, extra=None, file_map=None)ΒΆ
+

Initialize Image

+

The image is a combination of +(array, affine matrix, header, subheader, mlist) +with optional meta data in extra, and filename / file-like objects +contained in the file_map.

+
+
Parameters:
+
+
dataobjarray-like

image data

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coords and +world coords.

+
+
headerNone or header instance

meta data for this image format

+
+
subheaderNone or subheader instance

meta data for each sub-image for frame in the image

+
+
mlistNone or array

Matrix list array giving offset and order of data in file

+
+
extraNone or mapping, optional

metadata associated with this image that cannot be +stored in header or subheader

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Examples

+
>>> import os
+>>> import nibabel as nib
+>>> nibabel_dir = os.path.dirname(nib.__file__)
+>>> from nibabel import ecat
+>>> ecat_file = os.path.join(nibabel_dir,'tests','data','tinypet.v')
+>>> img = ecat.load(ecat_file)
+>>> frame0 = img.get_frame(0)
+>>> frame0.shape == (10, 10, 3)
+True
+>>> data4d = img.get_fdata()
+>>> data4d.shape == (10, 10, 3, 1)
+True
+
+
+
+ +
+
+ImageArrayProxyΒΆ
+

alias of EcatImageArrayProxy

+
+ +
+
+property affineΒΆ
+
+ +
+
+files_types: tuple[ExtensionSpec, ...] = (('image', '.v'), ('header', '.v'))ΒΆ
+
+ +
+
+classmethod from_file_map(file_map, *, mmap=True, keep_file_open=None)ΒΆ
+

class method to create image from mapping +specified in file_map

+
+ +
+
+classmethod from_image(img)ΒΆ
+

Class method to create new instance of own class from img

+
+
Parameters:
+
+
imgspatialimage instance

In fact, an object with the API of spatialimage - +specifically dataobj, affine, header and extra.

+
+
+
+
Returns:
+
+
cimgspatialimage instance

Image, of our own class

+
+
+
+
+
+ +
+
+get_data_dtype(frame)ΒΆ
+
+ +
+
+get_frame(frame, orientation=None)ΒΆ
+

Get full volume for a time frame

+
+
Parameters:
+
    +
  • frame – Time frame index from where to fetch data

  • +
  • orientation – None (default), β€˜neurological’ or β€˜radiological’

  • +
+
+
Return type:
+

Numpy array containing (possibly oriented) raw data

+
+
+
+ +
+
+get_frame_affine(frame)ΒΆ
+

returns 4X4 affine

+
+ +
+
+get_mlist()ΒΆ
+

get access to the mlist

+
+ +
+
+get_subheaders()ΒΆ
+

get access to subheaders

+
+ +
+
+header_classΒΆ
+

alias of EcatHeader

+
+ +
+
+classmethod load(filespec)ΒΆ
+

Class method to create image from filename filename

+
+
Parameters:
+
+
filenamestr

Filename of image to load

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
Returns:
+
+
imgDataobjImage instance
+
+
+
+
+ +
+
+property shapeΒΆ
+
+ +
+
+subheader_classΒΆ
+

alias of EcatSubHeader

+
+ +
+
+to_file_map(file_map=None)ΒΆ
+

Write ECAT7 image to file_map or contained self.file_map

+

The format consist of:

+
    +
  • +
    A main header (512L) with dictionary entries in the form

    [numAvail, nextDir, previousDir, numUsed]

    +
    +
    +
  • +
  • For every frame (3D volume in 4D data) +- A subheader (size = frame_offset) +- Frame data (3D volume)

  • +
+
+ +
+
+valid_exts: tuple[str, ...] = ('.v',)ΒΆ
+
+ +
+ +
+
+

EcatImageArrayProxyΒΆ

+
+
+class nibabel.ecat.EcatImageArrayProxy(subheader)ΒΆ
+

Bases: object

+

Ecat implementation of array proxy protocol

+

The array proxy allows us to freeze the passed fileobj and +header such that it returns the expected data array.

+
+
+__init__(subheader)ΒΆ
+
+ +
+
+property is_proxyΒΆ
+
+ +
+
+property ndimΒΆ
+
+ +
+
+property shapeΒΆ
+
+ +
+ +
+
+

EcatSubHeaderΒΆ

+
+
+class nibabel.ecat.EcatSubHeader(hdr, mlist, fileobj)ΒΆ
+

Bases: object

+

parses the subheaders in the ecat (.v) file +there is one subheader for each frame in the ecat file

+
+
Parameters:
+
+
hdrEcatHeader

ECAT main header

+
+
mlistarray shape (N, 4)

Matrix list

+
+
fileobjECAT file <filename>.v fileholder or file object

with read, seek methods

+
+
+
+
+
+
+__init__(hdr, mlist, fileobj)ΒΆ
+

parses the subheaders in the ecat (.v) file +there is one subheader for each frame in the ecat file

+
+
Parameters:
+
+
hdrEcatHeader

ECAT main header

+
+
mlistarray shape (N, 4)

Matrix list

+
+
fileobjECAT file <filename>.v fileholder or file object

with read, seek methods

+
+
+
+
+
+ +
+
+data_from_fileobj(frame=0, orientation=None)ΒΆ
+

Read scaled data from file for a given frame

+
+
Parameters:
+
    +
  • frame – Time frame index from where to fetch data

  • +
  • orientation – None (default), β€˜neurological’ or β€˜radiological’

  • +
+
+
Return type:
+

Numpy array containing (possibly oriented) raw data

+
+
+
+

See also

+

raw_data_from_fileobj

+
+
+ +
+
+get_frame_affine(frame=0)ΒΆ
+

returns best affine for given frame of data

+
+ +
+
+get_nframes()ΒΆ
+

returns number of frames

+
+ +
+
+get_shape(frame=0)ΒΆ
+

returns shape of given frame

+
+ +
+
+get_zooms(frame=0)ΒΆ
+

returns zooms …pixdims

+
+ +
+
+raw_data_from_fileobj(frame=0, orientation=None)ΒΆ
+

Get raw data from file object.

+
+
Parameters:
+
    +
  • frame – Time frame index from where to fetch data

  • +
  • orientation – None (default), β€˜neurological’ or β€˜radiological’

  • +
+
+
Return type:
+

Numpy array containing (possibly oriented) raw data

+
+
+
+

See also

+

data_from_fileobj

+
+
+ +
+ +
+
+

get_frame_orderΒΆ

+
+
+nibabel.ecat.get_frame_order(mlist)ΒΆ
+

Returns the order of the frames stored in the file +Sometimes Frames are not stored in the file in +chronological order, this can be used to extract frames +in correct order

+
+
Returns:
+
+
id_dict: dict mapping frame number -> [mlist_row, mlist_id]
+
(where mlist id is value in the first column of the mlist matrix )
+
+
+
+

Examples

+
>>> import os
+>>> import nibabel as nib
+>>> nibabel_dir = os.path.dirname(nib.__file__)
+>>> from nibabel import ecat
+>>> ecat_file = os.path.join(nibabel_dir,'tests','data','tinypet.v')
+>>> img = ecat.load(ecat_file)
+>>> mlist = img.get_mlist()
+>>> get_frame_order(mlist)
+{0: [0, 16842758]}
+
+
+
+ +
+
+

get_series_framenumbersΒΆ

+
+
+nibabel.ecat.get_series_framenumbers(mlist)ΒΆ
+

Returns framenumber of data as it was collected, +as part of a series; not just the order of how it was +stored in this or across other files

+

For example, if the data is split between multiple files +this should give you the true location of this frame as +collected in the series +(Frames are numbered starting at ONE (1) not Zero)

+
+
Returns:
+
+
frame_dict: dict mapping order_stored -> frame in series

where frame in series counts from 1; [1,2,3,4…]

+
+
+
+
+

Examples

+
>>> import os
+>>> import nibabel as nib
+>>> nibabel_dir = os.path.dirname(nib.__file__)
+>>> from nibabel import ecat
+>>> ecat_file = os.path.join(nibabel_dir,'tests','data','tinypet.v')
+>>> img = ecat.load(ecat_file)
+>>> mlist = img.get_mlist()
+>>> get_series_framenumbers(mlist)
+{0: 1}
+
+
+
+ +
+
+

read_mlistΒΆ

+
+
+nibabel.ecat.read_mlist(fileobj, endianness)ΒΆ
+

read (nframes, 4) matrix list array from fileobj

+
+
Parameters:
+
+
fileobjfile-like

an open file-like object implementing seek and read

+
+
+
+
Returns:
+
+
mlist(nframes, 4) ndarray

matrix list is an array with nframes rows and columns:

+
    +
  • 0: Matrix identifier (frame number)

  • +
  • 1: matrix data start block number (subheader followed by image data)

  • +
  • 2: Last block number of matrix (image) data

  • +
  • 3: Matrix status

    +
    +
      +
    • 1: hxists - rw

    • +
    • 2: exists - ro

    • +
    • 3: matrix deleted

    • +
    +
    +
  • +
+
+
+
+
+

Notes

+

A block is 512 bytes.

+

block_no in the code below is 1-based. block 1 is the main header, +and the mlist blocks start at block number 2.

+

The 512 bytes in an mlist block contain 32 rows of the int32 (nframes, +4) mlist matrix.

+

The first row of these 32 looks like a special row. The 4 values appear +to be (respectively):

+
    +
  • not sure - maybe negative number of mlist rows (out of 31) that are +blank and not used in this block. Called nfree but unused in CTI +code;

  • +
  • block_no - of next set of mlist entries or 2 if no more entries. We also +allow 1 or 0 to signal no more entries;

  • +
  • <no idea>. Called prvblk in CTI code, so maybe previous block no;

  • +
  • n_rows - number of mlist rows in this block (between ?0 and 31) (called +nused in CTI code).

  • +
+
+ +
+
+

read_subheadersΒΆ

+
+
+nibabel.ecat.read_subheaders(fileobj, mlist, endianness)ΒΆ
+

Retrieve all subheaders and return list of subheader recarrays

+
+
Parameters:
+
+
fileobjfile-like

implementing read and seek

+
+
mlist(nframes, 4) ndarray

Columns are: +* 0 - Matrix identifier. +* 1 - subheader block number +* 2 - Last block number of matrix data block. +* 3 - Matrix status

+
+
endianness{β€˜<’, β€˜>’}

little / big endian code

+
+
+
+
Returns:
+
+
subheaderslist

List of subheader structured arrays

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.environment.html b/reference/nibabel.environment.html new file mode 100644 index 0000000000..b88a98b331 --- /dev/null +++ b/reference/nibabel.environment.html @@ -0,0 +1,233 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

environmentΒΆ

+

Settings from the system environment relevant to NIPY

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

get_home_dir()

Return the closest possible equivalent to a 'home' directory.

get_nipy_system_dir()

Get systemwide NIPY configuration file directory

get_nipy_user_dir()

Get the NIPY user directory

+
+

get_home_dirΒΆ

+
+
+nibabel.environment.get_home_dir()ΒΆ
+

Return the closest possible equivalent to a β€˜home’ directory.

+

The path may not exist; code using this routine should not +expect the directory to exist.

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
home_dirstring

best guess at location of home directory

+
+
+
+
+
+ +
+
+

get_nipy_system_dirΒΆ

+
+
+nibabel.environment.get_nipy_system_dir()ΒΆ
+

Get systemwide NIPY configuration file directory

+

On posix systems this will be /etc/nipy. +On Windows, the directory is less useful, but by default it will be +C:\etc\nipy

+

The path may well not exist; code using this routine should not +expect the directory to exist.

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
nipy_dirstring

path to systemwide NIPY configuration directory

+
+
+
+
+

Examples

+
>>> pth = get_nipy_system_dir()
+
+
+
+ +
+
+

get_nipy_user_dirΒΆ

+
+
+nibabel.environment.get_nipy_user_dir()ΒΆ
+

Get the NIPY user directory

+

This uses the logic in get_home_dir to find the home directory +and the adds either .nipy or _nipy to the end of the path.

+

We check first in environment variable NIPY_USER_DIR, otherwise +returning the default of <homedir>/.nipy (Unix) or +<homedir>/_nipy (Windows)

+

The path may well not exist; code using this routine should not +expect the directory to exist.

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
nipy_dirstring

path to user’s NIPY configuration directory

+
+
+
+
+

Examples

+
>>> pth = get_nipy_user_dir()
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.eulerangles.html b/reference/nibabel.eulerangles.html new file mode 100644 index 0000000000..ff5c95dbdd --- /dev/null +++ b/reference/nibabel.eulerangles.html @@ -0,0 +1,519 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

euleranglesΒΆ

+

Module implementing Euler angle rotations and their conversions

+

See:

+ +

See also: Representing Attitude with Euler Angles and Quaternions: A +Reference (2006) by James Diebel. A cached PDF link last found here:

+

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.110.5134

+

Euler’s rotation theorem tells us that any rotation in 3D can be +described by 3 angles. Let’s call the 3 angles the Euler angle vector +and call the angles in the vector \(alpha\), \(beta\) and +\(gamma\). The vector is [ \(alpha\), +\(beta\). \(gamma\) ] and, in this description, the order of the +parameters specifies the order in which the rotations occur (so the +rotation corresponding to \(alpha\) is applied first).

+

In order to specify the meaning of an Euler angle vector we need to +specify the axes around which each of the rotations corresponding to +\(alpha\), \(beta\) and \(gamma\) will occur.

+

There are therefore three axes for the rotations \(alpha\), +\(beta\) and \(gamma\); let’s call them \(i\) \(j\), +\(k\).

+

Let us express the rotation \(alpha\) around axis i as a 3 by 3 +rotation matrix A. Similarly \(beta\) around j becomes 3 x 3 +matrix B and \(gamma\) around k becomes matrix G. Then the +whole rotation expressed by the Euler angle vector [ \(alpha\), +\(beta\). \(gamma\) ], R is given by:

+
R = np.dot(G, np.dot(B, A))
+
+
+

See http://mathworld.wolfram.com/EulerAngles.html

+

The order \(G B A\) expresses the fact that the rotations are +performed in the order of the vector (\(alpha\) around axis i = +A first).

+

To convert a given Euler angle vector to a meaningful rotation, and a +rotation matrix, we need to define:

+
    +
  • the axes i, j, k

  • +
  • whether a rotation matrix should be applied on the left of a vector to +be transformed (vectors are column vectors) or on the right (vectors +are row vectors).

  • +
  • whether the rotations move the axes as they are applied (intrinsic +rotations) - compared the situation where the axes stay fixed and the +vectors move within the axis frame (extrinsic)

  • +
  • the handedness of the coordinate system

  • +
+

See: https://en.wikipedia.org/wiki/Rotation_matrix#Ambiguities

+

We are using the following conventions:

+
    +
  • axes i, j, k are the z, y, and x axes respectively. Thus +an Euler angle vector [ \(alpha\), \(beta\). \(gamma\) ] +in our convention implies a \(alpha\) radian rotation around the +z axis, followed by a \(beta\) rotation around the y axis, +followed by a \(gamma\) rotation around the x axis.

  • +
  • the rotation matrix applies on the left, to column vectors on the +right, so if R is the rotation matrix, and v is a 3 x N matrix +with N column vectors, the transformed vector set vdash is given by +vdash = np.dot(R, v).

  • +
  • extrinsic rotations - the axes are fixed, and do not move with the +rotations.

  • +
  • a right-handed coordinate system

  • +
+

The convention of rotation around z, followed by rotation around +y, followed by rotation around x, is known (confusingly) as +β€œxyz”, pitch-roll-yaw, Cardan angles, or Tait-Bryan angles.

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

angle_axis2euler(theta,Β vector[,Β is_normalized])

Convert angle, axis pair to Euler angles

euler2angle_axis([z,Β y,Β x])

Return angle, axis corresponding to these Euler angles

euler2mat([z,Β y,Β x])

Return matrix for rotations around z, y and x axes

euler2quat([z,Β y,Β x])

Return quaternion corresponding to these Euler angles

mat2euler(M[,Β cy_thresh])

Discover Euler angle vector from 3x3 matrix

quat2euler(q)

Return Euler angles corresponding to quaternion q

+
+

angle_axis2eulerΒΆ

+
+
+nibabel.eulerangles.angle_axis2euler(theta, vector, is_normalized=False)ΒΆ
+

Convert angle, axis pair to Euler angles

+
+
Parameters:
+
+
thetascalar

angle of rotation

+
+
vector3 element sequence

vector specifying axis for rotation.

+
+
is_normalizedbool, optional

True if vector is already normalized (has norm of 1). Default +False

+
+
+
+
Returns:
+
+
zscalar
+
yscalar
+
xscalar

Rotations in radians around z, y, x axes, respectively

+
+
+
+
+

Notes

+

It’s possible to reduce the amount of calculation a little, by +combining parts of the angle_axis2mat and mat2euler +functions, but the reduction in computation is small, and the code +repetition is large.

+

Examples

+
>>> z, y, x = angle_axis2euler(0, [1, 0, 0])
+>>> np.allclose((z, y, x), 0)
+True
+
+
+
+ +
+
+

euler2angle_axisΒΆ

+
+
+nibabel.eulerangles.euler2angle_axis(z=0, y=0, x=0)ΒΆ
+

Return angle, axis corresponding to these Euler angles

+

Uses the z, then y, then x convention above

+
+
Parameters:
+
+
zscalar

Rotation angle in radians around z-axis (performed first)

+
+
yscalar

Rotation angle in radians around y-axis

+
+
xscalar

Rotation angle in radians around x-axis (performed last)

+
+
+
+
Returns:
+
+
thetascalar

angle of rotation

+
+
vectorarray shape (3,)

axis around which rotation occurs

+
+
+
+
+

Examples

+
>>> theta, vec = euler2angle_axis(0, 1.5, 0)
+>>> print(theta)
+1.5
+>>> np.allclose(vec, [0, 1, 0])
+True
+
+
+
+ +
+
+

euler2matΒΆ

+
+
+nibabel.eulerangles.euler2mat(z=0, y=0, x=0)ΒΆ
+

Return matrix for rotations around z, y and x axes

+

Uses the z, then y, then x convention above

+
+
Parameters:
+
+
zscalar

Rotation angle in radians around z-axis (performed first)

+
+
yscalar

Rotation angle in radians around y-axis

+
+
xscalar

Rotation angle in radians around x-axis (performed last)

+
+
+
+
Returns:
+
+
Marray shape (3,3)

Rotation matrix giving same rotation as for given angles

+
+
+
+
+

Notes

+

The direction of rotation is given by the right-hand rule (orient +the thumb of the right hand along the axis around which the rotation +occurs, with the end of the thumb at the positive end of the axis; +curl your fingers; the direction your fingers curl is the direction +of rotation). Therefore, the rotations are counterclockwise if +looking along the axis of rotation from positive to negative.

+

Examples

+
>>> zrot = 1.3 # radians
+>>> yrot = -0.1
+>>> xrot = 0.2
+>>> M = euler2mat(zrot, yrot, xrot)
+>>> M.shape == (3, 3)
+True
+
+
+

The output rotation matrix is equal to the composition of the +individual rotations

+
>>> M1 = euler2mat(zrot)
+>>> M2 = euler2mat(0, yrot)
+>>> M3 = euler2mat(0, 0, xrot)
+>>> composed_M = np.dot(M3, np.dot(M2, M1))
+>>> np.allclose(M, composed_M)
+True
+
+
+

You can specify rotations by named arguments

+
>>> np.all(M3 == euler2mat(x=xrot))
+True
+
+
+

When applying M to a vector, the vector should column vector to the +right of M. If the right hand side is a 2D array rather than a +vector, then each column of the 2D array represents a vector.

+
>>> vec = np.array([1, 0, 0]).reshape((3,1))
+>>> v2 = np.dot(M, vec)
+>>> vecs = np.array([[1, 0, 0],[0, 1, 0]]).T # giving 3x2 array
+>>> vecs2 = np.dot(M, vecs)
+
+
+

Rotations are counter-clockwise.

+
>>> zred = np.dot(euler2mat(z=np.pi/2), np.eye(3))
+>>> np.allclose(zred, [[0, -1, 0],[1, 0, 0], [0, 0, 1]])
+True
+>>> yred = np.dot(euler2mat(y=np.pi/2), np.eye(3))
+>>> np.allclose(yred, [[0, 0, 1],[0, 1, 0], [-1, 0, 0]])
+True
+>>> xred = np.dot(euler2mat(x=np.pi/2), np.eye(3))
+>>> np.allclose(xred, [[1, 0, 0],[0, 0, -1], [0, 1, 0]])
+True
+
+
+
+ +
+
+

euler2quatΒΆ

+
+
+nibabel.eulerangles.euler2quat(z=0, y=0, x=0)ΒΆ
+

Return quaternion corresponding to these Euler angles

+

Uses the z, then y, then x convention above

+
+
Parameters:
+
+
zscalar

Rotation angle in radians around z-axis (performed first)

+
+
yscalar

Rotation angle in radians around y-axis

+
+
xscalar

Rotation angle in radians around x-axis (performed last)

+
+
+
+
Returns:
+
+
quatarray shape (4,)

Quaternion in w, x, y z (real, then vector) format

+
+
+
+
+

Notes

+

We can derive this formula in Sympy using:

+
    +
  1. Formula giving quaternion corresponding to rotation of theta radians +about arbitrary axis: +http://mathworld.wolfram.com/EulerParameters.html

  2. +
  3. Generated formulae from 1.) for quaternions corresponding to +theta radians rotations about x, y, z axes

  4. +
  5. Apply quaternion multiplication formula - +https://en.wikipedia.org/wiki/Quaternions#Hamilton_product - to +formulae from 2.) to give formula for combined rotations.

  6. +
+
+ +
+
+

mat2eulerΒΆ

+
+
+nibabel.eulerangles.mat2euler(M, cy_thresh=None)ΒΆ
+

Discover Euler angle vector from 3x3 matrix

+

Uses the conventions above.

+
+
Parameters:
+
+
Marray-like, shape (3,3)
+
cy_threshNone or scalar, optional

threshold below which to give up on straightforward arctan for +estimating x rotation. If None (default), estimate from +precision of input.

+
+
+
+
Returns:
+
+
zscalar
+
yscalar
+
xscalar

Rotations in radians around z, y, x axes, respectively

+
+
+
+
+

Notes

+

If there was no numerical error, the routine could be derived using +Sympy expression for z then y then x rotation matrix, which is:

+
[                       cos(y)*cos(z),                       -cos(y)*sin(z),         sin(y)],
+[cos(x)*sin(z) + cos(z)*sin(x)*sin(y), cos(x)*cos(z) - sin(x)*sin(y)*sin(z), -cos(y)*sin(x)],
+[sin(x)*sin(z) - cos(x)*cos(z)*sin(y), cos(z)*sin(x) + cos(x)*sin(y)*sin(z),  cos(x)*cos(y)]
+
+
+

with the obvious derivations for z, y, and x

+
+

z = atan2(-r12, r11) +y = asin(r13) +x = atan2(-r23, r33)

+
+

Problems arise when cos(y) is close to zero, because both of:

+
z = atan2(cos(y)*sin(z), cos(y)*cos(z))
+x = atan2(cos(y)*sin(x), cos(x)*cos(y))
+
+
+

will be close to atan2(0, 0), and highly unstable.

+

The cy fix for numerical instability below is from: Graphics +Gems IV, Paul Heckbert (editor), Academic Press, 1994, ISBN: +0123361559. Specifically it comes from EulerAngles.c by Ken +Shoemake, and deals with the case where cos(y) is close to zero:

+

See: http://www.graphicsgems.org/

+

The code appears to be licensed (from the website) as β€œcan be used +without restrictions”.

+
+ +
+
+

quat2eulerΒΆ

+
+
+nibabel.eulerangles.quat2euler(q)ΒΆ
+

Return Euler angles corresponding to quaternion q

+
+
Parameters:
+
+
q4 element sequence

w, x, y, z of quaternion

+
+
+
+
Returns:
+
+
zscalar

Rotation angle in radians around z-axis (performed first)

+
+
yscalar

Rotation angle in radians around y-axis

+
+
xscalar

Rotation angle in radians around x-axis (performed last)

+
+
+
+
+

Notes

+

It’s possible to reduce the amount of calculation a little, by +combining parts of the quat2mat and mat2euler functions, but +the reduction in computation is small, and the code repetition is +large.

+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.filebasedimages.html b/reference/nibabel.filebasedimages.html new file mode 100644 index 0000000000..69a23b4540 --- /dev/null +++ b/reference/nibabel.filebasedimages.html @@ -0,0 +1,794 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

filebasedimagesΒΆ

+

Common interface for any image format–volume or surface, binary or xml

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

FileBasedHeader()

Template class to implement header protocol

FileBasedImage([header,Β extra,Β file_map])

Abstract image class with interface for loading/saving images from disk.

ImageFileError

SerializableImage([header,Β extra,Β file_map])

Abstract image class for (de)serializing images to/from byte streams/strings.

+
+

FileBasedHeaderΒΆ

+
+
+class nibabel.filebasedimages.FileBasedHeaderΒΆ
+

Bases: object

+

Template class to implement header protocol

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+copy() HdrTΒΆ
+

Copy object to independent representation

+

The copy should not be affected by any changes to the original +object.

+
+ +
+
+classmethod from_fileobj(fileobj: IOBase) HdrTΒΆ
+
+ +
+
+classmethod from_header(header: FileBasedHeader | Mapping | None = None) HdrTΒΆ
+
+ +
+
+write_to(fileobj: IOBase) NoneΒΆ
+
+ +
+ +
+
+

FileBasedImageΒΆ

+
+
+class nibabel.filebasedimages.FileBasedImage(header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Bases: object

+

Abstract image class with interface for loading/saving images from disk.

+

The class doesn’t define any image properties.

+

It has:

+

attributes:

+
+
    +
  • extra

  • +
+
+

properties:

+
+
    +
  • header

  • +
+
+

methods:

+
+
    +
  • to_filename(fname) - writes data to filename(s) derived from +fname, where the derivation may differ between formats.

  • +
  • to_file_map() - save image to files with which the image is already +associated.

  • +
+
+

classmethods:

+
+
    +
  • from_filename(fname) - make instance by loading from filename

  • +
  • from_file_map(fmap) - make instance from file map

  • +
  • instance_to_filename(img, fname) - save img instance to +filename fname.

  • +
+
+

It also has a header - some standard set of meta-data that is specific +to the image format, and extra - a dictionary container for any other +metadata.

+

You cannot slice an image, and trying to slice an image generates an +informative TypeError.

+

There are several ways of writing data

+

There is the usual way, which is the default:

+
img.to_filename(fname)
+
+
+

and that is, to take the data encapsulated by the image and cast it to +the datatype the header expects, setting any available header scaling +into the header to help the data match.

+

You can load the data into an image from file with:

+
img.from_filename(fname)
+
+
+

The image stores its associated files in its file_map attribute. In +order to just save an image, for which you know there is an associated +filename, or other storage, you can do:

+
img.to_file_map()
+
+
+

Files interface

+

The image has an attribute file_map. This is a mapping, that has keys +corresponding to the file types that an image needs for storage. For +example, the Analyze data format needs an image and a header +file type for storage:

+
>>> import numpy as np
+>>> import nibabel as nib
+>>> data = np.arange(24, dtype='f4').reshape((2,3,4))
+>>> img = nib.AnalyzeImage(data, np.eye(4))
+>>> sorted(img.file_map)
+['header', 'image']
+
+
+

The values of file_map are not in fact files but objects with +attributes filename, fileobj and pos.

+

The reason for this interface, is that the contents of files has to +contain enough information so that an existing image instance can save +itself back to the files pointed to in file_map. When a file holder +holds active file-like objects, then these may be affected by the +initial file read; in this case, the file-like objects need to +carry the position at which a write (with to_file_map) should place the +data. The file_map contents should therefore be such, that this will +work.

+

Initialize image

+

The image is a combination of (header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Initialize image

+

The image is a combination of (header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+files_types: tuple[ExtensionSpec, ...] = (('image', None),)ΒΆ
+
+ +
+
+classmethod filespec_to_file_map(filespec: FileSpec) FileMapΒΆ
+

Make file_map for this class from filename filespec

+

Class method

+
+
Parameters:
+
+
filespecstr or os.PathLike

Filename that might be for this image file type.

+
+
+
+
Returns:
+
+
file_mapdict

file_map dict with (key, value) pairs of (file_type, +FileHolder instance), where file_type is a string giving the +type of the contained file.

+
+
+
+
Raises:
+
+
ImageFileError

if filespec is not recognizable as being a filename for this +image type.

+
+
+
+
+
+ +
+
+classmethod from_file_map(file_map: Mapping[str, FileHolder]) ImgTΒΆ
+
+ +
+
+classmethod from_filename(filename: FileSpec) ImgTΒΆ
+
+ +
+
+classmethod from_image(img: FileBasedImage) ImgTΒΆ
+

Class method to create new instance of own class from img

+
+
Parameters:
+
+
imgFileBasedImage instance

In fact, an object with the API of FileBasedImage.

+
+
+
+
Returns:
+
+
imgFileBasedImage instance

Image, of our own class

+
+
+
+
+
+ +
+
+get_filename() str | NoneΒΆ
+

Fetch the image filename

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
fnameNone or str

Returns None if there is no filename, or a filename string. +If an image may have several filenames associated with it (e.g. +Analyze .img, .hdr pair) then we return the more characteristic +filename (the .img filename in the case of Analyze’)

+
+
+
+
+
+ +
+
+property header: FileBasedHeaderΒΆ
+
+ +
+
+header_classΒΆ
+

alias of FileBasedHeader

+
+ +
+
+classmethod instance_to_filename(img: FileBasedImage, filename: FileSpec) NoneΒΆ
+

Save img in our own format, to name implied by filename

+

This is a class method

+
+
Parameters:
+
+
imgany FileBasedImage instance
+
filenamestr

Filename, implying name to which to save image.

+
+
+
+
+
+ +
+
+classmethod load(filename: FileSpec) ImgTΒΆ
+
+ +
+
+classmethod make_file_map(mapping: Mapping[str, str | IOBase] | None = None) Mapping[str, FileHolder]ΒΆ
+

Class method to make files holder for this image type

+
+
Parameters:
+
+
mappingNone or mapping, optional

mapping with keys corresponding to image file types (such as +β€˜image’, β€˜header’ etc, depending on image class) and values +that are filenames or file-like. Default is None

+
+
+
+
Returns:
+
+
file_mapdict

dict with string keys given by first entry in tuples in +sequence klass.files_types, and values of type FileHolder, +where FileHolder objects have default values, other than +those given by mapping

+
+
+
+
+
+ +
+
+makeable: bool = TrueΒΆ
+
+ +
+
+classmethod path_maybe_image(filename: FileSpec, sniff: FileSniff | None = None, sniff_max: int = 1024) tuple[bool, FileSniff | None]ΒΆ
+

Return True if filename may be image matching this class

+
+
Parameters:
+
+
filenamestr or os.PathLike

Filename for an image, or an image header (metadata) file. +If filename points to an image data file, and the image type has +a separate β€œheader” file, we work out the name of the header file, +and read from that instead of filename.

+
+
sniffNone or (bytes, filename), optional

Bytes content read from a previous call to this method, on another +class, with metadata filename. This allows us to read metadata +bytes once from the image or header, and pass this read set of +bytes to other image classes, therefore saving a repeat read of the +metadata. filename is used to validate that metadata would be +read from the same file, re-reading if not. None forces this +method to read the metadata.

+
+
sniff_maxint, optional

The maximum number of bytes to read from the metadata. If the +metadata file is long enough, we read this many bytes from the +file, otherwise we read to the end of the file. Longer values +sniff more of the metadata / image file, making it more likely that +the returned sniff will be useful for later calls to +path_maybe_image for other image classes.

+
+
+
+
Returns:
+
+
maybe_imagebool

True if filename may be valid for an image of this class.

+
+
sniffNone or (bytes, filename)

Read bytes content from found metadata. May be None if the file +does not appear to have useful metadata.

+
+
+
+
+
+ +
+
+rw: bool = TrueΒΆ
+
+ +
+
+set_filename(filename: str) NoneΒΆ
+

Sets the files in the object from a given filename

+

The different image formats may check whether the filename has +an extension characteristic of the format, and raise an error if +not.

+
+
Parameters:
+
+
filenamestr or os.PathLike

If the image format only has one file associated with it, +this will be the only filename set into the image +.file_map attribute. Otherwise, the image instance will +try and guess the other filenames from this given filename.

+
+
+
+
+
+ +
+
+to_file_map(file_map: Mapping[str, FileHolder] | None = None, **kwargs) NoneΒΆ
+
+ +
+
+to_filename(filename: FileSpec, **kwargs) NoneΒΆ
+

Write image to files implied by filename string

+
+
Parameters:
+
+
filenamestr or os.PathLike

filename to which to save image. We will parse filename +with filespec_to_file_map to work out names for image, +header etc.

+
+
**kwargskeyword arguments

Keyword arguments to format-specific save

+
+
+
+
Returns:
+
+
None
+
+
+
+
+ +
+
+valid_exts: tuple[str, ...] = ()ΒΆ
+
+ +
+ +
+
+

ImageFileErrorΒΆ

+
+
+class nibabel.filebasedimages.ImageFileErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

SerializableImageΒΆ

+
+
+class nibabel.filebasedimages.SerializableImage(header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Bases: FileBasedImage

+

Abstract image class for (de)serializing images to/from byte streams/strings.

+

The class doesn’t define any image properties.

+

It has:

+

methods:

+
+
    +
  • to_bytes() - serialize image to byte string

  • +
+
+

classmethods:

+
+
    +
  • from_bytes(bytestring) - make instance by deserializing a byte string

  • +
  • from_url(url) - make instance by fetching and deserializing a URL

  • +
+
+

Loading from byte strings should provide round-trip equivalence:

+
img_a = klass.from_bytes(bstr)
+img_b = klass.from_bytes(img_a.to_bytes())
+
+np.allclose(img_a.get_fdata(), img_b.get_fdata())
+np.allclose(img_a.affine, img_b.affine)
+
+
+

Further, for images that are single files on disk, the following methods of loading +the image must be equivalent:

+
img = klass.from_filename(fname)
+
+with open(fname, 'rb') as fobj:
+    img = klass.from_bytes(fobj.read())
+
+
+

And the following methods of saving a file must be equivalent:

+
img.to_filename(fname)
+
+with open(fname, 'wb') as fobj:
+    fobj.write(img.to_bytes())
+
+
+

Images that consist of separate header and data files (e.g., Analyze +images) currently do not support this interface. +For multi-file images, to_bytes() and from_bytes() must be +overridden, and any encoding details should be documented.

+

Initialize image

+

The image is a combination of (header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Initialize image

+

The image is a combination of (header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+classmethod from_bytes(bytestring: bytes) StreamImgTΒΆ
+

Construct image from a byte string

+

Class method

+
+
Parameters:
+
+
bytestringbytes

Byte string containing the on-disk representation of an image

+
+
+
+
+
+ +
+
+classmethod from_stream(io_obj: IOBase) StreamImgTΒΆ
+

Load image from readable IO stream

+

Convert to BytesIO to enable seeking, if input stream is not seekable

+
+
Parameters:
+
+
io_objIOBase object

Readable stream

+
+
+
+
+
+ +
+
+classmethod from_url(url: str | Request, timeout: float = 5) StreamImgTΒΆ
+

Retrieve and load an image from a URL

+

Class method

+
+
Parameters:
+
+
urlstr or urllib.request.Request object

URL of file to retrieve

+
+
timeoutfloat, optional

Time (in seconds) to wait for a response

+
+
+
+
+
+ +
+
+to_bytes(**kwargs) bytesΒΆ
+

Return a bytes object with the contents of the file that would +be written if the image were saved.

+
+
Parameters:
+
+
**kwargskeyword arguments

Keyword arguments that may be passed to img.to_file_map()

+
+
+
+
Returns:
+
+
bytes

Serialized image

+
+
+
+
+
+ +
+
+to_stream(io_obj: IOBase, **kwargs) NoneΒΆ
+

Save image to writable IO stream

+
+
Parameters:
+
+
io_objIOBase object

Writable stream

+
+
**kwargskeyword arguments

Keyword arguments that may be passed to img.to_file_map()

+
+
+
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.fileholders.html b/reference/nibabel.fileholders.html new file mode 100644 index 0000000000..c2ce17030e --- /dev/null +++ b/reference/nibabel.fileholders.html @@ -0,0 +1,290 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

fileholdersΒΆ

+

Fileholder class

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

FileHolder([filename,Β fileobj,Β pos])

class to contain filename, fileobj and file position

FileHolderError

copy_file_map(file_map)

Copy mapping of fileholders given by file_map

+
+

FileHolderΒΆ

+
+
+class nibabel.fileholders.FileHolder(filename: str | None = None, fileobj: IOBase | None = None, pos: int = 0)ΒΆ
+

Bases: object

+

class to contain filename, fileobj and file position

+

Initialize FileHolder instance

+
+
Parameters:
+
+
filenamestr, optional

filename. Default is None

+
+
fileobjfile-like object, optional

Should implement at least β€˜seek’ (for the purposes for this +class). Default is None

+
+
posint, optional

position in filename or fileobject at which to start reading +or writing data; defaults to 0

+
+
+
+
+
+
+__init__(filename: str | None = None, fileobj: IOBase | None = None, pos: int = 0)ΒΆ
+

Initialize FileHolder instance

+
+
Parameters:
+
+
filenamestr, optional

filename. Default is None

+
+
fileobjfile-like object, optional

Should implement at least β€˜seek’ (for the purposes for this +class). Default is None

+
+
posint, optional

position in filename or fileobject at which to start reading +or writing data; defaults to 0

+
+
+
+
+
+ +
+
+property file_like: str | IOBase | NoneΒΆ
+

Return self.fileobj if not None, otherwise self.filename

+
+ +
+
+get_prepare_fileobj(*args, **kwargs) ImageOpenerΒΆ
+

Return fileobj if present, or return fileobj from filename

+

Set position to that given in self.pos

+
+
Parameters:
+
+
*argstuple

positional arguments to file open. Ignored if there is a +defined self.fileobj. These might include the mode, such +as β€˜rb’

+
+
**kwargsdict

named arguments to file open. Ignored if there is a +defined self.fileobj

+
+
+
+
Returns:
+
+
fileobjfile-like object

object has position set (via fileobj.seek()) to +self.pos

+
+
+
+
+
+ +
+
+same_file_as(other: FileHolder) boolΒΆ
+

Test if self refers to same files / fileobj as other

+
+
Parameters:
+
+
otherobject

object with filename and fileobj attributes

+
+
+
+
Returns:
+
+
tfbool

True if other has the same filename (or both have None) and the +same fileobj (or both have None

+
+
+
+
+
+ +
+ +
+
+

FileHolderErrorΒΆ

+
+
+class nibabel.fileholders.FileHolderErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

copy_file_mapΒΆ

+
+
+nibabel.fileholders.copy_file_map(file_map: Mapping[str, FileHolder]) Mapping[str, FileHolder]ΒΆ
+

Copy mapping of fileholders given by file_map

+
+
Parameters:
+
+
file_mapmapping

mapping of FileHolder instances

+
+
+
+
Returns:
+
+
fm_copydict

Copy of file_map, using shallow copy of FileHolders

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.filename_parser.html b/reference/nibabel.filename_parser.html new file mode 100644 index 0000000000..e9d480c99d --- /dev/null +++ b/reference/nibabel.filename_parser.html @@ -0,0 +1,333 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

filename_parserΒΆ

+

Create filename pairs, triplets etc, with expected extensions

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

TypesFilenamesError

parse_filename(filename,Β types_exts,Β ...[,Β ...])

Split filename into fileroot, extension, trailing suffix; guess type.

splitext_addext(filename[,Β addexts,Β match_case])

Split /pth/fname.ext.gz into /pth/fname, .ext, .gz

types_filenames(template_fname,Β types_exts)

Return filenames with standard extensions from template name

+
+

TypesFilenamesErrorΒΆ

+
+
+class nibabel.filename_parser.TypesFilenamesErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

parse_filenameΒΆ

+
+
+nibabel.filename_parser.parse_filename(filename: FileSpec, types_exts: ty.Sequence[ExtensionSpec], trailing_suffixes: ty.Sequence[str], match_case: bool = False) tuple[str, str, str | None, str | None]ΒΆ
+

Split filename into fileroot, extension, trailing suffix; guess type.

+
+
Parameters:
+
+
filenamestr or os.PathLike

filename in which to search for type extensions

+
+
types_extssequence of sequences

sequence of (name, extension) str sequences defining type to +extension mapping.

+
+
trailing_suffixessequence of strings

suffixes that should be ignored when looking for +extensions

+
+
match_casebool, optional

If True, match case of extensions and trailing suffixes when +searching in filename, otherwise do case-insensitive match.

+
+
+
+
Returns:
+
+
pthstr

path with any matching extensions or trailing suffixes removed

+
+
extstr

If there were any matching extensions, in types_exts return +that; otherwise return extension derived from +os.path.splitext.

+
+
trailingstr

If there were any matching trailing_suffixes return that +matching suffix, otherwise β€˜β€™

+
+
guessed_typestr

If we found a matching extension in types_exts return the +corresponding type

+
+
+
+
+

Examples

+
>>> types_exts = (('t1', 'ext1'),('t2', 'ext2'))
+>>> parse_filename('/path/fname.funny', types_exts, ())
+('/path/fname', '.funny', None, None)
+>>> parse_filename('/path/fnameext2', types_exts, ())
+('/path/fname', 'ext2', None, 't2')
+>>> parse_filename('/path/fnameext2', types_exts, ('.gz',))
+('/path/fname', 'ext2', None, 't2')
+>>> parse_filename('/path/fnameext2.gz', types_exts, ('.gz',))
+('/path/fname', 'ext2', '.gz', 't2')
+
+
+
+ +
+
+

splitext_addextΒΆ

+
+
+nibabel.filename_parser.splitext_addext(filename: FileSpec, addexts: ty.Sequence[str] = ('.gz', '.bz2', '.zst'), match_case: bool = False) tuple[str, str, str]ΒΆ
+

Split /pth/fname.ext.gz into /pth/fname, .ext, .gz

+

where .gz may be any of passed addext trailing suffixes.

+
+
Parameters:
+
+
filenamestr or os.PathLike

filename that may end in any or none of addexts

+
+
match_casebool, optional

If True, match case of addexts and filename, otherwise do +case-insensitive match.

+
+
+
+
Returns:
+
+
frootstr

Root of filename - e.g. /pth/fname in example above

+
+
extstr

Extension, where extension is not in addexts - e.g. .ext in +example above

+
+
addextstr

Any suffixes appearing in addext occurring at end of filename

+
+
+
+
+

Examples

+
>>> splitext_addext('fname.ext.gz')
+('fname', '.ext', '.gz')
+>>> splitext_addext('fname.ext')
+('fname', '.ext', '')
+>>> splitext_addext('fname.ext.foo', ('.foo', '.bar'))
+('fname', '.ext', '.foo')
+
+
+
+ +
+
+

types_filenamesΒΆ

+
+
+nibabel.filename_parser.types_filenames(template_fname: FileSpec, types_exts: ty.Sequence[ExtensionSpec], trailing_suffixes: ty.Sequence[str] = ('.gz', '.bz2'), enforce_extensions: bool = True, match_case: bool = False) dict[str, str]ΒΆ
+

Return filenames with standard extensions from template name

+

The typical case is returning image and header filenames for an +Analyze image, that expects an β€˜image’ file type with extension .img, +and a β€˜header’ file type, with extension .hdr.

+
+
Parameters:
+
+
template_fnamestr or os.PathLike

template filename from which to construct output dict of +filenames, with given types_exts type to extension mapping. If +self.enforce_extensions is True, then filename must have one +of the defined extensions from the types list. If +self.enforce_extensions is False, then the other filenames +are guessed at by adding extensions to the base filename. +Ignored suffixes (from trailing_suffixes) append themselves to +the end of all the filenames.

+
+
types_extssequence of sequences

sequence of (name, extension) str sequences defining type to +extension mapping.

+
+
trailing_suffixessequence of strings, optional

suffixes that should be ignored when looking for +extensions - default is ('.gz', '.bz2')

+
+
enforce_extensions{True, False}, optional

If True, raise an error when attempting to set value to +type which has the wrong extension

+
+
match_casebool, optional

If True, match case of extensions and trailing suffixes when +searching in template_fname, otherwise do case-insensitive +match.

+
+
+
+
Returns:
+
+
types_fnamesdict

dict with types as keys, and generated filenames as values. The +types are given by the first elements of the tuples in +types_exts.

+
+
+
+
+

Examples

+
>>> types_exts = (('t1','.ext1'),('t2', '.ext2'))
+>>> tfns = types_filenames('/path/test.ext1', types_exts)
+>>> tfns == {'t1': '/path/test.ext1', 't2': '/path/test.ext2'}
+True
+
+
+

Bare file roots without extensions get them added

+
>>> tfns = types_filenames('/path/test', types_exts)
+>>> tfns == {'t1': '/path/test.ext1', 't2': '/path/test.ext2'}
+True
+
+
+

With enforce_extensions == False, allow first type to have any +extension.

+
>>> tfns = types_filenames('/path/test.funny', types_exts,
+...                        enforce_extensions=False)
+>>> tfns == {'t1': '/path/test.funny', 't2': '/path/test.ext2'}
+True
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.fileslice.html b/reference/nibabel.fileslice.html new file mode 100644 index 0000000000..5d733ec2c9 --- /dev/null +++ b/reference/nibabel.fileslice.html @@ -0,0 +1,746 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

filesliceΒΆ

+

Utilities for getting array slices out of file-like objects

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

calc_slicedefs(sliceobj,Β in_shape,Β itemsize,Β ...)

Return parameters for slicing array with sliceobj given memory layout

canonical_slicers(sliceobj,Β shape[,Β check_inds])

Return canonical version of sliceobj for array shape shape

fileslice(fileobj,Β sliceobj,Β shape,Β dtype[,Β ...])

Slice array in fileobj using sliceobj slicer and array definitions

fill_slicer(slicer,Β in_len)

Return slice object with Nones filled out to match in_len

is_fancy(sliceobj)

Returns True if sliceobj is attempting fancy indexing

optimize_read_slicers(sliceobj,Β in_shape,Β ...)

Calculates slices to read from disk, and apply after reading

optimize_slicer(slicer,Β dim_len,Β all_full,Β ...)

Return maybe modified slice and post-slice slicing for slicer

predict_shape(sliceobj,Β in_shape)

Predict shape of array from slicing array shape shape with sliceobj

read_segments(fileobj,Β segments,Β n_bytes[,Β lock])

Read n_bytes byte data implied by segments from fileobj

slice2len(slicer,Β in_len)

Output length after slicing original length in_len with slicer Parameters ---------- slicer : slice object in_len : int

slice2outax(ndim,Β sliceobj)

Matching output axes for input array ndim ndim and slice sliceobj

slicers2segments(read_slicers,Β in_shape,Β ...)

Get segments from read_slicers given in_shape and memory steps

strided_scalar(shape[,Β scalar])

Return array shape shape where all entries point to value scalar

threshold_heuristic(slicer,Β dim_len,Β stride)

Whether to force full axis read or contiguous read of stepped slice

+
+

calc_slicedefsΒΆ

+
+
+nibabel.fileslice.calc_slicedefs(sliceobj, in_shape, itemsize, offset, order, heuristic=<function threshold_heuristic>)ΒΆ
+

Return parameters for slicing array with sliceobj given memory layout

+

Calculate the best combination of skips / (read + discard) to use for +reading the data from disk / memory, then generate corresponding +segments, the disk offsets and read lengths to read the memory. If we +have chosen some (read + discard) optimization, then we need to discard the +surplus values from the read array using post_slicers, a slicing tuple +that takes the array as read from a file-like object, and returns the array +we want.

+
+
Parameters:
+
+
sliceobjobject

something that can be used to slice an array as in arr[sliceobj]

+
+
in_shapesequence

shape of underlying array to be sliced

+
+
itemsizeint

element size in array (in bytes)

+
+
offsetint

offset of array data in underlying file or memory buffer

+
+
order{β€˜C’, β€˜F’}

memory layout of underlying array

+
+
heuristiccallable, optional

function taking slice object, dim_len, stride length as arguments, +returning one of β€˜full’, β€˜contiguous’, None. See +optimize_slicer() and threshold_heuristic()

+
+
+
+
Returns:
+
+
segmentslist

list of 2 element lists where lists are (offset, length), giving +absolute memory offset in bytes and number of bytes to read

+
+
read_shapetuple

shape with which to interpret memory as read from segments. +Interpreting the memory read from segments with this shape, and a +dtype, gives an intermediate array - call this R

+
+
post_slicerstuple

Any new slicing to be applied to the array R after reading via +segments and reshaping via read_shape. Slices are in terms of +read_shape. If empty, no new slicing to apply

+
+
+
+
+
+ +
+
+

canonical_slicersΒΆ

+
+
+nibabel.fileslice.canonical_slicers(sliceobj, shape, check_inds=True)ΒΆ
+

Return canonical version of sliceobj for array shape shape

+

sliceobj is a slicer for an array A implied by shape.

+
    +
  • Expand sliceobj with slice(None) to add any missing (implied) axes +in sliceobj

  • +
  • Find any slicers in sliceobj that do a full axis slice and replace by +slice(None)

  • +
  • Replace any floating point values for slicing with integers

  • +
  • Replace negative integer slice values with equivalent positive integers.

  • +
+

Does not handle fancy indexing (indexing with arrays or array-like indices)

+
+
Parameters:
+
+
sliceobjobject

something that can be used to slice an array as in arr[sliceobj]

+
+
shapesequence

shape of array that will be indexed by sliceobj

+
+
check_inds{True, False}, optional

Whether to check if integer indices are out of bounds

+
+
+
+
Returns:
+
+
can_slicerstuple

version of sliceobj for which Ellipses have been expanded, missing +(implied) dimensions have been appended, and slice objects equivalent +to slice(None) have been replaced by slice(None), integer axes +have been checked, and negative indices set to positive equivalent

+
+
+
+
+
+ +
+
+

filesliceΒΆ

+
+
+nibabel.fileslice.fileslice(fileobj, sliceobj, shape, dtype, offset=0, order='C', heuristic=<function threshold_heuristic>, lock=None)ΒΆ
+

Slice array in fileobj using sliceobj slicer and array definitions

+

fileobj contains the contiguous binary data for an array A of shape, +dtype, memory layout shape, dtype, order, with the binary data +starting at file offset offset.

+

Our job is to return the sliced array A[sliceobj] in the most efficient +way in terms of memory and time.

+

Sometimes it will be quicker to read memory that we will later throw away, +to save time we might lose doing short seeks on fileobj. Call these +alternatives: (read + discard); and skip. This routine guesses when to +(read+discard) or skip using the callable heuristic, with a default using +a hard threshold for the memory gap large enough to prefer a skip.

+
+
Parameters:
+
+
fileobjfile-like object

file-like object, opened for reading in binary mode. Implements +read and seek.

+
+
sliceobjobject

something that can be used to slice an array as in arr[sliceobj].

+
+
shapesequence

shape of full array inside fileobj.

+
+
dtypedtype specifier

dtype of array inside fileobj, or input to numpy.dtype to specify +array dtype.

+
+
offsetint, optional

offset of array data within fileobj

+
+
order{β€˜C’, β€˜F’}, optional

memory layout of array in fileobj.

+
+
heuristiccallable, optional

function taking slice object, axis length, stride length as arguments, +returning one of β€˜full’, β€˜contiguous’, None. See +optimize_slicer() and see threshold_heuristic() for an +example.

+
+
lock{None, threading.Lock, lock-like} optional

If provided, used to ensure that paired calls to seek and read +cannot be interrupted by another thread accessing the same fileobj. +Each thread which accesses the same file via read_segments must +share a lock in order to ensure that the file access is thread-safe. +A lock does not need to be provided for single-threaded access. The +default value (None) results in a lock-like object (a +_NullLock) which does not do anything.

+
+
+
+
Returns:
+
+
sliced_arrarray

Array in fileobj as sliced with sliceobj

+
+
+
+
+
+ +
+
+

fill_slicerΒΆ

+
+
+nibabel.fileslice.fill_slicer(slicer, in_len)ΒΆ
+

Return slice object with Nones filled out to match in_len

+

Also fixes too large stop / start values according to slice() slicing +rules.

+

The returned slicer can have a None as slicer.stop if slicer.step is +negative and the input slicer.stop is None. This is because we can’t +represent the stop as an integer, because -1 has a different meaning.

+
+
Parameters:
+
+
slicerslice object
+
in_lenint

length of axis on which slicer will be applied

+
+
+
+
Returns:
+
+
can_slicerslice object

slice with start, stop, step set to explicit values, with the exception +of stop for negative step, which is None for the case of slicing +down through the first element

+
+
+
+
+
+ +
+
+

is_fancyΒΆ

+
+
+nibabel.fileslice.is_fancy(sliceobj)ΒΆ
+

Returns True if sliceobj is attempting fancy indexing

+
+
Parameters:
+
+
sliceobjobject

something that can be used to slice an array as in arr[sliceobj]

+
+
+
+
Returns:
+
+
tf: bool

True if sliceobj represents fancy indexing, False for basic indexing

+
+
+
+
+
+ +
+
+

optimize_read_slicersΒΆ

+
+
+nibabel.fileslice.optimize_read_slicers(sliceobj, in_shape, itemsize, heuristic)ΒΆ
+

Calculates slices to read from disk, and apply after reading

+
+
Parameters:
+
+
sliceobjobject

something that can be used to slice an array as in arr[sliceobj]. +Can be assumed to be canonical in the sense of canonical_slicers

+
+
in_shapesequence

shape of underlying array to be sliced. Array for in_shape assumed +to be already in β€˜F’ order. Reorder shape / sliceobj for slicing a β€˜C’ +array before passing to this function.

+
+
itemsizeint

element size in array (bytes)

+
+
heuristiccallable

function taking slice object, axis length, and stride length as +arguments, returning one of β€˜full’, β€˜contiguous’, None. See +optimize_slicer(); see threshold_heuristic() for an +example.

+
+
+
+
Returns:
+
+
read_slicerstuple

sliceobj maybe rephrased to fill out dimensions that are better read +from disk and later trimmed to their original size with post_slicers. +read_slicers implies a block of memory to be read from disk. The +actual disk positions come from slicers2segments run over +read_slicers. Includes any newaxis dimensions in sliceobj

+
+
post_slicerstuple

Any new slicing to be applied to the read array after reading. The +post_slicers discard any memory that we read to save time, but that +we don’t need for the slice. Include any newaxis dimension added +by sliceobj

+
+
+
+
+
+ +
+
+

optimize_slicerΒΆ

+
+
+nibabel.fileslice.optimize_slicer(slicer, dim_len, all_full, is_slowest, stride, heuristic=<function threshold_heuristic>)ΒΆ
+

Return maybe modified slice and post-slice slicing for slicer

+
+
Parameters:
+
+
slicerslice object or int
+
dim_lenint

length of axis along which to slice

+
+
all_fullbool

Whether dimensions up until now have been full (all elements)

+
+
is_slowestbool

Whether this dimension is the slowest changing in memory / on disk

+
+
strideint

size of one step along this axis

+
+
heuristiccallable, optional

function taking slice object, dim_len, stride length as arguments, +returning one of β€˜full’, β€˜contiguous’, None. See +threshold_heuristic() for an example.

+
+
+
+
Returns:
+
+
to_readslice object or int

maybe modified slice based on slicer expressing what data should be +read from an underlying file or buffer. to_read must always have +positive step (because we don’t want to go backwards in the buffer +/ file)

+
+
post_sliceslice object

slice to be applied after array has been read. Applies any +transformations in slicer that have not been applied in to_read. If +axis will be dropped by to_read slicing, so no slicing would make +sense, return string dropped

+
+
+
+
+

Notes

+

This is the heart of the algorithm for making segments from slice objects.

+

A contiguous slice is a slice with slice.step in (1, -1)

+

A full slice is a continuous slice returning all elements.

+

The main question we have to ask is whether we should transform to_read, +post_slice to prefer a full read and partial slice. We only do this in +the case of all_full==True. In this case we might benefit from reading a +continuous chunk of data even if the slice is not continuous, or reading +all the data even if the slice is not full. Apply a heuristic heuristic +to decide whether to do this, and adapt to_read and post_slice slice +accordingly.

+

Otherwise (apart from constraint to be positive) return to_read unaltered +and post_slice as slice(None)

+
+ +
+
+

predict_shapeΒΆ

+
+
+nibabel.fileslice.predict_shape(sliceobj, in_shape)ΒΆ
+

Predict shape of array from slicing array shape shape with sliceobj

+
+
Parameters:
+
+
sliceobjobject

something that can be used to slice an array as in arr[sliceobj]

+
+
in_shapesequence

shape of array that could be sliced by sliceobj

+
+
+
+
Returns:
+
+
out_shapetuple

predicted shape arising from slicing array shape in_shape with +sliceobj

+
+
+
+
+
+ +
+
+

read_segmentsΒΆ

+
+
+nibabel.fileslice.read_segments(fileobj, segments, n_bytes, lock=None)ΒΆ
+

Read n_bytes byte data implied by segments from fileobj

+
+
Parameters:
+
+
fileobjfile-like object

Implements seek and read

+
+
segmentssequence

list of 2 sequences where sequences are (offset, length), giving +absolute file offset in bytes and number of bytes to read

+
+
n_bytesint

total number of bytes that will be read

+
+
lock{None, threading.Lock, lock-like} optional

If provided, used to ensure that paired calls to seek and read +cannot be interrupted by another thread accessing the same fileobj. +Each thread which accesses the same file via read_segments must +share a lock in order to ensure that the file access is thread-safe. +A lock does not need to be provided for single-threaded access. The +default value (None) results in a lock-like object (a +_NullLock) which does not do anything.

+
+
+
+
Returns:
+
+
bufferbuffer object

object implementing buffer protocol, such as byte string or ndarray or +mmap or ctypes c_char_array

+
+
+
+
+
+ +
+
+

slice2lenΒΆ

+
+
+nibabel.fileslice.slice2len(slicer, in_len)ΒΆ
+

Output length after slicing original length in_len with slicer +Parameters +β€”β€”β€”- +slicer : slice object +in_len : int

+
+
Returns:
+
+
out_lenint

Length after slicing

+
+
+
+
+

Notes

+

Returns same as len(np.arange(in_len)[slicer])

+
+ +
+
+

slice2outaxΒΆ

+
+
+nibabel.fileslice.slice2outax(ndim, sliceobj)ΒΆ
+

Matching output axes for input array ndim ndim and slice sliceobj

+
+
Parameters:
+
+
ndimint

number of axes in input array

+
+
sliceobjobject

something that can be used to slice an array as in arr[sliceobj]

+
+
+
+
Returns:
+
+
out_ax_indstuple

Say A` is a (pretend) input array of `ndim` dimensions. Say ``B = +A[sliceobj]. out_ax_inds has one value per axis in A giving +corresponding axis in B.

+
+
+
+
+
+ +
+
+

slicers2segmentsΒΆ

+
+
+nibabel.fileslice.slicers2segments(read_slicers, in_shape, offset, itemsize)ΒΆ
+

Get segments from read_slicers given in_shape and memory steps

+
+
Parameters:
+
+
read_slicersobject

something that can be used to slice an array as in arr[sliceobj] +Slice objects can by be assumed canonical as in canonical_slicers, +and positive as in _positive_slice

+
+
in_shapesequence

shape of underlying array on disk before reading

+
+
offsetint

offset of array data in underlying file or memory buffer

+
+
itemsizeint

element size in array (in bytes)

+
+
+
+
Returns:
+
+
segmentslist

list of 2 element lists where lists are [offset, length], giving +absolute memory offset in bytes and number of bytes to read

+
+
+
+
+
+ +
+
+

strided_scalarΒΆ

+
+
+nibabel.fileslice.strided_scalar(shape, scalar=0.0)ΒΆ
+

Return array shape shape where all entries point to value scalar

+
+
Parameters:
+
+
shapesequence

Shape of output array.

+
+
scalarscalar

Scalar value with which to fill array.

+
+
+
+
Returns:
+
+
strided_arrarray

Array of shape shape for which all values == scalar, built by +setting all strides of strided_arr to 0, so the scalar is broadcast +out to the full array shape. strided_arr is flagged as not +writeable.

+

The array is set read-only to avoid a numpy error when broadcasting - +see https://github.com/numpy/numpy/issues/6491

+
+
+
+
+
+ +
+
+

threshold_heuristicΒΆ

+
+
+nibabel.fileslice.threshold_heuristic(slicer, dim_len, stride, skip_thresh=256)ΒΆ
+

Whether to force full axis read or contiguous read of stepped slice

+

Allows fileslice() to sometimes read memory that it will throw away +in order to get maximum speed. In other words, trade memory for fewer disk +reads.

+
+
Parameters:
+
+
slicerslice object, or int

If slice, can be assumed to be full as in fill_slicer

+
+
dim_lenint

length of axis being sliced

+
+
strideint

memory distance between elements on this axis

+
+
skip_threshint, optional

Memory gap threshold in bytes above which to prefer skipping memory +rather than reading it and later discarding.

+
+
+
+
Returns:
+
+
action{β€˜full’, β€˜contiguous’, None}

Gives the suggested optimization for reading the data

+
    +
  • β€˜full’ - read whole axis

  • +
  • β€˜contiguous’ - read all elements between start and stop

  • +
  • None - read only memory needed for output

  • +
+
+
+
+
+

Notes

+

Let’s say we are in the middle of reading a file at the start of some +memory length \(B\) bytes. We don’t need the memory, and we are considering +whether to read it anyway (then throw it away) (READ) or stop reading, skip +\(B\) bytes and restart reading from there (SKIP).

+

After trying some more fancy algorithms, a hard threshold (skip_thresh) +for the maximum skip distance seemed to work well, as measured by times on +nibabel.benchmarks.bench_fileslice

+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.fileutils.html b/reference/nibabel.fileutils.html new file mode 100644 index 0000000000..d8de6225a5 --- /dev/null +++ b/reference/nibabel.fileutils.html @@ -0,0 +1,166 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

fileutilsΒΆ

+

Utilities for reading and writing to binary file formats

+ + + + + + +

read_zt_byte_strings(fobj[,Β n_strings,Β bufsize])

Read zero-terminated byte strings from a file object fobj

+
+

read_zt_byte_stringsΒΆ

+
+
+nibabel.fileutils.read_zt_byte_strings(fobj, n_strings=1, bufsize=1024)ΒΆ
+

Read zero-terminated byte strings from a file object fobj

+

Returns byte strings with terminal zero stripped.

+

Found strings can be of any length.

+

The file position of fobj on exit will be at the byte after the terminal +0 of the final read byte string.

+
+
Parameters:
+
+
ffileobj

File object to use. Should implement read, returning byte objects, +and seek(n, 1) to seek from current file position.

+
+
n_stringsint, optional

Number of byte strings to return

+
+
bufsize: int, optional

Define chunk size to load from file while searching for zero terminals. +We load this many bytes at a time from the file, but the returned +strings can be longer than bufsize.

+
+
+
+
Returns:
+
+
byte_stringslist

List of byte strings, where strings do not include the terminal 0

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.freesurfer.html b/reference/nibabel.freesurfer.html new file mode 100644 index 0000000000..5c2a0a2fc8 --- /dev/null +++ b/reference/nibabel.freesurfer.html @@ -0,0 +1,1018 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

freesurferΒΆ

+

Reading functions for freesurfer files

+ + + +
+
+

Module: freesurfer.ioΒΆ

+

Read / write FreeSurfer geometry, morphometry, label, annotation formats

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

read_annot(filepath[,Β orig_ids])

Read in a Freesurfer annotation from a .annot file.

read_geometry(filepath[,Β read_metadata,Β ...])

Read a triangular format Freesurfer surface mesh.

read_label(filepath[,Β read_scalars])

Load in a Freesurfer .label file.

read_morph_data(filepath)

Read a Freesurfer morphometry data file.

write_annot(filepath,Β labels,Β ctab,Β names[,Β ...])

Write out a "new-style" Freesurfer annotation file.

write_geometry(filepath,Β coords,Β faces[,Β ...])

Write a triangular format Freesurfer surface mesh.

write_morph_data(file_like,Β values[,Β fnum])

Write Freesurfer morphometry data values to file-like file_like

+
+
+

Module: freesurfer.mghformatΒΆ

+

Header and image reading / writing functions for MGH image format

+

Author: Krish Subramaniam

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

MGHError

Exception for MGH format related problems.

MGHHeader([binaryblock,Β check])

Class for MGH format header

MGHImage(dataobj,Β affine[,Β header,Β extra,Β ...])

Class for MGH format image

+
+

read_annotΒΆ

+
+
+nibabel.freesurfer.io.read_annot(filepath, orig_ids=False)ΒΆ
+

Read in a Freesurfer annotation from a .annot file.

+

An .annot file contains a sequence of vertices with a label (also known +as an β€œannotation value”) associated with each vertex, and then a sequence +of colors corresponding to each label.

+

Annotation file format versions 1 and 2 are supported, corresponding to +the β€œold-style” and β€œnew-style” color table layout.

+

Note that the output color table ctab is in RGBT form, where T +(transparency) is 255 - alpha.

+
+
See:
+
+
+
+
Parameters:
+
+
filepathstr

Path to annotation file.

+
+
orig_idsbool

Whether to return the vertex ids as stored in the annotation +file or the positional colortable ids. With orig_ids=False +vertices with no id have an id set to -1.

+
+
+
+
Returns:
+
+
labelsndarray, shape (n_vertices,)

Annotation id at each vertex. If a vertex does not belong +to any label and orig_ids=False, its id will be set to -1.

+
+
ctabndarray, shape (n_labels, 5)

RGBT + label id colortable array.

+
+
nameslist of bytes

The names of the labels. The length of the list is n_labels.

+
+
+
+
+
+ +
+
+

read_geometryΒΆ

+
+
+nibabel.freesurfer.io.read_geometry(filepath, read_metadata=False, read_stamp=False)ΒΆ
+

Read a triangular format Freesurfer surface mesh.

+
+
Parameters:
+
+
filepathstr

Path to surface file.

+
+
read_metadatabool, optional

If True, read and return metadata as key-value pairs.

+

Valid keys:

+
    +
  • β€˜head’ : array of int

  • +
  • β€˜valid’ : str

  • +
  • β€˜filename’ : str

  • +
  • β€˜volume’ : array of int, shape (3,)

  • +
  • β€˜voxelsize’ : array of float, shape (3,)

  • +
  • β€˜xras’ : array of float, shape (3,)

  • +
  • β€˜yras’ : array of float, shape (3,)

  • +
  • β€˜zras’ : array of float, shape (3,)

  • +
  • β€˜cras’ : array of float, shape (3,)

  • +
+
+
read_stampbool, optional

Return the comment from the file

+
+
+
+
Returns:
+
+
coordsnumpy array

nvtx x 3 array of vertex (x, y, z) coordinates.

+
+
facesnumpy array

nfaces x 3 array of defining mesh triangles.

+
+
volume_infoOrderedDict

Returned only if read_metadata is True. Key-value pairs found in the +geometry file.

+
+
create_stampstr

Returned only if read_stamp is True. The comment added by the +program that saved the file.

+
+
+
+
+
+ +
+
+

read_labelΒΆ

+
+
+nibabel.freesurfer.io.read_label(filepath, read_scalars=False)ΒΆ
+

Load in a Freesurfer .label file.

+
+
Parameters:
+
+
filepathstr

Path to label file.

+
+
read_scalarsbool, optional

If True, read and return scalars associated with each vertex.

+
+
+
+
Returns:
+
+
label_arraynumpy array

Array with indices of vertices included in label.

+
+
scalar_arraynumpy array (floats)

Only returned if read_scalars is True. Array of scalar data for each +vertex.

+
+
+
+
+
+ +
+
+

read_morph_dataΒΆ

+
+
+nibabel.freesurfer.io.read_morph_data(filepath)ΒΆ
+

Read a Freesurfer morphometry data file.

+

This function reads in what Freesurfer internally calls β€œcurv” file types, +(e.g. ?h. curv, ?h.thickness), but as that has the potential to cause +confusion where β€œcurv” also refers to the surface curvature values, +we refer to these files as β€œmorphometry” files with PySurfer.

+
+
Parameters:
+
+
filepathstr

Path to morphometry file

+
+
+
+
Returns:
+
+
curvnumpy array

Vector representation of surface morpometry values

+
+
+
+
+
+ +
+
+

write_annotΒΆ

+
+
+nibabel.freesurfer.io.write_annot(filepath, labels, ctab, names, fill_ctab=True)ΒΆ
+

Write out a β€œnew-style” Freesurfer annotation file.

+

Note that the color table ctab is in RGBT form, where T (transparency) +is 255 - alpha.

+
+
See:
+
+
+
+
Parameters:
+
+
filepathstr

Path to annotation file to be written

+
+
labelsndarray, shape (n_vertices,)

Annotation id at each vertex.

+
+
ctabndarray, shape (n_labels, 5)

RGBT + label id colortable array.

+
+
nameslist of str

The names of the labels. The length of the list is n_labels.

+
+
fill_ctab{True, False} optional

If True, the annotation values for each vertex are automatically +generated. In this case, the provided ctab may have shape +(n_labels, 4) or (n_labels, 5) - if the latter, the final column is +ignored.

+
+
+
+
+
+ +
+
+

write_geometryΒΆ

+
+
+nibabel.freesurfer.io.write_geometry(filepath, coords, faces, create_stamp=None, volume_info=None)ΒΆ
+

Write a triangular format Freesurfer surface mesh.

+
+
Parameters:
+
+
filepathstr

Path to surface file.

+
+
coordsnumpy array

nvtx x 3 array of vertex (x, y, z) coordinates.

+
+
facesnumpy array

nfaces x 3 array of defining mesh triangles.

+
+
create_stampstr, optional

User/time stamp (default: β€œcreated by <user> on <ctime>”)

+
+
volume_infodict-like or None, optional

Key-value pairs to encode at the end of the file.

+

Valid keys:

+
    +
  • β€˜head’ : array of int

  • +
  • β€˜valid’ : str

  • +
  • β€˜filename’ : str

  • +
  • β€˜volume’ : array of int, shape (3,)

  • +
  • β€˜voxelsize’ : array of float, shape (3,)

  • +
  • β€˜xras’ : array of float, shape (3,)

  • +
  • β€˜yras’ : array of float, shape (3,)

  • +
  • β€˜zras’ : array of float, shape (3,)

  • +
  • β€˜cras’ : array of float, shape (3,)

  • +
+
+
+
+
+
+ +
+
+

write_morph_dataΒΆ

+
+
+nibabel.freesurfer.io.write_morph_data(file_like, values, fnum=0)ΒΆ
+

Write Freesurfer morphometry data values to file-like file_like

+

Equivalent to FreeSurfer’s write_curv.m

+

See also: +http://www.grahamwideman.com/gw/brain/fs/surfacefileformats.htm#CurvNew

+
+
Parameters:
+
+
file_likefile-like

String containing path of file to be written, or file-like object, open +in binary write (β€˜wb’ mode, implementing the write method)

+
+
valuesarray-like

Surface morphometry values. Shape must be (N,), (N, 1), (1, N) or (N, +1, 1)

+
+
fnumint, optional

Number of faces in the associated surface.

+
+
+
+
+
+ +
+
+

MGHErrorΒΆ

+
+
+class nibabel.freesurfer.mghformat.MGHErrorΒΆ
+

Bases: Exception

+

Exception for MGH format related problems.

+

To be raised whenever MGH is not happy, or we are not happy with +MGH.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

MGHHeaderΒΆ

+
+
+class nibabel.freesurfer.mghformat.MGHHeader(binaryblock=None, check=True)ΒΆ
+

Bases: LabeledWrapStruct, SpatialHeader

+

Class for MGH format header

+

The header also consists of the footer data which MGH places after the data +chunk.

+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+
+
+__init__(binaryblock=None, check=True)ΒΆ
+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+
+ +
+
+as_byteswapped(endianness=None)ΒΆ
+

Return new object with given endianness

+

If big endian, returns a copy of the object. Otherwise raises ValueError.

+
+
Parameters:
+
+
endiannessNone or string, optional

endian code to which to swap. None means swap from current +endianness, and is the default

+
+
+
+
Returns:
+
+
wstrMGHHeader

MGHHeader object

+
+
+
+
+
+ +
+
+static chk_version(hdr, fix=False)ΒΆ
+
+ +
+
+copy()ΒΆ
+

Return copy of structure

+
+ +
+
+data_from_fileobj(fileobj)ΒΆ
+

Read data array from fileobj

+
+
Parameters:
+
+
fileobjfile-like

Must be open, and implement read and seek methods

+
+
+
+
Returns:
+
+
arrndarray

data array

+
+
+
+
+
+ +
+
+classmethod default_structarr(endianness=None)ΒΆ
+

Return header data for empty header

+

Ignores byte order; always big endian

+
+ +
+
+classmethod diagnose_binaryblock(binaryblock, endianness=None)ΒΆ
+

Run checks over binary data, return string

+
+ +
+
+classmethod from_fileobj(fileobj, check=True)ΒΆ
+

classmethod for loading a MGH fileobject

+
+ +
+
+classmethod from_header(header=None, check=True)ΒΆ
+

Class method to create MGH header from another MGH header

+
+ +
+
+get_affine()ΒΆ
+

Get the affine transform from the header information.

+

MGH format doesn’t store the transform directly. Instead it’s gleaned +from the zooms ( delta ), direction cosines ( Mdc ), RAS centers ( +Pxyz_c ) and the dimensions.

+
+ +
+
+get_best_affine()ΒΆ
+

Get the affine transform from the header information.

+

MGH format doesn’t store the transform directly. Instead it’s gleaned +from the zooms ( delta ), direction cosines ( Mdc ), RAS centers ( +Pxyz_c ) and the dimensions.

+
+ +
+
+get_data_bytespervox()ΒΆ
+

Get the number of bytes per voxel of the data

+
+ +
+
+get_data_dtype()ΒΆ
+

Get numpy dtype for MGH data

+

For examples see set_data_dtype

+
+ +
+
+get_data_offset()ΒΆ
+

Return offset into data file to read data

+
+ +
+
+get_data_shape()ΒΆ
+

Get shape of data

+
+ +
+
+get_data_size()ΒΆ
+

Get the number of bytes the data chunk occupies.

+
+ +
+ +

Return offset where the footer resides. +Occurs immediately after the data chunk.

+
+ +
+
+get_ras2vox()ΒΆ
+

return the inverse get_affine()

+
+ +
+
+get_slope_inter()ΒΆ
+

MGH format does not do scaling?

+
+ +
+
+get_vox2ras()ΒΆ
+

return the get_affine()

+
+ +
+
+get_vox2ras_tkr()ΒΆ
+

Get the vox2ras-tkr transform. See β€œTorig” here: +https://surfer.nmr.mgh.harvard.edu/fswiki/CoordinateSystems

+
+ +
+
+get_zooms()ΒΆ
+

Get zooms from header

+

Returns the spacing of voxels in the x, y, and z dimensions. +For four-dimensional files, a fourth zoom is included, equal to the +repetition time (TR) in ms (see The MGH/MGZ Volume Format).

+

To access only the spatial zooms, use hdr[β€˜delta’].

+
+
Returns:
+
+
ztuple

tuple of header zoom values

+
+
+
+
+
+ +
+
+classmethod guessed_endian(mapping)ΒΆ
+

MGHHeader data must be big-endian

+
+ +
+
+set_data_dtype(datatype)ΒΆ
+

Set numpy dtype for data from code or dtype or type

+
+ +
+
+set_data_shape(shape)ΒΆ
+

Set shape of data

+
+
Parameters:
+
+
shapesequence

sequence of integers specifying data array shape

+
+
+
+
+
+ +
+
+set_zooms(zooms)ΒΆ
+

Set zooms into header fields

+

Sets the spacing of voxels in the x, y, and z dimensions. +For four-dimensional files, a temporal zoom (repetition time, or TR, in +ms) may be provided as a fourth sequence element.

+
+
Parameters:
+
+
zoomssequence

sequence of floats specifying spatial and (optionally) temporal +zooms

+
+
+
+
+
+ +
+
+template_dtype = dtype([('version', '>i4'), ('dims', '>i4', (4,)), ('type', '>i4'), ('dof', '>i4'), ('goodRASFlag', '>i2'), ('delta', '>f4', (3,)), ('Mdc', '>f4', (3, 3)), ('Pxyz_c', '>f4', (3,)), ('tr', '>f4'), ('flip_angle', '>f4'), ('te', '>f4'), ('ti', '>f4'), ('fov', '>f4')])ΒΆ
+
+ +
+
+writeftr_to(fileobj)ΒΆ
+

Write footer to fileobj

+

Footer data is located after the data chunk. So move there and write.

+
+
Parameters:
+
+
fileobjfile-like object

Should implement write and seek method

+
+
+
+
Returns:
+
+
None
+
+
+
+
+ +
+
+writehdr_to(fileobj)ΒΆ
+

Write header to fileobj

+

Write starts at the beginning.

+
+
Parameters:
+
+
fileobjfile-like object

Should implement write and seek method

+
+
+
+
Returns:
+
+
None
+
+
+
+
+ +
+ +
+
+

MGHImageΒΆ

+
+
+class nibabel.freesurfer.mghformat.MGHImage(dataobj, affine, header=None, extra=None, file_map=None)ΒΆ
+

Bases: SpatialImage, SerializableImage

+

Class for MGH format image

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj, affine, header=None, extra=None, file_map=None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+ImageArrayProxyΒΆ
+

alias of ArrayProxy

+
+ +
+
+files_types: tuple[ExtensionSpec, ...] = (('image', '.mgh'),)ΒΆ
+
+ +
+
+classmethod filespec_to_file_map(filespec)ΒΆ
+

Make file_map for this class from filename filespec

+

Class method

+
+
Parameters:
+
+
filespecstr or os.PathLike

Filename that might be for this image file type.

+
+
+
+
Returns:
+
+
file_mapdict

file_map dict with (key, value) pairs of (file_type, +FileHolder instance), where file_type is a string giving the +type of the contained file.

+
+
+
+
Raises:
+
+
ImageFileError

if filespec is not recognizable as being a filename for this +image type.

+
+
+
+
+
+ +
+
+classmethod from_file_map(file_map, *, mmap=True, keep_file_open=None)ΒΆ
+

Class method to create image from mapping in file_map

+
+
Parameters:
+
+
file_mapdict

Mapping with (kay, value) pairs of (file_type, FileHolder +instance giving file-likes for each file needed for this image +type.

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_map refers to an open file handle, this setting has no +effect. The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
Returns:
+
+
imgMGHImage instance
+
+
+
+
+ +
+
+header_classΒΆ
+

alias of MGHHeader

+
+ +
+
+makeable: bool = TrueΒΆ
+
+ +
+
+rw: bool = TrueΒΆ
+
+ +
+
+to_file_map(file_map=None)ΒΆ
+

Write image to file_map or contained self.file_map

+
+
Parameters:
+
+
file_mapNone or mapping, optional

files mapping. If None (default) use object’s file_map +attribute instead

+
+
+
+
+
+ +
+
+valid_exts: tuple[str, ...] = ('.mgh', '.mgz')ΒΆ
+
+ +
+ +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.funcs.html b/reference/nibabel.funcs.html new file mode 100644 index 0000000000..3d45da8112 --- /dev/null +++ b/reference/nibabel.funcs.html @@ -0,0 +1,301 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

funcsΒΆ

+

Processor functions for images

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

as_closest_canonical(img[,Β enforce_diag])

Return img with data reordered to be closest to canonical

concat_images(images[,Β check_affines,Β axis])

Concatenate images in list to single image, along specified dimension

four_to_three(img)

Create 3D images from 4D image by slicing over last axis

squeeze_image(img)

Return image, remove axes length 1 at end of image shape

+
+

as_closest_canonicalΒΆ

+
+
+nibabel.funcs.as_closest_canonical(img, enforce_diag=False)ΒΆ
+

Return img with data reordered to be closest to canonical

+

Canonical order is the ordering of the output axes.

+
+
Parameters:
+
+
imgspatialimage
+
enforce_diag{False, True}, optional

If True, before transforming image, check if the resulting image +affine will be close to diagonal, and if not, raise an error

+
+
+
+
Returns:
+
+
canonical_imgspatialimage

Version of img where the underlying array may have been +reordered and / or flipped so that axes 0,1,2 are those axes in +the input data that are, respectively, closest to the output axis +orientation. We modify the affine accordingly. If img is +already has the correct data ordering, we just return img +unmodified.

+
+
+
+
+
+ +
+
+

concat_imagesΒΆ

+
+
+nibabel.funcs.concat_images(images, check_affines=True, axis=None)ΒΆ
+

Concatenate images in list to single image, along specified dimension

+
+
Parameters:
+
+
imagessequence

sequence of SpatialImage or filenames of the same dimensionalitys

+
+
check_affines{True, False}, optional

If True, then check that all the affines for images are nearly +the same, raising a ValueError otherwise. Default is True

+
+
axisNone or int, optional

If None, concatenates on a new dimension. This requires all images to +be the same shape. If not None, concatenates on the specified +dimension. This requires all images to be the same shape, except on +the specified dimension.

+
+
+
+
Returns:
+
+
concat_imgSpatialImage

New image resulting from concatenating images across last +dimension

+
+
+
+
+
+ +
+
+

four_to_threeΒΆ

+
+
+nibabel.funcs.four_to_three(img)ΒΆ
+

Create 3D images from 4D image by slicing over last axis

+
+
Parameters:
+
+
imgimage

4D image instance of some class with methods get_data, +header and affine, and a class constructor +allowing klass(data, affine, header)

+
+
+
+
Returns:
+
+
imgslist

list of 3D images

+
+
+
+
+
+ +
+
+

squeeze_imageΒΆ

+
+
+nibabel.funcs.squeeze_image(img)ΒΆ
+

Return image, remove axes length 1 at end of image shape

+

For example, an image may have shape (10,20,30,1,1). In this case +squeeze will result in an image with shape (10,20,30). See doctests +for further description of behavior.

+
+
Parameters:
+
+
imgSpatialImage
+
+
+
Returns:
+
+
squeezed_imgSpatialImage

Copy of img, such that data, and data shape have been squeezed, +for dimensions > 3rd, and at the end of the shape list

+
+
+
+
+

Examples

+
>>> import nibabel as nf
+>>> shape = (10,20,30,1,1)
+>>> data = np.arange(np.prod(shape), dtype='int32').reshape(shape)
+>>> affine = np.eye(4)
+>>> img = nf.Nifti1Image(data, affine)
+>>> img.shape == (10, 20, 30, 1, 1)
+True
+>>> img2 = squeeze_image(img)
+>>> img2.shape == (10, 20, 30)
+True
+
+
+

If the data are 3D then last dimensions of 1 are ignored

+
>>> shape = (10,1,1)
+>>> data = np.arange(np.prod(shape), dtype='int32').reshape(shape)
+>>> img = nf.ni1.Nifti1Image(data, affine)
+>>> img.shape == (10, 1, 1)
+True
+>>> img2 = squeeze_image(img)
+>>> img2.shape == (10, 1, 1)
+True
+
+
+

Only final dimensions of 1 are squeezed

+
>>> shape = (1, 1, 5, 1, 2, 1, 1)
+>>> data = data.reshape(shape)
+>>> img = nf.ni1.Nifti1Image(data, affine)
+>>> img.shape == (1, 1, 5, 1, 2, 1, 1)
+True
+>>> img2 = squeeze_image(img)
+>>> img2.shape == (1, 1, 5, 1, 2)
+True
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.gifti.html b/reference/nibabel.gifti.html new file mode 100644 index 0000000000..95e9b258a4 --- /dev/null +++ b/reference/nibabel.gifti.html @@ -0,0 +1,1039 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

giftiΒΆ

+

GIfTI format IO

+ + + + + + +

gifti

Classes defining Gifti objects

+ + + +
+
+

Module: gifti.giftiΒΆ

+

Classes defining Gifti objects

+

The Gifti specification was (at time of writing) available as a PDF download +from http://www.nitrc.org/projects/gifti/

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

GiftiCoordSystem([dataspace,Β xformspace,Β xform])

Gifti coordinate system transform matrix

GiftiDataArray([data,Β intent,Β datatype,Β ...])

Container for Gifti numerical data array and associated metadata

GiftiImage([header,Β extra,Β file_map,Β meta,Β ...])

GIFTI image object

GiftiLabel([key,Β red,Β green,Β blue,Β alpha])

Gifti label: association of integer key with optional RGBA values

GiftiLabelTable()

Gifti label table: a sequence of key, label pairs

GiftiMetaData(*args,Β **kwargs)

A sequence of GiftiNVPairs containing metadata for a gifti data array

GiftiNVPairs([name,Β value])

Gifti name / value pairs

+
+
+

Module: gifti.parse_gifti_fastΒΆ

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

GiftiImageParser([encoding,Β buffer_size,Β ...])

+
Parameters:
+

+
+

GiftiParseError

Gifti-specific parsing error

read_data_block(darray,Β fname,Β data,Β mmap)

Parses data from a <Data> element, or loads from an external file.

+
+
+

Module: gifti.utilΒΆ

+ + + +
+
+

GiftiCoordSystemΒΆ

+
+
+class nibabel.gifti.gifti.GiftiCoordSystem(dataspace=0, xformspace=0, xform=None)ΒΆ
+

Bases: XmlSerializable

+

Gifti coordinate system transform matrix

+

Quotes are from the gifti spec dated 2011-01-14.

+
+

β€œFor a DataArray with an Intent NIFTI_INTENT_POINTSET, this element +describes the stereotaxic space of the data before and after the +application of a transformation matrix. The most common stereotaxic +space is the Talairach Space that places the origin at the anterior +commissure and the negative X, Y, and Z axes correspond to left, +posterior, and inferior respectively. At least one +CoordinateSystemTransformMatrix is required in a DataArray with an +intent of NIFTI_INTENT_POINTSET. Multiple +CoordinateSystemTransformMatrix elements may be used to describe the +transformation to multiple spaces.”

+
+
+
Attributes:
+
+
dataspaceint

From the spec: Contains the stereotaxic space of a DataArray’s data +prior to application of the transformation matrix. The stereotaxic +space should be one of:

+
+
    +
  • NIFTI_XFORM_UNKNOWN

  • +
  • NIFTI_XFORM_SCANNER_ANAT

  • +
  • NIFTI_XFORM_ALIGNED_ANAT

  • +
  • NIFTI_XFORM_TALAIRACH

  • +
  • NIFTI_XFORM_MNI_152

  • +
+
+
+
xformspaceint

Spec: β€œContains the stereotaxic space of a DataArray’s data after +application of the transformation matrix. See the DataSpace element for +a list of stereotaxic spaces.”

+
+
xformarray-like shape (4, 4)

Affine transformation matrix

+
+
+
+
+
+
+__init__(dataspace=0, xformspace=0, xform=None)ΒΆ
+
+ +
+
+print_summary()ΒΆ
+
+ +
+ +
+
+

GiftiDataArrayΒΆ

+
+
+class nibabel.gifti.gifti.GiftiDataArray(data=None, intent='NIFTI_INTENT_NONE', datatype=None, encoding='GIFTI_ENCODING_B64GZ', endian='little', coordsys=None, ordering='C', meta=None, ext_fname='', ext_offset=0)ΒΆ
+

Bases: XmlSerializable

+

Container for Gifti numerical data array and associated metadata

+

Quotes are from the gifti spec dated 2011-01-14.

+
+
Description of DataArray in spec:

β€œThis element contains the numeric data and its related metadata. The +CoordinateSystemTransformMatrix child is only used when the DataArray’s +Intent is NIFTI_INTENT_POINTSET. FileName and FileOffset are required +if the data is stored in an external file.”

+
+
+
+
Attributes:
+
+
darrayNone or ndarray

Data array

+
+
intentint

NIFTI intent code, see nifti1.intent_codes

+
+
datatypeint

NIFTI data type codes, see nifti1.data_type_codes. From the spec: +β€œThis required attribute describes the numeric type of the data +contained in a Data Array and are limited to the types displayed in the +table:

+

NIFTI_TYPE_UINT8 : Unsigned, 8-bit bytes. +NIFTI_TYPE_INT32 : Signed, 32-bit integers. +NIFTI_TYPE_FLOAT32 : 32-bit single precision floating point.”

+

At the moment, we do not enforce that the datatype is one of these +three.

+
+
encodingstring

Encoding of the data, see util.gifti_encoding_codes; default is +GIFTI_ENCODING_B64GZ.

+
+
endianstring

The Endianness to store the data array. Should correspond to the +machine endianness. Default is system byteorder.

+
+
coordsysGiftiCoordSystem instance

Input and output coordinate system with transformation matrix between +the two.

+
+
ind_ordint

The ordering of the array. see util.array_index_order_codes. Default +is RowMajorOrder - C ordering

+
+
metaGiftiMetaData instance

An instance equivalent to a dictionary for metadata information.

+
+
ext_fnamestr

Filename in which data is stored, or empty string if no corresponding +filename.

+
+
ext_offsetint

Position in bytes within ext_fname at which to start reading data.

+
+
+
+
+

Returns a shell object that cannot be saved.

+
+
+__init__(data=None, intent='NIFTI_INTENT_NONE', datatype=None, encoding='GIFTI_ENCODING_B64GZ', endian='little', coordsys=None, ordering='C', meta=None, ext_fname='', ext_offset=0)ΒΆ
+

Returns a shell object that cannot be saved.

+
+ +
+
+property metadataΒΆ
+

Returns metadata as dictionary

+
+ +
+
+property num_dimΒΆ
+
+ +
+
+print_summary()ΒΆ
+
+ +
+ +
+
+

GiftiImageΒΆ

+
+
+class nibabel.gifti.gifti.GiftiImage(header=None, extra=None, file_map=None, meta=None, labeltable=None, darrays=None, version='1.0')ΒΆ
+

Bases: XmlSerializable, SerializableImage

+

GIFTI image object

+

The Gifti spec suggests using the following suffixes to your +filename when saving each specific type of data:

+
+
.gii

Generic GIFTI File

+
+
.coord.gii

Coordinates

+
+
.func.gii

Functional

+
+
.label.gii

Labels

+
+
.rgba.gii

RGB or RGBA

+
+
.shape.gii

Shape

+
+
.surf.gii

Surface

+
+
.tensor.gii

Tensors

+
+
.time.gii

Time Series

+
+
.topo.gii

Topology

+
+
+

The Gifti file is stored in endian convention of the current machine.

+
+
+__init__(header=None, extra=None, file_map=None, meta=None, labeltable=None, darrays=None, version='1.0')ΒΆ
+
+ +
+
+add_gifti_data_array(dataarr)ΒΆ
+

Adds a data array to the GiftiImage

+
+
Parameters:
+
+
dataarrGiftiDataArray instance
+
+
+
+
+ +
+
+agg_data(intent_code=None)ΒΆ
+

Aggregate GIFTI data arrays into an ndarray or tuple of ndarray

+

In the general case, the numpy data array is extracted from each GiftiDataArray +object and returned in a tuple, in the order they are found in the GIFTI image.

+

If all GiftiDataArray s have intent of 2001 (NIFTI_INTENT_TIME_SERIES), +then the data arrays are concatenated as columns, producing a vertex-by-time array. +If an intent_code is passed, data arrays are filtered by the selected intents, +before being aggregated. +This may be useful for images containing several intents, or ensuring an expected +data type in an image of uncertain provenance. +If intent_code is a tuple, then a tuple will be returned with the result of +agg_data for each element, in order. +This may be useful for ensuring that expected data arrives in a consistent order.

+
+
Parameters:
+
+
intent_codeNone, string, integer or tuple of strings or integers, optional

code(s) specifying nifti intent

+
+
+
+
Returns:
+
+
tuple of ndarrays or ndarray

If the input is a tuple, the returned tuple will match the order.

+
+
+
+
+

Examples

+

Consider a surface GIFTI file:

+
>>> import nibabel as nib
+>>> from nibabel.testing import get_test_data
+>>> surf_img = nib.load(get_test_data('gifti', 'ascii.gii'))
+
+
+

The coordinate data, which is indicated by the NIFTI_INTENT_POINTSET +intent code, may be retrieved using any of the following equivalent +calls:

+
>>> coords = surf_img.agg_data('NIFTI_INTENT_POINTSET')
+>>> coords_2 = surf_img.agg_data('pointset')
+>>> coords_3 = surf_img.agg_data(1008)  # Numeric code for pointset
+>>> print(np.array2string(coords, precision=3))
+[[-16.072 -66.188  21.267]
+ [-16.706 -66.054  21.233]
+ [-17.614 -65.402  21.071]]
+>>> np.array_equal(coords, coords_2)
+True
+>>> np.array_equal(coords, coords_3)
+True
+
+
+

Similarly, the triangle mesh can be retrieved using various intent +specifiers:

+
>>> triangles = surf_img.agg_data('NIFTI_INTENT_TRIANGLE')
+>>> triangles_2 = surf_img.agg_data('triangle')
+>>> triangles_3 = surf_img.agg_data(1009)  # Numeric code for pointset
+>>> print(np.array2string(triangles))
+[0 1 2]
+>>> np.array_equal(triangles, triangles_2)
+True
+>>> np.array_equal(triangles, triangles_3)
+True
+
+
+

All arrays can be retrieved as a tuple by omitting the intent +code:

+
>>> coords_4, triangles_4 = surf_img.agg_data()
+>>> np.array_equal(coords, coords_4)
+True
+>>> np.array_equal(triangles, triangles_4)
+True
+
+
+

Finally, a tuple of intent codes may be passed in order to select +the arrays in a specific order:

+
>>> triangles_5, coords_5 = surf_img.agg_data(('triangle', 'pointset'))
+>>> np.array_equal(triangles, triangles_5)
+True
+>>> np.array_equal(coords, coords_5)
+True
+
+
+

The following image is a GIFTI file with ten (10) data arrays of the same +size, and with intent code 2001 (NIFTI_INTENT_TIME_SERIES):

+
>>> func_img = nib.load(get_test_data('gifti', 'task.func.gii'))
+
+
+

When aggregating time series data, these arrays are concatenated into +a single, vertex-by-timestep array:

+
>>> series = func_img.agg_data()
+>>> series.shape
+(642, 10)
+
+
+

In the case of a GIFTI file with unknown data arrays, it may be preferable +to specify the intent code, so that a time series array is always returned:

+
>>> series_2 = func_img.agg_data('NIFTI_INTENT_TIME_SERIES')
+>>> series_3 = func_img.agg_data('time series')
+>>> series_4 = func_img.agg_data(2001)
+>>> np.array_equal(series, series_2)
+True
+>>> np.array_equal(series, series_3)
+True
+>>> np.array_equal(series, series_4)
+True
+
+
+

Requesting a data array from a GIFTI file with no matching intent codes +will result in an empty tuple:

+
>>> surf_img.agg_data('time series')
+()
+>>> func_img.agg_data('triangle')
+()
+
+
+
+ +
+
+files_types: tuple[ExtensionSpec, ...] = (('image', '.gii'),)ΒΆ
+
+ +
+
+classmethod from_file_map(file_map, buffer_size=35000000, mmap=True)ΒΆ
+

Load a Gifti image from a file_map

+
+
Parameters:
+
+
file_mapdict

Dictionary with single key image with associated value which is +a FileHolder instance pointing to the image file.

+
+
buffer_size: None or int, optional

size of read buffer. None uses default buffer_size +from xml.parsers.expat.

+
+
mmap{True, False, β€˜c’, β€˜r’, β€˜r+’}

Controls the use of numpy memory mapping for reading data. Only +has an effect when loading GIFTI images with data stored in +external files (DataArray elements with an Encoding equal +to ExternalFileBinary). If False, do not try numpy +memmap for data array. If one of {'c', 'r', 'r+'}, try +numpy memmap with mode=mmap. A mmap value of True +gives the same behavior as mmap='c'. If the file cannot be +memory-mapped, ignore mmap value and read array from file.

+
+
+
+
Returns:
+
+
imgGiftiImage
+
+
+
+
+ +
+
+classmethod from_filename(filename, buffer_size=35000000, mmap=True)ΒΆ
+
+ +
+
+get_arrays_from_intent(intent)ΒΆ
+

Return list of GiftiDataArray elements matching given intent

+
+ +
+
+property labeltableΒΆ
+
+ +
+
+property metaΒΆ
+
+ +
+
+property numDAΒΆ
+
+ +
+
+parserΒΆ
+

alias of GiftiImageParser

+
+ +
+
+print_summary()ΒΆ
+
+ +
+
+remove_gifti_data_array(ith)ΒΆ
+

Removes the ith data array element from the GiftiImage

+
+ +
+
+remove_gifti_data_array_by_intent(intent)ΒΆ
+

Removes all the data arrays with the given intent type

+
+ +
+
+to_bytes(enc='utf-8', *, mode='strict')ΒΆ
+

Return a bytes object with the contents of the file that would +be written if the image were saved.

+
+
Parameters:
+
+
**kwargskeyword arguments

Keyword arguments that may be passed to img.to_file_map()

+
+
+
+
Returns:
+
+
bytes

Serialized image

+
+
+
+
+
+ +
+
+to_file_map(file_map=None, enc='utf-8', *, mode='strict')ΒΆ
+

Save the current image to the specified file_map

+
+
Parameters:
+
+
file_mapdict

Dictionary with single key image with associated value which is +a FileHolder instance pointing to the image file.

+
+
+
+
Returns:
+
+
None
+
+
+
+
+ +
+
+to_xml(enc='utf-8', *, mode='strict', **kwargs) bytesΒΆ
+

Return XML corresponding to image content

+
+ +
+
+valid_exts: tuple[str, ...] = ('.gii',)ΒΆ
+
+ +
+ +
+
+

GiftiLabelΒΆ

+
+
+class nibabel.gifti.gifti.GiftiLabel(key=0, red=None, green=None, blue=None, alpha=None)ΒΆ
+

Bases: XmlSerializable

+

Gifti label: association of integer key with optional RGBA values

+

Quotes are from the gifti spec dated 2011-01-14.

+

Notes

+

freesurfer examples seem not to conform to datatype β€œNIFTI_TYPE_RGBA32” +because they are floats, not 4 8-bit integers.

+
+
Attributes:
+
+
keyint

(From the spec): β€œThis required attribute contains a non-negative +integer value. If a DataArray’s Intent is NIFTI_INTENT_LABEL and a +value in the DataArray is β€˜X’, its corresponding label is the label +with the Key attribute containing the value β€˜X’. In early versions of +the GIFTI file format, the attribute Index was used instead of Key. If +an Index attribute is encountered, it should be processed like the Key +attribute.”

+
+
redNone or float

Optional value for red.

+
+
greenNone or float

Optional value for green.

+
+
blueNone or float

Optional value for blue.

+
+
alphaNone or float

Optional value for alpha.

+
+
+
+
+
+
+__init__(key=0, red=None, green=None, blue=None, alpha=None)ΒΆ
+
+ +
+
+property rgbaΒΆ
+

Returns RGBA as tuple

+
+ +
+ +
+
+

GiftiLabelTableΒΆ

+
+
+class nibabel.gifti.gifti.GiftiLabelTableΒΆ
+

Bases: XmlSerializable

+

Gifti label table: a sequence of key, label pairs

+
+
From the gifti spec dated 2011-01-14:

The label table is used by DataArrays whose values are an key into the +LabelTable’s labels. A file should contain at most one LabelTable and +it must be located in the file prior to any DataArray elements.

+
+
+
+
+__init__()ΒΆ
+
+ +
+
+get_labels_as_dict()ΒΆ
+
+ +
+
+print_summary()ΒΆ
+
+ +
+ +
+
+

GiftiMetaDataΒΆ

+
+
+class nibabel.gifti.gifti.GiftiMetaData(*args, **kwargs)ΒΆ
+

Bases: CaretMetaData

+

A sequence of GiftiNVPairs containing metadata for a gifti data array

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+property dataΒΆ
+

The data attribute is deprecated. Use GiftiMetaData object directly as a dict.

+
    +
  • deprecated from version: 4.0

  • +
  • Will raise <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 6.0

  • +
+
+ +
+
+classmethod from_dict(data_dict)ΒΆ
+

from_dict class method deprecated. Use GiftiMetaData directly.

+
    +
  • deprecated from version: 4.0

  • +
  • Will raise <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 6.0

  • +
+
+ +
+
+property metadataΒΆ
+

Returns metadata as dictionary

+

metadata property deprecated. Use GiftiMetaData object as dict or pass to dict() for a standard dictionary.

+
    +
  • deprecated from version: 4.0

  • +
  • Will raise <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 6.0

  • +
+
+ +
+
+print_summary()ΒΆ
+
+ +
+ +
+
+

GiftiNVPairsΒΆ

+
+
+class nibabel.gifti.gifti.GiftiNVPairs(name='', value='')ΒΆ
+

Bases: object

+

Gifti name / value pairs

+
+
Attributes:
+
+
namestr
+
valuestr
+
+
+
+

GiftiNVPairs objects are deprecated. Use the GiftiMetaData object as a dict, instead.

+
    +
  • deprecated from version: 4.0

  • +
  • Will raise <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 6.0

  • +
+
+
+__init__(name='', value='')ΒΆ
+

GiftiNVPairs objects are deprecated. Use the GiftiMetaData object as a dict, instead.

+
    +
  • deprecated from version: 4.0

  • +
  • Will raise <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 6.0

  • +
+
+ +
+
+property nameΒΆ
+
+ +
+
+property valueΒΆ
+
+ +
+ +
+
+

GiftiImageParserΒΆ

+
+
+class nibabel.gifti.parse_gifti_fast.GiftiImageParser(encoding=None, buffer_size=35000000, verbose=0, mmap=True)ΒΆ
+

Bases: XmlParser

+
+
Parameters:
+
+
encodingstr

string containing xml document

+
+
buffer_size: None or int, optional

size of read buffer. None uses default buffer_size +from xml.parsers.expat.

+
+
verboseint, optional

amount of output during parsing (0=silent, by default).

+
+
+
+
+
+
+__init__(encoding=None, buffer_size=35000000, verbose=0, mmap=True)ΒΆ
+
+
Parameters:
+
+
encodingstr

string containing xml document

+
+
buffer_size: None or int, optional

size of read buffer. None uses default buffer_size +from xml.parsers.expat.

+
+
verboseint, optional

amount of output during parsing (0=silent, by default).

+
+
+
+
+
+ +
+
+CharacterDataHandler(data)ΒΆ
+

Collect character data chunks pending collation

+

The parser breaks the data up into chunks of size depending on the +buffer_size of the parser. A large bit of character data, with +standard parser buffer_size (such as 8K) can easily span many calls to +this function. We thus collect the chunks and process them when we +hit start or end tags.

+
+ +
+
+EndElementHandler(name)ΒΆ
+
+ +
+
+StartElementHandler(name, attrs)ΒΆ
+
+ +
+
+flush_chardata()ΒΆ
+

Collate and process collected character data

+
+ +
+
+property pending_dataΒΆ
+

True if there is character data pending for processing

+
+ +
+ +
+
+

GiftiParseErrorΒΆ

+
+
+class nibabel.gifti.parse_gifti_fast.GiftiParseErrorΒΆ
+

Bases: ExpatError

+

Gifti-specific parsing error

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

read_data_blockΒΆ

+
+
+nibabel.gifti.parse_gifti_fast.read_data_block(darray, fname, data, mmap)ΒΆ
+

Parses data from a <Data> element, or loads from an external file.

+
+
Parameters:
+
+
darrayGiftiDataArray

GiftiDataArray object representing the parent <DataArray> of this +<Data> element

+
+
fnamestr or None

Name of GIFTI file being loaded, or None if in-memory

+
+
datastr or None

Data to parse, or None if data is in an external file

+
+
mmap{True, False, β€˜c’, β€˜r’, β€˜r+’}

Controls the use of numpy memory mapping for reading data. Only has +an effect when loading GIFTI images with data stored in external files +(DataArray elements with an Encoding equal to +ExternalFileBinary). If False, do not try numpy memmap +for data array. If one of {'c', 'r', 'r+'}, try numpy memmap +with mode=mmap. A mmap value of True gives the same +behavior as mmap='c'. If the file cannot be memory-mapped, ignore +mmap value and read array from file.

+
+
+
+
Returns:
+
+
numpy.ndarray or numpy.memmap containing the parsed data
+
+
+
+
+ +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.html b/reference/nibabel.html new file mode 100644 index 0000000000..42891a3cf7 --- /dev/null +++ b/reference/nibabel.html @@ -0,0 +1,306 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

nibabelΒΆ

+

Read and write access to common neuroimaging file formats, including: +ANALYZE (plain, SPM99, SPM2 and later), GIFTI, NIfTI1, NIfTI2, CIFTI-2, +MINC1, MINC2, AFNI BRIK/HEAD, ECAT and Philips PAR/REC. +In addition, NiBabel also supports FreeSurfer’s MGH, geometry, annotation and +morphometry files, and provides some limited support for DICOM.

+

NiBabel’s API gives full or selective access to header information (metadata), +and image data is made available via NumPy arrays. For more information, see +NiBabel’s documentation site and API reference.

+
+

InstallationΒΆ

+

To install NiBabel’s current release with pip, run:

+
pip install nibabel
+
+
+

To install the latest development version, run:

+
pip install git+https://github.com/nipy/nibabel
+
+
+

When working on NiBabel itself, it may be useful to install in β€œeditable” mode:

+
git clone https://github.com/nipy/nibabel.git
+pip install -e ./nibabel
+
+
+

For more information on previous releases, see the release archive or +development changelog.

+
+
+

TestingΒΆ

+

During development, we recommend using tox to run nibabel tests:

+
git clone https://github.com/nipy/nibabel.git
+cd nibabel
+tox
+
+
+

To test an installed version of nibabel, install the test dependencies +and run pytest:

+
pip install nibabel[test]
+pytest --pyargs nibabel
+
+
+

For more information, consult the developer guidelines.

+
+
+

Mailing ListΒΆ

+

Please send any questions or suggestions to the neuroimaging mailing list.

+
+
+

LicenseΒΆ

+

NiBabel is licensed under the terms of the MIT license. +Some code included with NiBabel is licensed under the BSD license. +For more information, please see the COPYING file.

+
+
+

CitationΒΆ

+

NiBabel releases have a Zenodo Digital Object Identifier (DOI) badge at +the top of the release notes. Click on the badge for more information.

+
+
+

QuickstartΒΆ

+
import nibabel as nib
+
+img1 = nib.load('my_file.nii')
+img2 = nib.load('other_file.nii.gz')
+img3 = nib.load('spm_file.img')
+
+data = img1.get_fdata()
+affine = img1.affine
+
+print(img1)
+
+nib.save(img1, 'my_file_copy.nii.gz')
+
+new_image = nib.Nifti1Image(data, affine)
+nib.save(new_image, 'new_image.nii.gz')
+
+
+

For more detailed information see the NiBabel Manual.

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

bench([label,Β verbose,Β extra_argv])

Run benchmarks for nibabel using pytest

get_info()

test([label,Β verbose,Β extra_argv,Β doctests,Β ...])

Run tests for nibabel using pytest

+
+

benchΒΆ

+
+
+nibabel.bench(label=None, verbose=1, extra_argv=None)ΒΆ
+

Run benchmarks for nibabel using pytest

+

The protocol mimics the numpy.testing.NoseTester.bench(). +Not all features are currently implemented.

+
+
Parameters:
+
+
labelNone

Unused.

+
+
verbose: int, optional

Verbosity value for test outputs. Positive values increase verbosity, and +negative values decrease it. Default is 1.

+
+
extra_argvlist, optional

List with any extra arguments to pass to pytest.

+
+
+
+
Returns:
+
+
codeExitCode

Returns the result of running the tests as a pytest.ExitCode enum

+
+
+
+
+
+ +
+
+

get_infoΒΆ

+
+
+nibabel.get_info()ΒΆ
+
+ +
+
+

testΒΆ

+
+
+nibabel.test(label=None, verbose=1, extra_argv=None, doctests=False, coverage=False, raise_warnings=None, timer=False)ΒΆ
+

Run tests for nibabel using pytest

+

The protocol mimics the numpy.testing.NoseTester.test(). +Not all features are currently implemented.

+
+
Parameters:
+
+
labelNone

Unused.

+
+
verbose: int, optional

Verbosity value for test outputs. Positive values increase verbosity, and +negative values decrease it. Default is 1.

+
+
extra_argvlist, optional

List with any extra arguments to pass to pytest.

+
+
doctests: bool, optional

If True, run doctests in module. Default is False.

+
+
coverage: bool, optional

If True, report coverage of NumPy code. Default is False. +(This requires the +coverage module).

+
+
raise_warningsNone

Unused.

+
+
timerFalse

Unused.

+
+
+
+
Returns:
+
+
codeExitCode

Returns the result of running the tests as a pytest.ExitCode enum

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.imageclasses.html b/reference/nibabel.imageclasses.html new file mode 100644 index 0000000000..c69d1aa21d --- /dev/null +++ b/reference/nibabel.imageclasses.html @@ -0,0 +1,155 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

imageclassesΒΆ

+

Define supported image classes and names

+ + + + + + +

spatial_axes_first(img)

True if spatial image axes for img always precede other axes

+
+

spatial_axes_firstΒΆ

+
+
+nibabel.imageclasses.spatial_axes_first(img: DataobjImage) boolΒΆ
+

True if spatial image axes for img always precede other axes

+
+
Parameters:
+
+
imgobject

Image object implementing at least shape attribute.

+
+
+
+
Returns:
+
+
spatial_axes_firstbool

True if image only has spatial axes (number of axes < 4) or image type +known to have spatial axes preceding other axes.

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.imageglobals.html b/reference/nibabel.imageglobals.html new file mode 100644 index 0000000000..71c5cb7499 --- /dev/null +++ b/reference/nibabel.imageglobals.html @@ -0,0 +1,184 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

imageglobalsΒΆ

+

Defaults for images and headers

+

error_level is the problem level (see BatteryRunners) at which an error will be +raised, by the batteryrunners log_raise method. Thus a level of 0 will +result in an error for any problem at all, and a level of 50 will mean no errors +will be raised (unless someone’s put some strange problem_level > 50 code in).

+

logger is the default logger (python log instance)

+

To set the log level (log message appears for problem of level >= log level), +use e.g. logger.level = 40.

+

As for most loggers, if logger.level == 0 then a default log level is used - +use logger.getEffectiveLevel() to see what that default is.

+

Use logger.level = 1 to see all messages.

+ + + + + + + + + +

ErrorLevel(level)

Context manager to set log error level

LoggingOutputSuppressor()

Context manager to prevent global logger from printing

+
+

ErrorLevelΒΆ

+
+
+class nibabel.imageglobals.ErrorLevel(level)ΒΆ
+

Bases: object

+

Context manager to set log error level

+
+
+__init__(level)ΒΆ
+
+ +
+ +
+
+

LoggingOutputSuppressorΒΆ

+
+
+class nibabel.imageglobals.LoggingOutputSuppressorΒΆ
+

Bases: object

+

Context manager to prevent global logger from printing

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.imagestats.html b/reference/nibabel.imagestats.html new file mode 100644 index 0000000000..9c20411c0d --- /dev/null +++ b/reference/nibabel.imagestats.html @@ -0,0 +1,195 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

imagestatsΒΆ

+

Functions for computing image statistics

+ + + + + + + + + +

count_nonzero_voxels(img)

Count number of non-zero voxels

mask_volume(img)

Compute volume of mask image.

+
+

count_nonzero_voxelsΒΆ

+
+
+nibabel.imagestats.count_nonzero_voxels(img)ΒΆ
+

Count number of non-zero voxels

+
+
Parameters:
+
+
imgSpatialImage

All voxels of the mask should be of value 1, background should have value 0.

+
+
+
+
Returns:
+
+
countint

Number of non-zero voxels

+
+
+
+
+
+ +
+
+

mask_volumeΒΆ

+
+
+nibabel.imagestats.mask_volume(img)ΒΆ
+

Compute volume of mask image.

+

Equivalent to β€œfslstats /path/file.nii -V”

+
+
Parameters:
+
+
imgSpatialImage

All voxels of the mask should be of value 1, background should have value 0.

+
+
+
+
Returns:
+
+
volumefloat

Volume of mask expressed in mm3.

+
+
+
+
+

Examples

+
>>> import numpy as np
+>>> import nibabel as nb
+>>> mask_data = np.zeros((20, 20, 20), dtype='u1')
+>>> mask_data[5:15, 5:15, 5:15] = 1
+>>> nb.imagestats.mask_volume(nb.Nifti1Image(mask_data, np.eye(4)))
+1000.0
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.loadsave.html b/reference/nibabel.loadsave.html new file mode 100644 index 0000000000..011bce22b1 --- /dev/null +++ b/reference/nibabel.loadsave.html @@ -0,0 +1,231 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

loadsaveΒΆ

+

Utilities to load and save image objects

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

guessed_image_type(filename)

Guess image type from file filename

load(filename,Β **kwargs)

Load file given filename, guessing at file type

read_img_data(img[,Β prefer])

Read data from image associated with files

save(img,Β filename,Β **kwargs)

Save an image to file adapting format to filename

+
+

guessed_image_typeΒΆ

+
+
+nibabel.loadsave.guessed_image_type(filename)ΒΆ
+

Guess image type from file filename

+

guessed_image_type deprecated.

+
    +
  • deprecated from version: 3.2

  • +
  • Raises <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 5.0

  • +
+
+ +
+
+

loadΒΆ

+
+
+nibabel.loadsave.load(filename: FileSpec, **kwargs) FileBasedImageΒΆ
+

Load file given filename, guessing at file type

+
+
Parameters:
+
+
filenamestr or os.PathLike

specification of file to load

+
+
**kwargskeyword arguments

Keyword arguments to format-specific load

+
+
+
+
Returns:
+
+
imgSpatialImage

Image of guessed type

+
+
+
+
+
+ +
+
+

read_img_dataΒΆ

+
+
+nibabel.loadsave.read_img_data(img, prefer='scaled')ΒΆ
+

Read data from image associated with files

+

read_img_data deprecated. Please use img.dataobj.get_unscaled() instead.

+
    +
  • deprecated from version: 3.2

  • +
  • Raises <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 5.0

  • +
+
+ +
+
+

saveΒΆ

+
+
+nibabel.loadsave.save(img: FileBasedImage, filename: FileSpec, **kwargs) NoneΒΆ
+

Save an image to file adapting format to filename

+
+
Parameters:
+
+
imgSpatialImage

image to save

+
+
filenamestr or os.PathLike

filename (often implying filenames) to which to save img.

+
+
**kwargskeyword arguments

Keyword arguments to format-specific save

+
+
+
+
Returns:
+
+
None
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.minc1.html b/reference/nibabel.minc1.html new file mode 100644 index 0000000000..99f2d5a3cb --- /dev/null +++ b/reference/nibabel.minc1.html @@ -0,0 +1,499 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

minc1ΒΆ

+

Read MINC1 format images

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

Minc1File(mincfile)

Class to wrap MINC1 format opened netcdf object

Minc1Header(data_dtype,Β shape,Β zooms)

Minc1Image(dataobj,Β affine[,Β header,Β extra,Β ...])

Class for MINC1 format images

MincError

Error when reading MINC files

MincHeader(data_dtype,Β shape,Β zooms)

Class to contain header for MINC formats

MincImageArrayProxy(minc_file)

MINC implementation of array proxy protocol

+
+

Minc1FileΒΆ

+
+
+class nibabel.minc1.Minc1File(mincfile)ΒΆ
+

Bases: object

+

Class to wrap MINC1 format opened netcdf object

+

Although it has some of the same methods as a Header, we use +this only when reading a MINC file, to pull out useful header +information, and for the method of reading the data out

+
+
+__init__(mincfile)ΒΆ
+
+ +
+
+get_affine()ΒΆ
+
+ +
+
+get_data_dtype()ΒΆ
+
+ +
+
+get_data_shape()ΒΆ
+
+ +
+
+get_scaled_data(sliceobj=())ΒΆ
+

Return scaled data for slice definition sliceobj

+
+
Parameters:
+
+
sliceobjtuple, optional

slice definition. If not specified, return whole array

+
+
+
+
Returns:
+
+
scaled_arrarray

array from minc file with scaling applied

+
+
+
+
+
+ +
+
+get_zooms()ΒΆ
+

Get real-world sizes of voxels

+
+ +
+ +
+
+

Minc1HeaderΒΆ

+
+
+class nibabel.minc1.Minc1Header(data_dtype: npt.DTypeLike = <class 'numpy.float32'>, shape: Sequence[int] = (0, ), zooms: Sequence[float] | None = None)ΒΆ
+

Bases: MincHeader

+
+
+__init__(data_dtype: npt.DTypeLike = <class 'numpy.float32'>, shape: Sequence[int] = (0, ), zooms: Sequence[float] | None = None)ΒΆ
+
+ +
+
+classmethod may_contain_header(binaryblock)ΒΆ
+
+ +
+ +
+
+

Minc1ImageΒΆ

+
+
+class nibabel.minc1.Minc1Image(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Bases: SpatialImage

+

Class for MINC1 format images

+

The MINC1 image class uses the default header type, rather than a specific +MINC header type - and reads the relevant information from the MINC file on +load.

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+ImageArrayProxyΒΆ
+

alias of MincImageArrayProxy

+
+ +
+
+files_types: tuple[tuple[str, str], ...] = (('image', '.mnc'),)ΒΆ
+
+ +
+
+classmethod from_file_map(file_map, *, mmap=True, keep_file_open=None)ΒΆ
+

Class method to create image from mapping in file_map

+
+
Parameters:
+
+
file_mapdict

Mapping with (kay, value) pairs of (file_type, FileHolder +instance giving file-likes for each file needed for this image +type.

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_map refers to an open file handle, this setting has no +effect. The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
Returns:
+
+
imgDataobjImage instance
+
+
+
+
+ +
+
+header_classΒΆ
+

alias of Minc1Header

+
+ +
+
+makeable: bool = TrueΒΆ
+
+ +
+
+rw: bool = FalseΒΆ
+
+ +
+
+valid_exts: tuple[str, ...] = ('.mnc',)ΒΆ
+
+ +
+ +
+
+

MincErrorΒΆ

+
+
+class nibabel.minc1.MincErrorΒΆ
+

Bases: Exception

+

Error when reading MINC files

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

MincHeaderΒΆ

+
+
+class nibabel.minc1.MincHeader(data_dtype: npt.DTypeLike = <class 'numpy.float32'>, shape: Sequence[int] = (0, ), zooms: Sequence[float] | None = None)ΒΆ
+

Bases: SpatialHeader

+

Class to contain header for MINC formats

+
+
+__init__(data_dtype: npt.DTypeLike = <class 'numpy.float32'>, shape: Sequence[int] = (0, ), zooms: Sequence[float] | None = None)ΒΆ
+
+ +
+
+data_from_fileobj(fileobj)ΒΆ
+

See Header class for an implementation we can’t use

+
+ +
+
+data_layout: Literal['F', 'C'] = 'C'ΒΆ
+
+ +
+
+data_to_fileobj(data, fileobj, rescale=True)ΒΆ
+

See Header class for an implementation we can’t use

+
+ +
+ +
+
+

MincImageArrayProxyΒΆ

+
+
+class nibabel.minc1.MincImageArrayProxy(minc_file)ΒΆ
+

Bases: object

+

MINC implementation of array proxy protocol

+

The array proxy allows us to freeze the passed fileobj and +header such that it returns the expected data array.

+
+
+__init__(minc_file)ΒΆ
+
+ +
+
+property is_proxyΒΆ
+
+ +
+
+property ndimΒΆ
+
+ +
+
+property shapeΒΆ
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.minc2.html b/reference/nibabel.minc2.html new file mode 100644 index 0000000000..aee8c3eb44 --- /dev/null +++ b/reference/nibabel.minc2.html @@ -0,0 +1,380 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

minc2ΒΆ

+

Preliminary MINC2 support

+

Use with care; I haven’t tested this against a wide range of MINC files.

+

If you have a file that isn’t read correctly, please send an example.

+

Test reading with something like:

+
import nibabel as nib
+img = nib.load('my_funny.mnc')
+data = img.get_fdata()
+print(data.mean())
+print(data.max())
+print(data.min())
+
+
+

and compare against command line output of:

+
mincstats my_funny.mnc
+
+
+ + + + + + + + + + + + + + + +

Hdf5Bunch(var)

Make object for accessing attributes of variable

Minc2File(mincfile)

Class to wrap MINC2 format file

Minc2Header(data_dtype,Β shape,Β zooms)

Minc2Image(dataobj,Β affine[,Β header,Β extra,Β ...])

Class for MINC2 images

+
+

Hdf5BunchΒΆ

+
+
+class nibabel.minc2.Hdf5Bunch(var)ΒΆ
+

Bases: object

+

Make object for accessing attributes of variable

+
+
+__init__(var)ΒΆ
+
+ +
+ +
+
+

Minc2FileΒΆ

+
+
+class nibabel.minc2.Minc2File(mincfile)ΒΆ
+

Bases: Minc1File

+

Class to wrap MINC2 format file

+

Although it has some of the same methods as a Header, we use +this only when reading a MINC2 file, to pull out useful header +information, and for the method of reading the data out

+
+
+__init__(mincfile)ΒΆ
+
+ +
+
+get_data_dtype()ΒΆ
+
+ +
+
+get_data_shape()ΒΆ
+
+ +
+
+get_scaled_data(sliceobj=())ΒΆ
+

Return scaled data for slice definition sliceobj

+
+
Parameters:
+
+
sliceobjtuple, optional

slice definition. If not specified, return whole array

+
+
+
+
Returns:
+
+
scaled_arrarray

array from minc file with scaling applied

+
+
+
+
+
+ +
+ +
+
+

Minc2HeaderΒΆ

+
+
+class nibabel.minc2.Minc2Header(data_dtype: npt.DTypeLike = <class 'numpy.float32'>, shape: Sequence[int] = (0, ), zooms: Sequence[float] | None = None)ΒΆ
+

Bases: MincHeader

+
+
+__init__(data_dtype: npt.DTypeLike = <class 'numpy.float32'>, shape: Sequence[int] = (0, ), zooms: Sequence[float] | None = None)ΒΆ
+
+ +
+
+classmethod may_contain_header(binaryblock)ΒΆ
+
+ +
+ +
+
+

Minc2ImageΒΆ

+
+
+class nibabel.minc2.Minc2Image(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Bases: Minc1Image

+

Class for MINC2 images

+

The MINC2 image class uses the default header type, rather than a +specific MINC header type - and reads the relevant information from +the MINC file on load.

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+classmethod from_file_map(file_map, *, mmap=True, keep_file_open=None)ΒΆ
+

Class method to create image from mapping in file_map

+
+
Parameters:
+
+
file_mapdict

Mapping with (kay, value) pairs of (file_type, FileHolder +instance giving file-likes for each file needed for this image +type.

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_map refers to an open file handle, this setting has no +effect. The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
Returns:
+
+
imgDataobjImage instance
+
+
+
+
+ +
+
+header_classΒΆ
+

alias of Minc2Header

+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.mriutils.html b/reference/nibabel.mriutils.html new file mode 100644 index 0000000000..f6da5ea760 --- /dev/null +++ b/reference/nibabel.mriutils.html @@ -0,0 +1,189 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

mriutilsΒΆ

+

Utilities for calculations related to MRI

+ + + + + + + + + +

MRIError

calculate_dwell_time(water_fat_shift,Β ...)

Calculate the dwell time

+
+

MRIErrorΒΆ

+
+
+class nibabel.mriutils.MRIErrorΒΆ
+

Bases: ValueError

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

calculate_dwell_timeΒΆ

+
+
+nibabel.mriutils.calculate_dwell_time(water_fat_shift, echo_train_length, field_strength)ΒΆ
+

Calculate the dwell time

+
+
Parameters:
+
+
water_fat_shiftfloat

The water fat shift of the recording, in pixels.

+
+
echo_train_lengthint

The echo train length of the imaging sequence.

+
+
field_strengthfloat

Strength of the magnet in Tesla, e.g. 3.0 for a 3T magnet recording.

+
+
+
+
Returns:
+
+
dwell_timefloat

The dwell time in seconds.

+
+
+
+
Raises:
+
+
MRIError

if values are out of range

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.nicom.html b/reference/nibabel.nicom.html new file mode 100644 index 0000000000..a8fc0cf2d4 --- /dev/null +++ b/reference/nibabel.nicom.html @@ -0,0 +1,2098 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

nicomΒΆ

+

DICOM reader

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

csareader

CSA header reader from SPM spec

dicomreaders

dicomwrappers

Classes to wrap DICOM objects and files

dwiparams

Process diffusion imaging parameters

structreader

Stream-like reader for packed data

+ + + +
+
+

Module: nicom.ascconvΒΆ

+

Parse the β€œASCCONV” meta data format found in a variety of Siemens MR files.

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

AscconvParseError

Error parsing ascconv file

Atom(op,Β obj_type,Β obj_id)

Object to hold operation, object type and object identifier

NoValue()

Signals no value present

assign2atoms(assign_ast[,Β default_class])

Parse single assignment ast from ascconv line into atoms

obj_from_atoms(atoms,Β namespace)

Return object defined by list atoms in dict-like namespace

parse_ascconv(ascconv_str[,Β str_delim])

Parse the 'ASCCONV' format from input_str.

+
+
+

Module: nicom.csareaderΒΆ

+

CSA header reader from SPM spec

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

CSAError

CSAReadError

get_acq_mat_txt(csa_dict)

get_b_matrix(csa_dict)

get_b_value(csa_dict)

get_csa_header(dcm_data[,Β csa_type])

Get CSA header information from DICOM header

get_g_vector(csa_dict)

get_ice_dims(csa_dict)

get_n_mosaic(csa_dict)

get_scalar(csa_dict,Β tag_name)

get_slice_normal(csa_dict)

get_vector(csa_dict,Β tag_name,Β n)

is_mosaic(csa_dict)

Return True if the data is of Mosaic type

nt_str(s)

Strip string to first null

read(csa_str)

Read CSA header from string csa_str

+
+
+

Module: nicom.dicomreadersΒΆ

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

DicomReadError

mosaic_to_nii(dcm_data)

Get Nifti file from Siemens

read_mosaic_dir(dicom_path[,Β globber,Β ...])

Read all Siemens mosaic DICOMs in directory, return arrays, params

read_mosaic_dwi_dir(dicom_path[,Β globber,Β ...])

slices_to_series(wrappers)

Sort sequence of slice wrappers into series

+
+
+

Module: nicom.dicomwrappersΒΆ

+

Classes to wrap DICOM objects and files

+

The wrappers encapsulate the capabilities of the different DICOM +formats.

+

They also allow dictionary-like access to named fields.

+

For calculated attributes, we return None where needed data is missing. +It seemed strange to raise an error during attribute processing, other +than an AttributeError - breaking the β€˜properties manifesto’. So, any +processing that needs to raise an error, should be in a method, rather +than in a property, or property-like thing.

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

MosaicWrapper(dcm_data[,Β csa_header,Β n_mosaic])

Class for Siemens mosaic format data

MultiframeWrapper(dcm_data)

Wrapper for Enhanced MR Storage SOP Class

SiemensWrapper(dcm_data[,Β csa_header])

Wrapper for Siemens format DICOMs

Wrapper(dcm_data)

Class to wrap general DICOM files

WrapperError

WrapperPrecisionError

none_or_close(val1,Β val2[,Β rtol,Β atol])

Match if val1 and val2 are both None, or are close

wrapper_from_data(dcm_data)

Create DICOM wrapper from DICOM data object

wrapper_from_file(file_like,Β *args,Β **kwargs)

Create DICOM wrapper from file_like object

+
+
+

Module: nicom.dwiparamsΒΆ

+

Process diffusion imaging parameters

+
    +
  • q is a vector in Q space

  • +
  • b is a b value

  • +
  • g is the unit vector along the direction of q (the gradient +direction)

  • +
+

Thus:

+
+

b = norm(q)

+

g = q / norm(q)

+
+

(norm(q) is the Euclidean norm of q)

+

The B matrix B is a symmetric positive semi-definite matrix. If +q_est is the closest q vector equivalent to the B matrix, then:

+
+

B ~ (q_est . q_est.T) / norm(q_est)

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

B2q(B[,Β tol])

Estimate q vector from input B matrix B

nearest_pos_semi_def(B)

Least squares positive semi-definite tensor estimation

q2bg(q_vector[,Β tol])

Return b value and q unit vector from q vector q_vector

+
+
+

Module: nicom.structreaderΒΆ

+

Stream-like reader for packed data

+ + + + + + +

Unpacker(buf[,Β ptr,Β endian])

Class to unpack values from buffer object

+
+
+

Module: nicom.utilsΒΆ

+

Utilities for working with DICOM datasets

+ + + + + + +

find_private_section(dcm_data,Β group_no,Β creator)

Return start element in group group_no given creator name creator

+
+

AscconvParseErrorΒΆ

+
+
+class nibabel.nicom.ascconv.AscconvParseErrorΒΆ
+

Bases: Exception

+

Error parsing ascconv file

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

AtomΒΆ

+
+
+class nibabel.nicom.ascconv.Atom(op, obj_type, obj_id)ΒΆ
+

Bases: object

+

Object to hold operation, object type and object identifier

+

An atom represents an element in an expression. For example:

+
a.b[0].c
+
+
+

has four elements. We call these elements β€œatoms”.

+

We represent objects (like a) as dicts for convenience.

+

The last element (.c) is an op = ast.Attribute operation where the +object type (obj_type) of c is not constrained (we can’t tell from +the operation what type it is). The obj_id is the name of the object – +β€œc”.

+

The second to last element [0], is op = ast.Subscript, with object type +dict (we know from the subsequent operation .c that this must be an +object, we represent the object by a dict). The obj_id is the index 0.

+
+
Parameters:
+
+
op{β€˜name’, β€˜attr’, β€˜list’}

Assignment type. Assignment to name (root namespace), attribute or +list element.

+
+
obj_type{list, dict, other}

Object type being assigned to.

+
+
obj_idstr or int

Key (obj_type is dict) or index (obj_type is list)

+
+
+
+
+
+
+__init__(op, obj_type, obj_id)ΒΆ
+
+ +
+ +
+
+

NoValueΒΆ

+
+
+class nibabel.nicom.ascconv.NoValueΒΆ
+

Bases: object

+

Signals no value present

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

assign2atomsΒΆ

+
+
+nibabel.nicom.ascconv.assign2atoms(assign_ast, default_class=<class 'int'>)ΒΆ
+

Parse single assignment ast from ascconv line into atoms

+
+
Parameters:
+
+
assign_astassignment statement ast

ast derived from single line of ascconv file.

+
+
default_classclass, optional

Class that will create an object where we cannot yet know the object +type in the assignment.

+
+
+
+
Returns:
+
+
atomslist

List of atoms. See docstring for atoms. Defines +left to right sequence of assignment in line_ast.

+
+
+
+
+
+ +
+
+

obj_from_atomsΒΆ

+
+
+nibabel.nicom.ascconv.obj_from_atoms(atoms, namespace)ΒΆ
+

Return object defined by list atoms in dict-like namespace

+
+
Parameters:
+
+
atomslist

List of atoms

+
+
namespacedict-like

Namespace in which object will be defined.

+
+
+
+
Returns:
+
+
obj_rootobject

Namespace such that we can set a desired value to the object defined in +atoms with obj_root[obj_key] = value.

+
+
obj_keystr or int

Index into list or key into dictionary for obj_root.

+
+
+
+
+
+ +
+
+

parse_ascconvΒΆ

+
+
+nibabel.nicom.ascconv.parse_ascconv(ascconv_str, str_delim='"')ΒΆ
+

Parse the β€˜ASCCONV’ format from input_str.

+
+
Parameters:
+
+
ascconv_strstr

The string we are parsing

+
+
str_delimstr, optional

String delimiter. Typically β€˜β€β€™ or β€˜β€β€β€™

+
+
+
+
Returns:
+
+
prot_dictOrderedDict

Meta data pulled from the ASCCONV section.

+
+
attrsOrderedDict

Any attributes stored in the β€˜ASCCONV BEGIN’ line

+
+
+
+
Raises:
+
+
AsconvParseError

A line of the ASCCONV section could not be parsed.

+
+
+
+
+
+ +
+
+

CSAErrorΒΆ

+
+
+class nibabel.nicom.csareader.CSAErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

CSAReadErrorΒΆ

+
+
+class nibabel.nicom.csareader.CSAReadErrorΒΆ
+

Bases: CSAError

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

get_acq_mat_txtΒΆ

+
+
+nibabel.nicom.csareader.get_acq_mat_txt(csa_dict)ΒΆ
+
+ +
+
+

get_b_matrixΒΆ

+
+
+nibabel.nicom.csareader.get_b_matrix(csa_dict)ΒΆ
+
+ +
+
+

get_b_valueΒΆ

+
+
+nibabel.nicom.csareader.get_b_value(csa_dict)ΒΆ
+
+ +
+
+

get_csa_headerΒΆ

+
+
+nibabel.nicom.csareader.get_csa_header(dcm_data, csa_type='image')ΒΆ
+

Get CSA header information from DICOM header

+

Return None if the header does not contain CSA information of the +specified csa_type

+
+
Parameters:
+
+
dcm_datadicom.Dataset

DICOM dataset. Should implement __getitem__ and, if initial check +for presence of dcm_data[(0x29, 0x10)] passes, should satisfy +interface for find_private_section.

+
+
csa_type{β€˜image’, β€˜series’}, optional

Type of CSA field to read; default is β€˜image’

+
+
+
+
Returns:
+
+
csa_infoNone or dict

Parsed CSA field of csa_type or None, if we cannot find the CSA +information.

+
+
+
+
+
+ +
+
+

get_g_vectorΒΆ

+
+
+nibabel.nicom.csareader.get_g_vector(csa_dict)ΒΆ
+
+ +
+
+

get_ice_dimsΒΆ

+
+
+nibabel.nicom.csareader.get_ice_dims(csa_dict)ΒΆ
+
+ +
+
+

get_n_mosaicΒΆ

+
+
+nibabel.nicom.csareader.get_n_mosaic(csa_dict)ΒΆ
+
+ +
+
+

get_scalarΒΆ

+
+
+nibabel.nicom.csareader.get_scalar(csa_dict, tag_name)ΒΆ
+
+ +
+
+

get_slice_normalΒΆ

+
+
+nibabel.nicom.csareader.get_slice_normal(csa_dict)ΒΆ
+
+ +
+
+

get_vectorΒΆ

+
+
+nibabel.nicom.csareader.get_vector(csa_dict, tag_name, n)ΒΆ
+
+ +
+
+

is_mosaicΒΆ

+
+
+nibabel.nicom.csareader.is_mosaic(csa_dict)ΒΆ
+

Return True if the data is of Mosaic type

+
+
Parameters:
+
+
csa_dictdict

dict containing read CSA data

+
+
+
+
Returns:
+
+
tfbool

True if the dcm_data appears to be of Siemens mosaic type, +False otherwise

+
+
+
+
+
+ +
+
+

nt_strΒΆ

+
+
+nibabel.nicom.csareader.nt_str(s)ΒΆ
+

Strip string to first null

+
+
Parameters:
+
+
sbytes
+
+
+
Returns:
+
+
sdashstr

s stripped to first occurrence of null (0)

+
+
+
+
+
+ +
+
+

readΒΆ

+
+
+nibabel.nicom.csareader.read(csa_str)ΒΆ
+

Read CSA header from string csa_str

+
+
Parameters:
+
+
csa_strstr

byte string containing CSA header information

+
+
+
+
Returns:
+
+
headerdict

header information as dict, where header has fields (at least) +type, n_tags, tags. header['tags'] is also a dictionary +with one key, value pair for each tag in the header.

+
+
+
+
+
+ +
+
+

DicomReadErrorΒΆ

+
+
+class nibabel.nicom.dicomreaders.DicomReadErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

mosaic_to_niiΒΆ

+
+
+nibabel.nicom.dicomreaders.mosaic_to_nii(dcm_data)ΒΆ
+

Get Nifti file from Siemens

+
+
Parameters:
+
+
dcm_datadicom.DataSet

DICOM header / image as read by dicom package

+
+
+
+
Returns:
+
+
imgNifti1Image

Nifti image object

+
+
+
+
+
+ +
+
+

read_mosaic_dirΒΆ

+
+
+nibabel.nicom.dicomreaders.read_mosaic_dir(dicom_path, globber='*.dcm', check_is_dwi=False, dicom_kwargs=None)ΒΆ
+

Read all Siemens mosaic DICOMs in directory, return arrays, params

+
+
Parameters:
+
+
dicom_pathstr

path containing mosaic DICOM images

+
+
globberstr, optional

glob to apply within dicom_path to select DICOM files. Default +is *.dcm

+
+
check_is_dwibool, optional

If True, raises an error if we don’t find DWI information in the +DICOM headers.

+
+
dicom_kwargsNone or dict

Extra keyword arguments to pass to the pydicom dcmread function.

+
+
+
+
Returns:
+
+
data4D array

data array with last dimension being acquisition. If there were N +acquisitions, each of shape (X, Y, Z), data will be shape (X, +Y, Z, N)

+
+
affine(4,4) array

affine relating 3D voxel space in data to RAS world space

+
+
b_values(N,) array

b values for each acquisition. nan if we did not find diffusion +information for these images.

+
+
unit_gradients(N, 3) array

gradient directions of unit length for each acquisition. (nan, +nan, nan) if we did not find diffusion information.

+
+
+
+
+
+ +
+
+

read_mosaic_dwi_dirΒΆ

+
+
+nibabel.nicom.dicomreaders.read_mosaic_dwi_dir(dicom_path, globber='*.dcm', dicom_kwargs=None)ΒΆ
+
+ +
+
+

slices_to_seriesΒΆ

+
+
+nibabel.nicom.dicomreaders.slices_to_series(wrappers)ΒΆ
+

Sort sequence of slice wrappers into series

+

This follows the SPM model fairly closely

+
+
Parameters:
+
+
wrapperssequence

sequence of Wrapper objects for sorting into volumes

+
+
+
+
Returns:
+
+
seriessequence

sequence of sequences of wrapper objects, where each sequence is +wrapper objects comprising a series, sorted into slice order

+
+
+
+
+
+ +
+
+

MosaicWrapperΒΆ

+
+
+class nibabel.nicom.dicomwrappers.MosaicWrapper(dcm_data, csa_header=None, n_mosaic=None)ΒΆ
+

Bases: SiemensWrapper

+

Class for Siemens mosaic format data

+

Mosaic format is a way of storing a 3D image in a 2D slice - and +it’s as simple as you’d imagine it would be - just storing the slices +in a mosaic similar to a light-box print.

+

We need to allow for this when getting the data and (because of an +idiosyncrasy in the way Siemens stores the images) calculating the +position of the first voxel.

+

Adds attributes:

+
    +
  • n_mosaic : int

  • +
  • mosaic_size : int

  • +
+

Initialize Siemens Mosaic wrapper

+

The Siemens-specific information is in the csa_header, either +passed in here, or read from the input dcm_data.

+
+
Parameters:
+
+
dcm_dataobject

object should allow β€˜get’ and β€˜__getitem__’ access. If csa_header +is None, it should also be possible for to extract a CSA header from +dcm_data. Usually this will be a dicom.dataset.Dataset object +resulting from reading a DICOM file. A dict should also work.

+
+
csa_headerNone or mapping, optional

mapping giving values for Siemens CSA image sub-header.

+
+
n_mosaicNone or int, optional

number of images in mosaic. If None, try to get this number +from csa_header. If this fails, raise an error

+
+
+
+
+
+
+__init__(dcm_data, csa_header=None, n_mosaic=None)ΒΆ
+

Initialize Siemens Mosaic wrapper

+

The Siemens-specific information is in the csa_header, either +passed in here, or read from the input dcm_data.

+
+
Parameters:
+
+
dcm_dataobject

object should allow β€˜get’ and β€˜__getitem__’ access. If csa_header +is None, it should also be possible for to extract a CSA header from +dcm_data. Usually this will be a dicom.dataset.Dataset object +resulting from reading a DICOM file. A dict should also work.

+
+
csa_headerNone or mapping, optional

mapping giving values for Siemens CSA image sub-header.

+
+
n_mosaicNone or int, optional

number of images in mosaic. If None, try to get this number +from csa_header. If this fails, raise an error

+
+
+
+
+
+ +
+
+get_data()ΒΆ
+

Get scaled image data from DICOMs

+

Resorts data block from mosaic to 3D

+
+
Returns:
+
+
dataarray

array with data as scaled from any scaling in the DICOM +fields.

+
+
+
+
+

Notes

+

The apparent image in the DICOM file is a 2D array that consists of +blocks, that are the output 2D slices. Let’s call the original array +the slab, and the contained slices slices. The slices are of +pixel dimension n_slice_rows x n_slice_cols. The slab is of +pixel dimension n_slab_rows x n_slab_cols. Because the +arrangement of blocks in the slab is defined as being square, the +number of blocks per slab row and slab column is the same. Let +n_blocks be the number of blocks contained in the slab. There is +also n_slices - the number of slices actually collected, some +number <= n_blocks. We have the value n_slices from the +β€˜NumberOfImagesInMosaic’ field of the Siemens private (CSA) header. +n_row_blocks and n_col_blocks are therefore given by +ceil(sqrt(n_slices)), and n_blocks is n_row_blocks ** 2. +Also n_slice_rows == n_slab_rows / n_row_blocks, etc. Using these +numbers we can therefore reconstruct the slices from the 2D DICOM pixel +array.

+
+ +
+
+image_position()ΒΆ
+

Return position of first voxel in data block

+

Adjusts Siemens mosaic position vector for bug in mosaic format +position. See dicom_mosaic in doc/theory for details.

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
img_pos(3,) array

position in mm of voxel (0,0,0) in Mosaic array

+
+
+
+
+
+ +
+
+image_shape()ΒΆ
+

Return image shape as returned by get_data()

+
+ +
+
+is_mosaic = TrueΒΆ
+
+ +
+ +
+
+

MultiframeWrapperΒΆ

+
+
+class nibabel.nicom.dicomwrappers.MultiframeWrapper(dcm_data)ΒΆ
+

Bases: Wrapper

+

Wrapper for Enhanced MR Storage SOP Class

+

Tested with Philips’ Enhanced DICOM implementation.

+

The specification for the Enhanced MR image IOP / SOP began life as DICOM +supplement 49, +but as of 2016 it is part of the standard. In particular see:

+ +
+
Attributes:
+
+
is_multiframeboolean

Identifies dcmdata as multi-frame

+
+
framessequence

A sequence of dicom.dataset.Dataset objects populated by the +dicom.dataset.Dataset.PerFrameFunctionalGroupsSequence attribute

+
+
sharedobject

The first (and only) dicom.dataset.Dataset object from a +dicom.dataset.Dataset.SharedFunctionalgroupSequence.

+
+
+
+
+

Methods

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

image_shape(self)

image_orient_patient(self)

voxel_sizes(self)

image_position(self)

series_signature(self)

get_data(self)

+

Initializes MultiframeWrapper

+
+
Parameters:
+
+
dcm_dataobject

object should allow β€˜get’ and β€˜__getitem__’ access. Usually this +will be a dicom.dataset.Dataset object resulting from reading a +DICOM file, but a dictionary should also work.

+
+
+
+
+
+
+__init__(dcm_data)ΒΆ
+

Initializes MultiframeWrapper

+
+
Parameters:
+
+
dcm_dataobject

object should allow β€˜get’ and β€˜__getitem__’ access. Usually this +will be a dicom.dataset.Dataset object resulting from reading a +DICOM file, but a dictionary should also work.

+
+
+
+
+
+ +
+
+get_data()ΒΆ
+

Get scaled image data from DICOMs

+

We return the data as DICOM understands it, first dimension is +rows, second dimension is columns

+
+
Returns:
+
+
dataarray

array with data as scaled from any scaling in the DICOM +fields.

+
+
+
+
+
+ +
+
+image_orient_patient()ΒΆ
+

Note that this is _not_ LR flipped

+
+ +
+
+image_position()ΒΆ
+

Return position of first voxel in data block

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
img_pos(3,) array

position in mm of voxel (0,0) in image array

+
+
+
+
+
+ +
+
+image_shape()ΒΆ
+

The array shape as it will be returned by get_data()

+

The shape is determined by the Rows DICOM attribute, Columns +DICOM attribute, and the set of frame indices given by the +FrameContentSequence[0].DimensionIndexValues DICOM attribute of each +element in the PerFrameFunctionalGroupsSequence. The first two +axes of the returned shape correspond to the rows, and columns +respectively. The remaining axes correspond to those of the frame +indices with order preserved.

+

What each axis in the frame indices refers to is given by the +corresponding entry in the DimensionIndexSequence DICOM attribute. +WARNING: Any axis referring to the StackID DICOM attribute will +have been removed from the frame indices in determining the shape. This +is because only a file containing a single stack is currently allowed by +this wrapper.

+

References

+ +
+ +
+
+is_multiframe = TrueΒΆ
+
+ +
+
+series_signature()ΒΆ
+

Signature for matching slices into series

+

We use signature in self.is_same_series(other).

+
+
Returns:
+
+
signaturedict

with values of 2-element sequences, where first element is +value, and second element is function to compare this value +with another. This allows us to pass things like arrays, +that might need to be allclose instead of equal

+
+
+
+
+
+ +
+
+voxel_sizes()ΒΆ
+

Get i, j, k voxel sizes

+
+ +
+ +
+
+

SiemensWrapperΒΆ

+
+
+class nibabel.nicom.dicomwrappers.SiemensWrapper(dcm_data, csa_header=None)ΒΆ
+

Bases: Wrapper

+

Wrapper for Siemens format DICOMs

+

Adds attributes:

+
    +
  • csa_header : mapping

  • +
  • b_matrix : (3,3) array

  • +
  • q_vector : (3,) array

  • +
+

Initialize Siemens wrapper

+

The Siemens-specific information is in the csa_header, either +passed in here, or read from the input dcm_data.

+
+
Parameters:
+
+
dcm_dataobject

object should allow β€˜get’ and β€˜__getitem__’ access. If csa_header +is None, it should also be possible to extract a CSA header from +dcm_data. Usually this will be a dicom.dataset.Dataset object +resulting from reading a DICOM file. A dict should also work.

+
+
csa_headerNone or mapping, optional

mapping giving values for Siemens CSA image sub-header. If +None, we try and read the CSA information from dcm_data. +If this fails, we fall back to an empty dict.

+
+
+
+
+
+
+__init__(dcm_data, csa_header=None)ΒΆ
+

Initialize Siemens wrapper

+

The Siemens-specific information is in the csa_header, either +passed in here, or read from the input dcm_data.

+
+
Parameters:
+
+
dcm_dataobject

object should allow β€˜get’ and β€˜__getitem__’ access. If csa_header +is None, it should also be possible to extract a CSA header from +dcm_data. Usually this will be a dicom.dataset.Dataset object +resulting from reading a DICOM file. A dict should also work.

+
+
csa_headerNone or mapping, optional

mapping giving values for Siemens CSA image sub-header. If +None, we try and read the CSA information from dcm_data. +If this fails, we fall back to an empty dict.

+
+
+
+
+
+ +
+
+b_matrix()ΒΆ
+

Get DWI B matrix referring to voxel space

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
B(3,3) array or None

B matrix in voxel orientation space. Returns None if this is +not a Siemens header with the required information. We return +None if this is a b0 acquisition

+
+
+
+
+
+ +
+
+is_csa = TrueΒΆ
+
+ +
+
+q_vector()ΒΆ
+

Get DWI q vector referring to voxel space

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
q: (3,) array

Estimated DWI q vector in voxel orientation space. Returns +None if this is not (detectably) a DWI

+
+
+
+
+
+ +
+
+series_signature()ΒΆ
+

Add ICE dims from CSA header to signature

+
+ +
+
+slice_normal()ΒΆ
+
+ +
+ +
+
+

WrapperΒΆ

+
+
+class nibabel.nicom.dicomwrappers.Wrapper(dcm_data)ΒΆ
+

Bases: object

+

Class to wrap general DICOM files

+

Methods:

+
    +
  • get_data()

  • +
  • get_pixel_array()

  • +
  • is_same_series(other)

  • +
  • __getitem__ : return attributes from dcm_data

  • +
  • get(key[, default]) - as usual given __getitem__ above

  • +
+

Attributes and things that look like attributes:

+
    +
  • affine : (4, 4) array

  • +
  • dcm_data : object

  • +
  • image_shape : tuple

  • +
  • image_orient_patient : (3,2) array

  • +
  • slice_normal : (3,) array

  • +
  • rotation_matrix : (3,3) array

  • +
  • voxel_sizes : tuple length 3

  • +
  • image_position : sequence length 3

  • +
  • slice_indicator : float

  • +
  • series_signature : tuple

  • +
+

Initialize wrapper

+
+
Parameters:
+
+
dcm_dataobject

object should allow β€˜get’ and β€˜__getitem__’ access. Usually this +will be a dicom.dataset.Dataset object resulting from reading a +DICOM file, but a dictionary should also work.

+
+
+
+
+
+
+__init__(dcm_data)ΒΆ
+

Initialize wrapper

+
+
Parameters:
+
+
dcm_dataobject

object should allow β€˜get’ and β€˜__getitem__’ access. Usually this +will be a dicom.dataset.Dataset object resulting from reading a +DICOM file, but a dictionary should also work.

+
+
+
+
+
+ +
+
+property affineΒΆ
+

Mapping between voxel and DICOM coordinate system

+

(4, 4) affine matrix giving transformation between voxels in data array +and mm in the DICOM patient coordinate system.

+
+ +
+
+b_matrix = NoneΒΆ
+
+ +
+
+b_value()ΒΆ
+

Return b value for diffusion or None if not available

+
+ +
+
+b_vector()ΒΆ
+

Return b vector for diffusion or None if not available

+
+ +
+
+get(key, default=None)ΒΆ
+

Get values from underlying dicom data

+
+ +
+
+get_data()ΒΆ
+

Get scaled image data from DICOMs

+

We return the data as DICOM understands it, first dimension is +rows, second dimension is columns

+
+
Returns:
+
+
dataarray

array with data as scaled from any scaling in the DICOM +fields.

+
+
+
+
+
+ +
+
+get_pixel_array()ΒΆ
+

Return unscaled pixel array from DICOM

+
+ +
+
+image_orient_patient()ΒΆ
+

Note that this is _not_ LR flipped

+
+ +
+
+image_position()ΒΆ
+

Return position of first voxel in data block

+
+
Parameters:
+
+
None
+
+
+
Returns:
+
+
img_pos(3,) array

position in mm of voxel (0,0) in image array

+
+
+
+
+
+ +
+
+image_shape()ΒΆ
+

The array shape as it will be returned by get_data()

+
+ +
+
+instance_number()ΒΆ
+

Just because we use this a lot for sorting

+
+ +
+
+is_csa = FalseΒΆ
+
+ +
+
+is_mosaic = FalseΒΆ
+
+ +
+
+is_multiframe = FalseΒΆ
+
+ +
+
+is_same_series(other)ΒΆ
+

Return True if other appears to be in same series

+
+
Parameters:
+
+
otherobject

object with series_signature attribute that is a +mapping. Usually it’s a Wrapper or sub-class instance.

+
+
+
+
Returns:
+
+
tfbool

True if other might be in the same series as self, False +otherwise.

+
+
+
+
+
+ +
+
+q_vector = NoneΒΆ
+
+ +
+
+rotation_matrix()ΒΆ
+

Return rotation matrix between array indices and mm

+

Note that we swap the two columns of the β€˜ImageOrientPatient’ +when we create the rotation matrix. This is takes into account +the slightly odd ij transpose construction of the DICOM +orientation fields - see doc/theory/dicom_orientaiton.rst.

+
+ +
+
+series_signature()ΒΆ
+

Signature for matching slices into series

+

We use signature in self.is_same_series(other).

+
+
Returns:
+
+
signaturedict

with values of 2-element sequences, where first element is +value, and second element is function to compare this value +with another. This allows us to pass things like arrays, +that might need to be allclose instead of equal

+
+
+
+
+
+ +
+
+slice_indicator()ΒΆ
+

A number that is higher for higher slices in Z

+

Comparing this number between two adjacent slices should give a +difference equal to the voxel size in Z.

+

See doc/theory/dicom_orientation for description

+
+ +
+
+slice_normal()ΒΆ
+
+ +
+
+voxel_sizes()ΒΆ
+

voxel sizes for array as returned by get_data()

+
+ +
+ +
+
+

WrapperErrorΒΆ

+
+
+class nibabel.nicom.dicomwrappers.WrapperErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

WrapperPrecisionErrorΒΆ

+
+
+class nibabel.nicom.dicomwrappers.WrapperPrecisionErrorΒΆ
+

Bases: WrapperError

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

none_or_closeΒΆ

+
+
+nibabel.nicom.dicomwrappers.none_or_close(val1, val2, rtol=1e-05, atol=1e-06)ΒΆ
+

Match if val1 and val2 are both None, or are close

+
+
Parameters:
+
+
val1None or array-like
+
val2None or array-like
+
rtolfloat, optional

Relative tolerance; see np.allclose

+
+
atolfloat, optional

Absolute tolerance; see np.allclose

+
+
+
+
Returns:
+
+
tfbool

True iff (both val1 and val2 are None) or (val1 and val2 +are close arrays, as detected by np.allclose with parameters +rtol and atal).

+
+
+
+
+

Examples

+
>>> none_or_close(None, None)
+True
+>>> none_or_close(1, None)
+False
+>>> none_or_close(None, 1)
+False
+>>> none_or_close([1,2], [1,2])
+True
+>>> none_or_close([0,1], [0,2])
+False
+
+
+
+ +
+
+

wrapper_from_dataΒΆ

+
+
+nibabel.nicom.dicomwrappers.wrapper_from_data(dcm_data)ΒΆ
+

Create DICOM wrapper from DICOM data object

+
+
Parameters:
+
+
dcm_datadicom.dataset.Dataset instance or similar

Object allowing attribute access, with DICOM attributes. +Probably a dataset as read by pydicom.

+
+
+
+
Returns:
+
+
dcm_wdicomwrappers.Wrapper or subclass

DICOM wrapper corresponding to DICOM data type

+
+
+
+
+
+ +
+
+

wrapper_from_fileΒΆ

+
+
+nibabel.nicom.dicomwrappers.wrapper_from_file(file_like, *args, **kwargs)ΒΆ
+

Create DICOM wrapper from file_like object

+
+
Parameters:
+
+
file_likeobject

filename string or file-like object, pointing to a valid DICOM +file readable by pydicom

+
+
*argspositional

args to dicom.dcmread command.

+
+
**kwargskeyword

args to dicom.dcmread command. force=True might be a +likely keyword argument.

+
+
+
+
Returns:
+
+
dcm_wdicomwrappers.Wrapper or subclass

DICOM wrapper corresponding to DICOM data type

+
+
+
+
+
+ +
+
+

B2qΒΆ

+
+
+nibabel.nicom.dwiparams.B2q(B, tol=None)ΒΆ
+

Estimate q vector from input B matrix B

+

We require that the input B is symmetric positive definite.

+

Because the solution is a square root, the sign of the returned +vector is arbitrary. We set the vector to have a positive x +component by convention.

+
+
Parameters:
+
+
B(3,3) array-like

B matrix - symmetric. We do not check the symmetry.

+
+
tolNone or float

absolute tolerance below which to consider eigenvalues of the B +matrix to be small enough not to worry about them being negative, +in check for positive semi-definite-ness. None (default) results +in a fairly tight numerical threshold proportional to the maximum +eigenvalue

+
+
+
+
Returns:
+
+
q(3,) vector

Estimated q vector from B matrix B

+
+
+
+
+
+ +
+
+

nearest_pos_semi_defΒΆ

+
+
+nibabel.nicom.dwiparams.nearest_pos_semi_def(B)ΒΆ
+

Least squares positive semi-definite tensor estimation

+

Reference: Niethammer M, San Jose Estepar R, Bouix S, Shenton M, +Westin CF. On diffusion tensor estimation. Conf Proc IEEE Eng Med +Biol Soc. 2006;1:2622-5. PubMed PMID: 17946125; PubMed Central +PMCID: PMC2791793.

+
+
Parameters:
+
+
B(3,3) array-like

B matrix - symmetric. We do not check the symmetry.

+
+
+
+
Returns:
+
+
npds(3,3) array

Estimated nearest positive semi-definite array to matrix B.

+
+
+
+
+

Examples

+
>>> B = np.diag([1, 1, -1])
+>>> nearest_pos_semi_def(B)
+array([[0.75, 0.  , 0.  ],
+       [0.  , 0.75, 0.  ],
+       [0.  , 0.  , 0.  ]])
+
+
+
+ +
+
+

q2bgΒΆ

+
+
+nibabel.nicom.dwiparams.q2bg(q_vector, tol=1e-05)ΒΆ
+

Return b value and q unit vector from q vector q_vector

+
+
Parameters:
+
+
q_vector(3,) array-like

q vector

+
+
tolfloat, optional

q vector L2 norm below which q_vector considered to be b_value of +zero, and therefore g_vector also considered to zero.

+
+
+
+
Returns:
+
+
b_valuefloat

L2 Norm of q_vector or 0 if L2 norm < tol

+
+
g_vectorshape (3,) ndarray

q_vector / b_value or 0 if L2 norma < tol

+
+
+
+
+

Examples

+
>>> q2bg([1, 0, 0])
+(1.0, array([1., 0., 0.]))
+>>> q2bg([0, 10, 0])
+(10.0, array([0., 1., 0.]))
+>>> q2bg([0, 0, 0])
+(0.0, array([0., 0., 0.]))
+
+
+
+ +
+
+

UnpackerΒΆ

+
+
+class nibabel.nicom.structreader.Unpacker(buf, ptr=0, endian=None)ΒΆ
+

Bases: object

+

Class to unpack values from buffer object

+

The buffer object is usually a string. Caches compiled struct +format strings so that repeated unpacking with the same format +string should be faster than using struct.unpack directly.

+

Examples

+
>>> a = b'1234567890'
+>>> upk = Unpacker(a)
+>>> upk.unpack('2s') == (b'12',)
+True
+>>> upk.unpack('2s') == (b'34',)
+True
+>>> upk.ptr
+4
+>>> upk.read(3) == b'567'
+True
+>>> upk.ptr
+7
+
+
+

Initialize unpacker

+
+
Parameters:
+
+
bufbuffer

object implementing buffer protocol (e.g. str)

+
+
ptrint, optional

offset at which to begin reads from buf

+
+
endianNone or str, optional

endian code to prepend to format, as for unpack endian +codes. None (the default) corresponds to the default +behavior of struct - assuming system endian unless you +specify the byte order specifically in the format string +passed to unpack

+
+
+
+
+
+
+__init__(buf, ptr=0, endian=None)ΒΆ
+

Initialize unpacker

+
+
Parameters:
+
+
bufbuffer

object implementing buffer protocol (e.g. str)

+
+
ptrint, optional

offset at which to begin reads from buf

+
+
endianNone or str, optional

endian code to prepend to format, as for unpack endian +codes. None (the default) corresponds to the default +behavior of struct - assuming system endian unless you +specify the byte order specifically in the format string +passed to unpack

+
+
+
+
+
+ +
+
+read(n_bytes=-1)ΒΆ
+

Return byte string of length n_bytes at current position

+

Returns sub-string from self.buf and updates self.ptr to the +position after the read data.

+
+
Parameters:
+
+
n_bytesint, optional

number of bytes to read. Can be -1 (the default) in which +case we return all the remaining bytes in self.buf

+
+
+
+
Returns:
+
+
sbyte string
+
+
+
+
+ +
+
+unpack(fmt)ΒΆ
+

Unpack values from contained buffer

+

Unpacks values from self.buf and updates self.ptr to the +position after the read data.

+
+
Parameters:
+
+
fmtstr

format string as for unpack

+
+
+
+
Returns:
+
+
valuestuple

values as unpacked from self.buf according to fmt

+
+
+
+
+
+ +
+ +
+
+

find_private_sectionΒΆ

+
+
+nibabel.nicom.utils.find_private_section(dcm_data, group_no, creator)ΒΆ
+

Return start element in group group_no given creator name creator

+

Private attribute tags need to announce where they will go by putting a tag +in the private group (here group_no) between elements 1 and 0xFF. The +element number of these tags give the start of matching information, in the +higher tag numbers.

+
+
Parameters:
+
+
dcm_datadicom dataset

Iterating over dcm_data produces elements with attributes +tag, VR, value

+
+
group_noint

Group number in which to search

+
+
creatorstr or bytes or regex

Name of section - e.g. β€˜SIEMENS CSA HEADER’ - or regex to search for +section name. Regex used via creator.search(element_value) where +element_value is the value of the data element.

+
+
+
+
Returns:
+
+
element_startint

Element number at which named section starts.

+
+
+
+
+
+ +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.nifti1.html b/reference/nibabel.nifti1.html new file mode 100644 index 0000000000..ac030fe24f --- /dev/null +++ b/reference/nibabel.nifti1.html @@ -0,0 +1,1912 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

nifti1ΒΆ

+

Read / write access to NIfTI1 image format

+

NIfTI1 format defined at http://nifti.nimh.nih.gov/nifti-1/

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

Nifti1DicomExtension(code,Β content[,Β parent_hdr])

NIfTI1 DICOM header extension

Nifti1Extension(code,Β content)

Baseclass for NIfTI1 header extensions.

Nifti1Extensions([iterable])

Simple extension collection, implemented as a list-subclass.

Nifti1Header([binaryblock,Β endianness,Β ...])

Class for NIfTI1 header

Nifti1Image(dataobj,Β affine[,Β header,Β ...])

Class for single file NIfTI1 format image

Nifti1Pair(dataobj,Β affine[,Β header,Β extra,Β ...])

Class for NIfTI1 format image, header pair

Nifti1PairHeader([binaryblock,Β endianness,Β ...])

Class for NIfTI1 pair header

load(filename)

Load NIfTI1 single or pair from filename

save(img,Β filename)

Save NIfTI1 single or pair to filename

+
+

Nifti1DicomExtensionΒΆ

+
+
+class nibabel.nifti1.Nifti1DicomExtension(code, content, parent_hdr=None)ΒΆ
+

Bases: Nifti1Extension

+

NIfTI1 DICOM header extension

+

This class is a thin wrapper around pydicom to read a binary DICOM +byte string. If pydicom is available, content is exposed as a Dicom Dataset. +Otherwise, this silently falls back to the standard NiftiExtension class +and content is the raw bytestring loaded directly from the nifti file +header.

+
+
Parameters:
+
+
codeint or str

Canonical extension code as defined in the NIfTI standard, given +either as integer or corresponding label +(see extension_codes)

+
+
contentbytes or pydicom Dataset or None

Extension content - either a bytestring as read from the NIfTI file +header or an existing pydicom Dataset. If a bystestring, the content +is converted into a Dataset on initialization. If None, a new empty +Dataset is created.

+
+
parent_hdrNifti1Header, optional

If a dicom extension belongs to an existing +Nifti1Header, it may be provided here to +ensure that the DICOM dataset is written with correctly corresponding +endianness; otherwise it is assumed the dataset is little endian.

+
+
+
+
+

Notes

+

code should always be 2 for DICOM.

+
+
+__init__(code, content, parent_hdr=None)ΒΆ
+
+
Parameters:
+
+
codeint or str

Canonical extension code as defined in the NIfTI standard, given +either as integer or corresponding label +(see extension_codes)

+
+
contentbytes or pydicom Dataset or None

Extension content - either a bytestring as read from the NIfTI file +header or an existing pydicom Dataset. If a bystestring, the content +is converted into a Dataset on initialization. If None, a new empty +Dataset is created.

+
+
parent_hdrNifti1Header, optional

If a dicom extension belongs to an existing +Nifti1Header, it may be provided here to +ensure that the DICOM dataset is written with correctly corresponding +endianness; otherwise it is assumed the dataset is little endian.

+
+
+
+
+

Notes

+

code should always be 2 for DICOM.

+
+ +
+ +
+
+

Nifti1ExtensionΒΆ

+
+
+class nibabel.nifti1.Nifti1Extension(code, content)ΒΆ
+

Bases: object

+

Baseclass for NIfTI1 header extensions.

+

This class is sufficient to handle very simple text-based extensions, such +as comment. More sophisticated extensions should/will be supported by +dedicated subclasses.

+
+
Parameters:
+
+
codeint or str

Canonical extension code as defined in the NIfTI standard, given +either as integer or corresponding label +(see extension_codes)

+
+
contentstr

Extension content as read from the NIfTI file header. This content is +converted into a runtime representation.

+
+
+
+
+
+
+__init__(code, content)ΒΆ
+
+
Parameters:
+
+
codeint or str

Canonical extension code as defined in the NIfTI standard, given +either as integer or corresponding label +(see extension_codes)

+
+
contentstr

Extension content as read from the NIfTI file header. This content is +converted into a runtime representation.

+
+
+
+
+
+ +
+
+get_code()ΒΆ
+

Return the canonical extension type code.

+
+ +
+
+get_content()ΒΆ
+

Return the extension content in its runtime representation.

+
+ +
+
+get_sizeondisk()ΒΆ
+

Return the size of the extension in the NIfTI file.

+
+ +
+
+write_to(fileobj, byteswap)ΒΆ
+

Write header extensions to fileobj

+

Write starts at fileobj current file position.

+
+
Parameters:
+
+
fileobjfile-like object

Should implement write method

+
+
byteswapboolean

Flag if byteswapping the data is required.

+
+
+
+
Returns:
+
+
None
+
+
+
+
+ +
+ +
+
+

Nifti1ExtensionsΒΆ

+
+
+class nibabel.nifti1.Nifti1Extensions(iterable=(), /)ΒΆ
+

Bases: list

+

Simple extension collection, implemented as a list-subclass.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+count(ecode)ΒΆ
+

Returns the number of extensions matching a given ecode.

+
+
Parameters:
+
+
codeint | str

The ecode can be specified either literal or as numerical value.

+
+
+
+
+
+ +
+
+classmethod from_fileobj(fileobj, size, byteswap)ΒΆ
+

Read header extensions from a fileobj

+
+
Parameters:
+
+
fileobjfile-like object

We begin reading the extensions at the current file position

+
+
sizeint

Number of bytes to read. If negative, fileobj will be read till its +end.

+
+
byteswapboolean

Flag if byteswapping the read data is required.

+
+
+
+
Returns:
+
+
An extension list. This list might be empty in case not extensions
+
were present in fileobj.
+
+
+
+
+ +
+
+get_codes()ΒΆ
+

Return a list of the extension code of all available extensions

+
+ +
+
+get_sizeondisk()ΒΆ
+

Return the size of the complete header extensions in the NIfTI file.

+
+ +
+
+write_to(fileobj, byteswap)ΒΆ
+

Write header extensions to fileobj

+

Write starts at fileobj current file position.

+
+
Parameters:
+
+
fileobjfile-like object

Should implement write method

+
+
byteswapboolean

Flag if byteswapping the data is required.

+
+
+
+
Returns:
+
+
None
+
+
+
+
+ +
+ +
+
+

Nifti1HeaderΒΆ

+
+
+class nibabel.nifti1.Nifti1Header(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Bases: SpmAnalyzeHeader

+

Class for NIfTI1 header

+

The NIfTI1 header has many more coded fields than the simpler Analyze +variants. NIfTI1 headers also have extensions.

+

Nifti allows the header to be a separate file, as part of a nifti image / +header pair, or to precede the data in a single file. The object needs to +know which type it is, in order to manage the voxel offset pointing to the +data, extension reading, and writing the correct magic string.

+

This class handles the header-preceding-data case.

+

Initialize header from binary data block and extensions

+
+
+__init__(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Initialize header from binary data block and extensions

+
+ +
+
+copy()ΒΆ
+

Return copy of header

+

Take reference to extensions as well as copy of header contents

+
+ +
+
+classmethod default_structarr(endianness=None)ΒΆ
+

Create empty header binary block with given endianness

+
+ +
+
+exts_klassΒΆ
+

alias of Nifti1Extensions

+
+ +
+
+classmethod from_fileobj(fileobj, endianness=None, check=True)ΒΆ
+

Return read structure with given or guessed endiancode

+
+
Parameters:
+
+
fileobjfile-like object

Needs to implement read method

+
+
endiannessNone or endian code, optional

Code specifying endianness of read data

+
+
+
+
Returns:
+
+
wstrWrapStruct object

WrapStruct object initialized from data in fileobj

+
+
+
+
+
+ +
+
+classmethod from_header(header=None, check=True)ΒΆ
+

Class method to create header from another header

+

Extend Analyze header copy by copying extensions from other Nifti +types.

+
+
Parameters:
+
+
headerHeader instance or mapping

a header of this class, or another class of header for +conversion to this type

+
+
check{True, False}

whether to check header for integrity

+
+
+
+
Returns:
+
+
hdrheader instance

fresh header instance of our own class

+
+
+
+
+
+ +
+
+get_best_affine()ΒΆ
+

Select best of available transforms

+
+ +
+
+get_data_shape()ΒΆ
+

Get shape of data

+

Notes

+

Applies freesurfer hack for large vectors described in issue 100 and +save_nifti.m.

+

Allows for freesurfer hack for 7th order icosahedron surface described +in issue 309, load_nifti.m, and save_nifti.m.

+

Examples

+
>>> hdr = Nifti1Header()
+>>> hdr.get_data_shape()
+(0,)
+>>> hdr.set_data_shape((1,2,3))
+>>> hdr.get_data_shape()
+(1, 2, 3)
+
+
+

Expanding number of dimensions gets default zooms

+
>>> hdr.get_zooms()
+(1.0, 1.0, 1.0)
+
+
+
+ +
+
+get_dim_info()ΒΆ
+

Gets NIfTI MRI slice etc dimension information

+
+
Returns:
+
+
freq{None,0,1,2}

Which data array axis is frequency encode direction

+
+
phase{None,0,1,2}

Which data array axis is phase encode direction

+
+
slice{None,0,1,2}

Which data array axis is slice encode direction

+
+
where data array is the array returned by get_data
+
Because NIfTI1 files are natively Fortran indexed:

0 is fastest changing in file +1 is medium changing in file +2 is slowest changing in file

+
+
None means the axis appears not to be specified.
+
+
+
+

Examples

+

See set_dim_info function

+
+ +
+
+get_intent(code_repr='label')ΒΆ
+

Get intent code, parameters and name

+
+
Parameters:
+
+
code_reprstring

string giving output form of intent code representation. +Default is β€˜label’; use β€˜code’ for integer representation.

+
+
+
+
Returns:
+
+
codestring or integer

intent code, or string describing code

+
+
parameterstuple

parameters for the intent

+
+
namestring

intent name

+
+
+
+
+

Examples

+
>>> hdr = Nifti1Header()
+>>> hdr.set_intent('t test', (10,), name='some score')
+>>> hdr.get_intent()
+('t test', (10.0,), 'some score')
+>>> hdr.get_intent('code')
+(3, (10.0,), 'some score')
+
+
+
+ +
+
+get_n_slices()ΒΆ
+

Return the number of slices

+
+ +
+
+get_qform(coded=False)ΒΆ
+

Return 4x4 affine matrix from qform parameters in header

+
+
Parameters:
+
+
codedbool, optional

If True, return {affine or None}, and qform code. If False, just +return affine. {affine or None} means, return None if qform code +== 0, and affine otherwise.

+
+
+
+
Returns:
+
+
affineNone or (4,4) ndarray

If coded is False, always return affine reconstructed from qform +quaternion. If coded is True, return None if qform code is 0, +else return the affine.

+
+
codeint

Qform code. Only returned if coded is True.

+
+
+
+
+
+ +
+
+get_qform_quaternion()ΒΆ
+

Compute quaternion from b, c, d of quaternion

+

Fills a value by assuming this is a unit quaternion

+
+ +
+
+get_sform(coded=False)ΒΆ
+

Return 4x4 affine matrix from sform parameters in header

+
+
Parameters:
+
+
codedbool, optional

If True, return {affine or None}, and sform code. If False, just +return affine. {affine or None} means, return None if sform code +== 0, and affine otherwise.

+
+
+
+
Returns:
+
+
affineNone or (4,4) ndarray

If coded is False, always return affine from sform fields. If +coded is True, return None if sform code is 0, else return the +affine.

+
+
codeint

Sform code. Only returned if coded is True.

+
+
+
+
+
+ +
+
+get_slice_duration()ΒΆ
+

Get slice duration

+
+
Returns:
+
+
slice_durationfloat

time to acquire one slice

+
+
+
+
+

Notes

+

The NIfTI1 spec appears to require the slice dimension to be +defined for slice_duration to have meaning.

+

Examples

+
>>> hdr = Nifti1Header()
+>>> hdr.set_dim_info(slice=2)
+>>> hdr.set_slice_duration(0.3)
+>>> print("%0.1f" % hdr.get_slice_duration())
+0.3
+
+
+
+ +
+
+get_slice_times()ΒΆ
+

Get slice times from slice timing information

+
+
Returns:
+
+
slice_timestuple

Times of acquisition of slices, where 0 is the beginning of +the acquisition, ordered by position in file. nifti allows +slices at the top and bottom of the volume to be excluded from +the standard slice timing specification, and calls these +β€œpadding slices”. We give padding slices None as a time +of acquisition

+
+
+
+
+

Examples

+
>>> hdr = Nifti1Header()
+>>> hdr.set_dim_info(slice=2)
+>>> hdr.set_data_shape((1, 1, 7))
+>>> hdr.set_slice_duration(0.1)
+>>> hdr['slice_code'] = slice_order_codes['sequential increasing']
+>>> slice_times = hdr.get_slice_times()
+>>> np.allclose(slice_times, [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
+True
+
+
+
+ +
+
+get_slope_inter()ΒΆ
+

Get data scaling (slope) and DC offset (intercept) from header data

+
+
Returns:
+
+
slopeNone or float

scaling (slope). None if there is no valid scaling from these +fields

+
+
interNone or float

offset (intercept). None if there is no valid scaling or if offset +is not finite.

+
+
+
+
+

Examples

+
>>> hdr = Nifti1Header()
+>>> hdr.get_slope_inter()
+(1.0, 0.0)
+>>> hdr['scl_slope'] = 0
+>>> hdr.get_slope_inter()
+(None, None)
+>>> hdr['scl_slope'] = np.nan
+>>> hdr.get_slope_inter()
+(None, None)
+>>> hdr['scl_slope'] = 1
+>>> hdr['scl_inter'] = 1
+>>> hdr.get_slope_inter()
+(1.0, 1.0)
+>>> hdr['scl_inter'] = np.inf
+>>> hdr.get_slope_inter() 
+Traceback (most recent call last):
+    ...
+HeaderDataError: Valid slope but invalid intercept inf
+
+
+
+ +
+
+get_xyzt_units()ΒΆ
+
+ +
+
+has_data_intercept = TrueΒΆ
+
+ +
+
+has_data_slope = TrueΒΆ
+
+ +
+
+is_single = TrueΒΆ
+
+ +
+
+classmethod may_contain_header(binaryblock)ΒΆ
+
+ +
+
+pair_magic = b'ni1'ΒΆ
+
+ +
+
+pair_vox_offset = 0ΒΆ
+
+ +
+
+quaternion_threshold = 3.5762786865234375e-07ΒΆ
+
+ +
+
+set_data_dtype(datatype)ΒΆ
+

Set numpy dtype for data from code or dtype or type

+

Using int or "int" is disallowed, as these types +will be interpreted as np.int64, which is almost never desired. +np.int64 is permitted for those intent on making poor choices.

+

Examples

+
>>> hdr = Nifti1Header()
+>>> hdr.set_data_dtype(np.uint8)
+>>> hdr.get_data_dtype()
+dtype('uint8')
+>>> hdr.set_data_dtype(np.dtype(np.uint8))
+>>> hdr.get_data_dtype()
+dtype('uint8')
+>>> hdr.set_data_dtype('implausible')
+Traceback (most recent call last):
+   ...
+nibabel.spatialimages.HeaderDataError: data dtype "implausible" not recognized
+>>> hdr.set_data_dtype('none')
+Traceback (most recent call last):
+   ...
+nibabel.spatialimages.HeaderDataError: data dtype "none" known but not supported
+>>> hdr.set_data_dtype(np.void)
+Traceback (most recent call last):
+   ...
+nibabel.spatialimages.HeaderDataError: data dtype "<class 'numpy.void'>" known
+but not supported
+>>> hdr.set_data_dtype('int')
+Traceback (most recent call last):
+   ...
+ValueError: Invalid data type 'int'. Specify a sized integer, e.g., 'uint8' or numpy.int16.
+>>> hdr.set_data_dtype(int)
+Traceback (most recent call last):
+   ...
+ValueError: Invalid data type <class 'int'>. Specify a sized integer, e.g., 'uint8' or
+numpy.int16.
+>>> hdr.set_data_dtype('int64')
+>>> hdr.get_data_dtype() == np.dtype('int64')
+True
+
+
+
+ +
+
+set_data_shape(shape)ΒΆ
+

Set shape of data # noqa

+

If ndims == len(shape) then we set zooms for dimensions higher than +ndims to 1.0

+

Nifti1 images can have up to seven dimensions. For FreeSurfer-variant +Nifti surface files, the first dimension is assumed to correspond to +vertices/nodes on a surface, and dimensions two and three are +constrained to have depth of 1. Dimensions 4-7 are constrained only by +type bounds.

+
+
Parameters:
+
+
shapesequence

sequence of integers specifying data array shape

+
+
+
+
+

Notes

+

Applies freesurfer hack for large vectors described in issue 100 and +save_nifti.m.

+

Allows for freesurfer hack for 7th order icosahedron surface described +in issue 309, load_nifti.m, and save_nifti.m.

+

The Nifti1 standard header allows for the following β€œpoint set” +definition of a surface, not currently implemented in nibabel.

+
To signify that the vector value at each voxel is really a
+spatial coordinate (e.g., the vertices or nodes of a surface mesh):
+  - dataset must have a 5th dimension
+  - intent_code must be NIFTI_INTENT_POINTSET
+  - dim[0] = 5
+  - dim[1] = number of points
+  - dim[2] = dim[3] = dim[4] = 1
+  - dim[5] must be the dimensionality of space (e.g., 3 => 3D space).
+  - intent_name may describe the object these points come from
+    (e.g., "pial", "gray/white" , "EEG", "MEG").
+
+
+
+ +
+
+set_dim_info(freq=None, phase=None, slice=None)ΒΆ
+

Sets nifti MRI slice etc dimension information

+
+
Parameters:
+
+
freq{None, 0, 1, 2}

axis of data array referring to frequency encoding

+
+
phase{None, 0, 1, 2}

axis of data array referring to phase encoding

+
+
slice{None, 0, 1, 2}

axis of data array referring to slice encoding

+
+
``None`` means the axis is not specified.
+
+
+
+

Notes

+

This is stored in one byte in the header

+

Examples

+
>>> hdr = Nifti1Header()
+>>> hdr.set_dim_info(1, 2, 0)
+>>> hdr.get_dim_info()
+(1, 2, 0)
+>>> hdr.set_dim_info(freq=1, phase=2, slice=0)
+>>> hdr.get_dim_info()
+(1, 2, 0)
+>>> hdr.set_dim_info()
+>>> hdr.get_dim_info()
+(None, None, None)
+>>> hdr.set_dim_info(freq=1, phase=None, slice=0)
+>>> hdr.get_dim_info()
+(1, None, 0)
+
+
+
+ +
+
+set_intent(code, params=(), name='', allow_unknown=False)ΒΆ
+

Set the intent code, parameters and name

+

If parameters are not specified, assumed to be all zero. Each +intent code has a set number of parameters associated. If you +specify any parameters, then it will need to be the correct number +(e.g the β€œf test” intent requires 2). However, parameters can +also be set in the file data, so we also allow not setting any +parameters (empty parameter tuple).

+
+
Parameters:
+
+
codeinteger or string

code specifying nifti intent

+
+
paramslist, tuple of scalars

parameters relating to intent (see intent_codes) +defaults to (). Unspecified parameters are set to 0.0

+
+
namestring

intent name (description). Defaults to β€˜β€™

+
+
allow_unknown{False, True}, optional

Allow unknown integer intent codes. If False (the default), +a KeyError is raised on attempts to set the intent +to an unknown code.

+
+
+
+
Returns:
+
+
None
+
+
+
+

Examples

+
>>> hdr = Nifti1Header()
+>>> hdr.set_intent(0)  # no intent
+>>> hdr.set_intent('z score')
+>>> hdr.get_intent()
+('z score', (), '')
+>>> hdr.get_intent('code')
+(5, (), '')
+>>> hdr.set_intent('t test', (10,), name='some score')
+>>> hdr.get_intent()
+('t test', (10.0,), 'some score')
+>>> hdr.set_intent('f test', (2, 10), name='another score')
+>>> hdr.get_intent()
+('f test', (2.0, 10.0), 'another score')
+>>> hdr.set_intent('f test')
+>>> hdr.get_intent()
+('f test', (0.0, 0.0), '')
+>>> hdr.set_intent(9999, allow_unknown=True) # unknown code
+>>> hdr.get_intent()
+('unknown code 9999', (), '')
+
+
+
+ +
+
+set_qform(affine, code=None, strip_shears=True)ΒΆ
+

Set qform header values from 4x4 affine

+
+
Parameters:
+
+
affineNone or 4x4 array

affine transform to write into sform. If None, only set code.

+
+
codeNone, string or integer, optional

String or integer giving meaning of transform in affine. +The default is None. If code is None, then:

+
    +
  • If affine is None, code-> 0

  • +
  • If affine not None and existing qform code in header == 0, +code-> 2 (aligned)

  • +
  • If affine not None and existing qform code in header != 0, +code-> existing qform code in header

  • +
+
+
strip_shearsbool, optional

Whether to strip shears in affine. If True, shears will be +silently stripped. If False, the presence of shears will raise a +HeaderDataError

+
+
+
+
+

Notes

+

The qform transform only encodes translations, rotations and +zooms. If there are shear components to the affine transform, and +strip_shears is True (the default), the written qform gives the +closest approximation where the rotation matrix is orthogonal. This is +to allow quaternion representation. The orthogonal representation +enforces orthogonal axes.

+

Examples

+
>>> hdr = Nifti1Header()
+>>> int(hdr['qform_code'])  # gives 0 - unknown
+0
+>>> affine = np.diag([1,2,3,1])
+>>> np.all(hdr.get_qform() == affine)
+False
+>>> hdr.set_qform(affine)
+>>> np.all(hdr.get_qform() == affine)
+True
+>>> int(hdr['qform_code'])  # gives 2 - aligned
+2
+>>> hdr.set_qform(affine, code='talairach')
+>>> int(hdr['qform_code'])
+3
+>>> hdr.set_qform(affine, code=None)
+>>> int(hdr['qform_code'])
+3
+>>> hdr.set_qform(affine, code='scanner')
+>>> int(hdr['qform_code'])
+1
+>>> hdr.set_qform(None)
+>>> int(hdr['qform_code'])
+0
+
+
+
+ +
+
+set_sform(affine, code=None)ΒΆ
+

Set sform transform from 4x4 affine

+
+
Parameters:
+
+
affineNone or 4x4 array

affine transform to write into sform. If None, only set code

+
+
codeNone, string or integer, optional

String or integer giving meaning of transform in affine. +The default is None. If code is None, then:

+
    +
  • If affine is None, code-> 0

  • +
  • If affine not None and existing sform code in header == 0, +code-> 2 (aligned)

  • +
  • If affine not None and existing sform code in header != 0, +code-> existing sform code in header

  • +
+
+
+
+
+

Examples

+
>>> hdr = Nifti1Header()
+>>> int(hdr['sform_code'])  # gives 0 - unknown
+0
+>>> affine = np.diag([1,2,3,1])
+>>> np.all(hdr.get_sform() == affine)
+False
+>>> hdr.set_sform(affine)
+>>> np.all(hdr.get_sform() == affine)
+True
+>>> int(hdr['sform_code'])  # gives 2 - aligned
+2
+>>> hdr.set_sform(affine, code='talairach')
+>>> int(hdr['sform_code'])
+3
+>>> hdr.set_sform(affine, code=None)
+>>> int(hdr['sform_code'])
+3
+>>> hdr.set_sform(affine, code='scanner')
+>>> int(hdr['sform_code'])
+1
+>>> hdr.set_sform(None)
+>>> int(hdr['sform_code'])
+0
+
+
+
+ +
+
+set_slice_duration(duration)ΒΆ
+

Set slice duration

+
+
Parameters:
+
+
durationscalar

time to acquire one slice

+
+
+
+
+

Examples

+

See get_slice_duration

+
+ +
+
+set_slice_times(slice_times)ΒΆ
+

Set slice times into hdr

+
+
Parameters:
+
+
slice_timestuple

tuple of slice times, one value per slice +tuple can include None to indicate no slice time for that slice

+
+
+
+
+

Examples

+
>>> hdr = Nifti1Header()
+>>> hdr.set_dim_info(slice=2)
+>>> hdr.set_data_shape([1, 1, 7])
+>>> hdr.set_slice_duration(0.1)
+>>> times = [None, 0.2, 0.4, 0.1, 0.3, 0.0, None]
+>>> hdr.set_slice_times(times)
+>>> hdr.get_value_label('slice_code')
+'alternating decreasing'
+>>> int(hdr['slice_start'])
+1
+>>> int(hdr['slice_end'])
+5
+
+
+
+ +
+
+set_slope_inter(slope, inter=None)ΒΆ
+

Set slope and / or intercept into header

+

Set slope and intercept for image data, such that, if the image +data is arr, then the scaled image data will be (arr * +slope) + inter

+

(slope, inter) of (NaN, NaN) is a signal to a containing image to +set slope, inter automatically on write.

+
+
Parameters:
+
+
slopeNone or float

If None, implies slope of NaN. If slope is None or NaN then +inter should be None or NaN. Values of 0, Inf or -Inf raise +HeaderDataError

+
+
interNone or float, optional

Intercept. If None, implies inter of NaN. If slope is None or +NaN then inter should be None or NaN. Values of Inf or -Inf raise +HeaderDataError

+
+
+
+
+
+ +
+
+set_xyzt_units(xyz=None, t=None)ΒΆ
+
+ +
+
+single_magic = b'n+1'ΒΆ
+
+ +
+
+single_vox_offset = 352ΒΆ
+
+ +
+
+template_dtype = dtype([('sizeof_hdr', '<i4'), ('data_type', 'S10'), ('db_name', 'S18'), ('extents', '<i4'), ('session_error', '<i2'), ('regular', 'S1'), ('dim_info', 'u1'), ('dim', '<i2', (8,)), ('intent_p1', '<f4'), ('intent_p2', '<f4'), ('intent_p3', '<f4'), ('intent_code', '<i2'), ('datatype', '<i2'), ('bitpix', '<i2'), ('slice_start', '<i2'), ('pixdim', '<f4', (8,)), ('vox_offset', '<f4'), ('scl_slope', '<f4'), ('scl_inter', '<f4'), ('slice_end', '<i2'), ('slice_code', 'u1'), ('xyzt_units', 'u1'), ('cal_max', '<f4'), ('cal_min', '<f4'), ('slice_duration', '<f4'), ('toffset', '<f4'), ('glmax', '<i4'), ('glmin', '<i4'), ('descrip', 'S80'), ('aux_file', 'S24'), ('qform_code', '<i2'), ('sform_code', '<i2'), ('quatern_b', '<f4'), ('quatern_c', '<f4'), ('quatern_d', '<f4'), ('qoffset_x', '<f4'), ('qoffset_y', '<f4'), ('qoffset_z', '<f4'), ('srow_x', '<f4', (4,)), ('srow_y', '<f4', (4,)), ('srow_z', '<f4', (4,)), ('intent_name', 'S16'), ('magic', 'S4')])ΒΆ
+
+ +
+
+write_to(fileobj)ΒΆ
+

Write structure to fileobj

+

Write starts at fileobj current file position.

+
+
Parameters:
+
+
fileobjfile-like object

Should implement write method

+
+
+
+
Returns:
+
+
None
+
+
+
+

Examples

+
>>> wstr = WrapStruct()
+>>> from io import BytesIO
+>>> str_io = BytesIO()
+>>> wstr.write_to(str_io)
+>>> wstr.binaryblock == str_io.getvalue()
+True
+
+
+
+ +
+ +
+
+

Nifti1ImageΒΆ

+
+
+class nibabel.nifti1.Nifti1Image(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Bases: Nifti1Pair, SerializableImage

+

Class for single file NIfTI1 format image

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Notes

+

If both a header and an affine are specified, and the affine does +not match the affine that is in the header, the affine will be used, +but the sform_code and qform_code fields in the header will be +re-initialised to their default values. This is performed on the basis +that, if you are changing the affine, you are likely to be changing the +space to which the affine is pointing. The set_sform() and +set_qform() methods can be used to update the codes after an image +has been created - see those methods, and the manual for more details.

+
+
+__init__(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Notes

+

If both a header and an affine are specified, and the affine does +not match the affine that is in the header, the affine will be used, +but the sform_code and qform_code fields in the header will be +re-initialised to their default values. This is performed on the basis +that, if you are changing the affine, you are likely to be changing the +space to which the affine is pointing. The set_sform() and +set_qform() methods can be used to update the codes after an image +has been created - see those methods, and the manual for more details.

+
+ +
+
+files_types: tuple[tuple[str, str], ...] = (('image', '.nii'),)ΒΆ
+
+ +
+
+header_classΒΆ
+

alias of Nifti1Header

+
+ +
+
+update_header()ΒΆ
+

Harmonize header with image data and affine

+
+ +
+
+valid_exts: tuple[str, ...] = ('.nii',)ΒΆ
+
+ +
+ +
+
+

Nifti1PairΒΆ

+
+
+class nibabel.nifti1.Nifti1Pair(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Bases: AnalyzeImage

+

Class for NIfTI1 format image, header pair

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Notes

+

If both a header and an affine are specified, and the affine does +not match the affine that is in the header, the affine will be used, +but the sform_code and qform_code fields in the header will be +re-initialised to their default values. This is performed on the basis +that, if you are changing the affine, you are likely to be changing the +space to which the affine is pointing. The set_sform() and +set_qform() methods can be used to update the codes after an image +has been created - see those methods, and the manual for more details.

+
+
+__init__(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Notes

+

If both a header and an affine are specified, and the affine does +not match the affine that is in the header, the affine will be used, +but the sform_code and qform_code fields in the header will be +re-initialised to their default values. This is performed on the basis +that, if you are changing the affine, you are likely to be changing the +space to which the affine is pointing. The set_sform() and +set_qform() methods can be used to update the codes after an image +has been created - see those methods, and the manual for more details.

+
+ +
+
+as_reoriented(ornt)ΒΆ
+

Apply an orientation change and return a new image

+

If ornt is identity transform, return the original image, unchanged

+
+
Parameters:
+
+
ornt(n,2) orientation array

orientation transform. ornt[N,1]` is flip of axis N of the +array implied by `shape`, where 1 means no flip and -1 means +flip.  For example, if ``N==0 and ornt[0,1] == -1, and +there’s an array arr of shape shape, the flip would +correspond to the effect of np.flipud(arr). ornt[:,0] is +the transpose that needs to be done to the implied array, as in +arr.transpose(ornt[:,0])

+
+
+
+
+
+ +
+
+get_data_dtype(finalize=False)ΒΆ
+

Get numpy dtype for data

+

If set_data_dtype() has been called with an alias +and finalize is False, return the alias. +If finalize is True, determine the appropriate dtype +from the image data object and set the final dtype in the +header before returning it.

+
+ +
+
+get_qform(coded=False)ΒΆ
+

Return 4x4 affine matrix from qform parameters in header

+
+
Parameters:
+
+
codedbool, optional

If True, return {affine or None}, and qform code. If False, just +return affine. {affine or None} means, return None if qform code +== 0, and affine otherwise.

+
+
+
+
Returns:
+
+
affineNone or (4,4) ndarray

If coded is False, always return affine reconstructed from qform +quaternion. If coded is True, return None if qform code is 0, +else return the affine.

+
+
codeint

Qform code. Only returned if coded is True.

+
+
+
+
+
+

See also

+
+
set_qform
+
get_sform
+
+
+
+ +
+
+get_sform(coded=False)ΒΆ
+

Return 4x4 affine matrix from sform parameters in header

+
+
Parameters:
+
+
codedbool, optional

If True, return {affine or None}, and sform code. If False, just +return affine. {affine or None} means, return None if sform code +== 0, and affine otherwise.

+
+
+
+
Returns:
+
+
affineNone or (4,4) ndarray

If coded is False, always return affine from sform fields. If +coded is True, return None if sform code is 0, else return the +affine.

+
+
codeint

Sform code. Only returned if coded is True.

+
+
+
+
+
+

See also

+
+
set_sform
+
get_qform
+
+
+
+ +
+
+header_classΒΆ
+

alias of Nifti1PairHeader

+
+ +
+
+rw: bool = TrueΒΆ
+
+ +
+
+set_data_dtype(datatype)ΒΆ
+

Set numpy dtype for data from code, dtype, type or alias

+

Using int or "int" is disallowed, as these types +will be interpreted as np.int64, which is almost never desired. +np.int64 is permitted for those intent on making poor choices.

+

The following aliases are defined to allow for flexible specification:

+
+
    +
  • 'mask' - Alias for uint8

  • +
  • 'compat' - The nearest Analyze-compatible datatype +(uint8, int16, int32, float32)

  • +
  • 'smallest' - The smallest Analyze-compatible integer +(uint8, int16, int32)

  • +
+
+

Dynamic aliases are resolved when get_data_dtype() is called +with a finalize=True flag. Until then, these aliases are not +written to the header and will not persist to new images.

+

Examples

+
>>> ints = np.arange(24, dtype='i4').reshape((2,3,4))
+
+
+
>>> img = Nifti1Image(ints, np.eye(4))
+>>> img.set_data_dtype(np.uint8)
+>>> img.get_data_dtype()
+dtype('uint8')
+>>> img.set_data_dtype('mask')
+>>> img.get_data_dtype()
+dtype('uint8')
+>>> img.set_data_dtype('compat')
+>>> img.get_data_dtype()
+'compat'
+>>> img.get_data_dtype(finalize=True)
+dtype('<i4')
+>>> img.get_data_dtype()
+dtype('<i4')
+>>> img.set_data_dtype('smallest')
+>>> img.get_data_dtype()
+'smallest'
+>>> img.get_data_dtype(finalize=True)
+dtype('uint8')
+>>> img.get_data_dtype()
+dtype('uint8')
+
+
+

Note that floating point values will not be coerced to int

+
>>> floats = np.arange(24, dtype='f4').reshape((2,3,4))
+>>> img = Nifti1Image(floats, np.eye(4))
+>>> img.set_data_dtype('smallest')
+>>> img.get_data_dtype(finalize=True)
+Traceback (most recent call last):
+   ...
+ValueError: Cannot automatically cast array (of type float32) to an integer
+type with fewer than 64 bits. Please set_data_dtype() to an explicit data type.
+
+
+
>>> arr = np.arange(1000, 1024, dtype='i4').reshape((2,3,4))
+>>> img = Nifti1Image(arr, np.eye(4))
+>>> img.set_data_dtype('smallest')
+>>> img.set_data_dtype('implausible')
+Traceback (most recent call last):
+   ...
+nibabel.spatialimages.HeaderDataError: data dtype "implausible" not recognized
+>>> img.set_data_dtype('none')
+Traceback (most recent call last):
+   ...
+nibabel.spatialimages.HeaderDataError: data dtype "none" known but not supported
+>>> img.set_data_dtype(np.void)
+Traceback (most recent call last):
+   ...
+nibabel.spatialimages.HeaderDataError: data dtype "<class 'numpy.void'>" known
+but not supported
+>>> img.set_data_dtype('int')
+Traceback (most recent call last):
+   ...
+ValueError: Invalid data type 'int'. Specify a sized integer, e.g., 'uint8' or numpy.int16.
+>>> img.set_data_dtype(int)
+Traceback (most recent call last):
+   ...
+ValueError: Invalid data type <class 'int'>. Specify a sized integer, e.g., 'uint8' or
+numpy.int16.
+>>> img.set_data_dtype('int64')
+>>> img.get_data_dtype() == np.dtype('int64')
+True
+
+
+
+ +
+
+set_qform(affine, code=None, strip_shears=True, **kwargs)ΒΆ
+

Set qform header values from 4x4 affine

+
+
Parameters:
+
+
affineNone or 4x4 array

affine transform to write into sform. If None, only set code.

+
+
codeNone, string or integer

String or integer giving meaning of transform in affine. +The default is None. If code is None, then:

+
    +
  • If affine is None, code-> 0

  • +
  • If affine not None and existing qform code in header == 0, +code-> 2 (aligned)

  • +
  • If affine not None and existing qform code in header != 0, +code-> existing qform code in header

  • +
+
+
strip_shearsbool, optional

Whether to strip shears in affine. If True, shears will be +silently stripped. If False, the presence of shears will raise a +HeaderDataError

+
+
update_affinebool, optional

Whether to update the image affine from the header best affine +after setting the qform. Must be keyword argument (because of +different position in set_qform). Default is True

+
+
+
+
+
+

See also

+
+
get_qform
+
set_sform
+
+
+

Examples

+
>>> data = np.arange(24, dtype='f4').reshape((2,3,4))
+>>> aff = np.diag([2, 3, 4, 1])
+>>> img = Nifti1Pair(data, aff)
+>>> img.get_qform()
+array([[2., 0., 0., 0.],
+       [0., 3., 0., 0.],
+       [0., 0., 4., 0.],
+       [0., 0., 0., 1.]])
+>>> img.get_qform(coded=True)
+(None, 0)
+>>> aff2 = np.diag([3, 4, 5, 1])
+>>> img.set_qform(aff2, 'talairach')
+>>> qaff, code = img.get_qform(coded=True)
+>>> np.all(qaff == aff2)
+True
+>>> int(code)
+3
+
+
+
+ +
+
+set_sform(affine, code=None, **kwargs)ΒΆ
+

Set sform transform from 4x4 affine

+
+
Parameters:
+
+
affineNone or 4x4 array

affine transform to write into sform. If None, only set code

+
+
codeNone, string or integer

String or integer giving meaning of transform in affine. +The default is None. If code is None, then:

+
    +
  • If affine is None, code-> 0

  • +
  • If affine not None and existing sform code in header == 0, +code-> 2 (aligned)

  • +
  • If affine not None and existing sform code in header != 0, +code-> existing sform code in header

  • +
+
+
update_affinebool, optional

Whether to update the image affine from the header best affine +after setting the qform. Must be keyword argument (because of +different position in set_qform). Default is True

+
+
+
+
+
+

See also

+
+
get_sform
+
set_qform
+
+
+

Examples

+
>>> data = np.arange(24, dtype='f4').reshape((2,3,4))
+>>> aff = np.diag([2, 3, 4, 1])
+>>> img = Nifti1Pair(data, aff)
+>>> img.get_sform()
+array([[2., 0., 0., 0.],
+       [0., 3., 0., 0.],
+       [0., 0., 4., 0.],
+       [0., 0., 0., 1.]])
+>>> saff, code = img.get_sform(coded=True)
+>>> saff
+array([[2., 0., 0., 0.],
+       [0., 3., 0., 0.],
+       [0., 0., 4., 0.],
+       [0., 0., 0., 1.]])
+>>> int(code)
+2
+>>> aff2 = np.diag([3, 4, 5, 1])
+>>> img.set_sform(aff2, 'talairach')
+>>> saff, code = img.get_sform(coded=True)
+>>> np.all(saff == aff2)
+True
+>>> int(code)
+3
+
+
+
+ +
+
+to_file_map(file_map=None, dtype=None)ΒΆ
+

Write image to file_map or contained self.file_map

+
+
Parameters:
+
+
file_mapNone or mapping, optional

files mapping. If None (default) use object’s file_map +attribute instead

+
+
dtypedtype-like, optional

The on-disk data type to coerce the data array.

+
+
+
+
+
+ +
+
+update_header()ΒΆ
+

Harmonize header with image data and affine

+

See AnalyzeImage.update_header for more examples

+

Examples

+
>>> data = np.zeros((2,3,4))
+>>> affine = np.diag([1.0,2.0,3.0,1.0])
+>>> img = Nifti1Image(data, affine)
+>>> hdr = img.header
+>>> np.all(hdr.get_qform() == affine)
+True
+>>> np.all(hdr.get_sform() == affine)
+True
+
+
+
+ +
+ +
+
+

Nifti1PairHeaderΒΆ

+
+
+class nibabel.nifti1.Nifti1PairHeader(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Bases: Nifti1Header

+

Class for NIfTI1 pair header

+

Initialize header from binary data block and extensions

+
+
+__init__(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Initialize header from binary data block and extensions

+
+ +
+
+is_single = FalseΒΆ
+
+ +
+ +
+
+

loadΒΆ

+
+
+nibabel.nifti1.load(filename)ΒΆ
+

Load NIfTI1 single or pair from filename

+
+
Parameters:
+
+
filenamestr

filename of image to be loaded

+
+
+
+
Returns:
+
+
imgNifti1Image or Nifti1Pair

NIfTI1 single or pair image instance

+
+
+
+
Raises:
+
+
ImageFileError

if filename doesn’t look like NIfTI1;

+
+
OSError

if filename does not exist.

+
+
+
+
+
+ +
+
+

saveΒΆ

+
+
+nibabel.nifti1.save(img, filename)ΒΆ
+

Save NIfTI1 single or pair to filename

+
+
Parameters:
+
+
filenamestr

filename to which to save image

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.nifti2.html b/reference/nibabel.nifti2.html new file mode 100644 index 0000000000..927c6ac6d1 --- /dev/null +++ b/reference/nibabel.nifti2.html @@ -0,0 +1,556 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

nifti2ΒΆ

+

Read / write access to NIfTI2 image format

+

Format described here:

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

Nifti2Header([binaryblock,Β endianness,Β ...])

Class for NIfTI2 header

Nifti2Image(dataobj,Β affine[,Β header,Β ...])

Class for single file NIfTI2 format image

Nifti2Pair(dataobj,Β affine[,Β header,Β extra,Β ...])

Class for NIfTI2 format image, header pair

Nifti2PairHeader([binaryblock,Β endianness,Β ...])

Class for NIfTI2 pair header

load(filename)

Load NIfTI2 single or pair image from filename

save(img,Β filename)

Save NIfTI2 single or pair to filename

+
+

Nifti2HeaderΒΆ

+
+
+class nibabel.nifti2.Nifti2Header(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Bases: Nifti1Header

+

Class for NIfTI2 header

+

NIfTI2 is a slightly simplified variant of NIfTI1 which replaces 32-bit +floats with 64-bit floats, and increases some integer widths to 32 or 64 +bits.

+

Initialize header from binary data block and extensions

+
+
+__init__(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Initialize header from binary data block and extensions

+
+ +
+
+classmethod default_structarr(endianness=None)ΒΆ
+

Create empty header binary block with given endianness

+
+ +
+
+get_data_shape()ΒΆ
+

Get shape of data

+

Notes

+

Does not use Nifti1 freesurfer hack for large vectors described in +Nifti1Header.set_data_shape()

+

Examples

+
>>> hdr = Nifti2Header()
+>>> hdr.get_data_shape()
+(0,)
+>>> hdr.set_data_shape((1,2,3))
+>>> hdr.get_data_shape()
+(1, 2, 3)
+
+
+

Expanding number of dimensions gets default zooms

+
>>> hdr.get_zooms()
+(1.0, 1.0, 1.0)
+
+
+
+ +
+
+classmethod may_contain_header(binaryblock)ΒΆ
+
+ +
+
+pair_magic = b'ni2'ΒΆ
+
+ +
+
+pair_vox_offset = 0ΒΆ
+
+ +
+
+quaternion_threshold = -6.661338147750939e-16ΒΆ
+
+ +
+
+set_data_shape(shape)ΒΆ
+

Set shape of data

+

If ndims == len(shape) then we set zooms for dimensions higher than +ndims to 1.0

+
+
Parameters:
+
+
shapesequence

sequence of integers specifying data array shape

+
+
+
+
+

Notes

+

Does not apply nifti1 Freesurfer hack for long vectors (see +Nifti1Header.set_data_shape())

+
+ +
+
+single_magic = b'n+2'ΒΆ
+
+ +
+
+single_vox_offset = 544ΒΆ
+
+ +
+
+sizeof_hdr = 540ΒΆ
+
+ +
+
+template_dtype = dtype([('sizeof_hdr', '<i4'), ('magic', 'S4'), ('eol_check', 'i1', (4,)), ('datatype', '<i2'), ('bitpix', '<i2'), ('dim', '<i8', (8,)), ('intent_p1', '<f8'), ('intent_p2', '<f8'), ('intent_p3', '<f8'), ('pixdim', '<f8', (8,)), ('vox_offset', '<i8'), ('scl_slope', '<f8'), ('scl_inter', '<f8'), ('cal_max', '<f8'), ('cal_min', '<f8'), ('slice_duration', '<f8'), ('toffset', '<f8'), ('slice_start', '<i8'), ('slice_end', '<i8'), ('descrip', 'S80'), ('aux_file', 'S24'), ('qform_code', '<i4'), ('sform_code', '<i4'), ('quatern_b', '<f8'), ('quatern_c', '<f8'), ('quatern_d', '<f8'), ('qoffset_x', '<f8'), ('qoffset_y', '<f8'), ('qoffset_z', '<f8'), ('srow_x', '<f8', (4,)), ('srow_y', '<f8', (4,)), ('srow_z', '<f8', (4,)), ('slice_code', '<i4'), ('xyzt_units', '<i4'), ('intent_code', '<i4'), ('intent_name', 'S16'), ('dim_info', 'u1'), ('unused_str', 'S15')])ΒΆ
+
+ +
+ +
+
+

Nifti2ImageΒΆ

+
+
+class nibabel.nifti2.Nifti2Image(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Bases: Nifti1Image

+

Class for single file NIfTI2 format image

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Notes

+

If both a header and an affine are specified, and the affine does +not match the affine that is in the header, the affine will be used, +but the sform_code and qform_code fields in the header will be +re-initialised to their default values. This is performed on the basis +that, if you are changing the affine, you are likely to be changing the +space to which the affine is pointing. The set_sform() and +set_qform() methods can be used to update the codes after an image +has been created - see those methods, and the manual for more details.

+
+
+__init__(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Notes

+

If both a header and an affine are specified, and the affine does +not match the affine that is in the header, the affine will be used, +but the sform_code and qform_code fields in the header will be +re-initialised to their default values. This is performed on the basis +that, if you are changing the affine, you are likely to be changing the +space to which the affine is pointing. The set_sform() and +set_qform() methods can be used to update the codes after an image +has been created - see those methods, and the manual for more details.

+
+ +
+
+header_classΒΆ
+

alias of Nifti2Header

+
+ +
+ +
+
+

Nifti2PairΒΆ

+
+
+class nibabel.nifti2.Nifti2Pair(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Bases: Nifti1Pair

+

Class for NIfTI2 format image, header pair

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Notes

+

If both a header and an affine are specified, and the affine does +not match the affine that is in the header, the affine will be used, +but the sform_code and qform_code fields in the header will be +re-initialised to their default values. This is performed on the basis +that, if you are changing the affine, you are likely to be changing the +space to which the affine is pointing. The set_sform() and +set_qform() methods can be used to update the codes after an image +has been created - see those methods, and the manual for more details.

+
+
+__init__(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+

Notes

+

If both a header and an affine are specified, and the affine does +not match the affine that is in the header, the affine will be used, +but the sform_code and qform_code fields in the header will be +re-initialised to their default values. This is performed on the basis +that, if you are changing the affine, you are likely to be changing the +space to which the affine is pointing. The set_sform() and +set_qform() methods can be used to update the codes after an image +has been created - see those methods, and the manual for more details.

+
+ +
+
+header_classΒΆ
+

alias of Nifti2PairHeader

+
+ +
+ +
+
+

Nifti2PairHeaderΒΆ

+
+
+class nibabel.nifti2.Nifti2PairHeader(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Bases: Nifti2Header

+

Class for NIfTI2 pair header

+

Initialize header from binary data block and extensions

+
+
+__init__(binaryblock=None, endianness=None, check=True, extensions=())ΒΆ
+

Initialize header from binary data block and extensions

+
+ +
+
+is_single = FalseΒΆ
+
+ +
+ +
+
+

loadΒΆ

+
+
+nibabel.nifti2.load(filename)ΒΆ
+

Load NIfTI2 single or pair image from filename

+
+
Parameters:
+
+
filenamestr

filename of image to be loaded

+
+
+
+
Returns:
+
+
imgNifti2Image or Nifti2Pair

nifti2 single or pair image instance

+
+
+
+
Raises:
+
+
ImageFileError

if filename doesn’t look like nifti2;

+
+
OSError

if filename does not exist.

+
+
+
+
+
+ +
+
+

saveΒΆ

+
+
+nibabel.nifti2.save(img, filename)ΒΆ
+

Save NIfTI2 single or pair to filename

+
+
Parameters:
+
+
filenamestr

filename to which to save image

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.onetime.html b/reference/nibabel.onetime.html new file mode 100644 index 0000000000..59eff4939c --- /dev/null +++ b/reference/nibabel.onetime.html @@ -0,0 +1,339 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

onetimeΒΆ

+

Descriptor support for NIPY

+

Utilities to support special Python descriptors [1,2], in particular the use of +a useful pattern for properties we call β€˜one time properties’. These are +object attributes which are declared as properties, but become regular +attributes once they’ve been read the first time. They can thus be evaluated +later in the object’s life cycle, but once evaluated they become normal, static +attributes with no function call overhead on access or any other constraints.

+

A special ResetMixin class is provided to add a .reset() method to users who +may want to have their objects capable of resetting these computed properties +to their β€˜untriggered’ state.

+
+

ReferencesΒΆ

+

[1] How-To Guide for Descriptors, Raymond +Hettinger. https://docs.python.org/howto/descriptor.html

+

[2] Python data model, https://docs.python.org/reference/datamodel.html

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

OneTimeProperty(func)

A descriptor to make special properties that become normal attributes.

ResetMixin()

A Mixin class to add a .reset() method to users of OneTimeProperty.

auto_attr(func)

Decorator to create OneTimeProperty attributes.

setattr_on_read(func)

Decorator to create OneTimeProperty attributes.

+
+

OneTimePropertyΒΆ

+
+
+class nibabel.onetime.OneTimeProperty(func: Callable[[InstanceT], T])ΒΆ
+

Bases: Generic[T]

+

A descriptor to make special properties that become normal attributes.

+

This is meant to be used mostly by the auto_attr decorator in this module.

+

Create a OneTimeProperty instance.

+
+
Parameters:
+
+
funcmethod
+
The method that will be called the first time to compute a value.
+
Afterwards, the method’s name will be a standard attribute holding
+
the value of this computation.
+
+
+
+
+
+__init__(func: Callable[[InstanceT], T]) NoneΒΆ
+

Create a OneTimeProperty instance.

+
+
Parameters:
+
+
funcmethod
+
The method that will be called the first time to compute a value.
+
Afterwards, the method’s name will be a standard attribute holding
+
the value of this computation.
+
+
+
+
+ +
+ +
+
+

ResetMixinΒΆ

+
+
+class nibabel.onetime.ResetMixinΒΆ
+

Bases: object

+

A Mixin class to add a .reset() method to users of OneTimeProperty.

+

By default, auto attributes once computed, become static. If they happen +to depend on other parts of an object and those parts change, their values +may now be invalid.

+

This class offers a .reset() method that users can call explicitly when +they know the state of their objects may have changed and they want to +ensure that all their special attributes should be invalidated. Once +reset() is called, all their auto attributes are reset to their +OneTimeProperty descriptors, and their accessor functions will be triggered +again.

+
+

Warning

+

If a class has a set of attributes that are OneTimeProperty, but that +can be initialized from any one of them, do NOT use this mixin! For +instance, UniformTimeSeries can be initialized with only sampling_rate +and t0, sampling_interval and time are auto-computed. But if you were +to reset() a UniformTimeSeries, it would lose all 4, and there would be +then no way to break the circular dependency chains.

+

If this becomes a problem in practice (for our analyzer objects it +isn’t, as they don’t have the above pattern), we can extend reset() to +check for a _no_reset set of names in the instance which are meant to be +kept protected. But for now this is NOT done, so caveat emptor.

+
+

Examples

+
>>> class A(ResetMixin):
+...     def __init__(self,x=1.0):
+...         self.x = x
+...
+...     @auto_attr
+...     def y(self):
+...         print('*** y computation executed ***')
+...         return self.x / 2.0
+...
+
+
+
>>> a = A(10)
+
+
+

About to access y twice, the second time no computation is done: +>>> a.y +* y computation executed * +5.0 +>>> a.y +5.0

+

Changing x +>>> a.x = 20

+

a.y doesn’t change to 10, since it is a static attribute: +>>> a.y +5.0

+

We now reset a, and this will then force all auto attributes to recompute +the next time we access them: +>>> a.reset()

+

About to access y twice again after reset(): +>>> a.y +* y computation executed * +10.0 +>>> a.y +10.0

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+reset() NoneΒΆ
+

Reset all OneTimeProperty attributes that may have fired already.

+
+ +
+ +
+
+

auto_attrΒΆ

+
+
+nibabel.onetime.auto_attr(func: Callable[[InstanceT], T]) OneTimeProperty[T]ΒΆ
+

Decorator to create OneTimeProperty attributes.

+
+
Parameters:
+
+
funcmethod

The method that will be called the first time to compute a value. +Afterwards, the method’s name will be a standard attribute holding the +value of this computation.

+
+
+
+
+

Examples

+
>>> class MagicProp:
+...     @auto_attr
+...     def a(self):
+...         return 99
+...
+>>> x = MagicProp()
+>>> 'a' in x.__dict__
+False
+>>> x.a
+99
+>>> 'a' in x.__dict__
+True
+
+
+
+ +
+
+

setattr_on_readΒΆ

+
+
+nibabel.onetime.setattr_on_read(func: Callable[[InstanceT], T]) OneTimeProperty[T]ΒΆ
+

Decorator to create OneTimeProperty attributes.

+

setattr_on_read has been renamed to auto_attr. Please use nibabel.onetime.auto_attr

+
    +
  • deprecated from version: 3.2

  • +
  • Raises <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 5.0

  • +
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.openers.html b/reference/nibabel.openers.html new file mode 100644 index 0000000000..f5766d1c07 --- /dev/null +++ b/reference/nibabel.openers.html @@ -0,0 +1,449 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

openersΒΆ

+

Context manager openers for various fileobject types

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

DeterministicGzipFile([filename,Β mode,Β ...])

Deterministic variant of GzipFile

Fileish(*args,Β **kwargs)

ImageOpener(fileish,Β *args,Β **kwargs)

Opener-type class to collect extra compressed extensions

Opener(fileish,Β *args,Β **kwargs)

Class to accept, maybe open, and context-manage file-likes / filenames

+
+

DeterministicGzipFileΒΆ

+
+
+class nibabel.openers.DeterministicGzipFile(filename: str | None = None, mode: Mode | None = None, compresslevel: int = 9, fileobj: io.FileIO | None = None, mtime: int = 0)ΒΆ
+

Bases: GzipFile

+

Deterministic variant of GzipFile

+

This writer does not add filename information to the header, and defaults +to a modification time (mtime) of 0 seconds.

+

Constructor for the GzipFile class.

+

At least one of fileobj and filename must be given a +non-trivial value.

+

The new class instance is based on fileobj, which can be a regular +file, an io.BytesIO object, or any other object which simulates a file. +It defaults to None, in which case filename is opened to provide +a file object.

+

When fileobj is not None, the filename argument is only used to be +included in the gzip file header, which may include the original +filename of the uncompressed file. It defaults to the filename of +fileobj, if discernible; otherwise, it defaults to the empty string, +and in this case the original filename is not included in the header.

+

The mode argument can be any of β€˜r’, β€˜rb’, β€˜a’, β€˜ab’, β€˜w’, β€˜wb’, β€˜x’, or +β€˜xb’ depending on whether the file will be read or written. The default +is the mode of fileobj if discernible; otherwise, the default is β€˜rb’. +A mode of β€˜r’ is equivalent to one of β€˜rb’, and similarly for β€˜w’ and +β€˜wb’, β€˜a’ and β€˜ab’, and β€˜x’ and β€˜xb’.

+

The compresslevel argument is an integer from 0 to 9 controlling the +level of compression; 1 is fastest and produces the least compression, +and 9 is slowest and produces the most compression. 0 is no compression +at all. The default is 9.

+

The mtime argument is an optional numeric timestamp to be written +to the last modification time field in the stream when compressing. +If omitted or None, the current time is used.

+
+
+__init__(filename: str | None = None, mode: Mode | None = None, compresslevel: int = 9, fileobj: io.FileIO | None = None, mtime: int = 0)ΒΆ
+

Constructor for the GzipFile class.

+

At least one of fileobj and filename must be given a +non-trivial value.

+

The new class instance is based on fileobj, which can be a regular +file, an io.BytesIO object, or any other object which simulates a file. +It defaults to None, in which case filename is opened to provide +a file object.

+

When fileobj is not None, the filename argument is only used to be +included in the gzip file header, which may include the original +filename of the uncompressed file. It defaults to the filename of +fileobj, if discernible; otherwise, it defaults to the empty string, +and in this case the original filename is not included in the header.

+

The mode argument can be any of β€˜r’, β€˜rb’, β€˜a’, β€˜ab’, β€˜w’, β€˜wb’, β€˜x’, or +β€˜xb’ depending on whether the file will be read or written. The default +is the mode of fileobj if discernible; otherwise, the default is β€˜rb’. +A mode of β€˜r’ is equivalent to one of β€˜rb’, and similarly for β€˜w’ and +β€˜wb’, β€˜a’ and β€˜ab’, and β€˜x’ and β€˜xb’.

+

The compresslevel argument is an integer from 0 to 9 controlling the +level of compression; 1 is fastest and produces the least compression, +and 9 is slowest and produces the most compression. 0 is no compression +at all. The default is 9.

+

The mtime argument is an optional numeric timestamp to be written +to the last modification time field in the stream when compressing. +If omitted or None, the current time is used.

+
+ +
+ +
+
+

FileishΒΆ

+
+
+class nibabel.openers.Fileish(*args, **kwargs)ΒΆ
+

Bases: Protocol

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+read(size: int = -1, /) bytesΒΆ
+
+ +
+
+write(b: bytes, /) int | NoneΒΆ
+
+ +
+ +
+
+

ImageOpenerΒΆ

+
+
+class nibabel.openers.ImageOpener(fileish: str | IOBase, *args, **kwargs)ΒΆ
+

Bases: Opener

+

Opener-type class to collect extra compressed extensions

+

A trivial sub-class of opener to which image classes can add extra +extensions with custom openers, such as compressed openers.

+

To add an extension, add a line to the class definition (not __init__):

+
+

ImageOpener.compress_ext_map[ext] = func_def

+
+

ext is a file extension beginning with β€˜.’ and should be included in +the image class’s valid_exts tuple.

+

func_def is a (function, (args,)) tuple, where function accepts a +filename as the first parameter, and `args defines the other arguments +that function accepts. These arguments must be any (unordered) subset of +mode, compresslevel, and buffering.

+
+
+__init__(fileish: str | IOBase, *args, **kwargs)ΒΆ
+
+ +
+
+compress_ext_map: dict[str | None, OpenerDef] = {'.bz2': (<class 'bz2.BZ2File'>, ('mode', 'buffering', 'compresslevel')), '.gz': (<function _gzip_open>, ('mode', 'compresslevel', 'mtime', 'keep_open')), '.mgz': (<function _gzip_open>, ('mode', 'compresslevel', 'mtime', 'keep_open')), '.zst': (<function _zstd_open>, ('mode', 'level_or_option', 'zstd_dict')), None: (<built-in function open>, ('mode', 'buffering'))}ΒΆ
+
+ +
+ +
+
+

OpenerΒΆ

+
+
+class nibabel.openers.Opener(fileish: str | IOBase, *args, **kwargs)ΒΆ
+

Bases: object

+

Class to accept, maybe open, and context-manage file-likes / filenames

+

Provides context manager to close files that the constructor opened for +you.

+
+
Parameters:
+
+
fileishstr or file-like

if str, then open with suitable opening method. If file-like, accept as +is

+
+
*argspositional arguments

passed to opening method when fileish is str. mode, if not +specified, is rb. compresslevel, if relevant, and not specified, +is set from class variable default_compresslevel. keep_open, if +relevant, and not specified, is False.

+
+
**kwargskeyword arguments

passed to opening method when fileish is str. Change of defaults as +for *args

+
+
+
+
+
+
+__init__(fileish: str | IOBase, *args, **kwargs)ΒΆ
+
+ +
+
+bz2_def = (<class 'bz2.BZ2File'>, ('mode', 'buffering', 'compresslevel'))ΒΆ
+
+ +
+
+close() NoneΒΆ
+
+ +
+
+close_if_mine() NoneΒΆ
+

Close self.fobj iff we opened it in the constructor

+
+ +
+
+property closed: boolΒΆ
+
+ +
+
+compress_ext_icase: bool = TrueΒΆ
+

whether to ignore case looking for compression extensions

+
+ +
+
+compress_ext_map: dict[str | None, OpenerDef] = {'.bz2': (<class 'bz2.BZ2File'>, ('mode', 'buffering', 'compresslevel')), '.gz': (<function _gzip_open>, ('mode', 'compresslevel', 'mtime', 'keep_open')), '.zst': (<function _zstd_open>, ('mode', 'level_or_option', 'zstd_dict')), None: (<built-in function open>, ('mode', 'buffering'))}ΒΆ
+
+ +
+
+default_compresslevel = 1ΒΆ
+

default compression level when writing gz and bz2 files

+
+ +
+
+default_level_or_option = {'r': None, 'rb': None, 'w': 3, 'wb': 3}ΒΆ
+
+ +
+
+default_zst_compresslevel = 3ΒΆ
+

default option for zst files

+
+ +
+
+fileno() intΒΆ
+
+ +
+
+fobj: io.IOBaseΒΆ
+
+ +
+
+gz_def = (<function _gzip_open>, ('mode', 'compresslevel', 'mtime', 'keep_open'))ΒΆ
+
+ +
+
+property mode: strΒΆ
+
+ +
+
+property name: str | NoneΒΆ
+

Return self.fobj.name or self._name if not present

+

self._name will be None if object was created with a fileobj, otherwise +it will be the filename.

+
+ +
+
+read(size: int = -1, /) bytesΒΆ
+
+ +
+
+readinto(buffer: WriteableBuffer, /) int | NoneΒΆ
+
+ +
+
+seek(pos: int, whence: int = 0, /) intΒΆ
+
+ +
+
+tell() intΒΆ
+
+ +
+
+write(b: bytes, /) int | NoneΒΆ
+
+ +
+
+zstd_def = (<function _zstd_open>, ('mode', 'level_or_option', 'zstd_dict'))ΒΆ
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.optpkg.html b/reference/nibabel.optpkg.html new file mode 100644 index 0000000000..2d8c4f9815 --- /dev/null +++ b/reference/nibabel.optpkg.html @@ -0,0 +1,202 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

optpkgΒΆ

+

Routines to support optional packages

+ + + + + + +

optional_package(name[,Β trip_msg,Β min_version])

Return package-like thing and module setup for package name

+
+

optional_packageΒΆ

+
+
+nibabel.optpkg.optional_package(name: str, trip_msg: str | None = None, min_version: str | Version | Callable[[module], bool] | None = None) tuple[module | TripWire, bool, Callable[[], None]]ΒΆ
+

Return package-like thing and module setup for package name

+
+
Parameters:
+
+
namestr

package name

+
+
trip_msgNone or str

message to give when someone tries to use the return package, but we +could not import it at an acceptable version, and have returned a +TripWire object instead. Default message if None.

+
+
min_versionNone or str or Version or callable

If None, do not specify a minimum version. If str, convert to a +packaging.version.Version. If str or Version compare to +version of package name with min_version <= pkg.__version__. If +callable, accepts imported pkg as argument, and returns value of +callable is True for acceptable package versions, False otherwise.

+
+
+
+
Returns:
+
+
pkg_likemodule or TripWire instance

If we can import the package, return it. Otherwise return an object +raising an error when accessed

+
+
have_pkgbool

True if import for package was successful, false otherwise

+
+
module_setupfunction

callable usually set as setup_module in calling namespace, to allow +skipping tests.

+
+
+
+
+

Examples

+

Typical use would be something like this at the top of a module using an +optional package:

+
>>> from nibabel.optpkg import optional_package
+>>> pkg, have_pkg, setup_module = optional_package('not_a_package')
+
+
+

Of course in this case the package doesn’t exist, and so, in the module:

+
>>> have_pkg
+False
+
+
+

and

+
>>> pkg.some_function() 
+Traceback (most recent call last):
+    ...
+TripWireError: We need package not_a_package for these functions,
+    but ``import not_a_package`` raised an ImportError
+
+
+

If the module does exist - we get the module

+
>>> pkg, _, _ = optional_package('os')
+>>> hasattr(pkg, 'path')
+True
+
+
+

Or a submodule if that’s what we asked for

+
>>> subpkg, _, _ = optional_package('os.path')
+>>> hasattr(subpkg, 'dirname')
+True
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.orientations.html b/reference/nibabel.orientations.html new file mode 100644 index 0000000000..cbd8df9716 --- /dev/null +++ b/reference/nibabel.orientations.html @@ -0,0 +1,466 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

orientationsΒΆ

+

Utilities for calculating and applying affine orientations

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

OrientationError

aff2axcodes(aff[,Β labels,Β tol])

axis direction codes for affine aff

apply_orientation(arr,Β ornt)

Apply transformations implied by ornt to the first n axes of the array arr

axcodes2ornt(axcodes[,Β labels])

Convert axis codes axcodes to an orientation

flip_axis(arr[,Β axis])

Flip contents of axis in array arr

inv_ornt_aff(ornt,Β shape)

Affine transform reversing transforms implied in ornt

io_orientation(affine[,Β tol])

Orientation of input axes in terms of output axes for affine

ornt2axcodes(ornt[,Β labels])

Convert orientation ornt to labels for axis directions

ornt_transform(start_ornt,Β end_ornt)

Return the orientation that transforms from start_ornt to end_ornt.

+
+

OrientationErrorΒΆ

+
+
+class nibabel.orientations.OrientationErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

aff2axcodesΒΆ

+
+
+nibabel.orientations.aff2axcodes(aff, labels=None, tol=None)ΒΆ
+

axis direction codes for affine aff

+
+
Parameters:
+
+
aff(N,M) array-like

affine transformation matrix

+
+
labelsoptional, None or sequence of (2,) sequences

Labels for negative and positive ends of output axes of aff. See +docstring for ornt2axcodes for more detail

+
+
tolNone or float

Tolerance for SVD of affine - see io_orientation for more detail.

+
+
+
+
Returns:
+
+
axcodes(N,) tuple

labels for positive end of voxel axes. Dropped axes get a label of +None.

+
+
+
+
+

Examples

+
>>> aff = [[0,1,0,10],[-1,0,0,20],[0,0,1,30],[0,0,0,1]]
+>>> aff2axcodes(aff, (('L','R'),('B','F'),('D','U')))
+('B', 'R', 'U')
+
+
+
+ +
+
+

apply_orientationΒΆ

+
+
+nibabel.orientations.apply_orientation(arr, ornt)ΒΆ
+

Apply transformations implied by ornt to the first +n axes of the array arr

+
+
Parameters:
+
+
arrarray-like of data with ndim >= n
+
ornt(n,2) orientation array

orientation transform. ornt[N,1]` is flip of axis N of the +array implied by `shape`, where 1 means no flip and -1 means +flip.  For example, if ``N==0 and ornt[0,1] == -1, and +there’s an array arr of shape shape, the flip would +correspond to the effect of np.flipud(arr). ornt[:,0] is +the transpose that needs to be done to the implied array, as in +arr.transpose(ornt[:,0])

+
+
+
+
Returns:
+
+
t_arrndarray

data array arr transformed according to ornt

+
+
+
+
+
+ +
+
+

axcodes2orntΒΆ

+
+
+nibabel.orientations.axcodes2ornt(axcodes, labels=None)ΒΆ
+

Convert axis codes axcodes to an orientation

+
+
Parameters:
+
+
axcodes(N,) tuple

axis codes - see ornt2axcodes docstring

+
+
labelsoptional, None or sequence of (2,) sequences

(2,) sequences are labels for (beginning, end) of output axis. That +is, if the first element in axcodes is front, and the second +(2,) sequence in labels is (β€˜back’, β€˜front’) then the first +row of ornt will be [1, 1]. If None, equivalent to +(('L','R'),('P','A'),('I','S')) - that is - RAS axes.

+
+
+
+
Returns:
+
+
ornt(N,2) array-like

orientation array - see io_orientation docstring

+
+
+
+
+

Examples

+
>>> axcodes2ornt(('F', 'L', 'U'), (('L','R'),('B','F'),('D','U')))
+array([[ 1.,  1.],
+       [ 0., -1.],
+       [ 2.,  1.]])
+
+
+
+ +
+
+

flip_axisΒΆ

+
+
+nibabel.orientations.flip_axis(arr, axis=0)ΒΆ
+

Flip contents of axis in array arr

+

flip_axis is deprecated. Please use numpy.flip instead.

+
    +
  • deprecated from version: 3.2

  • +
  • Raises <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 5.0

  • +
+
+ +
+
+

inv_ornt_affΒΆ

+
+
+nibabel.orientations.inv_ornt_aff(ornt, shape)ΒΆ
+

Affine transform reversing transforms implied in ornt

+

Imagine you have an array arr of shape shape, and you apply the +transforms implied by ornt (more below), to get tarr. +tarr may have a different shape shape_prime. This routine +returns the affine that will take a array coordinate for tarr +and give you the corresponding array coordinate in arr.

+
+
Parameters:
+
+
ornt(p, 2) ndarray

orientation transform. ornt[P, 1]` is flip of axis N of the array +implied by `shape`, where 1 means no flip and -1 means flip.  For +example, if ``P==0 and ornt[0, 1] == -1, and there’s an array +arr of shape shape, the flip would correspond to the effect of +np.flipud(arr). ornt[:,0] gives us the (reverse of the) +transpose that has been done to arr. If there are any NaNs in +ornt, we raise an OrientationError (see notes)

+
+
shapelength p sequence

shape of array you may transform with ornt

+
+
+
+
Returns:
+
+
transform_affine(p + 1, p + 1) ndarray

An array arr (shape shape) might be transformed according to +ornt, resulting in a transformed array tarr. transformed_affine +is the transform that takes you from array coordinates in tarr to +array coordinates in arr.

+
+
+
+
+

Notes

+

If a row in ornt contains NaN, this means that the input row does not +influence the output space, and is thus effectively dropped from the output +space. In that case one tarr coordinate maps to many arr +coordinates, we can’t invert the transform, and we raise an error

+
+ +
+
+

io_orientationΒΆ

+
+
+nibabel.orientations.io_orientation(affine, tol=None)ΒΆ
+

Orientation of input axes in terms of output axes for affine

+

Valid for an affine transformation from p dimensions to q +dimensions (affine.shape == (q + 1, p + 1)).

+

The calculated orientations can be used to transform associated +arrays to best match the output orientations. If p > q, then +some of the output axes should be considered dropped in this +orientation.

+
+
Parameters:
+
+
affine(q+1, p+1) ndarray-like

Transformation affine from p inputs to q outputs. Usually this +will be a shape (4,4) matrix, transforming 3 inputs to 3 outputs, but +the code also handles the more general case

+
+
tol{None, float}, optional

threshold below which SVD values of the affine are considered zero. If +tol is None, and S is an array with singular values for affine, +and eps is the epsilon value for datatype of S, then tol set +to S.max() * max((q, p)) * eps

+
+
+
+
Returns:
+
+
orientations(p, 2) ndarray

one row per input axis, where the first value in each row is the closest +corresponding output axis. The second value in each row is 1 if the +input axis is in the same direction as the corresponding output axis and +-1 if it is in the opposite direction. If a row is [np.nan, np.nan], +which can happen when p > q, then this row should be considered dropped.

+
+
+
+
+
+ +
+
+

ornt2axcodesΒΆ

+
+
+nibabel.orientations.ornt2axcodes(ornt, labels=None)ΒΆ
+

Convert orientation ornt to labels for axis directions

+
+
Parameters:
+
+
ornt(N,2) array-like

orientation array - see io_orientation docstring

+
+
labelsoptional, None or sequence of (2,) sequences

(2,) sequences are labels for (beginning, end) of output axis. That +is, if the first row in ornt is [1, 1], and the second (2,) +sequence in labels is (β€˜back’, β€˜front’) then the first returned axis +code will be 'front'. If the first row in ornt had been +[1, -1] then the first returned value would have been 'back'. +If None, equivalent to (('L','R'),('P','A'),('I','S')) - that is - +RAS axes.

+
+
+
+
Returns:
+
+
axcodes(N,) tuple

labels for positive end of voxel axes. Dropped axes get a label of +None.

+
+
+
+
+

Examples

+
>>> ornt2axcodes([[1, 1],[0,-1],[2,1]], (('L','R'),('B','F'),('D','U')))
+('F', 'L', 'U')
+
+
+
+ +
+
+

ornt_transformΒΆ

+
+
+nibabel.orientations.ornt_transform(start_ornt, end_ornt)ΒΆ
+

Return the orientation that transforms from start_ornt to end_ornt.

+
+
Parameters:
+
+
start_ornt(n,2) orientation array

Initial orientation.

+
+
end_ornt(n,2) orientation array

Final orientation.

+
+
+
+
Returns:
+
+
orientations(p, 2) ndarray

The orientation that will transform the start_ornt to the end_ornt.

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.parrec.html b/reference/nibabel.parrec.html new file mode 100644 index 0000000000..7b98a2508d --- /dev/null +++ b/reference/nibabel.parrec.html @@ -0,0 +1,1032 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

parrecΒΆ

+

Read images in PAR/REC format

+

This is yet another MRI image format generated by Philips scanners. It is an +ASCII header (PAR) plus a binary blob (REC).

+

This implementation aims to read version 4.0 through 4.2 of this format. Other +versions could probably be supported, but we need example images to test +against. If you want us to support another version, and have an image we can +add to the test suite, let us know. You would make us very happy by submitting +a pull request.

+
+

PAR file formatΒΆ

+

The PAR format appears to have two sections:

+
+

General informationΒΆ

+

This is a set of lines each giving one key : value pair, examples:

+
.    EPI factor        <0,1=no EPI>     :   39
+.    Dynamic scan      <0=no 1=yes> ?   :   1
+.    Diffusion         <0=no 1=yes> ?   :   0
+
+
+

(from nibabel/tests/data/phantom_EPI_asc_CLEAR_2_1.PAR)

+
+
+

Image informationΒΆ

+

There is a # prefixed list of fields under the heading β€œIMAGE INFORMATION +DEFINITION”. From the same file, here is the start of this list:

+
# === IMAGE INFORMATION DEFINITION =============================================
+#  The rest of this file contains ONE line per image, this line contains the following information:
+#
+#  slice number                             (integer)
+#  echo number                              (integer)
+#  dynamic scan number                      (integer)
+
+
+

There follows a space separated table with values for these fields, each row +containing all the named values. Here are the first few lines from the example +file above:

+
# === IMAGE INFORMATION ==========================================================
+#  sl ec  dyn ph ty    idx pix scan% rec size                (re)scale              window        angulation              offcentre        thick   gap   info      spacing     echo     dtime   ttime    diff  avg  flip    freq   RR-int  turbo delay b grad cont anis         diffusion       L.ty
+
+1   1    1  1 0 2     0  16    62   64   64     0.00000   1.29035 4.28404e-003  1070  1860 -13.26  -0.00  -0.00    2.51   -0.81   -8.69  6.000  2.000 0 1 0 2  3.750  3.750  30.00    0.00     0.00    0.00   0   90.00     0    0    0    39   0.0  1   1    8    0   0.000    0.000    0.000  1
+2   1    1  1 0 2     1  16    62   64   64     0.00000   1.29035 4.28404e-003  1122  1951 -13.26  -0.00  -0.00    2.51    6.98  -10.53  6.000  2.000 0 1 0 2  3.750  3.750  30.00    0.00     0.00    0.00   0   90.00     0    0    0    39   0.0  1   1    8    0   0.000    0.000    0.000  1
+3   1    1  1 0 2     2  16    62   64   64     0.00000   1.29035 4.28404e-003  1137  1977 -13.26  -0.00  -0.00    2.51   14.77  -12.36  6.000  2.000 0 1 0 2  3.750  3.750  30.00    0.00     0.00    0.00   0   90.00     0    0    0    39   0.0  1   1    8    0   0.000    0.000    0.000  1
+
+
+
+
+

OrientationΒΆ

+

PAR files refer to orientations β€œap”, β€œfh” and β€œrl”.

+

Nibabel’s required affine output axes are RAS (left to Right, posterior to +Anterior, inferior to Superior). The correspondence of the PAR file’s axes to +RAS axes is:

+
    +
  • ap = anterior -> posterior = negative A in RAS = P

  • +
  • fh = foot -> head = S in RAS = S

  • +
  • rl = right -> left = negative R in RAS = L

  • +
+

We therefore call the PAR file’s axis system β€œPSL” (Posterior, Superior, Left).

+

The orientation of the PAR file axes corresponds to DICOM’s LPS coordinate +system (right to Left, anterior to Posterior, inferior to Superior), but in a +different order.

+
+
+

Data typeΒΆ

+

It seems that everyone agrees that Philips stores REC data in little-endian +format - see https://github.com/nipy/nibabel/issues/274

+

Philips XML header files, and some previous experience, suggest that the REC +data is always stored as 8 or 16 bit unsigned integers - see +https://github.com/nipy/nibabel/issues/275

+
+
+

Data SortingΒΆ

+

PAR/REC files have a large number of potential image dimensions. To handle +sorting of volumes in PAR/REC files based on these fields and not the order +slices first appear in the PAR file, the strict_sort flag of +nibabel.load (or parrec.load) should be set to True. The fields +that are taken into account during sorting are:

+
+
    +
  • slice number

  • +
  • echo number

  • +
  • cardiac phase number

  • +
  • gradient orientation number

  • +
  • diffusion b value number

  • +
  • label type (ASL tag vs. control)

  • +
  • dynamic scan number

  • +
  • image_type_mr (Re, Im, Mag, Phase)

  • +
+
+

Slices are sorted into the third dimension and the +order of preference for sorting along the 4th dimension corresponds to the +order in the list above. If the image data has more than 4 dimensions these +will all be concatenated along the 4th dimension. For example, for a scan with +two echos and two dynamics, the 4th dimension will have both echos of dynamic 1 +prior to the two echos for dynamic 2.

+

The``get_volume_labels`` method of the header returns a dictionary containing +the PAR field labels for this 4th dimension.

+

The volume sorting described above can be enabled in the parrec2nii command +utility via the option β€œβ€“strict-sort”. The dimension info can be exported +to a CSV file by adding the option β€œβ€“volume-info”.

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

PARRECArrayProxy(file_like,Β header,Β *[,Β ...])

Initialize PARREC array proxy

PARRECError

Exception for PAR/REC format related problems.

PARRECHeader(info,Β image_defs[,Β ...])

PAR/REC header

PARRECImage(dataobj,Β affine[,Β header,Β ...])

PAR/REC image

exts2pars(exts_source)

Parse, return any PAR headers from NIfTI extensions in exts_source

one_line(long_str)

Make maybe mutli-line long_str into one long line

parse_PAR_header(fobj)

Parse a PAR header and aggregate all information into useful containers.

vol_is_full(slice_nos,Β slice_max[,Β slice_min])

Vector with True for slices in complete volume, False otherwise

vol_numbers(slice_nos)

Calculate volume numbers inferred from slice numbers slice_nos

+
+

PARRECArrayProxyΒΆ

+
+
+class nibabel.parrec.PARRECArrayProxy(file_like, header, *, mmap=True, scaling='dv')ΒΆ
+

Bases: object

+

Initialize PARREC array proxy

+
+
Parameters:
+
+
file_likefile-like object

Filename or object implementing read, seek, tell

+
+
headerPARRECHeader instance

Implementing get_data_shape, get_data_dtype, +get_sorted_slice_indices, get_data_scaling, +get_rec_shape.

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading data. +If False, do not try numpy memmap for data array. If one of +{β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A mmap value of +True gives the same behavior as mmap='c'. If file_like +cannot be memory-mapped, ignore mmap value and read array from +file.

+
+
scaling{β€˜fp’, β€˜dv’}, optional, keyword only

Type of scaling to use - see header get_data_scaling method.

+
+
+
+
+
+
+__init__(file_like, header, *, mmap=True, scaling='dv')ΒΆ
+

Initialize PARREC array proxy

+
+
Parameters:
+
+
file_likefile-like object

Filename or object implementing read, seek, tell

+
+
headerPARRECHeader instance

Implementing get_data_shape, get_data_dtype, +get_sorted_slice_indices, get_data_scaling, +get_rec_shape.

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading data. +If False, do not try numpy memmap for data array. If one of +{β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A mmap value of +True gives the same behavior as mmap='c'. If file_like +cannot be memory-mapped, ignore mmap value and read array from +file.

+
+
scaling{β€˜fp’, β€˜dv’}, optional, keyword only

Type of scaling to use - see header get_data_scaling method.

+
+
+
+
+
+ +
+
+property dtypeΒΆ
+
+ +
+
+get_unscaled()ΒΆ
+

Read data from file

+

This is an optional part of the proxy API

+
+ +
+
+property is_proxyΒΆ
+
+ +
+
+property ndimΒΆ
+
+ +
+
+property shapeΒΆ
+
+ +
+ +
+
+

PARRECErrorΒΆ

+
+
+class nibabel.parrec.PARRECErrorΒΆ
+

Bases: Exception

+

Exception for PAR/REC format related problems.

+

To be raised whenever PAR/REC is not happy, or we are not happy with +PAR/REC.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

PARRECHeaderΒΆ

+
+
+class nibabel.parrec.PARRECHeader(info, image_defs, permit_truncated=False, strict_sort=False)ΒΆ
+

Bases: SpatialHeader

+

PAR/REC header

+
+
Parameters:
+
+
infodict

β€œGeneral information” from the PAR file (as returned by +parse_PAR_header()).

+
+
image_defsarray

Structured array with image definitions from the PAR file (as +returned by parse_PAR_header()).

+
+
permit_truncatedbool, optional

If True, a warning is emitted instead of an error when a truncated +recording is detected.

+
+
strict_sortbool, optional, keyword-only

If True, a larger number of header fields are used while sorting +the REC data array. This may produce a different sort order than +strict_sort=False, where volumes are sorted by the order in which +the slices appear in the .PAR file.

+
+
+
+
+
+
+__init__(info, image_defs, permit_truncated=False, strict_sort=False)ΒΆ
+
+
Parameters:
+
+
infodict

β€œGeneral information” from the PAR file (as returned by +parse_PAR_header()).

+
+
image_defsarray

Structured array with image definitions from the PAR file (as +returned by parse_PAR_header()).

+
+
permit_truncatedbool, optional

If True, a warning is emitted instead of an error when a truncated +recording is detected.

+
+
strict_sortbool, optional, keyword-only

If True, a larger number of header fields are used while sorting +the REC data array. This may produce a different sort order than +strict_sort=False, where volumes are sorted by the order in which +the slices appear in the .PAR file.

+
+
+
+
+
+ +
+
+as_analyze_map()ΒΆ
+

Convert PAR parameters to NIFTI1 format

+
+ +
+
+copy()ΒΆ
+

Copy object to independent representation

+

The copy should not be affected by any changes to the original +object.

+
+ +
+
+classmethod from_fileobj(fileobj, permit_truncated=False, strict_sort=False)ΒΆ
+
+ +
+
+classmethod from_header(header=None)ΒΆ
+
+ +
+
+get_affine(origin='scanner')ΒΆ
+

Compute affine transformation into scanner space.

+

The method only considers global rotation and offset settings in the +header and ignores potentially deviating information in the image +definitions.

+
+
Parameters:
+
+
origin{β€˜scanner’, β€˜fov’}

Transformation origin. By default the transformation is computed +relative to the scanner’s iso center. If β€˜fov’ is requested the +transformation origin will be the center of the field of view +instead.

+
+
+
+
Returns:
+
+
aff(4, 4) array

4x4 array, with output axis order corresponding to RAS or (x,y,z) +or (lr, pa, fh).

+
+
+
+
+

Notes

+

Transformations appear to be specified in (ap, fh, rl) axes. The +orientation of data is recorded in the β€œslice orientation” field of the +PAR header β€œGeneral Information”.

+

We need to:

+
    +
  • translate to coordinates in terms of the center of the FOV

  • +
  • apply voxel size scaling

  • +
  • reorder / flip the data to Philips’ PSL axes

  • +
  • apply the rotations

  • +
  • apply any isocenter scaling offset if origin == β€œscanner”

  • +
  • reorder and flip to RAS axes

  • +
+
+ +
+
+get_bvals_bvecs()ΒΆ
+

Get bvals and bvecs from data

+
+
Returns:
+
+
b_valsNone or array

Array of b values, shape (n_directions,), or None if not a +diffusion acquisition.

+
+
b_vectorsNone or array

Array of b vectors, shape (n_directions, 3), or None if not a +diffusion acquisition.

+
+
+
+
+
+ +
+
+get_data_offset()ΒΆ
+

PAR header always has 0 data offset (into REC file)

+
+ +
+
+get_data_scaling(method='dv')ΒΆ
+

Returns scaling slope and intercept.

+
+
Parameters:
+
+
method{β€˜fp’, β€˜dv’}

Scaling settings to be reported – see notes below.

+
+
+
+
Returns:
+
+
slopearray

scaling slope

+
+
interceptarray

scaling intercept

+
+
+
+
+

Notes

+

The PAR header contains two different scaling settings: β€˜dv’ (value on +console) and β€˜fp’ (floating point value). Here is how they are defined:

+

DV = PV * RS + RI +FP = DV / (RS * SS)

+

where:

+

PV: value in REC +RS: rescale slope +RI: rescale intercept +SS: scale slope

+
+ +
+
+get_def(name)ΒΆ
+

Return a single image definition field (or None if missing)

+
+ +
+
+get_echo_train_length()ΒΆ
+

Echo train length of the recording

+
+ +
+
+get_q_vectors()ΒΆ
+

Get Q vectors from the data

+
+
Returns:
+
+
q_vectorsNone or array

Array of q vectors (bvals * bvecs), or None if not a diffusion +acquisition.

+
+
+
+
+
+ +
+
+get_rec_shape()ΒΆ
+
+ +
+
+get_slice_orientation()ΒΆ
+

Returns the slice orientation label.

+
+
Returns:
+
+
orientation{β€˜transverse’, β€˜sagittal’, β€˜coronal’}
+
+
+
+
+ +
+
+get_sorted_slice_indices()ΒΆ
+

Return indices to sort (and maybe discard) slices in REC file.

+

If the recording is truncated, the returned indices take care of +discarding any slice indices from incomplete volumes.

+

If self.strict_sort is True, a more complicated sorting based on +multiple fields from the .PAR file is used. This may produce a +different sort order than strict_sort=False, where volumes are sorted +by the order in which the slices appear in the .PAR file.

+
+
Returns:
+
+
slice_indiceslist

List for indexing into the last (third) dimension of the REC data +array, and (equivalently) the only dimension of +self.image_defs.

+
+
+
+
+
+ +
+
+get_volume_labels()ΒΆ
+

Dynamic labels corresponding to the final data dimension(s).

+

This is useful for custom data sorting. A subset of the info in +self.image_defs is returned in an order that matches the final +data dimension(s). Only labels that have more than one unique value +across the dataset will be returned.

+
+
Returns:
+
+
sort_infodict

Each key corresponds to volume labels for a dynamically varying +sequence dimension. The ordering of the labels matches the volume +ordering determined via self.get_sorted_slice_indices.

+
+
+
+
+
+ +
+
+get_water_fat_shift()ΒΆ
+

Water fat shift, in pixels

+
+ +
+
+set_data_offset(offset)ΒΆ
+

PAR header always has 0 data offset (into REC file)

+
+ +
+ +
+
+

PARRECImageΒΆ

+
+
+class nibabel.parrec.PARRECImage(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Bases: SpatialImage

+

PAR/REC image

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+ImageArrayProxyΒΆ
+

alias of PARRECArrayProxy

+
+ +
+
+files_types: tuple[ExtensionSpec, ...] = (('image', '.rec'), ('header', '.par'))ΒΆ
+
+ +
+
+classmethod from_file_map(file_map, *, mmap=True, permit_truncated=False, scaling='dv', strict_sort=False)ΒΆ
+

Create PARREC image from file map file_map

+
+
Parameters:
+
+
file_mapdict

dict with keys image, header and values being fileholder +objects for the respective REC and PAR files.

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
permit_truncated{False, True}, optional, keyword-only

If False, raise an error for an image where the header shows signs +that fewer slices / volumes were recorded than were expected.

+
+
scaling{β€˜dv’, β€˜fp’}, optional, keyword-only

Scaling method to apply to data (see +PARRECHeader.get_data_scaling()).

+
+
strict_sortbool, optional, keyword-only

If True, a larger number of header fields are used while sorting +the REC data array. This may produce a different sort order than +strict_sort=False, where volumes are sorted by the order in which +the slices appear in the .PAR file.

+
+
+
+
+
+ +
+
+classmethod from_filename(filename, *, mmap=True, permit_truncated=False, scaling='dv', strict_sort=False)ΒΆ
+

Create PARREC image from filename filename

+
+
Parameters:
+
+
filenamestr

Filename of β€œPAR” or β€œREC” file

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
permit_truncated{False, True}, optional, keyword-only

If False, raise an error for an image where the header shows signs +that fewer slices / volumes were recorded than were expected.

+
+
scaling{β€˜dv’, β€˜fp’}, optional, keyword-only

Scaling method to apply to data (see +PARRECHeader.get_data_scaling()).

+
+
strict_sortbool, optional, keyword-only

If True, a larger number of header fields are used while sorting +the REC data array. This may produce a different sort order than +strict_sort=False, where volumes are sorted by the order in which +the slices appear in the .PAR file.

+
+
+
+
+
+ +
+
+header_classΒΆ
+

alias of PARRECHeader

+
+ +
+
+classmethod load(filename, *, mmap=True, permit_truncated=False, scaling='dv', strict_sort=False)ΒΆ
+

Create PARREC image from filename filename

+
+
Parameters:
+
+
filenamestr

Filename of β€œPAR” or β€œREC” file

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
permit_truncated{False, True}, optional, keyword-only

If False, raise an error for an image where the header shows signs +that fewer slices / volumes were recorded than were expected.

+
+
scaling{β€˜dv’, β€˜fp’}, optional, keyword-only

Scaling method to apply to data (see +PARRECHeader.get_data_scaling()).

+
+
strict_sortbool, optional, keyword-only

If True, a larger number of header fields are used while sorting +the REC data array. This may produce a different sort order than +strict_sort=False, where volumes are sorted by the order in which +the slices appear in the .PAR file.

+
+
+
+
+
+ +
+
+makeable: bool = FalseΒΆ
+
+ +
+
+rw: bool = FalseΒΆ
+
+ +
+
+valid_exts: tuple[str, ...] = ('.rec', '.par')ΒΆ
+
+ +
+ +
+
+

exts2parsΒΆ

+
+
+nibabel.parrec.exts2pars(exts_source)ΒΆ
+

Parse, return any PAR headers from NIfTI extensions in exts_source

+
+
Parameters:
+
+
exts_sourcesequence or Nifti1Image, Nifti1Header instance

A sequence of extensions, or header containing NIfTI extensions, or an +image containing a header with NIfTI extensions.

+
+
+
+
Returns:
+
+
par_headerslist

A list of PARRECHeader objects, usually empty or with one element, each +element contains a PARRECHeader read from the contained extensions.

+
+
+
+
+
+ +
+
+

one_lineΒΆ

+
+
+nibabel.parrec.one_line(long_str)ΒΆ
+

Make maybe mutli-line long_str into one long line

+
+ +
+
+

parse_PAR_headerΒΆ

+
+
+nibabel.parrec.parse_PAR_header(fobj)ΒΆ
+

Parse a PAR header and aggregate all information into useful containers.

+
+
Parameters:
+
+
fobjfile-object

The PAR header file object.

+
+
+
+
Returns:
+
+
general_infodict

Contains all β€œGeneral Information” from the header file

+
+
image_infondarray

Structured array with fields giving all β€œImage information” in the +header

+
+
+
+
+
+ +
+
+

vol_is_fullΒΆ

+
+
+nibabel.parrec.vol_is_full(slice_nos, slice_max, slice_min=1)ΒΆ
+

Vector with True for slices in complete volume, False otherwise

+
+
Parameters:
+
+
slice_nossequence

Sequence of slice numbers, e.g. [1, 2, 3, 4, 1, 2, 3, 4].

+
+
slice_maxint

Highest slice number for a full slice set. Slice set will be +range(slice_min, slice_max+1).

+
+
slice_minint, optional

Lowest slice number for full slice set. Default is 1.

+
+
+
+
Returns:
+
+
is_fullarray

Bool vector with True for slices in full volumes, False for slices in +partial volumes. A full volume is a volume with all slices in the +slice set as defined above.

+
+
+
+
Raises:
+
+
ValueError

if any value in slice_nos is outside slice set indices.

+
+
+
+
+
+ +
+
+

vol_numbersΒΆ

+
+
+nibabel.parrec.vol_numbers(slice_nos)ΒΆ
+

Calculate volume numbers inferred from slice numbers slice_nos

+

The volume number for each slice is the number of times this slice number +has occurred previously in the slice_nos sequence

+
+
Parameters:
+
+
slice_nossequence

Sequence of slice numbers, e.g. [1, 2, 3, 4, 1, 2, 3, 4].

+
+
+
+
Returns:
+
+
vol_noslist

A list, the same length of slice_nos giving the volume number for +each corresponding slice number.

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.pointset.html b/reference/nibabel.pointset.html new file mode 100644 index 0000000000..ebaa0cf769 --- /dev/null +++ b/reference/nibabel.pointset.html @@ -0,0 +1,360 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

pointsetΒΆ

+

Point-set structures

+

Imaging data are sampled at points in space, and these points +can be described by coordinates. +These structures are designed to enable operations on sets of +points, as opposed to the data sampled at those points.

+

Abstractly, a point set is any collection of points, but there are +two types that warrant special consideration in the neuroimaging +context: grids and meshes.

+

A grid is a collection of regularly-spaced points. The canonical +examples of grids are the indices of voxels and their affine +projection into a reference space.

+

A mesh is a collection of points and some structure that enables +adjacent points to be identified. A triangular mesh in particular +uses triplets of adjacent vertices to describe faces.

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

CoordinateArray(*args,Β **kwargs)

Grid(coordinates[,Β affine,Β homogeneous])

A regularly-spaced collection of coordinates

GridIndices(shape[,Β dtype])

Class for generating indices just-in-time

Pointset(coordinates[,Β affine,Β homogeneous])

A collection of points described by coordinates.

+
+

CoordinateArrayΒΆ

+
+
+class nibabel.pointset.CoordinateArray(*args, **kwargs)ΒΆ
+

Bases: Protocol

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+ndim: intΒΆ
+
+ +
+
+shape: tuple[int, int]ΒΆ
+
+ +
+ +
+
+

GridΒΆ

+
+
+class nibabel.pointset.Grid(coordinates: CoordinateArray, affine: ndarray | None = None, homogeneous: bool = False)ΒΆ
+

Bases: Pointset

+

A regularly-spaced collection of coordinates

+

This class provides factory methods for generating Pointsets from +SpatialImages and generating masks +from coordinate sets.

+
+
+__init__(coordinates: CoordinateArray, affine: ndarray | None = None, homogeneous: bool = False)ΒΆ
+
+ +
+
+classmethod from_image(spatialimage: SpatialImage) SelfΒΆ
+
+ +
+
+classmethod from_mask(mask: SpatialImage) SelfΒΆ
+
+ +
+
+to_mask(shape=None) SpatialImageΒΆ
+
+ +
+ +
+
+

GridIndicesΒΆ

+
+
+class nibabel.pointset.GridIndices(shape, dtype=None)ΒΆ
+

Bases: object

+

Class for generating indices just-in-time

+
+
+__init__(shape, dtype=None)ΒΆ
+
+ +
+
+dtypeΒΆ
+
+ +
+
+gridshapeΒΆ
+
+ +
+
+ndim = 2ΒΆ
+
+ +
+
+shapeΒΆ
+
+ +
+ +
+
+

PointsetΒΆ

+
+
+class nibabel.pointset.Pointset(coordinates: CoordinateArray, affine: ndarray | None = None, homogeneous: bool = False)ΒΆ
+

Bases: object

+

A collection of points described by coordinates.

+
+
Parameters:
+
+
coordsarray-like

(N, n) array with N being points and columns their n-dimensional coordinates

+
+
affinenumpy.ndarray

Affine transform to be applied to coordinates array

+
+
homogeneousbool

Indicate whether the provided coordinates are homogeneous, +i.e., homogeneous 3D coordinates have the form (x, y, z, 1)

+
+
+
+
+
+
+__init__(coordinates: CoordinateArray, affine: ndarray | None = None, homogeneous: bool = False)ΒΆ
+
+ +
+
+affine: ndarrayΒΆ
+
+ +
+
+coordinates: CoordinateArrayΒΆ
+
+ +
+
+property dim: intΒΆ
+

The dimensionality of the space the coordinates are in

+
+ +
+
+get_coords(*, as_homogeneous: bool = False)ΒΆ
+

Retrieve the coordinates

+
+
Parameters:
+
+
as_homogeneousbool

Return homogeneous coordinates if True, or Cartesian +coordinates if False.

+
+
namestr

Select a particular coordinate system if more than one may exist. +By default, None is equivalent to β€œworld” and corresponds to +an RAS+ coordinate system.

+
+
+
+
+
+ +
+
+homogeneous: bool = FalseΒΆ
+
+ +
+
+property n_coords: intΒΆ
+

Number of coordinates

+

Subclasses should override with more efficient implementations.

+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.processing.html b/reference/nibabel.processing.html new file mode 100644 index 0000000000..8f95e06276 --- /dev/null +++ b/reference/nibabel.processing.html @@ -0,0 +1,477 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

processingΒΆ

+

Image processing functions

+

Image processing functions for:

+
+
    +
  • smoothing

  • +
  • resampling

  • +
  • converting SD to and from FWHM

  • +
+
+

Smoothing and resampling routines need scipy.

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

adapt_affine(affine,Β n_dim)

Adapt input / output dimensions of spatial affine for n_dims

conform(from_img[,Β out_shape,Β voxel_size,Β ...])

Resample image to out_shape with voxels of size voxel_size.

fwhm2sigma(fwhm)

Convert a FWHM value to sigma in a Gaussian kernel.

resample_from_to(from_img,Β to_vox_map[,Β ...])

Resample image from_img to mapped voxel space to_vox_map

resample_to_output(in_img[,Β voxel_sizes,Β ...])

Resample image in_img to output voxel axes (world space)

sigma2fwhm(sigma)

Convert a sigma in a Gaussian kernel to a FWHM value

smooth_image(img,Β fwhm[,Β mode,Β cval,Β out_class])

Smooth image img along voxel axes by FWHM fwhm millimeters

+
+

adapt_affineΒΆ

+
+
+nibabel.processing.adapt_affine(affine, n_dim)ΒΆ
+

Adapt input / output dimensions of spatial affine for n_dims

+

Adapts a spatial (4, 4) affine that is being applied to an image with fewer +than 3 spatial dimensions, or more than 3 dimensions. If there are more +than three dimensions, assume an identity transformation for these +dimensions.

+
+
Parameters:
+
+
affinearray-like

affine transform. Usually shape (4, 4). For what follows N, M = +affine.shape

+
+
n_dimsint

Number of dimensions of underlying array, and therefore number of input +dimensions for affine.

+
+
+
+
Returns:
+
+
adaptedshape (M, n_dims+1) array

Affine array adapted to number of input dimensions. Columns of the +affine corresponding to missing input dimensions have been dropped, +columns corresponding to extra input dimensions have an extra identity +column added

+
+
+
+
+
+ +
+
+

conformΒΆ

+
+
+nibabel.processing.conform(from_img, out_shape=(256, 256, 256), voxel_size=(1.0, 1.0, 1.0), order=3, cval=0.0, orientation='RAS', out_class=None)ΒΆ
+

Resample image to out_shape with voxels of size voxel_size.

+

Using the default arguments, this function is meant to replicate most parts +of FreeSurfer’s mri_convert --conform command. Specifically, this +function:

+
+
    +
  • Resamples data to output_shape

  • +
  • Resamples voxel sizes to voxel_size

  • +
  • Reorients to RAS (mri_convert --conform reorients to LIA)

  • +
+
+

Unlike mri_convert --conform, this command does not:

+
+
    +
  • Transform data to range [0, 255]

  • +
  • Cast to unsigned eight-bit integer

  • +
+
+
+
Parameters:
+
+
from_imgobject

Object having attributes dataobj, affine, header and +shape. If out_class is not None, img.__class__ should be able +to construct an image from data, affine and header.

+
+
out_shapesequence, optional

The shape of the output volume. Default is (256, 256, 256).

+
+
voxel_sizesequence, optional

The size in millimeters of the voxels in the resampled output. Default +is 1mm isotropic.

+
+
orderint, optional

The order of the spline interpolation, default is 3. The order has to +be in the range 0-5 (see scipy.ndimage.affine_transform)

+
+
cvalscalar, optional

Value used for points outside the boundaries of the input if +mode='constant'. Default is 0.0 (see +scipy.ndimage.affine_transform)

+
+
orientationstr, optional

Orientation of output image. Default is β€œRAS”.

+
+
out_classNone or SpatialImage class, optional

Class of output image. If None, use from_img.__class__.

+
+
+
+
Returns:
+
+
out_imgobject

Image of instance specified by out_class, containing data output from +resampling from_img into axes aligned to the output space of +from_img.affine

+
+
+
+
+
+ +
+
+

fwhm2sigmaΒΆ

+
+
+nibabel.processing.fwhm2sigma(fwhm)ΒΆ
+

Convert a FWHM value to sigma in a Gaussian kernel.

+
+
Parameters:
+
+
fwhmarray-like

FWHM value or values

+
+
+
+
Returns:
+
+
sigmaarray or float

sigma values corresponding to fwhm values

+
+
+
+
+

Examples

+
>>> sigma = fwhm2sigma(6)
+>>> sigmae = fwhm2sigma([6, 7, 8])
+>>> sigma == sigmae[0]
+True
+
+
+
+ +
+
+

resample_from_toΒΆ

+
+
+nibabel.processing.resample_from_to(from_img, to_vox_map, order=3, mode='constant', cval=0.0, out_class=<class 'nibabel.nifti1.Nifti1Image'>)ΒΆ
+

Resample image from_img to mapped voxel space to_vox_map

+

Resample using N-d spline interpolation.

+
+
Parameters:
+
+
from_imgobject

Object having attributes dataobj, affine, header and +shape. If out_class is not None, img.__class__ should be able +to construct an image from data, affine and header.

+
+
to_vox_mapimage object or length 2 sequence

If object, has attributes shape giving input voxel shape, and +affine giving mapping of input voxels to output space. If length 2 +sequence, elements are (shape, affine) with same meaning as above. The +affine is a (4, 4) array-like.

+
+
orderint, optional

The order of the spline interpolation, default is 3. The order has to +be in the range 0-5 (see scipy.ndimage.affine_transform)

+
+
modestr, optional

Points outside the boundaries of the input are filled according +to the given mode (β€˜constant’, β€˜nearest’, β€˜reflect’ or β€˜wrap’). +Default is β€˜constant’ (see scipy.ndimage.affine_transform)

+
+
cvalscalar, optional

Value used for points outside the boundaries of the input if +mode='constant'. Default is 0.0 (see +scipy.ndimage.affine_transform)

+
+
out_classNone or SpatialImage class, optional

Class of output image. If None, use from_img.__class__.

+
+
+
+
Returns:
+
+
out_imgobject

Image of instance specified by out_class, containing data output from +resampling from_img into axes aligned to the output space of +from_img.affine

+
+
+
+
+
+ +
+
+

resample_to_outputΒΆ

+
+
+nibabel.processing.resample_to_output(in_img, voxel_sizes=None, order=3, mode='constant', cval=0.0, out_class=<class 'nibabel.nifti1.Nifti1Image'>)ΒΆ
+

Resample image in_img to output voxel axes (world space)

+
+
Parameters:
+
+
in_imgobject

Object having attributes dataobj, affine, header. If +out_class is not None, img.__class__ should be able to construct +an image from data, affine and header.

+
+
voxel_sizesNone or sequence

Gives the diagonal entries of out_img.affine` (except the trailing 1 +for the homogeneous coordinates) (``out_img.affine == +np.diag(voxel_sizes + [1])). If None, return identity +out_img.affine. If scalar, interpret as vector [voxel_sizes] * +len(in_img.shape).

+
+
orderint, optional

The order of the spline interpolation, default is 3. The order has to +be in the range 0-5 (see scipy.ndimage.affine_transform).

+
+
modestr, optional

Points outside the boundaries of the input are filled according to the +given mode (β€˜constant’, β€˜nearest’, β€˜reflect’ or β€˜wrap’). Default is +β€˜constant’ (see scipy.ndimage.affine_transform).

+
+
cvalscalar, optional

Value used for points outside the boundaries of the input if +mode='constant'. Default is 0.0 (see +scipy.ndimage.affine_transform).

+
+
out_classNone or SpatialImage class, optional

Class of output image. If None, use in_img.__class__.

+
+
+
+
Returns:
+
+
out_imgobject

Image of instance specified by out_class, containing data output from +resampling in_img into axes aligned to the output space of +in_img.affine

+
+
+
+
+
+ +
+
+

sigma2fwhmΒΆ

+
+
+nibabel.processing.sigma2fwhm(sigma)ΒΆ
+

Convert a sigma in a Gaussian kernel to a FWHM value

+
+
Parameters:
+
+
sigmaarray-like

sigma value or values

+
+
+
+
Returns:
+
+
fwhmarray or float

fwhm values corresponding to sigma values

+
+
+
+
+

Examples

+
>>> fwhm = sigma2fwhm(3)
+>>> fwhms = sigma2fwhm([3, 4, 5])
+>>> fwhm == fwhms[0]
+True
+
+
+
+ +
+
+

smooth_imageΒΆ

+
+
+nibabel.processing.smooth_image(img, fwhm, mode='nearest', cval=0.0, out_class=<class 'nibabel.nifti1.Nifti1Image'>)ΒΆ
+

Smooth image img along voxel axes by FWHM fwhm millimeters

+
+
Parameters:
+
+
imgobject

Object having attributes dataobj, affine, header and +shape. If out_class is not None, img.__class__ should be able +to construct an image from data, affine and header.

+
+
fwhmscalar or length 3 sequence

FWHM in mm over which to smooth. The smoothing applies to the voxel +axes, not to the output axes, but is in millimeters. The function +adjusts the FWHM to voxels using the voxel sizes calculated from the +affine. A scalar implies the same smoothing across the spatial +dimensions of the image, but 0 smoothing over any further dimensions +such as time. A vector should be the same length as the number of +image dimensions.

+
+
modestr, optional

Points outside the boundaries of the input are filled according +to the given mode (β€˜constant’, β€˜nearest’, β€˜reflect’ or β€˜wrap’). +Default is β€˜nearest’. This is different from the default for +scipy.ndimage.affine_transform, which is β€˜constant’. β€˜nearest’ +might be a better choice when smoothing to the edge of an image where +there is still strong brain signal, otherwise this signal will get +blurred towards zero.

+
+
cvalscalar, optional

Value used for points outside the boundaries of the input if +mode='constant'. Default is 0.0 (see +scipy.ndimage.affine_transform).

+
+
out_classNone or SpatialImage class, optional

Class of output image. If None, use img.__class__.

+
+
+
+
Returns:
+
+
smoothed_imgobject

Image of instance specified by out_class, containing data output from +smoothing img data by given FWHM kernel.

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.pydicom_compat.html b/reference/nibabel.pydicom_compat.html new file mode 100644 index 0000000000..5b2e138a13 --- /dev/null +++ b/reference/nibabel.pydicom_compat.html @@ -0,0 +1,162 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

pydicom_compatΒΆ

+

Adapter module for working with pydicom < 1.0 and >= 1.0

+

In what follows, β€œdicom is available” means we can import either a) dicom +(pydicom < 1.0) or or b) pydicom (pydicom >= 1.0).

+

Regardless of whether dicom is available this module should be importable +without error, and always defines:

+
    +
  • have_dicom : True if we can import pydicom or dicom;

  • +
  • pydicom : pydicom module or dicom module or None if not importable;

  • +
  • read_file : read_file function if pydicom or dicom module is importable +else None;

  • +
  • tag_for_keyword : tag_for_keyword function if pydicom or dicom module +is importable else None;

  • +
+

A test decorator is available in nibabel.nicom.tests:

+
    +
  • dicom_test : test decorator that skips test if dicom not available.

  • +
+

A deprecated copy is available here for backward compatibility.

+ + + + + + +

dicom_test(func)

dicom_test has been moved to nibabel.nicom.tests

+
+

dicom_testΒΆ

+
+
+nibabel.pydicom_compat.dicom_test(func)ΒΆ
+

dicom_test has been moved to nibabel.nicom.tests

+
    +
  • deprecated from version: 3.1

  • +
  • Raises <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 5.0

  • +
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.quaternions.html b/reference/nibabel.quaternions.html new file mode 100644 index 0000000000..d2744a1d43 --- /dev/null +++ b/reference/nibabel.quaternions.html @@ -0,0 +1,665 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

quaternionsΒΆ

+

Functions to operate on, or return, quaternions

+

The module also includes functions for the closely related angle, axis +pair as a specification for rotation.

+

Quaternions here consist of 4 values w, x, y, z, where w is the +real (scalar) part, and x, y, z are the complex (vector) part.

+

Note - rotation matrices here apply to column vectors, that is, +they are applied on the left of the vector. For example:

+
>>> import numpy as np
+>>> from nibabel.quaternions import quat2mat
+>>> q = [0, 1, 0, 0] # 180 degree rotation around axis 0
+>>> M = quat2mat(q) # from this module
+>>> vec = np.array([1, 2, 3]).reshape((3,1)) # column vector
+>>> tvec = np.dot(M, vec)
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

angle_axis2mat(theta,Β vector[,Β is_normalized])

Rotation matrix of angle theta around vector

angle_axis2quat(theta,Β vector[,Β is_normalized])

Quaternion for rotation of angle theta around vector

conjugate(q)

Conjugate of quaternion

eye()

Return identity quaternion

fillpositive(xyz[,Β w2_thresh])

Compute unit quaternion from last 3 values

inverse(q)

Return multiplicative inverse of quaternion q

isunit(q)

Return True is this is very nearly a unit quaternion

mat2quat(M)

Calculate quaternion corresponding to given rotation matrix

mult(q1,Β q2)

Multiply two quaternions

nearly_equivalent(q1,Β q2[,Β rtol,Β atol])

Returns True if q1 and q2 give near equivalent transforms

norm(q)

Return norm of quaternion

quat2angle_axis(quat[,Β identity_thresh])

Convert quaternion to rotation of angle around axis

quat2mat(q)

Calculate rotation matrix corresponding to quaternion

rotate_vector(v,Β q)

Apply transformation in quaternion q to vector v

+
+

angle_axis2matΒΆ

+
+
+nibabel.quaternions.angle_axis2mat(theta, vector, is_normalized=False)ΒΆ
+

Rotation matrix of angle theta around vector

+
+
Parameters:
+
+
thetascalar

angle of rotation

+
+
vector3 element sequence

vector specifying axis for rotation.

+
+
is_normalizedbool, optional

True if vector is already normalized (has norm of 1). Default +False

+
+
+
+
Returns:
+
+
matarray shape (3,3)

rotation matrix for specified rotation

+
+
+
+
+

Notes

+

From: https://en.wikipedia.org/wiki/Rotation_matrix#Axis_and_angle

+
+ +
+
+

angle_axis2quatΒΆ

+
+
+nibabel.quaternions.angle_axis2quat(theta, vector, is_normalized=False)ΒΆ
+

Quaternion for rotation of angle theta around vector

+
+
Parameters:
+
+
thetascalar

angle of rotation

+
+
vector3 element sequence

vector specifying axis for rotation.

+
+
is_normalizedbool, optional

True if vector is already normalized (has norm of 1). Default +False

+
+
+
+
Returns:
+
+
quat4 element sequence of symbols

quaternion giving specified rotation

+
+
+
+
+

Notes

+

Formula from http://mathworld.wolfram.com/EulerParameters.html

+

Examples

+
>>> q = angle_axis2quat(np.pi, [1, 0, 0])
+>>> np.allclose(q, [0, 1, 0,  0])
+True
+
+
+
+ +
+
+

conjugateΒΆ

+
+
+nibabel.quaternions.conjugate(q)ΒΆ
+

Conjugate of quaternion

+
+
Parameters:
+
+
q4 element sequence

w, i, j, k of quaternion

+
+
+
+
Returns:
+
+
conjqarray shape (4,)

w, i, j, k of conjugate of q

+
+
+
+
+
+ +
+
+

eyeΒΆ

+
+
+nibabel.quaternions.eye()ΒΆ
+

Return identity quaternion

+
+ +
+
+

fillpositiveΒΆ

+
+
+nibabel.quaternions.fillpositive(xyz, w2_thresh=None)ΒΆ
+

Compute unit quaternion from last 3 values

+
+
Parameters:
+
+
xyziterable

iterable containing 3 values, corresponding to quaternion x, y, z

+
+
w2_threshNone or float, optional

threshold to determine if w squared is non-zero. +If None (default) then w2_thresh set equal to +3 * np.finfo(xyz.dtype).eps, if possible, otherwise +3 * np.finfo(np.float64).eps

+
+
+
+
Returns:
+
+
wxyzarray shape (4,)

Full 4 values of quaternion

+
+
+
+
+

Notes

+

If w, x, y, z are the values in the full quaternion, assumes w is +positive.

+

Gives error if w*w is estimated to be negative

+

w = 0 corresponds to a 180 degree rotation

+

The unit quaternion specifies that np.dot(wxyz, wxyz) == 1.

+

If w is positive (assumed here), w is given by:

+

w = np.sqrt(1.0-(x*x+y*y+z*z))

+

w2 = 1.0-(x*x+y*y+z*z) can be near zero, which will lead to +numerical instability in sqrt. Here we use the system maximum +float type to reduce numerical instability

+

Examples

+
>>> import numpy as np
+>>> wxyz = fillpositive([0,0,0])
+>>> np.all(wxyz == [1, 0, 0, 0])
+True
+>>> wxyz = fillpositive([1,0,0]) # Corner case; w is 0
+>>> np.all(wxyz == [0, 1, 0, 0])
+True
+>>> np.dot(wxyz, wxyz)
+1.0
+
+
+
+ +
+
+

inverseΒΆ

+
+
+nibabel.quaternions.inverse(q)ΒΆ
+

Return multiplicative inverse of quaternion q

+
+
Parameters:
+
+
q4 element sequence

w, i, j, k of quaternion

+
+
+
+
Returns:
+
+
invqarray shape (4,)

w, i, j, k of quaternion inverse

+
+
+
+
+
+ +
+
+

isunitΒΆ

+
+
+nibabel.quaternions.isunit(q)ΒΆ
+

Return True is this is very nearly a unit quaternion

+
+ +
+
+

mat2quatΒΆ

+
+
+nibabel.quaternions.mat2quat(M)ΒΆ
+

Calculate quaternion corresponding to given rotation matrix

+
+
Parameters:
+
+
Marray-like

3x3 rotation matrix

+
+
+
+
Returns:
+
+
q(4,) array

closest quaternion to input matrix, having positive q[0]

+
+
+
+
+

Notes

+

Method claimed to be robust to numerical errors in M

+

Constructs quaternion by calculating maximum eigenvector for matrix +K (constructed from input M). Although this is not tested, a +maximum eigenvalue of 1 corresponds to a valid rotation.

+

A quaternion q*-1 corresponds to the same rotation as q; thus the +sign of the reconstructed quaternion is arbitrary, and we return +quaternions with positive w (q[0]).

+

References

+ +

Examples

+
>>> import numpy as np
+>>> q = mat2quat(np.eye(3)) # Identity rotation
+>>> np.allclose(q, [1, 0, 0, 0])
+True
+>>> q = mat2quat(np.diag([1, -1, -1]))
+>>> np.allclose(q, [0, 1, 0, 0]) # 180 degree rotn around axis 0
+True
+
+
+
+ +
+
+

multΒΆ

+
+
+nibabel.quaternions.mult(q1, q2)ΒΆ
+

Multiply two quaternions

+
+
Parameters:
+
+
q14 element sequence
+
q24 element sequence
+
+
+
Returns:
+
+
q12shape (4,) array
+
+
+
+

Notes

+

See : https://en.wikipedia.org/wiki/Quaternions#Hamilton_product

+
+ +
+
+

nearly_equivalentΒΆ

+
+
+nibabel.quaternions.nearly_equivalent(q1, q2, rtol=1e-05, atol=1e-08)ΒΆ
+

Returns True if q1 and q2 give near equivalent transforms

+

q1 may be nearly numerically equal to q2, or nearly equal to q2 * -1 +(because a quaternion multiplied by -1 gives the same transform).

+
+
Parameters:
+
+
q14 element sequence

w, x, y, z of first quaternion

+
+
q24 element sequence

w, x, y, z of second quaternion

+
+
+
+
Returns:
+
+
equivbool

True if q1 and q2 are nearly equivalent, False otherwise

+
+
+
+
+

Examples

+
>>> q1 = [1, 0, 0, 0]
+>>> nearly_equivalent(q1, [0, 1, 0, 0])
+False
+>>> nearly_equivalent(q1, [1, 0, 0, 0])
+True
+>>> nearly_equivalent(q1, [-1, 0, 0, 0])
+True
+
+
+
+ +
+
+

normΒΆ

+
+
+nibabel.quaternions.norm(q)ΒΆ
+

Return norm of quaternion

+
+
Parameters:
+
+
q4 element sequence

w, i, j, k of quaternion

+
+
+
+
Returns:
+
+
nscalar

quaternion norm

+
+
+
+
+
+ +
+
+

quat2angle_axisΒΆ

+
+
+nibabel.quaternions.quat2angle_axis(quat, identity_thresh=None)ΒΆ
+

Convert quaternion to rotation of angle around axis

+
+
Parameters:
+
+
quat4 element sequence

w, x, y, z forming quaternion

+
+
identity_threshNone or scalar, optional

threshold below which the norm of the vector part of the +quaternion (x, y, z) is deemed to be 0, leading to the identity +rotation. None (the default) leads to a threshold estimated +based on the precision of the input.

+
+
+
+
Returns:
+
+
thetascalar

angle of rotation

+
+
vectorarray shape (3,)

axis around which rotation occurs

+
+
+
+
+

Notes

+

A quaternion for which x, y, z are all equal to 0, is an identity +rotation. In this case we return a 0 angle and an arbitrary +vector, here [1, 0, 0]

+

Examples

+
>>> theta, vec = quat2angle_axis([0, 1, 0, 0])
+>>> np.allclose(theta, np.pi)
+True
+>>> vec
+array([1., 0., 0.])
+
+
+

If this is an identity rotation, we return a zero angle and an +arbitrary vector

+
>>> quat2angle_axis([1, 0, 0, 0])
+(0.0, array([1., 0., 0.]))
+
+
+
+ +
+
+

quat2matΒΆ

+
+
+nibabel.quaternions.quat2mat(q)ΒΆ
+

Calculate rotation matrix corresponding to quaternion

+
+
Parameters:
+
+
q4 element array-like
+
+
+
Returns:
+
+
M(3,3) array

Rotation matrix corresponding to input quaternion q

+
+
+
+
+

Notes

+

Rotation matrix applies to column vectors, and is applied to the +left of coordinate vectors. The algorithm here allows non-unit +quaternions.

+

References

+

Algorithm from +https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion

+

Examples

+
>>> import numpy as np
+>>> M = quat2mat([1, 0, 0, 0]) # Identity quaternion
+>>> np.allclose(M, np.eye(3))
+True
+>>> M = quat2mat([0, 1, 0, 0]) # 180 degree rotn around axis 0
+>>> np.allclose(M, np.diag([1, -1, -1]))
+True
+
+
+
+ +
+
+

rotate_vectorΒΆ

+
+
+nibabel.quaternions.rotate_vector(v, q)ΒΆ
+

Apply transformation in quaternion q to vector v

+
+
Parameters:
+
+
v3 element sequence

3 dimensional vector

+
+
q4 element sequence

w, i, j, k of quaternion

+
+
+
+
Returns:
+
+
vdasharray shape (3,)

v rotated by quaternion q

+
+
+
+
+

Notes

+

See: +https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Describing_rotations_with_quaternions

+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.rstutils.html b/reference/nibabel.rstutils.html new file mode 100644 index 0000000000..73ddf91f12 --- /dev/null +++ b/reference/nibabel.rstutils.html @@ -0,0 +1,174 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

rstutilsΒΆ

+

ReStructured Text utilities

+
    +
  • Make ReST table given array of values

  • +
+ + + + + + +

rst_table(cell_values[,Β row_names,Β ...])

Return string for ReST table with entries cell_values

+
+

rst_tableΒΆ

+
+
+nibabel.rstutils.rst_table(cell_values, row_names=None, col_names=None, title='', val_fmt='{0:5.2f}', format_chars=None)ΒΆ
+

Return string for ReST table with entries cell_values

+
+
Parameters:
+
+
cell_values(R, C) array-like

At least 2D. Can be greater than 2D, in which case you should adapt +the val_fmt to deal with the multiple entries that will go in each +cell

+
+
row_namesNone or (R,) length sequence, optional

Row names. If None, use row[0] etc.

+
+
col_namesNone or (C,) length sequence, optional

Column names. If None, use col[0] etc.

+
+
titlestr, optional

Title for table. Add as heading above table

+
+
val_fmtstr, optional

Format string using string format method mini-language. Converts +the result of cell_values[r, c] to a string to make the cell +contents. Default assumes a floating point value in a 2D cell_values.

+
+
format_charsNone or dict, optional

With keys β€˜down’, β€˜along’, β€˜thick_long’, β€˜cross’ and β€˜title_heading’. +Values are characters for: lines going down; lines going along; thick +lines along; two lines crossing; and the title overline / underline. +All missing values filled with rst defaults.

+
+
+
+
Returns:
+
+
table_strstr

Multiline string with ascii table, suitable for printing

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.spaces.html b/reference/nibabel.spaces.html new file mode 100644 index 0000000000..b3ad1f6e34 --- /dev/null +++ b/reference/nibabel.spaces.html @@ -0,0 +1,238 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

spacesΒΆ

+

Routines to work with spaces

+

A space is defined by coordinate axes.

+

A voxel space can be expressed by a shape implying an array, where the axes are +the axes of the array.

+

A mapped voxel space (mapped voxels) is either:

+
    +
  • an image, with attributes shape (the voxel space) and affine (the +mapping), or

  • +
  • a length 2 sequence with the same information (shape, affine).

  • +
+ + + + + + + + + +

slice2volume(index,Β axis[,Β shape])

Affine expressing selection of a single slice from 3D volume

vox2out_vox(mapped_voxels[,Β voxel_sizes])

output-aligned shape, affine for input implied by mapped_voxels

+
+

slice2volumeΒΆ

+
+
+nibabel.spaces.slice2volume(index, axis, shape=None)ΒΆ
+

Affine expressing selection of a single slice from 3D volume

+

Imagine we have taken a slice from an image data array, s = data[:, :, +index]. This function returns the affine to map the array coordinates of +s to the array coordinates of data.

+

This can be useful for resampling a single slice from a volume. For +example, to resample slice k in the space of img1 from the matching +spatial voxel values in img2, you might do something like:

+
slice_shape = img1.shape[:2]
+slice_aff = slice2volume(k, 2)
+whole_aff = np.linalg.inv(img2.affine).dot(img1.affine.dot(slice_aff))
+
+
+

and then use whole_aff in scipy.ndimage.affine_transform:

+
+

rzs, trans = to_matvec(whole_aff) +data = img2.get_fdata() +new_slice = scipy.ndimage.affine_transform(data, rzs, trans, slice_shape)

+
+
+
Parameters:
+
+
indexint

index of selected slice

+
+
axis{0, 1, 2}

axis to which index applies

+
+
+
+
Returns:
+
+
slice_affshape (4, 3) affine

Affine relating input coordinates in a slice to output coordinates in +the embedded volume

+
+
+
+
+
+ +
+
+

vox2out_voxΒΆ

+
+
+nibabel.spaces.vox2out_vox(mapped_voxels, voxel_sizes=None)ΒΆ
+

output-aligned shape, affine for input implied by mapped_voxels

+

The input (voxel) space, and the affine mapping to output space, are given +in mapped_voxels.

+

The output space is implied by the affine, we don’t need to know what that +is, we just return something with the same (implied) output space.

+

Our job is to work out another voxel space where the voxel array axes and +the output axes are aligned (top left 3 x 3 of affine is diagonal with all +positive entries) and which contains all the voxels of the implied input +image at their correct output space positions, once resampled into the +output voxel space.

+
+
Parameters:
+
+
mapped_voxelsobject or length 2 sequence

If object, has attributes shape giving input voxel shape, and +affine giving mapping of input voxels to output space. If length 2 +sequence, elements are (shape, affine) with same meaning as above. The +affine is a (4, 4) array-like.

+
+
voxel_sizesNone or sequence

Gives the diagonal entries of output_affine (except the trailing 1 +for the homogeneous coordinates) (output_affine == np.diag(voxel_sizes ++ [1])). If None, return identity output_affine.

+
+
+
+
Returns:
+
+
output_shapesequence

Shape of output image that has voxel axes aligned to original image +output space axes, and encloses all the voxel data from the original +image implied by input shape.

+
+
output_affine(4, 4) array

Affine of output image that has voxel axes aligned to the output axes +implied by input affine. Top-left 3 x 3 part of affine is diagonal with +all positive entries. The entries come from voxel_sizes if +specified, or are all 1. If the image is < 3D, then the missing +dimensions will have a 1 in the matching diagonal.

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.spatialimages.html b/reference/nibabel.spatialimages.html new file mode 100644 index 0000000000..908cfe0d1a --- /dev/null +++ b/reference/nibabel.spatialimages.html @@ -0,0 +1,852 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

spatialimagesΒΆ

+

A simple spatial image class

+

The image class maintains the association between a 3D (or greater) +array, and an affine transform that maps voxel coordinates to some world space. +It also has a header - some standard set of meta-data that is specific to +the image format, and extra - a dictionary container for any other +metadata.

+

It has attributes:

+
+
    +
  • extra

  • +
+
+

methods:

+
+
    +
  • .get_fdata()

  • +
  • .to_filename(fname) - writes data to filename(s) derived from +fname, where the derivation may differ between formats.

  • +
  • to_file_map() - save image to files with which the image is already +associated.

  • +
+
+

properties:

+
+
    +
  • shape

  • +
  • affine

  • +
  • header

  • +
  • dataobj

  • +
+
+

classmethods:

+
+
    +
  • from_filename(fname) - make instance by loading from filename

  • +
  • from_file_map(fmap) - make instance from file map

  • +
  • instance_to_filename(img, fname) - save img instance to +filename fname.

  • +
+
+

You cannot slice an image, and trying to slice an image generates an +informative TypeError.

+
+

There are several ways of writing data.ΒΆ

+

There is the usual way, which is the default:

+
img.to_filename(fname)
+
+
+

and that is, to take the data encapsulated by the image and cast it to +the datatype the header expects, setting any available header scaling +into the header to help the data match.

+

You can load the data into an image from file with:

+
img.from_filename(fname)
+
+
+

The image stores its associated files in its file_map attribute. In order +to just save an image, for which you know there is an associated filename, or +other storage, you can do:

+
img.to_file_map()
+
+
+

You can get the data out again with:

+
img.get_fdata()
+
+
+

Less commonly, for some image types that support it, you might want to +fetch out the unscaled array via the object containing the data:

+
unscaled_data = img.dataoobj.get_unscaled()
+
+
+

Analyze-type images (including nifti) support this, but others may not +(MINC, for example).

+

Sometimes you might to avoid any loss of precision by making the +data type the same as the input:

+
hdr = img.header
+hdr.set_data_dtype(data.dtype)
+img.to_filename(fname)
+
+
+
+
+

Files interfaceΒΆ

+

The image has an attribute file_map. This is a mapping, that has keys +corresponding to the file types that an image needs for storage. For +example, the Analyze data format needs an image and a header +file type for storage:

+
>>> import numpy as np
+>>> import nibabel as nib
+>>> data = np.arange(24, dtype='f4').reshape((2,3,4))
+>>> img = nib.AnalyzeImage(data, np.eye(4))
+>>> sorted(img.file_map)
+['header', 'image']
+
+
+

The values of file_map are not in fact files but objects with +attributes filename, fileobj and pos.

+

The reason for this interface, is that the contents of files has to +contain enough information so that an existing image instance can save +itself back to the files pointed to in file_map. When a file holder +holds active file-like objects, then these may be affected by the +initial file read; in this case, the contains file-like objects need to +carry the position at which a write (with to_file_map) should place the +data. The file_map contents should therefore be such, that this will +work:

+
>>> # write an image to files
+>>> from io import BytesIO
+>>> import nibabel as nib
+>>> file_map = nib.AnalyzeImage.make_file_map()
+>>> file_map['image'].fileobj = BytesIO()
+>>> file_map['header'].fileobj = BytesIO()
+>>> img = nib.AnalyzeImage(data, np.eye(4))
+>>> img.file_map = file_map
+>>> img.to_file_map()
+>>> # read it back again from the written files
+>>> img2 = nib.AnalyzeImage.from_file_map(file_map)
+>>> np.all(img2.get_fdata(dtype=np.float32) == data)
+True
+>>> # write, read it again
+>>> img2.to_file_map()
+>>> img3 = nib.AnalyzeImage.from_file_map(file_map)
+>>> np.all(img3.get_fdata(dtype=np.float32) == data)
+True
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

HasDtype(*args,Β **kwargs)

HeaderDataError

Class to indicate error in getting or setting header data

HeaderTypeError

Class to indicate error in parameters into header functions

ImageDataError

SpatialFirstSlicer(img)

Slicing interface that returns a new image with an updated affine

SpatialHeader(data_dtype,Β shape,Β zooms)

Template class to implement header protocol

SpatialImage(dataobj,Β affine[,Β header,Β ...])

Template class for volumetric (3D/4D) images

SpatialProtocol(*args,Β **kwargs)

supported_np_types(obj)

Numpy data types that instance obj supports

+
+

HasDtypeΒΆ

+
+
+class nibabel.spatialimages.HasDtype(*args, **kwargs)ΒΆ
+

Bases: Protocol

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+get_data_dtype() dtypeΒΆ
+
+ +
+
+set_data_dtype(dtype: npt.DTypeLike) NoneΒΆ
+
+ +
+ +
+
+

HeaderDataErrorΒΆ

+
+
+class nibabel.spatialimages.HeaderDataErrorΒΆ
+

Bases: Exception

+

Class to indicate error in getting or setting header data

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

HeaderTypeErrorΒΆ

+
+
+class nibabel.spatialimages.HeaderTypeErrorΒΆ
+

Bases: Exception

+

Class to indicate error in parameters into header functions

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

ImageDataErrorΒΆ

+
+
+class nibabel.spatialimages.ImageDataErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

SpatialFirstSlicerΒΆ

+
+
+class nibabel.spatialimages.SpatialFirstSlicer(img: SpatialImgT)ΒΆ
+

Bases: Generic[SpatialImgT]

+

Slicing interface that returns a new image with an updated affine

+

Checks that an image’s first three axes are spatial

+
+
+__init__(img: SpatialImgT)ΒΆ
+
+ +
+
+check_slicing(slicer: object, return_spatial: bool = False) tuple[slice | int | None, ...]ΒΆ
+

Canonicalize slicers and check for scalar indices in spatial dims

+
+
Parameters:
+
+
slicerobject

something that can be used to slice an array as in +arr[sliceobj]

+
+
return_spatialbool

return only slices along spatial dimensions (x, y, z)

+
+
+
+
Returns:
+
+
slicerobject

Validated slicer object that will slice image’s dataobj +without collapsing spatial dimensions

+
+
+
+
+
+ +
+
+img: SpatialImgTΒΆ
+
+ +
+
+slice_affine(slicer: object) ndarrayΒΆ
+

Retrieve affine for current image, if sliced by a given index

+

Applies scaling if down-sampling is applied, and adjusts the intercept +to account for any cropping.

+
+
Parameters:
+
+
slicerobject

something that can be used to slice an array as in +arr[sliceobj]

+
+
+
+
Returns:
+
+
affine(4,4) ndarray

Affine with updated scale and intercept

+
+
+
+
+
+ +
+ +
+
+

SpatialHeaderΒΆ

+
+
+class nibabel.spatialimages.SpatialHeader(data_dtype: npt.DTypeLike = <class 'numpy.float32'>, shape: Sequence[int] = (0, ), zooms: Sequence[float] | None = None)ΒΆ
+

Bases: FileBasedHeader, SpatialProtocol

+

Template class to implement header protocol

+
+
+__init__(data_dtype: npt.DTypeLike = <class 'numpy.float32'>, shape: Sequence[int] = (0, ), zooms: Sequence[float] | None = None)ΒΆ
+
+ +
+
+copy() SpatialHdrTΒΆ
+

Copy object to independent representation

+

The copy should not be affected by any changes to the original +object.

+
+ +
+
+data_from_fileobj(fileobj: IOBase) ndarrayΒΆ
+

Read binary image data from fileobj

+
+ +
+
+data_layout: Literal['F', 'C'] = 'F'ΒΆ
+
+ +
+
+data_to_fileobj(data: npt.ArrayLike, fileobj: io.IOBase, rescale: bool = True)ΒΆ
+

Write array data data as binary to fileobj

+
+
Parameters:
+
+
dataarray-like

data to write

+
+
fileobjfile-like object

file-like object implementing β€˜write’

+
+
rescale{True, False}, optional

Whether to try and rescale data to match output dtype specified by +header. For this minimal header, rescale has no effect

+
+
+
+
+
+ +
+
+default_x_flip: bool = TrueΒΆ
+
+ +
+
+classmethod from_header(header: SpatialProtocol | FileBasedHeader | Mapping | None = None) SpatialHdrTΒΆ
+
+ +
+
+get_base_affine() ndarrayΒΆ
+
+ +
+
+get_best_affine() ndarrayΒΆ
+
+ +
+
+get_data_dtype() dtypeΒΆ
+
+ +
+
+get_data_shape() tuple[int, ...]ΒΆ
+
+ +
+
+get_zooms() tuple[float, ...]ΒΆ
+
+ +
+
+set_data_dtype(dtype: npt.DTypeLike) NoneΒΆ
+
+ +
+
+set_data_shape(shape: Sequence[int]) NoneΒΆ
+
+ +
+
+set_zooms(zooms: Sequence[float]) NoneΒΆ
+
+ +
+ +
+
+

SpatialImageΒΆ

+
+
+class nibabel.spatialimages.SpatialImage(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Bases: DataobjImage

+

Template class for volumetric (3D/4D) images

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj: ArrayLike, affine: ndarray | None, header: FileBasedHeader | Mapping | None = None, extra: Mapping | None = None, file_map: Mapping[str, FileHolder] | None = None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+ImageSlicerΒΆ
+

alias of SpatialFirstSlicer

+
+ +
+
+property affineΒΆ
+
+ +
+
+as_reoriented(ornt: Sequence[Sequence[int]]) SpatialImgTΒΆ
+

Apply an orientation change and return a new image

+

If ornt is identity transform, return the original image, unchanged

+
+
Parameters:
+
+
ornt(n,2) orientation array

orientation transform. ornt[N,1]` is flip of axis N of the +array implied by `shape`, where 1 means no flip and -1 means +flip.  For example, if ``N==0 and ornt[0,1] == -1, and +there’s an array arr of shape shape, the flip would +correspond to the effect of np.flipud(arr). ornt[:,0] is +the transpose that needs to be done to the implied array, as in +arr.transpose(ornt[:,0])

+
+
+
+
+

Notes

+

Subclasses should override this if they have additional requirements +when re-orienting an image.

+
+ +
+
+classmethod from_image(img: SpatialImage | FileBasedImage) SpatialImgTΒΆ
+

Class method to create new instance of own class from img

+
+
Parameters:
+
+
imgspatialimage instance

In fact, an object with the API of spatialimage - +specifically dataobj, affine, header and extra.

+
+
+
+
Returns:
+
+
cimgspatialimage instance

Image, of our own class

+
+
+
+
+
+ +
+
+get_data_dtype() dtypeΒΆ
+
+ +
+
+header_classΒΆ
+

alias of SpatialHeader

+
+ +
+
+orthoview() OrthoSlicer3DΒΆ
+

Plot the image using OrthoSlicer3D

+
+
Returns:
+
+
viewerinstance of OrthoSlicer3D

The viewer.

+
+
+
+
+

Notes

+

This requires matplotlib. If a non-interactive backend is used, +consider using viewer.show() (equivalently plt.show()) to show +the figure.

+
+ +
+
+set_data_dtype(dtype: npt.DTypeLike) NoneΒΆ
+
+ +
+
+property slicer: SpatialFirstSlicer[SpatialImgT]ΒΆ
+

Slicer object that returns cropped and subsampled images

+

The image is resliced in the current orientation; no rotation or +resampling is performed, and no attempt is made to filter the image +to avoid aliasing.

+

The affine matrix is updated with the new intercept (and scales, if +down-sampling is used), so that all values are found at the same RAS +locations.

+

Slicing may include non-spatial dimensions. +However, this method does not currently adjust the repetition time in +the image header.

+
+ +
+
+update_header() NoneΒΆ
+

Harmonize header with image data and affine

+
>>> data = np.zeros((2,3,4))
+>>> affine = np.diag([1.0,2.0,3.0,1.0])
+>>> img = SpatialImage(data, affine)
+>>> img.shape == (2, 3, 4)
+True
+>>> img.update_header()
+>>> img.header.get_data_shape() == (2, 3, 4)
+True
+>>> img.header.get_zooms()
+(1.0, 2.0, 3.0)
+
+
+
+ +
+ +
+
+

SpatialProtocolΒΆ

+
+
+class nibabel.spatialimages.SpatialProtocol(*args, **kwargs)ΒΆ
+

Bases: Protocol

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+get_data_dtype() dtypeΒΆ
+
+ +
+
+get_data_shape() Tuple[int, ...]ΒΆ
+
+ +
+
+get_zooms() Tuple[float, ...]ΒΆ
+
+ +
+ +
+
+

supported_np_typesΒΆ

+
+
+nibabel.spatialimages.supported_np_types(obj: HasDtype) set[type[generic]]ΒΆ
+

Numpy data types that instance obj supports

+
+
Parameters:
+
+
objobject

Object implementing get_data_dtype and set_data_dtype. The object +should raise HeaderDataError for setting unsupported dtypes. The +object will likely be a header or a SpatialImage

+
+
+
+
Returns:
+
+
np_typesset

set of numpy types that obj supports

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.spm2analyze.html b/reference/nibabel.spm2analyze.html new file mode 100644 index 0000000000..b2e5285690 --- /dev/null +++ b/reference/nibabel.spm2analyze.html @@ -0,0 +1,431 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

spm2analyzeΒΆ

+

Read / write access to SPM2 version of analyze image format

+ + + + + + + + + +

Spm2AnalyzeHeader([binaryblock,Β endianness,Β ...])

Class for SPM2 variant of basic Analyze header

Spm2AnalyzeImage(dataobj,Β affine[,Β header,Β ...])

Class for SPM2 variant of basic Analyze image

+
+

Spm2AnalyzeHeaderΒΆ

+
+
+class nibabel.spm2analyze.Spm2AnalyzeHeader(binaryblock=None, endianness=None, check=True)ΒΆ
+

Bases: Spm99AnalyzeHeader

+

Class for SPM2 variant of basic Analyze header

+

SPM2 variant adds the following to basic Analyze format:

+
    +
  • voxel origin;

  • +
  • slope scaling of data;

  • +
  • reading - but not writing - intercept of data.

  • +
+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> hdr1 = AnalyzeHeader() # an empty header
+>>> hdr1.endianness == native_code
+True
+>>> hdr1.get_data_shape()
+(0,)
+>>> hdr1.set_data_shape((1,2,3)) # now with some content
+>>> hdr1.get_data_shape()
+(1, 2, 3)
+
+
+

We can set the binary block directly via this initialization. +Here we get it from the header we have just made

+
>>> binblock2 = hdr1.binaryblock
+>>> hdr2 = AnalyzeHeader(binblock2)
+>>> hdr2.get_data_shape()
+(1, 2, 3)
+
+
+

Empty headers are native endian by default

+
>>> hdr2.endianness == native_code
+True
+
+
+

You can pass valid opposite endian headers with the +endianness parameter. Even empty headers can have +endianness

+
>>> hdr3 = AnalyzeHeader(endianness=swapped_code)
+>>> hdr3.endianness == swapped_code
+True
+
+
+

If you do not pass an endianness, and you pass some data, we +will try to guess from the passed data.

+
>>> binblock3 = hdr3.binaryblock
+>>> hdr4 = AnalyzeHeader(binblock3)
+>>> hdr4.endianness == swapped_code
+True
+
+
+
+
+__init__(binaryblock=None, endianness=None, check=True)ΒΆ
+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> hdr1 = AnalyzeHeader() # an empty header
+>>> hdr1.endianness == native_code
+True
+>>> hdr1.get_data_shape()
+(0,)
+>>> hdr1.set_data_shape((1,2,3)) # now with some content
+>>> hdr1.get_data_shape()
+(1, 2, 3)
+
+
+

We can set the binary block directly via this initialization. +Here we get it from the header we have just made

+
>>> binblock2 = hdr1.binaryblock
+>>> hdr2 = AnalyzeHeader(binblock2)
+>>> hdr2.get_data_shape()
+(1, 2, 3)
+
+
+

Empty headers are native endian by default

+
>>> hdr2.endianness == native_code
+True
+
+
+

You can pass valid opposite endian headers with the +endianness parameter. Even empty headers can have +endianness

+
>>> hdr3 = AnalyzeHeader(endianness=swapped_code)
+>>> hdr3.endianness == swapped_code
+True
+
+
+

If you do not pass an endianness, and you pass some data, we +will try to guess from the passed data.

+
>>> binblock3 = hdr3.binaryblock
+>>> hdr4 = AnalyzeHeader(binblock3)
+>>> hdr4.endianness == swapped_code
+True
+
+
+
+ +
+
+get_slope_inter()ΒΆ
+

Get data scaling (slope) and intercept from header data

+

Uses the algorithm from SPM2 spm_vol_ana.m by John Ashburner

+
+
Parameters:
+
+
selfheader

Mapping with fields: +* scl_slope - slope +* scl_inter - possible intercept (SPM2 use - shared by nifti) +* glmax - the (recorded) maximum value in the data (unscaled) +* glmin - recorded minimum unscaled value +* cal_max - the calibrated (scaled) maximum value in the dataset +* cal_min - ditto minimum value

+
+
+
+
Returns:
+
+
scl_slopeNone or float

slope. None if there is no valid scaling from these fields

+
+
scl_interNone or float

intercept. Also None if there is no valid slope, intercept

+
+
+
+
+

Examples

+
>>> fields = {'scl_slope': 1, 'scl_inter': 0, 'glmax': 0, 'glmin': 0,
+...           'cal_max': 0, 'cal_min': 0}
+>>> hdr = Spm2AnalyzeHeader()
+>>> for key, value in fields.items():
+...     hdr[key] = value
+>>> hdr.get_slope_inter()
+(1.0, 0.0)
+>>> hdr['scl_inter'] = 0.5
+>>> hdr.get_slope_inter()
+(1.0, 0.5)
+>>> hdr['scl_inter'] = np.nan
+>>> hdr.get_slope_inter()
+(1.0, 0.0)
+
+
+

If β€˜scl_slope’ is 0, nan or inf, cannot use β€˜scl_slope’. +Without valid information in the gl / cal fields, we cannot get +scaling, and return None

+
>>> hdr['scl_slope'] = 0
+>>> hdr.get_slope_inter()
+(None, None)
+>>> hdr['scl_slope'] = np.nan
+>>> hdr.get_slope_inter()
+(None, None)
+
+
+

Valid information in the gl AND cal fields are needed

+
>>> hdr['cal_max'] = 0.8
+>>> hdr['cal_min'] = 0.2
+>>> hdr.get_slope_inter()
+(None, None)
+>>> hdr['glmax'] = 110
+>>> hdr['glmin'] = 10
+>>> np.allclose(hdr.get_slope_inter(), [0.6/100, 0.2-0.6/100*10])
+True
+
+
+
+ +
+
+classmethod may_contain_header(binaryblock)ΒΆ
+
+ +
+
+template_dtype = dtype([('sizeof_hdr', '<i4'), ('data_type', 'S10'), ('db_name', 'S18'), ('extents', '<i4'), ('session_error', '<i2'), ('regular', 'S1'), ('hkey_un0', 'S1'), ('dim', '<i2', (8,)), ('vox_units', 'S4'), ('cal_units', 'S8'), ('unused1', '<i2'), ('datatype', '<i2'), ('bitpix', '<i2'), ('dim_un0', '<i2'), ('pixdim', '<f4', (8,)), ('vox_offset', '<f4'), ('scl_slope', '<f4'), ('scl_inter', '<f4'), ('funused3', '<f4'), ('cal_max', '<f4'), ('cal_min', '<f4'), ('compressed', '<i4'), ('verified', '<i4'), ('glmax', '<i4'), ('glmin', '<i4'), ('descrip', 'S80'), ('aux_file', 'S24'), ('orient', 'S1'), ('origin', '<i2', (5,)), ('generated', 'S10'), ('scannum', 'S10'), ('patient_id', 'S10'), ('exp_date', 'S10'), ('exp_time', 'S10'), ('hist_un0', 'S3'), ('views', '<i4'), ('vols_added', '<i4'), ('start_field', '<i4'), ('field_skip', '<i4'), ('omax', '<i4'), ('omin', '<i4'), ('smax', '<i4'), ('smin', '<i4')])ΒΆ
+
+ +
+ +
+
+

Spm2AnalyzeImageΒΆ

+
+
+class nibabel.spm2analyze.Spm2AnalyzeImage(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Bases: Spm99AnalyzeImage

+

Class for SPM2 variant of basic Analyze image

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+header_classΒΆ
+

alias of Spm2AnalyzeHeader

+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.spm99analyze.html b/reference/nibabel.spm99analyze.html new file mode 100644 index 0000000000..d6de089c0f --- /dev/null +++ b/reference/nibabel.spm99analyze.html @@ -0,0 +1,745 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

spm99analyzeΒΆ

+

Read / write access to SPM99 version of analyze image format

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

Spm99AnalyzeHeader([binaryblock,Β ...])

Class for SPM99 variant of basic Analyze header

Spm99AnalyzeImage(dataobj,Β affine[,Β header,Β ...])

Class for SPM99 variant of basic Analyze image

SpmAnalyzeHeader([binaryblock,Β endianness,Β ...])

Basic scaling Spm Analyze header

+
+

Spm99AnalyzeHeaderΒΆ

+
+
+class nibabel.spm99analyze.Spm99AnalyzeHeader(binaryblock=None, endianness=None, check=True)ΒΆ
+

Bases: SpmAnalyzeHeader

+

Class for SPM99 variant of basic Analyze header

+

SPM99 variant adds the following to basic Analyze format:

+
    +
  • voxel origin;

  • +
  • slope scaling of data.

  • +
+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> hdr1 = AnalyzeHeader() # an empty header
+>>> hdr1.endianness == native_code
+True
+>>> hdr1.get_data_shape()
+(0,)
+>>> hdr1.set_data_shape((1,2,3)) # now with some content
+>>> hdr1.get_data_shape()
+(1, 2, 3)
+
+
+

We can set the binary block directly via this initialization. +Here we get it from the header we have just made

+
>>> binblock2 = hdr1.binaryblock
+>>> hdr2 = AnalyzeHeader(binblock2)
+>>> hdr2.get_data_shape()
+(1, 2, 3)
+
+
+

Empty headers are native endian by default

+
>>> hdr2.endianness == native_code
+True
+
+
+

You can pass valid opposite endian headers with the +endianness parameter. Even empty headers can have +endianness

+
>>> hdr3 = AnalyzeHeader(endianness=swapped_code)
+>>> hdr3.endianness == swapped_code
+True
+
+
+

If you do not pass an endianness, and you pass some data, we +will try to guess from the passed data.

+
>>> binblock3 = hdr3.binaryblock
+>>> hdr4 = AnalyzeHeader(binblock3)
+>>> hdr4.endianness == swapped_code
+True
+
+
+
+
+__init__(binaryblock=None, endianness=None, check=True)ΒΆ
+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> hdr1 = AnalyzeHeader() # an empty header
+>>> hdr1.endianness == native_code
+True
+>>> hdr1.get_data_shape()
+(0,)
+>>> hdr1.set_data_shape((1,2,3)) # now with some content
+>>> hdr1.get_data_shape()
+(1, 2, 3)
+
+
+

We can set the binary block directly via this initialization. +Here we get it from the header we have just made

+
>>> binblock2 = hdr1.binaryblock
+>>> hdr2 = AnalyzeHeader(binblock2)
+>>> hdr2.get_data_shape()
+(1, 2, 3)
+
+
+

Empty headers are native endian by default

+
>>> hdr2.endianness == native_code
+True
+
+
+

You can pass valid opposite endian headers with the +endianness parameter. Even empty headers can have +endianness

+
>>> hdr3 = AnalyzeHeader(endianness=swapped_code)
+>>> hdr3.endianness == swapped_code
+True
+
+
+

If you do not pass an endianness, and you pass some data, we +will try to guess from the passed data.

+
>>> binblock3 = hdr3.binaryblock
+>>> hdr4 = AnalyzeHeader(binblock3)
+>>> hdr4.endianness == swapped_code
+True
+
+
+
+ +
+
+get_best_affine()ΒΆ
+

Get affine from header, using SPM origin field if sensible

+

The default translations are got from the origin +field, if set, or from the center of the image otherwise.

+

Examples

+
>>> hdr = Spm99AnalyzeHeader()
+>>> hdr.set_data_shape((3, 5, 7))
+>>> hdr.set_zooms((3, 2, 1))
+>>> hdr.default_x_flip
+True
+>>> hdr.get_origin_affine() # from center of image
+array([[-3.,  0.,  0.,  3.],
+       [ 0.,  2.,  0., -4.],
+       [ 0.,  0.,  1., -3.],
+       [ 0.,  0.,  0.,  1.]])
+>>> hdr['origin'][:3] = [3,4,5]
+>>> hdr.get_origin_affine() # using origin
+array([[-3.,  0.,  0.,  6.],
+       [ 0.,  2.,  0., -6.],
+       [ 0.,  0.,  1., -4.],
+       [ 0.,  0.,  0.,  1.]])
+>>> hdr['origin'] = 0 # unset origin
+>>> hdr.set_data_shape((3, 5, 7))
+>>> hdr.get_origin_affine() # from center of image
+array([[-3.,  0.,  0.,  3.],
+       [ 0.,  2.,  0., -4.],
+       [ 0.,  0.,  1., -3.],
+       [ 0.,  0.,  0.,  1.]])
+
+
+
+ +
+
+get_origin_affine()ΒΆ
+

Get affine from header, using SPM origin field if sensible

+

The default translations are got from the origin +field, if set, or from the center of the image otherwise.

+

Examples

+
>>> hdr = Spm99AnalyzeHeader()
+>>> hdr.set_data_shape((3, 5, 7))
+>>> hdr.set_zooms((3, 2, 1))
+>>> hdr.default_x_flip
+True
+>>> hdr.get_origin_affine() # from center of image
+array([[-3.,  0.,  0.,  3.],
+       [ 0.,  2.,  0., -4.],
+       [ 0.,  0.,  1., -3.],
+       [ 0.,  0.,  0.,  1.]])
+>>> hdr['origin'][:3] = [3,4,5]
+>>> hdr.get_origin_affine() # using origin
+array([[-3.,  0.,  0.,  6.],
+       [ 0.,  2.,  0., -6.],
+       [ 0.,  0.,  1., -4.],
+       [ 0.,  0.,  0.,  1.]])
+>>> hdr['origin'] = 0 # unset origin
+>>> hdr.set_data_shape((3, 5, 7))
+>>> hdr.get_origin_affine() # from center of image
+array([[-3.,  0.,  0.,  3.],
+       [ 0.,  2.,  0., -4.],
+       [ 0.,  0.,  1., -3.],
+       [ 0.,  0.,  0.,  1.]])
+
+
+
+ +
+
+set_origin_from_affine(affine)ΒΆ
+

Set SPM origin to header from affine matrix.

+

The origin field was read but not written by SPM99 and 2. It was +used for storing a central voxel coordinate, that could be used in +aligning the image to some standard position - a proxy for a full +translation vector that was usually stored in a separate matlab .mat +file.

+

Nifti uses the space occupied by the SPM origin field for important +other information (the transform codes), so writing the origin will +make the header a confusing Nifti file. If you work with both Analyze +and Nifti, you should probably avoid doing this.

+
+
Parameters:
+
+
affinearray-like, shape (4,4)

Affine matrix to set

+
+
+
+
Returns:
+
+
None
+
+
+
+

Examples

+
>>> hdr = Spm99AnalyzeHeader()
+>>> hdr.set_data_shape((3, 5, 7))
+>>> hdr.set_zooms((3,2,1))
+>>> hdr.get_origin_affine()
+array([[-3.,  0.,  0.,  3.],
+       [ 0.,  2.,  0., -4.],
+       [ 0.,  0.,  1., -3.],
+       [ 0.,  0.,  0.,  1.]])
+>>> affine = np.diag([3,2,1,1])
+>>> affine[:3,3] = [-6, -6, -4]
+>>> hdr.set_origin_from_affine(affine)
+>>> np.all(hdr['origin'][:3] == [3,4,5])
+True
+>>> hdr.get_origin_affine()
+array([[-3.,  0.,  0.,  6.],
+       [ 0.,  2.,  0., -6.],
+       [ 0.,  0.,  1., -4.],
+       [ 0.,  0.,  0.,  1.]])
+
+
+
+ +
+ +
+
+

Spm99AnalyzeImageΒΆ

+
+
+class nibabel.spm99analyze.Spm99AnalyzeImage(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Bases: AnalyzeImage

+

Class for SPM99 variant of basic Analyze image

+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+
+__init__(dataobj, affine, header=None, extra=None, file_map=None, dtype=None)ΒΆ
+

Initialize image

+

The image is a combination of (array-like, affine matrix, header), with +optional metadata in extra, and filename / file-like objects +contained in the file_map mapping.

+
+
Parameters:
+
+
dataobjobject

Object containing image data. It should be some object that returns an +array from np.asanyarray. It should have a shape attribute +or property

+
+
affineNone or (4,4) array-like

homogeneous affine giving relationship between voxel coordinates and +world coordinates. Affine can also be None. In this case, +obj.affine also returns None, and the affine as written to disk +will depend on the file format.

+
+
headerNone or mapping or header instance, optional

metadata for this image format

+
+
extraNone or mapping, optional

metadata to associate with image that cannot be stored in the +metadata of this image type

+
+
file_mapmapping, optional

mapping giving file information for this image format

+
+
+
+
+
+ +
+
+files_types: tuple[tuple[str, str], ...] = (('image', '.img'), ('header', '.hdr'), ('mat', '.mat'))ΒΆ
+
+ +
+
+classmethod from_file_map(file_map, *, mmap=True, keep_file_open=None)ΒΆ
+

Class method to create image from mapping in file_map

+
+
Parameters:
+
+
file_mapdict

Mapping with (kay, value) pairs of (file_type, FileHolder +instance giving file-likes for each file needed for this image +type.

+
+
mmap{True, False, β€˜c’, β€˜r’}, optional, keyword only

mmap controls the use of numpy memory mapping for reading image +array data. If False, do not try numpy memmap for data array. +If one of {β€˜c’, β€˜r’}, try numpy memmap with mode=mmap. A +mmap value of True gives the same behavior as mmap='c'. If +image data file cannot be memory-mapped, ignore mmap value and +read array from file.

+
+
keep_file_open{ None, True, False }, optional, keyword only

keep_file_open controls whether a new file handle is created +every time the image is accessed, or a single file handle is +created and used for the lifetime of this ArrayProxy. If +True, a single file handle is created and used. If False, +a new file handle is created every time the image is accessed. +If file_map refers to an open file handle, this setting has no +effect. The default value (None) will result in the value of +nibabel.arrayproxy.KEEP_FILE_OPEN_DEFAULT being used.

+
+
+
+
Returns:
+
+
imgSpm99AnalyzeImage instance
+
+
+
+
+ +
+
+has_affine = TrueΒΆ
+
+ +
+
+header_classΒΆ
+

alias of Spm99AnalyzeHeader

+
+ +
+
+makeable: bool = TrueΒΆ
+
+ +
+
+rw: bool = FalseΒΆ
+
+ +
+
+to_file_map(file_map=None, dtype=None)ΒΆ
+

Write image to file_map or contained self.file_map

+

Extends Analyze to_file_map method by writing mat file

+
+
Parameters:
+
+
file_mapNone or mapping, optional

files mapping. If None (default) use object’s file_map +attribute instead

+
+
+
+
+
+ +
+ +
+
+

SpmAnalyzeHeaderΒΆ

+
+
+class nibabel.spm99analyze.SpmAnalyzeHeader(binaryblock=None, endianness=None, check=True)ΒΆ
+

Bases: AnalyzeHeader

+

Basic scaling Spm Analyze header

+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> hdr1 = AnalyzeHeader() # an empty header
+>>> hdr1.endianness == native_code
+True
+>>> hdr1.get_data_shape()
+(0,)
+>>> hdr1.set_data_shape((1,2,3)) # now with some content
+>>> hdr1.get_data_shape()
+(1, 2, 3)
+
+
+

We can set the binary block directly via this initialization. +Here we get it from the header we have just made

+
>>> binblock2 = hdr1.binaryblock
+>>> hdr2 = AnalyzeHeader(binblock2)
+>>> hdr2.get_data_shape()
+(1, 2, 3)
+
+
+

Empty headers are native endian by default

+
>>> hdr2.endianness == native_code
+True
+
+
+

You can pass valid opposite endian headers with the +endianness parameter. Even empty headers can have +endianness

+
>>> hdr3 = AnalyzeHeader(endianness=swapped_code)
+>>> hdr3.endianness == swapped_code
+True
+
+
+

If you do not pass an endianness, and you pass some data, we +will try to guess from the passed data.

+
>>> binblock3 = hdr3.binaryblock
+>>> hdr4 = AnalyzeHeader(binblock3)
+>>> hdr4.endianness == swapped_code
+True
+
+
+
+
+__init__(binaryblock=None, endianness=None, check=True)ΒΆ
+

Initialize header from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into header. By default, None, in +which case we insert the default empty header block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of header in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> hdr1 = AnalyzeHeader() # an empty header
+>>> hdr1.endianness == native_code
+True
+>>> hdr1.get_data_shape()
+(0,)
+>>> hdr1.set_data_shape((1,2,3)) # now with some content
+>>> hdr1.get_data_shape()
+(1, 2, 3)
+
+
+

We can set the binary block directly via this initialization. +Here we get it from the header we have just made

+
>>> binblock2 = hdr1.binaryblock
+>>> hdr2 = AnalyzeHeader(binblock2)
+>>> hdr2.get_data_shape()
+(1, 2, 3)
+
+
+

Empty headers are native endian by default

+
>>> hdr2.endianness == native_code
+True
+
+
+

You can pass valid opposite endian headers with the +endianness parameter. Even empty headers can have +endianness

+
>>> hdr3 = AnalyzeHeader(endianness=swapped_code)
+>>> hdr3.endianness == swapped_code
+True
+
+
+

If you do not pass an endianness, and you pass some data, we +will try to guess from the passed data.

+
>>> binblock3 = hdr3.binaryblock
+>>> hdr4 = AnalyzeHeader(binblock3)
+>>> hdr4.endianness == swapped_code
+True
+
+
+
+ +
+
+classmethod default_structarr(endianness=None)ΒΆ
+

Create empty header binary block with given endianness

+
+ +
+
+get_slope_inter()ΒΆ
+

Get scalefactor and intercept

+

If scalefactor is 0.0 return None to indicate no scalefactor. +Intercept is always None because SPM99 analyze cannot store intercepts.

+
+ +
+
+has_data_intercept = FalseΒΆ
+
+ +
+
+has_data_slope = TrueΒΆ
+
+ +
+
+set_slope_inter(slope, inter=None)ΒΆ
+

Set slope and / or intercept into header

+

Set slope and intercept for image data, such that, if the image +data is arr, then the scaled image data will be (arr * +slope) + inter

+

The SPM Analyze header can’t save an intercept value, and we raise an +error unless inter is None, NaN or 0

+
+
Parameters:
+
+
slopeNone or float

If None, implies slope of NaN. NaN is a signal to the image +writing routines to rescale on save. 0, Inf, -Inf are invalid and +cause a HeaderDataError

+
+
interNone or float, optional

intercept. Must be None, NaN or 0, because SPM99 cannot store +intercepts.

+
+
+
+
+
+ +
+
+template_dtype = dtype([('sizeof_hdr', '<i4'), ('data_type', 'S10'), ('db_name', 'S18'), ('extents', '<i4'), ('session_error', '<i2'), ('regular', 'S1'), ('hkey_un0', 'S1'), ('dim', '<i2', (8,)), ('vox_units', 'S4'), ('cal_units', 'S8'), ('unused1', '<i2'), ('datatype', '<i2'), ('bitpix', '<i2'), ('dim_un0', '<i2'), ('pixdim', '<f4', (8,)), ('vox_offset', '<f4'), ('scl_slope', '<f4'), ('funused2', '<f4'), ('funused3', '<f4'), ('cal_max', '<f4'), ('cal_min', '<f4'), ('compressed', '<i4'), ('verified', '<i4'), ('glmax', '<i4'), ('glmin', '<i4'), ('descrip', 'S80'), ('aux_file', 'S24'), ('orient', 'S1'), ('origin', '<i2', (5,)), ('generated', 'S10'), ('scannum', 'S10'), ('patient_id', 'S10'), ('exp_date', 'S10'), ('exp_time', 'S10'), ('hist_un0', 'S3'), ('views', '<i4'), ('vols_added', '<i4'), ('start_field', '<i4'), ('field_skip', '<i4'), ('omax', '<i4'), ('omin', '<i4'), ('smax', '<i4'), ('smin', '<i4')])ΒΆ
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.streamlines.html b/reference/nibabel.streamlines.html new file mode 100644 index 0000000000..3e00741e2d --- /dev/null +++ b/reference/nibabel.streamlines.html @@ -0,0 +1,2329 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

streamlinesΒΆ

+

Multiformat-capable streamline format read / write interface

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

detect_format(fileobj)

Returns the StreamlinesFile object guessed from the file-like object.

is_supported(fileobj)

Checks if the file-like object if supported by NiBabel.

load(fileobj[,Β lazy_load])

Loads streamlines in RAS+ and mm space from a file-like object.

save(tractogram,Β filename,Β **kwargs)

Saves a tractogram to a file.

+
+

Module: streamlines.array_sequenceΒΆ

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

ArraySequence([iterable,Β buffer_size])

Sequence of ndarrays having variable first dimension sizes.

concatenate(seqs,Β axis)

Concatenates multiple ArraySequence objects along an axis.

create_arraysequences_from_generator(gen,Β n)

Creates ArraySequence objects from a generator yielding tuples

is_array_sequence(obj)

Return True if obj is an array sequence.

is_ndarray_of_int_or_bool(obj)

+
+
+

Module: streamlines.headerΒΆ

+

Field class defining common header fields in tractogram files

+ + + + + + +

Field()

Header fields common to multiple streamline file formats.

+
+
+

Module: streamlines.tckΒΆ

+

Read / write access to TCK streamlines format.

+

TCK format is defined at +http://mrtrix.readthedocs.io/en/latest/getting_started/image_data.html?highlight=format#tracks-file-format-tck

+ + + + + + +

TckFile(tractogram[,Β header])

Convenience class to encapsulate TCK file format.

+
+
+

Module: streamlines.tractogramΒΆ

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

LazyDict(*args,Β **kwargs)

Dictionary of generator functions.

LazyTractogram([streamlines,Β ...])

Lazy container for streamlines and their data information.

PerArrayDict([n_rows])

Dictionary for which key access can do slicing on the values.

PerArraySequenceDict([n_rows])

Dictionary for which key access can do slicing on the values.

SliceableDataDict(*args,Β **kwargs)

Dictionary for which key access can do slicing on the values.

Tractogram([streamlines,Β ...])

Container for streamlines and their data information.

TractogramItem(streamline,Β ...)

Class containing information about one streamline.

is_data_dict(obj)

True if obj seems to implement the DataDict API

is_lazy_dict(obj)

True if obj seems to implement the LazyDict API

+
+
+

Module: streamlines.tractogram_fileΒΆ

+

Define abstract interface for Tractogram file classes

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

DataError

Raised when data is missing or inconsistent in a tractogram file.

DataWarning

Base class for warnings about tractogram file data.

ExtensionWarning

Base class for warnings about tractogram file extension.

HeaderError

Raised when a tractogram file header contains invalid information.

HeaderWarning

Base class for warnings about tractogram file header.

TractogramFile(tractogram[,Β header])

Convenience class to encapsulate tractogram file format.

abstractclassmethod(callable)

+
+
+

Module: streamlines.trkΒΆ

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

TrkFile(tractogram[,Β header])

Convenience class to encapsulate TRK file format.

decode_value_from_name(encoded_name)

Decodes a value that has been encoded in the last bytes of a string.

encode_value_in_name(value,Β name[,Β max_name_len])

Return name as fixed-length string, appending value as string.

get_affine_rasmm_to_trackvis(header)

get_affine_trackvis_to_rasmm(header)

Get affine mapping trackvis voxelmm space to RAS+ mm space

+
+
+

Module: streamlines.utilsΒΆ

+ + + + + + + + + +

get_affine_from_reference(ref)

Returns the affine defining the reference space.

peek_next(iterable)

Peek next element of iterable.

+
+

detect_formatΒΆ

+
+
+nibabel.streamlines.detect_format(fileobj)ΒΆ
+

Returns the StreamlinesFile object guessed from the file-like object.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object pointing +to a tractogram file (and ready to read from the beginning of the +header)

+
+
+
+
Returns:
+
+
tractogram_fileTractogramFile class

The class type guessed from the content of fileobj.

+
+
+
+
+
+ +
+
+

is_supportedΒΆ

+
+
+nibabel.streamlines.is_supported(fileobj)ΒΆ
+

Checks if the file-like object if supported by NiBabel.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object pointing +to a streamlines file (and ready to read from the beginning of the +header)

+
+
+
+
Returns:
+
+
is_supportedboolean
+
+
+
+
+ +
+
+

loadΒΆ

+
+
+nibabel.streamlines.load(fileobj, lazy_load=False)ΒΆ
+

Loads streamlines in RAS+ and mm space from a file-like object.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object +pointing to a streamlines file (and ready to read from the beginning +of the streamlines file’s header).

+
+
lazy_load{False, True}, optional

If True, load streamlines in a lazy manner i.e. they will not be kept +in memory and only be loaded when needed. +Otherwise, load all streamlines in memory.

+
+
+
+
Returns:
+
+
tractogram_fileTractogramFile object

Returns an instance of a TractogramFile containing data and +metadata of the tractogram loaded from fileobj.

+
+
+
+
+

Notes

+

The streamline coordinate (0,0,0) refers to the center of the voxel.

+
+ +
+
+

saveΒΆ

+
+
+nibabel.streamlines.save(tractogram, filename, **kwargs)ΒΆ
+

Saves a tractogram to a file.

+
+
Parameters:
+
+
tractogramTractogram object or TractogramFile object

If Tractogram object, the file format will be guessed from +filename and a TractogramFile object will be created using +provided keyword arguments. +If TractogramFile object, the file format is known and will +be used to save its content to filename.

+
+
filenamestr

Name of the file where the tractogram will be saved.

+
+
**kwargskeyword arguments

Keyword arguments passed to TractogramFile constructor. +Should not be specified if tractogram is already an instance of +TractogramFile.

+
+
+
+
+
+ +
+
+

ArraySequenceΒΆ

+
+
+class nibabel.streamlines.array_sequence.ArraySequence(iterable=None, buffer_size=4)ΒΆ
+

Bases: object

+

Sequence of ndarrays having variable first dimension sizes.

+

This is a container that can store multiple ndarrays where each ndarray +might have a different first dimension size but a common size for the +remaining dimensions.

+

More generally, an instance of ArraySequence of length \(N\) is +composed of \(N\) ndarrays of shape \((d_1, d_2, ... d_D)\) where \(d_1\) +can vary in length between arrays but \((d_2, ..., d_D)\) have to be the +same for every ndarray.

+

Initialize array sequence instance

+
+
Parameters:
+
+
iterableNone or iterable or ArraySequence, optional

If None, create an empty ArraySequence object. +If iterable, create a ArraySequence object initialized +from array-like objects yielded by the iterable. +If ArraySequence, create a view (no memory is allocated). +For an actual copy use copy() instead.

+
+
buffer_sizefloat, optional

Size (in Mb) for memory allocation when iterable is a generator.

+
+
+
+
+
+
+__init__(iterable=None, buffer_size=4)ΒΆ
+

Initialize array sequence instance

+
+
Parameters:
+
+
iterableNone or iterable or ArraySequence, optional

If None, create an empty ArraySequence object. +If iterable, create a ArraySequence object initialized +from array-like objects yielded by the iterable. +If ArraySequence, create a view (no memory is allocated). +For an actual copy use copy() instead.

+
+
buffer_sizefloat, optional

Size (in Mb) for memory allocation when iterable is a generator.

+
+
+
+
+
+ +
+
+append(element, cache_build=False)ΒΆ
+

Appends element to this array sequence.

+

Append can be a lot faster if it knows that it is appending several +elements instead of a single element. In that case it can cache the +parameters it uses between append operations, in a β€œbuild cache”. To +tell append to do this, use cache_build=True. If you use +cache_build=True, you need to finalize the append operations with +finalize_append().

+
+
Parameters:
+
+
elementndarray

Element to append. The shape must match already inserted elements +shape except for the first dimension.

+
+
cache_build{False, True}

Whether to save the build cache from this append routine. If True, +append can assume it is the only player updating self, and the +caller must finalize self after all append operations, with +self.finalize_append().

+
+
+
+
Returns:
+
+
None
+
+
+
+

Notes

+

If you need to add multiple elements you should consider +ArraySequence.extend.

+
+ +
+
+property common_shapeΒΆ
+

Matching shape of the elements in this array sequence.

+
+ +
+
+copy()ΒΆ
+

Creates a copy of this ArraySequence object.

+
+
Returns:
+
+
seq_copyArraySequence instance

Copy of self.

+
+
+
+
+

Notes

+

We do not simply deepcopy this object because we have a chance to use +less memory. For example, if the array sequence being copied is the +result of a slicing operation on an array sequence.

+
+ +
+
+extend(elements)ΒΆ
+

Appends all elements to this array sequence.

+
+
Parameters:
+
+
elementsiterable of ndarrays or ArraySequence object

If iterable of ndarrays, each ndarray will be concatenated along +the first dimension then appended to the data of this +ArraySequence. +If ArraySequence object, its data are simply appended to +the data of this ArraySequence.

+
+
+
+
Returns:
+
+
None
+
+
+
+

Notes

+

The shape of the elements to be added must match the one of the data of +this ArraySequence except for the first dimension.

+
+ +
+
+finalize_append()ΒΆ
+

Finalize process of appending several elements to self

+

append() can be a lot faster if it knows that it is appending +several elements instead of a single element. To tell the append +method this is the case, use cache_build=True. This method +finalizes the series of append operations after a call to +append() with cache_build=True.

+
+ +
+
+get_data()ΒΆ
+

Returns a copy of the elements in this array sequence.

+

Notes

+

To modify the data on this array sequence, one can use +in-place mathematical operators (e.g., seq += …) or the use +assignment operator (i.e, seq[…] = value).

+
+ +
+
+property is_array_sequenceΒΆ
+
+ +
+
+property is_sliced_viewΒΆ
+
+ +
+
+classmethod load(filename)ΒΆ
+

Loads a ArraySequence object from a .npz file.

+
+ +
+
+save(filename)ΒΆ
+

Saves this ArraySequence object to a .npz file.

+
+ +
+
+shrink_data()ΒΆ
+
+ +
+
+property total_nb_rowsΒΆ
+

Total number of rows in this array sequence.

+
+ +
+ +
+
+

concatenateΒΆ

+
+
+nibabel.streamlines.array_sequence.concatenate(seqs, axis)ΒΆ
+

Concatenates multiple ArraySequence objects along an axis.

+
+
Parameters:
+
+
seqs: iterable of :class:`ArraySequence` objects

Sequences to concatenate.

+
+
axisint

Axis along which the sequences will be concatenated.

+
+
+
+
Returns:
+
+
new_seq: ArraySequence object

New ArraySequence object which is the result of +concatenating multiple sequences along the given axis.

+
+
+
+
+
+ +
+
+

create_arraysequences_from_generatorΒΆ

+
+
+nibabel.streamlines.array_sequence.create_arraysequences_from_generator(gen, n, buffer_sizes=None)ΒΆ
+

Creates ArraySequence objects from a generator yielding tuples

+
+
Parameters:
+
+
gengenerator

Generator yielding a size n tuple containing the values to put in the +array sequences.

+
+
nint

Number of ArraySequences object to create.

+
+
buffer_sizeslist of float, optional

Sizes (in Mb) for each ArraySequence’s buffer.

+
+
+
+
+
+ +
+
+

is_array_sequenceΒΆ

+
+
+nibabel.streamlines.array_sequence.is_array_sequence(obj)ΒΆ
+

Return True if obj is an array sequence.

+
+ +
+
+

is_ndarray_of_int_or_boolΒΆ

+
+
+nibabel.streamlines.array_sequence.is_ndarray_of_int_or_bool(obj)ΒΆ
+
+ +
+
+

FieldΒΆ

+
+
+class nibabel.streamlines.header.FieldΒΆ
+

Bases: object

+

Header fields common to multiple streamline file formats.

+

In IPython, use nibabel.streamlines.Field?? to list them.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+DIMENSIONS = 'dimensions'ΒΆ
+
+ +
+
+ENDIANNESS = 'endianness'ΒΆ
+
+ +
+
+MAGIC_NUMBER = 'magic_number'ΒΆ
+
+ +
+
+METHOD = 'method'ΒΆ
+
+ +
+
+NB_POINTS = 'nb_points'ΒΆ
+
+ +
+
+NB_PROPERTIES_PER_STREAMLINE = 'nb_properties_per_streamline'ΒΆ
+
+ +
+
+NB_SCALARS_PER_POINT = 'nb_scalars_per_point'ΒΆ
+
+ +
+
+NB_STREAMLINES = 'nb_streamlines'ΒΆ
+
+ +
+
+ORIGIN = 'origin'ΒΆ
+
+ +
+
+STEP_SIZE = 'step_size'ΒΆ
+
+ +
+
+VOXEL_ORDER = 'voxel_order'ΒΆ
+
+ +
+
+VOXEL_SIZES = 'voxel_sizes'ΒΆ
+
+ +
+
+VOXEL_TO_RASMM = 'voxel_to_rasmm'ΒΆ
+
+ +
+ +
+
+

TckFileΒΆ

+
+
+class nibabel.streamlines.tck.TckFile(tractogram, header=None)ΒΆ
+

Bases: TractogramFile

+

Convenience class to encapsulate TCK file format.

+

Notes

+

MRtrix (so its file format: TCK) considers streamlines coordinates +to be in world space (RAS+ and mm space). MRtrix refers to that space +as the β€œreal” or β€œscanner” space [1].

+

Moreover, when streamlines are mapped back to voxel space [2], a +streamline point located at an integer coordinate (i,j,k) is considered +to be at the center of the corresponding voxel. This is in contrast with +TRK’s internal convention where it would have referred to a corner.

+

NiBabel’s streamlines internal representation follows the same +convention as MRtrix.

+ +
+
Parameters:
+
+
tractogramTractogram object

Tractogram that will be contained in this TckFile.

+
+
headerNone or dict, optional

Metadata associated to this tractogram file. If None, make +default empty header.

+
+
+
+
+

Notes

+

Streamlines of the tractogram are assumed to be in RAS+ and mm +space. It is also assumed that when streamlines are mapped back to +voxel space, a streamline point located at an integer coordinate +(i,j,k) is considered to be at the center of the corresponding voxel. +This is in contrast with TRK’s internal convention where it would +have referred to a corner.

+
+
+__init__(tractogram, header=None)ΒΆ
+
+
Parameters:
+
+
tractogramTractogram object

Tractogram that will be contained in this TckFile.

+
+
headerNone or dict, optional

Metadata associated to this tractogram file. If None, make +default empty header.

+
+
+
+
+

Notes

+

Streamlines of the tractogram are assumed to be in RAS+ and mm +space. It is also assumed that when streamlines are mapped back to +voxel space, a streamline point located at an integer coordinate +(i,j,k) is considered to be at the center of the corresponding voxel. +This is in contrast with TRK’s internal convention where it would +have referred to a corner.

+
+ +
+
+EOF_DELIMITER = array([[inf, inf, inf]], dtype=float32)ΒΆ
+
+ +
+
+FIBER_DELIMITER = array([[nan, nan, nan]], dtype=float32)ΒΆ
+
+ +
+
+MAGIC_NUMBER = b'mrtrix tracks'ΒΆ
+
+ +
+
+SUPPORTS_DATA_PER_POINT = FalseΒΆ
+
+ +
+
+SUPPORTS_DATA_PER_STREAMLINE = FalseΒΆ
+
+ +
+
+classmethod create_empty_header()ΒΆ
+

Return an empty compliant TCK header as dict

+
+ +
+
+classmethod is_correct_format(fileobj)ΒΆ
+

Check if the file is in TCK format.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object in +binary mode pointing to TCK file (and ready to read from the +beginning of the TCK header). Note that calling this function +does not change the file position.

+
+
+
+
Returns:
+
+
is_correct_format{True, False}

Returns True if fileobj is compatible with TCK format, +otherwise returns False.

+
+
+
+
+
+ +
+
+classmethod load(fileobj, lazy_load=False)ΒΆ
+

Loads streamlines from a filename or file-like object.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object in +binary mode pointing to TCK file (and ready to read from the +beginning of the TCK header). Note that calling this function +does not change the file position.

+
+
lazy_load{False, True}, optional

If True, load streamlines in a lazy manner i.e. they will not be +kept in memory. Otherwise, load all streamlines in memory.

+
+
+
+
Returns:
+
+
tck_fileTckFile object

Returns an object containing tractogram data and header +information.

+
+
+
+
+

Notes

+

Streamlines of the tractogram are assumed to be in RAS+ and mm +space. It is also assumed that when streamlines are mapped back to +voxel space, a streamline point located at an integer coordinate +(i,j,k) is considered to be at the center of the corresponding voxel. +This is in contrast with TRK’s internal convention where it would +have referred to a corner.

+
+ +
+
+save(fileobj)ΒΆ
+

Save tractogram to a filename or file-like object using TCK format.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object in +binary mode pointing to TCK file (and ready to write from the +beginning of the TCK header data).

+
+
+
+
+
+ +
+ +
+
+

LazyDictΒΆ

+
+
+class nibabel.streamlines.tractogram.LazyDict(*args, **kwargs)ΒΆ
+

Bases: MutableMapping

+

Dictionary of generator functions.

+

This container behaves like a dictionary but it makes sure its elements are +callable objects that it assumes are generator functions yielding values. +When getting the element associated with a given key, the element (i.e. a +generator function) is first called before being returned.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

LazyTractogramΒΆ

+
+
+class nibabel.streamlines.tractogram.LazyTractogram(streamlines=None, data_per_streamline=None, data_per_point=None, affine_to_rasmm=None)ΒΆ
+

Bases: Tractogram

+

Lazy container for streamlines and their data information.

+

This container behaves lazily as it uses generator functions to manage +streamlines and their data information. This container is thus memory +friendly since it doesn’t require having all this data loaded in memory.

+

Streamlines of a tractogram can be in any coordinate system of your +choice as long as you provide the correct affine_to_rasmm matrix, at +construction time. When applied to streamlines coordinates, that +transformation matrix should bring the streamlines back to world space +(RAS+ and mm space) [3].

+

Moreover, when streamlines are mapped back to voxel space [4], a +streamline point located at an integer coordinate (i,j,k) is considered +to be at the center of the corresponding voxel. This is in contrast with +other conventions where it might have referred to a corner.

+

Notes

+

LazyTractogram objects do not support indexing currently. +LazyTractogram objects are suited for operations that can be linearized +such as applying an affine transformation or converting streamlines from +one file format to another.

+

References

+ +
+
Attributes:
+
+
streamlinesgenerator function

Generator function yielding streamlines. Each streamline is an +ndarray of shape (\(N_t\), 3) where \(N_t\) is the number of points of +streamline \(t\).

+
+
data_per_streamlineinstance of LazyDict

Dictionary where the items are (str, instantiated generator). +Each key represents a piece of information \(i\) to be kept alongside +every streamline, and its associated value is a generator function +yielding that information via ndarrays of shape (\(P_i\),) where \(P_i\) is +the number of values to store for that particular piece of information +\(i\).

+
+
data_per_pointLazyDict object

Dictionary where the items are (str, instantiated generator). Each key +represents a piece of information \(i\) to be kept alongside every point +of every streamline, and its associated value is a generator function +yielding that information via ndarrays of shape (\(N_t\), \(M_i\)) where +\(N_t\) is the number of points for a particular streamline \(t\) and \(M_i\) +is the number of values to store for that particular piece of +information \(i\).

+
+
+
+
+
+
Parameters:
+
+
streamlinesgenerator function, optional

Generator function yielding streamlines. Each streamline is an +ndarray of shape (\(N_t\), 3) where \(N_t\) is the number of points of +streamline \(t\).

+
+
data_per_streamlinedict of generator functions, optional

Dictionary where the items are (str, generator function). +Each key represents an information \(i\) to be kept alongside every +streamline, and its associated value is a generator function +yielding that information via ndarrays of shape (\(P_i\),) where +\(P_i\) is the number of values to store for that particular +information \(i\).

+
+
data_per_pointdict of generator functions, optional

Dictionary where the items are (str, generator function). +Each key represents an information \(i\) to be kept alongside every +point of every streamline, and its associated value is a generator +function yielding that information via ndarrays of shape +(\(N_t\), \(M_i\)) where \(N_t\) is the number of points for a particular +streamline \(t\) and \(M_i\) is the number of values to store for +that particular information \(i\).

+
+
affine_to_rasmmndarray of shape (4, 4) or None, optional

Transformation matrix that brings the streamlines contained in +this tractogram to RAS+ and mm space where coordinate (0,0,0) +refers to the center of the voxel. By default, the streamlines +are in an unknown space, i.e. affine_to_rasmm is None.

+
+
+
+
+
+
+__init__(streamlines=None, data_per_streamline=None, data_per_point=None, affine_to_rasmm=None)ΒΆ
+
+
Parameters:
+
+
streamlinesgenerator function, optional

Generator function yielding streamlines. Each streamline is an +ndarray of shape (\(N_t\), 3) where \(N_t\) is the number of points of +streamline \(t\).

+
+
data_per_streamlinedict of generator functions, optional

Dictionary where the items are (str, generator function). +Each key represents an information \(i\) to be kept alongside every +streamline, and its associated value is a generator function +yielding that information via ndarrays of shape (\(P_i\),) where +\(P_i\) is the number of values to store for that particular +information \(i\).

+
+
data_per_pointdict of generator functions, optional

Dictionary where the items are (str, generator function). +Each key represents an information \(i\) to be kept alongside every +point of every streamline, and its associated value is a generator +function yielding that information via ndarrays of shape +(\(N_t\), \(M_i\)) where \(N_t\) is the number of points for a particular +streamline \(t\) and \(M_i\) is the number of values to store for +that particular information \(i\).

+
+
affine_to_rasmmndarray of shape (4, 4) or None, optional

Transformation matrix that brings the streamlines contained in +this tractogram to RAS+ and mm space where coordinate (0,0,0) +refers to the center of the voxel. By default, the streamlines +are in an unknown space, i.e. affine_to_rasmm is None.

+
+
+
+
+
+ +
+
+apply_affine(affine, lazy=True)ΒΆ
+

Applies an affine transformation to the streamlines.

+

The transformation given by the affine matrix is applied after any +other pending transformations to the streamline points.

+
+
Parameters:
+
+
affine2D array (4,4)

Transformation matrix that will be applied on each streamline.

+
+
lazyTrue, optional

Should always be True for LazyTractogram object. Doing +otherwise will raise a ValueError.

+
+
+
+
Returns:
+
+
lazy_tractogramLazyTractogram object

A copy of this LazyTractogram instance but with a +transformation to be applied on the streamlines.

+
+
+
+
+
+ +
+
+copy()ΒΆ
+

Returns a copy of this LazyTractogram object.

+
+ +
+
+property dataΒΆ
+
+ +
+
+property data_per_pointΒΆ
+
+ +
+
+property data_per_streamlineΒΆ
+
+ +
+
+extend(other)ΒΆ
+

Appends the data of another Tractogram.

+

Data that will be appended includes the streamlines and the content +of both dictionaries data_per_streamline and data_per_point.

+
+
Parameters:
+
+
otherTractogram object

Its data will be appended to the data of this tractogram.

+
+
+
+
Returns:
+
+
None
+
+
+
+

Notes

+

The entries in both dictionaries self.data_per_streamline and +self.data_per_point must match respectively those contained in +the other tractogram.

+
+ +
+
+classmethod from_data_func(data_func)ΒΆ
+

Creates an instance from a generator function.

+

The generator function must yield TractogramItem objects.

+
+
Parameters:
+
+
data_funcgenerator function yielding TractogramItem objects

Generator function that whenever is called starts yielding +TractogramItem objects that will be used to instantiate a +LazyTractogram.

+
+
+
+
Returns:
+
+
lazy_tractogramLazyTractogram object

New lazy tractogram.

+
+
+
+
+
+ +
+
+classmethod from_tractogram(tractogram)ΒΆ
+

Creates a LazyTractogram object from a Tractogram object.

+
+
Parameters:
+
+
tractogramTractgogram object

Tractogram from which to create a LazyTractogram object.

+
+
+
+
Returns:
+
+
lazy_tractogramLazyTractogram object

New lazy tractogram.

+
+
+
+
+
+ +
+
+property streamlinesΒΆ
+
+ +
+
+to_world(lazy=True)ΒΆ
+

Brings the streamlines to world space (i.e. RAS+ and mm).

+

The transformation is applied after any other pending transformations +to the streamline points.

+
+
Parameters:
+
+
lazyTrue, optional

Should always be True for LazyTractogram object. Doing +otherwise will raise a ValueError.

+
+
+
+
Returns:
+
+
lazy_tractogramLazyTractogram object

A copy of this LazyTractogram instance but with a +transformation to be applied on the streamlines.

+
+
+
+
+
+ +
+ +
+
+

PerArrayDictΒΆ

+
+
+class nibabel.streamlines.tractogram.PerArrayDict(n_rows=0, *args, **kwargs)ΒΆ
+

Bases: SliceableDataDict

+

Dictionary for which key access can do slicing on the values.

+

This container behaves like a standard dictionary but extends key access to +allow keys for key access to be indices slicing into the contained ndarray +values. The elements must also be ndarrays.

+

In addition, it makes sure the amount of data contained in those ndarrays +matches the number of streamlines given at the instantiation of this +instance.

+
+
Parameters:
+
+
n_rowsNone or int, optional

Number of rows per value in each key, value pair or None for not +specified.

+
+
*args
+
**kwargs

Positional and keyword arguments, passed straight through the dict +constructor.

+
+
+
+
+
+
+__init__(n_rows=0, *args, **kwargs)ΒΆ
+
+ +
+
+extend(other)ΒΆ
+

Appends the elements of another PerArrayDict.

+

That is, for each entry in this dictionary, we append the elements +coming from the other dictionary at the corresponding entry.

+
+
Parameters:
+
+
otherPerArrayDict object

Its data will be appended to the data of this dictionary.

+
+
+
+
Returns:
+
+
None
+
+
+
+

Notes

+

The keys in both dictionaries must be the same.

+
+ +
+ +
+
+

PerArraySequenceDictΒΆ

+
+
+class nibabel.streamlines.tractogram.PerArraySequenceDict(n_rows=0, *args, **kwargs)ΒΆ
+

Bases: PerArrayDict

+

Dictionary for which key access can do slicing on the values.

+

This container behaves like a standard dictionary but extends key access to +allow keys for key access to be indices slicing into the contained ndarray +values. The elements must also be ArraySequence.

+

In addition, it makes sure the amount of data contained in those array +sequences matches the number of elements given at the instantiation +of the instance.

+
+
+__init__(n_rows=0, *args, **kwargs)ΒΆ
+
+ +
+ +
+
+

SliceableDataDictΒΆ

+
+
+class nibabel.streamlines.tractogram.SliceableDataDict(*args, **kwargs)ΒΆ
+

Bases: MutableMapping

+

Dictionary for which key access can do slicing on the values.

+

This container behaves like a standard dictionary but extends key access to +allow keys for key access to be indices slicing into the contained ndarray +values.

+
+
Parameters:
+
+
*args
+
**kwargs

Positional and keyword arguments, passed straight through the dict +constructor.

+
+
+
+
+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

TractogramΒΆ

+
+
+class nibabel.streamlines.tractogram.Tractogram(streamlines=None, data_per_streamline=None, data_per_point=None, affine_to_rasmm=None)ΒΆ
+

Bases: object

+

Container for streamlines and their data information.

+

Streamlines of a tractogram can be in any coordinate system of your +choice as long as you provide the correct affine_to_rasmm matrix, at +construction time. When applied to streamlines coordinates, that +transformation matrix should bring the streamlines back to world space +(RAS+ and mm space) [5].

+

Moreover, when streamlines are mapped back to voxel space [6], a +streamline point located at an integer coordinate (i,j,k) is considered +to be at the center of the corresponding voxel. This is in contrast with +other conventions where it might have referred to a corner.

+

References

+ +
+
Attributes:
+
+
streamlinesArraySequence object

Sequence of \(T\) streamlines. Each streamline is an ndarray of +shape (\(N_t\), 3) where \(N_t\) is the number of points of +streamline \(t\).

+
+
data_per_streamlinePerArrayDict object

Dictionary where the items are (str, 2D array). Each key represents a +piece of information \(i\) to be kept alongside every streamline, and its +associated value is a 2D array of shape (\(T\), \(P_i\)) where \(T\) is the +number of streamlines and \(P_i\) is the number of values to store for +that particular piece of information \(i\).

+
+
data_per_pointPerArraySequenceDict object

Dictionary where the items are (str, ArraySequence). Each key +represents a piece of information \(i\) to be kept alongside every point +of every streamline, and its associated value is an iterable of +ndarrays of shape (\(N_t\), \(M_i\)) where \(N_t\) is the number of points +for a particular streamline \(t\) and \(M_i\) is the number values to store +for that particular piece of information \(i\).

+
+
+
+
+
+
Parameters:
+
+
streamlinesiterable of ndarrays or ArraySequence, optional

Sequence of \(T\) streamlines. Each streamline is an ndarray of +shape (\(N_t\), 3) where \(N_t\) is the number of points of +streamline \(t\).

+
+
data_per_streamlinedict of iterable of ndarrays, optional

Dictionary where the items are (str, iterable). +Each key represents an information \(i\) to be kept alongside every +streamline, and its associated value is an iterable of ndarrays of +shape (\(P_i\),) where \(P_i\) is the number of scalar values to store +for that particular information \(i\).

+
+
data_per_pointdict of iterable of ndarrays, optional

Dictionary where the items are (str, iterable). +Each key represents an information \(i\) to be kept alongside every +point of every streamline, and its associated value is an iterable +of ndarrays of shape (\(N_t\), \(M_i\)) where \(N_t\) is the number of +points for a particular streamline \(t\) and \(M_i\) is the number +scalar values to store for that particular information \(i\).

+
+
affine_to_rasmmndarray of shape (4, 4) or None, optional

Transformation matrix that brings the streamlines contained in +this tractogram to RAS+ and mm space where coordinate (0,0,0) +refers to the center of the voxel. By default, the streamlines +are in an unknown space, i.e. affine_to_rasmm is None.

+
+
+
+
+
+
+__init__(streamlines=None, data_per_streamline=None, data_per_point=None, affine_to_rasmm=None)ΒΆ
+
+
Parameters:
+
+
streamlinesiterable of ndarrays or ArraySequence, optional

Sequence of \(T\) streamlines. Each streamline is an ndarray of +shape (\(N_t\), 3) where \(N_t\) is the number of points of +streamline \(t\).

+
+
data_per_streamlinedict of iterable of ndarrays, optional

Dictionary where the items are (str, iterable). +Each key represents an information \(i\) to be kept alongside every +streamline, and its associated value is an iterable of ndarrays of +shape (\(P_i\),) where \(P_i\) is the number of scalar values to store +for that particular information \(i\).

+
+
data_per_pointdict of iterable of ndarrays, optional

Dictionary where the items are (str, iterable). +Each key represents an information \(i\) to be kept alongside every +point of every streamline, and its associated value is an iterable +of ndarrays of shape (\(N_t\), \(M_i\)) where \(N_t\) is the number of +points for a particular streamline \(t\) and \(M_i\) is the number +scalar values to store for that particular information \(i\).

+
+
affine_to_rasmmndarray of shape (4, 4) or None, optional

Transformation matrix that brings the streamlines contained in +this tractogram to RAS+ and mm space where coordinate (0,0,0) +refers to the center of the voxel. By default, the streamlines +are in an unknown space, i.e. affine_to_rasmm is None.

+
+
+
+
+
+ +
+
+property affine_to_rasmmΒΆ
+

Affine bringing streamlines in this tractogram to RAS+mm.

+
+ +
+
+apply_affine(affine, lazy=False)ΒΆ
+

Applies an affine transformation on the points of each streamline.

+

If lazy is not specified, this is performed in-place.

+
+
Parameters:
+
+
affinendarray of shape (4, 4)

Transformation that will be applied to every streamline.

+
+
lazy{False, True}, optional

If True, streamlines are not transformed in-place and a +LazyTractogram object is returned. Otherwise, streamlines +are modified in-place.

+
+
+
+
Returns:
+
+
tractogramTractogram or LazyTractogram object

Tractogram where the streamlines have been transformed according +to the given affine transformation. If the lazy option is true, +it returns a LazyTractogram object, otherwise it returns a +reference to this Tractogram object with updated +streamlines.

+
+
+
+
+
+ +
+
+copy()ΒΆ
+

Returns a copy of this Tractogram object.

+
+ +
+
+property data_per_pointΒΆ
+
+ +
+
+property data_per_streamlineΒΆ
+
+ +
+
+extend(other)ΒΆ
+

Appends the data of another Tractogram.

+

Data that will be appended includes the streamlines and the content +of both dictionaries data_per_streamline and data_per_point.

+
+
Parameters:
+
+
otherTractogram object

Its data will be appended to the data of this tractogram.

+
+
+
+
Returns:
+
+
None
+
+
+
+

Notes

+

The entries in both dictionaries self.data_per_streamline and +self.data_per_point must match respectively those contained in +the other tractogram.

+
+ +
+
+property streamlinesΒΆ
+
+ +
+
+to_world(lazy=False)ΒΆ
+

Brings the streamlines to world space (i.e. RAS+ and mm).

+

If lazy is not specified, this is performed in-place.

+
+
Parameters:
+
+
lazy{False, True}, optional

If True, streamlines are not transformed in-place and a +LazyTractogram object is returned. Otherwise, streamlines +are modified in-place.

+
+
+
+
Returns:
+
+
tractogramTractogram or LazyTractogram object

Tractogram where the streamlines have been sent to world space. +If the lazy option is true, it returns a LazyTractogram +object, otherwise it returns a reference to this +Tractogram object with updated streamlines.

+
+
+
+
+
+ +
+ +
+
+

TractogramItemΒΆ

+
+
+class nibabel.streamlines.tractogram.TractogramItem(streamline, data_for_streamline, data_for_points)ΒΆ
+

Bases: object

+

Class containing information about one streamline.

+

TractogramItem objects have three public attributes: streamline, +data_for_streamline, and data_for_points.

+
+
Parameters:
+
+
streamlinendarray shape (N, 3)

Points of this streamline represented as an ndarray of shape (N, 3) +where N is the number of points.

+
+
data_for_streamlinedict

Dictionary containing some data associated with this particular +streamline. Each key k is mapped to a ndarray of shape (Pt,), where +Pt is the dimension of the data associated with key k.

+
+
data_for_pointsdict

Dictionary containing some data associated to each point of this +particular streamline. Each key k is mapped to a ndarray of shape +(Nt, Mk), where Nt is the number of points of this streamline and +Mk is the dimension of the data associated with key k.

+
+
+
+
+
+
+__init__(streamline, data_for_streamline, data_for_points)ΒΆ
+
+ +
+ +
+
+

is_data_dictΒΆ

+
+
+nibabel.streamlines.tractogram.is_data_dict(obj)ΒΆ
+

True if obj seems to implement the DataDict API

+
+ +
+
+

is_lazy_dictΒΆ

+
+
+nibabel.streamlines.tractogram.is_lazy_dict(obj)ΒΆ
+

True if obj seems to implement the LazyDict API

+
+ +
+
+

DataErrorΒΆ

+
+
+class nibabel.streamlines.tractogram_file.DataErrorΒΆ
+

Bases: Exception

+

Raised when data is missing or inconsistent in a tractogram file.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

DataWarningΒΆ

+
+
+class nibabel.streamlines.tractogram_file.DataWarningΒΆ
+

Bases: Warning

+

Base class for warnings about tractogram file data.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

ExtensionWarningΒΆ

+
+
+class nibabel.streamlines.tractogram_file.ExtensionWarningΒΆ
+

Bases: Warning

+

Base class for warnings about tractogram file extension.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

HeaderErrorΒΆ

+
+
+class nibabel.streamlines.tractogram_file.HeaderErrorΒΆ
+

Bases: Exception

+

Raised when a tractogram file header contains invalid information.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

HeaderWarningΒΆ

+
+
+class nibabel.streamlines.tractogram_file.HeaderWarningΒΆ
+

Bases: Warning

+

Base class for warnings about tractogram file header.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

TractogramFileΒΆ

+
+
+class nibabel.streamlines.tractogram_file.TractogramFile(tractogram, header=None)ΒΆ
+

Bases: ABC

+

Convenience class to encapsulate tractogram file format.

+
+
+__init__(tractogram, header=None)ΒΆ
+
+ +
+
+property affineΒΆ
+

voxmm -> rasmm affine.

+
+ +
+
+classmethod create_empty_header()ΒΆ
+

Returns an empty header for this streamlines file format.

+
+ +
+
+property headerΒΆ
+
+ +
+
+abstract classmethod is_correct_format(fileobj)ΒΆ
+

Checks if the file has the right streamlines file format.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object +pointing to a streamlines file (and ready to read from the +beginning of the header).

+
+
+
+
Returns:
+
+
is_correct_format{True, False}

Returns True if fileobj is in the right streamlines file format, +otherwise returns False.

+
+
+
+
+
+ +
+
+abstract classmethod load(fileobj, lazy_load=True)ΒΆ
+

Loads streamlines from a filename or file-like object.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object +pointing to a streamlines file (and ready to read from the +beginning of the header).

+
+
lazy_load{False, True}, optional

If True, load streamlines in a lazy manner i.e. they will not be +kept in memory. Otherwise, load all streamlines in memory.

+
+
+
+
Returns:
+
+
tractogram_fileTractogramFile object

Returns an object containing tractogram data and header +information.

+
+
+
+
+
+ +
+
+abstract save(fileobj)ΒΆ
+

Saves streamlines to a filename or file-like object.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object +opened and ready to write.

+
+
+
+
+
+ +
+
+property streamlinesΒΆ
+
+ +
+
+property tractogramΒΆ
+
+ +
+ +
+
+

abstractclassmethodΒΆ

+
+
+class nibabel.streamlines.tractogram_file.abstractclassmethod(callable)ΒΆ
+

Bases: classmethod

+
+
+__init__(callable)ΒΆ
+
+ +
+ +
+
+

TrkFileΒΆ

+
+
+class nibabel.streamlines.trk.TrkFile(tractogram, header=None)ΒΆ
+

Bases: TractogramFile

+

Convenience class to encapsulate TRK file format.

+

Notes

+

TrackVis (so its file format: TRK) considers the streamline coordinate +(0,0,0) to be in the corner of the voxel whereas NiBabel’s streamlines +internal representation (Voxel space) assumes (0,0,0) to be in the +center of the voxel.

+

Thus, streamlines are shifted by half a voxel on load and are shifted +back on save.

+
+
Parameters:
+
+
tractogramTractogram object

Tractogram that will be contained in this TrkFile.

+
+
headerdict, optional

Metadata associated to this tractogram file.

+
+
+
+
+

Notes

+

Streamlines of the tractogram are assumed to be in RAS+ +and mm space where coordinate (0,0,0) refers to the center +of the voxel.

+
+
+__init__(tractogram, header=None)ΒΆ
+
+
Parameters:
+
+
tractogramTractogram object

Tractogram that will be contained in this TrkFile.

+
+
headerdict, optional

Metadata associated to this tractogram file.

+
+
+
+
+

Notes

+

Streamlines of the tractogram are assumed to be in RAS+ +and mm space where coordinate (0,0,0) refers to the center +of the voxel.

+
+ +
+
+HEADER_SIZE = 1000ΒΆ
+
+ +
+
+MAGIC_NUMBER = b'TRACK'ΒΆ
+
+ +
+
+SUPPORTS_DATA_PER_POINT = TrueΒΆ
+
+ +
+
+SUPPORTS_DATA_PER_STREAMLINE = TrueΒΆ
+
+ +
+
+classmethod create_empty_header(endianness=None)ΒΆ
+

Return an empty compliant TRK header as dict

+
+ +
+
+classmethod is_correct_format(fileobj)ΒΆ
+

Check if the file is in TRK format.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object +pointing to TRK file (and ready to read from the beginning +of the TRK header data). Note that calling this function +does not change the file position.

+
+
+
+
Returns:
+
+
is_correct_format{True, False}

Returns True if fileobj is compatible with TRK format, +otherwise returns False.

+
+
+
+
+
+ +
+
+classmethod load(fileobj, lazy_load=False)ΒΆ
+

Loads streamlines from a filename or file-like object.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object +pointing to TRK file (and ready to read from the beginning +of the TRK header). Note that calling this function +does not change the file position.

+
+
lazy_load{False, True}, optional

If True, load streamlines in a lazy manner i.e. they will not be +kept in memory. Otherwise, load all streamlines in memory.

+
+
+
+
Returns:
+
+
trk_fileTrkFile object

Returns an object containing tractogram data and header +information.

+
+
+
+
+

Notes

+

Streamlines of the returned tractogram are assumed to be in RAS +and mm space where coordinate (0,0,0) refers to the center of the +voxel.

+
+ +
+
+save(fileobj)ΒΆ
+

Save tractogram to a filename or file-like object using TRK format.

+
+
Parameters:
+
+
fileobjstring or file-like object

If string, a filename; otherwise an open file-like object +pointing to TRK file (and ready to write from the beginning +of the TRK header data).

+
+
+
+
+
+ +
+ +
+
+

decode_value_from_nameΒΆ

+
+
+nibabel.streamlines.trk.decode_value_from_name(encoded_name)ΒΆ
+

Decodes a value that has been encoded in the last bytes of a string.

+

Check encode_value_in_name() to see how the value has been encoded.

+
+
Parameters:
+
+
encoded_namebytes

Name in which a value has been encoded or not.

+
+
+
+
Returns:
+
+
namebytes

Name without the encoded value.

+
+
valueint

Value decoded from the name.

+
+
+
+
+
+ +
+
+

encode_value_in_nameΒΆ

+
+
+nibabel.streamlines.trk.encode_value_in_name(value, name, max_name_len=20)ΒΆ
+

Return name as fixed-length string, appending value as string.

+

Form output from name if value <= 1 else name + \ + +str(value).

+

Return output as fixed length string length max_name_len, padded with +\.

+

This function also verifies that the modified length of name is less than +max_name_len.

+
+
Parameters:
+
+
valueint

Integer value to encode.

+
+
namestr

Name to which we may append an ascii / latin-1 representation of +value.

+
+
max_name_lenint, optional

Maximum length of byte string that output can have.

+
+
+
+
Returns:
+
+
encoded_namebytes

Name maybe followed by \ and ascii / latin-1 representation of +value, padded with \ bytes.

+
+
+
+
+
+ +
+
+

get_affine_rasmm_to_trackvisΒΆ

+
+
+nibabel.streamlines.trk.get_affine_rasmm_to_trackvis(header)ΒΆ
+
+ +
+
+

get_affine_trackvis_to_rasmmΒΆ

+
+
+nibabel.streamlines.trk.get_affine_trackvis_to_rasmm(header)ΒΆ
+

Get affine mapping trackvis voxelmm space to RAS+ mm space

+

The streamlines in a trackvis file are in β€˜voxelmm’ space, where the +coordinates refer to the corner of the voxel.

+

Compute the affine matrix that will bring them back to RAS+ mm space, where +the coordinates refer to the center of the voxel.

+
+
Parameters:
+
+
headerdict or ndarray

Dict or numpy structured array containing trackvis header.

+
+
+
+
Returns:
+
+
aff_tv2rasshape (4, 4) array

Affine array mapping coordinates in β€˜voxelmm’ space to RAS+ mm space.

+
+
+
+
+
+ +
+
+

get_affine_from_referenceΒΆ

+
+
+nibabel.streamlines.utils.get_affine_from_reference(ref)ΒΆ
+

Returns the affine defining the reference space.

+
+
Parameters:
+
+
refstr or Nifti1Image object or ndarray shape (4, 4)

If str then it’s the filename of reference file that will be loaded +using nibabel.load() in order to obtain the affine. +If Nifti1Image object then the affine is obtained from it. +If ndarray shape (4, 4) then it’s the affine.

+
+
+
+
Returns:
+
+
affinendarray (4, 4)

Transformation matrix mapping voxel space to RAS+mm space.

+
+
+
+
+
+ +
+
+

peek_nextΒΆ

+
+
+nibabel.streamlines.utils.peek_next(iterable)ΒΆ
+

Peek next element of iterable.

+
+
Parameters:
+
+
iterable

Iterable to peek the next element from.

+
+
+
+
Returns:
+
+
next_item

Element peeked from iterable.

+
+
new_iterable

Iterable behaving like if the original iterable was untouched.

+
+
+
+
+
+ +
+
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.tmpdirs.html b/reference/nibabel.tmpdirs.html new file mode 100644 index 0000000000..7dfb8ecaa5 --- /dev/null +++ b/reference/nibabel.tmpdirs.html @@ -0,0 +1,260 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

tmpdirsΒΆ

+

Contexts for with statement providing temporary directories

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

TemporaryDirectory([suffix,Β prefix,Β dir])

Create and return a temporary directory.

InGivenDirectory([path])

Change directory to given directory for duration of with block

InTemporaryDirectory()

Create, return, and change directory to a temporary directory

+
+

TemporaryDirectoryΒΆ

+
+
+class nibabel.tmpdirs.TemporaryDirectory(suffix='', prefix='tmp', dir=None)ΒΆ
+

Bases: TemporaryDirectory

+

Create and return a temporary directory. This has the same +behavior as mkdtemp but can be used as a context manager.

+

Upon exiting the context, the directory and everything contained +in it are removed.

+

Please use the standard library tempfile.TemporaryDirectory

+
    +
  • deprecated from version: 5.0

  • +
  • Will raise <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 7.0

  • +
+

Examples

+
>>> import os
+>>> with TemporaryDirectory() as tmpdir:
+...     fname = os.path.join(tmpdir, 'example_file.txt')
+...     with open(fname, 'wt') as fobj:
+...         _ = fobj.write('a string\n')
+>>> os.path.exists(tmpdir)
+False
+
+
+
+
+__init__(suffix='', prefix='tmp', dir=None)ΒΆ
+

Please use the standard library tempfile.TemporaryDirectory

+
    +
  • deprecated from version: 5.0

  • +
  • Will raise <class β€˜nibabel.deprecator.ExpiredDeprecationError’> as of version: 7.0

  • +
+

Examples

+
>>> import os
+>>> with TemporaryDirectory() as tmpdir:
+...     fname = os.path.join(tmpdir, 'example_file.txt')
+...     with open(fname, 'wt') as fobj:
+...         _ = fobj.write('a string\n')
+>>> os.path.exists(tmpdir)
+False
+
+
+
+ +
+ +
+
+

InGivenDirectoryΒΆ

+
+
+nibabel.tmpdirs.InGivenDirectory(path=None)ΒΆ
+

Change directory to given directory for duration of with block

+

Useful when you want to use InTemporaryDirectory for the final test, but +you are still debugging. For example, you may want to do this in the end:

+
>>> with InTemporaryDirectory() as tmpdir:
+...     # do something complicated which might break
+...     pass
+
+
+

But indeed the complicated thing does break, and meanwhile the +InTemporaryDirectory context manager wiped out the directory with the +temporary files that you wanted for debugging. So, while debugging, you +replace with something like:

+
>>> with InGivenDirectory() as tmpdir: # Use working directory by default
+...     # do something complicated which might break
+...     pass
+
+
+

You can then look at the temporary file outputs to debug what is happening, +fix, and finally replace InGivenDirectory with InTemporaryDirectory +again.

+
+
Parameters:
+
+
pathNone or str, optional

path to change directory to, for duration of with block. +Defaults to os.getcwd() if None

+
+
+
+
+
+ +
+
+

InTemporaryDirectoryΒΆ

+
+
+nibabel.tmpdirs.InTemporaryDirectory()ΒΆ
+

Create, return, and change directory to a temporary directory

+

Notes

+

As its name suggests, the class temporarily changes the working +directory of the Python process, and this is not thread-safe. We suggest +using it only for tests.

+

Examples

+
>>> import os
+>>> from pathlib import Path
+>>> my_cwd = os.getcwd()
+>>> with InTemporaryDirectory() as tmpdir:
+...     _ = Path('test.txt').write_text('some text')
+...     assert os.path.isfile('test.txt')
+...     assert os.path.isfile(os.path.join(tmpdir, 'test.txt'))
+>>> os.path.exists(tmpdir)
+False
+>>> os.getcwd() == my_cwd
+True
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.tripwire.html b/reference/nibabel.tripwire.html new file mode 100644 index 0000000000..ce31e51271 --- /dev/null +++ b/reference/nibabel.tripwire.html @@ -0,0 +1,206 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

tripwireΒΆ

+

Class to raise error for missing modules or other misfortunes

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

TripWire(msg)

Class raising error if used

TripWireError

Exception if trying to use TripWire object

is_tripwire(obj)

Returns True if obj appears to be a TripWire object

+
+

TripWireΒΆ

+
+
+class nibabel.tripwire.TripWire(msg: str)ΒΆ
+

Bases: object

+

Class raising error if used

+

Standard use is to proxy modules that we could not import

+

Examples

+
>>> a_module = TripWire('We do not have a_module')
+>>> a_module.do_silly_thing('with silly string') 
+Traceback (most recent call last):
+    ...
+TripWireError: We do not have a_module
+
+
+
+
+__init__(msg: str) NoneΒΆ
+
+ +
+ +
+
+

TripWireErrorΒΆ

+
+
+class nibabel.tripwire.TripWireErrorΒΆ
+

Bases: AttributeError

+

Exception if trying to use TripWire object

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

is_tripwireΒΆ

+
+
+nibabel.tripwire.is_tripwire(obj: Any) boolΒΆ
+

Returns True if obj appears to be a TripWire object

+

Examples

+
>>> is_tripwire(object())
+False
+>>> is_tripwire(TripWire('some message'))
+True
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.viewers.html b/reference/nibabel.viewers.html new file mode 100644 index 0000000000..89f1411719 --- /dev/null +++ b/reference/nibabel.viewers.html @@ -0,0 +1,319 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

viewersΒΆ

+

Utilities for viewing images

+

Includes version of OrthoSlicer3D code originally written by our own +Paul Ivanov.

+ + + + + + +

OrthoSlicer3D(data[,Β affine,Β axes,Β title])

Orthogonal-plane slice viewer

+
+

OrthoSlicer3DΒΆ

+
+
+class nibabel.viewers.OrthoSlicer3D(data, affine=None, axes=None, title=None)ΒΆ
+

Bases: object

+

Orthogonal-plane slice viewer

+

OrthoSlicer3d expects 3- or 4-dimensional array data. It treats +4D data as a sequence of 3D spatial volumes, where a slice over the final +array axis gives a single 3D spatial volume.

+

For 3D data, the default behavior is to create a figure with 3 axes, one +for each slice orientation of the spatial volume.

+

Clicking and dragging the mouse in any one axis will select out the +corresponding slices in the other two. Scrolling up and +down moves the slice up and down in the current axis.

+

For 4D data, the fourth figure axis can be used to control which +3D volume is displayed. Alternatively, the - key can be used to +decrement the displayed volume and the + or = keys can be used to +increment it.

+

Examples

+
>>> import numpy as np
+>>> a = np.sin(np.linspace(0, np.pi, 20))
+>>> b = np.sin(np.linspace(0, np.pi*5, 20))
+>>> data = np.outer(a, b)[..., np.newaxis] * a
+>>> OrthoSlicer3D(data).show()  
+
+
+
+
Parameters:
+
+
dataarray-like

The data that will be displayed by the slicer. Should have 3+ +dimensions.

+
+
affinearray-like or None, optional

Affine transform for the data. This is used to determine +how the data should be sliced for plotting into the sagittal, +coronal, and axial view axes. If None, identity is assumed. +The aspect ratio of the data are inferred from the affine +transform.

+
+
axestuple of mpl.Axes or None, optional

3 or 4 axes instances for the 3 slices plus volumes, +or None (default).

+
+
titlestr or None, optional

The title to display. Can be None (default) to display no +title.

+
+
+
+
+
+
+__init__(data, affine=None, axes=None, title=None)ΒΆ
+
+
Parameters:
+
+
dataarray-like

The data that will be displayed by the slicer. Should have 3+ +dimensions.

+
+
affinearray-like or None, optional

Affine transform for the data. This is used to determine +how the data should be sliced for plotting into the sagittal, +coronal, and axial view axes. If None, identity is assumed. +The aspect ratio of the data are inferred from the affine +transform.

+
+
axestuple of mpl.Axes or None, optional

3 or 4 axes instances for the 3 slices plus volumes, +or None (default).

+
+
titlestr or None, optional

The title to display. Can be None (default) to display no +title.

+
+
+
+
+
+ +
+
+property climΒΆ
+

The current color limits

+
+ +
+
+close()ΒΆ
+

Close the viewer figures

+
+ +
+
+property cmapΒΆ
+

The current colormap

+
+ +
+
+draw()ΒΆ
+

Redraw the current image

+
+ +
+
+property figsΒΆ
+

A tuple of the figure(s) containing the axes

+
+ +
+ +

Link positional changes between two canvases

+
+
Parameters:
+
+
otherinstance of OrthoSlicer3D

Other viewer to use to link movements.

+
+
+
+
+
+ +
+
+property n_volumesΒΆ
+

Number of volumes in the data

+
+ +
+
+property positionΒΆ
+

The current coordinates

+
+ +
+
+set_position(x=None, y=None, z=None)ΒΆ
+

Set current displayed slice indices

+
+
Parameters:
+
+
xfloat | None

X coordinate to use. If None, do not change.

+
+
yfloat | None

Y coordinate to use. If None, do not change.

+
+
zfloat | None

Z coordinate to use. If None, do not change.

+
+
+
+
+
+ +
+
+set_volume_idx(v)ΒΆ
+

Set current displayed volume index

+
+
Parameters:
+
+
vint

Volume index.

+
+
+
+
+
+ +
+
+show()ΒΆ
+

Show the slicer in blocking mode; convenience for plt.show()

+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.volumeutils.html b/reference/nibabel.volumeutils.html new file mode 100644 index 0000000000..ce55e2582a --- /dev/null +++ b/reference/nibabel.volumeutils.html @@ -0,0 +1,1123 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

volumeutilsΒΆ

+

Utility functions for analyze-like formats

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

DtypeMapper()

Specialized mapper for numpy dtypes

Recoder(codes,Β fields,Β map_maker,Β ...)

class to return canonical code(s) from code or aliases

apply_read_scaling(arr[,Β slope,Β inter])

Apply scaling in slope and inter to array arr

array_from_file(shape,Β in_dtype,Β infile[,Β ...])

Get array from file with specified shape, dtype and file offset

array_to_file(data,Β fileobj[,Β out_dtype,Β ...])

Helper function for writing arrays to file objects

best_write_scale_ftype(arr[,Β slope,Β inter,Β ...])

Smallest float type to contain range of arr after scaling

better_float_of(first,Β second[,Β default])

Return more capable float type of first and second

finite_range()

Get range (min, max) or range and flag (min, max, has_nan) from arr

fname_ext_ul_case(fname)

fname with ext changed to upper / lower case if file exists

int_scinter_ftype(ifmt[,Β slope,Β inter,Β default])

float type containing int type ifmt * slope + inter

make_dt_codes(codes_seqs)

Create full dt codes Recoder instance from datatype codes

pretty_mapping(mapping[,Β getterfunc])

Make pretty string from mapping

rec2dict(rec)

Convert recarray to dictionary

seek_tell(fileobj,Β offset[,Β write0])

Seek in fileobj or check we're in the right place already

shape_zoom_affine(shape,Β zooms[,Β x_flip])

Get affine implied by given shape and zooms

working_type(in_type[,Β slope,Β inter])

Return array type from applying slope, inter to array of in_type

write_zeros(fileobj,Β count[,Β block_size])

Write count zero bytes to fileobj

+
+

DtypeMapperΒΆ

+
+
+class nibabel.volumeutils.DtypeMapperΒΆ
+

Bases: Dict[Hashable, Hashable]

+

Specialized mapper for numpy dtypes

+

We pass this mapper into the Recoder class to deal with numpy dtype +hashing.

+

The hashing problem is that dtypes that compare equal may not have the same +hash. This is true for numpys up to the current at time of writing +(1.6.0). For numpy 1.2.1 at least, even dtypes that look exactly the same +in terms of fields don’t always have the same hash. This makes dtypes +difficult to use as keys in a dictionary.

+

This class wraps a dictionary in order to implement a __getitem__ to deal +with dtype hashing. If the key doesn’t appear to be in the mapping, and it +is a dtype, we compare (using ==) all known dtype keys to the input key, +and return any matching values for the matching key.

+
+
+__init__() NoneΒΆ
+
+ +
+ +
+
+

RecoderΒΆ

+
+
+class nibabel.volumeutils.Recoder(codes: ~typing.Sequence[~typing.Sequence[~typing.Hashable]], fields: ~typing.Sequence[str] = ('code',), map_maker: type[~typing.Mapping[~typing.Hashable, ~typing.Hashable]] = <class 'dict'>)ΒΆ
+

Bases: object

+

class to return canonical code(s) from code or aliases

+

The concept is a lot easier to read in the implementation and +tests than it is to explain, so…

+
>>> # If you have some codes, and several aliases, like this:
+>>> code1 = 1; aliases1=['one', 'first']
+>>> code2 = 2; aliases2=['two', 'second']
+>>> # You might want to do this:
+>>> codes = [[code1]+aliases1,[code2]+aliases2]
+>>> recodes = Recoder(codes)
+>>> recodes.code['one']
+1
+>>> recodes.code['second']
+2
+>>> recodes.code[2]
+2
+>>> # Or maybe you have a code, a label and some aliases
+>>> codes=((1,'label1','one', 'first'),(2,'label2','two'))
+>>> # you might want to get back the code or the label
+>>> recodes = Recoder(codes, fields=('code','label'))
+>>> recodes.code['first']
+1
+>>> recodes.code['label1']
+1
+>>> recodes.label[2]
+'label2'
+>>> # For convenience, you can get the first entered name by
+>>> # indexing the object directly
+>>> recodes[2]
+2
+
+
+

Create recoder object

+

codes give a sequence of code, alias sequences +fields are names by which the entries in these sequences can be +accessed.

+

By default fields gives the first column the name +β€œcode”. The first column is the vector of first entries +in each of the sequences found in codes. Thence you can +get the equivalent first column value with ob.code[value], +where value can be a first column value, or a value in any of +the other columns in that sequence.

+

You can give other columns names too, and access them in the +same way - see the examples in the class docstring.

+
+
Parameters:
+
+
codessequence of sequences

Each sequence defines values (codes) that are equivalent

+
+
fields{(β€˜code’,) string sequence}, optional

names by which elements in sequences can be accessed

+
+
map_maker: callable, optional

constructor for dict-like objects used to store key value pairs. +Default is dict. map_maker() generates an empty mapping. +The mapping need only implement __getitem__, __setitem__, keys, +values.

+
+
+
+
+
+
+__init__(codes: ~typing.Sequence[~typing.Sequence[~typing.Hashable]], fields: ~typing.Sequence[str] = ('code',), map_maker: type[~typing.Mapping[~typing.Hashable, ~typing.Hashable]] = <class 'dict'>)ΒΆ
+

Create recoder object

+

codes give a sequence of code, alias sequences +fields are names by which the entries in these sequences can be +accessed.

+

By default fields gives the first column the name +β€œcode”. The first column is the vector of first entries +in each of the sequences found in codes. Thence you can +get the equivalent first column value with ob.code[value], +where value can be a first column value, or a value in any of +the other columns in that sequence.

+

You can give other columns names too, and access them in the +same way - see the examples in the class docstring.

+
+
Parameters:
+
+
codessequence of sequences

Each sequence defines values (codes) that are equivalent

+
+
fields{(β€˜code’,) string sequence}, optional

names by which elements in sequences can be accessed

+
+
map_maker: callable, optional

constructor for dict-like objects used to store key value pairs. +Default is dict. map_maker() generates an empty mapping. +The mapping need only implement __getitem__, __setitem__, keys, +values.

+
+
+
+
+
+ +
+
+add_codes(code_syn_seqs: Sequence[Sequence[Hashable]]) NoneΒΆ
+

Add codes to object

+
+
Parameters:
+
+
code_syn_seqssequence

sequence of sequences, where each sequence S = code_syn_seqs[n] +for n in 0..len(code_syn_seqs), is a sequence giving values in the +same order as self.fields. Each S should be at least of the +same length as self.fields. After this call, if self.fields +== ['field1', 'field2'], then ``self.field1[S[n]] == S[0] for all +n in 0..len(S) and self.field2[S[n]] == S[1] for all n in +0..len(S).

+
+
+
+
+

Examples

+
>>> code_syn_seqs = ((2, 'two'), (1, 'one'))
+>>> rc = Recoder(code_syn_seqs)
+>>> rc.value_set() == set((1,2))
+True
+>>> rc.add_codes(((3, 'three'), (1, 'first')))
+>>> rc.value_set() == set((1,2,3))
+True
+>>> print(rc.value_set())  # set is actually ordered
+OrderedSet([2, 1, 3])
+
+
+
+ +
+
+fields: tuple[str, ...]ΒΆ
+
+ +
+
+keys()ΒΆ
+

Return all available code and alias values

+

Returns same value as obj.field1.keys() and, with the +default initializing fields argument of fields=(β€˜code’,), +this will return the same as obj.code.keys()

+
>>> codes = ((1, 'one'), (2, 'two'), (1, 'repeat value'))
+>>> k = Recoder(codes).keys()
+>>> set(k) == set([1, 2, 'one', 'repeat value', 'two'])
+True
+
+
+
+ +
+
+value_set(name: str | None = None) OrderedSetΒΆ
+

Return OrderedSet of possible returned values for column

+

By default, the column is the first column.

+

Returns same values as set(obj.field1.values()) and, +with the default initializing``fields`` argument of +fields=(β€˜code’,), this will return the same as +set(obj.code.values())

+
+
Parameters:
+
+
name{None, string}

Where default of none gives result for first column

+
+
>>> codes = ((1, β€˜one’), (2, β€˜two’), (1, β€˜repeat value’))
+
>>> vs = Recoder(codes).value_set()
+
>>> vs == set([1, 2]) # Sets are not ordered, hence this test
+
True
+
>>> rc = Recoder(codes, fields=(β€˜code’, β€˜label’))
+
>>> rc.value_set(β€˜label’) == set((β€˜one’, β€˜two’, β€˜repeat value’))
+
True
+
+
+
+
+ +
+ +
+
+

apply_read_scalingΒΆ

+
+
+nibabel.volumeutils.apply_read_scaling(arr: np.ndarray, slope: Scalar | None = None, inter: Scalar | None = None) np.ndarrayΒΆ
+

Apply scaling in slope and inter to array arr

+

This is for loading the array from a file (as opposed to the reverse +scaling when saving an array to file)

+

Return data will be arr * slope + inter. The trick is that we have to +find a good precision to use for applying the scaling. The heuristic is +that the data is always upcast to the higher of the types from arr, +`slope, inter if slope and / or inter are not default values. If the +dtype of arr is an integer, then we assume the data more or less fills +the integer range, and upcast to a type such that the min, max of +arr.dtype * scale + inter, will be finite.

+
+
Parameters:
+
+
arrarray-like
+
slopeNone or float, optional

slope value to apply to arr (arr * slope + inter). None +corresponds to a value of 1.0

+
+
interNone or float, optional

intercept value to apply to arr (arr * slope + inter). None +corresponds to a value of 0.0

+
+
+
+
Returns:
+
+
retarray

array with scaling applied. Maybe upcast in order to give room for the +scaling. If scaling is default (1, 0), then ret may be arr ret is +arr.

+
+
+
+
+
+ +
+
+

array_from_fileΒΆ

+
+
+nibabel.volumeutils.array_from_file(shape: tuple[int, ...], in_dtype: np.dtype[DT], infile: io.IOBase, offset: int = 0, order: ty.Literal['C', 'F'] = 'F', mmap: bool | ty.Literal['c', 'r', 'r+'] = True) npt.NDArray[DT]ΒΆ
+

Get array from file with specified shape, dtype and file offset

+
+
Parameters:
+
+
shapesequence

sequence specifying output array shape

+
+
in_dtypenumpy dtype

fully specified numpy dtype, including correct endianness

+
+
infilefile-like

open file-like object implementing at least read() and seek()

+
+
offsetint, optional

offset in bytes into infile to start reading array data. Default is 0

+
+
order{β€˜F’, β€˜C’} string

order in which to write data. Default is β€˜F’ (fortran order).

+
+
mmap{True, False, β€˜c’, β€˜r’, β€˜r+’}

mmap controls the use of numpy memory mapping for reading data. If +False, do not try numpy memmap for data array. If one of {β€˜c’, +β€˜r’, β€˜r+’}, try numpy memmap with mode=mmap. A mmap value of +True gives the same behavior as mmap='c'. If infile cannot be +memory-mapped, ignore mmap value and read array from file.

+
+
+
+
Returns:
+
+
arrarray-like

array like object that can be sliced, containing data

+
+
+
+
+

Examples

+
>>> from io import BytesIO
+>>> bio = BytesIO()
+>>> arr = np.arange(6).reshape(1,2,3)
+>>> _ = bio.write(arr.tobytes('F'))  # outputs int
+>>> arr2 = array_from_file((1,2,3), arr.dtype, bio)
+>>> np.all(arr == arr2)
+True
+>>> bio = BytesIO()
+>>> _ = bio.write(b' ' * 10)
+>>> _ = bio.write(arr.tobytes('F'))
+>>> arr2 = array_from_file((1,2,3), arr.dtype, bio, 10)
+>>> np.all(arr == arr2)
+True
+
+
+
+ +
+
+

array_to_fileΒΆ

+
+
+nibabel.volumeutils.array_to_file(data: npt.ArrayLike, fileobj: io.IOBase, out_dtype: np.dtype | None = None, offset: int = 0, intercept: Scalar = 0.0, divslope: Scalar | None = 1.0, mn: Scalar | None = None, mx: Scalar | None = None, order: ty.Literal['C', 'F'] = 'F', nan2zero: bool = True) NoneΒΆ
+

Helper function for writing arrays to file objects

+

Writes arrays as scaled by intercept and divslope, and clipped +at (prescaling) mn minimum, and mx maximum.

+
    +
  • Clip data array at min mn, max max where there are not None -> +clipped (this is pre scale clipping)

  • +
  • Scale clipped with clipped_scaled = (clipped - intercept) / +divslope

  • +
  • Clip clipped_scaled to fit into range of out_dtype (post scale +clipping) -> clipped_scaled_clipped

  • +
  • If converting to integer out_dtype and nan2zero is True, set NaN +values in clipped_scaled_clipped to 0

  • +
  • Write clipped_scaled_clipped_n2z to fileobj fileobj starting at +offset offset in memory layout order

  • +
+
+
Parameters:
+
+
dataarray-like

array or array-like to write.

+
+
fileobjfile-like

file-like object implementing write method.

+
+
out_dtypeNone or dtype, optional

dtype to write array as. Data array will be coerced to this dtype +before writing. If None (default) then use input data type.

+
+
offsetNone or int, optional

offset into fileobj at which to start writing data. Default is 0. None +means start at current file position

+
+
interceptscalar, optional

scalar to subtract from data, before dividing by divslope. Default +is 0.0

+
+
divslopeNone or scalar, optional

scalefactor to divide data by before writing. Default is 1.0. If +None, there is no valid data, we write zeros.

+
+
mnscalar, optional

minimum threshold in (unscaled) data, such that all data below this +value are set to this value. Default is None (no threshold). The +typical use is to set -np.inf in the data to have this value (which +might be the minimum non-finite value in the data).

+
+
mxscalar, optional

maximum threshold in (unscaled) data, such that all data above this +value are set to this value. Default is None (no threshold). The +typical use is to set np.inf in the data to have this value (which +might be the maximum non-finite value in the data).

+
+
order{β€˜F’, β€˜C’}, optional

memory order to write array. Default is β€˜F’

+
+
nan2zero{True, False}, optional

Whether to set NaN values to 0 when writing integer output. Defaults +to True. If False, NaNs will be represented as numpy does when +casting; this depends on the underlying C library and is undefined. In +practice nan2zero == False might be a good choice when you completely +sure there will be no NaNs in the data. This value ignored for float +output types. NaNs are treated as zero before applying intercept +and divslope - so an array [np.nan] with an intercept of 10 +becomes [-10] after conversion to integer out_dtype with +nan2zero set. That is because you will likely apply divslope and +intercept in reverse order when reading the data back, returning the +zero you probably expected from the input NaN.

+
+
+
+
+

Examples

+
>>> from io import BytesIO
+>>> sio = BytesIO()
+>>> data = np.arange(10, dtype=np.float64)
+>>> array_to_file(data, sio, np.float64)
+>>> sio.getvalue() == data.tobytes('F')
+True
+>>> _ = sio.truncate(0); _ = sio.seek(0)  # outputs 0
+>>> array_to_file(data, sio, np.int16)
+>>> sio.getvalue() == data.astype(np.int16).tobytes()
+True
+>>> _ = sio.truncate(0); _ = sio.seek(0)
+>>> array_to_file(data.byteswap(), sio, np.float64)
+>>> sio.getvalue() == data.byteswap().tobytes('F')
+True
+>>> _ = sio.truncate(0); _ = sio.seek(0)
+>>> array_to_file(data, sio, np.float64, order='C')
+>>> sio.getvalue() == data.tobytes('C')
+True
+
+
+
+ +
+
+

best_write_scale_ftypeΒΆ

+
+
+nibabel.volumeutils.best_write_scale_ftype(arr: np.ndarray, slope: npt.ArrayLike = 1.0, inter: npt.ArrayLike = 0.0, default: type[np.number] = <class 'numpy.float32'>) type[np.floating]ΒΆ
+

Smallest float type to contain range of arr after scaling

+

Scaling that will be applied to arr is (arr - inter) / slope.

+

Note that slope and inter get promoted to 1D arrays for this +purpose to avoid the numpy scalar casting rules, which prevent scalars +upcasting the array.

+
+
Parameters:
+
+
arrarray-like

array that will be scaled

+
+
slopearray-like, optional

scalar such that output array will be (arr - inter) / slope.

+
+
interarray-like, optional

scalar such that output array will be (arr - inter) / slope

+
+
defaultnumpy type, optional

minimum float type to return

+
+
+
+
Returns:
+
+
ftypenumpy type

Best floating point type for scaling. If no floating point type +prevents overflow, return the top floating point type. If the input +array arr already contains inf values, return the greater of the +input type and the default type.

+
+
+
+
+

Examples

+
>>> arr = np.array([0, 1, 2], dtype=np.int16)
+>>> best_write_scale_ftype(arr, 1, 0) is np.float32
+True
+
+
+

Specify higher default return value

+
>>> best_write_scale_ftype(arr, 1, 0, default=np.float64) is np.float64
+True
+
+
+

Even large values that don’t overflow don’t change output

+
>>> arr = np.array([0, np.finfo(np.float32).max], dtype=np.float32)
+>>> best_write_scale_ftype(arr, 1, 0) is np.float32
+True
+
+
+

Scaling > 1 reduces output values, so no upcast needed

+
>>> best_write_scale_ftype(arr, np.float32(2), 0) is np.float32
+True
+
+
+

Scaling < 1 increases values, so upcast may be needed (and is here)

+
>>> best_write_scale_ftype(arr, np.float32(0.5), 0) is np.float64
+True
+
+
+
+ +
+
+

better_float_ofΒΆ

+
+
+nibabel.volumeutils.better_float_of(first: npt.DTypeLike, second: npt.DTypeLike, default: type[np.floating] = <class 'numpy.float32'>) type[np.floating]ΒΆ
+

Return more capable float type of first and second

+

Return default if neither of first or second is a float

+
+
Parameters:
+
+
firstnumpy type specifier

Any valid input to np.dtype()`

+
+
secondnumpy type specifier

Any valid input to np.dtype()`

+
+
defaultnumpy type specifier, optional

Any valid input to np.dtype()`

+
+
+
+
Returns:
+
+
better_typenumpy type

More capable of first or second if both are floats; if only one is +a float return that, otherwise return default.

+
+
+
+
+

Examples

+
>>> better_float_of(np.float32, np.float64) is np.float64
+True
+>>> better_float_of(np.float32, 'i4') is np.float32
+True
+>>> better_float_of('i2', 'u4') is np.float32
+True
+>>> better_float_of('i2', 'u4', np.float64) is np.float64
+True
+
+
+
+ +
+
+

finite_rangeΒΆ

+
+
+nibabel.volumeutils.finite_range(arr: npt.ArrayLike, check_nan: Literal[False] = False) tuple[Scalar, Scalar]ΒΆ
+
+nibabel.volumeutils.finite_range(arr: npt.ArrayLike, check_nan: Literal[True]) tuple[Scalar, Scalar, bool]
+

Get range (min, max) or range and flag (min, max, has_nan) from arr

+
+
Parameters:
+
+
arrarray-like
+
check_nan{False, True}, optional

Whether to return third output, a bool signaling whether there are NaN +values in arr

+
+
+
+
Returns:
+
+
mnscalar

minimum of values in (flattened) array

+
+
mxscalar

maximum of values in (flattened) array

+
+
has_nanbool

Returned if check_nan is True. has_nan is True if there are one or +more NaN values in arr

+
+
+
+
+

Examples

+
>>> a = np.array([[-1, 0, 1],[np.inf, np.nan, -np.inf]])
+>>> finite_range(a)
+(-1.0, 1.0)
+>>> a = np.array([[-1, 0, 1],[np.inf, np.nan, -np.inf]])
+>>> finite_range(a, check_nan=True)
+(-1.0, 1.0, True)
+>>> a = np.array([[np.nan],[np.nan]])
+>>> finite_range(a) == (np.inf, -np.inf)
+True
+>>> a = np.array([[-3, 0, 1],[2,-1,4]], dtype=int)
+>>> finite_range(a)
+(-3, 4)
+>>> a = np.array([[1, 0, 1],[2,3,4]], dtype=np.uint)
+>>> finite_range(a)
+(0, 4)
+>>> a = a + 1j
+>>> finite_range(a)
+(1j, (4+1j))
+>>> a = np.zeros((2,), dtype=[('f1', 'i2')])
+>>> finite_range(a)
+Traceback (most recent call last):
+   ...
+TypeError: Can only handle numeric types
+
+
+
+ +
+
+

fname_ext_ul_caseΒΆ

+
+
+nibabel.volumeutils.fname_ext_ul_case(fname: str) strΒΆ
+

fname with ext changed to upper / lower case if file exists

+

Check for existence of fname. If it does exist, return unmodified. If +it doesn’t, check for existence of fname with case changed from lower to +upper, or upper to lower. Return this modified fname if it exists. +Otherwise return fname unmodified

+
+
Parameters:
+
+
fnamestr

filename.

+
+
+
+
Returns:
+
+
mod_fnamestr

filename, maybe with extension of opposite case

+
+
+
+
+
+ +
+
+

int_scinter_ftypeΒΆ

+
+
+nibabel.volumeutils.int_scinter_ftype(ifmt: type[np.integer], slope: npt.ArrayLike = 1.0, inter: npt.ArrayLike = 0.0, default: type[np.floating] = <class 'numpy.float32'>) type[np.floating]ΒΆ
+

float type containing int type ifmt * slope + inter

+

Return float type that can represent the max and the min of the ifmt type +after multiplication with slope and addition of inter with something +like np.array([imin, imax], dtype=ifmt) * slope + inter.

+

Note that slope and inter get promoted to 1D arrays for this +purpose to avoid the numpy scalar casting rules, which prevent scalars +upcasting the array.

+
+
Parameters:
+
+
ifmtobject

numpy integer type (e.g. np.int32)

+
+
slopefloat, optional

slope, default 1.0

+
+
interfloat, optional

intercept, default 0.0

+
+
default_outobject, optional

numpy floating point type, default is np.float32

+
+
+
+
Returns:
+
+
ftypeobject

numpy floating point type

+
+
+
+
+

Notes

+

It is difficult to make floats overflow with just addition because the +deltas are so large at the extremes of floating point. For example:

+
>>> arr = np.array([np.finfo(np.float32).max], dtype=np.float32)
+>>> res = arr + np.iinfo(np.int16).max
+>>> arr == res
+array([ True])
+
+
+

Examples

+
>>> int_scinter_ftype(np.int8, 1.0, 0.0) == np.float32
+True
+>>> int_scinter_ftype(np.int8, 1e38, 0.0) == np.float64
+True
+
+
+
+ +
+
+

make_dt_codesΒΆ

+
+
+nibabel.volumeutils.make_dt_codes(codes_seqs: Sequence[Sequence]) RecoderΒΆ
+

Create full dt codes Recoder instance from datatype codes

+

Include created numpy dtype (from numpy type) and opposite endian +numpy dtype

+
+
Parameters:
+
+
codes_seqssequence of sequences

contained sequences make be length 3 or 4, but must all be the same +length. Elements are data type code, data type name, and numpy +type (such as np.float32). The fourth element is the nifti string +representation of the code (e.g. β€œNIFTI_TYPE_FLOAT32”)

+
+
+
+
Returns:
+
+
recRecoder instance

Recoder that, by default, returns code when indexed with any +of the corresponding code, name, type, dtype, or swapped dtype. +You can also index with niistring values if codes_seqs had sequences +of length 4 instead of 3.

+
+
+
+
+
+ +
+
+

pretty_mappingΒΆ

+
+
+nibabel.volumeutils.pretty_mapping(mapping: ty.Mapping[K, V], getterfunc: ty.Callable[[ty.Mapping[K, V], K], V] | None = None) strΒΆ
+

Make pretty string from mapping

+

Adjusts text column to print values on basis of longest key. +Probably only sensible if keys are mainly strings.

+

You can pass in a callable that does clever things to get the values +out of the mapping, given the names. By default, we just use +__getitem__

+
+
Parameters:
+
+
mappingmapping

implementing iterator returning keys and .items()

+
+
getterfuncNone or callable

callable taking two arguments, obj and key where obj +is the passed mapping. If None, just use lambda obj, key: +obj[key]

+
+
+
+
Returns:
+
+
strstring
+
+
+
+

Examples

+
>>> d = {'a key': 'a value'}
+>>> print(pretty_mapping(d))
+a key  : a value
+>>> class C: # to control ordering, show get_ method
+...     def __iter__(self):
+...         return iter(('short_field','longer_field'))
+...     def __getitem__(self, key):
+...         if key == 'short_field':
+...             return 0
+...         if key == 'longer_field':
+...             return 'str'
+...     def get_longer_field(self):
+...         return 'method string'
+>>> def getter(obj, key):
+...     # Look for any 'get_<name>' methods
+...     try:
+...         return obj.__getattribute__('get_' + key)()
+...     except AttributeError:
+...         return obj[key]
+>>> print(pretty_mapping(C(), getter))
+short_field   : 0
+longer_field  : method string
+
+
+
+ +
+
+

rec2dictΒΆ

+
+
+nibabel.volumeutils.rec2dict(rec: ndarray) dict[str, generic | ndarray]ΒΆ
+

Convert recarray to dictionary

+

Also converts scalar values to scalars

+
+
Parameters:
+
+
recndarray

structured ndarray

+
+
+
+
Returns:
+
+
dctdict

dict with key, value pairs as for rec

+
+
+
+
+

Examples

+
>>> r = np.zeros((), dtype = [('x', 'i4'), ('s', 'S10')])
+>>> d = rec2dict(r)
+>>> d == {'x': 0, 's': b''}
+True
+
+
+
+ +
+
+

seek_tellΒΆ

+
+
+nibabel.volumeutils.seek_tell(fileobj: IOBase, offset: int, write0: bool = False) NoneΒΆ
+

Seek in fileobj or check we’re in the right place already

+
+
Parameters:
+
+
fileobjfile-like

object implementing seek and (if seek raises an OSError) tell

+
+
offsetint

position in file to which to seek

+
+
write0{False, True}, optional

If True, and standard seek fails, try to write zeros to the file to +reach offset. This can be useful when writing bz2 files, that cannot +do write seeks.

+
+
+
+
+
+ +
+
+

shape_zoom_affineΒΆ

+
+
+nibabel.volumeutils.shape_zoom_affine(shape: Sequence[int] | ndarray, zooms: Sequence[float] | ndarray, x_flip: bool = True) ndarrayΒΆ
+

Get affine implied by given shape and zooms

+

We get the translations from the center of the image (implied by +shape).

+
+
Parameters:
+
+
shape(N,) array-like

shape of image data. N is the number of dimensions

+
+
zooms(N,) array-like

zooms (voxel sizes) of the image

+
+
x_flip{True, False}

whether to flip the X row of the affine. Corresponds to +radiological storage on disk.

+
+
+
+
Returns:
+
+
aff(4,4) array

affine giving correspondence of voxel coordinates to mm +coordinates, taking the center of the image as origin

+
+
+
+
+

Examples

+
>>> shape = (3, 5, 7)
+>>> zooms = (3, 2, 1)
+>>> shape_zoom_affine((3, 5, 7), (3, 2, 1))
+array([[-3.,  0.,  0.,  3.],
+       [ 0.,  2.,  0., -4.],
+       [ 0.,  0.,  1., -3.],
+       [ 0.,  0.,  0.,  1.]])
+>>> shape_zoom_affine((3, 5, 7), (3, 2, 1), False)
+array([[ 3.,  0.,  0., -3.],
+       [ 0.,  2.,  0., -4.],
+       [ 0.,  0.,  1., -3.],
+       [ 0.,  0.,  0.,  1.]])
+
+
+
+ +
+
+

working_typeΒΆ

+
+
+nibabel.volumeutils.working_type(in_type: npt.DTypeLike, slope: npt.ArrayLike = 1.0, inter: npt.ArrayLike = 0.0) type[np.number]ΒΆ
+

Return array type from applying slope, inter to array of in_type

+

Numpy type that results from an array of type in_type being combined with +slope and inter. It returns something like the dtype type of +((np.zeros((2,), dtype=in_type) - inter) / slope), but ignoring the +actual values of slope and inter.

+

Note that you would not necessarily get the same type by applying slope and +inter the other way round. Also, you’ll see that the order in which slope +and inter are applied is the opposite of the order in which they are +passed.

+
+
Parameters:
+
+
in_typenumpy type specifier

Numpy type of input array. Any valid input for np.dtype()

+
+
slopescalar, optional

slope to apply to array. If 1.0 (default), ignore this value and its +type.

+
+
interscalar, optional

intercept to apply to array. If 0.0 (default), ignore this value and +its type.

+
+
+
+
Returns:
+
+
wtype: numpy type

Numpy type resulting from applying inter and slope to array of type +in_type.

+
+
+
+
+
+ +
+
+

write_zerosΒΆ

+
+
+nibabel.volumeutils.write_zeros(fileobj: IOBase, count: int, block_size: int = 8194) NoneΒΆ
+

Write count zero bytes to fileobj

+
+
Parameters:
+
+
fileobjfile-like object

with write method

+
+
countint

number of bytes to write

+
+
block_sizeint, optional

largest continuous block to write.

+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.wrapstruct.html b/reference/nibabel.wrapstruct.html new file mode 100644 index 0000000000..4a595c567f --- /dev/null +++ b/reference/nibabel.wrapstruct.html @@ -0,0 +1,721 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

wrapstructΒΆ

+

Class to wrap numpy structured array

+
+

wrapstructΒΆ

+

The WrapStruct class is a wrapper around a numpy structured array +type.

+

It implements:

+
    +
  • Mappingness from the underlying structured array fields

  • +
  • from_fileobj, write_to methods to read and write data to fileobj

  • +
  • A mechanism for setting checks and fixes to the data on object creation

  • +
  • Endianness guessing, and on-the-fly swapping

  • +
+

The LabeledWrapStruct subclass adds:

+ +
+

MappingnessΒΆ

+

You can access and set fields of the contained structarr using standard +__getitem__ / __setitem__ syntax:

+
+

wrapped[β€˜field’] = 10

+
+

Wrapped structures also implement general mappingness:

+
+

wrapped.keys() +wrapped.items() +wrapped.values()

+
+

Properties:

+
.endianness (read only)
+.binaryblock (read only)
+.structarr (read only)
+
+
+

Methods:

+
.as_byteswapped(endianness)
+.check_fix()
+.__str__
+.__eq__
+.__ne__
+.get_value_label(name)
+
+
+

Class methods:

+
.diagnose_binaryblock
+.as_byteswapped(endianness)
+.write_to(fileobj)
+.from_fileobj(fileobj)
+.default_structarr() - return default structured array
+.guessed_endian(structarr) - return guessed endian code from this structarr
+
+
+
+
Class variables:

template_dtype - native endian version of dtype for contained structarr

+
+
+
+
+

Consistency checksΒΆ

+

We have a file, and we would like information as to whether there are any +problems with the binary data in this file, and whether they are fixable. +WrapStruct can hold checks for internal consistency of the contained data:

+
wrapped = WrapStruct.from_fileobj(open('myfile.bin'), check=False)
+dx_result = WrapStruct.diagnose_binaryblock(wrapped.binaryblock)
+
+
+

This will run all known checks, with no fixes, returning a string with +diagnostic output. See below for the check=False flag.

+

In creating a WrapStruct object, we often want to check the consistency of +the contained data. The checks can test for problems of various levels of +severity. If the problem is severe enough, it should raise an Error. So, with +data that is consistent - no error:

+
wrapped = WrapStruct.from_fileobj(good_fileobj)
+
+
+

whereas:

+
wrapped = WrapStruct.from_fileobj(bad_fileobj)
+
+
+

would raise some error, with output to logging (see below).

+

If we want the created object, come what may:

+
hdr = WrapStruct.from_fileobj(bad_fileobj, check=False)
+
+
+

We set the error level (the level of problem that the check=True +versions will accept as OK) from global defaults:

+
import nibabel as nib
+nib.imageglobals.error_level = 30
+
+
+

The same for logging:

+
nib.imageglobals.logger = logger
+
+
+
+
+ + + + + + + + + + + + +

LabeledWrapStruct([binaryblock,Β endianness,Β ...])

A WrapStruct with some fields having value labels for printing etc

WrapStruct([binaryblock,Β endianness,Β check])

Initialize WrapStruct from binary data block

WrapStructError

+
+

LabeledWrapStructΒΆ

+
+
+class nibabel.wrapstruct.LabeledWrapStruct(binaryblock=None, endianness=None, check=True)ΒΆ
+

Bases: WrapStruct

+

A WrapStruct with some fields having value labels for printing etc

+

Initialize WrapStruct from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into object. By default, None, in +which case we insert the default empty block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of binary data in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> wstr1 = WrapStruct() # a default structure
+>>> wstr1.endianness == native_code
+True
+>>> wstr1['integer']
+array(0, dtype=int16)
+>>> wstr1['integer'] = 1
+>>> wstr1['integer']
+array(1, dtype=int16)
+
+
+
+
+__init__(binaryblock=None, endianness=None, check=True)ΒΆ
+

Initialize WrapStruct from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into object. By default, None, in +which case we insert the default empty block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of binary data in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> wstr1 = WrapStruct() # a default structure
+>>> wstr1.endianness == native_code
+True
+>>> wstr1['integer']
+array(0, dtype=int16)
+>>> wstr1['integer'] = 1
+>>> wstr1['integer']
+array(1, dtype=int16)
+
+
+
+ +
+
+get_value_label(fieldname)ΒΆ
+

Returns label for coded field

+

A coded field is an int field containing codes that stand for +discrete values that also have string labels.

+
+
Parameters:
+
+
fieldnamestr

name of header field to get label for

+
+
+
+
Returns:
+
+
labelstr

label for code value in header field fieldname

+
+
+
+
Raises:
+
+
ValueError

if field is not coded.

+
+
+
+
+

Examples

+
>>> from nibabel.volumeutils import Recoder
+>>> recoder = Recoder(((1, 'one'), (2, 'two')), ('code', 'label'))
+>>> class C(LabeledWrapStruct):
+...     template_dtype = np.dtype([('datatype', 'i2')])
+...     _field_recoders = dict(datatype = recoder)
+>>> hdr  = C()
+>>> hdr.get_value_label('datatype')
+'<unknown code 0>'
+>>> hdr['datatype'] = 2
+>>> hdr.get_value_label('datatype')
+'two'
+
+
+
+ +
+ +
+
+

WrapStructΒΆ

+
+
+class nibabel.wrapstruct.WrapStruct(binaryblock=None, endianness=None, check=True)ΒΆ
+

Bases: object

+

Initialize WrapStruct from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into object. By default, None, in +which case we insert the default empty block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of binary data in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> wstr1 = WrapStruct() # a default structure
+>>> wstr1.endianness == native_code
+True
+>>> wstr1['integer']
+array(0, dtype=int16)
+>>> wstr1['integer'] = 1
+>>> wstr1['integer']
+array(1, dtype=int16)
+
+
+
+
+__init__(binaryblock=None, endianness=None, check=True)ΒΆ
+

Initialize WrapStruct from binary data block

+
+
Parameters:
+
+
binaryblock{None, string} optional

binary block to set into object. By default, None, in +which case we insert the default empty block

+
+
endianness{None, β€˜<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness +from the data.

+
+
checkbool, optional

Whether to check content of binary data in initialization. +Default is True.

+
+
+
+
+

Examples

+
>>> wstr1 = WrapStruct() # a default structure
+>>> wstr1.endianness == native_code
+True
+>>> wstr1['integer']
+array(0, dtype=int16)
+>>> wstr1['integer'] = 1
+>>> wstr1['integer']
+array(1, dtype=int16)
+
+
+
+ +
+
+as_byteswapped(endianness=None)ΒΆ
+

return new byteswapped object with given endianness

+

Guaranteed to make a copy even if endianness is the same as +the current endianness.

+
+
Parameters:
+
+
endiannessNone or string, optional

endian code to which to swap. None means swap from current +endianness, and is the default

+
+
+
+
Returns:
+
+
wstrWrapStruct

WrapStruct object with given endianness

+
+
+
+
+

Examples

+
>>> wstr = WrapStruct()
+>>> wstr.endianness == native_code
+True
+>>> bs_wstr = wstr.as_byteswapped()
+>>> bs_wstr.endianness == swapped_code
+True
+>>> bs_wstr = wstr.as_byteswapped(swapped_code)
+>>> bs_wstr.endianness == swapped_code
+True
+>>> bs_wstr is wstr
+False
+>>> bs_wstr == wstr
+True
+
+
+

If you write to the resulting byteswapped data, it does not +change the original.

+
>>> bs_wstr['integer'] = 3
+>>> bs_wstr == wstr
+False
+
+
+

If you swap to the same endianness, it returns a copy

+
>>> nbs_wstr = wstr.as_byteswapped(native_code)
+>>> nbs_wstr.endianness == native_code
+True
+>>> nbs_wstr is wstr
+False
+
+
+
+ +
+
+property binaryblockΒΆ
+

binary block of data as string

+
+
Returns:
+
+
binaryblockstring

string giving binary data block

+
+
+
+
+

Examples

+
>>> # Make default empty structure
+>>> wstr = WrapStruct()
+>>> len(wstr.binaryblock)
+2
+
+
+
+ +
+
+check_fix(logger=None, error_level=None)ΒΆ
+

Check structured data with checks

+
+
Parameters:
+
+
loggerNone or logging.Logger
+
error_levelNone or int

Level of error severity at which to raise error. Any error of +severity >= error_level will cause an exception.

+
+
+
+
+
+ +
+
+copy()ΒΆ
+

Return copy of structure

+
>>> wstr = WrapStruct()
+>>> wstr['integer'] = 3
+>>> wstr2 = wstr.copy()
+>>> wstr2 is wstr
+False
+>>> wstr2['integer']
+array(3, dtype=int16)
+
+
+
+ +
+
+classmethod default_structarr(endianness=None)ΒΆ
+

Return structured array for default structure with given endianness

+
+ +
+
+classmethod diagnose_binaryblock(binaryblock, endianness=None)ΒΆ
+

Run checks over binary data, return string

+
+ +
+
+property endiannessΒΆ
+

endian code of binary data

+

The endianness code gives the current byte order +interpretation of the binary data.

+

Notes

+

Endianness gives endian interpretation of binary data. It is +read only because the only common use case is to set the +endianness on initialization, or occasionally byteswapping the +data - but this is done via the as_byteswapped method

+

Examples

+
>>> wstr = WrapStruct()
+>>> code = wstr.endianness
+>>> code == native_code
+True
+
+
+
+ +
+
+classmethod from_fileobj(fileobj, endianness=None, check=True)ΒΆ
+

Return read structure with given or guessed endiancode

+
+
Parameters:
+
+
fileobjfile-like object

Needs to implement read method

+
+
endiannessNone or endian code, optional

Code specifying endianness of read data

+
+
+
+
Returns:
+
+
wstrWrapStruct object

WrapStruct object initialized from data in fileobj

+
+
+
+
+
+ +
+
+get(k, d=None)ΒΆ
+

Return value for the key k if present or d otherwise

+
+ +
+
+classmethod guessed_endian(mapping)ΒΆ
+

Guess intended endianness from mapping-like mapping

+
+
Parameters:
+
+
wstrmapping-like

Something implementing a mapping. We will guess the endianness +from looking at the field values

+
+
+
+
Returns:
+
+
endianness{β€˜<’, β€˜>’}

Guessed endianness of binary data in wstr

+
+
+
+
+
+ +
+
+items()ΒΆ
+

Return items from structured data

+
+ +
+
+keys()ΒΆ
+

Return keys from structured data

+
+ +
+
+property structarrΒΆ
+

Structured data, with data fields

+

Examples

+
>>> wstr1 = WrapStruct() # with default data
+>>> an_int = wstr1.structarr['integer']
+>>> wstr1.structarr = None
+Traceback (most recent call last):
+   ...
+AttributeError: ...
+
+
+
+ +
+
+template_dtype = dtype([('integer', '<i2')])ΒΆ
+
+ +
+
+values()ΒΆ
+

Return values from structured data

+
+ +
+
+write_to(fileobj)ΒΆ
+

Write structure to fileobj

+

Write starts at fileobj current file position.

+
+
Parameters:
+
+
fileobjfile-like object

Should implement write method

+
+
+
+
Returns:
+
+
None
+
+
+
+

Examples

+
>>> wstr = WrapStruct()
+>>> from io import BytesIO
+>>> str_io = BytesIO()
+>>> wstr.write_to(str_io)
+>>> wstr.binaryblock == str_io.getvalue()
+True
+
+
+
+ +
+ +
+
+

WrapStructErrorΒΆ

+
+
+class nibabel.wrapstruct.WrapStructErrorΒΆ
+

Bases: Exception

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/reference/nibabel.xmlutils.html b/reference/nibabel.xmlutils.html new file mode 100644 index 0000000000..ee157a1478 --- /dev/null +++ b/reference/nibabel.xmlutils.html @@ -0,0 +1,282 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

xmlutilsΒΆ

+

Thin layer around xml.etree.ElementTree, to abstract nibabel xml support

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

XmlBasedHeader()

Basic wrapper around FileBasedHeader and XmlSerializable.

XmlParser([encoding,Β buffer_size,Β verbose])

Base class for defining how to parse xml-based image snippets.

XmlSerializable()

Basic interface for serializing an object to XML

+
+

XmlBasedHeaderΒΆ

+
+
+class nibabel.xmlutils.XmlBasedHeaderΒΆ
+

Bases: FileBasedHeader, XmlSerializable

+

Basic wrapper around FileBasedHeader and XmlSerializable.

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+ +
+
+

XmlParserΒΆ

+
+
+class nibabel.xmlutils.XmlParser(encoding='utf-8', buffer_size=35000000, verbose=0)ΒΆ
+

Bases: object

+

Base class for defining how to parse xml-based image snippets.

+
+
Image-specific parsers should define:

StartElementHandler +EndElementHandler +CharacterDataHandler

+
+
+
+
Parameters:
+
+
encodingstr

string containing xml document

+
+
buffer_size: None or int, optional

size of read buffer. None uses default buffer_size +from xml.parsers.expat.

+
+
verboseint, optional

amount of output during parsing (0=silent, by default).

+
+
+
+
+
+
+__init__(encoding='utf-8', buffer_size=35000000, verbose=0)ΒΆ
+
+
Parameters:
+
+
encodingstr

string containing xml document

+
+
buffer_size: None or int, optional

size of read buffer. None uses default buffer_size +from xml.parsers.expat.

+
+
verboseint, optional

amount of output during parsing (0=silent, by default).

+
+
+
+
+
+ +
+
+CharacterDataHandler(data)ΒΆ
+
+ +
+
+EndElementHandler(name)ΒΆ
+
+ +
+
+HANDLER_NAMES = ['StartElementHandler', 'EndElementHandler', 'CharacterDataHandler']ΒΆ
+
+ +
+
+StartElementHandler(name, attrs)ΒΆ
+
+ +
+
+parse(string=None, fname=None, fptr=None)ΒΆ
+
+
Parameters:
+
+
stringbytes

string (as a bytes object) containing xml document

+
+
fnamestr

file name of an xml document.

+
+
fptrfile pointer

open file pointer to an xml documents

+
+
+
+
+
+ +
+ +
+
+

XmlSerializableΒΆ

+
+
+class nibabel.xmlutils.XmlSerializableΒΆ
+

Bases: object

+

Basic interface for serializing an object to XML

+
+
+__init__(*args, **kwargs)ΒΆ
+
+ +
+
+to_xml(enc='utf-8', **kwargs) bytesΒΆ
+

Generate an XML bytestring with a given encoding.

+
+
Parameters:
+
+
encstring

Encoding to use for the generated bytestring. Default: β€˜utf-8’

+
+
**kwargsdict

Additional keyword arguments to xml.etree.ElementTree.tostring().

+
+
+
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 0000000000..733b381468 --- /dev/null +++ b/search.html @@ -0,0 +1,105 @@ + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

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

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + + +
+ + + +
+ +
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 0000000000..48b37ce4a1 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["api", "changelog", "coordinate_systems", "devel/add_image_format", "devel/add_test_data", "devel/advanced_testing", "devel/biaps/biap_0000", "devel/biaps/biap_0001", "devel/biaps/biap_0002", "devel/biaps/biap_0003", "devel/biaps/biap_0004", "devel/biaps/biap_0005", "devel/biaps/biap_0006", "devel/biaps/biap_0007", "devel/biaps/biap_0008", "devel/biaps/biap_0009", "devel/biaps/biap_template", "devel/biaps/index", "devel/bv_formats", "devel/core_developer", "devel/data_pkg_discuss", "devel/devdiscuss", "devel/devguide", "devel/governance", "devel/image_design", "devel/index", "devel/make_release", "devel/modified_images", "devel/roadmap", "devel/scaling", "devel/spm_use", "dicom/dcm2nii_algorithms", "dicom/dicom", "dicom/dicom_fields", "dicom/dicom_info", "dicom/dicom_intro", "dicom/dicom_mosaic", "dicom/dicom_niftiheader", "dicom/dicom_orientation", "dicom/siemens_csa", "dicom/spm_dicom", "gettingstarted", "gitwash/configure_git", "gitwash/development_workflow", "gitwash/following_latest", "gitwash/forking_hell", "gitwash/git_development", "gitwash/git_install", "gitwash/git_intro", "gitwash/git_resources", "gitwash/index", "gitwash/maintainer_workflow", "gitwash/patching", "gitwash/set_up_fork", "image_orientation", "images_and_memory", "index", "installation", "legal", "manual", "neuro_radio_conventions", "nibabel_images", "nifti_images", "notebooks/index", "old/ioimplementation", "reference/index", "reference/nibabel", "reference/nibabel._compression", "reference/nibabel.affines", "reference/nibabel.analyze", "reference/nibabel.arrayproxy", "reference/nibabel.arraywriters", "reference/nibabel.batteryrunners", "reference/nibabel.benchmarks", "reference/nibabel.brikhead", "reference/nibabel.caret", "reference/nibabel.casting", "reference/nibabel.cifti2", "reference/nibabel.cmdline", "reference/nibabel.data", "reference/nibabel.dataobj_images", "reference/nibabel.deprecated", "reference/nibabel.deprecator", "reference/nibabel.dft", "reference/nibabel.ecat", "reference/nibabel.environment", "reference/nibabel.eulerangles", "reference/nibabel.filebasedimages", "reference/nibabel.fileholders", "reference/nibabel.filename_parser", "reference/nibabel.fileslice", "reference/nibabel.fileutils", "reference/nibabel.freesurfer", "reference/nibabel.funcs", "reference/nibabel.gifti", "reference/nibabel.imageclasses", "reference/nibabel.imageglobals", "reference/nibabel.imagestats", "reference/nibabel.loadsave", "reference/nibabel.minc1", "reference/nibabel.minc2", "reference/nibabel.mriutils", "reference/nibabel.nicom", "reference/nibabel.nifti1", "reference/nibabel.nifti2", "reference/nibabel.onetime", "reference/nibabel.openers", "reference/nibabel.optpkg", "reference/nibabel.orientations", "reference/nibabel.parrec", "reference/nibabel.pointset", "reference/nibabel.processing", "reference/nibabel.pydicom_compat", "reference/nibabel.quaternions", "reference/nibabel.rstutils", "reference/nibabel.spaces", "reference/nibabel.spatialimages", "reference/nibabel.spm2analyze", "reference/nibabel.spm99analyze", "reference/nibabel.streamlines", "reference/nibabel.tmpdirs", "reference/nibabel.tripwire", "reference/nibabel.viewers", "reference/nibabel.volumeutils", "reference/nibabel.wrapstruct", "reference/nibabel.xmlutils", "tutorials"], "filenames": ["api.rst", "changelog.rst", "coordinate_systems.rst", "devel/add_image_format.rst", "devel/add_test_data.rst", "devel/advanced_testing.rst", "devel/biaps/biap_0000.rst", "devel/biaps/biap_0001.rst", "devel/biaps/biap_0002.rst", "devel/biaps/biap_0003.rst", "devel/biaps/biap_0004.rst", "devel/biaps/biap_0005.rst", "devel/biaps/biap_0006.rst", "devel/biaps/biap_0007.rst", "devel/biaps/biap_0008.rst", "devel/biaps/biap_0009.rst", "devel/biaps/biap_template.rst", "devel/biaps/index.rst", "devel/bv_formats.rst", "devel/core_developer.rst", "devel/data_pkg_discuss.rst", "devel/devdiscuss.rst", "devel/devguide.rst", "devel/governance.rst", "devel/image_design.rst", "devel/index.rst", "devel/make_release.rst", "devel/modified_images.rst", "devel/roadmap.rst", "devel/scaling.rst", "devel/spm_use.rst", "dicom/dcm2nii_algorithms.rst", "dicom/dicom.rst", "dicom/dicom_fields.rst", "dicom/dicom_info.rst", "dicom/dicom_intro.rst", "dicom/dicom_mosaic.rst", "dicom/dicom_niftiheader.rst", "dicom/dicom_orientation.rst", "dicom/siemens_csa.rst", "dicom/spm_dicom.rst", "gettingstarted.rst", "gitwash/configure_git.rst", "gitwash/development_workflow.rst", "gitwash/following_latest.rst", "gitwash/forking_hell.rst", "gitwash/git_development.rst", "gitwash/git_install.rst", "gitwash/git_intro.rst", "gitwash/git_resources.rst", "gitwash/index.rst", "gitwash/maintainer_workflow.rst", "gitwash/patching.rst", "gitwash/set_up_fork.rst", "image_orientation.rst", "images_and_memory.rst", "index.rst", "installation.rst", "legal.rst", "manual.rst", "neuro_radio_conventions.rst", "nibabel_images.rst", "nifti_images.rst", "notebooks/index.rst", "old/ioimplementation.rst", "reference/index.rst", "reference/nibabel.rst", "reference/nibabel._compression.rst", "reference/nibabel.affines.rst", "reference/nibabel.analyze.rst", "reference/nibabel.arrayproxy.rst", "reference/nibabel.arraywriters.rst", "reference/nibabel.batteryrunners.rst", "reference/nibabel.benchmarks.rst", "reference/nibabel.brikhead.rst", "reference/nibabel.caret.rst", "reference/nibabel.casting.rst", "reference/nibabel.cifti2.rst", "reference/nibabel.cmdline.rst", "reference/nibabel.data.rst", "reference/nibabel.dataobj_images.rst", "reference/nibabel.deprecated.rst", "reference/nibabel.deprecator.rst", "reference/nibabel.dft.rst", "reference/nibabel.ecat.rst", "reference/nibabel.environment.rst", "reference/nibabel.eulerangles.rst", "reference/nibabel.filebasedimages.rst", "reference/nibabel.fileholders.rst", "reference/nibabel.filename_parser.rst", "reference/nibabel.fileslice.rst", "reference/nibabel.fileutils.rst", "reference/nibabel.freesurfer.rst", "reference/nibabel.funcs.rst", "reference/nibabel.gifti.rst", "reference/nibabel.imageclasses.rst", "reference/nibabel.imageglobals.rst", "reference/nibabel.imagestats.rst", "reference/nibabel.loadsave.rst", "reference/nibabel.minc1.rst", "reference/nibabel.minc2.rst", "reference/nibabel.mriutils.rst", "reference/nibabel.nicom.rst", "reference/nibabel.nifti1.rst", "reference/nibabel.nifti2.rst", "reference/nibabel.onetime.rst", "reference/nibabel.openers.rst", "reference/nibabel.optpkg.rst", "reference/nibabel.orientations.rst", "reference/nibabel.parrec.rst", "reference/nibabel.pointset.rst", "reference/nibabel.processing.rst", "reference/nibabel.pydicom_compat.rst", "reference/nibabel.quaternions.rst", "reference/nibabel.rstutils.rst", "reference/nibabel.spaces.rst", "reference/nibabel.spatialimages.rst", "reference/nibabel.spm2analyze.rst", "reference/nibabel.spm99analyze.rst", "reference/nibabel.streamlines.rst", "reference/nibabel.tmpdirs.rst", "reference/nibabel.tripwire.rst", "reference/nibabel.viewers.rst", "reference/nibabel.volumeutils.rst", "reference/nibabel.wrapstruct.rst", "reference/nibabel.xmlutils.rst", "tutorials.rst"], "titles": ["API Documentation", "NiBabel Development Changelog", "Coordinate systems and affines", "How to add a new image format to nibabel", "Adding test data", "Advanced Testing", "BIAP 0 - Purpose and process", "BIAP1 - Towards immutable images", "BIAP2 - Slicecopy", "BIAP3 - A JSON nifti header extension", "BIAP4 - Merging nibabel and dcmstack", "BIAP5 - A streamlines converter", "BIAP6 - Identifying image axes", "BIAP7 - Loading multiple images", "BIAP8 - Always load image data as floating point", "BIAP9 - The Coordinate Image API", "BIAP X \u2014 Template and Instructions", "BIAPs", "BrainVoyager file formats", "Core Developer Guide", "Principles of data package", "Developer discussions", "NiBabel Developer Guidelines", "Governance and Decision Making", "The nibabel image object", "Developer documentation page", "A guide to making a nibabel release", "Keeping track of whether images have been modified since load", "Roadmap", "Scalefactors and intercepts", "Image use-cases in SPM", "dcm2nii algorithms", "DICOM concepts and implementations", "DICOM fields", "DICOM information", "Introduction to DICOM", "Siemens mosaic format", "DICOM Tags in the NIfTI Header", "Defining the DICOM orientation", "Siemens format DICOM with CSA header", "SPM DICOM conversion", "Getting Started", "Configure git", "Development workflow", "Following the latest source", "Making your own copy (fork) of nibabel", "Git for development", "Install git", "Introduction", "git resources", "Working with nibabel source code", "Maintainer workflow", "Making a patch", "Set up your fork", "Image voxel orientation", "Images and memory", "NiBabel", "Installation", "Copyright and Licenses", "NiBabel Manual", "Radiological vs neurological conventions", "Nibabel images", "Working with NIfTI images", "IPython notebooks for Nibabel project", "Relationship between images and io implementations", "API Reference", "nibabel", "_compression", "affines", "analyze", "arrayproxy", "arraywriters", "batteryrunners", "benchmarks", "brikhead", "caret", "casting", "cifti2", "cmdline", "data", "dataobj_images", "deprecated", "deprecator", "dft", "ecat", "environment", "eulerangles", "filebasedimages", "fileholders", "filename_parser", "fileslice", "fileutils", "freesurfer", "funcs", "gifti", "imageclasses", "imageglobals", "imagestats", "loadsave", "minc1", "minc2", "mriutils", "nicom", "nifti1", "nifti2", "onetime", "openers", "optpkg", "orientations", "parrec", "pointset", "processing", "pydicom_compat", "quaternions", "rstutils", "spaces", "spatialimages", "spm2analyze", "spm99analyze", "streamlines", "tmpdirs", "tripwire", "viewers", "volumeutils", "wrapstruct", "xmlutils", "General tutorials"], "terms": {"nibabel": [0, 5, 6, 7, 8, 9, 11, 13, 14, 15, 16, 17, 18, 19, 20, 23, 25, 27, 28, 37, 41, 43, 44, 46, 48, 51, 52, 53, 54, 55, 57, 60, 62, 64, 65, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126], "_compress": [0, 1, 65], "affin": [0, 1, 3, 7, 9, 10, 13, 15, 27, 30, 32, 36, 41, 54, 55, 59, 60, 61, 64, 65, 66, 69, 74, 77, 84, 87, 92, 93, 94, 99, 100, 102, 103, 104, 108, 109, 110, 111, 115, 116, 117, 118, 119, 122, 123, 126], "analyz": [0, 1, 8, 27, 29, 56, 57, 60, 61, 65, 66, 70, 72, 87, 89, 103, 105, 116, 117, 118, 123], "arrayproxi": [0, 1, 3, 55, 61, 64, 65, 69, 73, 74, 80, 84, 92, 99, 100, 118], "arraywrit": [0, 1, 65], "batteryrunn": [0, 65, 96], "benchmark": [0, 1, 65, 66, 90], "brikhead": [0, 65], "caret": [0, 1, 65], "cast": [0, 1, 14, 23, 29, 49, 61, 62, 65, 71, 87, 103, 111, 116, 123], "cifti2": [0, 1, 65], "cmdline": [0, 1, 65], "data": [0, 1, 3, 7, 8, 9, 12, 13, 17, 18, 25, 27, 29, 30, 32, 33, 34, 37, 41, 42, 55, 56, 59, 60, 64, 65, 66, 69, 70, 71, 72, 74, 75, 77, 78, 80, 84, 87, 88, 90, 92, 93, 94, 98, 99, 100, 102, 103, 104, 105, 108, 110, 111, 115, 117, 118, 119, 122, 123, 124, 125, 126], "dataobj_imag": [0, 1, 65], "deprec": [0, 13, 14, 59, 65, 70, 76, 80, 94, 98, 105, 108, 112, 120], "dft": [0, 65], "ecat": [0, 1, 12, 13, 56, 65, 66, 70], "environ": [0, 1, 5, 6, 22, 65, 79], "eulerangl": [0, 65], "filebasedimag": [0, 1, 65, 80, 98, 116], "filehold": [0, 61, 65, 69, 74, 80, 84, 87, 92, 94, 99, 100, 109, 116, 118], "filename_pars": [0, 1, 65], "fileslic": [0, 1, 65], "fileutil": [0, 65], "freesurf": [0, 1, 15, 28, 56, 65, 66, 94, 103, 104, 111], "func": [0, 1, 10, 15, 65, 72, 94, 105, 112], "gifti": [0, 1, 15, 28, 56, 65, 66], "imageclass": [0, 1, 65], "imageglob": [0, 65, 124], "imagestat": [0, 1, 65], "loadsav": [0, 1, 65], "minc1": [0, 1, 12, 56, 65, 66, 70], "minc2": [0, 1, 4, 12, 56, 57, 65, 66], "mriutil": [0, 65], "nicom": [0, 1, 65, 112], "nifti1": [0, 1, 8, 29, 37, 56, 61, 62, 65, 66, 69, 70, 81, 94, 104, 109, 111], "nifti2": [0, 1, 3, 56, 62, 65, 66, 69, 77], "onetim": [0, 1, 65], "open": [0, 1, 13, 23, 25, 26, 31, 43, 57, 65, 69, 70, 74, 78, 80, 84, 87, 88, 90, 92, 99, 100, 118, 119, 120, 123, 124, 125], "optpkg": [0, 1, 65], "orient": [0, 1, 2, 9, 31, 32, 33, 35, 59, 60, 61, 62, 65, 69, 84, 86, 93, 102, 103, 111, 116, 117, 118, 122], "parrec": [0, 1, 3, 65, 70], "pointset": [0, 1, 15, 65, 94], "process": [0, 1, 9, 10, 11, 12, 16, 17, 19, 22, 25, 28, 40, 65, 69, 71, 76, 77, 94, 102, 119, 120], "pydicom_compat": [0, 1, 65], "quaternion": [0, 1, 62, 65, 86, 103], "rstutil": [0, 65], "space": [0, 1, 9, 12, 15, 18, 32, 33, 35, 54, 60, 61, 62, 64, 65, 68, 74, 77, 92, 94, 102, 103, 104, 108, 109, 110, 111, 116, 118, 119, 126], "spatialimag": [0, 1, 3, 10, 65, 69, 74, 84, 92, 93, 97, 98, 99, 103, 109, 110, 111], "spm2analyz": [0, 65], "spm99analyz": [0, 65], "streamlin": [0, 1, 17, 25, 65], "tmpdir": [0, 1, 65], "tripwir": [0, 1, 65, 107], "viewer": [0, 1, 60, 63, 65, 116], "volumeutil": [0, 1, 65, 124], "wrapstruct": [0, 1, 65, 69, 84, 103], "xmlutil": [0, 65], "i": [1, 2, 3, 4, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20, 22, 23, 24, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 37, 39, 40, 41, 42, 43, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 64, 66, 68, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 92, 93, 94, 96, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 126], "successor": 1, "much": [1, 3, 7, 20, 35, 43, 62], "love": 1, "packag": [1, 22, 27, 28, 31, 58, 59, 79, 82, 102, 107], "here": [1, 2, 7, 8, 9, 12, 14, 15, 16, 18, 20, 23, 26, 31, 33, 34, 35, 36, 37, 38, 42, 43, 45, 47, 48, 49, 52, 53, 54, 60, 61, 62, 68, 69, 77, 86, 92, 102, 103, 104, 109, 112, 113, 117, 118, 123], "we": [1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 19, 20, 22, 23, 26, 27, 28, 29, 30, 33, 34, 35, 36, 38, 39, 40, 41, 43, 45, 52, 53, 54, 55, 56, 57, 60, 61, 62, 64, 66, 68, 69, 71, 72, 76, 77, 78, 79, 80, 81, 84, 85, 86, 87, 89, 90, 91, 92, 93, 94, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 112, 113, 115, 117, 118, 119, 120, 121, 123, 124], "list": [1, 2, 3, 4, 6, 7, 9, 10, 11, 12, 14, 15, 16, 19, 20, 22, 23, 26, 30, 32, 34, 35, 40, 43, 52, 58, 61, 65, 74, 75, 77, 78, 79, 84, 89, 90, 91, 92, 93, 94, 102, 103, 109, 119], "both": [1, 2, 4, 9, 10, 19, 20, 23, 35, 39, 40, 41, 55, 62, 69, 76, 77, 86, 88, 102, 103, 104, 109, 118, 119, 123], "The": [1, 4, 6, 7, 8, 10, 11, 13, 14, 16, 17, 18, 19, 20, 22, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 38, 39, 40, 41, 42, 44, 45, 46, 49, 51, 52, 53, 54, 55, 56, 58, 59, 60, 64, 65, 66, 68, 70, 71, 72, 74, 76, 77, 79, 80, 82, 84, 85, 86, 87, 89, 90, 91, 92, 94, 99, 100, 101, 102, 103, 104, 105, 106, 108, 109, 110, 111, 113, 115, 116, 117, 118, 119, 122, 123, 124, 126], "full": [1, 2, 4, 6, 8, 9, 15, 20, 22, 23, 26, 28, 35, 36, 40, 55, 56, 57, 66, 69, 74, 77, 79, 80, 81, 84, 90, 109, 113, 118, 123], "vc": [1, 22, 30], "avail": [1, 6, 11, 12, 20, 22, 23, 26, 35, 41, 47, 56, 58, 66, 87, 94, 102, 103, 112, 116, 123], "http": [1, 4, 6, 7, 8, 9, 10, 13, 18, 20, 22, 26, 31, 34, 38, 43, 45, 47, 56, 57, 58, 66, 74, 76, 77, 79, 81, 84, 86, 90, 92, 94, 102, 103, 104, 105, 109, 113, 119], "github": [1, 3, 4, 6, 8, 10, 13, 16, 18, 19, 22, 23, 26, 44, 46, 47, 48, 49, 51, 52, 53, 56, 57, 58, 66, 76, 90, 92, 109], "com": [1, 4, 8, 10, 13, 18, 20, 26, 38, 42, 43, 44, 45, 47, 51, 52, 53, 56, 57, 58, 66, 76, 79, 86, 90, 92, 109, 113], "nipi": [1, 2, 4, 6, 7, 8, 9, 13, 18, 20, 23, 26, 27, 28, 44, 51, 52, 53, 56, 57, 66, 68, 79, 85, 105, 109, 119], "commit": [1, 4, 6, 19, 20, 23, 26, 42, 49, 52], "master": [1, 22, 26, 27, 42, 46, 51, 52, 53, 57], "most": [1, 2, 8, 9, 10, 11, 12, 13, 14, 15, 35, 41, 43, 47, 55, 56, 57, 64, 69, 71, 76, 90, 94, 96, 103, 106, 107, 111, 121, 123, 124], "work": [1, 2, 3, 4, 9, 10, 13, 14, 15, 19, 20, 21, 22, 23, 26, 27, 28, 30, 31, 32, 40, 41, 43, 48, 49, 52, 55, 56, 57, 58, 59, 60, 61, 66, 68, 69, 76, 77, 87, 90, 102, 112, 115, 116, 118, 120], "so": [1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 15, 19, 20, 26, 28, 29, 30, 31, 34, 35, 36, 37, 38, 40, 43, 51, 52, 53, 54, 55, 56, 58, 61, 62, 68, 69, 71, 74, 76, 77, 78, 79, 80, 81, 84, 86, 87, 90, 92, 93, 94, 102, 103, 105, 107, 116, 118, 119, 120, 123, 124], "far": [1, 2, 3, 9, 55, 56, 74], "ha": [1, 2, 4, 6, 7, 9, 10, 11, 12, 13, 14, 15, 18, 19, 20, 22, 23, 26, 27, 30, 34, 35, 36, 38, 39, 40, 41, 43, 49, 51, 54, 55, 56, 58, 60, 61, 62, 68, 69, 70, 71, 74, 76, 77, 78, 79, 80, 82, 84, 86, 87, 88, 89, 90, 92, 93, 94, 95, 99, 100, 102, 103, 104, 105, 108, 109, 111, 112, 113, 115, 116, 118, 119, 120], "been": [1, 4, 6, 7, 9, 12, 19, 20, 21, 25, 34, 36, 43, 51, 56, 58, 61, 62, 76, 77, 80, 81, 90, 93, 102, 103, 104, 105, 108, 111, 112, 119], "matthew": [1, 4, 7, 8, 9, 10, 12, 13, 14, 23, 42, 56, 58], "brett": [1, 4, 7, 8, 9, 10, 12, 13, 14, 23, 42, 56, 58], "mb": [1, 7, 8, 9, 14, 119], "chri": [1, 15, 23, 31, 34, 56, 58, 60], "markiewicz": [1, 15, 23, 56, 58], "cm": 1, "michael": [1, 23, 31, 56, 58], "hank": [1, 23, 31, 56, 58], "mh": 1, "marc": [1, 11, 56], "alexandr": [1, 11, 56], "c\u00f4t\u00e9": [1, 11, 56], "mc": 1, "ben": [1, 56], "cipollini": [1, 56], "bc": 1, "paul": [1, 56, 86, 122], "mccarthi": [1, 56], "pm": 1, "cheng": [1, 56], "cc": 1, "yaroslav": [1, 23, 56, 58], "halchenko": [1, 23, 56, 58], "yoh": 1, "satra": 1, "ghosh": [1, 56], "sg": 1, "eric": [1, 56], "larson": [1, 56], "el": 1, "demian": [1, 56], "wassermann": [1, 56], "stephan": [1, 58], "gerhard": [1, 58], "ross": [1, 56], "markello": [1, 56], "rm": [1, 31, 74], "refer": [1, 7, 8, 9, 10, 12, 15, 18, 20, 22, 28, 33, 35, 38, 40, 43, 48, 53, 54, 55, 56, 58, 60, 62, 66, 69, 74, 76, 77, 80, 86, 88, 92, 99, 100, 102, 103, 109, 110, 113, 118, 119, 126], "like": [1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 15, 20, 22, 26, 27, 28, 29, 30, 35, 36, 37, 38, 40, 42, 43, 51, 53, 57, 60, 61, 62, 64, 68, 69, 70, 71, 72, 74, 75, 76, 77, 79, 80, 84, 86, 87, 88, 90, 92, 94, 99, 100, 102, 103, 104, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124], "pr": [1, 6, 18], "298": 1, "pull": [1, 3, 4, 6, 13, 16, 18, 23, 25, 27, 40, 42, 43, 44, 49, 51, 52, 99, 100, 102, 109], "request": [1, 3, 4, 6, 15, 16, 23, 25, 35, 42, 43, 51, 87, 94, 109], "number": [1, 2, 4, 6, 9, 10, 12, 15, 18, 19, 20, 26, 31, 33, 34, 35, 36, 38, 39, 40, 62, 69, 76, 77, 79, 83, 84, 87, 90, 91, 92, 95, 97, 102, 103, 104, 109, 110, 111, 119, 122, 123], "x": [1, 2, 6, 9, 12, 15, 18, 20, 23, 26, 30, 36, 38, 40, 47, 61, 69, 76, 77, 81, 86, 92, 94, 102, 105, 106, 109, 110, 113, 115, 116, 122, 123], "seri": [1, 9, 10, 12, 13, 18, 26, 30, 31, 33, 34, 35, 36, 39, 49, 61, 72, 76, 77, 83, 84, 94, 102, 119, 126], "thi": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 22, 23, 24, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 48, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 64, 66, 68, 69, 70, 71, 72, 73, 74, 76, 77, 79, 80, 81, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 120, 122, 123, 124], "requir": [1, 3, 4, 5, 6, 9, 12, 15, 16, 19, 20, 23, 26, 28, 30, 35, 37, 59, 61, 66, 70, 71, 74, 81, 93, 94, 102, 103, 109, 116, 119], "minimum": [1, 2, 14, 26, 29, 41, 70, 76, 79, 107, 117, 123], "python": [1, 3, 4, 6, 7, 9, 19, 20, 22, 26, 28, 30, 34, 38, 56, 59, 61, 76, 79, 80, 81, 96, 105, 120], "numpi": [1, 2, 3, 7, 9, 11, 12, 14, 15, 19, 20, 22, 29, 41, 54, 55, 56, 57, 58, 60, 61, 62, 66, 68, 69, 70, 71, 74, 76, 77, 78, 80, 84, 87, 90, 92, 94, 97, 99, 100, 103, 108, 109, 110, 113, 116, 118, 119, 122, 123, 124], "test": [1, 3, 6, 7, 12, 19, 20, 25, 26, 31, 34, 40, 41, 42, 43, 52, 54, 55, 57, 58, 61, 62, 65, 70, 77, 78, 80, 82, 84, 88, 89, 94, 100, 102, 103, 107, 109, 112, 113, 120, 123, 124], "up": [1, 2, 3, 4, 6, 8, 9, 12, 13, 14, 16, 19, 20, 22, 23, 26, 30, 35, 39, 42, 46, 49, 50, 52, 57, 61, 62, 69, 76, 77, 82, 86, 90, 94, 103, 122, 123], "add": [1, 2, 4, 10, 11, 12, 19, 20, 22, 25, 26, 31, 36, 42, 43, 49, 51, 52, 53, 68, 69, 79, 85, 90, 94, 102, 105, 106, 109, 114, 117, 118, 119, 123, 124], "gener": [1, 2, 3, 6, 8, 11, 20, 22, 26, 27, 28, 30, 33, 34, 35, 36, 37, 43, 45, 48, 52, 60, 62, 65, 68, 69, 72, 77, 78, 82, 86, 87, 89, 90, 92, 94, 102, 105, 108, 110, 116, 117, 118, 119, 123, 124, 125], "regularli": [1, 110], "ndgrid": [1, 15], "structur": [1, 2, 9, 15, 30, 40, 58, 62, 71, 77, 84, 92, 103, 109, 110, 119, 123, 124, 126], "prepar": [1, 64], "coordin": [1, 3, 17, 25, 30, 32, 33, 36, 40, 41, 54, 60, 61, 62, 65, 68, 69, 74, 77, 86, 92, 94, 99, 100, 102, 103, 104, 108, 109, 110, 111, 113, 115, 116, 117, 118, 119, 122, 123, 126], "transform": [1, 9, 30, 35, 38, 40, 41, 62, 68, 69, 77, 86, 90, 92, 93, 94, 102, 103, 108, 109, 110, 111, 113, 116, 118, 119, 122, 126], "resampl": [1, 15, 30, 111, 115, 116], "1251": 1, "review": [1, 4, 23, 25, 26, 46], "oscar": [1, 23, 56], "esteban": [1, 23, 56], "copi": [1, 4, 9, 10, 12, 14, 20, 26, 27, 30, 42, 43, 46, 50, 52, 53, 55, 56, 58, 61, 62, 63, 64, 65, 66, 69, 70, 74, 87, 88, 92, 93, 103, 109, 112, 116, 119, 124], "method": [1, 3, 7, 10, 15, 21, 27, 28, 40, 41, 55, 61, 62, 64, 65, 69, 70, 71, 72, 75, 76, 77, 80, 82, 84, 87, 92, 93, 94, 96, 99, 100, 102, 103, 104, 105, 106, 109, 110, 113, 114, 116, 118, 119, 123, 124], "1255": 1, "permit": [1, 11, 35, 58, 74, 103], "to_xml": [1, 65, 75, 94, 125], "pass": [1, 2, 3, 6, 7, 9, 15, 20, 26, 27, 41, 55, 66, 68, 69, 70, 71, 72, 76, 77, 81, 82, 84, 87, 89, 90, 94, 99, 102, 106, 117, 118, 119, 120, 123], "keyword": [1, 8, 9, 10, 12, 35, 56, 59, 69, 70, 71, 74, 79, 80, 84, 87, 92, 94, 98, 99, 100, 102, 103, 106, 109, 118, 119, 125], "argument": [1, 12, 30, 62, 66, 68, 71, 77, 79, 80, 82, 86, 87, 88, 90, 94, 98, 102, 103, 106, 107, 111, 119, 123, 125], "tostr": [1, 125], "1258": 1, "allow": [1, 2, 6, 7, 9, 10, 12, 13, 15, 23, 35, 41, 45, 55, 61, 69, 70, 71, 79, 84, 87, 89, 90, 93, 99, 102, 103, 107, 113, 119], "user": [1, 3, 4, 6, 7, 9, 10, 11, 12, 14, 16, 19, 20, 22, 23, 26, 27, 35, 43, 49, 52, 53, 56, 57, 64, 72, 75, 77, 79, 85, 92, 105], "expans": 1, "e": [1, 6, 9, 10, 11, 12, 15, 16, 18, 19, 20, 22, 26, 29, 35, 38, 40, 41, 43, 49, 56, 57, 62, 66, 72, 74, 77, 78, 81, 87, 89, 92, 96, 101, 102, 103, 109, 110, 119, 123], "g": [1, 6, 9, 10, 12, 15, 16, 18, 19, 20, 22, 26, 35, 38, 40, 41, 43, 49, 62, 72, 74, 77, 81, 86, 87, 89, 92, 96, 101, 102, 103, 109, 119, 123], "string": [1, 9, 10, 11, 20, 30, 31, 35, 39, 40, 69, 72, 73, 77, 78, 79, 82, 85, 87, 89, 90, 91, 92, 94, 102, 103, 106, 114, 117, 118, 119, 120, 121, 123, 124, 125], "function": [1, 2, 3, 7, 10, 11, 12, 15, 16, 18, 19, 20, 21, 29, 31, 33, 35, 41, 55, 61, 68, 70, 74, 76, 77, 78, 81, 82, 86, 90, 92, 93, 94, 97, 102, 103, 105, 106, 107, 111, 112, 113, 115, 116, 119, 123], "accept": [1, 2, 10, 14, 16, 19, 30, 35, 76, 82, 106, 107, 124], "path": [1, 6, 19, 20, 22, 41, 54, 55, 61, 62, 73, 74, 78, 79, 80, 84, 85, 89, 92, 97, 102, 107, 120], "1260": 1, "reinder": [1, 56], "vo": [1, 56], "de": [1, 56, 58, 87], "wael": [1, 56], "expand": [1, 6, 9, 28, 49, 68, 69, 90, 103, 104], "cifti": [1, 28, 56, 65, 66], "brain": [1, 2, 12, 15, 28, 58, 60, 69, 77, 92, 111], "synonym": 1, "1256": 1, "mathia": [1, 56], "goncalv": [1, 56], "annot": [1, 26, 56, 66, 92], "none": [1, 3, 8, 14, 15, 19, 20, 61, 62, 64, 66, 68, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 92, 93, 94, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125], "1253": 1, "blake": [1, 56], "dewei": [1, 56], "warn": [1, 7, 14, 40, 79, 81, 82, 102, 109, 119], "invalid": [1, 9, 76, 103, 105, 118, 119], "declar": [1, 105], "treat": [1, 10, 15, 122, 123], "miss": [1, 4, 9, 22, 26, 27, 40, 90, 102, 109, 111, 114, 115, 119, 121], "1237": 1, "peter": [1, 56], "suter": [1, 56], "refactor": [1, 10, 22, 43], "find_private_el": 1, "improv": [1, 28], "readabl": [1, 9, 19, 22, 40, 43, 72, 87, 102], "maintain": [1, 6, 19, 23, 37, 43, 46, 50, 61, 116], "1228": 1, "resolv": [1, 6, 10, 15, 19, 23, 43, 81, 103], "failur": 1, "relat": [1, 2, 3, 6, 9, 10, 11, 15, 20, 22, 23, 26, 35, 43, 51, 56, 61, 62, 77, 92, 94, 101, 102, 103, 109, 113, 115], "randomli": 1, "case": [1, 2, 6, 8, 10, 12, 13, 16, 18, 19, 20, 21, 22, 25, 26, 27, 35, 36, 38, 39, 40, 41, 43, 51, 54, 55, 57, 60, 61, 62, 64, 68, 69, 74, 76, 77, 80, 81, 84, 86, 87, 89, 90, 92, 93, 94, 99, 100, 102, 103, 104, 106, 107, 108, 109, 113, 114, 116, 117, 118, 119, 123, 124], "1221": 1, "remov": [1, 10, 14, 20, 26, 31, 43, 76, 77, 81, 89, 93, 94, 102, 120], "from": [1, 3, 4, 6, 7, 8, 10, 11, 12, 14, 16, 18, 22, 23, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 40, 41, 42, 44, 47, 49, 50, 51, 53, 54, 55, 57, 58, 60, 61, 62, 64, 68, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125, 126], "1275": 1, "dimitri": [1, 56], "papadopoulo": [1, 56], "qualiti": 1, "life": [1, 20, 102, 105], "ci": [1, 4, 26, 42], "includ": [1, 2, 4, 6, 9, 10, 12, 15, 16, 20, 23, 26, 28, 35, 37, 43, 51, 56, 58, 66, 70, 72, 76, 77, 82, 88, 90, 91, 92, 103, 106, 113, 116, 119, 122, 123], "color": [1, 42, 77, 92, 122], "output": [1, 10, 26, 30, 36, 40, 43, 60, 61, 62, 64, 66, 68, 69, 70, 71, 77, 78, 86, 89, 90, 92, 93, 94, 100, 102, 103, 108, 109, 111, 115, 116, 119, 120, 123, 124, 125, 126], "oidc": 1, "publish": [1, 26, 58], "1282": 1, "patch": [1, 6, 9, 15, 19, 22, 50, 51, 79], "pre": [1, 40, 43, 123], "compat": [1, 4, 6, 7, 9, 10, 11, 13, 22, 28, 31, 37, 77, 103, 112, 119], "1250": 1, "mathieu": [1, 56], "scheltienn": [1, 56], "spellcheck": [1, 22], "tox": [1, 22, 56, 66], "1266": 1, "py312": 1, "dev": [1, 22, 26, 58, 81, 92], "x64": [1, 22], "1267": 1, "resurrect": 1, "configur": [1, 22, 26, 43, 46, 50, 79, 85], "cover": [1, 7, 9, 19, 33, 35, 56, 58, 77], "workflow": [1, 19, 22, 23, 46, 48, 50, 52], "check": [1, 2, 3, 4, 7, 9, 10, 12, 13, 20, 22, 26, 27, 30, 31, 39, 43, 52, 59, 62, 65, 68, 69, 70, 71, 76, 77, 79, 84, 85, 87, 90, 92, 93, 102, 103, 104, 105, 116, 117, 118, 119, 123], "1262": 1, "updat": [1, 4, 5, 6, 11, 19, 22, 26, 42, 46, 50, 57, 68, 102, 103, 104, 116, 119], "support": [1, 9, 11, 12, 13, 18, 22, 23, 28, 34, 35, 41, 57, 66, 69, 72, 87, 92, 95, 100, 103, 105, 107, 109, 116, 119, 125], "1247": 1, "1261": 1, "1273": 1, "us": [1, 3, 6, 8, 10, 11, 14, 16, 19, 20, 21, 22, 23, 25, 26, 27, 28, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47, 49, 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 84, 85, 86, 87, 88, 90, 91, 92, 94, 96, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126], "py3k": 1, "modul": [1, 3, 22, 26, 33, 35, 57, 58, 65, 66, 72, 76, 79, 81, 86, 105, 107, 112, 113, 121], "1243": 1, "variou": [1, 10, 22, 26, 30, 34, 38, 41, 62, 75, 76, 79, 94, 106, 124], "typo": [1, 23, 43], "style": [1, 6, 19, 25, 34, 60, 70, 74, 92], "issu": [1, 3, 6, 8, 13, 16, 22, 23, 25, 26, 28, 43, 76, 90, 103, 109], "detect": [1, 26, 51, 72, 78, 102, 109], "codespel": [1, 22], "pyupgrad": 1, "refurb": 1, "1263": 1, "1269": 1, "1270": 1, "1271": 1, "1276": 1, "stabl": [1, 20, 34], "argsort": 1, "ensur": [1, 15, 19, 22, 23, 29, 41, 43, 77, 90, 94, 103, 105], "consist": [1, 6, 11, 15, 19, 22, 23, 27, 35, 36, 65, 75, 77, 78, 84, 87, 92, 94, 102, 113], "behavior": [1, 12, 14, 30, 55, 62, 69, 70, 71, 74, 80, 84, 92, 93, 94, 99, 100, 102, 109, 118, 120, 122, 123], "system": [1, 3, 20, 32, 33, 35, 36, 40, 41, 54, 57, 60, 61, 62, 85, 86, 94, 102, 109, 110, 113, 119, 126], "avx512": 1, "simd": 1, "instruct": [1, 6, 23, 26, 31, 43, 44, 45, 47, 51, 53, 56, 57], "1234": 1, "codecov": 1, "submiss": 1, "1224": 1, "link": [1, 3, 6, 9, 16, 31, 34, 43, 49, 51, 76, 86, 122], "logo": 1, "url": [1, 6, 9, 16, 20, 43, 53, 63, 87], "avoid": [1, 6, 7, 8, 9, 11, 12, 15, 19, 20, 35, 43, 55, 60, 76, 81, 90, 116, 118, 123], "broken": [1, 2, 40, 76], "pypi": [1, 26, 57], "1218": 1, "zvi": [1, 56], "baratz": [1, 56], "1280": 1, "int_to_float": [1, 65], "as_int": [1, 65], "ar": [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 22, 23, 26, 27, 28, 29, 30, 31, 34, 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 64, 65, 66, 68, 69, 71, 72, 74, 75, 76, 77, 78, 79, 80, 84, 86, 87, 89, 90, 92, 93, 94, 101, 102, 103, 104, 105, 108, 109, 110, 111, 113, 114, 115, 117, 118, 119, 120, 122, 123, 124, 126], "longer": [1, 6, 10, 51, 62, 87, 91], "need": [1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 15, 16, 19, 20, 22, 26, 27, 28, 29, 30, 31, 35, 38, 40, 41, 42, 43, 44, 45, 51, 55, 60, 61, 64, 69, 70, 71, 72, 76, 77, 79, 80, 86, 87, 90, 92, 99, 100, 102, 103, 107, 108, 109, 111, 115, 116, 117, 118, 119, 123, 124], "around": [1, 2, 4, 6, 7, 9, 14, 16, 19, 27, 36, 40, 76, 86, 103, 113, 124, 125], "defici": 1, "have": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 15, 16, 18, 19, 20, 21, 22, 23, 25, 26, 28, 29, 31, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 45, 47, 49, 51, 52, 53, 55, 56, 57, 60, 61, 62, 64, 66, 68, 69, 70, 71, 74, 76, 77, 79, 80, 81, 84, 87, 88, 89, 90, 92, 93, 94, 95, 97, 99, 100, 102, 103, 104, 105, 107, 108, 109, 110, 111, 113, 115, 116, 117, 118, 119, 121, 122, 123, 124], "1272": 1, "make": [1, 2, 3, 4, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 22, 25, 27, 28, 29, 35, 36, 42, 46, 49, 50, 51, 53, 54, 58, 60, 61, 62, 71, 74, 79, 80, 82, 87, 90, 92, 100, 103, 105, 109, 114, 116, 118, 119, 123, 124], "import": [1, 2, 3, 4, 6, 7, 9, 11, 15, 19, 20, 22, 27, 29, 36, 37, 41, 54, 55, 57, 60, 61, 62, 64, 66, 69, 72, 73, 74, 76, 77, 79, 80, 81, 84, 87, 93, 94, 97, 100, 103, 107, 112, 113, 116, 118, 120, 121, 122, 123, 124], "1208": 1, "fabian": [1, 56], "perez": [1, 49, 56], "symmetr": [1, 102], "threshold": [1, 76, 86, 90, 102, 108, 113, 123], "identifi": [1, 9, 10, 17, 20, 25, 28, 31, 33, 35, 40, 56, 66, 77, 84, 102, 110], "unit": [1, 2, 9, 12, 37, 38, 40, 42, 60, 65, 68, 76, 77, 102, 103, 113], "qform": [1, 59, 103], "calcul": [1, 9, 14, 28, 36, 38, 39, 40, 62, 63, 68, 71, 76, 86, 90, 101, 102, 108, 109, 111, 113], "1182": 1, "type": [1, 3, 7, 8, 10, 11, 12, 13, 14, 15, 16, 21, 29, 30, 33, 35, 38, 39, 41, 43, 52, 55, 57, 61, 62, 64, 65, 67, 69, 70, 71, 72, 74, 76, 77, 78, 80, 81, 82, 84, 87, 89, 92, 94, 95, 98, 99, 100, 102, 103, 104, 106, 110, 113, 116, 117, 118, 119, 123, 124], "1213": 1, "1179": 1, "1188": 1, "1189": 1, "1197": 1, "explicit": [1, 2, 3, 7, 8, 9, 35, 40, 90, 103], "overrid": [1, 3, 9, 15, 27, 69, 110, 116], "write": [1, 2, 4, 6, 9, 10, 11, 14, 18, 20, 22, 25, 29, 30, 35, 36, 37, 42, 43, 45, 51, 52, 53, 56, 64, 65, 66, 69, 71, 72, 77, 84, 87, 88, 91, 92, 94, 103, 104, 106, 117, 118, 119, 120, 123, 124], "file": [1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 14, 15, 20, 21, 22, 25, 26, 27, 31, 32, 36, 37, 38, 39, 41, 42, 43, 52, 54, 56, 58, 59, 62, 63, 64, 65, 66, 69, 70, 71, 72, 73, 74, 77, 78, 79, 80, 84, 85, 87, 88, 89, 90, 91, 92, 94, 97, 98, 99, 100, 102, 103, 104, 106, 117, 118, 119, 120, 123, 124, 125, 126], "contain": [1, 2, 3, 6, 7, 10, 11, 12, 13, 15, 16, 18, 20, 28, 30, 31, 33, 35, 36, 37, 38, 40, 41, 42, 61, 62, 68, 69, 70, 74, 76, 77, 79, 80, 84, 87, 88, 90, 92, 94, 99, 100, 102, 103, 104, 108, 109, 111, 113, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125], "arrai": [1, 3, 8, 9, 10, 11, 12, 14, 15, 29, 30, 36, 38, 39, 40, 41, 42, 54, 56, 59, 60, 62, 64, 65, 66, 68, 69, 70, 71, 73, 74, 76, 77, 78, 80, 84, 86, 90, 92, 93, 94, 99, 100, 102, 103, 104, 108, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119, 122, 123, 124, 126], "standard": [1, 2, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 22, 26, 28, 32, 33, 36, 37, 38, 40, 55, 64, 76, 77, 81, 84, 87, 89, 94, 102, 103, 105, 116, 118, 119, 120, 121, 123, 124, 126], "1199": 1, "alexi": 1, "thual": 1, "move": [1, 2, 11, 12, 19, 23, 38, 39, 50, 60, 68, 86, 92, 112, 122], "compress": [1, 4, 20, 67, 69, 74, 106, 117, 118], "logic": [1, 3, 35, 85], "privat": [1, 3, 7, 9, 10, 20, 23, 28, 30, 31, 36, 37, 39, 40, 102, 126], "unexpect": 1, "error": [1, 3, 9, 13, 14, 22, 26, 28, 29, 31, 36, 40, 57, 63, 64, 65, 68, 69, 71, 72, 74, 76, 77, 79, 81, 82, 83, 84, 86, 87, 89, 90, 93, 94, 96, 99, 102, 107, 108, 109, 112, 113, 116, 118, 121, 124], "pyzstd": 1, "1212": 1, "docstr": [1, 3, 19, 22, 55, 69, 102, 108, 123], "format": [1, 2, 9, 10, 11, 12, 14, 16, 19, 21, 22, 25, 26, 28, 30, 31, 32, 34, 40, 41, 42, 52, 56, 57, 60, 61, 62, 65, 66, 70, 72, 74, 75, 77, 78, 79, 80, 84, 86, 87, 91, 92, 94, 98, 99, 100, 102, 103, 104, 114, 116, 117, 118, 119, 123, 126], "1200": [1, 62], "modern": 1, "readm": [1, 4, 26, 31, 43, 74], "text": [1, 6, 9, 18, 22, 26, 35, 42, 43, 51, 56, 60, 75, 77, 103, 114, 120, 123], "1195": 1, "badg": [1, 26, 56, 66], "distribut": [1, 4, 20, 22, 26, 27, 56, 57, 58, 61], "1192": 1, "horea": [1, 56], "christian": [1, 56, 58], "all": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 20, 22, 23, 26, 27, 30, 35, 38, 40, 41, 42, 43, 52, 53, 55, 56, 58, 60, 61, 62, 64, 66, 71, 76, 77, 78, 79, 80, 84, 86, 89, 90, 93, 94, 96, 97, 102, 103, 105, 106, 109, 113, 114, 115, 116, 118, 119, 123, 124], "depend": [1, 6, 9, 10, 12, 14, 16, 22, 26, 28, 29, 30, 35, 37, 38, 56, 66, 69, 74, 77, 87, 92, 94, 99, 100, 103, 104, 105, 106, 109, 116, 117, 118, 123], "distutil": [1, 26, 79], "setuptool": [1, 26], "1190": 1, "_version": 1, "pyi": 1, "stub": 1, "mypi": 1, "run": [1, 2, 4, 9, 18, 20, 22, 23, 25, 26, 27, 40, 42, 56, 57, 66, 72, 73, 76, 90, 92, 124], "without": [1, 2, 4, 6, 7, 9, 10, 11, 15, 16, 19, 20, 23, 26, 35, 41, 43, 58, 61, 69, 70, 72, 76, 79, 86, 89, 112, 116, 117, 119], "build": [1, 3, 6, 9, 20, 26, 28, 31, 41, 57, 119], "1210": [1, 40], "rag": 1, "voxel": [1, 12, 30, 32, 33, 36, 59, 61, 62, 68, 69, 74, 77, 78, 84, 92, 97, 99, 100, 102, 103, 104, 108, 109, 110, 111, 115, 116, 117, 118, 119, 123, 126], "parcelsaxi": [1, 65], "1194": 1, "michiel": [1, 56], "cottaar": [1, 56], "return": [1, 2, 3, 7, 8, 12, 14, 15, 27, 35, 37, 40, 52, 55, 60, 61, 62, 66, 68, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, 124], "cwd": 1, "except": [1, 2, 10, 13, 15, 38, 40, 42, 71, 72, 76, 77, 79, 81, 82, 83, 87, 88, 89, 90, 92, 93, 99, 102, 108, 109, 111, 115, 116, 119, 121, 123, 124], "intemporarydirectori": [1, 65], "1184": 1, "py": [1, 3, 4, 10, 11, 26, 38, 40, 52, 58, 73], "root": [1, 4, 26, 79, 89, 102], "enabl": [1, 5, 22, 87, 109, 110], "downstream": 1, "project": [1, 4, 6, 18, 20, 22, 23, 28, 30, 43, 45, 48, 49, 56, 58, 77, 94, 110], "fernando": [1, 49, 56], "p\u00e9rez": [1, 56], "garcia": 1, "cach": [1, 7, 14, 27, 59, 71, 80, 83, 86, 102, 119], "git": [1, 4, 5, 6, 19, 20, 25, 26, 43, 44, 48, 50, 51, 52, 53, 56, 57, 58, 66, 73], "archiv": [1, 6, 9, 20, 22, 26, 34, 56, 58, 66, 79], "separ": [1, 2, 6, 9, 10, 11, 13, 27, 30, 35, 36, 40, 43, 60, 61, 77, 79, 80, 87, 103, 109, 118], "action": [1, 45, 58, 90], "1186": 1, "serializableimag": [1, 65, 77, 92, 94, 103], "now": [1, 2, 3, 4, 7, 8, 10, 12, 14, 15, 20, 24, 26, 30, 35, 38, 39, 40, 41, 42, 43, 44, 45, 51, 52, 53, 62, 68, 69, 71, 90, 105, 117, 118], "to_stream": [1, 65, 87], "from_stream": [1, 65, 87], "read": [1, 2, 4, 7, 8, 9, 10, 14, 15, 18, 19, 20, 23, 25, 28, 31, 34, 36, 37, 39, 43, 49, 51, 52, 53, 55, 56, 62, 64, 65, 66, 69, 70, 74, 77, 78, 80, 84, 87, 88, 90, 91, 92, 94, 98, 99, 100, 103, 104, 105, 106, 109, 116, 117, 118, 119, 123, 124, 125], "stream": [1, 33, 35, 39, 72, 78, 87, 102, 106], "implement": [1, 3, 6, 7, 8, 10, 11, 12, 13, 15, 19, 20, 21, 28, 30, 33, 34, 35, 42, 43, 56, 62, 66, 68, 69, 70, 72, 74, 84, 86, 87, 88, 90, 91, 92, 95, 99, 102, 103, 109, 110, 116, 119, 123, 124], "iobas": [1, 87, 88, 106, 116, 123], "interfac": [1, 6, 7, 11, 15, 27, 30, 61, 64, 65, 69, 77, 87, 102, 119, 125], "A": [1, 2, 6, 12, 14, 15, 16, 17, 18, 20, 22, 23, 25, 27, 28, 29, 30, 33, 36, 38, 40, 41, 43, 49, 54, 58, 60, 61, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 84, 86, 90, 92, 94, 99, 100, 102, 105, 106, 108, 109, 110, 111, 112, 113, 115, 116, 118, 119, 122, 123, 124, 126], "from_url": [1, 65, 87], "load": [1, 2, 3, 8, 10, 11, 12, 15, 17, 21, 25, 29, 30, 36, 37, 41, 54, 55, 59, 60, 62, 64, 65, 66, 69, 73, 74, 77, 80, 84, 87, 91, 92, 94, 99, 100, 109, 116, 123], "imag": [1, 4, 8, 17, 18, 20, 21, 23, 25, 28, 29, 31, 32, 35, 36, 37, 38, 39, 40, 41, 56, 57, 58, 59, 60, 65, 66, 68, 69, 70, 73, 74, 77, 78, 80, 84, 87, 89, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 106, 110, 111, 115, 116, 117, 118, 122, 123, 125, 126], "1129": 1, "trkfile": [1, 11, 65], "trkv3": 1, "an": [1, 3, 4, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 19, 20, 22, 23, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 40, 41, 42, 43, 49, 52, 54, 55, 56, 57, 58, 60, 61, 62, 64, 66, 68, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 81, 84, 86, 87, 89, 90, 92, 93, 94, 96, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 113, 115, 116, 117, 118, 119, 123, 124, 125, 126], "undocu": 1, "variant": [1, 70, 103, 104, 106, 117, 118], "trkv2": 1, "1125": 1, "multilin": [1, 114], "header": [1, 2, 3, 7, 10, 12, 13, 14, 15, 17, 18, 25, 27, 28, 30, 32, 33, 34, 35, 36, 38, 40, 41, 56, 59, 64, 65, 66, 70, 72, 74, 77, 78, 80, 84, 87, 89, 92, 93, 94, 96, 99, 100, 102, 103, 104, 106, 109, 111, 116, 117, 118, 124], "field": [1, 2, 3, 6, 10, 11, 12, 30, 31, 32, 36, 38, 39, 40, 62, 65, 69, 76, 77, 78, 92, 102, 103, 104, 106, 109, 117, 118, 123, 124, 126], "tckfile": [1, 65], "1175": 1, "matt": [1, 56], "cieslak": [1, 56], "layout": [1, 70, 90, 92, 123, 126], "order": [1, 2, 6, 7, 8, 9, 10, 12, 15, 18, 27, 29, 30, 31, 32, 35, 37, 38, 56, 69, 70, 71, 72, 73, 77, 78, 79, 80, 84, 86, 87, 90, 92, 93, 94, 102, 103, 109, 111, 116, 119, 123, 124], "initi": [1, 22, 23, 41, 42, 44, 69, 70, 71, 72, 74, 76, 77, 79, 80, 84, 87, 88, 92, 99, 100, 102, 103, 104, 105, 108, 109, 116, 117, 118, 119, 123, 124], "paramet": [1, 2, 7, 14, 34, 62, 64, 66, 68, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125], "1131": 1, "1115": 1, "1178": 1, "handl": [1, 10, 43, 69, 70, 74, 80, 84, 90, 92, 99, 100, 103, 108, 109, 118, 123], "extens": [1, 10, 13, 17, 25, 27, 28, 37, 59, 61, 74, 77, 87, 89, 103, 104, 106, 109, 119, 123], "mismatch": 1, "incomplet": [1, 109], "1013": 1, "1138": 1, "thoma": [1, 56], "phil": 1, "tck": [1, 11, 65, 78], "which": [1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 27, 29, 30, 33, 35, 36, 40, 42, 43, 60, 61, 62, 64, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 81, 84, 86, 87, 88, 89, 90, 92, 94, 96, 98, 102, 103, 104, 105, 106, 108, 109, 111, 113, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124], "could": [1, 2, 7, 8, 9, 10, 11, 12, 13, 15, 20, 22, 27, 55, 60, 77, 86, 90, 102, 107, 109, 118, 121], "sometim": [1, 2, 6, 8, 13, 19, 34, 35, 43, 54, 55, 60, 84, 90, 116], "caus": [1, 22, 26, 58, 60, 92, 118, 124], "infinit": [1, 76], "loop": [1, 39, 40], "1140": 1, "anib": [1, 56], "solon": 1, "clean": [1, 26, 49], "left": [1, 2, 12, 15, 18, 36, 38, 40, 43, 54, 60, 62, 68, 69, 77, 86, 94, 102, 109, 113, 115], "filehandl": [1, 65], "fail": [1, 3, 22, 23, 68, 78, 102, 123], "class": [1, 3, 8, 10, 11, 12, 15, 30, 35, 61, 62, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 87, 88, 89, 92, 93, 94, 95, 96, 98, 99, 100, 101, 102, 103, 104, 105, 106, 108, 109, 110, 111, 112, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125], "variabl": [1, 5, 19, 35, 39, 40, 70, 79, 84, 85, 100, 106, 119, 124], "1155": 1, "simplifi": [1, 10, 28, 35, 36, 104], "code": [1, 2, 4, 6, 7, 9, 10, 11, 14, 16, 19, 23, 25, 26, 28, 34, 35, 36, 37, 39, 40, 41, 42, 43, 52, 53, 56, 57, 59, 65, 66, 69, 71, 72, 74, 77, 78, 84, 85, 86, 92, 94, 96, 102, 103, 104, 108, 117, 118, 122, 123, 124], "assum": [1, 8, 9, 12, 15, 19, 27, 30, 36, 38, 40, 51, 62, 69, 70, 77, 79, 90, 102, 103, 111, 113, 114, 119, 122, 123], "binari": [1, 26, 35, 58, 62, 69, 77, 84, 87, 90, 91, 92, 103, 104, 109, 116, 117, 118, 119, 124], "mode": [1, 52, 56, 64, 65, 66, 69, 70, 74, 80, 84, 88, 90, 92, 94, 99, 100, 106, 109, 111, 118, 119, 122, 123], "1142": 1, "1159": 1, "miscellan": [1, 21, 30], "cleanup": 1, "1148": 1, "1149": 1, "1153": 1, "1154": 1, "1156": 1, "deploi": 1, "artifact": [1, 61], "1134": 1, "transit": 1, "setup": [1, 25, 26, 31, 107], "cfg": 1, "pyproject": [1, 22], "toml": [1, 22], "1133": 1, "address": [1, 6, 16, 22, 42], "race": 1, "condit": [1, 35, 58, 81], "prevent": [1, 10, 42, 76, 96, 123], "pytest": [1, 5, 26, 56, 57, 66, 73], "xdist": 1, "1157": 1, "1158": 1, "haselgrov": [1, 56, 58], "appli": [1, 6, 7, 10, 13, 14, 20, 22, 28, 29, 30, 36, 38, 40, 56, 60, 62, 68, 69, 71, 72, 74, 77, 80, 86, 90, 99, 100, 102, 103, 104, 108, 109, 110, 111, 113, 115, 116, 119, 123, 126], "blue": [1, 2, 22, 42, 77, 94], "isort": 1, "auto": [1, 22, 105], "formatt": [1, 22], "provid": [1, 4, 6, 9, 10, 15, 16, 18, 19, 28, 35, 38, 41, 56, 58, 61, 62, 66, 75, 77, 78, 81, 87, 90, 92, 103, 105, 106, 110, 119, 120], "reduc": [1, 6, 10, 22, 43, 80, 86, 113, 123], "human": [1, 72], "burden": [1, 15, 19], "guidelin": [1, 6, 19, 23, 25, 56, 66], "1124": 1, "1165": 1, "1169": 1, "manag": [1, 11, 22, 23, 35, 49, 57, 61, 64, 96, 103, 106, 119, 120], "version": [1, 3, 6, 7, 8, 12, 14, 22, 24, 26, 31, 36, 38, 39, 40, 43, 56, 58, 59, 61, 66, 71, 76, 77, 79, 80, 81, 82, 90, 92, 93, 94, 98, 105, 107, 108, 109, 112, 117, 118, 120, 122, 124], "setuptools_scm": 1, "1171": 1, "instal": [1, 4, 22, 26, 31, 34, 37, 43, 44, 50, 59, 65, 79], "size": [1, 2, 4, 12, 13, 14, 18, 20, 30, 36, 38, 54, 61, 62, 65, 68, 77, 78, 84, 90, 91, 94, 99, 102, 103, 106, 109, 111, 119, 123, 125], "exclud": [1, 51, 68, 103], "veri": [1, 4, 6, 8, 10, 14, 20, 26, 35, 38, 42, 45, 60, 72, 77, 84, 103, 109, 113], "larg": [1, 4, 7, 20, 22, 27, 34, 76, 77, 86, 90, 94, 103, 104, 109, 123], "1176": 1, "int64": [1, 103], "nifti1imag": [1, 7, 41, 54, 55, 61, 62, 65, 66, 81, 93, 97, 102, 104, 109, 111, 119], "dtype": [1, 11, 14, 29, 41, 55, 61, 62, 64, 65, 69, 70, 71, 72, 76, 77, 78, 80, 84, 87, 90, 92, 93, 97, 103, 104, 109, 110, 113, 116, 117, 118, 119, 123, 124], "rais": [1, 9, 11, 13, 14, 15, 20, 23, 26, 64, 69, 71, 72, 74, 76, 77, 79, 80, 82, 87, 89, 92, 93, 94, 96, 98, 101, 102, 103, 104, 105, 107, 108, 109, 112, 116, 118, 119, 120, 121, 123, 124], "valueerror": [1, 14, 68, 77, 92, 93, 101, 103, 109, 119, 124], "1173": 1, "temporarydirectori": [1, 65], "favor": [1, 7, 13, 80], "tempfil": [1, 27, 64, 120], "1172": 1, "nisext": 1, "1170": 1, "drop": [1, 4, 27, 90, 108, 111], "19": [1, 9, 35, 61, 62], "1177": 1, "follow": [1, 2, 3, 6, 7, 8, 9, 14, 15, 18, 19, 22, 23, 26, 31, 35, 38, 39, 40, 41, 42, 43, 50, 52, 53, 56, 57, 58, 61, 62, 69, 70, 72, 77, 78, 79, 84, 86, 87, 94, 102, 103, 109, 111, 112, 117, 118, 119], "expireddeprecationerror": [1, 65, 76, 80, 94, 98, 105, 108, 112, 120], "": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 14, 15, 19, 20, 23, 26, 28, 29, 30, 31, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 48, 49, 51, 52, 54, 56, 60, 61, 62, 66, 68, 69, 76, 77, 78, 79, 84, 85, 86, 87, 88, 90, 92, 94, 96, 102, 103, 105, 106, 107, 108, 109, 110, 111, 115, 116, 118, 119, 122, 123], "read_img_data": [1, 65], "dataobjimag": [1, 65, 77, 84, 95, 99, 100, 116], "get_data": [1, 7, 8, 10, 12, 14, 65, 80, 93, 102, 103, 119], "guessed_image_typ": [1, 65], "setattr_on_read": [1, 65], "flip_axi": [1, 65], "expir": [1, 82], "were": [1, 6, 12, 16, 22, 40, 60, 64, 77, 78, 87, 89, 94, 102, 103, 105, 109], "fulli": [1, 7, 15, 19, 31, 35, 60, 123], "attributeerror": [1, 64, 79, 102, 121, 123, 124], "giftimetadata": [1, 65], "proxi": [1, 3, 8, 14, 15, 27, 59, 62, 70, 74, 80, 81, 84, 99, 109, 118, 121], "1127": 1, "hao": [1, 56], "ting": [1, 56], "wang": [1, 56], "final": [1, 2, 6, 12, 15, 16, 26, 36, 43, 52, 61, 68, 91, 92, 93, 94, 103, 108, 109, 119, 120, 122], "to_fileobj": [1, 65, 71], "nan2zero": [1, 71, 76, 123], "1126": 1, "convert": [1, 2, 6, 7, 10, 17, 20, 25, 34, 40, 42, 65, 69, 71, 76, 77, 86, 87, 103, 107, 108, 109, 111, 113, 114, 119, 123], "expect": [1, 3, 11, 12, 14, 23, 26, 40, 70, 77, 82, 84, 85, 87, 89, 94, 99, 109, 116, 122, 123], "deprecationwarn": [1, 12, 81, 82], "1117": 1, "suppress": [1, 2, 54, 61, 62, 81], "nan": [1, 61, 62, 69, 71, 76, 78, 102, 103, 108, 117, 118, 119, 123], "int": [1, 9, 18, 66, 70, 71, 72, 76, 77, 80, 81, 82, 87, 88, 90, 91, 92, 93, 94, 97, 99, 100, 101, 102, 103, 106, 109, 110, 111, 115, 116, 119, 122, 123, 124, 125], "1118": 1, "nib": [1, 2, 7, 11, 12, 14, 26, 37, 41, 54, 55, 60, 61, 62, 66, 73, 74, 80, 84, 87, 94, 100, 116, 124], "cli": 1, "tool": [1, 6, 9, 20, 22, 28, 34, 37, 49, 83], "convers": [1, 10, 11, 31, 32, 33, 34, 36, 57, 69, 71, 76, 77, 86, 103, 123], "access": [1, 3, 4, 27, 28, 35, 37, 41, 45, 51, 52, 55, 56, 57, 61, 62, 66, 69, 70, 74, 77, 79, 80, 81, 84, 90, 92, 99, 100, 102, 103, 104, 105, 107, 117, 118, 119, 123, 124], "via": [1, 3, 4, 6, 23, 34, 41, 43, 56, 57, 61, 66, 69, 88, 90, 102, 109, 116, 117, 118, 119, 124], "command": [1, 6, 34, 35, 42, 43, 44, 49, 52, 78, 100, 102, 109, 111], "line": [1, 2, 6, 7, 12, 14, 19, 20, 22, 26, 34, 42, 43, 44, 51, 52, 54, 69, 78, 100, 102, 106, 109, 114], "1113": 1, "ariel": [1, 56], "rokem": [1, 56], "mask": [1, 18, 43, 77, 97, 103, 110], "smallest": [1, 76, 103, 123], "alias": [1, 61, 103, 116, 123], "nifti": [1, 2, 3, 8, 12, 13, 14, 17, 25, 27, 28, 30, 31, 32, 34, 36, 40, 41, 54, 59, 60, 61, 69, 77, 78, 94, 102, 103, 109, 116, 117, 118, 123], "specif": [1, 2, 3, 6, 9, 11, 12, 14, 15, 20, 26, 28, 33, 35, 37, 38, 41, 45, 58, 61, 62, 64, 70, 74, 76, 77, 78, 84, 86, 87, 94, 98, 99, 100, 102, 103, 111, 113, 116, 125], "can": [1, 2, 4, 5, 6, 7, 8, 9, 11, 14, 15, 18, 19, 20, 22, 23, 25, 26, 27, 28, 29, 30, 34, 35, 36, 37, 38, 39, 41, 42, 43, 49, 51, 52, 53, 54, 55, 56, 57, 60, 61, 62, 63, 64, 68, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 84, 86, 87, 90, 91, 92, 94, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124], "content": [1, 4, 6, 20, 22, 26, 32, 35, 37, 42, 46, 50, 61, 69, 75, 77, 79, 87, 92, 94, 103, 108, 114, 116, 117, 118, 119, 124], "uint8": [1, 30, 39, 41, 69, 71, 76, 103], "find": [1, 2, 3, 6, 9, 19, 23, 40, 43, 45, 48, 52, 56, 60, 62, 76, 77, 79, 85, 90, 102, 123], "nearest": [1, 39, 54, 76, 102, 103, 111], "therefor": [1, 2, 7, 9, 12, 13, 18, 19, 20, 28, 35, 36, 38, 54, 60, 61, 68, 71, 76, 79, 86, 87, 102, 109, 111, 116], "wide": [1, 10, 100], "truncat": [1, 40, 109, 123], "attempt": [1, 6, 31, 64, 68, 72, 77, 89, 90, 103, 116], "integ": [1, 2, 8, 9, 14, 30, 35, 40, 41, 61, 69, 71, 72, 76, 77, 90, 92, 94, 103, 104, 106, 109, 111, 119, 123, 124], "1096": 1, "rorden": [1, 31, 34, 60], "josh": 1, "teve": 1, "cifti2imag": [1, 15, 65], "1111": 1, "__init__": [1, 3, 8, 26, 65, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 87, 88, 89, 92, 94, 96, 99, 100, 101, 102, 103, 104, 105, 106, 108, 109, 110, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125], "to_filenam": [1, 15, 27, 61, 65, 87, 116], "better": [1, 3, 6, 13, 38, 43, 48, 52, 76, 90, 111], "control": [1, 20, 26, 43, 61, 62, 69, 70, 74, 80, 84, 92, 94, 99, 100, 106, 109, 113, 118, 122, 123], "over": [1, 2, 6, 9, 11, 12, 19, 20, 26, 33, 35, 60, 77, 90, 92, 93, 102, 111, 122, 124], "1082": 1, "discuss": [1, 6, 7, 8, 13, 14, 20, 23, 25, 27, 28, 33, 35, 42, 56, 119], "jerom": 1, "dock": 1, "zstd": 1, "1005": 1, "andrew": [1, 56], "van": [1, 56, 58], "externalfilebinari": [1, 94], "non": [1, 2, 7, 9, 23, 40, 42, 58, 71, 73, 77, 94, 97, 106, 113, 116, 123], "thread": [1, 6, 9, 14, 16, 19, 90, 120], "safe": [1, 2, 4, 9, 27, 52, 90, 120], "1103": 1, "jacob": [1, 56], "robert": [1, 56], "unifi": 1, "xml": [1, 9, 75, 77, 87, 94, 109, 125], "metadata": [1, 2, 3, 27, 28, 56, 61, 64, 65, 66, 69, 74, 75, 77, 80, 84, 87, 92, 94, 99, 100, 103, 104, 109, 116, 117, 118, 119], "cifti2metadata": [1, 65], "dict": [1, 9, 15, 62, 69, 74, 75, 76, 77, 78, 79, 80, 84, 87, 88, 89, 92, 94, 99, 100, 102, 106, 109, 114, 118, 119, 123, 124, 125], "1091": 1, "__repr__": 1, "object": [1, 2, 6, 7, 9, 10, 11, 12, 14, 15, 20, 23, 27, 28, 30, 31, 33, 38, 41, 42, 43, 55, 56, 59, 62, 64, 66, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 87, 88, 90, 91, 92, 94, 95, 96, 98, 99, 100, 102, 103, 104, 105, 106, 107, 109, 110, 111, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 126], "1092": 1, "creat": [1, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 26, 30, 33, 35, 37, 41, 42, 46, 61, 62, 64, 65, 69, 70, 71, 74, 79, 80, 84, 87, 89, 92, 93, 99, 100, 102, 103, 104, 105, 106, 109, 116, 118, 119, 120, 122, 123, 124], "gzip": [1, 43, 73, 106], "determinist": [1, 106], "default": [1, 3, 4, 5, 7, 9, 10, 11, 12, 13, 14, 20, 27, 31, 41, 43, 45, 52, 55, 57, 59, 61, 64, 66, 69, 70, 71, 72, 74, 76, 77, 79, 80, 81, 84, 85, 86, 87, 88, 89, 90, 92, 93, 94, 96, 99, 100, 102, 103, 104, 105, 106, 107, 109, 110, 111, 113, 114, 116, 117, 118, 119, 120, 122, 123, 124, 125], "1024": [1, 4, 87, 91, 103], "clear": [1, 8, 9, 11, 13, 14, 19, 34, 55, 84], "messag": [1, 14, 19, 23, 32, 40, 43, 52, 65, 72, 77, 79, 81, 96, 104, 107, 121, 126], "when": [1, 2, 3, 4, 6, 8, 9, 11, 12, 13, 14, 15, 19, 20, 22, 23, 26, 27, 29, 30, 35, 36, 37, 40, 41, 42, 43, 52, 55, 56, 61, 62, 66, 68, 69, 70, 71, 74, 76, 77, 78, 79, 80, 81, 82, 86, 87, 89, 90, 94, 99, 100, 102, 103, 105, 106, 107, 108, 109, 111, 116, 119, 120, 123], "zip": [1, 20, 26], "don": [1, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 19, 20, 26, 29, 34, 37, 40, 43, 44, 45, 52, 57, 69, 76, 80, 81, 90, 102, 105, 115, 123], "t": [1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 16, 19, 20, 26, 27, 29, 33, 34, 36, 37, 38, 40, 43, 44, 45, 52, 53, 55, 57, 58, 60, 61, 64, 68, 69, 76, 79, 80, 81, 86, 87, 90, 92, 99, 100, 102, 103, 104, 105, 107, 108, 115, 118, 119, 123], "match": [1, 2, 3, 9, 15, 22, 26, 40, 62, 69, 72, 77, 87, 89, 90, 94, 102, 103, 104, 108, 109, 115, 116, 119, 123], "j\u00e9r\u00f4me": [1, 56], "dock\u00e8": [1, 56], "re": [1, 8, 9, 20, 23, 27, 33, 37, 38, 43, 45, 51, 52, 53, 68, 87, 103, 104, 109, 116, 123], "extern": [1, 19, 27, 58, 94], "netcdf": [1, 59, 99], "scipi": [1, 15, 57, 58, 111, 115], "1110": 1, "resiz": 1, "arraysequ": [1, 65], "helper": [1, 77, 78, 123], "increment": [1, 33, 77, 81, 122], "1093": 1, "submodul": [1, 3, 5, 25, 107], "protocol": [1, 43, 66, 70, 84, 87, 90, 99, 102, 106, 110, 116], "1097": 1, "biap": [1, 15, 25, 28], "coordinateimag": [1, 15], "1084": 1, "1073": 1, "lgtm": 1, "fals": [1, 7, 11, 12, 22, 27, 29, 40, 43, 55, 61, 66, 68, 69, 70, 71, 72, 73, 74, 76, 77, 80, 82, 83, 84, 86, 89, 90, 92, 93, 94, 99, 100, 102, 103, 104, 105, 106, 107, 109, 110, 113, 116, 118, 119, 120, 121, 123, 124], "alarm": 1, "log": [1, 22, 26, 43, 45, 49, 51, 72, 76, 96, 124], "sensit": [1, 9, 23], "inform": [1, 2, 3, 6, 9, 10, 11, 12, 15, 18, 20, 23, 28, 30, 32, 33, 37, 38, 39, 40, 41, 43, 47, 56, 57, 61, 65, 66, 69, 74, 77, 79, 80, 84, 87, 92, 94, 99, 100, 102, 103, 104, 106, 115, 116, 117, 118, 119, 124, 126], "1052": 1, "10": [1, 2, 9, 26, 29, 30, 35, 38, 40, 41, 54, 61, 62, 68, 69, 71, 72, 77, 84, 86, 93, 94, 102, 103, 105, 108, 109, 117, 123, 124], "1047": 1, "found": [1, 19, 22, 23, 31, 37, 77, 79, 86, 87, 89, 91, 92, 94, 102, 116, 123], "1040": 1, "1044": 1, "weekli": 1, "nightli": 1, "1025": 1, "establish": [1, 8], "clarifi": [1, 7], "govern": [1, 25], "decis": [1, 6, 12, 19, 25], "1019": [1, 39], "1020": [1, 39], "1022": 1, "1018": [1, 31, 39], "1017": 1, "1016": 1, "64": [1, 2, 12, 22, 39, 60, 61, 103, 104, 109], "bit": [1, 7, 9, 20, 22, 27, 35, 41, 60, 61, 77, 94, 103, 104, 109, 111], "get": [1, 2, 3, 4, 7, 8, 9, 10, 13, 14, 20, 22, 26, 27, 29, 30, 32, 33, 34, 35, 39, 40, 42, 43, 47, 48, 49, 50, 52, 53, 55, 59, 62, 64, 65, 69, 70, 71, 76, 77, 78, 80, 82, 84, 85, 89, 90, 92, 99, 102, 103, 104, 107, 108, 109, 111, 116, 117, 118, 119, 123, 124], "harder": [1, 19, 60], "u": [1, 2, 4, 8, 9, 10, 12, 20, 25, 26, 35, 36, 38, 43, 49, 51, 52, 55, 61, 70, 71, 84, 86, 87, 99, 102, 108, 109], "subclass": [1, 11, 77, 81, 102, 103, 110, 116, 124], "unless": [1, 4, 9, 14, 19, 20, 23, 26, 64, 74, 96, 102, 118], "option": [1, 6, 9, 12, 16, 20, 22, 23, 31, 35, 37, 43, 51, 52, 57, 66, 68, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 81, 82, 84, 86, 87, 88, 89, 90, 91, 92, 93, 94, 99, 100, 102, 103, 104, 106, 107, 108, 109, 111, 113, 114, 116, 117, 118, 119, 120, 122, 123, 124, 125], "futur": [1, 12, 14, 19, 21, 23, 26, 80, 81], "becom": [1, 9, 19, 20, 23, 27, 60, 81, 86, 105, 123], "addition": [1, 22, 61], "set_data_dtyp": [1, 27, 64, 65, 69, 77, 92, 103, 116], "1079": 1, "sinc": [1, 10, 20, 21, 25, 26, 43, 52, 76, 105, 119], "980": 1, "jonathan": [1, 42, 56], "daniel": [1, 56], "trackvi": [1, 11, 119], "calculate_scal": 1, "can_cast": 1, "scale_min_max": 1, "get_shap": [1, 65, 84], "mincimag": 1, "minc1imag": [1, 65, 100], "mincfil": [1, 99, 100], "minc1fil": [1, 65, 100], "from_fil": 1, "filespec_to_fil": 1, "to_filespec": 1, "to_fil": 1, "keep_file_open": [1, 69, 70, 74, 77, 80, 84, 92, 99, 100, 118], "must": [1, 6, 7, 12, 19, 23, 35, 40, 58, 68, 69, 70, 71, 74, 77, 78, 87, 89, 90, 92, 94, 102, 103, 106, 118, 119, 123], "boolean": [1, 77, 102, 103, 119], "reshap": [1, 7, 11, 55, 61, 62, 64, 65, 68, 69, 70, 81, 86, 87, 90, 93, 103, 113, 116, 123], "4x4": [1, 15, 30, 68, 77, 84, 103, 109], "encod": [1, 2, 6, 9, 10, 12, 15, 28, 35, 62, 69, 77, 82, 87, 92, 94, 103, 119, 125], "row": [1, 2, 9, 12, 18, 32, 36, 40, 62, 68, 70, 77, 84, 86, 102, 108, 109, 114, 119, 123], "major": [1, 6, 9, 16, 17, 23, 38, 70, 77, 79], "sequenc": [1, 15, 31, 35, 68, 69, 72, 76, 77, 79, 86, 87, 89, 90, 92, 93, 94, 99, 100, 101, 102, 103, 104, 108, 109, 111, 113, 114, 115, 116, 119, 122, 123], "1059": 1, "suggest": [1, 3, 12, 14, 19, 22, 38, 45, 56, 57, 66, 72, 90, 94, 109, 120], "save": [1, 7, 8, 10, 11, 13, 27, 28, 37, 41, 42, 43, 59, 62, 64, 65, 66, 69, 73, 80, 87, 90, 92, 94, 116, 118, 123], "call": [1, 2, 7, 9, 12, 13, 14, 19, 20, 22, 26, 27, 30, 31, 34, 35, 36, 38, 39, 40, 41, 42, 43, 54, 55, 60, 61, 62, 64, 69, 71, 76, 77, 80, 82, 84, 86, 87, 90, 92, 94, 102, 103, 105, 107, 109, 119, 121, 123, 124], "giftiio": 1, "1055": 1, "1043": 1, "1048": 1, "unclos": 1, "giftiimag": [1, 15, 65], "1038": 1, "lea": [1, 56], "waller": [1, 56], "being": [1, 2, 3, 6, 9, 10, 11, 12, 14, 19, 20, 31, 35, 36, 38, 60, 69, 70, 74, 80, 84, 87, 90, 92, 94, 99, 100, 102, 109, 110, 111, 118, 119, 123], "991": 1, "systemerror": 1, "1051": 1, "more": [1, 2, 3, 4, 6, 8, 9, 10, 11, 13, 15, 18, 19, 20, 22, 23, 26, 28, 29, 30, 35, 38, 40, 41, 45, 52, 55, 56, 57, 60, 61, 62, 65, 66, 68, 69, 70, 77, 80, 84, 87, 90, 103, 104, 108, 109, 110, 111, 119, 123], "constrain": [1, 9, 69, 102, 103], "mock": 1, "983": 1, "usag": [1, 6, 12, 35, 56], "1009": [1, 39, 40, 94], "tom\u00e1\u0161": [1, 56], "hrn\u010diar": [1, 56], "grammar": 1, "head": [1, 2, 35, 38, 42, 43, 51, 56, 60, 66, 74, 92, 109, 114], "coc": 1, "996": 1, "set": [1, 2, 4, 5, 6, 7, 9, 10, 12, 15, 18, 20, 22, 26, 27, 31, 32, 33, 34, 39, 40, 41, 42, 43, 46, 50, 51, 52, 61, 62, 64, 69, 70, 71, 72, 74, 76, 77, 78, 80, 84, 85, 86, 87, 88, 89, 90, 92, 96, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 113, 116, 117, 118, 122, 123, 124, 126], "pydicom": [1, 31, 34, 37, 57, 102, 103, 112], "1050": 1, "submit": [1, 6, 109], "coverag": [1, 3, 66], "pin": 1, "1008": [1, 39, 94], "upgrad": 1, "967": 1, "migrat": 1, "972": 1, "serg": [1, 56], "koudoro": [1, 56], "builtin": 1, "namespac": [1, 9, 20, 102, 107], "np": [1, 2, 7, 9, 11, 14, 15, 27, 29, 41, 54, 55, 60, 61, 62, 64, 68, 69, 70, 71, 72, 74, 76, 77, 78, 80, 81, 86, 87, 90, 92, 93, 94, 97, 99, 100, 102, 103, 104, 108, 109, 111, 113, 115, 116, 117, 118, 122, 123, 124], "float": [1, 9, 15, 17, 18, 25, 29, 35, 60, 61, 69, 70, 71, 76, 77, 78, 80, 87, 90, 92, 94, 97, 99, 100, 101, 102, 103, 104, 108, 109, 111, 113, 114, 116, 117, 118, 119, 122, 123], "964": 1, "963": 1, "stat": [1, 15, 42, 65], "expos": [1, 7, 15, 78, 103], "volum": [1, 2, 13, 18, 30, 36, 38, 55, 61, 65, 74, 77, 78, 83, 84, 87, 92, 97, 102, 103, 109, 111, 115, 122], "la": [1, 11, 60, 62], "fslstat": [1, 97], "v": [1, 2, 9, 13, 30, 42, 53, 84, 86, 97, 109, 113, 122, 123, 126], "julian": [1, 56], "klug": [1, 56], "0rc0": 1, "roi": [1, 65], "crop": [1, 61, 78, 116], "flip": [1, 2, 36, 38, 60, 61, 62, 69, 93, 102, 103, 108, 109, 116, 123], "ax": [1, 9, 15, 17, 21, 25, 28, 38, 42, 54, 65, 68, 86, 90, 93, 94, 95, 102, 103, 108, 109, 111, 115, 116, 122, 126], "947": 1, "parser": [1, 9, 28, 65, 77, 94, 125], "siemen": [1, 9, 10, 32, 34, 35, 40, 102], "ascconv": [1, 65], "896": 1, "brendan": [1, 10, 28, 56], "molonei": [1, 10, 28, 56], "confus": [1, 2, 7, 34, 35, 38, 43, 60, 76, 92, 118], "mention": 1, "img": [1, 7, 8, 9, 12, 14, 15, 27, 30, 41, 54, 55, 60, 61, 62, 64, 65, 66, 69, 77, 78, 80, 84, 87, 89, 92, 93, 94, 95, 97, 98, 99, 100, 102, 103, 104, 111, 116, 118], "start": [1, 2, 4, 9, 15, 25, 26, 28, 33, 35, 37, 40, 43, 47, 48, 59, 68, 70, 77, 84, 88, 90, 92, 94, 102, 103, 109, 119, 123, 124], "guid": [1, 12, 15, 23, 25, 43, 49, 105], "946": 1, "to_byt": [1, 65, 87, 94], "from_byt": [1, 65, 87], "938": 1, "dicom": [1, 2, 9, 12, 28, 31, 56, 57, 66, 83, 102, 103, 109, 112, 126], "910": 1, "canva": 1, "titl": [1, 6, 16, 35, 43, 73, 114, 122], "orthoslicer3d": [1, 65, 116], "958": 1, "record": [1, 2, 6, 9, 19, 27, 35, 41, 77, 78, 81, 82, 101, 109, 117], "second": [1, 2, 9, 11, 12, 29, 30, 38, 51, 54, 55, 60, 74, 77, 87, 101, 102, 105, 106, 108, 113, 123], "parrec2nii": [1, 65, 109], "previous": [1, 10, 109], "tr": [1, 77, 92], "retain": [1, 14, 58], "msec": 1, "931": 1, "reflect": [1, 6, 12, 20, 38, 111], "disk": [1, 3, 7, 8, 9, 12, 14, 18, 20, 27, 29, 30, 35, 36, 41, 55, 60, 61, 64, 69, 74, 80, 87, 90, 92, 99, 100, 103, 104, 109, 116, 117, 118, 123], "dimens": [1, 2, 3, 8, 11, 12, 13, 15, 30, 36, 38, 40, 65, 68, 69, 74, 77, 90, 92, 93, 102, 103, 104, 108, 109, 111, 115, 116, 119, 122, 123], "view": [1, 2, 6, 12, 26, 60, 63, 69, 109, 117, 118, 119, 122], "930": 1, "outdat": 1, "sympi": [1, 86], "deriv": [1, 26, 30, 36, 40, 58, 69, 77, 86, 87, 89, 102, 116], "911": 1, "escap": 1, "raw": [1, 14, 18, 35, 36, 41, 69, 84, 103], "909": 1, "doc": [1, 3, 6, 7, 22, 26, 38, 58, 74, 79, 81, 102, 105], "955": 1, "carl": [1, 56], "gauthier": [1, 56], "purg": 1, "nose": [1, 78], "934": 1, "mark\u00e9ta": [1, 56], "cal\u00e1bkov\u00e1": [1, 56], "949": 1, "dorota": [1, 56], "jarecka": [1, 56], "916": 1, "917": 1, "918": 1, "919": 1, "svg": [1, 26], "appear": [1, 6, 9, 12, 18, 23, 31, 35, 40, 51, 56, 58, 60, 62, 68, 74, 76, 77, 84, 86, 87, 89, 96, 102, 103, 109, 121, 123], "zoom": [1, 2, 68, 69, 84, 92, 99, 100, 103, 104, 116, 123], "914": 1, "922": 1, "alia": [1, 42, 43, 69, 74, 77, 78, 84, 87, 92, 94, 99, 100, 103, 104, 109, 116, 117, 118, 123], "auto_attr": [1, 65], "948": 1, "These": [1, 2, 3, 9, 10, 12, 19, 20, 31, 35, 38, 40, 44, 48, 64, 69, 72, 77, 88, 105, 106, 110], "small": [1, 2, 3, 6, 10, 20, 25, 27, 35, 62, 86, 102], "arm64": 1, "architectur": [1, 11], "indexed_gzip": 1, "indexedgzipfil": 1, "925": 1, "correctli": [1, 3, 9, 10, 12, 26, 43, 76, 100, 103], "array_to_fil": [1, 65, 73], "862": 1, "conform": [1, 3, 9, 35, 39, 65, 70, 94], "shape": [1, 2, 9, 10, 11, 12, 15, 23, 30, 41, 55, 60, 61, 62, 64, 65, 68, 69, 70, 74, 76, 77, 78, 80, 84, 86, 90, 92, 93, 94, 95, 99, 100, 102, 103, 104, 108, 109, 110, 111, 113, 115, 116, 117, 118, 119, 123], "853": 1, "jakub": [1, 56], "kaczmarzyk": [1, 56], "rescal": [1, 69, 70, 71, 99, 109, 116, 118], "rescale_affin": [1, 65], "delai": [1, 26, 109], "h5py": [1, 12, 57], "until": [1, 8, 26, 35, 55, 80, 82, 90, 103], "889": 1, "893": 1, "865": 1, "mani": [1, 2, 3, 10, 12, 13, 19, 20, 22, 23, 28, 30, 35, 37, 49, 74, 77, 84, 87, 91, 94, 103, 108], "sub": [1, 3, 10, 15, 74, 77, 84, 102, 106], "krzyzstof": 1, "gorgolewski": [1, 56], "roberto": [1, 7, 56], "guidotti": [1, 56], "Or": [1, 7, 8, 10, 20, 22, 42, 43, 56, 61, 107, 123], "duek": [1, 56], "kw_only_meth": 1, "kw_only_func": 1, "decor": [1, 4, 82, 105, 112], "848": 1, "extend": [1, 6, 9, 28, 37, 49, 57, 65, 71, 80, 103, 105, 118, 119], "incompat": [1, 13, 78], "last": [1, 2, 3, 7, 8, 9, 12, 26, 31, 35, 36, 38, 39, 40, 43, 54, 61, 62, 64, 68, 69, 71, 76, 77, 84, 86, 93, 102, 103, 106, 107, 109, 113, 119, 121, 123, 124], "respect": [1, 2, 6, 9, 15, 22, 26, 35, 38, 57, 58, 62, 68, 74, 77, 78, 84, 86, 93, 94, 102, 109, 119], "If": [1, 2, 3, 6, 7, 8, 9, 12, 14, 15, 16, 20, 22, 23, 26, 27, 29, 30, 31, 35, 37, 38, 39, 40, 43, 45, 51, 52, 55, 56, 57, 60, 61, 62, 66, 68, 69, 70, 71, 72, 74, 76, 77, 78, 79, 80, 84, 86, 87, 89, 90, 92, 93, 94, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 111, 113, 114, 115, 116, 117, 118, 119, 122, 123, 124], "you": [1, 2, 3, 4, 6, 8, 9, 10, 13, 14, 20, 22, 26, 27, 30, 33, 34, 35, 37, 38, 41, 42, 44, 45, 46, 48, 49, 51, 52, 53, 54, 55, 56, 57, 61, 62, 63, 64, 69, 70, 71, 74, 76, 77, 80, 81, 84, 86, 87, 100, 102, 103, 104, 105, 106, 108, 109, 114, 115, 116, 117, 118, 119, 120, 123, 124], "abl": [1, 2, 3, 7, 8, 9, 10, 11, 12, 15, 19, 20, 22, 27, 35, 42, 51, 71, 76, 111], "recommend": [1, 3, 6, 9, 14, 56, 61, 66, 77], "827": 1, "821": 1, "maximum": [1, 2, 36, 76, 87, 90, 102, 113, 117, 119, 123], "901": 1, "894": 1, "backport": [1, 22], "matplotlib": [1, 2, 36, 60, 116], "wheel": 1, "887": [1, 2], "859": 1, "tupl": [1, 11, 15, 69, 70, 72, 74, 77, 80, 84, 87, 88, 89, 90, 92, 94, 99, 100, 102, 103, 106, 107, 108, 109, 110, 116, 118, 119, 122, 123], "860": 1, "darwin": [1, 26, 56], "valid": [1, 9, 10, 19, 22, 35, 40, 59, 62, 69, 72, 74, 77, 79, 87, 92, 102, 103, 108, 113, 116, 117, 118, 123], "promot": [1, 58, 123], "857": 1, "accommod": 1, "float16": 1, "866": [1, 2], "858": 1, "__array__": 1, "dataobj": [1, 3, 7, 13, 14, 15, 55, 61, 62, 65, 69, 74, 77, 80, 84, 92, 98, 99, 100, 103, 104, 109, 111, 116, 117, 118], "well": [1, 3, 4, 6, 8, 9, 12, 14, 15, 16, 20, 22, 34, 41, 42, 43, 48, 68, 85, 90, 103], "directli": [1, 2, 4, 8, 9, 10, 12, 23, 27, 35, 36, 38, 39, 42, 43, 51, 55, 61, 62, 68, 69, 76, 81, 92, 94, 102, 103, 117, 118, 123], "exampl": [1, 3, 4, 6, 7, 9, 10, 11, 12, 14, 15, 16, 18, 19, 20, 26, 27, 29, 30, 34, 35, 36, 37, 41, 42, 43, 51, 52, 54, 55, 56, 58, 59, 61, 64, 65, 68, 69, 70, 71, 72, 74, 76, 79, 80, 81, 82, 84, 85, 86, 87, 89, 90, 92, 93, 94, 97, 100, 102, 103, 104, 105, 107, 108, 109, 110, 111, 113, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 126], "float32": [1, 30, 62, 71, 76, 99, 100, 103, 116, 119, 123], "scale": [1, 2, 30, 32, 38, 40, 59, 61, 65, 68, 69, 70, 71, 74, 80, 84, 87, 92, 98, 99, 100, 102, 103, 109, 116, 117, 118, 123], "factor": [1, 4, 62, 69, 70, 74, 109], "slope": [1, 14, 62, 65, 69, 70, 71, 103, 109, 117, 118, 123], "intercept": [1, 14, 21, 25, 62, 69, 70, 71, 103, 109, 116, 117, 118, 123], "narrow": 1, "memori": [1, 3, 8, 9, 11, 12, 14, 15, 26, 27, 29, 30, 35, 41, 59, 60, 61, 69, 70, 71, 74, 80, 84, 90, 92, 94, 99, 100, 109, 118, 119, 123], "basi": [1, 8, 15, 27, 38, 40, 62, 69, 76, 103, 104, 123], "get_fdata": [1, 2, 15, 27, 41, 59, 60, 61, 62, 65, 66, 74, 80, 84, 87, 100, 115, 116], "singl": [1, 2, 6, 9, 10, 12, 13, 15, 16, 18, 33, 35, 38, 40, 54, 61, 62, 69, 70, 72, 74, 75, 77, 80, 84, 87, 90, 92, 93, 94, 99, 100, 102, 103, 104, 109, 115, 118, 119, 122], "precis": [1, 2, 6, 9, 54, 61, 62, 71, 76, 86, 94, 113, 116, 123], "844": 1, "alejandro": 1, "vega": 1, "agg_data": [1, 15, 65, 94], "usabl": [1, 22], "793": 1, "o": [1, 11, 41, 47, 54, 55, 56, 61, 62, 64, 74, 79, 80, 84, 87, 89, 92, 98, 107, 120], "pathlik": [1, 15, 87, 89, 92, 98], "place": [1, 2, 6, 7, 9, 11, 14, 20, 23, 35, 40, 68, 76, 87, 92, 94, 116, 119, 123], "filenam": [1, 2, 7, 10, 20, 27, 30, 40, 41, 61, 64, 69, 70, 74, 77, 80, 84, 87, 88, 89, 92, 93, 94, 98, 99, 100, 102, 103, 104, 106, 109, 116, 117, 118, 119, 123], "610": 1, "cameron": [1, 56], "riddel": [1, 56], "obliqu": [1, 65], "815": 1, "847": 1, "slicer": [1, 8, 9, 15, 34, 61, 65, 78, 90, 116, 122], "846": 1, "float64": [1, 14, 18, 61, 64, 69, 76, 78, 80, 113, 123], "would": [1, 2, 4, 7, 8, 9, 10, 11, 12, 13, 14, 16, 20, 23, 27, 29, 30, 35, 37, 43, 60, 64, 69, 78, 80, 81, 87, 90, 94, 102, 103, 105, 107, 108, 109, 116, 119, 123, 124], "otherwis": [1, 8, 9, 11, 13, 27, 40, 58, 69, 71, 72, 74, 77, 79, 82, 85, 87, 88, 89, 90, 92, 93, 102, 103, 106, 107, 109, 111, 113, 118, 119, 123, 124], "unnecessarili": 1, "833": 1, "oper": [1, 12, 15, 30, 35, 38, 57, 77, 102, 110, 113, 119], "combin": [1, 2, 9, 15, 20, 31, 35, 43, 62, 68, 69, 74, 77, 80, 84, 86, 87, 90, 92, 99, 100, 103, 104, 109, 116, 117, 118, 123], "811": 1, "philipp": [1, 56], "poulin": 1, "rather": [1, 2, 4, 7, 8, 9, 12, 20, 22, 30, 35, 36, 38, 40, 51, 53, 61, 64, 76, 86, 90, 99, 100, 102], "than": [1, 2, 3, 6, 8, 9, 13, 20, 30, 31, 35, 38, 39, 40, 51, 52, 53, 61, 62, 68, 69, 70, 76, 77, 78, 82, 86, 87, 90, 91, 99, 100, 102, 103, 104, 109, 110, 111, 114, 119, 123], "unread": 1, "csa": [1, 10, 32, 36, 40, 102], "tag": [1, 9, 19, 22, 26, 32, 33, 77, 94, 102, 109, 126], "818": 1, "henri": [1, 56], "braun": [1, 56], "clariti": [1, 7], "tutori": [1, 19, 23, 50, 56], "823": 1, "egor": [1, 56], "panfilov": [1, 56], "slice": [1, 2, 12, 13, 18, 28, 30, 32, 33, 40, 55, 59, 60, 64, 69, 70, 73, 77, 87, 90, 93, 99, 100, 102, 103, 109, 115, 116, 119, 122, 123], "tractogram": [1, 65, 78], "apply_affin": [1, 2, 60, 65, 119], "origin": [1, 2, 6, 7, 15, 19, 20, 26, 27, 33, 36, 38, 40, 42, 43, 52, 53, 58, 60, 62, 65, 68, 69, 70, 72, 74, 80, 87, 90, 94, 102, 103, 106, 109, 115, 116, 117, 118, 119, 122, 123, 124], "replic": [1, 14, 22, 111], "manifest": 1, "845": 1, "787": 1, "slightli": [1, 2, 102, 104], "custom": [1, 69, 106, 109], "786": 1, "commun": [1, 6, 19, 25, 35, 37, 49], "778": 1, "checkwarn": 1, "minc": [1, 2, 3, 8, 9, 12, 61, 81, 99, 100, 116], "852": 1, "valu": [1, 2, 4, 6, 9, 10, 11, 12, 14, 15, 18, 19, 22, 23, 29, 30, 31, 36, 37, 38, 39, 40, 41, 55, 60, 61, 62, 65, 66, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, 84, 87, 89, 90, 92, 94, 97, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 111, 113, 114, 115, 116, 117, 118, 119, 123, 124, 126], "onli": [1, 2, 4, 7, 9, 10, 11, 12, 15, 16, 18, 20, 22, 25, 30, 31, 35, 36, 38, 39, 40, 41, 43, 45, 51, 53, 55, 60, 61, 62, 64, 68, 69, 70, 71, 72, 74, 76, 77, 79, 80, 84, 87, 90, 92, 93, 94, 95, 99, 100, 102, 103, 105, 106, 109, 116, 118, 119, 120, 123, 124], "794": 1, "809": 1, "ignor": [1, 6, 7, 9, 22, 38, 69, 70, 71, 74, 77, 80, 84, 88, 89, 92, 93, 94, 99, 100, 106, 109, 118, 123], "endian": [1, 18, 30, 39, 40, 61, 62, 65, 69, 77, 78, 84, 92, 94, 102, 103, 104, 109, 117, 118, 119, 123, 124], "diff": [1, 20, 22, 42, 43, 49, 51, 65, 109], "799": 1, "philip": [1, 10, 31, 34, 38, 56, 59, 66, 102, 109], "w": [1, 22, 74, 86, 106, 113], "795": 1, "limit": [1, 4, 6, 56, 58, 66, 94, 122], "1000": [1, 9, 35, 97, 103, 119], "parametr": 1, "relax": 1, "798": 1, "800": 1, "coerc": [1, 69, 103, 123], "intent": [1, 15, 94, 103], "806": 1, "report": [1, 22, 23, 31, 65, 66, 78, 82, 109], "tom": 1, "holroyd": 1, "window": [1, 26, 47, 57, 76, 85, 109], "804": 1, "dicomwrapp": [1, 65], "wrapper": [1, 10, 65, 103, 124, 125], "get_affin": [1, 7, 15, 65, 74, 92, 99, 109], "properti": [1, 2, 7, 11, 12, 15, 20, 55, 58, 61, 64, 69, 70, 71, 72, 74, 77, 80, 84, 87, 88, 92, 94, 99, 100, 102, 103, 104, 105, 106, 109, 110, 116, 117, 118, 119, 122, 124], "796": 1, "either": [1, 3, 9, 35, 39, 51, 57, 61, 74, 77, 80, 85, 102, 103, 112, 115], "through": [1, 2, 9, 11, 12, 19, 22, 23, 26, 35, 37, 62, 76, 77, 90, 109, 119], "thank": [1, 7, 11, 19, 23, 42, 52], "crabb": 1, "644": 1, "describ": [1, 2, 3, 6, 9, 12, 15, 16, 23, 26, 28, 34, 35, 36, 38, 48, 55, 62, 68, 70, 72, 77, 86, 94, 103, 104, 109, 110], "774": 1, "stricter": 1, "rule": [1, 8, 10, 12, 23, 26, 31, 35, 49, 71, 86, 90, 123], "768": 1, "trk": [1, 11, 65, 78], "written": [1, 2, 9, 12, 16, 23, 29, 31, 34, 35, 37, 40, 43, 58, 62, 69, 71, 74, 87, 92, 94, 99, 100, 103, 104, 106, 109, 116, 117, 118, 122], "big": [1, 23, 26, 84, 92], "782": 1, "multifram": [1, 10], "appveyor": 1, "accur": 1, "769": 1, "764": 1, "teardown": 1, "785": 1, "effect": [1, 4, 7, 19, 20, 40, 55, 62, 69, 70, 74, 80, 84, 92, 94, 99, 100, 103, 108, 116, 118], "threaten": 1, "some": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 18, 21, 22, 27, 29, 30, 33, 34, 35, 36, 38, 40, 41, 42, 45, 46, 49, 51, 52, 56, 58, 60, 61, 62, 64, 66, 69, 74, 76, 77, 80, 84, 87, 90, 92, 93, 96, 99, 100, 102, 103, 104, 108, 109, 110, 116, 117, 118, 119, 120, 121, 123, 124], "timelin": 1, "755": 1, "v2": [1, 47, 61, 62, 86], "schedul": [1, 26], "contribut": [1, 19, 23, 26, 56, 57], "pafilov": 1, "jath": [1, 56], "palasubramaniam": [1, 56], "richard": 1, "nemec": 1, "dave": 1, "allur": 1, "mmap": [1, 69, 70, 74, 77, 80, 84, 90, 92, 94, 99, 100, 109, 118, 123], "ani": [1, 2, 4, 6, 7, 9, 10, 12, 14, 15, 16, 19, 20, 22, 23, 26, 27, 30, 35, 40, 41, 42, 43, 44, 51, 52, 56, 57, 58, 60, 61, 66, 68, 69, 70, 71, 72, 74, 75, 76, 77, 79, 80, 84, 86, 87, 89, 90, 91, 92, 94, 96, 102, 103, 105, 106, 108, 109, 110, 111, 116, 119, 121, 122, 123, 124], "759": 1, "writabl": [1, 87], "750": [1, 109], "safer": [1, 62], "registri": [1, 20], "manipul": [1, 61, 77], "overflow": [1, 14, 76, 123], "753": 1, "duplic": [1, 15, 20, 26], "label": [1, 2, 9, 15, 20, 22, 26, 31, 35, 38, 42, 52, 62, 66, 74, 77, 92, 94, 103, 108, 109, 123, 124], "763": 1, "751": 1, "replac": [1, 6, 10, 20, 22, 30, 40, 42, 72, 90, 104, 120], "754": 1, "sphinx": [1, 6, 57, 59], "config": [1, 22, 42, 49, 52, 79], "recent": [1, 9, 39, 47, 64, 69, 71, 76, 103, 107, 121, 123, 124], "numpydoc": [1, 22], "749": 1, "pacifi": 1, "futurewarn": [1, 81], "760": 1, "collect": [1, 2, 6, 12, 15, 19, 20, 31, 35, 36, 40, 41, 43, 69, 77, 84, 94, 102, 103, 106, 110], "mutablemap": [1, 75, 77, 119], "762": 1, "761": 1, "altern": [1, 6, 8, 10, 13, 22, 77, 90, 103, 122], "axi": [1, 2, 15, 38, 42, 54, 60, 61, 65, 68, 69, 74, 86, 90, 93, 102, 103, 108, 109, 113, 115, 116, 119, 122], "base": [1, 9, 10, 11, 12, 19, 23, 28, 30, 38, 40, 43, 58, 62, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 87, 88, 89, 90, 92, 94, 96, 99, 100, 101, 102, 103, 104, 105, 106, 108, 109, 110, 113, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125], "641": 1, "produc": [1, 10, 11, 20, 61, 70, 94, 102, 106, 109], "other": [1, 4, 6, 7, 8, 9, 10, 11, 12, 13, 16, 19, 20, 22, 23, 26, 30, 31, 34, 35, 37, 40, 41, 46, 49, 51, 54, 57, 58, 61, 62, 69, 70, 71, 76, 77, 78, 84, 87, 88, 89, 90, 95, 102, 103, 105, 106, 109, 116, 117, 118, 119, 121, 122, 123, 124, 126], "delimit": [1, 35, 40, 102], "eof": 1, "720": 1, "soichi": [1, 56], "hayashi": [1, 56], "brainmodel": [1, 77], "parcel": [1, 15, 65, 77], "vertex": [1, 15, 77, 92, 94], "739": 1, "nifti_xform_template_oth": 1, "xform": [1, 62, 68, 94], "743": 1, "skip": [1, 4, 20, 77, 90, 107, 112], "refcheck": 1, "construct": [1, 19, 62, 75, 77, 87, 89, 102, 111, 113, 119], "719": 1, "724": 1, "726": 1, "jon": [1, 56], "haitz": [1, 56], "legarreta": [1, 56], "gorro\u00f1o": [1, 56], "sort": [1, 11, 26, 38, 61, 65, 76, 79, 87, 102, 116], "728": 1, "samir": [1, 56], "reddigari": [1, 56], "reorient": [1, 111], "dim_info": [1, 12, 61, 62, 103, 104], "konstantino": [1, 56], "raktivan": [1, 56], "upstream": [1, 26, 42, 43, 49, 51, 52], "711": 1, "705": 1, "738": 1, "speed": [1, 3, 30, 90], "699": 1, "increas": [1, 17, 19, 28, 35, 38, 60, 66, 76, 77, 103, 104, 123], "coveral": 1, "722": 1, "732": 1, "zenodo": [1, 26, 56, 66], "author": [1, 2, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 26, 27, 58, 92], "copyright": [1, 26, 30, 56, 57, 59], "742": 1, "restor": [1, 20, 26], "six": 1, "714": 1, "gael": 1, "varoquaux": [1, 56], "toggl": 1, "crosshair": 1, "ctrl": 1, "701": 1, "miguel": [1, 56], "estevan": [1, 56], "moreno": [1, 56], "par": [1, 3, 12, 56, 59, 65, 66, 78], "correspond": [1, 2, 7, 9, 10, 15, 18, 22, 27, 35, 40, 41, 55, 62, 68, 74, 77, 86, 87, 89, 90, 92, 94, 102, 103, 108, 109, 110, 111, 113, 116, 119, 122, 123, 124], "adc": 1, "map": [1, 9, 10, 15, 18, 30, 32, 33, 35, 36, 60, 61, 62, 68, 69, 70, 74, 75, 77, 80, 84, 87, 88, 89, 92, 94, 99, 100, 102, 103, 104, 108, 109, 111, 115, 116, 117, 118, 119, 123, 124, 126], "685": 1, "gregori": [1, 56], "r": [1, 2, 12, 26, 29, 36, 38, 40, 43, 54, 56, 60, 61, 62, 64, 69, 70, 74, 77, 80, 84, 86, 90, 92, 94, 99, 100, 102, 106, 108, 109, 114, 118, 123], "lee": [1, 56], "item": [1, 28, 35, 62, 65, 117, 119, 123, 124], "igor": [1, 56], "solovei": [1, 56], "issubdtyp": 1, "bool_": 1, "707": 1, "help": [1, 4, 7, 9, 14, 19, 22, 23, 25, 30, 43, 45, 47, 49, 57, 64, 79, 81, 87, 116], "682": 1, "roo": [1, 56], "asscalar": 1, "686": 1, "qa": 1, "direct": [1, 2, 6, 9, 12, 15, 38, 40, 58, 60, 86, 92, 102, 103, 108], "flake8": [1, 22], "695": 1, "doi": [1, 26, 56, 66, 86], "org": [1, 4, 6, 7, 8, 9, 20, 26, 31, 34, 56, 58, 76, 77, 79, 81, 86, 94, 102, 104, 105, 113, 119], "703": 1, "katrin": [1, 56], "leinweb": [1, 56], "fromstr": 1, "700": 1, "bz2file": [1, 106], "mutabl": 1, "byte": [1, 9, 18, 20, 30, 35, 39, 40, 60, 62, 70, 73, 76, 84, 87, 90, 91, 92, 94, 102, 103, 106, 119, 123, 124, 125], "hack": [1, 43, 52, 103, 104], "disabl": [1, 43], "bytearrai": 1, "readinto": [1, 65, 106], "strategi": [1, 26], "alloc": [1, 68, 119], "buffer": [1, 12, 77, 90, 94, 102, 106, 119, 125], "compar": [1, 2, 7, 31, 51, 60, 78, 82, 86, 100, 102, 107, 123], "617": 1, "672": 1, "678": 1, "pradeep": 1, "raamana": 1, "numer": [1, 86, 94, 102, 103, 106, 113, 123], "655": 1, "ndim": [1, 65, 69, 70, 80, 84, 90, 99, 103, 104, 108, 109, 110], "674": 1, "deduct": 1, "degener": 1, "647": 1, "0m": 1, "mgh": [1, 12, 15, 56, 66, 70, 92], "653": 1, "ppc64": 1, "littl": [1, 2, 7, 8, 18, 19, 20, 30, 39, 40, 43, 49, 61, 78, 84, 86, 94, 103, 109], "long": [1, 2, 4, 6, 14, 19, 23, 25, 26, 30, 35, 57, 68, 76, 87, 104, 109, 119], "doubl": [1, 30, 35, 76], "658": 1, "correct": [1, 9, 12, 13, 23, 36, 76, 79, 84, 93, 103, 115, 119, 123], "666": 1, "d": [1, 2, 8, 9, 20, 26, 35, 37, 38, 40, 42, 43, 56, 57, 61, 79, 81, 102, 103, 108, 111, 123, 124], "persist": [1, 35, 103], "index": [1, 2, 6, 9, 10, 12, 15, 18, 26, 30, 31, 38, 40, 56, 59, 70, 74, 77, 84, 90, 94, 102, 103, 109, 115, 116, 119, 122, 123], "679": 1, "semant": [1, 9, 35], "646": 1, "minor": [1, 9, 23, 79], "associ": [1, 2, 3, 7, 10, 13, 14, 15, 18, 30, 35, 58, 61, 64, 69, 74, 75, 77, 80, 84, 87, 92, 94, 98, 99, 100, 103, 104, 108, 109, 116, 117, 118, 119], "651": 1, "606": 1, "550": 1, "simplfii": 1, "mghimag": [1, 15, 65], "footer": [1, 92], "569": 1, "forc": [1, 14, 26, 51, 71, 87, 90, 102, 105], "sform": [1, 59, 103], "575": 1, "fill": [1, 3, 14, 26, 38, 55, 69, 80, 84, 90, 103, 111, 114, 123], "tabl": [1, 15, 20, 35, 77, 78, 92, 94, 109, 114], "592": 1, "604": 1, "tim": 1, "coalson": 1, "empti": [1, 9, 40, 55, 68, 69, 72, 77, 80, 84, 90, 92, 94, 102, 103, 104, 106, 109, 117, 118, 119, 123, 124], "611": 1, "nii": [1, 2, 7, 8, 10, 11, 12, 14, 15, 27, 30, 37, 41, 54, 55, 58, 60, 61, 62, 64, 66, 77, 80, 97, 103], "621": 1, "orfano": [1, 56], "take": [1, 2, 4, 7, 8, 9, 10, 12, 19, 20, 23, 26, 28, 30, 36, 38, 40, 43, 52, 60, 62, 64, 69, 76, 87, 90, 102, 103, 108, 109, 116, 123], "advantag": [1, 2], "drop_handl": 1, "flag": [1, 26, 27, 31, 35, 40, 43, 52, 69, 78, 80, 90, 103, 109, 123, 124], "614": [1, 94], "preserv": [1, 7, 9, 10, 12, 15, 28, 62, 68, 102], "first": [1, 2, 3, 6, 8, 9, 11, 12, 13, 19, 20, 30, 31, 35, 36, 38, 39, 43, 51, 53, 54, 55, 60, 61, 62, 64, 68, 69, 74, 76, 77, 84, 85, 86, 87, 89, 90, 102, 103, 105, 106, 108, 109, 113, 116, 119, 123], "point": [1, 6, 7, 8, 9, 11, 12, 15, 17, 19, 22, 25, 27, 29, 30, 33, 34, 35, 36, 38, 39, 40, 43, 52, 53, 60, 61, 62, 68, 71, 76, 77, 78, 80, 87, 90, 94, 102, 103, 104, 109, 110, 111, 114, 116, 119, 123, 126], "lazytractogram": [1, 65], "588": 1, "nil": 1, "goyett": 1, "stop": [1, 38, 43, 77, 90], "ad": [1, 2, 3, 6, 9, 10, 19, 22, 23, 25, 26, 42, 43, 52, 62, 77, 79, 80, 89, 90, 92, 109, 111, 119], "extran": 1, "pad": [1, 103, 119], "593": 1, "stutter": [1, 56], "lower": [1, 2, 60, 64, 82, 123], "600": [1, 9], "kesshi": [1, 56], "jordan": [1, 56], "597": 1, "eleftherio": [1, 56], "garyfallidi": [1, 56], "unboundlocalerror": 1, "607": 1, "do": [1, 2, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 19, 20, 22, 26, 27, 31, 35, 38, 40, 42, 44, 45, 46, 49, 51, 52, 54, 55, 57, 58, 61, 62, 64, 69, 70, 71, 74, 76, 79, 80, 81, 84, 86, 87, 89, 90, 91, 92, 94, 99, 100, 102, 105, 107, 109, 115, 116, 117, 118, 119, 120, 121, 122, 123], "crash": [1, 40, 49], "importerror": [1, 107], "618": 1, "638": 1, "ssh": [1, 43, 45], "kei": [1, 6, 9, 10, 11, 16, 20, 23, 45, 61, 65, 69, 74, 75, 77, 78, 79, 87, 89, 92, 94, 102, 109, 114, 116, 117, 119, 122, 123, 124], "auth": 1, "587": 1, "doctest": [1, 26, 66, 78, 93], "print": [1, 2, 4, 10, 26, 40, 61, 62, 66, 73, 74, 77, 78, 86, 94, 96, 100, 102, 103, 105, 114, 123, 124], "591": 1, "599": 1, "unreach": 1, "602": 1, "l": [1, 40, 54, 61, 65, 68, 69, 76, 108, 109], "program": [1, 3, 7, 27, 31, 34, 74, 78, 92], "601": 1, "615": 1, "encourag": [1, 6, 19], "637": 1, "accordingli": [1, 6, 90, 93], "keep_file_open_default": [1, 69, 70, 74, 80, 84, 92, 99, 100, 118], "same": [1, 2, 3, 7, 8, 9, 10, 11, 12, 14, 15, 16, 20, 27, 28, 29, 30, 31, 35, 36, 38, 39, 40, 43, 49, 55, 61, 62, 68, 69, 70, 71, 74, 76, 77, 78, 80, 84, 86, 87, 88, 90, 92, 93, 94, 99, 100, 102, 108, 109, 111, 113, 115, 116, 118, 119, 120, 123, 124], "orthoview": [1, 65, 116], "564": 1, "defer": [1, 6, 16], "ufunc": [1, 42], "memmap": [1, 69, 70, 74, 80, 84, 92, 94, 99, 100, 109, 118, 123], "freez": [1, 70, 84, 99], "572": 1, "582": 1, "576": 1, "580": 1, "bennet": [1, 56], "fauber": [1, 56], "maco": [1, 26], "newer": 1, "583": 1, "script": [1, 4, 26, 34], "conda": 1, "584": 1, "249": 1, "mrtrix": [1, 11, 119], "486": 1, "arnaud": 1, "bore": [1, 2], "j": [1, 2, 6, 9, 12, 30, 32, 36, 56, 60, 86, 102, 113, 119], "donald": 1, "tournier": 1, "jean": [1, 56], "christoph": [1, 56], "houd": 1, "retriev": [1, 6, 15, 84, 87, 94, 110, 116], "551": 1, "name": [1, 6, 7, 10, 11, 12, 15, 16, 18, 23, 26, 27, 30, 31, 35, 37, 38, 39, 40, 43, 45, 51, 52, 53, 58, 61, 65, 69, 75, 77, 78, 79, 80, 81, 86, 87, 88, 89, 92, 94, 95, 102, 103, 105, 106, 107, 109, 110, 114, 119, 120, 123, 124, 125, 126], "507": 1, "512": [1, 84], "concaten": [1, 12, 13, 65, 77, 93, 94, 109], "495": 1, "multipl": [1, 2, 6, 9, 10, 12, 15, 17, 19, 22, 25, 77, 84, 86, 94, 109, 113, 114, 119, 123, 126], "494": 1, "500": 1, "502": 1, "specifi": [1, 2, 7, 8, 9, 10, 11, 12, 13, 14, 22, 35, 38, 60, 62, 68, 69, 70, 71, 74, 76, 77, 78, 79, 80, 82, 84, 86, 90, 92, 93, 94, 99, 100, 102, 103, 104, 106, 107, 109, 111, 113, 115, 116, 119, 123, 124], "input": [1, 2, 6, 9, 10, 11, 19, 60, 68, 70, 71, 77, 82, 86, 87, 90, 93, 94, 102, 108, 111, 113, 115, 116, 123], "485": 1, "headerless": 1, "effici": [1, 14, 19, 28, 55, 71, 90, 110], "521": 1, "unknown": [1, 9, 35, 38, 41, 61, 62, 94, 103, 119, 124], "fsl": [1, 7, 9, 27, 28], "528": 1, "__getitem__": [1, 8, 15, 102, 123, 124], "533": 1, "deleg": 1, "544": [1, 104], "mark": [1, 6, 9, 56, 62, 82], "hymer": [1, 56], "552": 1, "reader": [1, 9, 60, 102], "493": 1, "vincent": [1, 56], "corner": [1, 2, 19, 38, 113, 119], "516": 1, "517": 1, "536": 1, "venki": [1, 56], "reddi": [1, 56], "514": 1, "ivan": [1, 56], "gonzalez": [1, 56], "509": 1, "503": 1, "renam": [1, 10, 52, 105], "spec": [1, 9, 15, 20, 62, 70, 77, 94, 102, 103], "entri": [1, 62, 75, 77, 79, 84, 87, 90, 102, 111, 114, 115, 119, 123], "evalu": [1, 19, 105], "instead": [1, 2, 9, 11, 14, 19, 37, 38, 51, 52, 59, 69, 74, 76, 77, 87, 92, 94, 98, 102, 103, 107, 108, 109, 118, 119, 123], "differ": [1, 2, 4, 6, 7, 9, 10, 11, 12, 18, 19, 22, 26, 29, 31, 35, 36, 38, 39, 40, 48, 60, 61, 62, 68, 72, 76, 78, 87, 90, 102, 103, 108, 109, 111, 116, 119], "eventu": [1, 6, 36], "current": [1, 7, 9, 10, 11, 13, 20, 22, 23, 26, 27, 28, 36, 40, 42, 43, 51, 53, 56, 57, 64, 66, 80, 82, 84, 87, 91, 92, 94, 102, 103, 106, 116, 119, 122, 123, 124], "391": 1, "bago": [1, 56], "amirbekian": [1, 56], "samuel": [1, 56], "st": [1, 35, 42, 56], "prototyp": [1, 6], "404": 1, "proto": 1, "ivanov": [1, 122], "smooth": [1, 12, 23, 111], "ndimag": [1, 111, 115], "255": [1, 71, 92, 111], "abil": [1, 3, 19, 27, 43], "morphologi": 1, "414": 1, "296": 1, "kastman": [1, 56], "geometri": [1, 15, 56, 66, 92], "460": 1, "gramfort": [1, 56], "jaakko": [1, 56], "lepp\u00e4kanga": [1, 56], "rec": [1, 3, 12, 56, 59, 66, 78, 109, 123], "429": 1, "427": 1, "diffus": [1, 9, 34, 102, 109], "426": 1, "sophist": [1, 43, 69, 103], "409": 1, "fewer": [1, 62, 90, 103, 109, 111], "strict": [1, 9, 58, 94, 109], "matrix": [1, 15, 30, 36, 38, 41, 61, 68, 69, 74, 77, 84, 86, 92, 94, 99, 100, 102, 103, 104, 108, 109, 113, 116, 117, 118, 119, 126], "413": 1, "assumpt": [1, 62], "posit": [1, 2, 22, 33, 35, 36, 38, 39, 40, 60, 65, 66, 70, 72, 76, 77, 86, 87, 88, 90, 91, 92, 94, 102, 103, 106, 108, 113, 115, 116, 118, 119, 122, 123, 124], "439": 1, "m": [1, 2, 7, 9, 12, 22, 26, 31, 32, 34, 35, 37, 38, 39, 43, 52, 56, 68, 77, 84, 86, 92, 102, 103, 108, 111, 113, 117], "baker": [1, 56], "robust": [1, 34, 113], "393": 1, "try": [1, 3, 4, 6, 8, 9, 10, 13, 16, 20, 26, 34, 35, 38, 53, 57, 60, 62, 64, 69, 70, 72, 74, 79, 80, 84, 87, 90, 92, 94, 99, 100, 102, 109, 116, 117, 118, 121, 123], "exist": [1, 7, 9, 11, 16, 23, 26, 38, 40, 62, 77, 78, 79, 84, 85, 87, 103, 104, 107, 110, 116, 120, 123], "455": 1, "show": [1, 2, 41, 43, 51, 53, 60, 65, 68, 78, 81, 109, 116, 122, 123], "statist": [1, 18, 78, 97], "437": 1, "348": [1, 61, 62, 69], "yarik": 1, "rotat": [1, 2, 36, 68, 86, 102, 103, 109, 113, 116], "matric": [1, 2, 40, 113], "comprehens": [1, 16, 48, 56], "surfac": [1, 18, 30, 35, 65, 77, 87, 92, 94, 103], "352": [1, 62, 103], "355": 1, "360": 1, "365": 1, "403": 1, "328": 1, "329": 1, "446": 1, "shebang": 1, "virtualenv": [1, 26, 57], "pip": [1, 22, 56, 59, 66], "434": 1, "pil": 1, "pillow": 1, "framework": [1, 9, 26], "345": 1, "end": [1, 2, 12, 20, 22, 26, 30, 34, 35, 36, 38, 40, 41, 43, 51, 68, 77, 85, 86, 87, 89, 92, 93, 94, 103, 108, 120], "478": 1, "jasper": [1, 56], "f": [1, 2, 8, 11, 15, 26, 35, 36, 38, 40, 43, 56, 69, 70, 71, 73, 76, 78, 90, 91, 92, 99, 103, 108, 116, 123], "den": [1, 56], "bosch": [1, 56], "breakag": 1, "dataerror": [1, 65], "too": [1, 4, 10, 19, 27, 82, 90, 123], "few": [1, 9, 23, 26, 43, 109], "headererror": [1, 65], "track": [1, 2, 6, 7, 16, 20, 21, 22, 25, 28, 37, 39, 42, 51, 119], "true": [1, 2, 7, 8, 9, 11, 12, 22, 27, 29, 30, 35, 36, 39, 40, 41, 42, 54, 55, 61, 62, 64, 66, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 84, 86, 87, 88, 89, 90, 92, 93, 94, 95, 99, 100, 102, 103, 104, 105, 106, 107, 109, 110, 111, 112, 113, 116, 117, 118, 119, 120, 121, 123, 124], "typeerror": [1, 72, 87, 116, 123], "align": [1, 2, 12, 15, 28, 54, 62, 74, 103, 111, 115, 118, 126], "scanner": [1, 12, 28, 31, 38, 60, 61, 62, 103, 109, 119, 126], "get_head": [1, 7], "from_filespec": 1, "class_map": 1, "instanc": [1, 14, 33, 35, 43, 61, 69, 70, 71, 72, 74, 77, 79, 80, 83, 84, 87, 88, 92, 93, 94, 96, 99, 100, 102, 103, 104, 105, 106, 107, 109, 111, 116, 117, 118, 119, 122, 123], "attribut": [1, 7, 9, 14, 15, 33, 37, 38, 61, 62, 64, 69, 70, 71, 72, 74, 75, 77, 80, 81, 87, 88, 92, 94, 95, 99, 100, 102, 103, 104, 105, 109, 111, 115, 116, 117, 118, 119, 126], "ext_map": 1, "spatialhead": [1, 65, 69, 74, 84, 92, 99, 109], "binopen": 1, "get_metadata": 1, "get_rgba": 1, "giftidataarrai": [1, 65], "get_labelt": 1, "set_labelt": 1, "get_meta": [1, 10], "set_meta": 1, "data_tag": 1, "num_dim": [1, 65, 94], "from_arrai": 1, "constructor": [1, 3, 7, 10, 77, 93, 106, 119, 123], "to_xml_open": 1, "to_xml_clos": 1, "parse_gifti_fast": [1, 65], "outputt": 1, "giftiimagepars": [1, 65], "parse_gifti_fil": 1, "pars": [1, 37, 65, 74, 77, 84, 87, 94, 102, 109, 125], "which_analyze_typ": 1, "where": [1, 2, 6, 7, 9, 12, 13, 14, 15, 16, 18, 19, 20, 25, 26, 27, 29, 30, 35, 36, 38, 40, 43, 49, 52, 58, 60, 61, 64, 68, 69, 70, 72, 74, 76, 77, 78, 79, 80, 81, 84, 86, 87, 89, 90, 91, 92, 93, 102, 103, 106, 108, 109, 111, 113, 115, 116, 119, 122, 123], "each": [1, 2, 6, 7, 9, 10, 11, 12, 13, 15, 16, 19, 20, 22, 26, 30, 33, 35, 36, 37, 38, 40, 43, 68, 69, 77, 78, 80, 84, 86, 90, 92, 94, 99, 100, 102, 103, 108, 109, 114, 118, 119, 122, 123], "dure": [1, 6, 10, 12, 22, 37, 40, 42, 43, 56, 66, 77, 78, 94, 102, 109, 125], "325": 1, "unusu": [1, 6], "332": 1, "336": 1, "340": 1, "347": 1, "339": 1, "363": 1, "358": 1, "379": 1, "workaround": 1, "regress": 1, "383": 1, "trigger": [1, 22, 105], "inspect": [1, 61, 79], "prior": [1, 16, 22, 58, 94, 109], "also": [1, 2, 3, 6, 7, 8, 10, 11, 12, 13, 14, 18, 19, 20, 22, 23, 26, 28, 29, 30, 31, 34, 35, 36, 38, 41, 42, 43, 53, 55, 56, 58, 60, 61, 62, 64, 66, 69, 70, 74, 76, 77, 79, 80, 84, 86, 87, 90, 92, 99, 100, 102, 103, 104, 108, 109, 113, 116, 117, 118, 119, 123, 124], "catch": [1, 22], "tripwireerror": [1, 65, 107], "clemen": [1, 56], "bauer": [1, 56], "freec84": [1, 56], "bugfix": [1, 22, 43], "concat_imag": [1, 65], "unsign": [1, 35, 40, 76, 94, 109, 111], "302": 1, "autom": [1, 26], "earli": [1, 3, 94], "307": 1, "312": [1, 74], "c": [1, 2, 8, 9, 12, 15, 26, 29, 30, 33, 34, 35, 36, 37, 38, 40, 42, 43, 52, 56, 57, 58, 62, 68, 69, 70, 71, 73, 74, 76, 80, 81, 84, 85, 86, 90, 92, 94, 99, 100, 102, 103, 109, 114, 116, 118, 123, 124], "ico7": 1, "315": 1, "page": [1, 18, 20, 22, 23, 24, 26, 34, 35, 40, 43, 45, 47, 48, 50, 51, 55, 56, 57, 62, 76], "host": [1, 35, 48], "neuroimag": [1, 2, 11, 28, 41, 56, 66, 78, 110], "mail": [1, 3, 4, 6, 7, 14, 16, 19, 23, 26, 38, 43, 52, 65, 79], "had": [1, 2, 9, 13, 14, 20, 43, 54, 55, 62, 64, 80, 108, 123], "nolan": [1, 56], "nichol": [1, 56], "basil": [1, 56], "pinsard": [1, 56], "johnson": 1, "nikolaa": [1, 56], "n": [1, 6, 9, 15, 26, 30, 31, 35, 38, 40, 56, 61, 62, 68, 75, 77, 84, 86, 91, 92, 102, 103, 104, 108, 110, 111, 113, 116, 119, 120, 123], "oosterhof": [1, 56], "offset": [1, 9, 30, 36, 40, 64, 65, 69, 70, 71, 73, 74, 78, 84, 90, 92, 102, 103, 109, 123], "begin": [1, 2, 6, 9, 36, 38, 39, 40, 92, 102, 103, 106, 108, 119], "befor": [1, 4, 5, 6, 7, 10, 12, 19, 22, 23, 26, 36, 43, 55, 61, 62, 71, 77, 79, 81, 90, 93, 94, 103, 119, 123], "keep": [1, 2, 7, 15, 19, 20, 21, 25, 26, 37, 39, 43, 52, 55, 61], "zero": [1, 2, 4, 9, 36, 38, 40, 62, 64, 68, 69, 71, 76, 77, 84, 86, 91, 97, 102, 103, 108, 111, 113, 116, 123], "necessari": [1, 2, 9, 11, 14, 16, 19, 22, 23, 27, 60, 64, 79, 80], "room": [1, 2, 123], "explicitli": [1, 15, 16, 35, 105], "To": [1, 2, 5, 6, 8, 9, 10, 11, 15, 20, 22, 29, 35, 36, 38, 40, 41, 42, 43, 56, 57, 62, 66, 72, 76, 80, 86, 92, 96, 103, 105, 106, 109, 119], "look": [1, 2, 3, 4, 6, 7, 8, 9, 11, 20, 26, 30, 31, 35, 38, 39, 40, 41, 43, 47, 51, 57, 60, 69, 84, 86, 89, 102, 103, 104, 106, 120, 123, 124], "inter": [1, 15, 62, 65, 69, 70, 71, 103, 118, 123], "in_memori": [1, 7, 59, 65, 80], "alreadi": [1, 4, 7, 11, 12, 20, 26, 29, 30, 34, 35, 43, 51, 52, 55, 57, 61, 77, 80, 86, 87, 90, 93, 105, 113, 116, 119, 123], "whether": [1, 2, 3, 6, 7, 8, 12, 19, 20, 21, 25, 26, 34, 35, 40, 58, 69, 70, 71, 74, 76, 77, 79, 80, 84, 86, 87, 90, 92, 99, 100, 103, 106, 110, 112, 116, 117, 118, 119, 123, 124], "should": [1, 2, 3, 6, 7, 9, 10, 11, 12, 14, 15, 16, 19, 20, 22, 23, 26, 31, 35, 38, 39, 42, 43, 45, 48, 51, 57, 60, 61, 62, 68, 69, 70, 72, 74, 77, 79, 80, 84, 85, 86, 87, 88, 89, 90, 91, 92, 94, 97, 99, 100, 102, 103, 104, 105, 106, 108, 109, 110, 111, 112, 114, 116, 117, 118, 119, 122, 123, 124, 125], "slowli": 1, "phase": [1, 9, 12, 16, 103, 109], "out": [1, 3, 4, 6, 7, 8, 9, 10, 12, 13, 19, 27, 32, 33, 40, 41, 52, 58, 60, 62, 76, 77, 78, 82, 84, 87, 90, 92, 99, 100, 101, 115, 116, 120, 122, 123], "algorithm": [1, 4, 15, 19, 20, 22, 34, 38, 40, 62, 69, 79, 90, 113, 117], "unnecessari": 1, "possibl": [1, 3, 6, 9, 10, 11, 14, 15, 16, 20, 21, 23, 26, 35, 37, 43, 49, 54, 58, 61, 62, 70, 71, 72, 73, 77, 78, 85, 86, 102, 113, 117, 123], "time": [1, 6, 8, 9, 10, 13, 14, 15, 18, 20, 22, 23, 28, 31, 33, 35, 37, 38, 43, 44, 59, 60, 61, 62, 65, 69, 70, 74, 77, 80, 84, 87, 90, 91, 92, 94, 99, 100, 101, 103, 105, 106, 109, 110, 111, 116, 118, 119, 123], "due": 1, "advic": [1, 3, 6, 57], "jeff": 1, "stevenson": 1, "bennett": 1, "landman": 1, "dtifit": 1, "fslview": 1, "analysi": [1, 23, 28], "pipelin": [1, 7, 9, 14], "preliminari": [1, 43, 59, 100], "ly": [1, 2, 56], "nguyen": [1, 56], "ohind": 1, "vox2ras_tkr": 1, "unscal": [1, 36, 69, 102, 116, 117, 123], "get_unsc": [1, 65, 70, 98, 109, 116], "previou": [1, 2, 8, 14, 20, 27, 40, 43, 56, 66, 84, 87, 109], "wai": [1, 2, 3, 4, 6, 7, 9, 10, 11, 13, 16, 18, 20, 23, 26, 28, 35, 36, 38, 40, 42, 43, 48, 49, 51, 52, 55, 56, 57, 58, 59, 60, 62, 65, 69, 76, 87, 90, 102, 105, 123], "wa": [1, 2, 6, 7, 10, 19, 20, 26, 27, 28, 31, 35, 38, 40, 43, 58, 61, 72, 77, 78, 84, 86, 94, 106, 107, 118, 119], "rang": [1, 22, 30, 35, 38, 71, 76, 77, 100, 101, 109, 111, 123], "did": [1, 14, 29, 40, 43, 61, 69, 102], "base64": 1, "didn": [1, 9, 40], "wrong": [1, 43, 89], "russ": 1, "poldrack": 1, "diagnosi": 1, "read_annot": [1, 65], "orig_id": [1, 92], "vertic": [1, 15, 18, 38, 77, 92, 103, 110], "introductori": 1, "lot": [1, 7, 8, 9, 102, 119, 123], "common": [1, 2, 10, 11, 12, 13, 15, 20, 22, 27, 28, 29, 35, 42, 49, 56, 60, 62, 66, 74, 78, 87, 94, 119, 124], "mechan": [1, 6, 35, 76, 124], "special": [1, 6, 10, 15, 28, 35, 40, 58, 84, 105, 110, 123], "jb": [1, 56], "polin": [1, 56], "triangl": [1, 15, 92, 94], "rank": 1, "normal": [1, 6, 15, 28, 31, 35, 54, 61, 72, 86, 105, 113], "137": 1, "longdoubl": [1, 76], "debian": [1, 22, 31, 47, 58, 59, 79], "ppc": [1, 26, 76], "halchecko": 1, "diagnos": 1, "hope": [1, 3, 9, 20, 35], "them": [1, 3, 6, 7, 9, 10, 11, 16, 19, 20, 26, 27, 28, 30, 31, 35, 43, 52, 54, 60, 62, 77, 86, 89, 94, 102, 105, 119, 123], "float128": [1, 76], "platform": [1, 26, 57, 76], "real": [1, 2, 6, 14, 16, 20, 30, 35, 36, 43, 86, 99, 113, 119], "ieee": [1, 76, 102], "binary128": [1, 76], "particular": [1, 2, 3, 7, 9, 10, 11, 20, 22, 26, 27, 31, 35, 38, 40, 41, 43, 58, 60, 69, 102, 105, 110, 119], "diagnost": [1, 78, 124], "dx": [1, 30], "column": [1, 2, 9, 12, 18, 32, 35, 36, 40, 68, 70, 77, 84, 86, 92, 94, 102, 110, 111, 113, 114, 123], "dicomf": [1, 26, 57, 65], "krish": [1, 56, 92], "subramaniam": [1, 56, 92], "cinde": [1, 56], "madison": [1, 56], "f\u00e9lix": [1, 56], "morenc": [1, 56], "fuse": [1, 65], "filesystem": [1, 27, 83], "round": [1, 36, 39, 76, 87, 123], "rgb": [1, 94], "yannick": [1, 56], "schwartz": [1, 56], "displai": [1, 2, 26, 35, 62, 69, 77, 94, 122, 124, 126], "about": [1, 2, 4, 6, 7, 9, 10, 11, 12, 13, 14, 18, 20, 22, 23, 26, 28, 31, 33, 35, 38, 40, 41, 43, 52, 56, 58, 60, 64, 65, 68, 77, 79, 86, 102, 105, 119], "burn": [1, 56], "jarrod": [1, 6, 23, 56, 58], "millman": [1, 6, 23, 56, 58], "substanti": [1, 26, 58], "mm": [1, 2, 16, 33, 36, 38, 40, 41, 68, 77, 102, 111, 119, 123], "neg": [1, 2, 38, 66, 69, 76, 84, 86, 90, 94, 102, 103, 108, 109, 113], "voxel_ord": [1, 11, 65, 119], "filo": 1, "problem": [1, 2, 7, 8, 12, 13, 14, 16, 20, 36, 38, 43, 55, 56, 69, 72, 86, 92, 96, 105, 109, 123, 124], "ruopeng": 1, "forum": [1, 6, 77, 104], "routin": [1, 7, 12, 20, 30, 37, 40, 54, 68, 69, 73, 76, 85, 86, 90, 107, 108, 111, 115, 118, 119], "give": [1, 6, 9, 10, 12, 19, 20, 23, 26, 30, 35, 36, 38, 39, 40, 41, 42, 43, 45, 49, 53, 56, 66, 69, 70, 72, 74, 76, 77, 79, 80, 82, 84, 86, 87, 90, 92, 94, 99, 100, 102, 103, 104, 107, 108, 109, 111, 113, 115, 116, 117, 118, 122, 123, 124, 126], "approxim": [1, 8, 29, 54, 103], "form": [1, 2, 3, 9, 12, 15, 26, 35, 38, 40, 51, 58, 61, 62, 77, 79, 84, 92, 103, 110, 113, 119], "ra": [1, 3, 15, 54, 60, 61, 62, 68, 77, 92, 102, 108, 109, 110, 111, 116, 119, 126], "lp": [1, 2, 109], "hash": [1, 7, 20, 73, 123], "infer": [1, 109, 122], "incorrect": [1, 36], "h": [1, 15, 40, 42, 92], "one": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 22, 23, 26, 28, 30, 35, 38, 40, 43, 45, 52, 58, 60, 61, 62, 68, 69, 70, 72, 74, 77, 78, 79, 80, 84, 87, 89, 90, 92, 94, 99, 100, 102, 103, 105, 106, 108, 109, 110, 118, 119, 122, 123, 124], "gracefulli": 1, "cote": 1, "level": [1, 4, 9, 10, 16, 28, 30, 41, 64, 72, 79, 96, 106, 124], "doe": [1, 2, 3, 6, 7, 8, 9, 10, 12, 16, 19, 22, 26, 27, 30, 34, 35, 38, 39, 40, 55, 60, 61, 62, 64, 69, 70, 72, 76, 77, 78, 79, 80, 81, 84, 87, 90, 92, 102, 103, 104, 106, 107, 108, 111, 116, 119, 120, 123, 124], "pair": [1, 9, 10, 20, 38, 40, 61, 69, 74, 75, 77, 78, 80, 86, 87, 89, 90, 92, 94, 99, 100, 102, 103, 104, 109, 113, 118, 119, 123, 126], "leak": [1, 43], "rw": [1, 51, 64, 65, 69, 74, 77, 84, 87, 92, 99, 103, 109, 118], "spm": [1, 7, 9, 12, 13, 21, 25, 27, 28, 29, 32, 33, 34, 36, 38, 39, 57, 62, 69, 102, 118], "swap": [1, 69, 71, 92, 102, 123, 124], "odd": [1, 35, 40, 102], "comparison": [1, 31, 78], "lead": [1, 6, 7, 36, 38, 40, 113], "public": [1, 7, 20, 23, 26, 43, 119], "complet": [1, 4, 6, 9, 12, 20, 26, 28, 40, 41, 51, 61, 103, 109, 123], "rewrit": 1, "pure": [1, 15, 57], "It": [1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 16, 19, 20, 22, 28, 31, 34, 35, 36, 38, 40, 41, 42, 43, 48, 51, 52, 54, 55, 57, 58, 60, 61, 62, 64, 69, 71, 74, 76, 77, 78, 79, 80, 84, 86, 87, 92, 99, 100, 102, 103, 104, 106, 109, 116, 117, 118, 119, 122, 123, 124], "design": [1, 6, 23, 28, 41, 71, 74, 110], "simpler": [1, 2, 40, 103], "easier": [1, 3, 10, 14, 28, 43, 80, 123], "fairli": [1, 8, 10, 20, 30, 102], "matlab": [1, 9, 12, 18, 30, 34, 40, 76, 92, 118], "mat": [1, 9, 13, 30, 32, 113, 118], "basic": [1, 51, 57, 69, 84, 90, 117, 118, 125], "simpl": [1, 3, 8, 9, 11, 18, 19, 20, 23, 30, 52, 62, 68, 75, 77, 79, 102, 103, 116], "pleas": [1, 4, 5, 6, 8, 19, 22, 26, 41, 45, 52, 56, 57, 66, 81, 98, 100, 103, 105, 108, 120], "let": [1, 2, 7, 8, 9, 12, 14, 20, 35, 36, 38, 43, 51, 54, 55, 62, 86, 90, 102, 109], "know": [1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 19, 20, 27, 29, 30, 35, 36, 38, 41, 43, 54, 55, 60, 62, 76, 80, 87, 102, 103, 105, 109, 115, 116, 119], "highli": [1, 6, 9, 86], "experiment": [1, 18], "ian": [1, 56], "nimmo": [1, 56], "smith": [1, 56], "closest": [1, 2, 85, 93, 102, 103, 108, 113], "canon": [1, 3, 15, 54, 77, 90, 93, 103, 110, 123], "right": [1, 2, 11, 12, 15, 18, 26, 36, 38, 40, 42, 43, 51, 54, 58, 60, 68, 69, 77, 86, 102, 109, 119, 123], "back": [1, 2, 4, 8, 9, 10, 14, 18, 26, 27, 29, 34, 35, 40, 43, 52, 55, 59, 61, 87, 102, 103, 108, 116, 119, 123], "front": [1, 2, 18, 38, 108], "third": [1, 2, 9, 22, 30, 36, 38, 54, 60, 77, 109, 123], "down": [1, 2, 8, 9, 38, 43, 44, 55, 61, 69, 90, 114, 116, 122], "taylor": 1, "stephen": 1, "util": [1, 12, 65, 68, 73, 76, 79, 90, 91, 92, 98, 101, 105, 108, 109, 114, 122, 123], "rip": 1, "edit": [1, 9, 26, 42, 46, 49, 52, 56, 66], "huge": [1, 7], "downward": 1, "step": [1, 14, 15, 16, 26, 30, 31, 35, 40, 44, 61, 68, 77, 90], "mostli": [1, 105], "good": [1, 3, 4, 6, 10, 15, 26, 42, 43, 47, 49, 51, 58, 123], "haven": [1, 7, 100], "even": [1, 6, 8, 19, 26, 29, 35, 40, 41, 43, 52, 58, 69, 78, 90, 117, 118, 123, 124], "soon": [1, 20], "modif": [1, 55, 58, 72, 106], "done": [1, 4, 6, 11, 14, 22, 27, 34, 43, 48, 52, 57, 62, 78, 103, 105, 108, 116, 124], "indic": [1, 2, 6, 9, 15, 35, 38, 40, 70, 77, 90, 92, 94, 102, 103, 109, 110, 116, 118, 119, 122], "close": [1, 3, 9, 25, 26, 43, 51, 54, 65, 86, 93, 102, 106, 113, 122], "statement": [1, 35, 39, 56, 102, 120], "id": [1, 35, 84, 92], "queri": [1, 9], "visit": [1, 35], "niftiformat": 1, "vx2": 1, "unfortun": [1, 2, 12, 84], "interact": [1, 23, 43, 116], "between": [1, 7, 9, 10, 11, 12, 14, 15, 19, 23, 29, 30, 33, 35, 38, 39, 40, 60, 61, 68, 69, 71, 74, 76, 77, 78, 84, 87, 90, 92, 94, 99, 100, 102, 103, 104, 109, 116, 117, 118, 119, 122, 126], "garbag": 1, "librari": [1, 6, 9, 12, 16, 18, 19, 23, 26, 28, 41, 57, 61, 76, 120, 123], "dictionari": [1, 9, 10, 11, 30, 61, 74, 77, 79, 84, 87, 94, 102, 109, 116, 119, 123, 126], "bogu": 1, "assign": [1, 6, 35, 77, 102, 119], "niftiimag": 1, "517920": 1, "length": [1, 2, 4, 9, 12, 18, 39, 60, 62, 68, 70, 77, 90, 91, 92, 93, 101, 102, 108, 109, 111, 114, 115, 119, 123, 126], "short": [1, 6, 9, 16, 35, 40, 41, 45, 90], "edata": 1, "whose": [1, 15, 28, 94], "aim": [1, 22, 78, 109], "stabil": [1, 6], "result": [1, 2, 7, 10, 13, 14, 15, 18, 20, 22, 27, 33, 36, 38, 40, 55, 58, 60, 62, 66, 68, 69, 70, 72, 74, 76, 77, 79, 80, 84, 90, 92, 93, 94, 96, 99, 100, 102, 108, 114, 118, 119, 123, 124], "whole": [1, 7, 8, 9, 11, 12, 35, 38, 39, 55, 86, 90, 99, 100], "restructur": [1, 22, 114], "clib": 1, "redirect": 1, "sure": [1, 2, 4, 6, 7, 9, 13, 26, 27, 42, 43, 80, 84, 119, 123], "break": [1, 2, 16, 22, 39, 40, 77, 94, 102, 105, 120], "thei": [1, 2, 3, 4, 6, 7, 9, 10, 12, 16, 19, 20, 22, 23, 26, 27, 28, 35, 36, 38, 43, 53, 60, 62, 64, 69, 71, 72, 77, 78, 79, 80, 86, 94, 102, 105, 109, 113, 116, 119, 123, 124], "emb": 1, "serializ": 1, "automat": [1, 4, 10, 19, 51, 62, 77, 92, 103], "upon": [1, 120], "meta": [1, 6, 15, 18, 35, 65, 77, 84, 87, 94, 102, 116], "dump": [1, 9, 10, 35, 39], "embed": [1, 41, 68, 115], "secur": [1, 20, 35], "implic": [1, 22], "becaus": [1, 2, 4, 6, 7, 8, 9, 10, 12, 14, 19, 20, 26, 28, 29, 31, 33, 34, 35, 36, 38, 40, 43, 51, 54, 55, 57, 60, 61, 62, 68, 69, 74, 76, 77, 79, 80, 86, 90, 94, 102, 103, 113, 118, 119, 123, 124], "actual": [1, 2, 6, 7, 8, 10, 11, 20, 30, 35, 36, 42, 43, 55, 77, 78, 80, 90, 102, 119, 123], "execut": [1, 19, 105], "risk": 1, "niftiextens": [1, 103], "handler": 1, "memmappedniftiimag": 1, "cropimag": 1, "old": [1, 9, 70, 92], "vx2q": 1, "defin": [1, 2, 3, 9, 10, 11, 15, 18, 20, 31, 32, 33, 35, 36, 40, 60, 62, 68, 69, 70, 76, 77, 79, 80, 86, 87, 88, 89, 91, 92, 94, 95, 102, 103, 106, 109, 112, 115, 119, 123, 125], "cal_min": [1, 61, 62, 69, 103, 104, 117, 118], "cal_max": [1, 61, 62, 69, 103, 104, 117, 118], "remain": [1, 6, 39, 40, 43, 72, 77, 102, 119], "modifi": [1, 6, 8, 19, 21, 25, 35, 39, 41, 43, 55, 58, 69, 70, 72, 80, 90, 93, 119, 123], "xyzt_unit": [1, 12, 41, 61, 62, 103, 104], "xyz_unit": 1, "time_unit": 1, "former": [1, 23], "see": [1, 2, 3, 4, 6, 7, 8, 10, 12, 13, 14, 18, 19, 20, 22, 23, 26, 28, 30, 33, 35, 36, 37, 38, 39, 40, 41, 43, 45, 47, 48, 52, 53, 54, 55, 56, 57, 60, 61, 62, 63, 64, 66, 69, 70, 71, 74, 76, 77, 80, 82, 84, 86, 90, 92, 93, 94, 96, 99, 102, 103, 104, 108, 109, 111, 113, 119, 123, 124], "getxyzunit": 1, "setxyzunit": 1, "gettimeunit": 1, "settimeunit": 1, "manuipul": 1, "getqformcod": 1, "setqformcod": 1, "getsformcod": 1, "setsformcod": 1, "qform_cod": [1, 61, 62, 103, 104], "sform_cod": [1, 61, 62, 103, 104], "its": [1, 2, 6, 9, 10, 11, 13, 16, 23, 26, 27, 28, 35, 36, 38, 41, 55, 58, 68, 70, 80, 82, 87, 92, 94, 103, 116, 119, 120, 123], "__str__": [1, 124], "pickl": 1, "switch": [1, 14, 43, 52], "procedur": [1, 6, 35, 56], "optim": [1, 8, 15, 22, 27, 30, 90], "swig": [1, 34], "introduc": [1, 126], "__version__": [1, 107], "updateqformfromquarternion": 1, "intern": [1, 7, 14, 21, 41, 55, 80, 92, 119, 124], "howev": [1, 6, 10, 20, 22, 29, 36, 43, 58, 61, 62, 77, 103, 116], "getscaleddata": 1, "unmodifi": [1, 3, 52, 93, 123], "unicod": [1, 77], "properli": [1, 9, 58], "charact": [1, 35, 39, 40, 77, 94, 114], "ga\u00ebl": [1, 56], "minim": [1, 9, 29, 72, 116], "nifticlib": 1, "makefil": [1, 26], "posix": [1, 85], "local": [1, 2, 4, 20, 22, 26, 43, 50, 53, 79], "built": [1, 26, 62, 90, 106], "On": [1, 2, 7, 12, 43, 57, 64, 85, 102], "still": [1, 2, 6, 7, 9, 12, 23, 26, 27, 35, 39, 40, 43, 61, 62, 64, 69, 111, 120], "proper": [1, 22, 26], "guarante": [1, 15, 70, 124], "setup_egg": 1, "wrap": [1, 10, 34, 99, 100, 102, 111, 123, 124], "accident": [1, 4, 53], "pointer": [1, 7, 33, 40, 52, 125], "honor": 1, "sync": 1, "flush": 1, "again": [1, 6, 8, 20, 32, 35, 36, 42, 43, 54, 61, 62, 80, 105, 116, 120], "circular": [1, 105], "destructor": 1, "merg": [1, 6, 9, 17, 23, 25, 26, 28, 46, 49, 51, 53, 58], "bashism": 1, "profil": [1, 35], "epydoc": 1, "pylint": [1, 22], "q": [1, 2, 9, 36, 68, 86, 102, 108, 109, 113], "setfilenam": 1, "benjamin": [1, 56], "thyreau": 1, "setpixdim": 1, "store": [1, 2, 4, 7, 9, 10, 12, 14, 15, 18, 20, 27, 28, 29, 35, 36, 37, 39, 41, 60, 61, 62, 69, 74, 77, 80, 84, 87, 92, 94, 99, 100, 102, 103, 104, 109, 116, 117, 118, 119, 123], "meaningless": 1, "pyarray_fromdimsanddata": 1, "uncompress": [1, 20, 106], "compil": [1, 10, 26, 35, 76, 102], "under": [1, 4, 56, 58, 66, 109], "mingw": [1, 76], "just": [1, 6, 7, 8, 10, 16, 20, 26, 27, 30, 35, 37, 38, 39, 40, 43, 44, 45, 48, 51, 52, 53, 57, 61, 68, 69, 84, 87, 93, 102, 103, 110, 115, 116, 117, 118, 123], "libniftiio": 1, "znzlib": 1, "those": [1, 9, 10, 13, 20, 22, 26, 33, 35, 37, 40, 41, 43, 49, 51, 56, 62, 68, 78, 80, 87, 93, 102, 103, 104, 105, 110, 119], "relicens": 1, "mit": [1, 56, 58, 66], "licens": [1, 3, 25, 31, 34, 57, 59, 65, 84, 86], "www": [1, 9, 18, 20, 31, 34, 38, 77, 79, 86, 92, 94, 104, 119], "opensourc": 1, "php": [1, 77, 104], "442175": 1, "unload": 1, "damag": [1, 58], "integr": [1, 10, 28, 46, 69, 76, 103], "recov": [1, 29, 38], "pixdim": [1, 12, 61, 62, 69, 72, 84, 103, 104, 117, 118], "vanish": 1, "dim": [1, 12, 30, 40, 61, 62, 65, 69, 77, 92, 102, 103, 104, 110, 116, 117, 118], "vector": [1, 2, 9, 15, 18, 30, 36, 37, 38, 40, 68, 77, 86, 92, 102, 103, 104, 109, 111, 113, 118, 123], "element": [1, 10, 12, 13, 20, 28, 30, 33, 38, 40, 41, 68, 72, 75, 77, 80, 86, 89, 90, 92, 94, 102, 108, 109, 111, 113, 115, 119, 123, 126], "applic": [1, 7, 9, 29, 35, 68, 77, 78, 94], "anymor": 1, "toward": [1, 2, 8, 17, 25, 38, 54, 60, 69, 76, 77, 111], "unittest": 1, "suit": [1, 11, 57, 109, 119], "pynifti_pst": 1, "peristimulu": 1, "signal": [1, 12, 43, 52, 84, 102, 103, 111, 118, 123], "onset": 1, "getperistimulustimeseri": 1, "comput": [1, 35, 42, 53, 78, 86, 97, 103, 105, 109, 113, 119], "mean": [1, 2, 4, 6, 7, 8, 9, 12, 20, 23, 26, 28, 35, 36, 38, 40, 43, 53, 54, 55, 60, 61, 62, 64, 69, 76, 77, 78, 80, 86, 90, 92, 96, 100, 103, 108, 111, 112, 115, 116, 123, 124], "varianc": 1, "among": [1, 15, 19, 23, 28, 76, 78], "timeseri": [1, 77], "deviat": [1, 109], "descript": [1, 3, 9, 18, 35, 38, 43, 74, 75, 77, 81, 86, 93, 94, 102, 103], "present": [1, 9, 15, 20, 28, 35, 40, 69, 71, 72, 76, 88, 102, 103, 106, 124], "note": [1, 3, 5, 8, 9, 14, 16, 18, 19, 26, 30, 31, 35, 37, 40, 42, 43, 51, 52, 53, 56, 61, 62, 65, 66, 76, 77, 78, 79, 80, 81, 84, 86, 90, 92, 94, 102, 103, 104, 108, 109, 113, 116, 119, 120, 123, 124], "relev": [1, 6, 9, 10, 16, 18, 22, 26, 34, 35, 39, 40, 56, 69, 85, 99, 100, 106], "accessor": [1, 105], "repetit": [1, 9, 86, 92, 116], "dt": [1, 30, 35, 72, 76, 123], "determin": [1, 36, 41, 74, 102, 103, 109, 113, 122], "bound": [1, 2, 90, 103], "box": [1, 2, 63, 102], "corrupt": [1, 20], "ioerror": 1, "filetyp": 1, "revers": [1, 2, 8, 26, 29, 36, 54, 108, 123], "seem": [1, 7, 9, 12, 13, 35, 38, 39, 40, 76, 90, 94, 102, 109, 119], "often": [1, 3, 6, 12, 13, 14, 19, 26, 27, 28, 30, 35, 43, 55, 98, 124], "sourc": [1, 4, 6, 9, 10, 15, 25, 26, 27, 31, 34, 56, 58, 59, 69, 79, 84], "tarbal": [1, 26, 57], "html": [1, 6, 7, 8, 9, 18, 22, 26, 38, 74, 79, 81, 86, 105, 113, 119], "upload": [1, 26], "413049": 1, "extent": [1, 61, 62, 68, 69, 103, 117, 118], "volext": 1, "timepoint": [1, 77], "niftifil": 1, "fulfil": 1, "wish": [1, 13, 35, 62], "libfslio": 1, "seven": [1, 103], "dimension": [1, 9, 12, 15, 40, 68, 77, 78, 92, 93, 103, 110, 113, 122], "dataset": [1, 10, 12, 30, 35, 37, 40, 55, 74, 77, 102, 103, 109, 117], "go": [1, 2, 3, 6, 7, 8, 9, 20, 22, 26, 30, 35, 38, 40, 42, 43, 45, 51, 52, 53, 57, 60, 61, 70, 76, 77, 78, 80, 90, 102, 114], "three": [2, 6, 7, 9, 11, 12, 14, 15, 20, 26, 28, 35, 38, 40, 43, 61, 62, 77, 86, 94, 103, 111, 116, 119, 123], "thing": [2, 6, 7, 8, 14, 20, 28, 46, 49, 52, 61, 64, 72, 76, 78, 102, 107, 120, 123], "3d": [2, 9, 12, 18, 30, 32, 36, 40, 60, 68, 69, 74, 77, 84, 86, 93, 102, 103, 110, 115, 116, 122], "4d": [2, 9, 12, 18, 30, 31, 84, 93, 102, 116, 122], "tell": [2, 6, 12, 27, 31, 35, 38, 42, 52, 53, 54, 65, 70, 86, 102, 106, 109, 119, 123], "usual": [2, 3, 10, 12, 26, 34, 35, 36, 43, 55, 61, 68, 77, 80, 87, 102, 107, 108, 109, 111, 116, 118], "document": [2, 3, 6, 9, 11, 12, 14, 17, 18, 19, 20, 21, 23, 26, 34, 35, 40, 41, 57, 58, 59, 66, 68, 74, 77, 84, 87, 94, 125], "how": [2, 7, 8, 9, 10, 11, 13, 16, 20, 23, 25, 27, 28, 35, 36, 40, 49, 51, 52, 57, 60, 62, 70, 74, 77, 80, 84, 105, 109, 119, 122, 125], "what": [2, 4, 7, 9, 10, 11, 16, 19, 20, 22, 29, 35, 36, 38, 40, 43, 53, 54, 56, 57, 60, 61, 62, 69, 72, 74, 77, 78, 80, 84, 90, 92, 96, 102, 107, 111, 112, 115, 120, 124], "scan": [2, 4, 9, 18, 20, 31, 61, 62, 109], "two": [2, 4, 6, 7, 9, 12, 20, 26, 28, 31, 35, 36, 38, 39, 40, 54, 62, 64, 74, 77, 80, 94, 102, 103, 109, 110, 113, 114, 122, 123, 124], "mri": [2, 10, 12, 18, 60, 101, 103, 109], "epi": [2, 109], "In": [2, 3, 6, 7, 8, 9, 10, 12, 15, 20, 23, 27, 29, 30, 31, 33, 34, 35, 36, 38, 39, 40, 41, 46, 50, 54, 55, 56, 58, 60, 61, 62, 64, 66, 69, 74, 76, 77, 80, 84, 86, 87, 90, 92, 93, 94, 99, 100, 102, 103, 104, 108, 109, 112, 113, 116, 117, 118, 119, 123, 124], "never": [2, 3, 6, 103], "person": [2, 4, 19, 20, 22, 35, 42, 58], "someones_epi": 2, "gz": [2, 41, 54, 55, 58, 60, 61, 62, 66, 73, 74, 80, 89, 106], "someones_anatomi": [2, 60], "epi_img": 2, "download": [2, 20, 31, 47, 57, 60, 94], "epi_img_data": 2, "53": [2, 30, 61, 109], "61": [2, 9, 43], "33": [2, 9, 26, 74], "Then": [2, 7, 14, 20, 26, 31, 36, 38, 39, 40, 41, 43, 52, 53, 57, 86], "pyplot": [2, 60], "plt": [2, 36, 60, 116, 122], "def": [2, 3, 4, 8, 11, 14, 15, 71, 72, 105, 123], "show_slic": 2, "fig": [2, 65, 122], "subplot": 2, "1": [2, 4, 6, 9, 10, 11, 12, 14, 20, 26, 29, 30, 31, 33, 35, 36, 38, 39, 40, 43, 54, 55, 57, 58, 59, 60, 61, 62, 64, 66, 68, 69, 70, 71, 72, 74, 76, 77, 78, 81, 82, 84, 86, 90, 91, 92, 93, 94, 96, 97, 102, 103, 104, 105, 106, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 123, 124], "len": [2, 4, 9, 68, 69, 90, 103, 104, 111, 123, 124], "enumer": [2, 77], "imshow": [2, 36, 60], "cmap": [2, 60, 65, 122], "grai": [2, 15, 60, 103], "slice_0": 2, "26": [2, 8, 9, 59, 61, 62, 109], "slice_1": 2, "30": [2, 9, 37, 57, 59, 62, 72, 93, 108, 109, 124], "slice_2": 2, "16": [2, 10, 15, 31, 35, 41, 58, 59, 61, 62, 68, 94, 102, 104, 109], "suptitl": 2, "center": [2, 33, 36, 38, 69, 77, 92, 109, 118, 119, 123], "png": [2, 57, 60], "hire": [2, 60], "pdf": [2, 60, 86, 94, 102], "anatom": [2, 18, 27, 38, 74, 77], "session": 2, "anat_img": 2, "anat_img_data": 2, "57": [2, 61, 62], "67": 2, "56": [2, 62], "28": [2, 31, 59, 60, 62, 68], "As": [2, 3, 8, 9, 19, 20, 27, 34, 35, 55, 60, 61, 76, 96, 120], "magnet": [2, 35, 101], "y": [2, 9, 12, 18, 30, 38, 40, 55, 69, 77, 86, 92, 94, 102, 105, 109, 110, 113, 116, 122], "pixel": [2, 12, 32, 33, 35, 36, 40, 101, 102, 109], "abov": [2, 4, 7, 8, 9, 12, 19, 20, 22, 23, 26, 30, 31, 35, 36, 38, 39, 40, 42, 43, 51, 58, 60, 62, 76, 77, 79, 84, 86, 89, 90, 102, 105, 109, 111, 114, 115, 123], "2d": [2, 12, 36, 68, 86, 102, 114, 119], "plot": [2, 116, 122], "grayscal": [2, 35], "grade": 2, "black": 2, "white": [2, 15, 103], "repres": [2, 6, 9, 11, 15, 35, 43, 61, 68, 76, 77, 80, 82, 86, 90, 94, 102, 119, 123], "certain": [2, 22], "thick": [2, 33, 77, 92, 109, 114], "select": [2, 9, 12, 15, 22, 26, 29, 34, 35, 43, 56, 57, 61, 66, 77, 80, 94, 102, 103, 110, 115, 122], "For": [2, 3, 4, 7, 8, 9, 10, 12, 14, 15, 20, 22, 26, 27, 29, 30, 35, 36, 37, 38, 40, 41, 42, 43, 48, 51, 54, 55, 56, 57, 60, 61, 62, 66, 68, 69, 71, 72, 76, 77, 80, 82, 84, 87, 92, 93, 94, 102, 103, 105, 108, 109, 111, 113, 115, 116, 119, 120, 122, 123], "middl": [2, 38, 60, 90], "n_i": 2, "n_j": 2, "n_k": 2, "center_i": 2, "2": [2, 3, 6, 7, 9, 10, 11, 12, 14, 20, 26, 30, 31, 33, 35, 36, 37, 38, 40, 41, 42, 43, 54, 55, 56, 59, 60, 61, 62, 64, 65, 66, 68, 69, 70, 71, 72, 74, 76, 78, 79, 81, 84, 86, 87, 90, 92, 93, 94, 98, 102, 103, 104, 105, 108, 109, 110, 111, 113, 115, 116, 117, 118, 119, 123, 124], "divis": 2, "center_j": 2, "center_k": 2, "center_vox_valu": 2, "81": [2, 109], "5492877960205": 2, "rel": [2, 9, 10, 33, 34, 38, 42, 43, 60, 76, 78, 79, 102, 109], "0": [2, 4, 7, 8, 9, 10, 12, 14, 15, 17, 20, 23, 25, 26, 27, 29, 30, 31, 35, 36, 37, 38, 39, 40, 43, 54, 55, 57, 58, 59, 60, 61, 62, 64, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 86, 88, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 108, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125], "goe": [2, 40, 54, 70], "52": [2, 62, 74], "similarli": [2, 7, 19, 38, 60, 77, 86, 94, 106], "60": [2, 9, 37], "32": [2, 9, 10, 12, 22, 30, 35, 36, 38, 40, 41, 54, 61, 62, 77, 84, 94, 104], "almost": [2, 60, 103], "noth": [2, 7, 27, 72], "came": [2, 20, 31], "term": [2, 4, 6, 9, 10, 12, 14, 15, 19, 30, 33, 35, 38, 40, 56, 60, 66, 68, 76, 84, 90, 108, 109, 123], "sai": [2, 6, 7, 9, 10, 12, 14, 20, 26, 29, 35, 36, 38, 40, 43, 51, 54, 55, 62, 90], "idea": [2, 3, 6, 9, 19, 26, 41, 60, 64, 84], "arbitrari": [2, 9, 53, 62, 78, 86, 102, 113], "within": [2, 6, 9, 20, 22, 34, 35, 39, 58, 69, 71, 76, 77, 86, 90, 94, 102], "took": [2, 54], "transvers": [2, 109], "moder": 2, "angl": [2, 68, 86, 113], "floor": [2, 76], "ceil": [2, 36, 76, 102], "consol": [2, 109], "red": [2, 77, 94], "block": [2, 35, 36, 61, 69, 77, 84, 90, 92, 102, 103, 104, 117, 118, 120, 122, 123, 124], "border": 2, "parallel": [2, 27], "quit": [2, 11, 35, 43], "isocent": [2, 60, 109], "later": [2, 3, 6, 9, 35, 38, 56, 61, 64, 66, 87, 90, 105], "want": [2, 3, 4, 8, 9, 10, 12, 13, 14, 20, 26, 27, 28, 30, 35, 36, 38, 39, 40, 42, 44, 46, 52, 53, 54, 55, 56, 57, 61, 62, 74, 77, 80, 81, 90, 105, 109, 116, 120, 123, 124], "easili": [2, 4, 10, 11, 15, 22, 23, 41, 77, 94], "moment": [2, 7, 8, 10, 12, 13, 14, 20, 26, 94], "locat": [2, 15, 20, 22, 28, 33, 38, 56, 61, 68, 69, 79, 84, 85, 92, 94, 116, 119], "solv": [2, 8, 10, 16, 20, 57], "relationship": [2, 8, 10, 20, 35, 60, 69, 74, 84, 92, 99, 100, 103, 104, 109, 116, 117, 118], "spatial": [2, 9, 10, 12, 60, 77, 92, 95, 103, 111, 115, 116, 122], "equival": [2, 8, 20, 28, 30, 35, 60, 61, 62, 68, 72, 76, 85, 87, 90, 92, 94, 97, 102, 106, 108, 109, 110, 113, 116, 123], "phrase": 2, "our": [2, 3, 4, 9, 12, 14, 19, 20, 22, 23, 26, 27, 28, 29, 30, 34, 38, 39, 48, 51, 53, 54, 57, 61, 62, 69, 77, 84, 86, 87, 90, 103, 105, 115, 116, 122], "world": [2, 3, 20, 29, 30, 41, 54, 61, 62, 68, 69, 74, 84, 92, 99, 100, 102, 103, 104, 109, 110, 111, 116, 117, 118, 119, 126], "3": [2, 7, 8, 9, 11, 12, 14, 15, 20, 22, 30, 31, 33, 35, 36, 38, 39, 40, 42, 55, 57, 58, 59, 60, 61, 62, 64, 68, 69, 72, 73, 74, 77, 79, 80, 81, 84, 86, 87, 92, 94, 98, 101, 102, 103, 104, 105, 106, 108, 109, 111, 112, 113, 115, 116, 117, 118, 119, 122, 123, 124], "independ": [2, 15, 41, 74, 77, 87, 109, 116], "decid": [2, 6, 7, 8, 20, 23, 90], "choos": [2, 8, 13, 22, 43, 59, 61], "orthogon": [2, 36, 38, 103, 122], "millimet": [2, 36, 61, 77, 111], "imagin": [2, 20, 27, 38, 60, 102, 108, 115], "observ": 2, "stand": [2, 6, 124], "behind": [2, 19, 27, 49, 60], "bed": [2, 38], "travel": [2, 6], "closer": [2, 7], "draw": [2, 65, 122], "definit": [2, 3, 9, 10, 11, 12, 18, 20, 33, 40, 60, 77, 90, 99, 100, 102, 103, 106, 109, 126], "z": [2, 12, 18, 30, 32, 36, 40, 68, 69, 77, 86, 92, 94, 102, 103, 109, 110, 113, 116, 122], "5": [2, 8, 9, 11, 12, 26, 30, 31, 35, 40, 57, 59, 60, 61, 62, 68, 69, 70, 74, 76, 77, 80, 86, 87, 92, 93, 97, 98, 102, 103, 105, 108, 111, 112, 114, 117, 118, 119, 120, 122, 123], "10mm": 2, "fiction": 2, "5mm": 2, "3mm": 2, "foot": [2, 38, 109], "known": [2, 10, 27, 35, 41, 62, 69, 77, 86, 92, 95, 103, 119, 123, 124], "xyz": [2, 18, 38, 77, 86, 103, 113], "predecessor": 2, "acr": 2, "nema": [2, 9, 102], "face": [2, 3, 15, 92, 110], "posterior": [2, 12, 18, 38, 54, 60, 69, 94, 109], "anterior": [2, 12, 18, 54, 60, 77, 94, 109], "inferior": [2, 12, 18, 54, 69, 94, 109], "superior": [2, 12, 18, 54, 77, 109], "mai": [2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 16, 19, 20, 22, 23, 26, 27, 28, 35, 36, 37, 38, 40, 42, 43, 44, 48, 54, 55, 56, 57, 58, 59, 60, 61, 62, 66, 70, 71, 72, 75, 76, 77, 80, 81, 82, 85, 87, 89, 92, 93, 94, 103, 105, 106, 108, 109, 110, 113, 116, 119, 120, 123, 124], "might": [2, 3, 4, 7, 8, 9, 10, 12, 13, 20, 22, 26, 27, 35, 38, 42, 46, 55, 64, 69, 70, 72, 74, 76, 80, 87, 88, 90, 92, 102, 103, 108, 111, 115, 116, 119, 120, 123], "prefer": [2, 4, 6, 7, 8, 9, 15, 19, 22, 38, 43, 55, 56, 62, 76, 80, 90, 94, 98, 109], "deal": [2, 10, 12, 13, 58, 67, 70, 76, 86, 114, 123], "patient": [2, 32, 33, 35, 36, 40, 58, 60, 84, 102], "come": [2, 9, 18, 20, 23, 41, 43, 49, 52, 62, 70, 84, 86, 90, 103, 115, 119, 124], "reorder": [2, 9, 12, 54, 90, 93, 109], "although": [2, 78, 99, 100, 113], "convent": [2, 3, 9, 22, 54, 86, 94, 102, 119, 126], "univers": [2, 58], "word": [2, 7, 22, 35, 42, 43, 90], "lpi": [2, 31], "ll": [2, 3, 4, 7, 8, 9, 20, 33, 35, 37, 38, 39, 40, 42, 43, 51, 53, 123], "interpret": [2, 22, 60, 62, 77, 90, 103, 111, 124], "peopl": [2, 4, 6, 14, 41, 51, 56, 60, 69], "hand": [2, 7, 8, 12, 26, 38, 60, 86], "side": [2, 6, 19, 38, 55, 60, 69, 86], "carefulli": 2, "familiar": [2, 7, 19], "folk": 2, "agre": [2, 4, 23, 109], "friend": [2, 57], "enemi": 2, "yet": [2, 7, 14, 20, 26, 31, 34, 61, 80, 81, 102, 109], "made": [2, 6, 7, 19, 20, 23, 35, 42, 43, 51, 52, 56, 66, 69, 116, 117, 118], "k": [2, 6, 12, 31, 38, 60, 77, 86, 102, 113, 115, 119, 123, 124], "theori": [2, 58, 102], "complic": [2, 9, 34, 35, 43, 61, 68, 76, 109, 120], "linear": [2, 43, 58, 68, 119], "practic": [2, 6, 7, 12, 15, 26, 30, 42, 60, 105, 123], "regular": [2, 6, 61, 62, 69, 103, 105, 106, 117, 118], "grid": [2, 15, 36, 65], "compris": [2, 16, 35, 102], "translat": [2, 9, 10, 15, 36, 38, 61, 68, 69, 77, 103, 109, 118, 123], "wikipedia": [2, 38, 76, 86, 113], "diagon": [2, 60, 68, 69, 93, 111, 115], "p": [2, 12, 29, 30, 35, 43, 51, 56, 68, 69, 81, 108, 109], "bmatrix": [2, 36, 38], "theta": [2, 86, 113], "radian": [2, 12, 68, 77, 86], "co": [2, 6, 26, 42, 86], "sin": [2, 86, 122], "phi": [2, 10], "gamma": [2, 86], "obviou": [2, 7, 9, 20, 38, 54, 86], "turn": [2, 6, 7, 9, 22, 36, 43, 77], "abcd": 2, "abc": [2, 77, 119], "b": [2, 7, 9, 15, 26, 29, 35, 38, 40, 43, 58, 61, 62, 68, 75, 77, 86, 90, 102, 103, 104, 106, 108, 109, 112, 119, 122, 123], "addit": [2, 6, 9, 10, 22, 23, 28, 38, 56, 66, 116, 119, 123, 125], "fact": [2, 3, 4, 6, 7, 8, 9, 12, 30, 31, 35, 60, 61, 62, 77, 84, 86, 87, 116], "4": [2, 3, 7, 9, 10, 11, 12, 20, 26, 30, 35, 36, 38, 39, 40, 41, 54, 55, 57, 59, 60, 61, 62, 64, 68, 69, 72, 74, 76, 77, 81, 84, 86, 87, 92, 93, 94, 95, 97, 99, 100, 102, 103, 104, 105, 108, 109, 111, 113, 115, 116, 117, 118, 119, 122, 123], "exactli": [2, 8, 29, 35, 61, 76, 77, 123], "m_": [2, 38], "why": [2, 9, 16, 43, 52, 61, 76], "extra": [2, 3, 4, 9, 10, 66, 69, 74, 77, 80, 84, 87, 92, 94, 99, 100, 102, 103, 104, 106, 109, 111, 116, 117, 118], "rephras": [2, 38, 90], "homogen": [2, 65, 68, 69, 74, 77, 84, 92, 99, 100, 103, 104, 109, 110, 111, 115, 116, 117, 118], "trick": [2, 12, 123], "put": [2, 3, 4, 9, 10, 11, 18, 22, 34, 40, 60, 96, 102, 119], "part": [2, 6, 10, 11, 12, 19, 20, 26, 31, 35, 40, 60, 64, 68, 69, 70, 76, 77, 84, 86, 102, 103, 105, 109, 111, 113, 115], "One": [2, 4, 9, 10, 11, 12, 13, 20, 27, 69, 77, 84], "compon": [2, 15, 36, 38, 68, 77, 102, 103], "mathemat": [2, 15, 119], "inconveni": 2, "anoth": [2, 7, 9, 10, 11, 16, 18, 20, 26, 27, 35, 38, 40, 42, 61, 69, 87, 90, 92, 102, 103, 109, 115, 119], "pleasant": [2, 9], "invert": [2, 108], "ident": [2, 4, 27, 29, 40, 41, 54, 61, 77, 103, 111, 113, 115, 116, 122], "That": [2, 7, 8, 10, 14, 20, 30, 35, 38, 69, 108, 119, 123], "decim": [2, 15, 35, 54, 61, 62], "set_printopt": [2, 54, 61, 62], "78": [2, 9, 60], "76": 2, "split": [2, 4, 6, 9, 10, 13, 15, 64, 68, 76, 79, 84, 89], "dot": [2, 10, 36, 40, 68, 86, 113, 115], "impress": 2, "epi_vox_cent": 2, "205": [2, 39], "8": [2, 6, 9, 10, 12, 33, 35, 39, 40, 57, 59, 60, 61, 62, 68, 69, 72, 76, 77, 94, 103, 104, 109, 111, 117, 118, 125], "453": 2, "2mm": 2, "multipli": [2, 9, 38, 62, 77, 113], "linalg": [2, 115], "npl": 2, "epi_vox2anat_vox": 2, "inv": [2, 30, 115], "364": 2, "31": [2, 9, 12, 26, 36, 38, 40, 59, 84], "562": 2, "36": [2, 9, 54, 61, 62, 68, 102, 109], "165": 2, "anat_vox_cent": 2, "27": [2, 26, 59], "nearli": [2, 7, 8, 19, 35, 76, 93, 113], "half": [2, 119], "across": [2, 9, 10, 12, 20, 22, 26, 28, 30, 35, 84, 93, 109, 111], "9": [2, 8, 9, 12, 20, 31, 35, 40, 57, 59, 61, 62, 68, 76, 106], "ey": [2, 7, 30, 41, 54, 61, 62, 65, 68, 77, 81, 86, 87, 93, 97, 103, 116], "sens": [2, 6, 7, 9, 12, 13, 15, 16, 27, 60, 71, 76, 90], "think": [2, 4, 6, 7, 8, 20, 22, 30, 36, 38, 43, 52, 60, 76, 84], "shown": [2, 23, 35, 81], "onto": [2, 20, 30, 43, 80], "equat": 2, "next": [2, 6, 7, 26, 31, 35, 38, 39, 40, 55, 60, 61, 62, 69, 76, 80, 84, 105, 119], "green": [2, 77, 94], "scaling_affin": 2, "after": [2, 6, 7, 10, 11, 14, 19, 22, 23, 26, 35, 39, 40, 43, 45, 62, 69, 72, 77, 80, 81, 90, 91, 92, 94, 102, 103, 104, 105, 119, 123], "one_vox_axis_0": 2, "cos_gamma": 2, "sin_gamma": 2, "rotation_affin": 2, "affine_so_far": 2, "yellow": [2, 42], "figur": [2, 35, 41, 78, 116, 122], "bottom": [2, 18, 38, 60, 103], "translation_affin": 2, "whole_affin": 2, "bring": [2, 19, 43, 119], "fanci": [2, 43, 90], "softwar": [2, 9, 12, 20, 34, 35, 37, 56, 58, 60], "regist": [2, 9, 20, 26], "templat": [2, 20, 23, 58, 80, 87, 89, 116], "montreal": [2, 58], "neurolog": [2, 58, 69, 84, 126], "institut": [2, 58], "mni": [2, 58, 62, 74], "registr": [2, 28, 30, 35], "chang": [2, 6, 7, 8, 9, 10, 12, 14, 16, 17, 18, 20, 22, 23, 26, 28, 30, 38, 40, 42, 44, 46, 52, 53, 55, 56, 59, 61, 62, 69, 70, 74, 76, 77, 81, 87, 90, 103, 104, 105, 106, 109, 116, 119, 120, 122, 123, 124], "probabl": [2, 8, 9, 12, 14, 20, 52, 60, 72, 102, 109, 118, 123], "commissur": [2, 94], "cross": [2, 36, 38, 40, 63, 114], "midlin": 2, "ac": [2, 9, 15], "hemispher": [2, 15, 77], "exact": [2, 4, 35, 76], "somewhat": [2, 9, 33, 40], "There": [2, 3, 4, 6, 9, 10, 11, 18, 20, 22, 28, 30, 31, 34, 35, 36, 39, 40, 41, 43, 47, 48, 49, 61, 62, 65, 74, 76, 77, 80, 84, 86, 87, 102, 109], "talairach": [2, 18, 62, 94, 103], "atla": [2, 62], "pc": [2, 76], "trajectori": 2, "regardless": [2, 6, 18, 19, 30, 80, 112], "underli": [2, 7, 8, 12, 14, 90, 93, 102, 111, 123, 124], "chose": [2, 3, 9, 62], "popular": [2, 31, 57], "enforc": [2, 4, 42, 78, 94, 103], "consult": [2, 19, 56, 66], "radiolog": [2, 69, 84, 123, 126], "progress": [3, 6, 16, 21, 23, 43, 52], "transpar": [3, 8, 67, 77, 92], "zen": 3, "gui": [3, 31, 34], "spring": 3, "mind": 3, "implicit": [3, 7, 35, 76], "silent": [3, 14, 77, 94, 103, 125], "ambigu": [3, 86], "refus": 3, "temptat": 3, "guess": [3, 64, 69, 79, 84, 85, 87, 89, 90, 98, 103, 117, 118, 119, 124], "hard": [3, 11, 20, 43, 90], "explain": [3, 16, 19, 20, 40, 43, 49, 52, 72, 123], "bad": [3, 6, 26, 72, 83], "tri": [3, 9, 23, 40, 41, 107], "fastest": [3, 8, 9, 12, 18, 69, 76, 103, 106], "vari": [3, 9, 34, 109, 119], "rest": [3, 9, 40, 43, 51, 109, 114], "learn": [3, 15, 19, 48, 49], "realli": [3, 4, 9, 57, 103], "top": [3, 4, 9, 10, 18, 36, 38, 43, 51, 56, 60, 64, 66, 103, 107, 115, 123], "excel": [3, 34, 49, 52, 57], "job": [3, 20, 27, 29, 34, 38, 76, 90, 115], "someon": [3, 6, 7, 20, 43, 51, 58, 96, 107, 126], "els": [3, 7, 19, 20, 43, 52, 56, 62, 69, 70, 71, 72, 77, 103, 112, 119], "test_image_api": 3, "testparrecapi": 3, "loadimageapi": 3, "loader": 3, "self": [3, 8, 14, 15, 69, 70, 71, 72, 74, 77, 79, 82, 84, 88, 89, 92, 102, 103, 105, 106, 109, 110, 117, 118, 119, 123], "fname": [3, 4, 7, 27, 30, 64, 74, 79, 87, 89, 94, 116, 120, 123, 125], "example_imag": 3, "parrec_example_imag": 3, "test_parrec": 3, "inherit": [3, 10, 11, 62, 69, 74], "strongli": [3, 19, 57], "free": [3, 6, 56, 58, 80], "alwai": [3, 4, 7, 8, 9, 12, 13, 17, 19, 20, 25, 27, 30, 35, 38, 39, 54, 55, 61, 62, 74, 76, 80, 84, 90, 92, 94, 95, 103, 109, 112, 118, 119, 123, 126], "ones": [3, 6, 10, 30, 40, 41, 77], "consid": [3, 6, 12, 15, 19, 20, 22, 26, 38, 46, 51, 52, 69, 72, 78, 90, 94, 102, 108, 109, 116, 119], "test_proxy_api": [3, 70], "file_map": [3, 61, 69, 74, 77, 80, 84, 87, 88, 92, 94, 99, 100, 103, 104, 109, 116, 117, 118], "least": [3, 6, 10, 12, 14, 19, 20, 23, 26, 29, 38, 70, 74, 76, 79, 84, 88, 94, 95, 102, 106, 114, 123], "get_data_dtyp": [3, 30, 41, 61, 62, 65, 69, 70, 74, 77, 84, 92, 99, 100, 103, 109, 116], "get_data_shap": [3, 61, 65, 69, 70, 74, 77, 92, 99, 100, 103, 104, 109, 116, 117, 118], "from_file_map": [3, 65, 69, 74, 77, 80, 84, 87, 92, 94, 99, 100, 109, 116, 118], "parrecimag": [3, 65], "test_my_format_name_her": 3, "extract": [3, 34, 40, 74, 78, 79, 84, 94, 102, 113], "enough": [3, 41, 87, 90, 102, 116, 124], "fit": [3, 58, 123], "forget": [3, 4, 26, 40], "mayb": [3, 7, 9, 10, 20, 27, 31, 43, 60, 68, 69, 71, 84, 90, 106, 109, 119, 123], "from_fileboj": 3, "repositori": [3, 4, 6, 20, 25, 26, 44, 51, 52, 57], "test_parrec_data": [3, 4], "ask": [3, 6, 19, 20, 27, 30, 35, 38, 46, 55, 61, 64, 90, 107], "easiest": [3, 52], "conserv": 4, "directori": [4, 6, 15, 20, 22, 26, 35, 41, 42, 43, 44, 53, 57, 79, 85, 102, 120], "below": [4, 6, 7, 9, 19, 20, 23, 35, 38, 39, 58, 72, 76, 77, 82, 84, 86, 102, 108, 109, 113, 123, 124], "larger": [4, 20, 23, 27, 28, 68, 71, 109], "own": [4, 9, 11, 13, 19, 20, 26, 35, 36, 41, 43, 46, 48, 49, 50, 51, 52, 53, 69, 77, 84, 87, 103, 116, 122], "50k": 4, "less": [4, 6, 7, 12, 20, 31, 35, 39, 60, 61, 77, 78, 85, 116, 119, 123], "By": [4, 6, 10, 12, 20, 23, 38, 54, 61, 62, 64, 69, 71, 79, 80, 84, 92, 105, 109, 110, 117, 118, 119, 123, 124], "zlib": [4, 20], "sy": [4, 79], "argv": 4, "rb": [4, 87, 88, 106], "fobj": [4, 65, 74, 87, 91, 106, 109, 120], "smaller": [4, 15, 28, 35, 71], "uninterest": 4, "yourself": [4, 19, 30, 43, 45, 53, 62], "repo": [4, 6, 26, 43, 45, 51, 52, 79], "reason": [4, 6, 7, 9, 10, 12, 19, 20, 23, 28, 35, 41, 43, 60, 71, 87, 116], "shame": 4, "pddl": [4, 58], "cc0": 4, "opportun": [4, 6, 15, 19, 26], "cite": 4, "who": [4, 6, 16, 23, 26, 41, 42, 51, 52, 56, 105], "easi": [4, 10, 11, 15, 22, 28, 34, 37, 41, 49, 57, 59, 76], "fine": [4, 6, 14, 41, 57], "kind": [4, 6, 19, 20, 22, 58, 76], "new": [4, 6, 9, 10, 11, 12, 13, 15, 16, 19, 20, 22, 23, 25, 26, 40, 41, 44, 46, 51, 52, 53, 55, 57, 59, 61, 62, 65, 68, 69, 70, 74, 78, 80, 84, 87, 90, 92, 93, 99, 100, 103, 106, 113, 116, 118, 119, 124], "yarikopt": [4, 23, 58], "nitest": [4, 58], "balls1": [4, 58], "despit": 4, "bitbucket": 4, "internet": 4, "someth": [4, 7, 8, 10, 19, 20, 22, 26, 27, 29, 36, 38, 42, 43, 52, 53, 57, 61, 69, 71, 90, 100, 107, 115, 116, 120, 123, 124], "rosetta": 4, "sampl": [4, 15, 30, 32, 61, 77, 110, 116], "your": [4, 6, 9, 14, 19, 20, 22, 25, 26, 42, 46, 49, 50, 51, 52, 59, 69, 79, 86, 94, 119], "stage": [4, 43], "area": [4, 6, 35, 60], "needs_nibabel_data": 4, "nibabel_data": 4, "get_nibabel_data": 4, "rosetta_data": 4, "pjoin": [4, 79], "test_someth": 4, "travi": [4, 26], "checkout": [4, 42, 43, 49, 51, 52, 57], "init": [4, 5, 71], "hundr": 4, "megabyt": 4, "ok": [4, 9, 26, 27, 40, 124], "joi": 4, "aren": [4, 9], "anyth": [4, 10, 41, 43, 52, 56, 62, 72, 90], "aw": [4, 9, 71], "resourc": [5, 9, 22, 25, 26, 34, 35, 48, 50, 57], "intens": [5, 30, 57], "nipy_extra_test": 5, "slow": [5, 12, 18, 26, 76], "machin": [5, 9, 18, 35, 39, 49, 76, 94], "4gb": 5, "ram": 5, "berkelei": [6, 26], "edu": [6, 9, 26, 58, 86, 92], "statu": [6, 7, 9, 11, 12, 13, 14, 15, 16, 26, 42, 43, 49, 52, 84], "draft": [6, 9, 10, 11, 12, 13, 15, 16, 20, 23], "2020": [6, 14, 57, 59], "06": [6, 9, 102], "25": [6, 54, 59, 61, 62, 74], "enhanc": [6, 25, 59, 102], "propos": [6, 10, 11, 13, 16, 17, 20, 25, 28, 42], "primari": 6, "featur": [6, 16, 19, 22, 27, 28, 34, 38, 41, 42, 46, 51, 52, 57, 59, 62, 66], "gone": [6, 9], "concis": 6, "technic": [6, 16, 49], "rational": 6, "respons": [6, 19, 25, 35, 58, 87], "consensu": [6, 23], "dissent": 6, "opinion": [6, 16, 23], "revis": [6, 43], "histori": [6, 19, 20, 49, 57], "histor": 6, "necessarili": [6, 29, 64, 123], "surround": 6, "event": [6, 23, 58], "languag": [6, 9, 10, 20, 114], "itself": [6, 10, 19, 20, 23, 35, 56, 61, 66, 87, 116], "codebas": [6, 13], "develop": [6, 16, 20, 26, 28, 31, 44, 49, 50, 51, 56, 58, 59, 66], "inject": 6, "focus": [6, 22], "success": [6, 28, 107], "tend": 6, "doubt": 6, "sever": [6, 7, 22, 35, 39, 48, 52, 65, 72, 77, 87, 94, 119, 123, 124], "champion": 6, "shepherd": [6, 19], "appropri": [6, 10, 15, 23, 61, 77, 81, 103], "ascertain": 6, "suitabl": [6, 58, 106, 114], "post": [6, 13, 16, 19, 38, 42, 49, 56, 77, 90, 123], "best": [6, 20, 29, 31, 35, 52, 57, 62, 71, 76, 84, 85, 90, 103, 108, 123], "devel": [6, 26], "biap_": 6, "rst": [6, 20, 26, 102, 114], "four": [6, 20, 28, 35, 77, 92, 102], "digit": [6, 9, 20, 54, 56, 61, 62, 66, 76], "biap_0000": 6, "onc": [6, 11, 19, 23, 26, 36, 45, 57, 80, 87, 105, 115], "section": [6, 9, 16, 20, 23, 33, 35, 38, 40, 42, 43, 51, 57, 60, 62, 76, 79, 80, 102, 109], "backward": [6, 7, 13, 20, 22, 90, 112], "impact": [6, 23], "broader": 6, "scope": [6, 28], "detail": [6, 22, 23, 34, 35, 41, 45, 46, 49, 50, 55, 56, 59, 62, 64, 66, 68, 80, 87, 102, 103, 104, 108], "At": [6, 7, 8, 10, 12, 13, 14, 20, 22, 39, 40, 41, 43, 61, 76, 94, 106, 114], "earliest": 6, "conveni": [6, 11, 38, 49, 55, 68, 102, 119, 122, 123], "etc": [6, 9, 10, 11, 13, 19, 26, 30, 35, 36, 77, 78, 85, 87, 89, 102, 103, 114, 124], "sound": [6, 43, 76], "principl": [6, 13, 15, 23], "impract": 6, "subject": [6, 15, 35, 58, 60, 126], "wip": 6, "incorpor": [6, 30, 51], "main": [6, 11, 20, 22, 26, 31, 41, 51, 52, 53, 65, 68, 84, 90], "gather": [6, 33], "feedback": 6, "api": [6, 7, 9, 10, 12, 13, 17, 19, 20, 23, 25, 41, 42, 55, 56, 59, 64, 66, 70, 77, 84, 87, 109, 116, 119], "provision": [6, 15, 30], "inclus": 6, "unlik": [6, 9, 14, 23, 62, 111], "reject": [6, 7, 8, 16, 23], "withdrawn": [6, 16], "releas": [6, 19, 22, 25, 56, 58, 59, 65, 66, 78], "wherev": [6, 20], "reli": [6, 27, 76], "challeng": 6, "wider": 6, "ecosystem": [6, 16, 23], "core": [6, 25, 28, 42, 47], "perhap": [6, 8, 13, 20, 43], "said": 6, "similar": [6, 7, 11, 12, 16, 26, 35, 45, 62, 76, 102], "themselv": [6, 89], "compet": 6, "supersed": [6, 16], "render": [6, 60], "obsolet": [6, 30], "activ": [6, 16, 23, 26, 49, 87, 116], "meant": [6, 105, 111], "interest": [6, 11, 16, 20, 23, 33, 35, 61, 77], "contributor": [6, 19, 26, 58], "concret": [6, 23, 77], "reach": [6, 23, 26, 35, 51, 123], "readi": [6, 26, 43, 49, 119], "send": [6, 19, 35, 52, 56, 66, 100], "email": [6, 16, 52], "bodi": 6, "latest": [6, 9, 22, 24, 50, 56, 57, 66, 119], "briefli": 6, "sentenc": [6, 23], "substant": 6, "7": [6, 9, 12, 26, 33, 35, 38, 43, 54, 57, 59, 61, 62, 68, 69, 76, 77, 81, 84, 102, 103, 111, 118, 120, 123], "dai": [6, 14], "anyon": [6, 19, 23, 27, 43, 56], "everyon": [6, 109], "verg": 6, "chanc": [6, 10, 119], "respond": [6, 19, 23, 35], "comment": [6, 9, 19, 36, 40, 84, 92, 103], "period": [6, 33, 82], "beyond": 6, "shouldn": 6, "goal": 6, "rigid": 6, "polici": [6, 79], "game": 6, "err": 6, "compromis": 6, "offici": [6, 22], "followup": 6, "notifi": 6, "celebratori": 6, "emoji": 6, "state": [6, 19, 20, 22, 26, 27, 35, 43, 57, 59, 105], "continu": [6, 7, 9, 12, 19, 23, 28, 33, 36, 40, 77, 90, 123], "disagr": [6, 23], "approach": [6, 10, 15, 16], "escal": [6, 23], "steer": 6, "council": 6, "controversi": [6, 28], "ultim": 6, "natur": [6, 8, 28, 35], "utf": [6, 94, 125], "restructuredtext": 6, "restructuredtextprim": 6, "web": [6, 9, 19, 26, 35, 38], "date": [6, 9, 16, 26, 31, 35, 42, 94], "dd": [6, 16], "mmm": 6, "yyyi": [6, 16], "random": [6, 54, 62], "dom": 6, "ain": 6, "given": [6, 9, 12, 14, 20, 26, 30, 35, 36, 38, 39, 40, 60, 61, 62, 68, 69, 70, 77, 78, 79, 82, 84, 86, 87, 88, 89, 90, 92, 94, 98, 102, 103, 104, 106, 111, 113, 114, 115, 116, 118, 119, 120, 123, 124, 125], "older": [6, 9, 14, 61, 76], "brows": 6, "2011": [7, 8, 9, 12, 58, 59, 94], "03": [7, 8, 9, 11], "23": [7, 9, 59, 61, 62, 68, 76, 113], "retir": [7, 35], "nibabel_imag": 7, "images_and_memori": [7, 8], "uncach": [7, 14, 59, 65, 80], "is_as_load": 7, "implicitli": 7, "typic": [7, 10, 12, 15, 28, 68, 77, 89, 102, 107, 123], "arr": [7, 8, 12, 69, 71, 76, 81, 90, 92, 103, 108, 116, 118, 123], "arang": [7, 11, 55, 61, 62, 64, 68, 69, 71, 81, 87, 90, 93, 103, 116, 123], "24": [7, 10, 41, 55, 59, 61, 62, 64, 68, 76, 81, 87, 103, 116], "_data": [7, 8], "px_img": 7, "px_arr": 7, "actual_arr": 7, "asarrai": [7, 55, 70], "isinst": 7, "ndarrai": [7, 15, 41, 55, 69, 70, 74, 76, 78, 80, 84, 90, 92, 94, 99, 100, 102, 103, 108, 109, 110, 116, 119, 123], "isn": [7, 38, 61, 100, 105], "anywher": 7, "distinct": [7, 30], "tempt": [7, 19], "me": [7, 31], "large_img1": 7, "large1": 7, "large_img2": 7, "large2": 7, "li1_mean": 7, "li2_mean": 7, "got": [7, 43, 51, 118], "unproxi": [7, 8], "insid": [7, 28, 56, 57, 70, 80, 90], "off": [7, 8, 22, 51, 61], "scalefactor": [7, 14, 21, 25, 30, 69, 71, 118, 123], "expens": [7, 9, 20, 76], "subsequ": [7, 35, 40, 78, 102], "faster": [7, 76, 102, 119], "hit": [7, 77, 94], "frequent": 7, "ve": [7, 8, 9, 12, 33, 34, 35, 43, 51, 52, 53, 60, 105], "stuff": [7, 8, 10, 20, 27, 30, 43, 48, 51, 57, 64], "run_spm_thing_on": 7, "run_spn_th": 7, "receiv": [7, 35], "run_spm_th": 7, "everi": [7, 9, 11, 15, 20, 26, 35, 41, 61, 69, 70, 74, 80, 84, 92, 99, 100, 118, 119], "dirti": [7, 27], "Not": [7, 15, 66, 76], "some_filenam": [7, 64], "With": [7, 15, 18, 22, 29, 89, 92, 114], "viviani": 7, "thought": [7, 8, 36, 38, 43], "whenev": [7, 92, 109, 119], "intend": [7, 16, 20, 22, 26, 28, 62, 69, 124], "summari": [7, 9, 16, 21, 22, 23, 42, 46, 50, 78, 86], "leav": [7, 14, 26, 52, 55, 80], "doesn": [7, 9, 19, 38, 43, 58, 87, 92, 103, 104, 105, 107, 119, 123], "bui": 7, "won": [7, 20, 33], "manual": [7, 11, 22, 26, 43, 50, 51, 56, 57, 66, 79, 103, 104], "my": [7, 20, 26, 42, 43, 51], "get_data_copi": 7, "situat": [7, 9, 27, 29, 41, 43, 60, 72, 86], "instanti": [7, 119], "shy": 7, "cheat": [7, 49], "ref": [7, 43, 119], "worri": [7, 43, 102], "mess": 7, "consequ": 7, "philosophi": [7, 25], "is_proxi": [7, 8, 61, 65, 80, 84, 99, 109], "kwarg": [7, 68, 70, 71, 74, 75, 76, 77, 78, 79, 81, 82, 83, 87, 88, 89, 92, 94, 96, 98, 99, 101, 102, 103, 105, 106, 108, 109, 110, 116, 119, 121, 124, 125], "99": [7, 9, 55, 64, 68, 80, 105], "affect": [7, 14, 16, 43, 70, 74, 87, 109, 116], "thu": [7, 9, 20, 26, 35, 38, 59, 69, 74, 76, 77, 84, 86, 94, 96, 102, 105, 108, 113, 119], "unproxy_if_this_is_a_proxy_do_nothing_otherwis": 7, "behav": [7, 55, 77, 119], "hdr": [7, 9, 11, 27, 41, 61, 69, 72, 84, 87, 89, 92, 103, 104, 116, 117, 118, 124], "aff": [7, 68, 103, 108, 109, 123], "upcom": [7, 26], "get_filenam": [7, 27, 30, 61, 65, 79, 87], "tempnam": 7, "set_head": 7, "set_affin": 7, "conflict": [7, 9, 26, 35, 43], "hdr_affine_from": 7, "nasti": 7, "syntax": [7, 8, 26, 30, 35, 124], "img2": [7, 27, 64, 66, 93, 115, 116], "new_affin": 7, "new_head": [7, 62], "motiv": [8, 21], "biiig": 8, "my_huge_imag": 8, "individu": [8, 9, 10, 12, 35, 62, 77, 86], "get_slic": 8, "biap1": [8, 17, 25], "immut": [8, 17, 25], "defeat": 8, "involv": [8, 20, 22, 23, 28, 77], "slowest": [8, 9, 12, 18, 69, 90, 103, 106], "anywai": [8, 90], "worth": [8, 19, 35, 40], "fortran": [8, 12, 60, 70, 71, 103, 123], "ugli": 8, "cours": [8, 9, 10, 11, 12, 15, 18, 20, 27, 41, 42, 49, 107], "contigu": [8, 12, 30, 64, 70, 90], "obvious": [8, 20, 31, 36, 38, 40, 76], "deproxi": 8, "someimag": 8, "parent": [8, 77, 94], "slicedef": 8, "iscontingu": 8, "read_off_disk_somehow": 8, "hidden": [8, 28], "annoi": 8, "complex": [8, 10, 19, 71, 113], "copy_if": 8, "But": [8, 14, 38, 43, 68, 76, 105, 120], "ourselv": [8, 38], "thrash": 8, "Of": [8, 9, 11, 12, 27, 35, 41, 42, 107], "boil": [8, 9], "bob": 9, "dougherti": 9, "wiki": [9, 20, 31, 76, 86, 113], "carri": [9, 15, 20, 23, 26, 87, 116], "nifti_ecode_ignor": 9, "nifti_ecode_dicom": 9, "medic": [9, 34, 35, 38, 58, 102], "nifti_ecode_afni": 9, "afni": [9, 13, 28, 56, 66, 68, 74], "nimh": [9, 74, 103], "nih": [9, 74, 103], "gov": [9, 74, 103], "afniextension1": 9, "6": [9, 10, 26, 33, 35, 38, 40, 58, 59, 61, 62, 68, 69, 76, 77, 79, 84, 94, 102, 103, 104, 109, 111, 113, 117, 118, 119, 123], "nifti_ecode_com": 9, "nul": 9, "ascii": [9, 94, 109, 114, 119], "impli": [9, 11, 12, 20, 35, 36, 51, 58, 62, 86, 87, 90, 98, 103, 108, 111, 115, 116, 118, 123], "nifti_ecode_xced": 9, "xcede": 9, "nbirn": 9, "net": [9, 31, 41, 84], "htm": [9, 34, 92], "nifti_ecode_jimdiminfo": 9, "jim": 9, "contact": 9, "info": [9, 26, 30, 39, 74, 76, 109], "dr": 9, "horsfield": 9, "mah5": 9, "AT": [9, 35], "leicest": 9, "uk": 9, "12": [9, 30, 35, 36, 38, 40, 54, 59, 61, 62, 68, 69, 102, 109], "nifti_ecode_workflow_fwd": 9, "fiswidget": 9, "kraepelin": 9, "wpic": 9, "pitt": 9, "fissel": 9, "kate": 9, "entir": [9, 11, 35], "prospect": 9, "evid": 9, "wild": [9, 84], "heavi": [9, 10], "schema": 9, "candid": [9, 20, 26], "bxh": 9, "websit": [9, 22, 23, 56, 57, 86], "quiet": 9, "dead": 9, "dtd": 9, "understand": [9, 23, 30, 34, 35, 40, 102], "gordon": 9, "kindlmann": 9, "consider": [9, 10, 110], "particularli": [9, 19, 26, 34], "team": [9, 23, 28, 58, 78], "summar": [9, 10, 23], "innov": 9, "axis_nam": 9, "transpos": [9, 36, 60, 102, 103, 108, 116], "struct": [9, 30, 40, 102], "incorrectli": 9, "primaci": 9, "ld": 9, "rdf": 9, "primer": 9, "essenti": [9, 30], "coupl": [9, 11], "uri": [9, 20], "derefer": 9, "pretti": [9, 42, 123, 124], "nipy_header_vers": 9, "has_label": 9, "clash": 9, "sparql": 9, "rdflib": 9, "act": [9, 10, 11, 70], "serial": [9, 15, 28, 87, 94, 125], "databas": [9, 20, 43], "engin": [9, 113], "context": [9, 35, 96, 106, 110, 120], "prefix": [9, 22, 26, 35, 79, 109, 120], "dcm": [9, 36, 102], "placehold": [9, 42], "neurolex": 9, "categori": [9, 22], "echo_tim": [9, 10], "45": [9, 42], "repetition_tim": 9, "occur": [9, 15, 23, 35, 86, 89, 92, 109, 113], "unrel": 9, "forward": [9, 23, 51, 79, 80], "manufactur": [9, 34, 35], "im": [9, 52, 109], "capit": 9, "letter": 9, "further": [9, 15, 25, 26, 31, 35, 38, 68, 76, 87, 93, 111], "writer": [9, 71, 106], "outsid": [9, 10, 26, 70, 76, 109, 111], "my_field1": 9, "my_field2": 9, "extended_mysoft": 9, "mysoft_on": 9, "mysoft_two": 9, "axis_metadata": 9, "constraint": [9, 90, 105], "omit": [9, 16, 77, 94, 106], "represent": [9, 43, 51, 58, 74, 76, 77, 87, 92, 103, 109, 116, 119, 123, 126], "vr": [9, 35, 39, 102], "00080070": 9, "lo": [9, 35, 37], "reconstruct": [9, 29, 33, 36, 40, 62, 102, 103, 113], "lossless": 9, "latter": [9, 19, 23, 77, 92], "recod": [9, 65, 124], "welcom": [9, 19], "frequenc": [9, 12, 35, 61, 103], "nor": [9, 11, 22, 58], "5d": [9, 12], "datatyp": [9, 11, 30, 61, 62, 69, 72, 77, 78, 87, 92, 94, 103, 104, 108, 116, 117, 118, 123, 124], "int16": [9, 14, 41, 55, 61, 62, 76, 103, 123, 124], "distanc": [9, 15, 38, 68, 90], "240": 9, "fourth": [9, 38, 62, 74, 92, 122, 123], "absent": [9, 35, 38, 40], "superset": [9, 19], "union": [9, 35], "applies_to": 9, "delet": [9, 20, 46, 55, 80, 84], "clutter": 9, "hei": 9, "mi": 9, "casa": 9, "su": 9, "plai": 9, "role": [9, 25], "cannot": [9, 12, 28, 40, 62, 69, 70, 71, 74, 80, 84, 87, 90, 92, 94, 99, 100, 102, 103, 104, 109, 116, 117, 118, 123], "scalar": [9, 11, 68, 71, 76, 77, 86, 90, 92, 103, 111, 113, 116, 119, 123], "along": [9, 12, 16, 35, 38, 54, 60, 61, 68, 74, 77, 86, 90, 93, 102, 109, 111, 114, 116, 119], "OR": [9, 15, 58, 70], "v_i": 9, "express": [9, 33, 35, 38, 58, 86, 90, 97, 102, 115], "cartesian": [9, 110], "product": [9, 36, 38, 40, 58, 63, 68], "ie": [9, 35], "6x10": 9, "a_": [9, 38, 40], "contrast": [9, 15, 20, 35, 119], "constant": [9, 11, 38, 40, 67, 111], "shape_of_imag": 9, "image_nam": 9, "axis_indic": 9, "axis_length": 9, "any_other_list": 9, "uniqu": [9, 20, 33, 35, 51, 77, 109], "repeat": [9, 10, 19, 22, 31, 45, 55, 73, 87, 102, 123], "NOT": [9, 58, 105], "gradient": [9, 12, 102, 109], "spatial_ax": 9, "bval": [9, 109], "bvec": [9, 109], "acquisit": [9, 12, 28, 31, 33, 40, 102, 103, 109], "millisecond": [9, 61], "choic": [9, 19, 42, 69, 103, 111, 119, 123], "decod": [9, 35, 40, 119], "sign": [9, 20, 26, 35, 41, 62, 94, 102, 109, 113], "6000": 9, "hour": 9, "loss": [9, 58, 116], "a_i": [9, 38], "ascend": [9, 38, 40], "sequenti": [9, 33, 103], "scheme": [9, 62], "20": [9, 30, 35, 57, 59, 61, 62, 68, 93, 97, 105, 108, 119, 122], "40": [9, 62, 72, 96], "80": 9, "100": [9, 31, 41, 68, 77, 103, 117], "multi": [9, 10, 12, 18, 32, 38, 40, 87, 102], "rare": [9, 10, 12, 15], "accord": [9, 19, 23, 30, 35, 40, 62, 90, 102, 108, 111, 119], "slice_cod": [9, 61, 62, 103, 104], "slice_start": [9, 61, 62, 103, 104], "slice_end": [9, 61, 62, 103, 104], "120": 9, "480": 9, "toffset": [9, 61, 62, 103, 104], "equal": [9, 20, 35, 38, 42, 62, 77, 82, 86, 92, 94, 102, 113, 123], "200": [9, 12, 20], "110": [9, 86, 117], "210": 9, "220": 9, "130": 9, "230": 9, "140": 9, "per": [9, 10, 11, 12, 13, 15, 30, 36, 40, 74, 77, 78, 84, 90, 92, 102, 103, 108, 109, 119], "nice": [9, 18, 34, 42, 49, 52, 60, 78], "mytim": 9, "myslic": 9, "assert": [9, 27, 42, 77, 80, 120], "Being": [9, 51], "frequency1": 9, "frequency2": 9, "motion": [9, 12, 13], "86": [9, 54, 61, 62], "83": 9, "01": [9, 94], "71": 9, "91": [9, 30, 60], "114": [9, 10], "59": 9, "54": [9, 62], "13": [9, 35, 40, 59, 61, 62, 109], "42": [9, 43, 62, 80], "34": [9, 26, 62, 102], "87": 9, "38": [9, 18, 62], "92": [9, 30], "77": [9, 39, 109], "97": [9, 30, 54, 61, 62], "82": [9, 10, 74], "89": 9, "39": [9, 109], "95": [9, 62], "116": 9, "29": [9, 40, 68], "68": 9, "41": [9, 74], "93": 9, "02": 9, "118": 9, "35": [9, 26, 42, 54, 61, 62], "44": [9, 62, 68], "49": [9, 10, 74, 102], "62": [9, 109], "125": 9, "46": [9, 42, 62], "17": [9, 35, 38, 54, 57, 59, 61, 62, 68, 94, 102], "21": [9, 10, 35, 36, 38, 40, 61, 62, 94], "66": [9, 43, 94], "obei": 9, "partial": [9, 15, 26, 90, 109], "output_vector": 9, "spatial_axi": 9, "output_offset": 9, "2012": [10, 59], "11": [10, 12, 22, 26, 35, 36, 38, 40, 54, 59, 61, 62, 68], "significantli": [10, 19], "spread": 10, "vast": 10, "amount": [10, 22, 36, 77, 86, 94, 119, 125], "lost": [10, 15, 37, 43], "nb": [10, 15, 97], "256": [10, 35, 90, 111], "repetitiontim": 10, "3500": 10, "echotim": 10, "idx": [10, 77, 109], "xrang": 10, "65": [10, 94], "98": [10, 109], "131": 10, "acquisitiontim": 10, "110455": 10, "370000": 10, "110457": 10, "272500": 10, "387500": 10, "multidimension": 10, "dcmmeta": 10, "filter": [10, 61, 94, 116], "togeth": [10, 20, 35, 77], "const": 10, "per_slic": 10, "per_volum": 10, "classif": 10, "while": [10, 15, 19, 22, 23, 26, 40, 41, 43, 61, 77, 83, 91, 109, 120], "simpli": [10, 22, 41, 77, 119], "json": [10, 13, 17, 25, 28], "chosen": [10, 16, 90], "flexibl": [10, 15, 41, 103], "ordereddict": [10, 78, 92, 102], "nifti1extens": [10, 37, 65, 77], "coregist": 10, "niftiwrapp": 10, "blob": [10, 20, 26, 92, 109], "d157741": 10, "src": [10, 26], "l1232": 10, "meta_valid": 10, "against": [10, 20, 23, 27, 31, 34, 76, 100, 109], "classmethod": [10, 11, 15, 69, 74, 77, 80, 84, 87, 92, 94, 99, 100, 103, 104, 109, 110, 116, 117, 118, 119, 124], "enclos": [10, 115], "potenti": [10, 92, 109], "popul": [10, 102], "four_to_thre": [10, 65], "three_to_four": 10, "todo": 10, "mosaic": [10, 31, 32, 34, 40, 102], "frame": [10, 12, 13, 32, 35, 37, 38, 84, 86, 102], "create_dcmmeta": 10, "variat": 10, "programmat": [10, 62], "manner": [10, 119], "live": [10, 23], "perframefunctionalsequ": 10, "reclassifi": 10, "entiti": [10, 23, 126], "unimport": 10, "unpack": [10, 20, 36, 57, 60, 65], "join": [10, 23, 41, 54, 55, 61, 62, 74, 79, 80, 84, 120], "notat": [10, 38], "csaseri": 10, "subhead": [10, 13, 84], "mrphoenixprotocol": 10, "ulvers": 10, "somehow": 10, "recurs": [10, 79], "mini": [10, 114], "travers": 10, "lose": [10, 28, 29, 71, 90, 105], "capabl": [10, 41, 102, 105, 119, 123], "2013": [11, 58], "09": [11, 15], "greatli": 11, "benefit": [11, 16, 20, 42, 80, 90], "vtk": 11, "camino": 11, "mitk": 11, "moreov": [11, 119], "eas": 11, "my_trk": 11, "lazy_load": [11, 119], "base_format": 11, "my_tck": 11, "f2": 11, "data1": 11, "fa": 11, "from_nifti": 11, "data2": 11, "voxel_s": [11, 65, 102, 111, 115, 119], "get_empty_head": 11, "data3": 11, "kept": [11, 105, 119], "folder": [11, 26], "iter": [11, 13, 72, 77, 102, 103, 113, 119, 123], "streamlinesfil": [11, 119], "get_magic_numb": 11, "cl": 11, "notimplementederror": [11, 14], "is_correct_format": [11, 65, 119], "fileobj": [11, 69, 70, 71, 74, 84, 87, 88, 90, 91, 92, 99, 103, 106, 109, 116, 119, 123, 124], "staticmethod": 11, "pretty_print": 11, "in_fileobj": 11, "out_filenam": 11, "streamlines_fil": 11, "detect_format": [11, 65], "ideal": [11, 22], "solut": [11, 16, 102], "commonhead": 11, "enum": [11, 66], "nb_fiber": 11, "dynamicstreamlinefil": 11, "offer": [11, 13, 41, 105], "append": [11, 37, 40, 65, 68, 77, 89, 90, 119], "2015": [12, 13, 58, 59], "07": [12, 13, 57, 103], "meaning": [12, 22, 35, 86], "my_4d": 12, "vol0": [12, 61], "vol1": [12, 55], "acquir": [12, 28, 33, 103], "3rd": [12, 22, 59, 93], "slice0": 12, "slice1": 12, "care": [12, 14, 23, 37, 41, 55, 62, 64, 76, 100, 109], "physicist": 12, "readout": 12, "stepwis": 12, "distort": 12, "hertz": [12, 77], "concentr": 12, "million": 12, "5th": [12, 103], "quot": [12, 18, 35, 76, 94], "spatiotempor": 12, "arrang": [12, 20, 35, 36, 38, 54, 60, 102], "happen": [12, 40, 60, 72, 76, 105, 108, 120], "deform": 12, "displac": 12, "y_highres001": 12, "121": 12, "145": 12, "width": [12, 76, 78, 104], "height": 12, "depth": [12, 49, 103], "nframe": [12, 84], "load_mgh": 12, "primarili": 12, "mnc2": 12, "minc2_4d": 12, "mnc": [12, 99, 100], "hdf5": [12, 13, 28], "f8": [12, 104], "xspace": 12, "i4": [12, 69, 76, 92, 103, 104, 117, 118, 123], "yspace": 12, "zspace": 12, "lineag": 12, "storag": [12, 20, 28, 35, 38, 69, 70, 76, 77, 87, 102, 116, 123], "versu": 12, "dataspac": [12, 94], "chapter": 12, "brainvoyag": [12, 21, 25], "stc": [12, 15, 18], "vtc": [12, 18], "fast": [12, 18, 27, 31, 51], "seen": [12, 26, 35, 61], "mr": [12, 18, 31, 33, 35, 39, 40, 102], "echo": [12, 31, 35, 101, 109], "fifth": 12, "thumb": [12, 38, 49, 86], "clearli": [12, 19, 20], "saw": [12, 55], "fmristat": 12, "plane": [12, 30, 33, 35, 38, 40, 68, 122], "attach": [12, 20, 28, 58, 61], "urgent": 12, "time_axis_index": 12, "axis_label": 12, "datarrai": 12, "xrai": 12, "panda": 12, "niminc1": 12, "niminc2": 12, "surpris": 12, "as_niminc": 12, "18": [13, 14, 18, 35, 59, 61, 62], "vista": 13, "lipsia": 13, "215": 13, "issuecom": 13, "122357444": 13, "estim": [13, 28, 40, 68, 86, 102, 113], "cumbersom": 13, "mix": 13, "investig": [13, 53], "nilearn": [13, 15, 28], "iter_img": 13, "slice_img": 13, "2018": [14, 59], "04": 14, "ship": [14, 58], "earlier": 14, "difficult": [14, 19, 20, 30, 123], "predict": [14, 80, 90], "awar": [14, 74], "my_imag": [14, 61, 74], "trap": 14, "sum": [14, 38, 40, 76], "ran": 14, "teach": [14, 28], "sensibl": [14, 43, 51, 118, 123], "answer": [14, 20], "scalng": 14, "_data_cach": 14, "asanyarrai": [14, 69, 74, 77, 80, 92, 99, 100, 103, 104, 109, 116, 117, 118], "_dataobj": 14, "trip": [14, 87], "accid": 14, "fdata": [14, 80], "issubclass": 14, "inexact": 14, "_fdata_cach": 14, "astyp": [14, 61, 69, 71, 76, 123], "pend": [14, 77, 94, 119], "april": [14, 59], "year": [14, 26, 28], "port": 14, "2021": 15, "volumetr": [15, 77, 116], "adjac": [15, 38, 102, 110], "pragmat": 15, "costli": 15, "reproduct": 15, "administr": 15, "consum": [15, 62, 68], "purpos": [15, 16, 17, 23, 25, 43, 58, 88, 123], "triplet": [15, 38, 77, 89, 110], "overlin": [15, 114], "ab": [15, 72, 76, 78, 106], "topologi": [15, 94], "subset": [15, 77, 106, 109], "connect": [15, 53, 58], "mesh": [15, 92, 94, 103, 110], "desir": [15, 20, 29, 102, 103], "densiti": 15, "lh": 15, "pial": [15, 103], "read_geometri": [15, 65], "write_geometri": [15, 65], "morphometri": [15, 56, 66, 92], "read_morph_data": [15, 65], "write_morph_data": [15, 65], "read_label": [15, 65], "subdivid": 15, "brainmodelaxi": [15, 65], "subspac": 15, "cortex": [15, 77], "medial": 15, "wall": 15, "subcort": 15, "wb": [15, 87, 92, 106], "mne": 15, "subjects_dir": 15, "n_vert": 15, "n_time": 15, "n_sensor": 15, "transfer": [15, 35], "absenc": 15, "signatur": [15, 20, 40, 71, 72, 102], "excess": 15, "consumpt": 15, "boundari": [15, 39, 111], "inflat": 15, "straightforward": [15, 43, 64, 86], "arithmet": 15, "paint": 15, "textur": 15, "possibli": [15, 16, 20, 36, 43, 72, 77, 84], "interpol": [15, 111], "downsampl": [15, 61], "sphere": 15, "reg": 15, "scikit": [15, 23], "coordaxi": 15, "coordinateaxi": 15, "load_structur": 15, "get_indic": 15, "str": [15, 69, 74, 77, 78, 79, 80, 81, 82, 84, 87, 88, 89, 92, 94, 98, 99, 100, 102, 103, 104, 106, 107, 109, 110, 111, 114, 116, 118, 119, 120, 121, 122, 123, 124, 125], "n_coord": [15, 65, 110], "get_coord": [15, 65, 110], "nx3": 15, "triangularmesh": 15, "n_triangl": 15, "get_triangl": 15, "mx3": 15, "get_mesh": 15, "get_nam": 15, "get_": [15, 62, 123], "coord": [15, 84, 92, 94, 110], "ratio": [15, 122], "overridden": [15, 69, 87], "ravel": 15, "triangular": [15, 92, 110], "geometrycollect": 15, "from_spec": 15, "klass": [15, 87, 93], "glm": 15, "first_level": 15, "make_first_level_design_matrix": 15, "run_glm": 15, "bold": [15, 42], "from_filenam": [15, 65, 80, 87, 94, 109, 116], "hemi": 15, "l_bold": 15, "gii": [15, 94], "dm": 15, "beta": [15, 86], "l_beta": 15, "mgz": [15, 92, 106], "anat": [15, 74], "l_midthick": 15, "surf": [15, 94], "networkx": [15, 19], "weight": 15, "graph": [15, 42, 43, 51], "get_graph": 15, "distance_matrix": 15, "gaussian": [15, 111], "sigma": [15, 111], "wildli": 15, "ineffici": 15, "l_smooth": 15, "_bold": 15, "plot_surf": 15, "plot_surf_img": 15, "tstat": 15, "l_contrast": 15, "taskvsbase_tstat": 15, "fs_subject": 15, "freesurfersubject": 15, "fsaverage5": 15, "get_structur": 15, "01_task": 15, "rest_bold": 15, "dtseri": 15, "fslr_hemi": 15, "l_label": 15, "dlpfc_mask": 15, "anatomicalstructureprimari": 15, "cortexleft": [15, 77], "vtx_idc": 15, "dlpfc_idc": 15, "dlpfc_img": 15, "wbspec": 15, "caretspec": 15, "fslr": 15, "resolut": [16, 18, 23, 29, 33, 38, 78], "achiev": [16, 40, 43], "elong": 16, "dash": [16, 35], "mainli": [16, 33, 60, 77, 123], "wouldn": 16, "perspect": [16, 22, 23, 60], "Its": [16, 119], "high": [16, 18, 27, 41, 64, 82], "pseudo": 16, "illustr": [16, 19], "technologi": 16, "art": 16, "branch": [16, 19, 22, 26, 42, 46, 49, 51, 52, 53, 57], "discret": [16, 124], "justif": 16, "bullet": 16, "regard": 16, "awesom": [17, 28], "biap2": [17, 25], "slicecopi": [17, 25], "biap3": [17, 25, 28], "biap4": [17, 25, 28], "dcmstack": [17, 25, 28], "biap5": [17, 25], "biap6": [17, 25, 28], "biap7": [17, 25], "biap8": [17, 25], "biap9": [17, 25], "216": 18, "appar": [18, 34, 36, 39, 40, 102], "bvqxtool": 18, "vmr": 18, "tal": 18, "fmr": 18, "nativ": [18, 57, 69, 78, 103, 117, 118, 124], "nr": 18, "vmp": 18, "msk": 18, "ubb": 18, "forum8": 18, "000087": 18, "smp": 18, "nrofvertic": 18, "approv": [19, 23], "volunt": 19, "tremend": 19, "grate": [19, 56], "critic": [19, 72], "remind": [19, 43, 51], "felt": 19, "novic": 19, "mentorship": 19, "handhold": 19, "experi": [19, 23, 109], "liber": 19, "recogn": [19, 26, 69, 72, 76, 77, 103], "realiz": 19, "gentl": 19, "polit": 19, "abandon": 19, "focu": 19, "global": [19, 20, 42, 52, 76, 96, 109, 124], "claim": [19, 58, 113], "explor": 19, "nitpicki": 19, "spell": [19, 22], "mistak": [19, 43], "push": [19, 26, 43, 49, 52, 53], "notif": [19, 35], "concern": 19, "mere": 19, "understood": 19, "freeli": 19, "member": [19, 23, 30], "insight": 19, "great": [19, 41], "bug": [19, 22, 42, 43, 52, 57, 59, 76, 102], "vouch": 19, "serious": 19, "clarif": 19, "reproduc": [19, 58], "fix": [19, 22, 23, 26, 31, 40, 42, 43, 52, 57, 59, 72, 76, 84, 86, 90, 92, 119, 120, 124], "deem": [19, 113], "nich": 19, "devot": 19, "sustain": 19, "effort": [19, 34], "priorit": 19, "feel": 19, "belong": [19, 77, 92, 103], "mainten": [19, 22, 26, 59], "signific": [19, 28], "margin": 19, "speedup": 19, "wari": 19, "alien": 19, "explan": [19, 35, 38, 40, 43, 80], "meet": 19, "visibl": 19, "appeal": [19, 23], "empow": 19, "outcom": 19, "past": [19, 63], "pep8": 19, "pep257": 19, "neurostar": 19, "monitor": 19, "prove": [20, 76], "uncomfort": 20, "data_packag": 20, "100k": 20, "atlas": [20, 74], "healthi": 20, "beat": 20, "clearer": 20, "0saga": 20, "model": [20, 23, 35, 52, 77, 102, 105], "believ": [20, 38, 40], "abstract": [20, 25, 28, 30, 35, 77, 87, 119, 125], "tree": [20, 22, 26, 44, 79], "enjoy": 20, "subvers": [20, 49], "mercuri": 20, "201": 20, "memor": 20, "restrict": [20, 35, 58, 69, 86], "static": [20, 77, 92, 105], "af5bd6": 20, "deliv": 20, "f745dc2": 20, "zipfil": 20, "server": [20, 26, 35], "home": [20, 26, 42, 45, 56, 85], "discov": [20, 52, 86], "remot": [20, 26, 42, 43, 49, 51, 52, 53], "somewher": [20, 52], "unstabl": [20, 86], "lenni": 20, "contrib": 20, "deb": [20, 57], "11_3": 20, "i386": 20, "12_9": 20, "creation": [20, 28, 62, 79, 81, 124], "adapt": [20, 71, 84, 90, 98, 111, 112, 114], "datapkg": 20, "brief": 20, "plan": [20, 23, 28], "confirm": [20, 35], "verif": [20, 35], "verifi": [20, 69, 117, 118, 119], "apt": [20, 47, 57], "checksum": 20, "gpg": 20, "trust": [20, 23], "encrypt": 20, "decrypt": 20, "persuad": 20, "Their": 20, "share": [20, 69, 70, 79, 90, 102, 117], "cost": [20, 27], "hold": [20, 23, 26, 76, 80, 87, 102, 105, 116, 124], "wherea": [20, 36, 40, 62, 68, 119, 124], "decreas": [20, 35, 66, 77, 103], "ourpkg": 20, "default_registri": 20, "my_pkg_path": 20, "pathfor": 20, "mypkg": 20, "mypkg_path": 20, "runtimeerror": [20, 81, 82], "footnot": [20, 35, 60], "agreement": [20, 23], "background": [21, 25, 54, 60, 97, 126], "overview": [21, 35, 41, 46, 50], "bv": 21, "introduct": [22, 32, 41, 49, 50, 126], "readthedoc": [22, 119], "io": [22, 26, 30, 43, 58, 65, 69, 77, 87, 94, 103, 106, 116, 119, 123, 124], "en": [22, 47, 76, 86, 113, 119], "finish": [22, 26, 43, 52], "dist": [22, 26, 74], "target": [22, 27, 78], "unoffici": 22, "snapshot": [22, 26, 31, 57], "channel": 22, "neurodebian": [22, 57], "elsewher": 22, "clone": [22, 43, 44, 49, 52, 56, 57, 66], "classifi": 22, "bf": [22, 52], "rf": 22, "nf": [22, 42, 43, 93], "bw": 22, "opt": [22, 78], "bk": 22, "pl": 22, "happier": 22, "absorb": 22, "advis": [22, 43, 58], "organ": [22, 43], "isol": 22, "pipx": 22, "iin": 22, "pick": [22, 26, 33, 43], "rapid": 22, "py311": 22, "x86": 22, "adopt": [22, 28], "isort_": 22, "sorter": 22, "group": [22, 23, 35, 40, 77, 102], "stdlib": 22, "parti": [22, 59], "checker": 22, "commit_": 22, "li": 22, "elimin": 22, "argu": 22, "uniformli": 22, "occasion": [22, 23, 124], "blunt": 22, "instrument": 22, "legitim": 22, "misspel": 22, "committ": 22, "toplevel": 22, "appendix": [22, 56], "neither": [22, 58, 123], "macroscop": 22, "perform": [22, 28, 35, 86, 103, 104, 116, 119], "bugtrack": 22, "criteria": 22, "conduct": 22, "particip": [23, 77], "deadlock": 23, "demonstr": 23, "ongo": 23, "vote": 23, "therebi": 23, "effigi": [23, 58], "oesteban": 23, "adher": 23, "nomin": [23, 33], "invit": 23, "lazi": [23, 119], "unanim": 23, "week": [23, 42], "voic": 23, "sc": 23, "strateg": 23, "fund": 23, "grant": [23, 58], "theirs": 23, "pursu": 23, "pictur": 23, "timefram": 23, "mih": 23, "tracker": [23, 28], "seek": [23, 40, 65, 69, 70, 74, 84, 87, 88, 90, 91, 92, 106, 109, 123], "distinguish": [23, 40], "fundament": [23, 28, 35], "perceiv": 23, "flaw": 23, "membership": 23, "land": 23, "confid": 23, "outlin": 23, "mission": 23, "formal": 23, "taken": [23, 41, 58, 77, 109, 115], "advoc": 23, "suffici": [23, 103], "dan": 23, "schult": 23, "changelog": [25, 26, 56, 59, 66], "acknowledg": [25, 26], "And": [25, 30, 69, 87], "roadmap": 25, "recip": 25, "checklist": 25, "advanc": [25, 50, 57, 70], "announc": [26, 56, 102], "outstand": 26, "grep": 26, "cut": 26, "uniq": 26, "shortlog": 26, "ae": [26, 35], "perl": 26, "dedup": 26, "stdin": 26, "_": [26, 38, 40, 107, 120, 123], "stackoverflow": 26, "question": [26, 27, 56, 66, 90], "6482436": 26, "6482473": 26, "mailmap": 26, "nse": 26, "conf": [26, 102], "refresh": [26, 52], "long_descript": 26, "rst2html": 26, "tmp": [26, 43, 120], "numpy_min_vers": 26, "txt": [26, 31, 79, 120], "yml": 26, "buildbot": 26, "try_branch": 26, "nibotmi": 26, "bewar": 26, "bic": 26, "builder": 26, "sdist": 26, "sys_vers": 26, "r266": 26, "84374": 26, "aug": [26, 59], "2010": [26, 40, 58, 59], "00": [26, 109], "51": [26, 109], "gcc": [26, 57], "appl": 26, "inc": [26, 57], "5493": 26, "commit_sourc": 26, "substitut": [26, 58], "np_version": 26, "commit_hash": 26, "25b4125": 26, "pkg_path": 26, "var": [26, 100], "jg": 26, "jgfz12zxhwgsfkd85xlplk": 26, "ti": [26, 92], "tmpgpid3": 26, "pylib": 26, "sys_execut": 26, "app": [26, 57], "sys_platform": 26, "pyc": 26, "mb312": 26, "dev_tre": 26, "bin": [26, 124], "nifti1_diagnos": 26, "everyth": [26, 43, 57, 120], "compileal": 26, "_version_extra": 26, "workon": 26, "python26": 26, "distclean": 26, "deactiv": 26, "zibi": 26, "buildslav": 26, "py2": 26, "osx": [26, 47, 57], "win32": 26, "amd64": 26, "bdist32": 26, "bdist64": 26, "intro": 26, "pypirc": 26, "warehous": 26, "usernam": 26, "password": 26, "legaci": 26, "nuke": 26, "fxd": 26, "gztar": 26, "twine": 26, "trunk": [26, 46, 53], "maint": 26, "bump": 26, "_version_micro": 26, "_version_minor": 26, "discard": [26, 40, 43, 55, 90, 109], "spuriou": 26, "plu": [26, 38, 77, 109, 122], "suffix": [26, 89, 94, 120], "abbrevi": [26, 35], "sha1": 26, "dsc": 26, "orig": [26, 74], "click": [26, 43, 45, 56, 66, 122], "minut": [26, 42], "deposit": 26, "button": [26, 43, 45], "markdown": 26, "5281": 26, "60847": 26, "citabl": 26, "realign": 27, "img1": [27, 66, 115], "meanfunct": 27, "flirt": 27, "param": [27, 102, 103], "source_filenam": 27, "as_filenam": 27, "source_img": 27, "target_filenam": 27, "target_img": 27, "temporari": [27, 120], "diverg": 27, "meantunct": 27, "mkstemp": [27, 64], "node": [27, 103], "farm": 27, "worker": 27, "lightweight": 27, "some_imag": [27, 30, 64], "_cach": 27, "complex64": 27, "quickli": 27, "prohibit": 27, "is_dirti": 27, "magic": [27, 49, 61, 62, 84, 103, 104], "scene": 27, "uncertainti": 27, "month": 28, "workbench": 28, "higher": [28, 69, 76, 82, 102, 103, 104, 123], "task": [28, 35, 43, 94], "broad": 28, "captur": [28, 77], "xarrai": 28, "visual": [28, 43], "layer": [28, 125], "vendor": 28, "lack": [28, 40, 79], "936": 28, "2171": 28, "toolbox": 28, "reus": 28, "itk": [28, 34, 38], "ant": 28, "niftyreg": 28, "nitransform": 28, "research": [28, 31], "aprim": 29, "perfect": 29, "pi": [29, 86, 113, 122], "r_dtype": 29, "s_dtype": 29, "cast_funct": 29, "r_prime": 29, "a_prim": 29, "upcast": [29, 123], "1d": [29, 68, 77, 123], "measur": [29, 33, 35, 90], "vol": 30, "character": 30, "subtl": 30, "spm_vol": 30, "109": 30, "pinfo": 30, "3x1": 30, "descrip": [30, 61, 62, 69, 103, 104, 117, 118], "1x1": 30, "128": [30, 35, 39, 40, 41, 55, 61, 62, 71, 76], "74": 30, "1x2": 30, "spm_type": 30, "ness": [30, 102], "jth": 30, "val": [30, 75, 76], "____________________________________________________________________________": 30, "mex": 30, "spm_map_vol": 30, "spm_unmap_vol": 30, "matlab4": 30, "spm94": 30, "_______________________________________________________________________": 30, "2005": 30, "wellcom": 30, "depart": 30, "neurosci": 30, "dat": 30, "91x109x91": 30, "file_arrai": 30, "mat_int": 30, "mni152": 30, "mat0": 30, "mat0_int": 30, "functional_01": 30, "191x1": 30, "img_arr": [30, 69], "spm_read_vol": 30, "new_fnam": 30, "another_imag": [30, 61], "new_vol": 30, "spm_write_vol": 30, "scratch": 30, "yet_another_imag": 30, "spm_create_vol": 30, "vox_z": 30, "spm_write_plan": 30, "dynam": [30, 33, 35, 103, 109, 113], "15": [30, 35, 41, 59, 61, 62, 84, 97], "hold_val": 30, "spline": [30, 111], "spm_sample_vol": 30, "0510": 30, "0531": 30, "arg": [30, 68, 70, 71, 74, 75, 76, 77, 78, 79, 81, 82, 83, 87, 88, 89, 92, 94, 96, 99, 101, 102, 103, 105, 106, 108, 109, 110, 116, 119, 121, 124, 125], "dy": 30, "dz": 30, "0033": 30, "0012": [30, 31, 33], "0020": [30, 31, 33, 35, 38], "0017": 30, "wc": 30, "48": [30, 42, 62], "5000": [30, 77], "58": 30, "0000": [30, 35], "6792": 30, "odder": 30, "slice_mat": 30, "out_siz": 30, "slice_no": [30, 109], "fetch": [30, 43, 51, 53, 55, 61, 84, 87, 116], "arr_slic": 30, "spm_slice_vol": 30, "img_slice_4": 30, "simplest": [30, 36, 42, 52, 60], "spm_conv_vol": 30, "convolv": 30, "spm_render_vol": 30, "spm_vol_check": 30, "delphi": 31, "pascal": 31, "mricron": [31, 34], "nitrc": [31, 77, 94, 104, 119], "site": [31, 56, 66], "bsd": [31, 34, 56, 66], "lazaru": 31, "freepasc": 31, "mac": [31, 76], "installing_lazarus_on_macos_x": 31, "gave": [31, 41], "carbon": 31, "hu": 31, "macosx_version_min": 31, "k10": 31, "xr": 31, "sdk": 31, "macosx10": 31, "inspir": [31, 68], "neuro": 31, "pool": [31, 38], "dicomfastread": 31, "pa": [31, 109], "dicomcompat": 31, "imagetyp": [31, 40], "datetim": 31, "studyd": 31, "studytim": 31, "dicomtyp": 31, "acquisitionnumb": [31, 40], "echonumb": [31, 40], "presum": [31, 35, 40], "scanningsequ": 31, "seriesnumb": [31, 40], "differenti": 31, "is_4d": 31, "2001": [31, 94], "numberoftemporalposit": 31, "numberoffram": 31, "sortdicom": 31, "shellsortdcm": 31, "dcm1": 31, "dcm2": 31, "instancenumb": [31, 40], "0013": [31, 33], "0011": [31, 33, 35], "ever": [31, 41], "formula": [32, 40, 86, 113], "csa1": 32, "csa2": 32, "spm_dicom_dict": 32, "spm_dicom_head": [32, 34, 39], "spm_dicom_convert": [32, 34], "talk": [33, 60], "modal": [33, 35, 40], "0008": [33, 35], "0060": 33, "equip": [33, 35, 58], "uid": 33, "000e": 33, "0031": 33, "0032": [33, 35, 38], "1041": [33, 38], "unspecifi": [33, 35, 36, 76, 103], "0018": [33, 38], "0050": 33, "0088": [33, 38], "tocent": 33, "tempor": [33, 60, 92], "0100": [33, 35], "0105": 33, "total": [33, 77, 90, 119], "prescrib": 33, "0110": 33, "delta": [33, 38, 40, 92, 123], "0028": [33, 35, 38], "0009": 33, "aspect": [34, 122], "partli": 34, "grassroot": 34, "gdcm": [34, 39], "callabl": [34, 72, 82, 90, 105, 107, 119, 123], "dcm2nii": 34, "battl": 34, "spm8": [34, 39, 40], "gpl": [34, 84], "dicom2nrrd": 34, "nrrd": 34, "ge": [34, 38, 40], "famou": 34, "cookbook": 34, "dicomcookbook": 34, "onlin": [34, 50, 56], "fr": 34, "dicomlink": 34, "barr": 34, "nom": 34, "pubimag": 34, "hcuge": 34, "ch": [34, 58], "8080": 34, "network": [35, 43], "encapsul": [35, 87, 102, 116, 119], "iod": 35, "exchang": 35, "media": 35, "interchang": 35, "physic": 35, "14": [35, 43, 54, 57, 59, 61, 62, 68, 94, 109], "explanatori": 35, "wado": 35, "hl7": 35, "badli": 35, "hexadecim": 35, "0010": [35, 37, 38], "patientnam": 35, "0002": [35, 52], "0004": 35, "0006": 35, "annex": 35, "eeee": 35, "reserv": [35, 58, 77], "0001": [35, 52], "0003": 35, "0005": 35, "0007": 35, "ffff": 35, "collis": 35, "creator": [35, 37, 102], "gggg": 35, "00xx": 35, "portion": [35, 58], "xx": [35, 39], "xx00": 35, "xxff": 35, "0019": 35, "10ff": 35, "greater": [35, 39, 40, 57, 82, 114, 116, 123], "shall": [35, 38, 58], "00ff": 35, "insert": [35, 40, 43, 65, 69, 77, 81, 84, 92, 117, 118, 119, 124], "identif": 35, "unus": [35, 39, 61, 66, 84], "unassign": 35, "vm": [35, 39], "1100": 35, "11ff": 35, "ff00": 35, "unreserv": 35, "AS": [35, 58], "ag": 35, "da": 35, "fl": 35, "fd": [35, 37], "lt": 35, "ob": [35, 39, 40, 123], "OF": [35, 58], "ow": 35, "pn": 35, "sh": 35, "sl": [35, 109], "sq": 35, "ss": [35, 109], "tm": 35, "ui": 35, "ul": 35, "un": 35, "ut": 35, "unlimit": 35, "undefin": [35, 62, 71, 76, 123], "termin": [35, 39, 57, 91], "ffffffffh": 35, "negoti": 35, "excerpt": 35, "patientid": 35, "0021": 35, "issuer": 35, "issuerofpatientid": 35, "0022": 35, "typeofpatientid": 35, "0024": 35, "qualifi": 35, "issuerofpatientidqualifierssequ": 35, "0030": [35, 38], "birth": 35, "patientbirthd": 35, "patientbirthtim": 35, "shorter": 35, "indirectli": 35, "studi": 35, "fiduci": 35, "sr": 35, "waveform": 35, "spectroscopi": [35, 40], "stereometr": 35, "diagram": [35, 102], "atom": [35, 65], "sent": [35, 38, 119], "Such": [35, 72], "inher": 35, "composit": [35, 86], "ct": [35, 40], "classic": 35, "intrins": [35, 86], "serv": 35, "pd": 35, "reson": 35, "clinic": 35, "trial": [35, 84], "bolu": 35, "devic": 35, "specimen": 35, "22": [35, 36, 38, 40, 59, 61, 62], "overlai": 35, "voi": 35, "lut": 35, "compos": [35, 119], "mandatori": 35, "lastli": 35, "macro": 35, "referenc": 35, "0054": [35, 37], "0410": 35, "graviti": 35, "baselin": 35, "0412": 35, "1c": 35, "gantri": 35, "0414": 35, "scu": 35, "client": 35, "scp": 35, "arriv": [35, 94], "null": [35, 39, 102], "iop": [35, 102], "transmit": [35, 38], "preambl": 35, "dicm": [35, 40], "0103": 35, "pylab": 36, "dcm_data": [36, 102], "read_fil": [36, 112], "my_fil": [36, 66], "pixel_arrai": [36, 38], "slab": [36, 102], "n_slice_row": [36, 102], "n_slice_col": [36, 102], "n_slab_row": [36, 102], "n_slab_col": [36, 102], "squar": [36, 40, 102, 113], "n_block": [36, 102], "n_slice": [36, 102], "numberofimagesinmosa": [36, 40, 102], "n_row_block": [36, 102], "n_col_block": [36, 102], "sqrt": [36, 102, 113], "mathbf": [36, 38], "diag": [36, 55, 61, 62, 68, 69, 102, 103, 111, 113, 115, 116, 118], "voxel_arrai": 36, "imageorientationpati": [36, 38, 40], "slicenormalvector": 36, "s_1": 36, "s_2": 36, "pixelspac": [36, 38, 40], "s_3": 36, "spacingbetweenslic": 36, "imagepositionpati": [36, 38, 40], "adjust": [36, 61, 102, 111, 116, 123], "c_x": 36, "c_y": 36, "c_z": 36, "rd_": 36, "col": [36, 114], "md_": 36, "faulti": 36, "rowss": 36, "rs_": 36, "rescaleslop": [36, 40], "rescaleintercept": [36, 40], "henc": [36, 76, 123], "amongst": 37, "ecod": [37, 103], "facilit": 37, "commerci": 37, "pmod": 37, "durat": [37, 103, 120], "0055": 37, "1001": 37, "1004": 37, "nim": 37, "pmod_pet": 37, "dcmext": 37, "bq": 37, "ml": 37, "pmod_1": 37, "13720": 37, "14320": 37, "30000": 37, "600000": 37, "get_cont": [37, 65, 103], "start_tim": 37, "0x0055": 37, "0x1001": 37, "0x1004": 37, "pet": [37, 84], "add_new": 37, "0x0054": 37, "0x0010": 37, "nifti1dicomextens": [37, 65], "pet_withdcm": 37, "Be": 37, "2009": [38, 58, 59], "2210": 38, "bipe": 38, "quadup": 38, "funni": [38, 52, 89], "doctor": 38, "held": 38, "her": 38, "spiderman": 38, "shoot": 38, "palm": 38, "finger": [38, 86], "7fe0": 38, "upper": [38, 123], "remaind": 38, "horizont": 38, "dcluni": 38, "faq": 38, "part2": 38, "cosin": [38, 40, 92], "0037": 38, "dpc": 38, "img_ornt_pat": 38, "rc": [38, 123], "conjunct": 38, "p_x": 38, "p_y": 38, "p_z": 38, "x_x": 38, "y_x": 38, "s_x": 38, "x_y": 38, "y_y": 38, "s_y": 38, "x_z": 38, "y_z": 38, "s_z": 38, "p_": 38, "s_": 38, "x_": 38, "y_": 38, "oh": 38, "dear": 38, "pixar": 38, "sorri": 38, "smallmatrix": [38, 40], "i_1": 38, "i_6": 38, "i_4": 38, "i_5": 38, "i_2": 38, "i_3": 38, "f_": [38, 40], "descend": 38, "k_1": 38, "k_2": 38, "k_3": 38, "n_1": [38, 40], "n_2": [38, 40], "n_3": [38, 40], "cdot": 38, "k_": 38, "frac": 38, "n_": 38, "spm_dicom_ori": [38, 40], "obtain": [38, 58, 74, 77, 80, 119], "proport": [38, 102], "sliceloc": 38, "reliabl": [38, 84], "a_j": 38, "rememb": [38, 43, 51, 80], "inner": 38, "neat": [38, 61, 62], "123": 38, "lambda": [38, 123], "syngo": 39, "0029": [39, 40], "num": 39, "20100114": [39, 40], "1010": 39, "11560": 39, "80248": 39, "csaimageheaderinfo": [39, 40], "whatev": 39, "sv10": 39, "csa_posit": 39, "sensibli": 39, "csa_max_po": 39, "n_tag": [39, 102], "uint32": 39, "abort": [39, 43], "s64": 39, "int32": [39, 76, 84, 93, 103, 123], "s4": [39, 69, 103, 104, 117, 118], "syngodt": 39, "nitem": 39, "item_len": 39, "tp": 39, "next_item_po": 39, "hdr_id": 39, "unused1": [39, 69, 117, 118], "unused2": 39, "filepoint": 39, "januari": [40, 59, 119], "cell": [40, 114], "john": [40, 117], "ahsburn": 40, "ja": 40, "subfunct": 40, "readdicomfil": 40, "po": [40, 87, 88, 106, 116], "read_dicom": 40, "twin": 40, "excit": 40, "fffe": 40, "e00d": 40, "he": 40, "read_tag": 40, "x00x00": 40, "imagedelimitationitem": 40, "ahead": [40, 43], "4294967295": 40, "inf": [40, 76, 103, 117, 118, 119, 123], "reset": [40, 43, 62, 65, 71, 105], "ashburn": [40, 117], "jesper": 40, "andersson": 40, "sopclassuid": 40, "1107": 40, "pt": [40, 68, 119], "startofpixeldata": 40, "samplesperpixel": 40, "bitsalloc": 40, "bitsstor": 40, "highbit": 40, "pixelrespresent": 40, "acquisitionmatrixtext": 40, "ice_dim": 40, "ice1": 40, "ic": [40, 102], "ice2": 40, "iff": [40, 69, 102, 106], "toler": [40, 78, 102, 108], "1e": [40, 102, 113], "sequencenam": 40, "seriesinstanceuid": 40, "z_dir_co": 40, "caught": 40, "recalcul": 40, "gap": [40, 76, 90, 109], "subtract": [40, 71, 123], "averag": 40, "work_list": 40, "bail": 40, "relic": 40, "is_process": 40, "hdr_vol_out": 40, "hdr_to_check": 40, "z_same_indic": 40, "zsind": 40, "emit": [40, 81, 109], "confusingli": [40, 60, 86], "dealt": 40, "analyze_to_dicom": 40, "grow": 41, "peculiar": 41, "data_path": [41, 54, 55, 61, 62, 79, 80], "example4d": [41, 54, 55, 61, 62, 74, 80], "example_filenam": 41, "96": [41, 55, 61, 62], "get_xyzt_unit": [41, 65, 103], "sec": 41, "setter": 41, "complianc": 41, "courag": 41, "structarr": [41, 65, 69, 124], "lowest": [41, 109], "safeti": 41, "trivial": [41, 106], "test4d": 41, "quick": [41, 52, 55, 78], "gitconfig": 42, "yourdomain": [42, 52], "br": 42, "wdiff": 42, "vim": 42, "shorten": 42, "lg": [42, 43], "cred": 42, "creset": 42, "cgreen": 42, "cr": 42, "abbrev": 42, "6d8e1e": 42, "ago": 42, "d304a73": 42, "hhuuggoo": 42, "terhorst": 42, "4aff2a8": 42, "test_bugfix": 42, "hugo": 42, "a7ff2e5": 42, "summit": 42, "corran": 42, "webster": 42, "68f6752": 42, "axisindex": 42, "index_bi": 42, "sketchi": 42, "corr": 42, "376adbd": 42, "b605216": 42, "joshu": 42, "2e991e8": 42, "outer": [42, 122], "7beda5a": 42, "throw": [42, 55, 69, 90], "65af65": 42, "956fbab": 42, "yuri": 42, "zaytsev": 42, "fork": [43, 46, 50, 52], "ipython": [43, 61, 119], "stuck": 43, "linux": [43, 49, 57], "strang": [43, 96, 102], "branchnam": 43, "fly": [43, 124], "buxfix": 43, "my_new_fil": 43, "am": [43, 52, 74], "ny": [43, 77], "untrack": 43, "new_file_nam": 43, "faith": [43, 52], "tangl": 43, "dropdown": 43, "menu": 43, "enter": [43, 123], "attent": 43, "happi": [43, 92, 109], "unwant": 43, "colon": 43, "account": [43, 46, 102, 109, 116], "admin": 43, "collabor": 43, "githhub": 43, "enh": 43, "graphic": [43, 60, 86], "gitk": 43, "cool": [43, 51], "meantim": 43, "sternli": 43, "messi": 43, "harmon": [43, 77, 103, 116], "replai": 43, "tear": 43, "backup": 43, "succinctli": 43, "man": 43, "luckili": 43, "notic": [43, 58], "forgot": 43, "reflog": 43, "8630830": 43, "immedi": [43, 61, 80, 92], "278dd2a": 43, "11ee694744f2552d": 43, "26aa21a": 43, "lib": [43, 84], "seek_gzip_factori": 43, "obj": [43, 69, 70, 71, 72, 74, 78, 80, 92, 99, 100, 103, 104, 109, 116, 117, 118, 119, 121, 123], "botch": 43, "embarrass": 43, "poster": 43, "suppos": 43, "onelin": [43, 51], "eadc391": 43, "a815645": 43, "2dec1ac": 43, "13d7934": 43, "6ad92e5": 43, "maskedconst": 43, "29001ed": 43, "nep": 43, "copul": 43, "structured_array_extens": 43, "editor": [43, 86], "reword": 43, "amend": 43, "squash": 43, "meld": 43, "fixup": 43, "THAT": 43, "WILL": 43, "BE": [43, 58], "ii": 43, "collaps": [43, 116], "detach": 43, "721fc64": 43, "foo": [43, 89], "199": 43, "0f22701": 43, "79": 43, "successfulli": 43, "went": 43, "recoveri": 43, "cd": [44, 52, 53, 56, 66], "articl": [45, 76], "paus": 45, "hardcor": 45, "mirror": 46, "ubuntu": [47, 59, 79], "sudo": [47, 57], "fedora": 47, "yum": 47, "msysgit": 47, "scm": 47, "book": [47, 49], "tailor": 48, "servic": [48, 58, 126], "quicker": [48, 90], "pro": 49, "sheet": 49, "video": 49, "snippet": [49, 56, 58, 125], "tos": 49, "intermedi": [49, 90], "parabl": 49, "concept": [49, 56, 123], "foundat": 49, "tip": 49, "svn": 49, "linu": 49, "torvald": 49, "scari": 51, "rebas": 51, "ff": 51, "rejoin": 51, "compact": [51, 62], "quickest": 52, "test_my_bug": 52, "warmli": 52, "deliber": [53, 60], "satisfact": 53, "voxel_data": 54, "single_line_axis_0": 54, "single_line_axis_1": 54, "single_line_axis_2": 54, "example_fil": [54, 55, 61, 120], "117": [54, 61, 62], "72": [54, 61, 62], "aff2axcod": [54, 61, 65], "rearrang": 54, "as_closest_canon": [54, 65], "canonical_img": [54, 93], "136": 54, "wait": [55, 87], "data_again": [55, 61, 80], "array_data": [55, 61, 62], "array_img": [55, 61, 62], "data_once_mor": 55, "proxy_img": 55, "data_arrai": 55, "unchang": [55, 61, 80, 103, 116], "awai": [55, 69, 70, 90], "plain": [56, 66], "spm99": [56, 66, 118], "spm2": [56, 66, 117], "brik": [56, 66, 74], "pytest_": 56, "pyarg": [56, 57, 66], "search": [56, 79, 89, 91, 102], "offlin": 56, "rough": 56, "bertrand": 56, "thirion": 56, "balling": 56, "valentin": 56, "haenel": 56, "satrajit": 56, "gervai": 56, "justin": 56, "lecher": 56, "oliv": 56, "hind": 56, "kevin": 56, "hahn": 56, "erik": 56, "fischer": 56, "syam": 56, "gadd": 56, "garc\u00eda": 56, "s\u00f3lon": 56, "beer": 56, "speech": 56, "subscript": [56, 102], "subscrib": 56, "sidebar": 56, "rpm": 57, "cmd": 57, "powershel": 57, "permiss": [57, 58], "importlib": 57, "aka": 57, "invok": 57, "fire": [57, 105], "sep": [57, 59, 78], "anaconda": 57, "credit": 57, "2019": [58, 59], "gmail": 58, "unidesign": 58, "2006": [58, 59, 86, 102], "2014": [58, 59, 119], "umassm": 58, "onerussian": 58, "herebi": 58, "charg": 58, "sublicens": 58, "sell": 58, "whom": 58, "furnish": 58, "THE": 58, "warranti": 58, "BUT": 58, "TO": 58, "merchant": 58, "FOR": 58, "AND": [58, 117], "noninfring": 58, "IN": 58, "NO": 58, "holder": [58, 87, 116], "liabl": 58, "liabil": 58, "contract": 58, "tort": 58, "aris": [58, 86, 90], "WITH": 58, "1999": 58, "redistribut": 58, "met": 58, "disclaim": 58, "materi": 58, "enthought": 58, "endors": 58, "BY": 58, "regent": 58, "indirect": 58, "incident": 58, "exemplari": 58, "consequenti": 58, "procur": 58, "profit": 58, "busi": 58, "interrupt": [58, 90], "ON": 58, "neglig": 58, "IF": 58, "SUCH": 58, "jul": [58, 59], "2007": [58, 59], "stefan": 58, "der": 58, "walt": 58, "oset": 58, "pythonhost": 58, "d6": 58, "b1": 58, "a49498c699a3fda5d635cc1fa222ffc686ea3b5d04b84a3166c4cab0c57b": 58, "tar": 58, "raymond": [58, 105], "hetting": [58, 105], "odict": 58, "bluedynam": 58, "allianc": 58, "austria": 58, "subsampl": [58, 116], "softwwar": 58, "1993": 58, "2004": 58, "loui": 58, "collin": 58, "mcconnel": 58, "centr": 58, "mcgill": 58, "fee": 58, "injuri": 58, "misus": 58, "phantom_epi_asc_clear_2_1": [58, 109], "phantom_epi_3mm_cor_20aptrans_15rlrot_sense_15_1": 58, "phantom_epi_3mm_cor_sense_8_1": 58, "phantom_epi_3mm_sag_15ap_sense_13_1": 58, "phantom_epi_3mm_sag_15fh_sense_12_1": 58, "phantom_epi_3mm_sag_15rl_sense_11_1": 58, "phantom_epi_3mm_sag_sense_7_1": 58, "phantom_epi_3mm_tra_": 58, "30ap_10rl_20fh_sense_14_1": 58, "phantom_epi_3mm_tra_15fh_sense_9_1": 58, "phantom_epi_3mm_tra_15rl_sense_10_1": 58, "phantom_epi_3mm_tra_sense_6_1": 58, "psydata": 58, "ovgu": 58, "philips_achieva_testfil": 58, "opendatacommon": 58, "dti": 58, "na": [58, 75, 77], "t1": [58, 89], "t2": [58, 89], "interleav": 58, "t2_": 58, "fieldmap": 58, "umass_anonym": 58, "courtesi": 58, "massachusett": 58, "school": 58, "fall": [59, 102, 103], "autosummari": 59, "orderedset": [59, 123], "mni_icbm152_t1_tal_nlin_asym_09a": 59, "mondai": 59, "decemb": 59, "2023": 59, "sundai": 59, "februari": 59, "wednesdai": 59, "august": 59, "2022": 59, "saturdai": 59, "june": 59, "novemb": 59, "tuesdai": 59, "octob": 59, "fridai": 59, "march": 59, "septemb": 59, "2017": 59, "2016": [59, 102], "thursdai": 59, "feb": 59, "oct": 59, "pynifti": 59, "20100706": 59, "tue": 59, "20100412": 59, "mon": 59, "apr": 59, "20090303": 59, "mar": 59, "20090205": 59, "20081017": 59, "fri": 59, "2008": 59, "20080710": 59, "20080630": 59, "jun": 59, "20080624": 59, "20070930": 59, "sun": 59, "20070917": 59, "20070905": 59, "wed": 59, "20070803": 59, "20070425": 59, "20070315": 59, "20070301": 59, "20070220": 59, "20070214": 59, "20061114": 59, "nov": 59, "radiologist": [60, 69], "feet": 60, "neurologist": [60, 69], "tast": 60, "stroke": 60, "lobe": 60, "dark": 60, "movement": [60, 122], "3x3": [60, 86, 113], "diag_affin": 60, "ijk": [60, 77], "screen": 60, "img_data": 60, "75": [60, 102], "a_slic": 60, "neurologi": 60, "commonli": [60, 116], "nipyer": 60, "conceptu": 60, "bear": 60, "radiog": 60, "exclus": [60, 74], "tab": 61, "nifti1head": [61, 62, 65, 104, 109], "sizeof_hdr": [61, 62, 65, 69, 103, 104, 117, 118], "data_typ": [61, 62, 69, 103, 117, 118], "db_name": [61, 62, 69, 103, 117, 118], "session_error": [61, 62, 69, 103, 117, 118], "intent_p1": [61, 62, 103, 104], "intent_p2": [61, 62, 103, 104], "intent_p3": [61, 62, 103, 104], "intent_cod": [61, 62, 94, 103, 104], "bitpix": [61, 62, 69, 72, 103, 104, 117, 118], "2000": [61, 62, 113], "vox_offset": [61, 62, 69, 103, 104, 117, 118], "scl_slope": [61, 62, 103, 104, 117, 118], "scl_inter": [61, 62, 103, 104, 117], "1162": [61, 62], "slice_dur": [61, 62, 69, 103, 104], "glmax": [61, 62, 69, 103, 117, 118], "glmin": [61, 62, 69, 103, 117, 118], "fsl3": [61, 62], "x00": [61, 62], "aux_fil": [61, 62, 69, 103, 104, 117, 118], "quatern_b": [61, 62, 103, 104], "94510681403e": [61, 62], "quatern_c": [61, 62, 103, 104], "996708512306": [61, 62], "quatern_d": [61, 62, 103, 104], "081068739295": [61, 62], "qoffset_x": [61, 62, 103, 104], "855102539": [61, 62], "qoffset_i": [61, 62, 103, 104], "7229423523": [61, 62], "qoffset_z": [61, 62, 103, 104], "24879837036": [61, 62], "srow_x": [61, 62, 103, 104], "srow_i": [61, 62, 103, 104], "srow_z": [61, 62, 103, 104], "intent_nam": [61, 62, 103, 104], "get_zoom": [61, 65, 69, 74, 84, 92, 99, 103, 104, 116], "19999": 61, "image_data": [61, 119], "farray_img": 61, "farray_data": 61, "cropped_img": 61, "array_equ": [61, 74, 94], "64mm": 61, "induc": 61, "spectrum": 61, "399998": 61, "img_again": 61, "my_image_again": 61, "set_filenam": [61, 65, 87], "pair_img": 61, "nifti1pair": [61, 65, 104], "my_pair_imag": 61, "ana_img": 61, "analyzeimag": [61, 65, 87, 103, 116, 118], "analyze_imag": 61, "example_ni1": 62, "n1_img": 62, "example_ni2": 62, "example_nifti2": 62, "n2_img": 62, "nifti2imag": [62, 65], "n1_header": 62, "540": [62, 104], "n2_header": 62, "nifti2head": [62, 65, 77], "eol_check": [62, 104], "unused_str": [62, 104], "set_": 62, "overal": 62, "get_sform": [62, 65, 103], "set_sform": [62, 65, 103, 104], "qfac": 62, "get_qform": [62, 65, 103], "set_qform": [62, 65, 103, 104], "resort": [62, 102], "nibabbl": 62, "central": [62, 68, 102, 118], "get_base_affin": [62, 65, 69, 116], "127": [62, 76], "get_best_affin": [62, 65, 69, 92, 103, 116, 118], "initialis": [62, 103, 104], "newli": 62, "furthermor": 62, "unabl": 62, "shear": [62, 68, 103], "uninitialis": 62, "new_data": 62, "new_img": 62, "array_head": 62, "get_slope_int": [62, 65, 69, 70, 74, 92, 103, 117, 118], "set_slope_int": [62, 65, 69, 103, 118], "scaled_imag": 62, "scaled_img": 62, "50": [62, 72, 96], "optimum": 62, "ata": 63, "medit": 64, "fusion": 64, "novel": 64, "hous": 64, "fp": [64, 109], "traceback": [64, 69, 71, 76, 103, 107, 121, 123, 124], "imageerror": 64, "filespec": [64, 74, 80, 84, 87, 89, 92, 98], "futz": 64, "img3": [64, 66, 116], "img4": 64, "mod_data": 64, "img5": 64, "fname2": 64, "set_filespec": 64, "ioimp": 64, "guessed_imp": 64, "fname3": 64, "set_data_shap": [64, 65, 69, 92, 103, 104, 116, 117, 118], "slice_def": 64, "write_slic": 64, "imageioerror": 64, "citat": 65, "quickstart": 65, "bench": [65, 73], "get_info": 65, "affineerror": 65, "append_diag": 65, "dot_reduc": 65, "from_matvec": 65, "to_matvec": [65, 115], "analyzehead": [65, 72, 117, 118], "as_analyze_map": [65, 69, 109], "data_from_fileobj": [65, 69, 84, 92, 99, 116], "data_to_fileobj": [65, 69, 99, 116], "default_structarr": [65, 69, 84, 92, 103, 104, 118, 124], "default_x_flip": [65, 69, 116, 118], "from_head": [65, 69, 74, 87, 92, 103, 109, 116], "get_data_offset": [65, 69, 70, 74, 92, 109], "guessed_endian": [65, 69, 84, 92, 124], "has_data_intercept": [65, 69, 103, 118], "has_data_slop": [65, 69, 103, 118], "may_contain_head": [65, 69, 77, 99, 100, 103, 104, 117], "raw_data_from_fileobj": [65, 69, 84], "set_data_offset": [65, 69, 109], "set_zoom": [65, 69, 92, 116, 118], "template_dtyp": [65, 69, 84, 92, 103, 104, 117, 118, 124], "imagearrayproxi": [65, 69, 74, 84, 92, 99, 109], "files_typ": [65, 69, 74, 77, 84, 87, 92, 94, 99, 103, 109, 118], "header_class": [65, 69, 74, 77, 84, 87, 92, 99, 100, 103, 104, 109, 116, 117, 118], "makeabl": [65, 69, 74, 77, 87, 92, 99, 109, 118], "to_file_map": [65, 69, 77, 84, 87, 92, 94, 103, 116, 118], "valid_ext": [65, 69, 74, 77, 84, 87, 92, 94, 99, 103, 106, 109], "arraylik": [65, 74, 80, 99, 100, 109, 116, 123], "get_obj_dtyp": 65, "reshape_dataobj": 65, "finite_rang": [65, 71, 73], "has_nan": [65, 71, 123], "out_dtyp": [65, 71, 123], "scaling_need": [65, 71], "scalingerror": 65, "slopearraywrit": 65, "calc_scal": [65, 71], "slopeinterarraywrit": 65, "writererror": 65, "make_array_writ": 65, "check_fix": [65, 72, 124], "check_onli": [65, 72], "log_rais": [65, 72, 96], "write_rais": [65, 72], "bench_array_to_fil": 65, "bench_arrayproxy_sl": 65, "bench_fileslic": [65, 90], "bench_finite_rang": 65, "bench_load_sav": 65, "butil": 65, "run_slic": 65, "print_git_titl": 65, "afniarrayproxi": 65, "afnihead": 65, "from_fileobj": [65, 74, 87, 92, 103, 109, 124], "get_data_sc": [65, 74, 109], "get_spac": [65, 74], "get_volume_label": [65, 74, 109], "afniheadererror": 65, "afniimag": 65, "filespec_to_file_map": [65, 74, 87, 92], "afniimageerror": 65, "parse_afni_head": 65, "caretmetadata": [65, 77, 94], "castingerror": 65, "floatingerror": 65, "able_int_typ": 65, "best_float": 65, "ceil_exact": 65, "float_to_int": 65, "floor_exact": 65, "floor_log2": 65, "have_binary128": 65, "int_ab": 65, "longdouble_lte_float64": 65, "longdouble_precision_improv": 65, "ok_float": 65, "on_powerpc": 65, "shared_rang": 65, "type_info": 65, "ulp": 65, "cifti2_ax": 65, "parse_cifti2": 65, "cifti2brainmodel": 65, "vertex_indic": [65, 77], "voxel_indices_ijk": [65, 77], "cifti2head": 65, "from_ax": [65, 77], "get_axi": [65, 77], "get_index_map": [65, 77], "mapped_indic": [65, 77], "number_of_mapped_indic": [65, 77], "cifti2headererror": 65, "from_imag": [65, 77, 84, 87, 110, 116], "nifti_head": [65, 77], "update_head": [65, 77, 103, 116], "cifti2label": 65, "rgba": [65, 77, 94], "cifti2labelt": 65, "cifti2matrix": 65, "cifti2matrixindicesmap": 65, "brain_model": [65, 77], "named_map": [65, 77], "difference_upd": [65, 77], "cifti2namedmap": 65, "label_t": [65, 77], "cifti2parcel": 65, "append_cifti_vertic": [65, 77], "pop_cifti2_vertic": [65, 77], "cifti2surfac": 65, "cifti2transformationmatrixvoxelindicesijktoxyz": 65, "cifti2vertexindic": 65, "cifti2vertic": 65, "cifti2volum": 65, "cifti2voxelindicesijk": 65, "limitednifti2head": 65, "from_index_map": 65, "from_mask": [65, 77, 110], "from_surfac": [65, 77], "get_el": [65, 77], "iter_structur": [65, 77], "surface_mask": [65, 77], "to_cifti_brain_structure_nam": [65, 77], "to_map": [65, 77], "volume_mask": [65, 77], "volume_shap": [65, 77], "labelaxi": 65, "from_brain_model": [65, 77], "scalaraxi": 65, "seriesaxi": 65, "to_head": 65, "cifti2extens": 65, "cifti2pars": 65, "characterdatahandl": [65, 77, 94, 125], "endelementhandl": [65, 77, 94, 125], "startelementhandl": [65, 77, 94, 125], "flush_chardata": [65, 77, 94], "pending_data": [65, 77, 94], "nifti_dx": 65, "tck2trk": 65, "trk2tck": 65, "get_path": [65, 78], "getattr": [65, 78], "match_path": [65, 78], "readdir": [65, 78], "dummy_fus": 65, "fuse_python_api": [65, 78], "get_opt_pars": 65, "are_values_differ": 65, "display_diff": 65, "get_data_diff": 65, "get_data_hash_diff": 65, "get_headers_diff": 65, "proc_fil": 65, "verbos": [65, 66, 77, 94, 125], "lossless_slic": 65, "parse_slic": 65, "sanit": 65, "parse_arg": 65, "ap": [65, 79, 109], "safe_get": 65, "table2str": 65, "bomber": 65, "bombererror": 65, "datasourc": 65, "list_fil": [65, 79], "versioneddatasourc": 65, "datasource_or_bomb": 65, "find_data_dir": 65, "get_data_path": 65, "make_datasourc": 65, "futurewarningmixin": 65, "warn_messag": [65, 81], "moduleproxi": 65, "visibledeprecationwarn": 65, "alert_future_error": 65, "is_bad_vers": [65, 82], "cachingerror": 65, "dfterror": 65, "instancestackerror": 65, "volumeerror": 65, "clear_cach": 65, "get_studi": 65, "update_cach": 65, "ecathead": 65, "get_filetyp": [65, 84], "get_patient_ori": [65, 84], "ecatimag": 65, "get_fram": [65, 84], "get_frame_affin": [65, 84], "get_mlist": [65, 84], "get_subhead": [65, 84], "subheader_class": [65, 84], "ecatimagearrayproxi": 65, "ecatsubhead": 65, "get_nfram": [65, 84], "get_frame_ord": 65, "get_series_framenumb": 65, "read_mlist": 65, "read_subhead": 65, "get_home_dir": 65, "get_nipy_system_dir": [65, 79], "get_nipy_user_dir": [65, 79], "angle_axis2eul": 65, "euler2angle_axi": 65, "euler2mat": 65, "euler2quat": 65, "mat2eul": 65, "quat2eul": 65, "filebasedhead": [65, 74, 77, 80, 99, 100, 109, 116, 125], "write_to": [65, 87, 103, 124], "instance_to_filenam": [65, 87, 116], "make_file_map": [65, 87, 116], "path_maybe_imag": [65, 87], "imagefileerror": [65, 74, 92, 103, 104], "file_lik": [65, 70, 73, 74, 88, 92, 102, 109], "get_prepare_fileobj": [65, 88], "same_file_a": [65, 88], "fileholdererror": 65, "copy_file_map": 65, "typesfilenameserror": 65, "parse_filenam": 65, "splitext_addext": 65, "types_filenam": 65, "calc_slicedef": 65, "canonical_slic": 65, "fill_slic": 65, "is_fanc": 65, "optimize_read_slic": 65, "optimize_slic": 65, "predict_shap": 65, "read_seg": 65, "slice2len": 65, "slice2outax": 65, "slicers2seg": 65, "strided_scalar": 65, "threshold_heurist": 65, "read_zt_byte_str": 65, "mghformat": 65, "write_annot": 65, "mgherror": 65, "mghheader": 65, "as_byteswap": [65, 92, 124], "chk_version": [65, 92], "diagnose_binaryblock": [65, 92, 124], "get_data_bytespervox": [65, 92], "get_data_s": [65, 92], "get_footer_offset": [65, 92], "get_ras2vox": [65, 92], "get_vox2ra": [65, 92], "get_vox2ras_tkr": [65, 92], "writeftr_to": [65, 92], "writehdr_to": [65, 92], "squeeze_imag": 65, "gifticoordsystem": 65, "print_summari": [65, 94], "add_gifti_data_arrai": [65, 94], "get_arrays_from_int": [65, 94], "labelt": [65, 77, 94], "numda": [65, 94], "remove_gifti_data_arrai": [65, 94], "remove_gifti_data_array_by_int": [65, 94], "giftilabel": 65, "giftilabelt": 65, "get_labels_as_dict": [65, 94], "from_dict": [65, 94], "giftinvpair": 65, "giftiparseerror": 65, "read_data_block": 65, "spatial_axes_first": 65, "errorlevel": 65, "loggingoutputsuppressor": 65, "count_nonzero_voxel": 65, "mask_volum": 65, "get_scaled_data": [65, 99, 100], "minc1head": 65, "mincerror": 65, "minchead": [65, 100], "data_layout": [65, 99, 116], "mincimagearrayproxi": 65, "hdf5bunch": 65, "minc2fil": 65, "minc2head": 65, "minc2imag": 65, "mrierror": 65, "calculate_dwell_tim": 65, "csaread": 65, "dicomread": 65, "dwiparam": 65, "structread": 65, "ascconvparseerror": 65, "novalu": 65, "assign2atom": 65, "obj_from_atom": 65, "parse_ascconv": 65, "csaerror": 65, "csareaderror": 65, "get_acq_mat_txt": 65, "get_b_matrix": 65, "get_b_valu": 65, "get_csa_head": 65, "get_g_vector": 65, "get_ice_dim": 65, "get_n_mosa": 65, "get_scalar": 65, "get_slice_norm": 65, "get_vector": 65, "is_mosa": 65, "nt_str": 65, "dicomreaderror": 65, "mosaic_to_nii": 65, "read_mosaic_dir": 65, "read_mosaic_dwi_dir": 65, "slices_to_seri": 65, "mosaicwrapp": 65, "image_posit": [65, 102], "image_shap": [65, 102], "multiframewrapp": 65, "image_orient_pati": [65, 102], "is_multifram": [65, 102], "series_signatur": [65, 102], "siemenswrapp": 65, "b_matrix": [65, 102], "is_csa": [65, 102], "q_vector": [65, 102, 109], "slice_norm": [65, 102], "b_valu": [65, 102], "b_vector": [65, 102, 109], "get_pixel_arrai": [65, 102], "instance_numb": [65, 102], "is_same_seri": [65, 102], "rotation_matrix": [65, 86, 102, 113], "slice_ind": [65, 102], "wrappererror": 65, "wrapperprecisionerror": 65, "none_or_clos": 65, "wrapper_from_data": 65, "wrapper_from_fil": 65, "b2q": 65, "nearest_pos_semi_def": 65, "q2bg": 65, "find_private_sect": 65, "get_cod": [65, 103], "get_sizeondisk": [65, 103], "count": [65, 84, 97, 103, 123], "exts_klass": [65, 103], "get_dim_info": [65, 103], "get_int": [65, 103], "get_n_slic": [65, 103], "get_qform_quaternion": [65, 103], "get_slice_dur": [65, 103], "get_slice_tim": [65, 103], "is_singl": [65, 103, 104], "pair_mag": [65, 103, 104], "pair_vox_offset": [65, 103, 104], "quaternion_threshold": [65, 103, 104], "set_dim_info": [65, 103], "set_int": [65, 103], "set_slice_dur": [65, 103], "set_slice_tim": [65, 103], "set_xyzt_unit": [65, 103], "single_mag": [65, 103, 104], "single_vox_offset": [65, 103, 104], "as_reori": [65, 103, 116], "nifti1pairhead": 65, "nifti2pair": 65, "nifti2pairhead": 65, "onetimeproperti": 65, "resetmixin": 65, "deterministicgzipfil": 65, "fileish": 65, "imageopen": [65, 88], "compress_ext_map": [65, 106], "bz2_def": [65, 106], "close_if_min": [65, 106], "compress_ext_icas": [65, 106], "default_compresslevel": [65, 106], "default_level_or_opt": [65, 106], "default_zst_compresslevel": [65, 106], "fileno": [65, 106], "gz_def": [65, 106], "zstd_def": [65, 106], "optional_packag": 65, "orientationerror": 65, "apply_orient": 65, "axcodes2ornt": 65, "inv_ornt_aff": 65, "io_orient": 65, "ornt2axcod": 65, "ornt_transform": 65, "parrecarrayproxi": 65, "parrecerror": 65, "parrechead": 65, "get_bvals_bvec": [65, 109], "get_def": [65, 109], "get_echo_train_length": [65, 109], "get_q_vector": [65, 109], "get_rec_shap": [65, 109], "get_slice_orient": [65, 109], "get_sorted_slice_indic": [65, 109], "get_water_fat_shift": [65, 109], "exts2par": 65, "one_lin": 65, "parse_par_head": 65, "vol_is_ful": 65, "vol_numb": 65, "coordinatearrai": 65, "to_mask": [65, 110], "gridindic": 65, "gridshap": [65, 110], "adapt_affin": 65, "fwhm2sigma": 65, "resample_from_to": 65, "resample_to_output": 65, "sigma2fwhm": 65, "smooth_imag": 65, "dicom_test": 65, "angle_axis2mat": [65, 86], "angle_axis2quat": 65, "conjug": 65, "fillposit": 65, "invers": [65, 77, 92, 126], "isunit": 65, "mat2quat": 65, "mult": 65, "nearly_equival": 65, "norm": [65, 86, 102], "quat2angle_axi": 65, "quat2mat": [65, 86], "rotate_vector": 65, "rst_tabl": 65, "slice2volum": 65, "vox2out_vox": 65, "hasdtyp": 65, "headerdataerror": [65, 69, 72, 74, 103, 118], "headertypeerror": [65, 69], "imagedataerror": [65, 74], "spatialfirstslic": 65, "check_slic": [65, 116], "slice_affin": [65, 116], "imageslic": [65, 116], "spatialprotocol": 65, "supported_np_typ": 65, "spm2analyzehead": 65, "spm2analyzeimag": 65, "spm99analyzehead": [65, 117], "get_origin_affin": [65, 118], "set_origin_from_affin": [65, 118], "spm99analyzeimag": [65, 117], "has_affin": [65, 118], "spmanalyzehead": [65, 103], "array_sequ": 65, "tractogram_fil": 65, "is_support": 65, "common_shap": [65, 119], "finalize_append": [65, 119], "is_array_sequ": 65, "is_sliced_view": [65, 119], "shrink_data": [65, 119], "total_nb_row": [65, 119], "create_arraysequences_from_gener": 65, "is_ndarray_of_int_or_bool": 65, "magic_numb": [65, 84, 119], "nb_point": [65, 119], "nb_properties_per_streamlin": [65, 119], "nb_scalars_per_point": [65, 119], "nb_streamlin": [65, 119], "step_siz": [65, 119], "voxel_to_rasmm": [65, 119], "eof_delimit": [65, 119], "fiber_delimit": [65, 119], "supports_data_per_point": [65, 119], "supports_data_per_streamlin": [65, 119], "create_empty_head": [65, 119], "lazydict": 65, "data_per_point": [65, 119], "data_per_streamlin": [65, 119], "from_data_func": [65, 119], "from_tractogram": [65, 119], "to_world": [65, 119], "perarraydict": 65, "perarraysequencedict": 65, "sliceabledatadict": 65, "affine_to_rasmm": [65, 119], "tractogramitem": 65, "is_data_dict": 65, "is_lazy_dict": 65, "datawarn": 65, "extensionwarn": 65, "headerwarn": 65, "tractogramfil": 65, "abstractclassmethod": 65, "header_s": [65, 119], "decode_value_from_nam": 65, "encode_value_in_nam": 65, "get_affine_rasmm_to_trackvi": 65, "get_affine_trackvis_to_rasmm": 65, "get_affine_from_refer": 65, "peek_next": 65, "ingivendirectori": 65, "is_tripwir": 65, "clim": [65, 122], "link_to": [65, 122], "n_volum": [65, 122], "set_posit": [65, 122], "set_volume_idx": [65, 122], "dtypemapp": 65, "add_cod": [65, 123], "value_set": [65, 123], "apply_read_sc": 65, "array_from_fil": 65, "best_write_scale_ftyp": 65, "better_float_of": 65, "fname_ext_ul_cas": 65, "int_scinter_ftyp": 65, "make_dt_cod": 65, "pretty_map": 65, "rec2dict": 65, "seek_tel": 65, "shape_zoom_affin": 65, "working_typ": 65, "write_zero": 65, "mapping": 65, "labeledwrapstruct": [65, 69, 92], "get_value_label": [65, 103, 124], "binaryblock": [65, 69, 77, 84, 92, 99, 100, 103, 104, 117, 118, 124], "wrapstructerror": 65, "xmlbasedhead": 65, "xmlparser": [65, 77, 94], "handler_nam": [65, 125], "xmlserializ": [65, 75, 77, 94], "other_fil": 66, "spm_file": 66, "my_file_copi": 66, "new_imag": 66, "extra_argv": 66, "mimic": 66, "nosetest": 66, "exitcod": 66, "raise_warn": 66, "timer": 66, "bool": [66, 68, 69, 71, 74, 77, 79, 80, 82, 86, 87, 88, 89, 90, 92, 95, 99, 102, 103, 106, 107, 109, 110, 113, 116, 117, 118, 121, 123, 124], "nxm": 68, "aff_plu": 68, "inplac": [68, 72], "transformed_pt": 68, "contrari": 68, "freshli": 68, "dot_product": 68, "cardin": 68, "new_shap": 68, "nxn": 68, "4x3": 68, "v0": 68, "v1_ax1": 68, "tran": [68, 115], "rz": [68, 115], "euclidean": [68, 102], "vox_siz": 68, "mayo": 69, "apart": [69, 90], "inabl": 69, "rightmost": 69, "proceed": 69, "hdr1": [69, 117, 118], "native_cod": [69, 117, 118, 124], "binblock2": [69, 117, 118], "hdr2": [69, 117, 118], "opposit": [69, 108, 117, 118, 123], "hdr3": [69, 117, 118], "swapped_cod": [69, 117, 118, 124], "binblock3": [69, 117, 118], "hdr4": [69, 117, 118], "analyze_map": 69, "bytesio": [69, 87, 103, 106, 116, 123, 124], "str_io": [69, 103, 124], "tobyt": [69, 123], "getvalu": [69, 103, 123, 124], "fresh": [69, 103], "hdr_data": 69, "header_dtyp": 69, "sw_hdr_data": 69, "byteswap": [69, 103, 123, 124], "blank": [69, 84], "tie": 69, "breaker": 69, "1543569408": 69, "though": 69, "implaus": [69, 103], "void": [69, 72, 103], "s10": [69, 84, 103, 117, 118, 123], "s18": [69, 103, 117, 118], "i2": [69, 74, 92, 103, 104, 117, 118, 123, 124], "s1": [69, 84, 103, 117, 118], "hkey_un0": [69, 117, 118], "vox_unit": [69, 117, 118], "cal_unit": [69, 117, 118], "s8": [69, 84, 117, 118], "dim_un0": [69, 117, 118], "f4": [69, 76, 84, 87, 92, 103, 116, 117, 118], "funused1": 69, "funused2": [69, 118], "funused3": [69, 117, 118], "s80": [69, 103, 104, 117, 118], "s24": [69, 103, 104, 117, 118], "scannum": [69, 117, 118], "patient_id": [69, 84, 117, 118], "exp_dat": [69, 117, 118], "exp_tim": [69, 117, 118], "hist_un0": [69, 117, 118], "s3": [69, 117, 118], "vols_ad": [69, 117, 118], "start_field": [69, 117, 118], "field_skip": [69, 117, 118], "omax": [69, 117, 118], "omin": [69, 117, 118], "smax": [69, 117, 118], "smin": [69, 117, 118], "kai": [69, 80, 92, 99, 100, 118], "file_typ": [69, 80, 84, 87, 92, 99, 100, 118], "lifetim": [69, 70, 74, 80, 84, 92, 99, 100, 118], "prox": 70, "slice_spec": 70, "stringent": 70, "storage_dtyp": 70, "_default_ord": 70, "lock": [70, 90], "min": [71, 76, 79, 100, 123], "max": [71, 76, 100, 108, 123], "check_scal": 71, "int8": [71, 76, 123], "finit": [71, 103, 123], "scaler_dtyp": 71, "254": 71, "strip": [71, 91, 102, 103], "divid": [71, 123], "out_typ": 71, "has_slop": 71, "has_intercept": 71, "batteri": 72, "runner": 72, "chk": 72, "btrun": 72, "fixed_obj": 72, "report_seq": 72, "problem_level": [72, 96], "problem_msg": 72, "fix_msg": 72, "chk_datatyp": 72, "rep": 72, "_data_type_cod": 72, "keyerror": [72, 103], "fix_problem_msg": 72, "chk_bitpix": 72, "items": [72, 90], "ret": [72, 123], "chk_pixdim": 72, "logger": [72, 96, 124], "error_level": [72, 96, 124], "log_level": 72, "ini": [73, 79], "filesl": 73, "file_": 73, "bz2": [73, 89, 106, 123], "zst": [73, 89, 106], "underlin": [73, 114], "pub": 74, "program_help": 74, "dataset_rank": 74, "denot": 74, "brick": 74, "parlanc": 74, "tradition": 74, "datadir": 74, "3511": 74, "tlrc": 74, "883363e": 74, "08": [74, 113], "holdov": 74, "elsedemo": 74, "afni_atlas_spac": 74, "niml": 74, "extensionspec": [74, 77, 84, 87, 89, 92, 94, 109], "recogniz": [74, 87, 92], "byteorder_str": 74, "lsb_first": 74, "brick_typ": 74, "suppli": [75, 77], "child": [75, 77, 94], "md": [75, 77], "odditi": 76, "uint": [76, 123], "ityp": 76, "Will": [76, 94, 120], "intel80": 76, "highest": [76, 109], "sparc": 76, "best_typ": 76, "flt_type": 76, "ceil_val": 76, "floor_val": 76, "significand": 76, "int_typ": 76, "infmax": 76, "clip": [76, 123], "delic": 76, "shared_min": 76, "shared_max": 76, "infin": 76, "iarr": 76, "c99": 76, "exce": 76, "32767": 76, "32768": 76, "log2": 76, "embarrassingli": 76, "binary_logarithm": 76, "absolut": [76, 78, 90, 102], "abs_arr": 76, "magnitud": 76, "msvc": 76, "power": [76, 77], "ibm": 76, "power7": 76, "mn": [76, 123], "mx": [76, 123], "2147483648": 76, "2147483520": 76, "np_type": [76, 116], "nexp": 76, "nmant": 76, "expon": [76, 77], "minexp": 76, "maxexp": 76, "finfo": [76, 113, 123], "2669": 76, "float96": 76, "protect": [76, 105], "ep": [76, 108, 113], "ulp_val": 76, "epsilon": [76, 108], "msg_id": [77, 104], "3738": [77, 104], "monoton": 77, "factori": [77, 110], "tensor": [77, 94, 102], "descriptor": [77, 105], "colour": 77, "thalamu": 77, "bm_cortex": 77, "cortex_left": 77, "bm_thal": 77, "thalamus_left": 77, "cortic": 77, "2x2x2": 77, "bm_full": 77, "hcp": 77, "grayordin": 77, "region": 77, "cifti_structure_cortex_left": 77, "cifti_structure_thalamus_left": 77, "slc": 77, "bm": 77, "surface_parcel": 77, "volume_parcel": 77, "combined_parcel": 77, "fmri": 77, "curvatur": [77, 92], "index_offset": 77, "index_count": 77, "model_typ": 77, "brain_structur": 77, "n_surface_vertic": 77, "indicesmaptodatatyp": 77, "cifti_index_type_brain_model": 77, "indexoffset": 77, "brainordin": 77, "indexcount": 77, "modeltyp": 77, "brainstructur": 77, "surfacenumberofvertic": 77, "cifti_model_type_surfac": 77, "vertexindic": 77, "voxelindicesijk": 77, "matrixindicesmap": 77, "cifti_model_typ": 77, "cifti_brain_structur": 77, "surface_number_of_vertic": 77, "cifti2_map": 77, "cimg": [77, 84, 116], "alpha": [77, 86, 92, 94], "namedmap": 77, "cifti_index_type_label": 77, "mutablesequ": 77, "appliestomatrixdimens": 77, "applies_to_matrix_dimens": 77, "indices_map_to_data_typ": 77, "number_of_series_point": 77, "series_expon": 77, "series_start": 77, "series_step": 77, "series_unit": 77, "comma": 77, "numberofseriespoint": 77, "seriesexpon": 77, "seriesstart": 77, "seriesstep": 77, "005": 77, "quantiti": 77, "seriesunit": 77, "cifti_map_typ": 77, "map_nam": 77, "mapnam": 77, "ith": [77, 94], "pop": 77, "cifti_index_type_parcel": 77, "cerebellum": 77, "meter_expon": 77, "meterexpon": 77, "meter": 77, "sixteen": 77, "whitespac": 77, "volume_dimens": 77, "transform_matrix": 77, "volumedimens": 77, "transformationmatrixvoxelindicesijktoxyz": 77, "transformation_matrix_voxel_indices_ijk_to_xyz": 77, "tripl": 77, "nvertic": 77, "greyordin": 77, "array_lik": 77, "mim": 77, "nx": 77, "nz": 77, "nvertex": 77, "cortexright": 77, "brain_stem": 77, "cifti_model_type_voxel": 77, "yield": [77, 119], "left_cortex": 77, "leftcortex": 77, "test_nam": 77, "hcp_label": 77, "parcel_axi": 77, "named_brain_model": 77, "extension_cod": [77, 103], "runtim": [77, 103], "buffer_s": [77, 94, 119, 125], "3500000": 77, "expat": [77, 94, 125], "chunk": [77, 90, 91, 92, 94], "collat": [77, 94], "8k": [77, 94], "span": [77, 94], "attr": [77, 94, 102, 125], "fh": [78, 109], "fno": 78, "dummi": 78, "blow": 78, "header_field": 78, "data_max_abs_diff": 78, "data_max_rel_diff": 78, "max_ab": 78, "max_rel": 78, "maxim": 78, "lesser": 78, "cmp": 78, "md5": 78, "file_head": 78, "road": 78, "msg": [78, 79, 81, 121], "exit_cod": 78, "infil": [78, 123], "indent": 78, "allow_step": 78, "helplist": 78, "format_": 78, "verbose_level": 78, "hasattr": [79, 107], "base_path": 79, "prepend": [79, 102], "somedir": 79, "afil": 79, "path_part": 79, "file_list": 79, "config_filenam": 79, "config_filanam": 79, "pkg_def": 79, "viabl": 79, "relpath": 79, "hint": 79, "root_dir": 79, "data_dir": 79, "nipy_data_path": 79, "glob": [79, 102], "sys_dir": 79, "usr": 79, "packaging_tool": 79, "msg05084": 79, "pth": [79, 85, 89], "unix": [79, 85], "slash": 79, "rel_path": 79, "datobj": 80, "liter": [80, 99, 103, 116, 123], "arrayimgt": 80, "ty": [80, 89, 109, 123], "npt": [80, 99, 100, 116, 123], "dtypelik": [80, 99, 100, 116, 123], "reload": 80, "img_fnam": 80, "catch_warn": 81, "module_nam": 81, "nifti1_imag": 81, "userwarn": 81, "whatsnew": 81, "warning_class": [81, 82], "error_class": [81, 82], "warning_rec": 81, "error_rec": 81, "stacklevel": 81, "led": 81, "alert": 81, "guidanc": [81, 113], "version_compar": 82, "warn_class": 82, "__call__": 82, "version_str": 82, "is_bad": 82, "si": 83, "unsupport": [83, 116], "base_dir": 83, "followlink": 83, "mlist": 84, "hxist": 84, "ro": 84, "terminologi": 84, "specul": 84, "xmedcon": 84, "sourceforg": 84, "tpc": 84, "cti": 84, "No": 84, "s14": 84, "original_filenam": 84, "s32": 84, "sw_version": 84, "u2": 84, "system_typ": 84, "serial_numb": 84, "scan_start_tim": 84, "u4": [84, 123], "isotope_nam": 84, "isotope_halflif": 84, "radiopharmaceut": 84, "gantry_tilt": 84, "gantry_rot": 84, "bed_elev": 84, "intrinsic_tilt": 84, "wobble_spe": 84, "transm_source_typ": 84, "distance_scan": 84, "transaxial_fov": 84, "angular_compress": 84, "coin_samp_mod": 84, "axial_samp_mod": 84, "ecat_calibration_factor": 84, "calibration_unit": 84, "calibration_units_typ": 84, "compression_cod": 84, "study_typ": 84, "s12": 84, "s16": [84, 103, 104], "patient_nam": 84, "patient_sex": 84, "patient_dexter": 84, "patient_ag": 84, "patient_height": 84, "patient_weight": 84, "patient_birth_d": 84, "physician_nam": 84, "operator_nam": 84, "study_descript": 84, "acquisition_typ": 84, "patient_orient": 84, "facility_nam": 84, "s20": 84, "num_plan": 84, "num_fram": 84, "num_gat": 84, "num_bed_po": 84, "init_bed_posit": 84, "bed_posit": 84, "plane_separ": 84, "lwr_sctr_thre": 84, "lwr_true_thr": 84, "upr_true_thr": 84, "user_process_cod": 84, "acquisition_mod": 84, "bin_siz": 84, "branching_fract": 84, "dose_start_tim": 84, "dosag": 84, "well_counter_corr_factor": 84, "data_unit": 84, "septa_st": 84, "nibabel_dir": 84, "dirnam": [84, 107], "__file__": 84, "ecat_fil": 84, "tinypet": 84, "frame0": 84, "data4d": 84, "ecat7": 84, "512l": 84, "numavail": 84, "nextdir": 84, "previousdir": 84, "numus": 84, "frame_offset": 84, "chronolog": 84, "id_dict": 84, "mlist_row": 84, "mlist_id": 84, "16842758": 84, "framenumb": 84, "ONE": [84, 109], "frame_dict": 84, "order_stor": 84, "block_no": 84, "nfree": 84, "prvblk": 84, "n_row": [84, 119], "nuse": 84, "recarrai": [84, 123], "home_dir": 85, "systemwid": 85, "nipy_dir": 85, "_nipi": 85, "nipy_user_dir": 85, "homedir": 85, "euler": 86, "euler_angl": 86, "mathworld": [86, 113], "wolfram": [86, 113], "attitud": 86, "jame": 86, "diebel": 86, "citeseerx": 86, "ist": 86, "psu": 86, "viewdoc": 86, "5134": 86, "theorem": 86, "stai": 86, "extrins": 86, "handed": 86, "vdash": [86, 113], "pitch": 86, "roll": 86, "yaw": 86, "cardan": 86, "tait": 86, "bryan": 86, "is_norm": [86, 113], "reduct": 86, "allclos": [86, 87, 102, 103, 113, 117], "vec": [86, 113], "curl": 86, "counterclockwis": 86, "zrot": 86, "yrot": 86, "xrot": 86, "m1": 86, "m2": 86, "m3": 86, "composed_m": 86, "3x2": 86, "vecs2": 86, "counter": 86, "clockwis": 86, "zred": 86, "yred": 86, "xred": 86, "quat": [86, 113], "eulerparamet": [86, 113], "hamilton_product": [86, 113], "cy_thresh": 86, "arctan": 86, "atan2": 86, "r12": 86, "r11": 86, "asin": 86, "r13": 86, "r23": 86, "r33": 86, "cy": 86, "instabl": [86, 113], "gem": 86, "iv": 86, "heckbert": 86, "academ": 86, "press": 86, "1994": 86, "isbn": 86, "0123361559": 86, "ken": 86, "shoemak": 86, "graphicsgem": 86, "hdrt": 87, "fmap": [87, 116], "filemap": 87, "imgt": 87, "characterist": 87, "sniff": 87, "filesniff": 87, "sniff_max": 87, "maybe_imag": 87, "bytestr": [87, 103, 125], "deseri": 87, "img_a": 87, "bstr": 87, "img_b": 87, "streamimgt": 87, "io_obj": 87, "seekabl": 87, "timeout": 87, "urllib": 87, "fileobject": [88, 92, 106], "tf": [88, 90, 102], "fm_copi": 88, "shallow": 88, "types_ext": 89, "trailing_suffix": 89, "match_cas": 89, "fileroot": 89, "trail": [89, 111, 115], "insensit": 89, "ext": [89, 106, 123], "splitext": 89, "guessed_typ": 89, "ext1": 89, "ext2": 89, "fnameext2": 89, "addext": 89, "froot": 89, "bar": [89, 113], "template_fnam": 89, "enforce_extens": 89, "types_fnam": 89, "tfn": 89, "bare": 89, "sliceobj": [90, 99, 100, 116], "in_shap": 90, "heurist": [90, 123], "segment": 90, "surplu": 90, "post_slic": 90, "dim_len": 90, "stride": 90, "read_shap": 90, "check_ind": 90, "can_slic": 90, "ellips": 90, "_nulllock": 90, "sliced_arr": 90, "in_len": 90, "read_slic": 90, "trim": 90, "newaxi": [90, 122], "all_ful": 90, "is_slowest": 90, "to_read": 90, "heart": 90, "unalt": 90, "out_shap": [90, 111], "n_byte": [90, 102], "ctype": 90, "c_char_arrai": 90, "out_len": 90, "out_ax_ind": 90, "pretend": 90, "_positive_slic": 90, "strided_arr": 90, "broadcast": 90, "writeabl": 90, "6491": 90, "skip_thresh": 90, "trade": 90, "restart": 90, "n_string": 91, "bufsiz": 91, "exit": [91, 120], "byte_str": 91, "filepath": 92, "ctab": 92, "rgbt": 92, "surfer": 92, "nmr": 92, "harvard": 92, "fswiki": 92, "labelsclutsannotationfil": 92, "8b88b34": 92, "colortab": 92, "colort": 92, "n_vertic": 92, "n_label": 92, "read_metadata": 92, "read_stamp": 92, "voxels": 92, "xra": 92, "yra": 92, "zra": 92, "cra": 92, "nvtx": 92, "nface": 92, "volume_info": 92, "create_stamp": 92, "read_scalar": 92, "label_arrai": 92, "scalar_arrai": 92, "curv": 92, "pysurf": 92, "morpometri": 92, "fill_ctab": 92, "stamp": 92, "ctime": 92, "fnum": 92, "write_curv": 92, "grahamwideman": 92, "gw": 92, "surfacefileformat": 92, "curvnew": 92, "wstr": [92, 103, 124], "glean": 92, "mdc": 92, "pxyz_c": 92, "occupi": [92, 118], "resid": 92, "vox2ra": 92, "tkr": 92, "torig": 92, "coordinatesystem": 92, "dof": 92, "goodrasflag": 92, "flip_angl": 92, "te": 92, "fov": [92, 109], "processor": 93, "enforce_diag": 93, "check_affin": 93, "concat_img": 93, "squeez": 93, "squeezed_img": 93, "prod": 93, "ni1": [93, 103], "xformspac": 94, "dataarrai": 94, "nifti_intent_pointset": [94, 103], "stereotax": 94, "coordinatesystemtransformmatrix": 94, "nifti_xform_unknown": 94, "nifti_xform_scanner_anat": 94, "nifti_xform_aligned_anat": 94, "nifti_xform_talairach": 94, "nifti_xform_mni_152": 94, "nifti_intent_non": 94, "gifti_encoding_b64gz": 94, "coordsi": 94, "ext_fnam": 94, "ext_offset": 94, "fileoffset": 94, "darrai": 94, "data_type_cod": 94, "nifti_type_uint8": 94, "nifti_type_int32": 94, "nifti_type_float32": [94, 123], "gifti_encoding_cod": 94, "byteord": 94, "ind_ord": 94, "array_index_order_cod": 94, "rowmajorord": 94, "shell": 94, "topo": 94, "dataarr": 94, "aggreg": [94, 109], "nifti_intent_time_seri": 94, "uncertain": 94, "proven": 94, "get_test_data": 94, "surf_img": 94, "coords_2": 94, "coords_3": 94, "array2str": 94, "072": 94, "188": 94, "267": 94, "706": 94, "054": 94, "233": 94, "402": 94, "071": 94, "nifti_intent_triangl": 94, "triangles_2": 94, "triangles_3": 94, "coords_4": 94, "triangles_4": 94, "triangles_5": 94, "coords_5": 94, "ten": 94, "func_img": 94, "timestep": 94, "642": 94, "series_2": 94, "series_3": 94, "series_4": 94, "35000000": [94, 125], "enc": [94, 125], "nifti_type_rgba32": 94, "nifti_intent_label": 94, "encount": 94, "data_dict": 94, "expaterror": 94, "preced": [95, 103], "geteffectivelevel": 96, "mm3": 97, "mask_data": 97, "u1": [97, 103, 104], "scaled_arr": [99, 100], "data_dtyp": [99, 100, 116], "minc_fil": 99, "my_funni": 100, "mincstat": 100, "water_fat_shift": 101, "echo_train_length": 101, "field_strength": 101, "dwell": 101, "water": [101, 109], "fat": [101, 109], "shift": [101, 109, 119], "train": [101, 109], "strength": 101, "tesla": 101, "3t": 101, "dwell_tim": 101, "varieti": 102, "manifesto": 102, "semi": 102, "q_est": 102, "pack": 102, "op": 102, "obj_typ": 102, "obj_id": 102, "ast": 102, "assign_ast": 102, "default_class": 102, "line_ast": 102, "obj_root": 102, "obj_kei": 102, "ascconv_str": 102, "str_delim": 102, "input_str": 102, "prot_dict": 102, "asconvparseerror": 102, "csa_dict": 102, "csa_typ": 102, "presenc": [102, 103], "0x29": 102, "0x10": 102, "satisfi": 102, "csa_info": 102, "tag_nam": 102, "sdash": 102, "occurr": 102, "csa_str": 102, "dicom_path": 102, "globber": 102, "check_is_dwi": 102, "dicom_kwarg": 102, "dwi": 102, "dcmread": 102, "unit_gradi": 102, "csa_head": 102, "n_mosaic": 102, "light": 102, "idiosyncrasi": 102, "mosaic_s": 102, "dicom_mosa": 102, "img_po": 102, "sop": [102, 126], "began": 102, "supplement": 102, "dcmdata": 102, "perframefunctionalgroupssequ": 102, "sharedfunctionalgroupsequ": 102, "_not_": 102, "lr": [102, 109], "framecontentsequ": 102, "dimensionindexvalu": 102, "dimensionindexsequ": 102, "stackid": 102, "stack": 102, "part03": 102, "sect_c": 102, "figure_c": 102, "b0": 102, "imageorientpati": 102, "ij": 102, "dicom_orientaiton": 102, "dicom_orient": 102, "val1": 102, "val2": 102, "rtol": [102, 113], "05": [102, 113], "atol": [102, 113], "atal": 102, "dcm_w": 102, "tol": [102, 108], "symmetri": 102, "eigenvalu": [102, 113], "tight": 102, "niethamm": 102, "san": 102, "jose": 102, "estepar": 102, "bouix": 102, "shenton": 102, "westin": 102, "cf": 102, "proc": 102, "eng": 102, "med": 102, "biol": 102, "soc": 102, "2622": 102, "pubm": 102, "pmid": 102, "17946125": 102, "pmcid": 102, "pmc2791793": 102, "npd": 102, "l2": 102, "g_vector": 102, "norma": 102, "buf": 102, "ptr": 102, "1234567890": 102, "upk": 102, "567": 102, "fmt": 102, "group_no": 102, "0xff": 102, "regex": 102, "element_valu": 102, "element_start": 102, "parent_hdr": 103, "thin": [103, 125], "bystestr": 103, "baseclass": 103, "dedic": 103, "till": 103, "endiancod": [103, 124], "save_nifti": 103, "7th": 103, "icosahedron": 103, "309": 103, "load_nifti": 103, "freq": [103, 109], "medium": 103, "code_repr": 103, "score": 103, "1f": 103, "slice_tim": 103, "slice_order_cod": 103, "dc": 103, "5762786865234375e": 103, "disallow": 103, "poor": 103, "noqa": 103, "signifi": 103, "eeg": 103, "meg": 103, "allow_unknown": 103, "9999": 103, "strip_shear": 103, "ornt": [103, 108, 116], "flipud": [103, 108, 116], "update_affin": 103, "aff2": 103, "qaff": 103, "saff": 103, "oserror": [103, 104, 123], "ni2": 104, "661338147750939e": 104, "i1": 104, "i8": 104, "s15": 104, "pattern": 105, "cycl": 105, "overhead": 105, "untrigg": 105, "howto": 105, "datamodel": 105, "instancet": 105, "afterward": 105, "mixin": 105, "uniformtimeseri": 105, "sampling_r": 105, "t0": 105, "sampling_interv": 105, "chain": 105, "_no_reset": 105, "caveat": 105, "emptor": 105, "twice": 105, "recomput": 105, "magicprop": 105, "__dict__": 105, "compresslevel": 106, "fileio": 106, "mtime": 106, "gzipfil": 106, "simul": 106, "discern": 106, "xb": 106, "timestamp": 106, "func_def": 106, "unord": 106, "openerdef": 106, "_gzip_open": 106, "keep_open": 106, "_zstd_open": 106, "level_or_opt": 106, "zstd_dict": 106, "_name": 106, "writeablebuff": 106, "whenc": 106, "trip_msg": 107, "min_vers": 107, "pkg": 107, "pkg_like": 107, "have_pkg": 107, "module_setup": 107, "setup_modul": 107, "not_a_packag": 107, "some_funct": 107, "subpkg": 107, "svd": 108, "axcod": 108, "t_arr": 108, "tarr": 108, "shape_prim": 108, "transform_affin": 108, "transformed_affin": 108, "influenc": 108, "singular": 108, "start_ornt": 108, "end_ornt": 108, "ye": 109, "ec": 109, "dyn": 109, "ph": 109, "pix": 109, "angul": 109, "offcentr": 109, "dtime": 109, "ttime": 109, "avg": 109, "rr": 109, "turbo": 109, "grad": 109, "cont": 109, "00000": 109, "29035": 109, "28404e": 109, "003": 109, "1070": 109, "1860": 109, "69": 109, "000": 109, "90": 109, "1122": 109, "1951": 109, "1137": 109, "1977": 109, "rl": 109, "psl": 109, "274": 109, "275": 109, "strict_sort": 109, "cardiac": 109, "asl": 109, "image_type_mr": 109, "mag": 109, "4th": 109, "export": 109, "csv": 109, "dv": 109, "image_def": 109, "permit_trunc": 109, "iso": 109, "b_val": 109, "n_direct": 109, "pv": 109, "ri": 109, "sagitt": [109, 122], "coron": [109, 122], "slice_indic": 109, "sort_info": 109, "exts_sourc": 109, "par_head": 109, "long_str": 109, "mutli": 109, "general_info": 109, "image_info": 109, "slice_max": 109, "slice_min": 109, "is_ful": 109, "vol_no": 109, "oppos": [110, 123], "abstractli": 110, "warrant": 110, "as_homogen": 110, "sd": 111, "fwhm": 111, "n_dim": 111, "from_img": 111, "cval": 111, "out_class": 111, "mri_convert": 111, "output_shap": [111, 115], "lia": 111, "eight": 111, "__class__": 111, "1mm": 111, "isotrop": 111, "affine_transform": [111, 115], "out_img": 111, "kernel": 111, "to_vox_map": 111, "in_img": 111, "edg": 111, "strong": 111, "blur": 111, "smoothed_img": 111, "have_dicom": 112, "tag_for_keyword": 112, "180": 113, "degre": 113, "tvec": 113, "axis_and_angl": 113, "symbol": 113, "conjq": 113, "w2_thresh": 113, "wxyz": 113, "w2": 113, "invq": 113, "eigenvector": 113, "itzhack": 113, "aiaa": 113, "journal": 113, "1085": 113, "1087": 113, "issn": 113, "0731": 113, "5090": 113, "rotn": 113, "q1": 113, "q2": 113, "q12": 113, "equiv": 113, "identity_thresh": 113, "quaternions_and_spatial_rot": 113, "describing_rotations_with_quaternion": 113, "cell_valu": 114, "row_nam": 114, "col_nam": 114, "val_fmt": 114, "2f": 114, "format_char": 114, "thick_long": 114, "title_head": 114, "table_str": 114, "slice_shap": 115, "slice_aff": 115, "whole_aff": 115, "new_slic": 115, "mapped_voxel": 115, "output_affin": 115, "unscaled_data": 116, "dataoobj": 116, "spatialimgt": 116, "return_spati": 116, "canonic": 116, "spatialhdrt": 116, "backend": 116, "reslic": 116, "spm_vol_ana": 117, "calibr": 117, "ditto": 117, "gl": 117, "cal": 117, "unset": 118, "multiformat": 119, "getting_start": 119, "highlight": 119, "d_1": 119, "d_2": 119, "d_d": 119, "cache_build": 119, "player": 119, "caller": 119, "seq_copi": 119, "deepcopi": 119, "seq": 119, "npz": 119, "new_seq": 119, "gen": 119, "pipermail": 119, "000859": 119, "coordinate_system": 119, "compliant": 119, "tck_file": 119, "lazili": 119, "friendli": 119, "n_t": 119, "piec": 119, "alongsid": 119, "p_i": 119, "m_i": 119, "lazy_tractogram": 119, "data_func": 119, "tractgogram": 119, "straight": 119, "data_for_streamlin": 119, "data_for_point": 119, "nt": 119, "mk": 119, "datadict": 119, "inconsist": 119, "voxmm": 119, "rasmm": 119, "trk_file": 119, "encoded_nam": 119, "max_name_len": 119, "latin": 119, "voxelmm": 119, "aff_tv2ra": 119, "peek": 119, "next_item": 119, "new_iter": 119, "untouch": 119, "dir": 120, "mkdtemp": 120, "wt": 120, "debug": 120, "inde": 120, "meanwhil": 120, "wipe": 120, "getcwd": 120, "temporarili": 120, "pathlib": 120, "my_cwd": 120, "write_text": 120, "isfil": 120, "misfortun": 121, "a_modul": 121, "do_silly_th": 121, "silli": 121, "drag": 122, "mous": 122, "scroll": 122, "decrement": 122, "linspac": 122, "axial": 122, "mpl": 122, "colormap": 122, "redraw": 122, "canvas": 122, "hashabl": 123, "mapper": 123, "map_mak": 123, "code1": 123, "aliases1": 123, "code2": 123, "aliases2": 123, "label1": 123, "label2": 123, "thenc": 123, "__setitem__": [123, 124], "code_syn_seq": 123, "field1": 123, "field2": 123, "in_dtyp": 123, "bio": 123, "arr2": 123, "divslop": 123, "prescal": 123, "clipped_sc": 123, "clipped_scaled_clip": 123, "clipped_scaled_clipped_n2z": 123, "sio": 123, "ftype": 123, "better_typ": 123, "check_nan": 123, "flatten": 123, "1j": 123, "f1": 123, "mod_fnam": 123, "ifmt": 123, "imin": 123, "imax": 123, "default_out": 123, "extrem": 123, "iinfo": 123, "1e38": 123, "codes_seq": 123, "niistr": 123, "getterfunc": 123, "longest": 123, "clever": 123, "__iter__": 123, "short_field": 123, "longer_field": 123, "get_longer_field": 123, "getter": 123, "__getattribute__": 123, "dct": 123, "write0": 123, "x_flip": 123, "in_typ": 123, "wtype": 123, "block_siz": 123, "8194": 123, "largest": 123, "wherebi": 124, "__str_": 124, "__eq__": 124, "__ne__": 124, "fixabl": 124, "myfil": 124, "dx_result": 124, "good_fileobj": 124, "bad_fileobj": 124, "wstr1": 124, "fieldnam": 124, "_field_recod": 124, "bs_wstr": 124, "nbs_wstr": 124, "wstr2": 124, "an_int": 124, "etre": 125, "elementtre": 125, "fptr": 125, "dims": 126}, "objects": {"": [[66, 0, 0, "-", "nibabel"]], "nibabel": [[67, 0, 0, "-", "_compression"], [68, 0, 0, "-", "affines"], [69, 0, 0, "-", "analyze"], [70, 0, 0, "-", "arrayproxy"], [71, 0, 0, "-", "arraywriters"], [72, 0, 0, "-", "batteryrunners"], [66, 3, 1, "", "bench"], [73, 0, 0, "-", "benchmarks"], [74, 0, 0, "-", "brikhead"], [75, 0, 0, "-", "caret"], [76, 0, 0, "-", "casting"], [77, 0, 0, "-", "cifti2"], [78, 0, 0, "-", "cmdline"], [79, 0, 0, "-", "data"], [80, 0, 0, "-", "dataobj_images"], [81, 0, 0, "-", "deprecated"], [82, 0, 0, "-", "deprecator"], [83, 0, 0, "-", "dft"], [84, 0, 0, "-", "ecat"], [85, 0, 0, "-", "environment"], [86, 0, 0, "-", "eulerangles"], [87, 0, 0, "-", "filebasedimages"], [88, 0, 0, "-", "fileholders"], [89, 0, 0, "-", "filename_parser"], [90, 0, 0, "-", "fileslice"], [91, 0, 0, "-", "fileutils"], [92, 0, 0, "-", "freesurfer"], [93, 0, 0, "-", "funcs"], [66, 3, 1, "", "get_info"], [94, 0, 0, "-", "gifti"], [95, 0, 0, "-", "imageclasses"], [96, 0, 0, "-", "imageglobals"], [97, 0, 0, "-", "imagestats"], [98, 0, 0, "-", "loadsave"], [99, 0, 0, "-", "minc1"], [100, 0, 0, "-", "minc2"], [101, 0, 0, "-", "mriutils"], [102, 0, 0, "-", "nicom"], [103, 0, 0, "-", "nifti1"], [104, 0, 0, "-", "nifti2"], [105, 0, 0, "-", "onetime"], [106, 0, 0, "-", "openers"], [107, 0, 0, "-", "optpkg"], [108, 0, 0, "-", "orientations"], [109, 0, 0, "-", "parrec"], [110, 0, 0, "-", "pointset"], [111, 0, 0, "-", "processing"], [112, 0, 0, "-", "pydicom_compat"], [113, 0, 0, "-", "quaternions"], [114, 0, 0, "-", "rstutils"], [115, 0, 0, "-", "spaces"], [116, 0, 0, "-", "spatialimages"], [117, 0, 0, "-", "spm2analyze"], [118, 0, 0, "-", "spm99analyze"], [119, 0, 0, "-", "streamlines"], [66, 3, 1, "", "test"], [120, 0, 0, "-", "tmpdirs"], [121, 0, 0, "-", "tripwire"], [122, 0, 0, "-", "viewers"], [123, 0, 0, "-", "volumeutils"], [124, 0, 0, "-", "wrapstruct"], [125, 0, 0, "-", "xmlutils"]], "nibabel.affines": [[68, 1, 1, "", "AffineError"], [68, 3, 1, "", "append_diag"], [68, 3, 1, "", "apply_affine"], [68, 3, 1, "", "dot_reduce"], [68, 3, 1, "", "from_matvec"], [68, 3, 1, "", "obliquity"], [68, 3, 1, "", "rescale_affine"], [68, 3, 1, "", "to_matvec"], [68, 3, 1, "", "voxel_sizes"]], "nibabel.affines.AffineError": [[68, 2, 1, "", "__init__"]], "nibabel.analyze": [[69, 1, 1, "", "AnalyzeHeader"], [69, 1, 1, "", "AnalyzeImage"]], "nibabel.analyze.AnalyzeHeader": [[69, 2, 1, "", "__init__"], [69, 2, 1, "", "as_analyze_map"], [69, 2, 1, "", "data_from_fileobj"], [69, 2, 1, "", "data_to_fileobj"], [69, 2, 1, "", "default_structarr"], [69, 4, 1, "", "default_x_flip"], [69, 2, 1, "", "from_header"], [69, 2, 1, "", "get_base_affine"], [69, 2, 1, "", "get_best_affine"], [69, 2, 1, "", "get_data_dtype"], [69, 2, 1, "", "get_data_offset"], [69, 2, 1, "", "get_data_shape"], [69, 2, 1, "", "get_slope_inter"], [69, 2, 1, "", "get_zooms"], [69, 2, 1, "", "guessed_endian"], [69, 4, 1, "", "has_data_intercept"], [69, 4, 1, "", "has_data_slope"], [69, 2, 1, "", "may_contain_header"], [69, 2, 1, "", "raw_data_from_fileobj"], [69, 2, 1, "", "set_data_dtype"], [69, 2, 1, "", "set_data_offset"], [69, 2, 1, "", "set_data_shape"], [69, 2, 1, "", "set_slope_inter"], [69, 2, 1, "", "set_zooms"], [69, 4, 1, "", "sizeof_hdr"], [69, 4, 1, "", "template_dtype"]], "nibabel.analyze.AnalyzeImage": [[69, 4, 1, "", "ImageArrayProxy"], [69, 2, 1, "", "__init__"], [69, 4, 1, "", "files_types"], [69, 2, 1, "", "from_file_map"], [69, 2, 1, "", "get_data_dtype"], [69, 4, 1, "", "header_class"], [69, 4, 1, "", "makeable"], [69, 4, 1, "", "rw"], [69, 2, 1, "", "set_data_dtype"], [69, 2, 1, "", "to_file_map"], [69, 4, 1, "", "valid_exts"]], "nibabel.arrayproxy": [[70, 1, 1, "", "ArrayLike"], [70, 1, 1, "", "ArrayProxy"], [70, 3, 1, "", "get_obj_dtype"], [70, 3, 1, "", "is_proxy"], [70, 3, 1, "", "reshape_dataobj"]], "nibabel.arrayproxy.ArrayLike": [[70, 2, 1, "", "__init__"], [70, 5, 1, "", "ndim"], [70, 4, 1, "", "shape"]], "nibabel.arrayproxy.ArrayProxy": [[70, 2, 1, "", "__init__"], [70, 2, 1, "", "copy"], [70, 5, 1, "", "dtype"], [70, 2, 1, "", "get_unscaled"], [70, 5, 1, "", "inter"], [70, 5, 1, "", "is_proxy"], [70, 5, 1, "", "ndim"], [70, 5, 1, "", "offset"], [70, 2, 1, "", "reshape"], [70, 5, 1, "", "shape"], [70, 5, 1, "", "slope"]], "nibabel.arraywriters": [[71, 1, 1, "", "ArrayWriter"], [71, 1, 1, "", "ScalingError"], [71, 1, 1, "", "SlopeArrayWriter"], [71, 1, 1, "", "SlopeInterArrayWriter"], [71, 1, 1, "", "WriterError"], [71, 3, 1, "", "get_slope_inter"], [71, 3, 1, "", "make_array_writer"]], "nibabel.arraywriters.ArrayWriter": [[71, 2, 1, "", "__init__"], [71, 5, 1, "", "array"], [71, 2, 1, "", "finite_range"], [71, 5, 1, "", "has_nan"], [71, 5, 1, "", "out_dtype"], [71, 2, 1, "", "scaling_needed"], [71, 2, 1, "", "to_fileobj"]], "nibabel.arraywriters.ScalingError": [[71, 2, 1, "", "__init__"]], "nibabel.arraywriters.SlopeArrayWriter": [[71, 2, 1, "", "__init__"], [71, 2, 1, "", "calc_scale"], [71, 2, 1, "", "reset"], [71, 2, 1, "", "scaling_needed"], [71, 5, 1, "", "slope"], [71, 2, 1, "", "to_fileobj"]], "nibabel.arraywriters.SlopeInterArrayWriter": [[71, 2, 1, "", "__init__"], [71, 5, 1, "", "inter"], [71, 2, 1, "", "reset"], [71, 2, 1, "", "to_fileobj"]], "nibabel.arraywriters.WriterError": [[71, 2, 1, "", "__init__"]], "nibabel.batteryrunners": [[72, 1, 1, "", "BatteryRunner"], [72, 1, 1, "", "Report"]], "nibabel.batteryrunners.BatteryRunner": [[72, 2, 1, "", "__init__"], [72, 2, 1, "", "check_fix"], [72, 2, 1, "", "check_only"]], "nibabel.batteryrunners.Report": [[72, 2, 1, "", "__init__"], [72, 2, 1, "", "log_raise"], [72, 5, 1, "", "message"], [72, 2, 1, "", "write_raise"]], "nibabel.benchmarks": [[73, 0, 0, "-", "bench_array_to_file"], [73, 0, 0, "-", "bench_arrayproxy_slicing"], [73, 0, 0, "-", "bench_fileslice"], [73, 0, 0, "-", "bench_finite_range"], [73, 0, 0, "-", "bench_load_save"], [73, 0, 0, "-", "butils"]], "nibabel.benchmarks.bench_array_to_file": [[73, 3, 1, "", "bench_array_to_file"]], "nibabel.benchmarks.bench_arrayproxy_slicing": [[73, 3, 1, "", "bench_arrayproxy_slicing"]], "nibabel.benchmarks.bench_fileslice": [[73, 3, 1, "", "bench_fileslice"], [73, 3, 1, "", "run_slices"]], "nibabel.benchmarks.bench_finite_range": [[73, 3, 1, "", "bench_finite_range"]], "nibabel.benchmarks.bench_load_save": [[73, 3, 1, "", "bench_load_save"]], "nibabel.benchmarks.butils": [[73, 3, 1, "", "print_git_title"]], "nibabel.brikhead": [[74, 1, 1, "", "AFNIArrayProxy"], [74, 1, 1, "", "AFNIHeader"], [74, 1, 1, "", "AFNIHeaderError"], [74, 1, 1, "", "AFNIImage"], [74, 1, 1, "", "AFNIImageError"], [74, 3, 1, "", "parse_AFNI_header"]], "nibabel.brikhead.AFNIArrayProxy": [[74, 2, 1, "", "__init__"], [74, 5, 1, "", "scaling"]], "nibabel.brikhead.AFNIHeader": [[74, 2, 1, "", "__init__"], [74, 2, 1, "", "copy"], [74, 2, 1, "", "from_fileobj"], [74, 2, 1, "", "from_header"], [74, 2, 1, "", "get_affine"], [74, 2, 1, "", "get_data_offset"], [74, 2, 1, "", "get_data_scaling"], [74, 2, 1, "", "get_slope_inter"], [74, 2, 1, "", "get_space"], [74, 2, 1, "", "get_volume_labels"]], "nibabel.brikhead.AFNIHeaderError": [[74, 2, 1, "", "__init__"]], "nibabel.brikhead.AFNIImage": [[74, 4, 1, "", "ImageArrayProxy"], [74, 2, 1, "", "__init__"], [74, 4, 1, "", "files_types"], [74, 2, 1, "", "filespec_to_file_map"], [74, 2, 1, "", "from_file_map"], [74, 4, 1, "", "header_class"], [74, 4, 1, "", "makeable"], [74, 4, 1, "", "rw"], [74, 4, 1, "", "valid_exts"]], "nibabel.brikhead.AFNIImageError": [[74, 2, 1, "", "__init__"]], "nibabel.caret": [[75, 1, 1, "", "CaretMetaData"]], "nibabel.caret.CaretMetaData": [[75, 2, 1, "", "__init__"]], "nibabel.casting": [[76, 1, 1, "", "CastingError"], [76, 1, 1, "", "FloatingError"], [76, 3, 1, "", "able_int_type"], [76, 3, 1, "", "as_int"], [76, 3, 1, "", "best_float"], [76, 3, 1, "", "ceil_exact"], [76, 3, 1, "", "float_to_int"], [76, 3, 1, "", "floor_exact"], [76, 3, 1, "", "floor_log2"], [76, 3, 1, "", "have_binary128"], [76, 3, 1, "", "int_abs"], [76, 3, 1, "", "int_to_float"], [76, 3, 1, "", "longdouble_lte_float64"], [76, 3, 1, "", "longdouble_precision_improved"], [76, 3, 1, "", "ok_floats"], [76, 3, 1, "", "on_powerpc"], [76, 3, 1, "", "shared_range"], [76, 3, 1, "", "type_info"], [76, 3, 1, "", "ulp"]], "nibabel.casting.CastingError": [[76, 2, 1, "", "__init__"]], "nibabel.casting.FloatingError": [[76, 2, 1, "", "__init__"]], "nibabel.cifti2": [[77, 0, 0, "-", "cifti2"], [77, 0, 0, "-", "cifti2_axes"], [77, 0, 0, "-", "parse_cifti2"]], "nibabel.cifti2.cifti2": [[77, 1, 1, "", "Cifti2BrainModel"], [77, 1, 1, "", "Cifti2Header"], [77, 1, 1, "", "Cifti2HeaderError"], [77, 1, 1, "", "Cifti2Image"], [77, 1, 1, "", "Cifti2Label"], [77, 1, 1, "", "Cifti2LabelTable"], [77, 1, 1, "", "Cifti2Matrix"], [77, 1, 1, "", "Cifti2MatrixIndicesMap"], [77, 1, 1, "", "Cifti2MetaData"], [77, 1, 1, "", "Cifti2NamedMap"], [77, 1, 1, "", "Cifti2Parcel"], [77, 1, 1, "", "Cifti2Surface"], [77, 1, 1, "", "Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ"], [77, 1, 1, "", "Cifti2VertexIndices"], [77, 1, 1, "", "Cifti2Vertices"], [77, 1, 1, "", "Cifti2Volume"], [77, 1, 1, "", "Cifti2VoxelIndicesIJK"], [77, 1, 1, "", "LimitedNifti2Header"]], "nibabel.cifti2.cifti2.Cifti2BrainModel": [[77, 2, 1, "", "__init__"], [77, 5, 1, "", "vertex_indices"], [77, 5, 1, "", "voxel_indices_ijk"]], "nibabel.cifti2.cifti2.Cifti2Header": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "from_axes"], [77, 2, 1, "", "get_axis"], [77, 2, 1, "", "get_index_map"], [77, 5, 1, "", "mapped_indices"], [77, 2, 1, "", "may_contain_header"], [77, 5, 1, "", "number_of_mapped_indices"]], "nibabel.cifti2.cifti2.Cifti2HeaderError": [[77, 2, 1, "", "__init__"]], "nibabel.cifti2.cifti2.Cifti2Image": [[77, 2, 1, "", "__init__"], [77, 4, 1, "", "files_types"], [77, 2, 1, "", "from_file_map"], [77, 2, 1, "", "from_image"], [77, 2, 1, "", "get_data_dtype"], [77, 4, 1, "", "header_class"], [77, 4, 1, "", "makeable"], [77, 5, 1, "", "nifti_header"], [77, 4, 1, "", "rw"], [77, 2, 1, "", "set_data_dtype"], [77, 2, 1, "", "to_file_map"], [77, 2, 1, "", "update_headers"], [77, 4, 1, "", "valid_exts"]], "nibabel.cifti2.cifti2.Cifti2Label": [[77, 2, 1, "", "__init__"], [77, 5, 1, "", "rgba"]], "nibabel.cifti2.cifti2.Cifti2LabelTable": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "append"]], "nibabel.cifti2.cifti2.Cifti2Matrix": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "get_axis"], [77, 2, 1, "", "get_data_shape"], [77, 2, 1, "", "get_index_map"], [77, 2, 1, "", "insert"], [77, 5, 1, "", "mapped_indices"], [77, 5, 1, "", "metadata"]], "nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap": [[77, 2, 1, "", "__init__"], [77, 5, 1, "", "brain_models"], [77, 2, 1, "", "insert"], [77, 5, 1, "", "named_maps"], [77, 5, 1, "", "parcels"], [77, 5, 1, "", "surfaces"], [77, 5, 1, "", "volume"]], "nibabel.cifti2.cifti2.Cifti2MetaData": [[77, 2, 1, "", "__init__"], [77, 5, 1, "", "data"], [77, 2, 1, "", "difference_update"]], "nibabel.cifti2.cifti2.Cifti2NamedMap": [[77, 2, 1, "", "__init__"], [77, 5, 1, "", "label_table"], [77, 5, 1, "", "metadata"]], "nibabel.cifti2.cifti2.Cifti2Parcel": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "append_cifti_vertices"], [77, 2, 1, "", "pop_cifti2_vertices"], [77, 5, 1, "", "voxel_indices_ijk"]], "nibabel.cifti2.cifti2.Cifti2Surface": [[77, 2, 1, "", "__init__"]], "nibabel.cifti2.cifti2.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ": [[77, 2, 1, "", "__init__"]], "nibabel.cifti2.cifti2.Cifti2VertexIndices": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "insert"]], "nibabel.cifti2.cifti2.Cifti2Vertices": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "insert"]], "nibabel.cifti2.cifti2.Cifti2Volume": [[77, 2, 1, "", "__init__"]], "nibabel.cifti2.cifti2.Cifti2VoxelIndicesIJK": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "insert"]], "nibabel.cifti2.cifti2.LimitedNifti2Header": [[77, 2, 1, "", "__init__"]], "nibabel.cifti2.cifti2_axes": [[77, 1, 1, "", "Axis"], [77, 1, 1, "", "BrainModelAxis"], [77, 1, 1, "", "LabelAxis"], [77, 1, 1, "", "ParcelsAxis"], [77, 1, 1, "", "ScalarAxis"], [77, 1, 1, "", "SeriesAxis"], [77, 3, 1, "", "from_index_mapping"], [77, 3, 1, "", "to_header"]], "nibabel.cifti2.cifti2_axes.Axis": [[77, 2, 1, "", "__init__"], [77, 5, 1, "", "size"]], "nibabel.cifti2.cifti2_axes.BrainModelAxis": [[77, 2, 1, "", "__init__"], [77, 5, 1, "", "affine"], [77, 2, 1, "", "from_index_mapping"], [77, 2, 1, "", "from_mask"], [77, 2, 1, "", "from_surface"], [77, 2, 1, "", "get_element"], [77, 2, 1, "", "iter_structures"], [77, 5, 1, "", "name"], [77, 5, 1, "", "surface_mask"], [77, 2, 1, "", "to_cifti_brain_structure_name"], [77, 2, 1, "", "to_mapping"], [77, 5, 1, "", "volume_mask"], [77, 5, 1, "", "volume_shape"]], "nibabel.cifti2.cifti2_axes.LabelAxis": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "from_index_mapping"], [77, 2, 1, "", "get_element"], [77, 2, 1, "", "to_mapping"]], "nibabel.cifti2.cifti2_axes.ParcelsAxis": [[77, 2, 1, "", "__init__"], [77, 5, 1, "", "affine"], [77, 2, 1, "", "from_brain_models"], [77, 2, 1, "", "from_index_mapping"], [77, 2, 1, "", "get_element"], [77, 2, 1, "", "to_mapping"], [77, 5, 1, "", "volume_shape"]], "nibabel.cifti2.cifti2_axes.ScalarAxis": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "from_index_mapping"], [77, 2, 1, "", "get_element"], [77, 2, 1, "", "to_mapping"]], "nibabel.cifti2.cifti2_axes.SeriesAxis": [[77, 2, 1, "", "__init__"], [77, 2, 1, "", "from_index_mapping"], [77, 2, 1, "", "get_element"], [77, 4, 1, "", "size"], [77, 5, 1, "", "time"], [77, 2, 1, "", "to_mapping"], [77, 5, 1, "", "unit"]], "nibabel.cifti2.parse_cifti2": [[77, 1, 1, "", "Cifti2Extension"], [77, 1, 1, "", "Cifti2Parser"]], "nibabel.cifti2.parse_cifti2.Cifti2Extension": [[77, 2, 1, "", "__init__"], [77, 4, 1, "", "code"]], "nibabel.cifti2.parse_cifti2.Cifti2Parser": [[77, 2, 1, "", "CharacterDataHandler"], [77, 2, 1, "", "EndElementHandler"], [77, 2, 1, "", "StartElementHandler"], [77, 2, 1, "", "__init__"], [77, 2, 1, "", "flush_chardata"], [77, 5, 1, "", "pending_data"]], "nibabel.cmdline": [[78, 0, 0, "-", "conform"], [78, 0, 0, "-", "convert"], [78, 0, 0, "-", "dicomfs"], [78, 0, 0, "-", "diff"], [78, 0, 0, "-", "ls"], [78, 0, 0, "-", "nifti_dx"], [78, 0, 0, "-", "parrec2nii"], [78, 0, 0, "-", "roi"], [78, 0, 0, "-", "stats"], [78, 0, 0, "-", "tck2trk"], [78, 0, 0, "-", "trk2tck"], [78, 0, 0, "-", "utils"]], "nibabel.cmdline.conform": [[78, 3, 1, "", "main"]], "nibabel.cmdline.convert": [[78, 3, 1, "", "main"]], "nibabel.cmdline.dicomfs": [[78, 1, 1, "", "DICOMFS"], [78, 1, 1, "", "FileHandle"], [78, 1, 1, "", "dummy_fuse"], [78, 4, 1, "", "fuse"], [78, 3, 1, "", "get_opt_parser"], [78, 3, 1, "", "main"]], "nibabel.cmdline.dicomfs.DICOMFS": [[78, 2, 1, "", "__init__"], [78, 2, 1, "", "get_paths"], [78, 2, 1, "", "getattr"], [78, 2, 1, "", "match_path"], [78, 2, 1, "", "open"], [78, 2, 1, "", "read"], [78, 2, 1, "", "readdir"], [78, 2, 1, "", "release"]], "nibabel.cmdline.dicomfs.FileHandle": [[78, 2, 1, "", "__init__"]], "nibabel.cmdline.dicomfs.dummy_fuse": [[78, 4, 1, "", "Fuse"], [78, 2, 1, "", "__init__"], [78, 4, 1, "", "fuse_python_api"]], "nibabel.cmdline.diff": [[78, 3, 1, "", "are_values_different"], [78, 3, 1, "", "diff"], [78, 3, 1, "", "display_diff"], [78, 3, 1, "", "get_data_diff"], [78, 3, 1, "", "get_data_hash_diff"], [78, 3, 1, "", "get_headers_diff"], [78, 3, 1, "", "get_opt_parser"], [78, 3, 1, "", "main"]], "nibabel.cmdline.ls": [[78, 3, 1, "", "get_opt_parser"], [78, 3, 1, "", "main"], [78, 3, 1, "", "proc_file"]], "nibabel.cmdline.nifti_dx": [[78, 3, 1, "", "main"]], "nibabel.cmdline.parrec2nii": [[78, 3, 1, "", "error"], [78, 3, 1, "", "get_opt_parser"], [78, 3, 1, "", "main"], [78, 3, 1, "", "proc_file"], [78, 3, 1, "", "verbose"]], "nibabel.cmdline.roi": [[78, 3, 1, "", "lossless_slice"], [78, 3, 1, "", "main"], [78, 3, 1, "", "parse_slice"], [78, 3, 1, "", "sanitize"]], "nibabel.cmdline.stats": [[78, 3, 1, "", "main"]], "nibabel.cmdline.tck2trk": [[78, 3, 1, "", "main"], [78, 3, 1, "", "parse_args"]], "nibabel.cmdline.trk2tck": [[78, 3, 1, "", "main"], [78, 3, 1, "", "parse_args"]], "nibabel.cmdline.utils": [[78, 3, 1, "", "ap"], [78, 3, 1, "", "safe_get"], [78, 3, 1, "", "table2string"], [78, 3, 1, "", "verbose"]], "nibabel.data": [[79, 1, 1, "", "Bomber"], [79, 1, 1, "", "BomberError"], [79, 1, 1, "", "DataError"], [79, 1, 1, "", "Datasource"], [79, 1, 1, "", "VersionedDatasource"], [79, 3, 1, "", "datasource_or_bomber"], [79, 3, 1, "", "find_data_dir"], [79, 3, 1, "", "get_data_path"], [79, 3, 1, "", "make_datasource"]], "nibabel.data.Bomber": [[79, 2, 1, "", "__init__"]], "nibabel.data.BomberError": [[79, 2, 1, "", "__init__"]], "nibabel.data.DataError": [[79, 2, 1, "", "__init__"]], "nibabel.data.Datasource": [[79, 2, 1, "", "__init__"], [79, 2, 1, "", "get_filename"], [79, 2, 1, "", "list_files"]], "nibabel.data.VersionedDatasource": [[79, 2, 1, "", "__init__"]], "nibabel.dataobj_images": [[80, 1, 1, "", "DataobjImage"]], "nibabel.dataobj_images.DataobjImage": [[80, 2, 1, "", "__init__"], [80, 5, 1, "", "dataobj"], [80, 2, 1, "", "from_file_map"], [80, 2, 1, "", "from_filename"], [80, 2, 1, "", "get_data"], [80, 2, 1, "", "get_fdata"], [80, 5, 1, "", "in_memory"], [80, 2, 1, "", "load"], [80, 5, 1, "", "ndim"], [80, 5, 1, "", "shape"], [80, 2, 1, "", "uncache"]], "nibabel.deprecated": [[81, 1, 1, "", "FutureWarningMixin"], [81, 1, 1, "", "ModuleProxy"], [81, 1, 1, "", "VisibleDeprecationWarning"], [81, 3, 1, "", "alert_future_error"]], "nibabel.deprecated.FutureWarningMixin": [[81, 2, 1, "", "__init__"], [81, 4, 1, "", "warn_message"]], "nibabel.deprecated.ModuleProxy": [[81, 2, 1, "", "__init__"]], "nibabel.deprecated.VisibleDeprecationWarning": [[81, 2, 1, "", "__init__"]], "nibabel.deprecator": [[82, 1, 1, "", "Deprecator"], [82, 1, 1, "", "ExpiredDeprecationError"]], "nibabel.deprecator.Deprecator": [[82, 2, 1, "", "__init__"], [82, 2, 1, "", "is_bad_version"]], "nibabel.deprecator.ExpiredDeprecationError": [[82, 2, 1, "", "__init__"]], "nibabel.dft": [[83, 1, 1, "", "CachingError"], [83, 1, 1, "", "DFTError"], [83, 1, 1, "", "InstanceStackError"], [83, 1, 1, "", "VolumeError"], [83, 3, 1, "", "clear_cache"], [83, 3, 1, "", "get_studies"], [83, 3, 1, "", "update_cache"]], "nibabel.dft.CachingError": [[83, 2, 1, "", "__init__"]], "nibabel.dft.DFTError": [[83, 2, 1, "", "__init__"]], "nibabel.dft.InstanceStackError": [[83, 2, 1, "", "__init__"]], "nibabel.dft.VolumeError": [[83, 2, 1, "", "__init__"]], "nibabel.ecat": [[84, 1, 1, "", "EcatHeader"], [84, 1, 1, "", "EcatImage"], [84, 1, 1, "", "EcatImageArrayProxy"], [84, 1, 1, "", "EcatSubHeader"], [84, 3, 1, "", "get_frame_order"], [84, 3, 1, "", "get_series_framenumbers"], [84, 3, 1, "", "read_mlist"], [84, 3, 1, "", "read_subheaders"]], "nibabel.ecat.EcatHeader": [[84, 2, 1, "", "__init__"], [84, 2, 1, "", "default_structarr"], [84, 2, 1, "", "get_data_dtype"], [84, 2, 1, "", "get_filetype"], [84, 2, 1, "", "get_patient_orient"], [84, 2, 1, "", "guessed_endian"], [84, 4, 1, "", "template_dtype"]], "nibabel.ecat.EcatImage": [[84, 4, 1, "", "ImageArrayProxy"], [84, 2, 1, "", "__init__"], [84, 5, 1, "", "affine"], [84, 4, 1, "", "files_types"], [84, 2, 1, "", "from_file_map"], [84, 2, 1, "", "from_image"], [84, 2, 1, "", "get_data_dtype"], [84, 2, 1, "", "get_frame"], [84, 2, 1, "", "get_frame_affine"], [84, 2, 1, "", "get_mlist"], [84, 2, 1, "", "get_subheaders"], [84, 4, 1, "", "header_class"], [84, 2, 1, "", "load"], [84, 5, 1, "", "shape"], [84, 4, 1, "", "subheader_class"], [84, 2, 1, "", "to_file_map"], [84, 4, 1, "", "valid_exts"]], "nibabel.ecat.EcatImageArrayProxy": [[84, 2, 1, "", "__init__"], [84, 5, 1, "", "is_proxy"], [84, 5, 1, "", "ndim"], [84, 5, 1, "", "shape"]], "nibabel.ecat.EcatSubHeader": [[84, 2, 1, "", "__init__"], [84, 2, 1, "", "data_from_fileobj"], [84, 2, 1, "", "get_frame_affine"], [84, 2, 1, "", "get_nframes"], [84, 2, 1, "", "get_shape"], [84, 2, 1, "", "get_zooms"], [84, 2, 1, "", "raw_data_from_fileobj"]], "nibabel.environment": [[85, 3, 1, "", "get_home_dir"], [85, 3, 1, "", "get_nipy_system_dir"], [85, 3, 1, "", "get_nipy_user_dir"]], "nibabel.eulerangles": [[86, 3, 1, "", "angle_axis2euler"], [86, 3, 1, "", "euler2angle_axis"], [86, 3, 1, "", "euler2mat"], [86, 3, 1, "", "euler2quat"], [86, 3, 1, "", "mat2euler"], [86, 3, 1, "", "quat2euler"]], "nibabel.filebasedimages": [[87, 1, 1, "", "FileBasedHeader"], [87, 1, 1, "", "FileBasedImage"], [87, 1, 1, "", "ImageFileError"], [87, 1, 1, "", "SerializableImage"]], "nibabel.filebasedimages.FileBasedHeader": [[87, 2, 1, "", "__init__"], [87, 2, 1, "", "copy"], [87, 2, 1, "", "from_fileobj"], [87, 2, 1, "", "from_header"], [87, 2, 1, "", "write_to"]], "nibabel.filebasedimages.FileBasedImage": [[87, 2, 1, "", "__init__"], [87, 4, 1, "", "files_types"], [87, 2, 1, "", "filespec_to_file_map"], [87, 2, 1, "", "from_file_map"], [87, 2, 1, "", "from_filename"], [87, 2, 1, "", "from_image"], [87, 2, 1, "", "get_filename"], [87, 5, 1, "", "header"], [87, 4, 1, "", "header_class"], [87, 2, 1, "", "instance_to_filename"], [87, 2, 1, "", "load"], [87, 2, 1, "", "make_file_map"], [87, 4, 1, "", "makeable"], [87, 2, 1, "", "path_maybe_image"], [87, 4, 1, "", "rw"], [87, 2, 1, "", "set_filename"], [87, 2, 1, "", "to_file_map"], [87, 2, 1, "", "to_filename"], [87, 4, 1, "", "valid_exts"]], "nibabel.filebasedimages.ImageFileError": [[87, 2, 1, "", "__init__"]], "nibabel.filebasedimages.SerializableImage": [[87, 2, 1, "", "__init__"], [87, 2, 1, "", "from_bytes"], [87, 2, 1, "", "from_stream"], [87, 2, 1, "", "from_url"], [87, 2, 1, "", "to_bytes"], [87, 2, 1, "", "to_stream"]], "nibabel.fileholders": [[88, 1, 1, "", "FileHolder"], [88, 1, 1, "", "FileHolderError"], [88, 3, 1, "", "copy_file_map"]], "nibabel.fileholders.FileHolder": [[88, 2, 1, "", "__init__"], [88, 5, 1, "", "file_like"], [88, 2, 1, "", "get_prepare_fileobj"], [88, 2, 1, "", "same_file_as"]], "nibabel.fileholders.FileHolderError": [[88, 2, 1, "", "__init__"]], "nibabel.filename_parser": [[89, 1, 1, "", "TypesFilenamesError"], [89, 3, 1, "", "parse_filename"], [89, 3, 1, "", "splitext_addext"], [89, 3, 1, "", "types_filenames"]], "nibabel.filename_parser.TypesFilenamesError": [[89, 2, 1, "", "__init__"]], "nibabel.fileslice": [[90, 3, 1, "", "calc_slicedefs"], [90, 3, 1, "", "canonical_slicers"], [90, 3, 1, "", "fileslice"], [90, 3, 1, "", "fill_slicer"], [90, 3, 1, "", "is_fancy"], [90, 3, 1, "", "optimize_read_slicers"], [90, 3, 1, "", "optimize_slicer"], [90, 3, 1, "", "predict_shape"], [90, 3, 1, "", "read_segments"], [90, 3, 1, "", "slice2len"], [90, 3, 1, "", "slice2outax"], [90, 3, 1, "", "slicers2segments"], [90, 3, 1, "", "strided_scalar"], [90, 3, 1, "", "threshold_heuristic"]], "nibabel.fileutils": [[91, 3, 1, "", "read_zt_byte_strings"]], "nibabel.freesurfer": [[92, 0, 0, "-", "io"], [92, 0, 0, "-", "mghformat"]], "nibabel.freesurfer.io": [[92, 3, 1, "", "read_annot"], [92, 3, 1, "", "read_geometry"], [92, 3, 1, "", "read_label"], [92, 3, 1, "", "read_morph_data"], [92, 3, 1, "", "write_annot"], [92, 3, 1, "", "write_geometry"], [92, 3, 1, "", "write_morph_data"]], "nibabel.freesurfer.mghformat": [[92, 1, 1, "", "MGHError"], [92, 1, 1, "", "MGHHeader"], [92, 1, 1, "", "MGHImage"]], "nibabel.freesurfer.mghformat.MGHError": [[92, 2, 1, "", "__init__"]], "nibabel.freesurfer.mghformat.MGHHeader": [[92, 2, 1, "", "__init__"], [92, 2, 1, "", "as_byteswapped"], [92, 2, 1, "", "chk_version"], [92, 2, 1, "", "copy"], [92, 2, 1, "", "data_from_fileobj"], [92, 2, 1, "", "default_structarr"], [92, 2, 1, "", "diagnose_binaryblock"], [92, 2, 1, "", "from_fileobj"], [92, 2, 1, "", "from_header"], [92, 2, 1, "", "get_affine"], [92, 2, 1, "", "get_best_affine"], [92, 2, 1, "", "get_data_bytespervox"], [92, 2, 1, "", "get_data_dtype"], [92, 2, 1, "", "get_data_offset"], [92, 2, 1, "", "get_data_shape"], [92, 2, 1, "", "get_data_size"], [92, 2, 1, "", "get_footer_offset"], [92, 2, 1, "", "get_ras2vox"], [92, 2, 1, "", "get_slope_inter"], [92, 2, 1, "", "get_vox2ras"], [92, 2, 1, "", "get_vox2ras_tkr"], [92, 2, 1, "", "get_zooms"], [92, 2, 1, "", "guessed_endian"], [92, 2, 1, "", "set_data_dtype"], [92, 2, 1, "", "set_data_shape"], [92, 2, 1, "", "set_zooms"], [92, 4, 1, "", "template_dtype"], [92, 2, 1, "", "writeftr_to"], [92, 2, 1, "", "writehdr_to"]], "nibabel.freesurfer.mghformat.MGHImage": [[92, 4, 1, "", "ImageArrayProxy"], [92, 2, 1, "", "__init__"], [92, 4, 1, "", "files_types"], [92, 2, 1, "", "filespec_to_file_map"], [92, 2, 1, "", "from_file_map"], [92, 4, 1, "", "header_class"], [92, 4, 1, "", "makeable"], [92, 4, 1, "", "rw"], [92, 2, 1, "", "to_file_map"], [92, 4, 1, "", "valid_exts"]], "nibabel.funcs": [[93, 3, 1, "", "as_closest_canonical"], [93, 3, 1, "", "concat_images"], [93, 3, 1, "", "four_to_three"], [93, 3, 1, "", "squeeze_image"]], "nibabel.gifti": [[94, 0, 0, "-", "gifti"], [94, 0, 0, "-", "parse_gifti_fast"], [94, 0, 0, "-", "util"]], "nibabel.gifti.gifti": [[94, 1, 1, "", "GiftiCoordSystem"], [94, 1, 1, "", "GiftiDataArray"], [94, 1, 1, "", "GiftiImage"], [94, 1, 1, "", "GiftiLabel"], [94, 1, 1, "", "GiftiLabelTable"], [94, 1, 1, "", "GiftiMetaData"], [94, 1, 1, "", "GiftiNVPairs"]], "nibabel.gifti.gifti.GiftiCoordSystem": [[94, 2, 1, "", "__init__"], [94, 2, 1, "", "print_summary"]], "nibabel.gifti.gifti.GiftiDataArray": [[94, 2, 1, "", "__init__"], [94, 5, 1, "", "metadata"], [94, 5, 1, "", "num_dim"], [94, 2, 1, "", "print_summary"]], "nibabel.gifti.gifti.GiftiImage": [[94, 2, 1, "", "__init__"], [94, 2, 1, "", "add_gifti_data_array"], [94, 2, 1, "", "agg_data"], [94, 4, 1, "", "files_types"], [94, 2, 1, "", "from_file_map"], [94, 2, 1, "", "from_filename"], [94, 2, 1, "", "get_arrays_from_intent"], [94, 5, 1, "", "labeltable"], [94, 5, 1, "", "meta"], [94, 5, 1, "", "numDA"], [94, 4, 1, "", "parser"], [94, 2, 1, "", "print_summary"], [94, 2, 1, "", "remove_gifti_data_array"], [94, 2, 1, "", "remove_gifti_data_array_by_intent"], [94, 2, 1, "", "to_bytes"], [94, 2, 1, "", "to_file_map"], [94, 2, 1, "", "to_xml"], [94, 4, 1, "", "valid_exts"]], "nibabel.gifti.gifti.GiftiLabel": [[94, 2, 1, "", "__init__"], [94, 5, 1, "", "rgba"]], "nibabel.gifti.gifti.GiftiLabelTable": [[94, 2, 1, "", "__init__"], [94, 2, 1, "", "get_labels_as_dict"], [94, 2, 1, "", "print_summary"]], "nibabel.gifti.gifti.GiftiMetaData": [[94, 2, 1, "", "__init__"], [94, 5, 1, "", "data"], [94, 2, 1, "", "from_dict"], [94, 5, 1, "", "metadata"], [94, 2, 1, "", "print_summary"]], "nibabel.gifti.gifti.GiftiNVPairs": [[94, 2, 1, "", "__init__"], [94, 5, 1, "", "name"], [94, 5, 1, "", "value"]], "nibabel.gifti.parse_gifti_fast": [[94, 1, 1, "", "GiftiImageParser"], [94, 1, 1, "", "GiftiParseError"], [94, 3, 1, "", "read_data_block"]], "nibabel.gifti.parse_gifti_fast.GiftiImageParser": [[94, 2, 1, "", "CharacterDataHandler"], [94, 2, 1, "", "EndElementHandler"], [94, 2, 1, "", "StartElementHandler"], [94, 2, 1, "", "__init__"], [94, 2, 1, "", "flush_chardata"], [94, 5, 1, "", "pending_data"]], "nibabel.gifti.parse_gifti_fast.GiftiParseError": [[94, 2, 1, "", "__init__"]], "nibabel.imageclasses": [[95, 3, 1, "", "spatial_axes_first"]], "nibabel.imageglobals": [[96, 1, 1, "", "ErrorLevel"], [96, 1, 1, "", "LoggingOutputSuppressor"]], "nibabel.imageglobals.ErrorLevel": [[96, 2, 1, "", "__init__"]], "nibabel.imageglobals.LoggingOutputSuppressor": [[96, 2, 1, "", "__init__"]], "nibabel.imagestats": [[97, 3, 1, "", "count_nonzero_voxels"], [97, 3, 1, "", "mask_volume"]], "nibabel.loadsave": [[98, 3, 1, "", "guessed_image_type"], [98, 3, 1, "", "load"], [98, 3, 1, "", "read_img_data"], [98, 3, 1, "", "save"]], "nibabel.minc1": [[99, 1, 1, "", "Minc1File"], [99, 1, 1, "", "Minc1Header"], [99, 1, 1, "", "Minc1Image"], [99, 1, 1, "", "MincError"], [99, 1, 1, "", "MincHeader"], [99, 1, 1, "", "MincImageArrayProxy"]], "nibabel.minc1.Minc1File": [[99, 2, 1, "", "__init__"], [99, 2, 1, "", "get_affine"], [99, 2, 1, "", "get_data_dtype"], [99, 2, 1, "", "get_data_shape"], [99, 2, 1, "", "get_scaled_data"], [99, 2, 1, "", "get_zooms"]], "nibabel.minc1.Minc1Header": [[99, 2, 1, "", "__init__"], [99, 2, 1, "", "may_contain_header"]], "nibabel.minc1.Minc1Image": [[99, 4, 1, "", "ImageArrayProxy"], [99, 2, 1, "", "__init__"], [99, 4, 1, "", "files_types"], [99, 2, 1, "", "from_file_map"], [99, 4, 1, "", "header_class"], [99, 4, 1, "", "makeable"], [99, 4, 1, "", "rw"], [99, 4, 1, "", "valid_exts"]], "nibabel.minc1.MincError": [[99, 2, 1, "", "__init__"]], "nibabel.minc1.MincHeader": [[99, 2, 1, "", "__init__"], [99, 2, 1, "", "data_from_fileobj"], [99, 4, 1, "", "data_layout"], [99, 2, 1, "", "data_to_fileobj"]], "nibabel.minc1.MincImageArrayProxy": [[99, 2, 1, "", "__init__"], [99, 5, 1, "", "is_proxy"], [99, 5, 1, "", "ndim"], [99, 5, 1, "", "shape"]], "nibabel.minc2": [[100, 1, 1, "", "Hdf5Bunch"], [100, 1, 1, "", "Minc2File"], [100, 1, 1, "", "Minc2Header"], [100, 1, 1, "", "Minc2Image"]], "nibabel.minc2.Hdf5Bunch": [[100, 2, 1, "", "__init__"]], "nibabel.minc2.Minc2File": [[100, 2, 1, "", "__init__"], [100, 2, 1, "", "get_data_dtype"], [100, 2, 1, "", "get_data_shape"], [100, 2, 1, "", "get_scaled_data"]], "nibabel.minc2.Minc2Header": [[100, 2, 1, "", "__init__"], [100, 2, 1, "", "may_contain_header"]], "nibabel.minc2.Minc2Image": [[100, 2, 1, "", "__init__"], [100, 2, 1, "", "from_file_map"], [100, 4, 1, "", "header_class"]], "nibabel.mriutils": [[101, 1, 1, "", "MRIError"], [101, 3, 1, "", "calculate_dwell_time"]], "nibabel.mriutils.MRIError": [[101, 2, 1, "", "__init__"]], "nibabel.nicom": [[102, 0, 0, "-", "ascconv"], [102, 0, 0, "-", "csareader"], [102, 0, 0, "-", "dicomreaders"], [102, 0, 0, "-", "dicomwrappers"], [102, 0, 0, "-", "dwiparams"], [102, 0, 0, "-", "structreader"], [102, 0, 0, "-", "utils"]], "nibabel.nicom.ascconv": [[102, 1, 1, "", "AscconvParseError"], [102, 1, 1, "", "Atom"], [102, 1, 1, "", "NoValue"], [102, 3, 1, "", "assign2atoms"], [102, 3, 1, "", "obj_from_atoms"], [102, 3, 1, "", "parse_ascconv"]], "nibabel.nicom.ascconv.AscconvParseError": [[102, 2, 1, "", "__init__"]], "nibabel.nicom.ascconv.Atom": [[102, 2, 1, "", "__init__"]], "nibabel.nicom.ascconv.NoValue": [[102, 2, 1, "", "__init__"]], "nibabel.nicom.csareader": [[102, 1, 1, "", "CSAError"], [102, 1, 1, "", "CSAReadError"], [102, 3, 1, "", "get_acq_mat_txt"], [102, 3, 1, "", "get_b_matrix"], [102, 3, 1, "", "get_b_value"], [102, 3, 1, "", "get_csa_header"], [102, 3, 1, "", "get_g_vector"], [102, 3, 1, "", "get_ice_dims"], [102, 3, 1, "", "get_n_mosaic"], [102, 3, 1, "", "get_scalar"], [102, 3, 1, "", "get_slice_normal"], [102, 3, 1, "", "get_vector"], [102, 3, 1, "", "is_mosaic"], [102, 3, 1, "", "nt_str"], [102, 3, 1, "", "read"]], "nibabel.nicom.csareader.CSAError": [[102, 2, 1, "", "__init__"]], "nibabel.nicom.csareader.CSAReadError": [[102, 2, 1, "", "__init__"]], "nibabel.nicom.dicomreaders": [[102, 1, 1, "", "DicomReadError"], [102, 3, 1, "", "mosaic_to_nii"], [102, 3, 1, "", "read_mosaic_dir"], [102, 3, 1, "", "read_mosaic_dwi_dir"], [102, 3, 1, "", "slices_to_series"]], "nibabel.nicom.dicomreaders.DicomReadError": [[102, 2, 1, "", "__init__"]], "nibabel.nicom.dicomwrappers": [[102, 1, 1, "", "MosaicWrapper"], [102, 1, 1, "", "MultiframeWrapper"], [102, 1, 1, "", "SiemensWrapper"], [102, 1, 1, "", "Wrapper"], [102, 1, 1, "", "WrapperError"], [102, 1, 1, "", "WrapperPrecisionError"], [102, 3, 1, "", "none_or_close"], [102, 3, 1, "", "wrapper_from_data"], [102, 3, 1, "", "wrapper_from_file"]], "nibabel.nicom.dicomwrappers.MosaicWrapper": [[102, 2, 1, "", "__init__"], [102, 2, 1, "", "get_data"], [102, 2, 1, "", "image_position"], [102, 2, 1, "", "image_shape"], [102, 4, 1, "", "is_mosaic"]], "nibabel.nicom.dicomwrappers.MultiframeWrapper": [[102, 2, 1, "", "__init__"], [102, 2, 1, "", "get_data"], [102, 2, 1, "", "image_orient_patient"], [102, 2, 1, "", "image_position"], [102, 2, 1, "", "image_shape"], [102, 4, 1, "", "is_multiframe"], [102, 2, 1, "", "series_signature"], [102, 2, 1, "", "voxel_sizes"]], "nibabel.nicom.dicomwrappers.SiemensWrapper": [[102, 2, 1, "", "__init__"], [102, 2, 1, "", "b_matrix"], [102, 4, 1, "", "is_csa"], [102, 2, 1, "", "q_vector"], [102, 2, 1, "", "series_signature"], [102, 2, 1, "", "slice_normal"]], "nibabel.nicom.dicomwrappers.Wrapper": [[102, 2, 1, "", "__init__"], [102, 5, 1, "", "affine"], [102, 4, 1, "", "b_matrix"], [102, 2, 1, "", "b_value"], [102, 2, 1, "", "b_vector"], [102, 2, 1, "", "get"], [102, 2, 1, "", "get_data"], [102, 2, 1, "", "get_pixel_array"], [102, 2, 1, "", "image_orient_patient"], [102, 2, 1, "", "image_position"], [102, 2, 1, "", "image_shape"], [102, 2, 1, "", "instance_number"], [102, 4, 1, "", "is_csa"], [102, 4, 1, "", "is_mosaic"], [102, 4, 1, "", "is_multiframe"], [102, 2, 1, "", "is_same_series"], [102, 4, 1, "", "q_vector"], [102, 2, 1, "", "rotation_matrix"], [102, 2, 1, "", "series_signature"], [102, 2, 1, "", "slice_indicator"], [102, 2, 1, "", "slice_normal"], [102, 2, 1, "", "voxel_sizes"]], "nibabel.nicom.dicomwrappers.WrapperError": [[102, 2, 1, "", "__init__"]], "nibabel.nicom.dicomwrappers.WrapperPrecisionError": [[102, 2, 1, "", "__init__"]], "nibabel.nicom.dwiparams": [[102, 3, 1, "", "B2q"], [102, 3, 1, "", "nearest_pos_semi_def"], [102, 3, 1, "", "q2bg"]], "nibabel.nicom.structreader": [[102, 1, 1, "", "Unpacker"]], "nibabel.nicom.structreader.Unpacker": [[102, 2, 1, "", "__init__"], [102, 2, 1, "", "read"], [102, 2, 1, "", "unpack"]], "nibabel.nicom.utils": [[102, 3, 1, "", "find_private_section"]], "nibabel.nifti1": [[103, 1, 1, "", "Nifti1DicomExtension"], [103, 1, 1, "", "Nifti1Extension"], [103, 1, 1, "", "Nifti1Extensions"], [103, 1, 1, "", "Nifti1Header"], [103, 1, 1, "", "Nifti1Image"], [103, 1, 1, "", "Nifti1Pair"], [103, 1, 1, "", "Nifti1PairHeader"], [103, 3, 1, "", "load"], [103, 3, 1, "", "save"]], "nibabel.nifti1.Nifti1DicomExtension": [[103, 2, 1, "", "__init__"]], "nibabel.nifti1.Nifti1Extension": [[103, 2, 1, "", "__init__"], [103, 2, 1, "", "get_code"], [103, 2, 1, "", "get_content"], [103, 2, 1, "", "get_sizeondisk"], [103, 2, 1, "", "write_to"]], "nibabel.nifti1.Nifti1Extensions": [[103, 2, 1, "", "__init__"], [103, 2, 1, "", "count"], [103, 2, 1, "", "from_fileobj"], [103, 2, 1, "", "get_codes"], [103, 2, 1, "", "get_sizeondisk"], [103, 2, 1, "", "write_to"]], "nibabel.nifti1.Nifti1Header": [[103, 2, 1, "", "__init__"], [103, 2, 1, "", "copy"], [103, 2, 1, "", "default_structarr"], [103, 4, 1, "", "exts_klass"], [103, 2, 1, "", "from_fileobj"], [103, 2, 1, "", "from_header"], [103, 2, 1, "", "get_best_affine"], [103, 2, 1, "", "get_data_shape"], [103, 2, 1, "", "get_dim_info"], [103, 2, 1, "", "get_intent"], [103, 2, 1, "", "get_n_slices"], [103, 2, 1, "", "get_qform"], [103, 2, 1, "", "get_qform_quaternion"], [103, 2, 1, "", "get_sform"], [103, 2, 1, "", "get_slice_duration"], [103, 2, 1, "", "get_slice_times"], [103, 2, 1, "", "get_slope_inter"], [103, 2, 1, "", "get_xyzt_units"], [103, 4, 1, "", "has_data_intercept"], [103, 4, 1, "", "has_data_slope"], [103, 4, 1, "", "is_single"], [103, 2, 1, "", "may_contain_header"], [103, 4, 1, "", "pair_magic"], [103, 4, 1, "", "pair_vox_offset"], [103, 4, 1, "", "quaternion_threshold"], [103, 2, 1, "", "set_data_dtype"], [103, 2, 1, "", "set_data_shape"], [103, 2, 1, "", "set_dim_info"], [103, 2, 1, "", "set_intent"], [103, 2, 1, "", "set_qform"], [103, 2, 1, "", "set_sform"], [103, 2, 1, "", "set_slice_duration"], [103, 2, 1, "", "set_slice_times"], [103, 2, 1, "", "set_slope_inter"], [103, 2, 1, "", "set_xyzt_units"], [103, 4, 1, "", "single_magic"], [103, 4, 1, "", "single_vox_offset"], [103, 4, 1, "", "template_dtype"], [103, 2, 1, "", "write_to"]], "nibabel.nifti1.Nifti1Image": [[103, 2, 1, "", "__init__"], [103, 4, 1, "", "files_types"], [103, 4, 1, "", "header_class"], [103, 2, 1, "", "update_header"], [103, 4, 1, "", "valid_exts"]], "nibabel.nifti1.Nifti1Pair": [[103, 2, 1, "", "__init__"], [103, 2, 1, "", "as_reoriented"], [103, 2, 1, "", "get_data_dtype"], [103, 2, 1, "", "get_qform"], [103, 2, 1, "", "get_sform"], [103, 4, 1, "", "header_class"], [103, 4, 1, "", "rw"], [103, 2, 1, "", "set_data_dtype"], [103, 2, 1, "", "set_qform"], [103, 2, 1, "", "set_sform"], [103, 2, 1, "", "to_file_map"], [103, 2, 1, "", "update_header"]], "nibabel.nifti1.Nifti1PairHeader": [[103, 2, 1, "", "__init__"], [103, 4, 1, "", "is_single"]], "nibabel.nifti2": [[104, 1, 1, "", "Nifti2Header"], [104, 1, 1, "", "Nifti2Image"], [104, 1, 1, "", "Nifti2Pair"], [104, 1, 1, "", "Nifti2PairHeader"], [104, 3, 1, "", "load"], [104, 3, 1, "", "save"]], "nibabel.nifti2.Nifti2Header": [[104, 2, 1, "", "__init__"], [104, 2, 1, "", "default_structarr"], [104, 2, 1, "", "get_data_shape"], [104, 2, 1, "", "may_contain_header"], [104, 4, 1, "", "pair_magic"], [104, 4, 1, "", "pair_vox_offset"], [104, 4, 1, "", "quaternion_threshold"], [104, 2, 1, "", "set_data_shape"], [104, 4, 1, "", "single_magic"], [104, 4, 1, "", "single_vox_offset"], [104, 4, 1, "", "sizeof_hdr"], [104, 4, 1, "", "template_dtype"]], "nibabel.nifti2.Nifti2Image": [[104, 2, 1, "", "__init__"], [104, 4, 1, "", "header_class"]], "nibabel.nifti2.Nifti2Pair": [[104, 2, 1, "", "__init__"], [104, 4, 1, "", "header_class"]], "nibabel.nifti2.Nifti2PairHeader": [[104, 2, 1, "", "__init__"], [104, 4, 1, "", "is_single"]], "nibabel.onetime": [[105, 1, 1, "", "OneTimeProperty"], [105, 1, 1, "", "ResetMixin"], [105, 3, 1, "", "auto_attr"], [105, 3, 1, "", "setattr_on_read"]], "nibabel.onetime.OneTimeProperty": [[105, 2, 1, "", "__init__"]], "nibabel.onetime.ResetMixin": [[105, 2, 1, "", "__init__"], [105, 2, 1, "", "reset"]], "nibabel.openers": [[106, 1, 1, "", "DeterministicGzipFile"], [106, 1, 1, "", "Fileish"], [106, 1, 1, "", "ImageOpener"], [106, 1, 1, "", "Opener"]], "nibabel.openers.DeterministicGzipFile": [[106, 2, 1, "", "__init__"]], "nibabel.openers.Fileish": [[106, 2, 1, "", "__init__"], [106, 2, 1, "", "read"], [106, 2, 1, "", "write"]], "nibabel.openers.ImageOpener": [[106, 2, 1, "", "__init__"], [106, 4, 1, "", "compress_ext_map"]], "nibabel.openers.Opener": [[106, 2, 1, "", "__init__"], [106, 4, 1, "", "bz2_def"], [106, 2, 1, "", "close"], [106, 2, 1, "", "close_if_mine"], [106, 5, 1, "", "closed"], [106, 4, 1, "", "compress_ext_icase"], [106, 4, 1, "", "compress_ext_map"], [106, 4, 1, "", "default_compresslevel"], [106, 4, 1, "", "default_level_or_option"], [106, 4, 1, "", "default_zst_compresslevel"], [106, 2, 1, "", "fileno"], [106, 4, 1, "", "fobj"], [106, 4, 1, "", "gz_def"], [106, 5, 1, "", "mode"], [106, 5, 1, "", "name"], [106, 2, 1, "", "read"], [106, 2, 1, "", "readinto"], [106, 2, 1, "", "seek"], [106, 2, 1, "", "tell"], [106, 2, 1, "", "write"], [106, 4, 1, "", "zstd_def"]], "nibabel.optpkg": [[107, 3, 1, "", "optional_package"]], "nibabel.orientations": [[108, 1, 1, "", "OrientationError"], [108, 3, 1, "", "aff2axcodes"], [108, 3, 1, "", "apply_orientation"], [108, 3, 1, "", "axcodes2ornt"], [108, 3, 1, "", "flip_axis"], [108, 3, 1, "", "inv_ornt_aff"], [108, 3, 1, "", "io_orientation"], [108, 3, 1, "", "ornt2axcodes"], [108, 3, 1, "", "ornt_transform"]], "nibabel.orientations.OrientationError": [[108, 2, 1, "", "__init__"]], "nibabel.parrec": [[109, 1, 1, "", "PARRECArrayProxy"], [109, 1, 1, "", "PARRECError"], [109, 1, 1, "", "PARRECHeader"], [109, 1, 1, "", "PARRECImage"], [109, 3, 1, "", "exts2pars"], [109, 3, 1, "", "one_line"], [109, 3, 1, "", "parse_PAR_header"], [109, 3, 1, "", "vol_is_full"], [109, 3, 1, "", "vol_numbers"]], "nibabel.parrec.PARRECArrayProxy": [[109, 2, 1, "", "__init__"], [109, 5, 1, "", "dtype"], [109, 2, 1, "", "get_unscaled"], [109, 5, 1, "", "is_proxy"], [109, 5, 1, "", "ndim"], [109, 5, 1, "", "shape"]], "nibabel.parrec.PARRECError": [[109, 2, 1, "", "__init__"]], "nibabel.parrec.PARRECHeader": [[109, 2, 1, "", "__init__"], [109, 2, 1, "", "as_analyze_map"], [109, 2, 1, "", "copy"], [109, 2, 1, "", "from_fileobj"], [109, 2, 1, "", "from_header"], [109, 2, 1, "", "get_affine"], [109, 2, 1, "", "get_bvals_bvecs"], [109, 2, 1, "", "get_data_offset"], [109, 2, 1, "", "get_data_scaling"], [109, 2, 1, "", "get_def"], [109, 2, 1, "", "get_echo_train_length"], [109, 2, 1, "", "get_q_vectors"], [109, 2, 1, "", "get_rec_shape"], [109, 2, 1, "", "get_slice_orientation"], [109, 2, 1, "", "get_sorted_slice_indices"], [109, 2, 1, "", "get_volume_labels"], [109, 2, 1, "", "get_water_fat_shift"], [109, 2, 1, "", "set_data_offset"]], "nibabel.parrec.PARRECImage": [[109, 4, 1, "", "ImageArrayProxy"], [109, 2, 1, "", "__init__"], [109, 4, 1, "", "files_types"], [109, 2, 1, "", "from_file_map"], [109, 2, 1, "", "from_filename"], [109, 4, 1, "", "header_class"], [109, 2, 1, "", "load"], [109, 4, 1, "", "makeable"], [109, 4, 1, "", "rw"], [109, 4, 1, "", "valid_exts"]], "nibabel.pointset": [[110, 1, 1, "", "CoordinateArray"], [110, 1, 1, "", "Grid"], [110, 1, 1, "", "GridIndices"], [110, 1, 1, "", "Pointset"]], "nibabel.pointset.CoordinateArray": [[110, 2, 1, "", "__init__"], [110, 4, 1, "", "ndim"], [110, 4, 1, "", "shape"]], "nibabel.pointset.Grid": [[110, 2, 1, "", "__init__"], [110, 2, 1, "", "from_image"], [110, 2, 1, "", "from_mask"], [110, 2, 1, "", "to_mask"]], "nibabel.pointset.GridIndices": [[110, 2, 1, "", "__init__"], [110, 4, 1, "", "dtype"], [110, 4, 1, "", "gridshape"], [110, 4, 1, "", "ndim"], [110, 4, 1, "", "shape"]], "nibabel.pointset.Pointset": [[110, 2, 1, "", "__init__"], [110, 4, 1, "", "affine"], [110, 4, 1, "", "coordinates"], [110, 5, 1, "", "dim"], [110, 2, 1, "", "get_coords"], [110, 4, 1, "", "homogeneous"], [110, 5, 1, "", "n_coords"]], "nibabel.processing": [[111, 3, 1, "", "adapt_affine"], [111, 3, 1, "", "conform"], [111, 3, 1, "", "fwhm2sigma"], [111, 3, 1, "", "resample_from_to"], [111, 3, 1, "", "resample_to_output"], [111, 3, 1, "", "sigma2fwhm"], [111, 3, 1, "", "smooth_image"]], "nibabel.pydicom_compat": [[112, 3, 1, "", "dicom_test"]], "nibabel.quaternions": [[113, 3, 1, "", "angle_axis2mat"], [113, 3, 1, "", "angle_axis2quat"], [113, 3, 1, "", "conjugate"], [113, 3, 1, "", "eye"], [113, 3, 1, "", "fillpositive"], [113, 3, 1, "", "inverse"], [113, 3, 1, "", "isunit"], [113, 3, 1, "", "mat2quat"], [113, 3, 1, "", "mult"], [113, 3, 1, "", "nearly_equivalent"], [113, 3, 1, "", "norm"], [113, 3, 1, "", "quat2angle_axis"], [113, 3, 1, "", "quat2mat"], [113, 3, 1, "", "rotate_vector"]], "nibabel.rstutils": [[114, 3, 1, "", "rst_table"]], "nibabel.spaces": [[115, 3, 1, "", "slice2volume"], [115, 3, 1, "", "vox2out_vox"]], "nibabel.spatialimages": [[116, 1, 1, "", "HasDtype"], [116, 1, 1, "", "HeaderDataError"], [116, 1, 1, "", "HeaderTypeError"], [116, 1, 1, "", "ImageDataError"], [116, 1, 1, "", "SpatialFirstSlicer"], [116, 1, 1, "", "SpatialHeader"], [116, 1, 1, "", "SpatialImage"], [116, 1, 1, "", "SpatialProtocol"], [116, 3, 1, "", "supported_np_types"]], "nibabel.spatialimages.HasDtype": [[116, 2, 1, "", "__init__"], [116, 2, 1, "", "get_data_dtype"], [116, 2, 1, "", "set_data_dtype"]], "nibabel.spatialimages.HeaderDataError": [[116, 2, 1, "", "__init__"]], "nibabel.spatialimages.HeaderTypeError": [[116, 2, 1, "", "__init__"]], "nibabel.spatialimages.ImageDataError": [[116, 2, 1, "", "__init__"]], "nibabel.spatialimages.SpatialFirstSlicer": [[116, 2, 1, "", "__init__"], [116, 2, 1, "", "check_slicing"], [116, 4, 1, "", "img"], [116, 2, 1, "", "slice_affine"]], "nibabel.spatialimages.SpatialHeader": [[116, 2, 1, "", "__init__"], [116, 2, 1, "", "copy"], [116, 2, 1, "", "data_from_fileobj"], [116, 4, 1, "", "data_layout"], [116, 2, 1, "", "data_to_fileobj"], [116, 4, 1, "", "default_x_flip"], [116, 2, 1, "", "from_header"], [116, 2, 1, "", "get_base_affine"], [116, 2, 1, "", "get_best_affine"], [116, 2, 1, "", "get_data_dtype"], [116, 2, 1, "", "get_data_shape"], [116, 2, 1, "", "get_zooms"], [116, 2, 1, "", "set_data_dtype"], [116, 2, 1, "", "set_data_shape"], [116, 2, 1, "", "set_zooms"]], "nibabel.spatialimages.SpatialImage": [[116, 4, 1, "", "ImageSlicer"], [116, 2, 1, "", "__init__"], [116, 5, 1, "", "affine"], [116, 2, 1, "", "as_reoriented"], [116, 2, 1, "", "from_image"], [116, 2, 1, "", "get_data_dtype"], [116, 4, 1, "", "header_class"], [116, 2, 1, "", "orthoview"], [116, 2, 1, "", "set_data_dtype"], [116, 5, 1, "", "slicer"], [116, 2, 1, "", "update_header"]], "nibabel.spatialimages.SpatialProtocol": [[116, 2, 1, "", "__init__"], [116, 2, 1, "", "get_data_dtype"], [116, 2, 1, "", "get_data_shape"], [116, 2, 1, "", "get_zooms"]], "nibabel.spm2analyze": [[117, 1, 1, "", "Spm2AnalyzeHeader"], [117, 1, 1, "", "Spm2AnalyzeImage"]], "nibabel.spm2analyze.Spm2AnalyzeHeader": [[117, 2, 1, "", "__init__"], [117, 2, 1, "", "get_slope_inter"], [117, 2, 1, "", "may_contain_header"], [117, 4, 1, "", "template_dtype"]], "nibabel.spm2analyze.Spm2AnalyzeImage": [[117, 2, 1, "", "__init__"], [117, 4, 1, "", "header_class"]], "nibabel.spm99analyze": [[118, 1, 1, "", "Spm99AnalyzeHeader"], [118, 1, 1, "", "Spm99AnalyzeImage"], [118, 1, 1, "", "SpmAnalyzeHeader"]], "nibabel.spm99analyze.Spm99AnalyzeHeader": [[118, 2, 1, "", "__init__"], [118, 2, 1, "", "get_best_affine"], [118, 2, 1, "", "get_origin_affine"], [118, 2, 1, "", "set_origin_from_affine"]], "nibabel.spm99analyze.Spm99AnalyzeImage": [[118, 2, 1, "", "__init__"], [118, 4, 1, "", "files_types"], [118, 2, 1, "", "from_file_map"], [118, 4, 1, "", "has_affine"], [118, 4, 1, "", "header_class"], [118, 4, 1, "", "makeable"], [118, 4, 1, "", "rw"], [118, 2, 1, "", "to_file_map"]], "nibabel.spm99analyze.SpmAnalyzeHeader": [[118, 2, 1, "", "__init__"], [118, 2, 1, "", "default_structarr"], [118, 2, 1, "", "get_slope_inter"], [118, 4, 1, "", "has_data_intercept"], [118, 4, 1, "", "has_data_slope"], [118, 2, 1, "", "set_slope_inter"], [118, 4, 1, "", "template_dtype"]], "nibabel.streamlines": [[119, 0, 0, "-", "array_sequence"], [119, 3, 1, "", "detect_format"], [119, 0, 0, "-", "header"], [119, 3, 1, "", "is_supported"], [119, 3, 1, "", "load"], [119, 3, 1, "", "save"], [119, 0, 0, "-", "tck"], [119, 0, 0, "-", "tractogram"], [119, 0, 0, "-", "tractogram_file"], [119, 0, 0, "-", "trk"], [119, 0, 0, "-", "utils"]], "nibabel.streamlines.array_sequence": [[119, 1, 1, "", "ArraySequence"], [119, 3, 1, "", "concatenate"], [119, 3, 1, "", "create_arraysequences_from_generator"], [119, 3, 1, "", "is_array_sequence"], [119, 3, 1, "", "is_ndarray_of_int_or_bool"]], "nibabel.streamlines.array_sequence.ArraySequence": [[119, 2, 1, "", "__init__"], [119, 2, 1, "", "append"], [119, 5, 1, "", "common_shape"], [119, 2, 1, "", "copy"], [119, 2, 1, "", "extend"], [119, 2, 1, "", "finalize_append"], [119, 2, 1, "", "get_data"], [119, 5, 1, "", "is_array_sequence"], [119, 5, 1, "", "is_sliced_view"], [119, 2, 1, "", "load"], [119, 2, 1, "", "save"], [119, 2, 1, "", "shrink_data"], [119, 5, 1, "", "total_nb_rows"]], "nibabel.streamlines.header": [[119, 1, 1, "", "Field"]], "nibabel.streamlines.header.Field": [[119, 4, 1, "", "DIMENSIONS"], [119, 4, 1, "", "ENDIANNESS"], [119, 4, 1, "", "MAGIC_NUMBER"], [119, 4, 1, "", "METHOD"], [119, 4, 1, "", "NB_POINTS"], [119, 4, 1, "", "NB_PROPERTIES_PER_STREAMLINE"], [119, 4, 1, "", "NB_SCALARS_PER_POINT"], [119, 4, 1, "", "NB_STREAMLINES"], [119, 4, 1, "", "ORIGIN"], [119, 4, 1, "", "STEP_SIZE"], [119, 4, 1, "", "VOXEL_ORDER"], [119, 4, 1, "", "VOXEL_SIZES"], [119, 4, 1, "", "VOXEL_TO_RASMM"], [119, 2, 1, "", "__init__"]], "nibabel.streamlines.tck": [[119, 1, 1, "", "TckFile"]], "nibabel.streamlines.tck.TckFile": [[119, 4, 1, "", "EOF_DELIMITER"], [119, 4, 1, "", "FIBER_DELIMITER"], [119, 4, 1, "", "MAGIC_NUMBER"], [119, 4, 1, "", "SUPPORTS_DATA_PER_POINT"], [119, 4, 1, "", "SUPPORTS_DATA_PER_STREAMLINE"], [119, 2, 1, "", "__init__"], [119, 2, 1, "", "create_empty_header"], [119, 2, 1, "", "is_correct_format"], [119, 2, 1, "", "load"], [119, 2, 1, "", "save"]], "nibabel.streamlines.tractogram": [[119, 1, 1, "", "LazyDict"], [119, 1, 1, "", "LazyTractogram"], [119, 1, 1, "", "PerArrayDict"], [119, 1, 1, "", "PerArraySequenceDict"], [119, 1, 1, "", "SliceableDataDict"], [119, 1, 1, "", "Tractogram"], [119, 1, 1, "", "TractogramItem"], [119, 3, 1, "", "is_data_dict"], [119, 3, 1, "", "is_lazy_dict"]], "nibabel.streamlines.tractogram.LazyDict": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.tractogram.LazyTractogram": [[119, 2, 1, "", "__init__"], [119, 2, 1, "", "apply_affine"], [119, 2, 1, "", "copy"], [119, 5, 1, "", "data"], [119, 5, 1, "", "data_per_point"], [119, 5, 1, "", "data_per_streamline"], [119, 2, 1, "", "extend"], [119, 2, 1, "", "from_data_func"], [119, 2, 1, "", "from_tractogram"], [119, 5, 1, "", "streamlines"], [119, 2, 1, "", "to_world"]], "nibabel.streamlines.tractogram.PerArrayDict": [[119, 2, 1, "", "__init__"], [119, 2, 1, "", "extend"]], "nibabel.streamlines.tractogram.PerArraySequenceDict": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.tractogram.SliceableDataDict": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.tractogram.Tractogram": [[119, 2, 1, "", "__init__"], [119, 5, 1, "", "affine_to_rasmm"], [119, 2, 1, "", "apply_affine"], [119, 2, 1, "", "copy"], [119, 5, 1, "", "data_per_point"], [119, 5, 1, "", "data_per_streamline"], [119, 2, 1, "", "extend"], [119, 5, 1, "", "streamlines"], [119, 2, 1, "", "to_world"]], "nibabel.streamlines.tractogram.TractogramItem": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.tractogram_file": [[119, 1, 1, "", "DataError"], [119, 1, 1, "", "DataWarning"], [119, 1, 1, "", "ExtensionWarning"], [119, 1, 1, "", "HeaderError"], [119, 1, 1, "", "HeaderWarning"], [119, 1, 1, "", "TractogramFile"], [119, 1, 1, "", "abstractclassmethod"]], "nibabel.streamlines.tractogram_file.DataError": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.tractogram_file.DataWarning": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.tractogram_file.ExtensionWarning": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.tractogram_file.HeaderError": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.tractogram_file.HeaderWarning": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.tractogram_file.TractogramFile": [[119, 2, 1, "", "__init__"], [119, 5, 1, "", "affine"], [119, 2, 1, "", "create_empty_header"], [119, 5, 1, "", "header"], [119, 2, 1, "", "is_correct_format"], [119, 2, 1, "", "load"], [119, 2, 1, "", "save"], [119, 5, 1, "", "streamlines"], [119, 5, 1, "", "tractogram"]], "nibabel.streamlines.tractogram_file.abstractclassmethod": [[119, 2, 1, "", "__init__"]], "nibabel.streamlines.trk": [[119, 1, 1, "", "TrkFile"], [119, 3, 1, "", "decode_value_from_name"], [119, 3, 1, "", "encode_value_in_name"], [119, 3, 1, "", "get_affine_rasmm_to_trackvis"], [119, 3, 1, "", "get_affine_trackvis_to_rasmm"]], "nibabel.streamlines.trk.TrkFile": [[119, 4, 1, "", "HEADER_SIZE"], [119, 4, 1, "", "MAGIC_NUMBER"], [119, 4, 1, "", "SUPPORTS_DATA_PER_POINT"], [119, 4, 1, "", "SUPPORTS_DATA_PER_STREAMLINE"], [119, 2, 1, "", "__init__"], [119, 2, 1, "", "create_empty_header"], [119, 2, 1, "", "is_correct_format"], [119, 2, 1, "", "load"], [119, 2, 1, "", "save"]], "nibabel.streamlines.utils": [[119, 3, 1, "", "get_affine_from_reference"], [119, 3, 1, "", "peek_next"]], "nibabel.tmpdirs": [[120, 3, 1, "", "InGivenDirectory"], [120, 3, 1, "", "InTemporaryDirectory"], [120, 1, 1, "", "TemporaryDirectory"]], "nibabel.tmpdirs.TemporaryDirectory": [[120, 2, 1, "", "__init__"]], "nibabel.tripwire": [[121, 1, 1, "", "TripWire"], [121, 1, 1, "", "TripWireError"], [121, 3, 1, "", "is_tripwire"]], "nibabel.tripwire.TripWire": [[121, 2, 1, "", "__init__"]], "nibabel.tripwire.TripWireError": [[121, 2, 1, "", "__init__"]], "nibabel.viewers": [[122, 1, 1, "", "OrthoSlicer3D"]], "nibabel.viewers.OrthoSlicer3D": [[122, 2, 1, "", "__init__"], [122, 5, 1, "", "clim"], [122, 2, 1, "", "close"], [122, 5, 1, "", "cmap"], [122, 2, 1, "", "draw"], [122, 5, 1, "", "figs"], [122, 2, 1, "", "link_to"], [122, 5, 1, "", "n_volumes"], [122, 5, 1, "", "position"], [122, 2, 1, "", "set_position"], [122, 2, 1, "", "set_volume_idx"], [122, 2, 1, "", "show"]], "nibabel.volumeutils": [[123, 1, 1, "", "DtypeMapper"], [123, 1, 1, "", "Recoder"], [123, 3, 1, "", "apply_read_scaling"], [123, 3, 1, "", "array_from_file"], [123, 3, 1, "", "array_to_file"], [123, 3, 1, "", "best_write_scale_ftype"], [123, 3, 1, "", "better_float_of"], [123, 3, 1, "", "finite_range"], [123, 3, 1, "", "fname_ext_ul_case"], [123, 3, 1, "", "int_scinter_ftype"], [123, 3, 1, "", "make_dt_codes"], [123, 3, 1, "", "pretty_mapping"], [123, 3, 1, "", "rec2dict"], [123, 3, 1, "", "seek_tell"], [123, 3, 1, "", "shape_zoom_affine"], [123, 3, 1, "", "working_type"], [123, 3, 1, "", "write_zeros"]], "nibabel.volumeutils.DtypeMapper": [[123, 2, 1, "", "__init__"]], "nibabel.volumeutils.Recoder": [[123, 2, 1, "", "__init__"], [123, 2, 1, "", "add_codes"], [123, 4, 1, "", "fields"], [123, 2, 1, "", "keys"], [123, 2, 1, "", "value_set"]], "nibabel.wrapstruct": [[124, 1, 1, "", "LabeledWrapStruct"], [124, 1, 1, "", "WrapStruct"], [124, 1, 1, "", "WrapStructError"]], "nibabel.wrapstruct.LabeledWrapStruct": [[124, 2, 1, "", "__init__"], [124, 2, 1, "", "get_value_label"]], "nibabel.wrapstruct.WrapStruct": [[124, 2, 1, "", "__init__"], [124, 2, 1, "", "as_byteswapped"], [124, 5, 1, "", "binaryblock"], [124, 2, 1, "", "check_fix"], [124, 2, 1, "", "copy"], [124, 2, 1, "", "default_structarr"], [124, 2, 1, "", "diagnose_binaryblock"], [124, 5, 1, "", "endianness"], [124, 2, 1, "", "from_fileobj"], [124, 2, 1, "", "get"], [124, 2, 1, "", "guessed_endian"], [124, 2, 1, "", "items"], [124, 2, 1, "", "keys"], [124, 5, 1, "", "structarr"], [124, 4, 1, "", "template_dtype"], [124, 2, 1, "", "values"], [124, 2, 1, "", "write_to"]], "nibabel.wrapstruct.WrapStructError": [[124, 2, 1, "", "__init__"]], "nibabel.xmlutils": [[125, 1, 1, "", "XmlBasedHeader"], [125, 1, 1, "", "XmlParser"], [125, 1, 1, "", "XmlSerializable"]], "nibabel.xmlutils.XmlBasedHeader": [[125, 2, 1, "", "__init__"]], "nibabel.xmlutils.XmlParser": [[125, 2, 1, "", "CharacterDataHandler"], [125, 2, 1, "", "EndElementHandler"], [125, 4, 1, "", "HANDLER_NAMES"], [125, 2, 1, "", "StartElementHandler"], [125, 2, 1, "", "__init__"], [125, 2, 1, "", "parse"]], "nibabel.xmlutils.XmlSerializable": [[125, 2, 1, "", "__init__"], [125, 2, 1, "", "to_xml"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:method", "3": "py:function", "4": "py:attribute", "5": "py:property"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "method", "Python method"], "3": ["py", "function", "Python function"], "4": ["py", "attribute", "Python attribute"], "5": ["py", "property", "Python property"]}, "titleterms": {"api": [0, 1, 3, 15, 28, 65], "document": [0, 1, 22, 25, 56], "file": [0, 4, 13, 18, 33, 35, 40, 61, 109, 116], "format": [0, 3, 6, 13, 15, 18, 20, 35, 36, 39, 69, 109], "imag": [0, 2, 3, 7, 9, 10, 12, 13, 14, 15, 24, 27, 30, 33, 34, 54, 55, 61, 62, 64, 109], "util": [0, 78, 94, 102, 119], "float": [0, 14], "integ": 0, "convers": [0, 40], "system": [0, 2, 38], "miscellan": 0, "helper": 0, "alphabet": 0, "refer": [0, 2, 6, 65, 105], "nibabel": [1, 2, 3, 4, 10, 12, 22, 24, 26, 45, 50, 56, 58, 59, 61, 63, 66], "develop": [1, 19, 21, 22, 23, 25, 43, 46, 52, 57], "changelog": [1, 22], "releas": [1, 20, 26], "5": 1, "2": [1, 8, 15, 77], "0": [1, 6], "mondai": 1, "11": 1, "decemb": 1, "2023": 1, "new": [1, 3, 43, 77], "featur": [1, 43], "enhanc": [1, 23], "bug": 1, "fix": 1, "mainten": [1, 6], "chang": [1, 19, 43, 51], "deprec": [1, 81, 82], "1": [1, 8], "3": 1, "april": 1, "sundai": 1, "12": 1, "februari": 1, "9": 1, "januari": 1, "4": 1, "wednesdai": 1, "31": 1, "august": 1, "2022": 1, "saturdai": 1, "18": 1, "june": 1, "7": 1, "28": 1, "novemb": 1, "2020": 1, "tuesdai": 1, "20": 1, "octob": 1, "fridai": 1, "26": 1, "8": 1, "march": 1, "27": 1, "2019": 1, "23": 1, "septemb": 1, "mai": 1, "16": 1, "2018": 1, "22": 1, "2017": 1, "13": 1, "2016": 1, "2015": 1, "2014": 1, "2012": 1, "6": 1, "thursdai": 1, "2011": 1, "14": 1, "feb": 1, "oct": 1, "2010": 1, "pynifti": 1, "20100706": 1, "tue": 1, "jul": 1, "20100412": 1, "mon": 1, "apr": 1, "20090303": 1, "mar": 1, "2009": 1, "20090205": 1, "thu": 1, "20081017": 1, "fri": 1, "17": 1, "2008": 1, "20080710": 1, "20080630": 1, "30": 1, "jun": 1, "20080624": 1, "24": 1, "20070930": 1, "sun": 1, "sep": 1, "2007": 1, "20070917": 1, "20070905": 1, "wed": 1, "20070803": 1, "aug": 1, "20070425": 1, "25": 1, "20070315": 1, "15": 1, "20070301": 1, "20070220": 1, "20070214": 1, "20061114": 1, "nov": 1, "2006": 1, "coordin": [2, 15, 38], "affin": [2, 38, 40, 62, 68], "introduc": 2, "someon": 2, "voxel": [2, 38, 40, 54, 60], "ar": [2, 116], "data": [2, 4, 10, 14, 15, 20, 28, 35, 36, 38, 40, 58, 61, 62, 79, 109, 116], "arrai": [2, 7, 55, 61], "point": [2, 14], "space": [2, 38, 115], "The": [2, 3, 9, 12, 15, 23, 24, 35, 43, 61, 62, 69], "scanner": 2, "subject": 2, "ax": [2, 12, 18, 60, 77], "from": [2, 9, 13, 15, 20, 36, 38, 43, 52], "name": [2, 9, 20, 42], "matrix": [2, 63], "transform": [2, 28], "between": [2, 64], "invers": [2, 113], "give": 2, "map": [2, 38], "exampl": [2, 62, 77], "appli": [2, 9], "seri": [2, 51], "other": [2, 15, 43], "alwai": [2, 14], "us": [2, 4, 7, 9, 12, 13, 15, 30, 55], "an": [2, 13, 15], "ra": 2, "output": [2, 42], "how": [3, 4, 6, 19], "add": [3, 13, 14], "philosophi": 3, "help": 3, "u": 3, "review": [3, 6, 19, 43], "your": [3, 43, 45, 53, 57], "code": [3, 20, 22, 44, 50, 58, 62], "can": [3, 10, 12, 13], "read": [3, 40, 102], "onli": [3, 19], "where": 3, "start": [3, 39, 41], "A": [3, 9, 11, 19, 26, 35, 51], "recip": 3, "write": [3, 40, 116], "ad": 4, "test": [4, 5, 22, 56, 66], "small": 4, "open": [4, 40, 106], "licens": [4, 56, 58, 66], "submodul": 4, "much": 4, "should": [4, 8], "go": 4, "singl": [4, 43], "If": 4, "doubt": 4, "advanc": [5, 49], "setup": 5, "long": [5, 51], "run": 5, "biap": [6, 16, 17, 23], "purpos": 6, "process": [6, 23, 111], "what": [6, 8], "i": [6, 15, 35, 38], "type": [6, 9, 18, 40, 109], "workflow": [6, 43, 49, 51], "resolut": [6, 7], "becom": 6, "accept": 6, "templat": [6, 16], "header": [6, 9, 11, 37, 39, 61, 62, 69, 119], "preambl": 6, "footnot": 6, "biap1": 7, "toward": 7, "immut": 7, "background": [7, 8, 9, 12, 13, 14, 15, 28, 35], "proxi": [7, 55, 61], "issu": [7, 10, 11, 19, 20], "design": 7, "case": [7, 9, 15, 30], "load": [7, 13, 14, 27, 61, 98, 103, 104, 119], "minim": 7, "memori": [7, 55], "maxim": 7, "speed": 7, "assert": 7, "modifi": [7, 27], "copi": [7, 8, 44, 45], "view": [7, 8], "when": [7, 10], "do": [7, 43], "you": [7, 19, 43], "want": [7, 43], "propos": [7, 9, 14, 15, 23], "question": [7, 8, 9], "biap2": 8, "slicecopi": 8, "statu": [8, 10], "slice0": 8, "slice": [8, 9, 10, 31, 36, 38, 61], "allow": 8, "option": [8, 13], "fanci": [8, 42], "object": [8, 24, 35, 61], "method": [8, 14, 30], "call": 8, "biap3": 9, "json": 9, "nifti": [9, 10, 37, 62], "extens": [9, 58], "abstract": [9, 16, 23], "altern": [9, 16], "learn": 9, "nrrd": 9, "gener": [9, 12, 15, 109, 126], "principl": [9, 20], "see": 9, "also": 9, "must": 9, "contain": 9, "version": [9, 20, 57], "usual": 9, "metadata": [9, 10, 15, 20], "field": [9, 33, 35, 119], "axi": [9, 12, 28, 77], "often": 9, "element": [9, 35], "q_vector": 9, "acquisition_tim": 9, "volum": [9, 10, 12, 31, 40], "axis_mean": 9, "multi_affin": 9, "implement": [9, 14, 16, 27, 32, 64], "biap4": 10, "merg": [10, 19, 22, 42, 43], "dcmstack": 10, "motiv": [10, 11, 16, 20, 27], "overview": [10, 11, 18, 42, 43, 47, 52, 53], "dcmmetaextens": 10, "ti": 10, "niftiextens": 10, "plan": 10, "keep": [10, 27], "track": [10, 27], "manipul": 10, "detect": 10, "specif": 10, "difficult": 10, "3d": [10, 13, 38], "4d": [10, 13], "dicom": [10, 32, 33, 34, 35, 36, 37, 38, 39, 40], "meta": 10, "nest": 10, "sequenc": [10, 13, 40], "independ": 10, "classifi": 10, "improv": 10, "access": 10, "vari": 10, "through": 10, "biap5": 11, "streamlin": [11, 119], "convert": [11, 78], "futur": 11, "work": [11, 16, 38, 50, 62], "biap6": 12, "identifi": 12, "time": [12, 55], "fourth": 12, "have": [12, 27], "more": [12, 43, 72], "than": 12, "four": 12, "current": [12, 14, 15], "convent": [12, 60], "distinguish": 12, "possibl": [12, 27, 40], "solut": 12, "find": 12, "associ": 12, "label": [12, 28], "enforc": 12, "4th": 12, "biap7": 13, "multipl": [13, 35], "some": [13, 20, 31, 43], "store": 13, "differ": [13, 20], "shape": 13, "same": 13, "It": 13, "return": 13, "load_multi": 13, "top": 13, "level": 13, "function": [13, 30], "next": 13, "step": 13, "biap8": 14, "summari": [14, 20, 27, 43, 49, 64], "In": [14, 42, 43, 47, 52, 53], "detail": [14, 16, 42, 43, 47, 52, 53, 61], "prefer": 14, "get_fdata": [14, 55], "biap9": 15, "surfac": [15, 28], "kept": 15, "separ": [15, 20], "geometr": 15, "terminologi": [15, 20], "support": [15, 56], "relev": 15, "desiderata": [15, 20], "promin": 15, "model": 15, "smooth": 15, "plot": 15, "subsampl": 15, "cifti": [15, 77], "x": 16, "instruct": 16, "scope": 16, "usag": 16, "impact": 16, "backward": 16, "compat": 16, "descript": 16, "relat": 16, "discuss": [16, 21], "brainvoyag": 18, "bv": 18, "intern": 18, "core": [19, 23], "guid": [19, 22, 26], "conduct": 19, "good": 19, "understand": 19, "close": 19, "pull": 19, "request": 19, "further": 19, "resourc": [19, 49], "acknowledg": [19, 23], "packag": [20, 57], "idea": 20, "instanti": 20, "pinstanc": 20, "revis": 20, "id": 20, "tag": [20, 31, 35, 37, 39, 40], "provid": 20, "bundl": 20, "prundl": 20, "discoveri": 20, "sourc": [20, 22, 44, 50, 57], "queri": 20, "instal": [20, 47, 56, 57, 66], "compar": 20, "debian": [20, 57], "depend": 20, "manag": 20, "authent": 20, "valid": [20, 57], "usecas": 20, "guidelin": 22, "git": [22, 42, 46, 47, 49], "repositori": [22, 43, 53], "layout": [22, 60], "commit": [22, 43, 51], "style": 22, "pre": 22, "hook": 22, "commun": [22, 23], "govern": 23, "decis": 23, "make": [23, 26, 40, 43, 45, 52], "role": 23, "And": 23, "respons": 23, "contributor": [23, 56], "steer": 23, "council": 23, "page": [25, 49], "checklist": 26, "whether": 27, "been": 27, "sinc": 27, "roadmap": 28, "express": 28, "tick": 28, "rang": 28, "spatial": 28, "scalefactor": 29, "intercept": 29, "spm": [30, 40], "dcm2nii": 31, "algorithm": 31, "compil": 31, "modif": 31, "sort": [31, 40, 109], "concept": 32, "order": 33, "multi": 33, "frame": 33, "inform": [34, 35, 109], "sampl": 34, "introduct": [35, 48], "messag": 35, "standard": 35, "attribut": 35, "privat": 35, "valu": 35, "represent": 35, "length": [35, 40], "dictionari": 35, "structur": 35, "set": [35, 38, 45, 53], "world": [35, 60], "entiti": 35, "definit": [35, 38], "servic": 35, "dims": 35, "pair": 35, "sop": 35, "siemen": [36, 39], "mosaic": 36, "get": [36, 38, 41, 44, 57, 61], "orient": [36, 38, 54, 108, 109], "scale": [36, 62], "defin": 38, "patient": 38, "pixel": 38, "j": 38, "column": 38, "row": 38, "again": 38, "formula": 38, "list": [38, 56, 66], "deriv": 38, "out": 38, "z": 38, "csa": 39, "csa1": 39, "each": 39, "item": [39, 40], "csa2": 39, "spm_dicom_dict": 40, "mat": 40, "spm_dicom_head": 40, "m": 40, "philip": [40, 58], "integra": 40, "sq": 40, "vr": 40, "spm_dicom_convert": 40, "categor": 40, "first": 40, "pass": 40, "second": 40, "final": 40, "check": [40, 51, 55, 72, 124], "resort": 40, "configur": [42, 45], "user": 42, "email": 42, "alias": 42, "editor": 42, "log": 42, "consid": 43, "delet": 43, "master": 43, "branch": 43, "updat": [43, 44], "mirror": 43, "trunk": [43, 51], "edit": 43, "ask": 43, "thing": 43, "might": 43, "github": [43, 45], "sever": [43, 116], "peopl": 43, "share": 43, "explor": 43, "rebas": 43, "recov": 43, "mess": 43, "up": [43, 45, 53], "rewrit": 43, "histori": [43, 51], "follow": 44, "latest": 44, "local": 44, "own": 45, "fork": [45, 53], "account": 45, "creat": [45, 77], "tutori": [49, 126], "manual": [49, 59], "onlin": 49, "maintain": 51, "integr": 51, "few": 51, "push": 51, "patch": 52, "move": 52, "clone": 53, "link": 53, "upstream": 53, "repo": 53, "in_memori": 55, "state": 55, "cach": [55, 61], "uncach": 55, "save": [55, 61, 98, 103, 104, 119], "instead": 55, "keyword": 55, "mail": [56, 66], "citat": [56, 66], "author": 56, "repris": 56, "download": 56, "pip": 57, "python": 57, "index": 57, "ubuntu": 57, "requir": 57, "copyright": 58, "3rd": 58, "parti": 58, "netcdf": 58, "sphinx": 58, "autosummari": 58, "orderedset": 58, "mni_icbm152_t1_tal_nlin_asym_09a": 58, "par": [58, 109], "rec": 58, "radiolog": 60, "v": 60, "neurolog": 60, "displai": 60, "align": 60, "easi": 61, "wai": [61, 116], "preliminari": 62, "sform": 62, "qform": 62, "fall": 62, "back": 62, "choos": 62, "default": 62, "ipython": 63, "notebook": 63, "project": 63, "rotat": 63, "orthogon": 63, "relationship": 64, "io": [64, 92], "sign": 64, "off": 64, "quickstart": 66, "bench": 66, "get_info": 66, "_compress": 67, "affineerror": 68, "append_diag": 68, "apply_affin": 68, "dot_reduc": 68, "from_matvec": 68, "obliqu": 68, "rescale_affin": 68, "to_matvec": 68, "voxel_s": 68, "analyz": 69, "note": [69, 74], "analyzehead": 69, "analyzeimag": 69, "arrayproxi": 70, "arraylik": 70, "get_obj_dtyp": 70, "is_proxi": 70, "reshape_dataobj": 70, "arraywrit": 71, "scalingerror": 71, "slopearraywrit": 71, "slopeinterarraywrit": 71, "writererror": 71, "get_slope_int": 71, "make_array_writ": 71, "batteryrunn": 72, "about": 72, "report": 72, "benchmark": 73, "modul": [73, 77, 78, 92, 94, 102, 119], "bench_array_to_fil": 73, "bench_arrayproxy_sl": 73, "bench_fileslic": 73, "bench_finite_rang": 73, "bench_load_sav": 73, "butil": 73, "run_slic": 73, "print_git_titl": 73, "brikhead": 74, "afniarrayproxi": 74, "afnihead": 74, "afniheadererror": 74, "afniimag": 74, "afniimageerror": 74, "parse_afni_head": 74, "caret": 75, "caretmetadata": 75, "cast": 76, "castingerror": 76, "floatingerror": 76, "able_int_typ": 76, "as_int": 76, "best_float": 76, "ceil_exact": 76, "float_to_int": 76, "floor_exact": 76, "floor_log2": 76, "have_binary128": 76, "int_ab": 76, "int_to_float": 76, "longdouble_lte_float64": 76, "longdouble_precision_improv": 76, "ok_float": 76, "on_powerpc": 76, "shared_rang": 76, "type_info": 76, "ulp": 76, "cifti2": 77, "cifti2_ax": 77, "parse_cifti2": 77, "cifti2brainmodel": 77, "cifti2head": 77, "cifti2headererror": 77, "cifti2imag": 77, "cifti2label": 77, "cifti2labelt": 77, "cifti2matrix": 77, "cifti2matrixindicesmap": 77, "cifti2metadata": 77, "cifti2namedmap": 77, "cifti2parcel": 77, "cifti2surfac": 77, "cifti2transformationmatrixvoxelindicesijktoxyz": 77, "cifti2vertexindic": 77, "cifti2vertic": 77, "cifti2volum": 77, "cifti2voxelindicesijk": 77, "limitednifti2head": 77, "brainmodelaxi": 77, "labelaxi": 77, "parcelsaxi": 77, "scalaraxi": 77, "seriesaxi": 77, "from_index_map": 77, "to_head": 77, "cifti2extens": 77, "cifti2pars": 77, "cmdline": 78, "conform": [78, 111], "dicomf": 78, "diff": 78, "l": 78, "nifti_dx": 78, "parrec2nii": 78, "roi": 78, "stat": 78, "tck2trk": 78, "trk2tck": 78, "main": 78, "filehandl": 78, "dummy_fus": 78, "fuse": 78, "get_opt_pars": 78, "are_values_differ": 78, "display_diff": 78, "get_data_diff": 78, "get_data_hash_diff": 78, "get_headers_diff": 78, "proc_fil": 78, "error": 78, "verbos": 78, "lossless_slic": 78, "parse_slic": 78, "sanit": 78, "parse_arg": 78, "ap": 78, "safe_get": 78, "table2str": 78, "bomber": 79, "bombererror": 79, "dataerror": [79, 119], "datasourc": 79, "versioneddatasourc": 79, "datasource_or_bomb": 79, "find_data_dir": 79, "get_data_path": 79, "make_datasourc": 79, "dataobj_imag": 80, "dataobjimag": 80, "futurewarningmixin": 81, "moduleproxi": 81, "visibledeprecationwarn": 81, "alert_future_error": 81, "expireddeprecationerror": 82, "dft": 83, "cachingerror": 83, "dfterror": 83, "instancestackerror": 83, "volumeerror": 83, "clear_cach": 83, "get_studi": 83, "update_cach": 83, "ecat": 84, "ecathead": 84, "ecatimag": 84, "ecatimagearrayproxi": 84, "ecatsubhead": 84, "get_frame_ord": 84, "get_series_framenumb": 84, "read_mlist": 84, "read_subhead": 84, "environ": 85, "get_home_dir": 85, "get_nipy_system_dir": 85, "get_nipy_user_dir": 85, "eulerangl": 86, "angle_axis2eul": 86, "euler2angle_axi": 86, "euler2mat": 86, "euler2quat": 86, "mat2eul": 86, "quat2eul": 86, "filebasedimag": 87, "filebasedhead": 87, "imagefileerror": 87, "serializableimag": 87, "filehold": 88, "fileholdererror": 88, "copy_file_map": 88, "filename_pars": 89, "typesfilenameserror": 89, "parse_filenam": 89, "splitext_addext": 89, "types_filenam": 89, "fileslic": 90, "calc_slicedef": 90, "canonical_slic": 90, "fill_slic": 90, "is_fanc": 90, "optimize_read_slic": 90, "optimize_slic": 90, "predict_shap": 90, "read_seg": 90, "slice2len": 90, "slice2outax": 90, "slicers2seg": 90, "strided_scalar": 90, "threshold_heurist": 90, "fileutil": 91, "read_zt_byte_str": 91, "freesurf": 92, "mghformat": 92, "read_annot": 92, "read_geometri": 92, "read_label": 92, "read_morph_data": 92, "write_annot": 92, "write_geometri": 92, "write_morph_data": 92, "mgherror": 92, "mghheader": 92, "mghimag": 92, "func": 93, "as_closest_canon": 93, "concat_imag": 93, "four_to_thre": 93, "squeeze_imag": 93, "gifti": 94, "parse_gifti_fast": 94, "gifticoordsystem": 94, "giftidataarrai": 94, "giftiimag": 94, "giftilabel": 94, "giftilabelt": 94, "giftimetadata": 94, "giftinvpair": 94, "giftiimagepars": 94, "giftiparseerror": 94, "read_data_block": 94, "imageclass": 95, "spatial_axes_first": 95, "imageglob": 96, "errorlevel": 96, "loggingoutputsuppressor": 96, "imagestat": 97, "count_nonzero_voxel": 97, "mask_volum": 97, "loadsav": 98, "guessed_image_typ": 98, "read_img_data": 98, "minc1": 99, "minc1fil": 99, "minc1head": 99, "minc1imag": 99, "mincerror": 99, "minchead": 99, "mincimagearrayproxi": 99, "minc2": 100, "hdf5bunch": 100, "minc2fil": 100, "minc2head": 100, "minc2imag": 100, "mriutil": 101, "mrierror": 101, "calculate_dwell_tim": 101, "nicom": 102, "ascconv": 102, "csaread": 102, "dicomread": 102, "dicomwrapp": 102, "dwiparam": 102, "structread": 102, "ascconvparseerror": 102, "atom": 102, "novalu": 102, "assign2atom": 102, "obj_from_atom": 102, "parse_ascconv": 102, "csaerror": 102, "csareaderror": 102, "get_acq_mat_txt": 102, "get_b_matrix": 102, "get_b_valu": 102, "get_csa_head": 102, "get_g_vector": 102, "get_ice_dim": 102, "get_n_mosa": 102, "get_scalar": 102, "get_slice_norm": 102, "get_vector": 102, "is_mosa": 102, "nt_str": 102, "dicomreaderror": 102, "mosaic_to_nii": 102, "read_mosaic_dir": 102, "read_mosaic_dwi_dir": 102, "slices_to_seri": 102, "mosaicwrapp": 102, "multiframewrapp": 102, "siemenswrapp": 102, "wrapper": 102, "wrappererror": 102, "wrapperprecisionerror": 102, "none_or_clos": 102, "wrapper_from_data": 102, "wrapper_from_fil": 102, "b2q": 102, "nearest_pos_semi_def": 102, "q2bg": 102, "unpack": 102, "find_private_sect": 102, "nifti1": 103, "nifti1dicomextens": 103, "nifti1extens": 103, "nifti1head": 103, "nifti1imag": 103, "nifti1pair": 103, "nifti1pairhead": 103, "nifti2": 104, "nifti2head": 104, "nifti2imag": 104, "nifti2pair": 104, "nifti2pairhead": 104, "onetim": 105, "onetimeproperti": 105, "resetmixin": 105, "auto_attr": 105, "setattr_on_read": 105, "deterministicgzipfil": 106, "fileish": 106, "imageopen": 106, "optpkg": 107, "optional_packag": 107, "orientationerror": 108, "aff2axcod": 108, "apply_orient": 108, "axcodes2ornt": 108, "flip_axi": 108, "inv_ornt_aff": 108, "io_orient": 108, "ornt2axcod": 108, "ornt_transform": 108, "parrec": 109, "parrecarrayproxi": 109, "parrecerror": 109, "parrechead": 109, "parrecimag": 109, "exts2par": 109, "one_lin": 109, "parse_par_head": 109, "vol_is_ful": 109, "vol_numb": 109, "pointset": 110, "coordinatearrai": 110, "grid": 110, "gridindic": 110, "adapt_affin": 111, "fwhm2sigma": 111, "resample_from_to": 111, "resample_to_output": 111, "sigma2fwhm": 111, "smooth_imag": 111, "pydicom_compat": 112, "dicom_test": 112, "quaternion": 113, "angle_axis2mat": 113, "angle_axis2quat": 113, "conjug": 113, "ey": 113, "fillposit": 113, "isunit": 113, "mat2quat": 113, "mult": 113, "nearly_equival": 113, "norm": 113, "quat2angle_axi": 113, "quat2mat": 113, "rotate_vector": 113, "rstutil": 114, "rst_tabl": 114, "slice2volum": 115, "vox2out_vox": 115, "spatialimag": 116, "There": 116, "interfac": 116, "hasdtyp": 116, "headerdataerror": 116, "headertypeerror": 116, "imagedataerror": 116, "spatialfirstslic": 116, "spatialhead": 116, "spatialprotocol": 116, "supported_np_typ": 116, "spm2analyz": 117, "spm2analyzehead": 117, "spm2analyzeimag": 117, "spm99analyz": 118, "spm99analyzehead": 118, "spm99analyzeimag": 118, "spmanalyzehead": 118, "array_sequ": 119, "tck": 119, "tractogram": 119, "tractogram_fil": 119, "trk": 119, "detect_format": 119, "is_support": 119, "arraysequ": 119, "concaten": 119, "create_arraysequences_from_gener": 119, "is_array_sequ": 119, "is_ndarray_of_int_or_bool": 119, "tckfile": 119, "lazydict": 119, "lazytractogram": 119, "perarraydict": 119, "perarraysequencedict": 119, "sliceabledatadict": 119, "tractogramitem": 119, "is_data_dict": 119, "is_lazy_dict": 119, "datawarn": 119, "extensionwarn": 119, "headererror": 119, "headerwarn": 119, "tractogramfil": 119, "abstractclassmethod": 119, "trkfile": 119, "decode_value_from_nam": 119, "encode_value_in_nam": 119, "get_affine_rasmm_to_trackvi": 119, "get_affine_trackvis_to_rasmm": 119, "get_affine_from_refer": 119, "peek_next": 119, "tmpdir": 120, "temporarydirectori": 120, "ingivendirectori": 120, "intemporarydirectori": 120, "tripwir": 121, "tripwireerror": 121, "is_tripwir": 121, "viewer": 122, "orthoslicer3d": 122, "volumeutil": 123, "dtypemapp": 123, "recod": 123, "apply_read_sc": 123, "array_from_fil": 123, "array_to_fil": 123, "best_write_scale_ftyp": 123, "better_float_of": 123, "finite_rang": 123, "fname_ext_ul_cas": 123, "int_scinter_ftyp": 123, "make_dt_cod": 123, "pretty_map": 123, "rec2dict": 123, "seek_tel": 123, "shape_zoom_affin": 123, "working_typ": 123, "write_zero": 123, "wrapstruct": 124, "mapping": 124, "consist": 124, "labeledwrapstruct": 124, "wrapstructerror": 124, "xmlutil": 125, "xmlbasedhead": 125, "xmlparser": 125, "xmlserializ": 125}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.todo": 2, "sphinx": 60}, "alltitles": {"API Documentation": [[0, "api-documentation"]], "File Formats": [[0, "file-formats"]], "Image Utilities": [[0, "image-utilities"]], "Float / integer conversion": [[0, "float-integer-conversion"]], "System utilities": [[0, "system-utilities"]], "Miscellaneous Helpers": [[0, "miscellaneous-helpers"]], "Alphabetical API reference": [[0, "alphabetical-api-reference"]], "NiBabel Development Changelog": [[1, "nibabel-development-changelog"]], "Nibabel releases": [[1, "nibabel-releases"]], "5.2.0 (Monday 11 December 2023)": [[1, "monday-11-december-2023"]], "New features": [[1, "new-features"], [1, "id6"], [1, "id16"], [1, "id24"], [1, "id30"], [1, "id40"], [1, "id57"], [1, "id66"], [1, "id70"], [1, "id77"], [1, "id82"]], "Enhancements": [[1, "enhancements"], [1, "id1"], [1, "id7"], [1, "id17"], [1, "id25"], [1, "id41"], [1, "id45"], [1, "id49"], [1, "id53"], [1, "id58"], [1, "id62"], [1, "id67"], [1, "id71"], [1, "id78"], [1, "id83"]], "Bug fixes": [[1, "bug-fixes"], [1, "id2"], [1, "id4"], [1, "id8"], [1, "id11"], [1, "id13"], [1, "id18"], [1, "id21"], [1, "id26"], [1, "id29"], [1, "id31"], [1, "id34"], [1, "id36"], [1, "id38"], [1, "id42"], [1, "id46"], [1, "id50"], [1, "id54"], [1, "id59"], [1, "id63"], [1, "id68"], [1, "id72"], [1, "id75"], [1, "id79"], [1, "id84"]], "Documentation": [[1, "documentation"], [22, "documentation"], [56, "documentation"]], "Maintenance": [[1, "maintenance"], [1, "id3"], [1, "id5"], [1, "id9"], [1, "id12"], [1, "id14"], [1, "id19"], [1, "id22"], [1, "id23"], [1, "id27"], [1, "id32"], [1, "id35"], [1, "id37"], [1, "id39"], [1, "id43"], [1, "id47"], [1, "id51"], [1, "id55"], [1, "id60"], [1, "id61"], [1, "id64"], [1, "id69"], [1, "id73"], [1, "id76"], [1, "id80"], [1, "id85"], [6, "maintenance"]], "API changes and deprecations": [[1, "api-changes-and-deprecations"], [1, "id10"], [1, "id20"], [1, "id28"], [1, "id33"], [1, "id44"], [1, "id48"], [1, "id52"], [1, "id56"], [1, "id65"], [1, "id74"], [1, "id81"], [1, "id86"]], "5.1.0 (Monday 3 April 2023)": [[1, "monday-3-april-2023"]], "5.0.1 (Sunday 12 February 2023)": [[1, "sunday-12-february-2023"]], "5.0.0 (Monday 9 January 2023)": [[1, "monday-9-january-2023"]], "4.0.2 (Wednesday 31 August 2022)": [[1, "wednesday-31-august-2022"]], "4.0.1 (Saturday 18 June 2022)": [[1, "saturday-18-june-2022"]], "4.0.0 (Saturday 18 June 2022)": [[1, "id15"]], "3.2.2 (Monday 7 February 2022)": [[1, "monday-7-february-2022"]], "3.2.1 (Saturday 28 November 2020)": [[1, "saturday-28-november-2020"]], "3.2.0 (Tuesday 20 October 2020)": [[1, "tuesday-20-october-2020"]], "3.1.1 (Friday 26 June 2020)": [[1, "friday-26-june-2020"]], "3.1.0 (Monday 20 April 2020)": [[1, "monday-20-april-2020"]], "2.5.2 (Wednesday 8 April 2020)": [[1, "wednesday-8-april-2020"]], "3.0.2 (Monday 9 March 2020)": [[1, "monday-9-march-2020"]], "3.0.1 (Monday 27 January 2020)": [[1, "monday-27-january-2020"]], "3.0.0 (Wednesday 18 December 2019)": [[1, "wednesday-18-december-2019"]], "2.5.1 (Monday 23 September 2019)": [[1, "monday-23-september-2019"]], "2.5.0 (Sunday 4 August 2019)": [[1, "sunday-4-august-2019"]], "2.4.1 (Monday 27 May 2019)": [[1, "monday-27-may-2019"]], "2.4.0 (Monday 1 April 2019)": [[1, "monday-1-april-2019"]], "2.3.3 (Wednesday 16 January 2019)": [[1, "wednesday-16-january-2019"]], "2.3.2 (Wednesday 2 January 2019)": [[1, "wednesday-2-january-2019"]], "2.3.1 (Tuesday 16 October 2018)": [[1, "tuesday-16-october-2018"]], "2.3 (Tuesday 12 June 2018)": [[1, "tuesday-12-june-2018"]], "2.2.1 (Wednesday 22 November 2017)": [[1, "wednesday-22-november-2017"]], "2.2 (Friday 13 October 2017)": [[1, "friday-13-october-2017"]], "2.1 (Monday 22 August 2016)": [[1, "monday-22-august-2016"]], "2.0.2 (Monday 23 November 2015)": [[1, "monday-23-november-2015"]], "2.0.1 (Saturday 27 June 2015)": [[1, "saturday-27-june-2015"]], "2.0.0 (Tuesday 9 December 2014)": [[1, "tuesday-9-december-2014"]], "1.3.0 (Tuesday 11 September 2012)": [[1, "tuesday-11-september-2012"]], "1.2.2 (Wednesday 27 June 2012)": [[1, "wednesday-27-june-2012"]], "1.2.1 (Wednesday 13 June 2012)": [[1, "wednesday-13-june-2012"]], "1.2.0 (Sunday 6 May 2012)": [[1, "sunday-6-may-2012"]], "1.1.0 (Thursday 28 April 2011)": [[1, "thursday-28-april-2011"]], "1.0.2 (Thursday 14 April 2011)": [[1, "thursday-14-april-2011"]], "1.0.1 (Wednesday 23 Feb 2011)": [[1, "wednesday-23-feb-2011"]], "1.0.0 (Thursday, 13, Oct 2010)": [[1, "thursday-13-oct-2010"]], "PyNifti releases": [[1, "pynifti-releases"]], "0.20100706.1 (Tue, 6 Jul 2010)": [[1, "tue-6-jul-2010"]], "0.20100412.1 (Mon, 12 Apr 2010)": [[1, "mon-12-apr-2010"]], "0.20090303.1 (Tue, 3 Mar 2009)": [[1, "tue-3-mar-2009"]], "0.20090205.1 (Thu, 5 Feb 2009)": [[1, "thu-5-feb-2009"]], "0.20081017.1 (Fri, 17 Oct 2008)": [[1, "fri-17-oct-2008"]], "0.20080710.1 (Thu, 7 Jul 2008)": [[1, "thu-7-jul-2008"]], "0.20080630.1 (Tue, 30 Jun 2008)": [[1, "tue-30-jun-2008"]], "0.20080624.1 (Tue, 24 Jun 2008)": [[1, "tue-24-jun-2008"]], "0.20070930.1 (Sun, 30 Sep 2007)": [[1, "sun-30-sep-2007"]], "0.20070917.1 (Mon, 17 Sep 2007)": [[1, "mon-17-sep-2007"]], "0.20070905.1 (Wed, 5 Sep 2007)": [[1, "wed-5-sep-2007"]], "0.20070803.1 (Fri, 3 Aug 2007)": [[1, "fri-3-aug-2007"]], "0.20070425.1 (Wed, 25 Apr 2007)": [[1, "wed-25-apr-2007"]], "0.20070315.1 (Thu, 15 Mar 2007)": [[1, "thu-15-mar-2007"]], "0.20070301.2 (Thu, 1 Mar 2007)": [[1, "thu-1-mar-2007"]], "0.20070301.1 (Thu, 1 Mar 2007)": [[1, "id87"]], "0.20070220.1 (Tue, 20 Feb 2007)": [[1, "tue-20-feb-2007"]], "0.20070214.1 (Wed, 14 Feb 2007)": [[1, "wed-14-feb-2007"]], "0.20061114 (Tue, 14 Nov 2006)": [[1, "tue-14-nov-2006"]], "Coordinate systems and affines": [[2, "coordinate-systems-and-affines"]], "Introducing Someone": [[2, "introducing-someone"]], "Voxel coordinates are coordinates in the image data array": [[2, "voxel-coordinates-are-coordinates-in-the-image-data-array"]], "Voxel coordinates and points in space": [[2, "voxel-coordinates-and-points-in-space"]], "The scanner-subject reference space": [[2, "the-scanner-subject-reference-space"]], "The scanner axes": [[2, "the-scanner-axes"]], "From scanner to subject": [[2, "from-scanner-to-subject"]], "Naming reference spaces": [[2, "naming-reference-spaces"]], "Voxel coordinates are in voxel space": [[2, "voxel-coordinates-are-in-voxel-space"]], "The affine matrix as a transformation between spaces": [[2, "the-affine-matrix-as-a-transformation-between-spaces"]], "The inverse of the affine gives the mapping from scanner to voxel": [[2, "the-inverse-of-the-affine-gives-the-mapping-from-scanner-to-voxel"]], "The affine by example": [[2, "the-affine-by-example"]], "Applying the affine": [[2, "applying-the-affine"]], "The affine as a series of transformations": [[2, "the-affine-as-a-series-of-transformations"]], "Other reference spaces": [[2, "other-reference-spaces"]], "Nibabel always uses an RAS+ output space": [[2, "nibabel-always-uses-an-ras-output-space"]], "How to add a new image format to nibabel": [[3, "how-to-add-a-new-image-format-to-nibabel"]], "Philosophy": [[3, "philosophy"]], "Helping us to review your code": [[3, "helping-us-to-review-your-code"]], "The format can be read-only": [[3, "the-format-can-be-read-only"]], "The image API": [[3, "the-image-api"]], "Where to start with the code": [[3, "where-to-start-with-the-code"]], "A recipe for writing a new image format": [[3, "a-recipe-for-writing-a-new-image-format"]], "Adding test data": [[4, "adding-test-data"]], "Small files": [[4, "small-files"]], "Files with open licenses": [[4, "files-with-open-licenses"]], "Adding the file to nibabel/tests/data": [[4, "adding-the-file-to-nibabel-tests-data"]], "Adding as a submodule to nibabel-data": [[4, "adding-as-a-submodule-to-nibabel-data"]], "Using submodules for tests": [[4, "using-submodules-for-tests"]], "How much data should go in a single submodule?": [[4, "how-much-data-should-go-in-a-single-submodule"]], "If in doubt": [[4, "if-in-doubt"]], "Advanced Testing": [[5, "advanced-testing"]], "Setup": [[5, "setup"]], "Long-running tests": [[5, "long-running-tests"]], "BIAP 0 - Purpose and process": [[6, "biap-0-purpose-and-process"]], "What is a BIAP?": [[6, "what-is-a-biap"]], "Types": [[6, "types"]], "BIAP Workflow": [[6, "biap-workflow"]], "Review and Resolution": [[6, "review-and-resolution"]], "How a BIAP becomes Accepted": [[6, "how-a-biap-becomes-accepted"]], "Format and Template": [[6, "format-and-template"]], "Header Preamble": [[6, "header-preamble"]], "References and Footnotes": [[6, "references-and-footnotes"]], "BIAP1 - Towards immutable images": [[7, "biap1-towards-immutable-images"]], "Resolution": [[7, "resolution"]], "Background": [[7, "background"], [8, "background"], [9, "background"], [12, "background"], [13, "background"], [14, "background"], [15, "background"], [28, "background"]], "Array images": [[7, "array-images"], [61, "array-images"]], "Proxy images": [[7, "proxy-images"]], "Issues for design": [[7, "issues-for-design"]], "Use cases": [[7, "use-cases"]], "Loading images, minimizing memory": [[7, "loading-images-minimizing-memory"]], "Loading images, maximizing speed": [[7, "loading-images-maximizing-speed"]], "Loading images, assert not modified": [[7, "loading-images-assert-not-modified"]], "Array images, proxy images, copy, view": [[7, "array-images-proxy-images-copy-view"]], "When do you want a copy and when do you want a view?": [[7, "when-do-you-want-a-copy-and-when-do-you-want-a-view"]], "Proposal": [[7, "proposal"], [9, "proposal"], [15, "proposal"]], "Questions": [[7, "questions"], [8, "questions"], [9, "questions"]], "BIAP2 - Slicecopy": [[8, "biap2-slicecopy"]], "Status": [[8, "status"], [10, "status"]], "Should slice0 be a copy or a view?": [[8, "should-slice0-be-a-copy-or-a-view"]], "What slices should the slicing allow?": [[8, "what-slices-should-the-slicing-allow"]], "Option 1: fancy slice object": [[8, "option-1-fancy-slice-object"]], "Option 2: not-fancy method call": [[8, "option-2-not-fancy-method-call"]], "BIAP3 - A JSON nifti header extension": [[9, "biap3-a-json-nifti-header-extension"]], "Abstract": [[9, "abstract"], [16, "abstract"], [23, "abstract"]], "Nifti extension types": [[9, "nifti-extension-types"]], "Alternatives": [[9, "alternatives"], [16, "alternatives"]], "Learning from NRRDs": [[9, "learning-from-nrrds"]], "General principles": [[9, "general-principles"]], "See also": [[9, "see-also"]], "The header must contain the header version": [[9, "the-header-must-contain-the-header-version"]], "The header will usually contain image metadata fields": [[9, "the-header-will-usually-contain-image-metadata-fields"]], "The header will usually contain axis names": [[9, "the-header-will-usually-contain-axis-names"]], "The header will often contain axis metadata": [[9, "the-header-will-often-contain-axis-metadata"]], "The axis metadata element": [[9, "the-axis-metadata-element"]], "The q_vector axis metadata field": [[9, "the-q-vector-axis-metadata-field"]], "acquisition_times field": [[9, "acquisition-times-field"]], "acquisition_times applying to slices": [[9, "acquisition-times-applying-to-slices"]], "acquisition_times applying to volumes": [[9, "acquisition-times-applying-to-volumes"]], "acquisition_times applying to slices and volumes": [[9, "acquisition-times-applying-to-slices-and-volumes"]], "axis_meanings field": [[9, "axis-meanings-field"]], "multi_affine field": [[9, "multi-affine-field"]], "Use case": [[9, "use-case"]], "Implementation": [[9, "implementation"], [16, "implementation"]], "BIAP4 - Merging nibabel and dcmstack": [[10, "biap4-merging-nibabel-and-dcmstack"]], "Motivation": [[10, "motivation"], [11, "motivation"], [20, "motivation"], [27, "motivation"]], "Overview": [[10, "overview"], [11, "overview"], [18, "overview"], [42, "overview"], [43, "overview"], [47, "overview"], [52, "overview"], [53, "overview"]], "Issues": [[10, "issues"], [11, "issues"], [20, "issues"]], "DcmMetaExtension tied to NiftiExtension": [[10, "dcmmetaextension-tied-to-niftiextension"]], "Plan": [[10, "plan"], [10, "id1"], [10, "id2"], [10, "id3"]], "Keeping track of metadata when manipulating images": [[10, "keeping-track-of-metadata-when-manipulating-images"]], "Detecting slice or volume-specific data difficult for 3D and 4D DICOMS": [[10, "detecting-slice-or-volume-specific-data-difficult-for-3d-and-4d-dicoms"]], "Meta data in nested DICOM sequences can not be independently classified": [[10, "meta-data-in-nested-dicom-sequences-can-not-be-independently-classified"]], "Improving access to varying meta data through the Nifti": [[10, "improving-access-to-varying-meta-data-through-the-nifti"]], "BIAP5 - A streamlines converter": [[11, "biap5-a-streamlines-converter"]], "Header": [[11, "header"]], "Future Work": [[11, "future-work"]], "BIAP6 - Identifying image axes": [[12, "biap6-identifying-image-axes"]], "Time axis as the fourth axis": [[12, "time-axis-as-the-fourth-axis"]], "Images can have more than four axes": [[12, "images-can-have-more-than-four-axes"]], "The current nibabel convention": [[12, "the-current-nibabel-convention"]], "Distinguishing time and volume": [[12, "distinguishing-time-and-volume"]], "Possible solutions to finding axes": [[12, "possible-solutions-to-finding-axes"]], "General solution: associating axes and labels": [[12, "general-solution-associating-axes-and-labels"]], "Using convention : enforcing time as 4th axis": [[12, "using-convention-enforcing-time-as-4th-axis"]], "BIAP7 - Loading multiple images": [[13, "biap7-loading-multiple-images"]], "Some formats store images with different shapes in the same file": [[13, "some-formats-store-images-with-different-shapes-in-the-same-file"]], "It can be useful to load 4D images as multiple 3D images": [[13, "it-can-be-useful-to-load-4d-images-as-multiple-3d-images"]], "Options": [[13, "options"]], "Return an image sequence from load for some file formats": [[13, "return-an-image-sequence-from-load-for-some-file-formats"]], "Add a load_multi top-level function": [[13, "add-a-load-multi-top-level-function"]], "Next steps:": [[13, "next-steps"]], "BIAP8 - Always load image data as floating point": [[14, "biap8-always-load-image-data-as-floating-point"]], "Summary": [[14, "summary"], [20, "summary"], [27, "summary"]], "In detail": [[14, "in-detail"], [42, "in-detail"], [47, "in-detail"], [52, "in-detail"], [53, "in-detail"]], "Current implementation": [[14, "current-implementation"]], "Proposal - add, prefer get_fdata method": [[14, "proposal-add-prefer-get-fdata-method"]], "BIAP9 - The Coordinate Image API": [[15, "biap9-the-coordinate-image-api"]], "Surface data is generally kept separate from geometric metadata": [[15, "surface-data-is-generally-kept-separate-from-geometric-metadata"]], "Terminology": [[15, "terminology"]], "Currently supported surface formats": [[15, "currently-supported-surface-formats"]], "Other relevant formats": [[15, "other-relevant-formats"]], "Desiderata for an API supporting surfaces": [[15, "desiderata-for-an-api-supporting-surfaces"]], "Prominent use cases": [[15, "prominent-use-cases"]], "Modeling": [[15, "modeling"]], "Smoothing": [[15, "smoothing"]], "Plotting": [[15, "plotting"]], "Subsampling CIFTI-2": [[15, "subsampling-cifti-2"]], "BIAP X \u2014 Template and Instructions": [[16, "biap-x-template-and-instructions"]], "Motivation and Scope": [[16, "motivation-and-scope"]], "Usage and Impact": [[16, "usage-and-impact"]], "Backward compatibility": [[16, "backward-compatibility"]], "Detailed description": [[16, "detailed-description"]], "Related Work": [[16, "related-work"]], "Discussion": [[16, "discussion"]], "BIAPs": [[17, "biaps"]], "BrainVoyager file formats": [[18, "brainvoyager-file-formats"]], "BV internal format axes": [[18, "bv-internal-format-axes"]], "Types of BV files": [[18, "types-of-bv-files"]], "Core Developer Guide": [[19, "core-developer-guide"]], "Reviewing": [[19, "reviewing"]], "How to Conduct A Good Review": [[19, "how-to-conduct-a-good-review"]], "Merge Only Changes You Understand": [[19, "merge-only-changes-you-understand"]], "Closing issues and pull requests": [[19, "closing-issues-and-pull-requests"]], "Further resources": [[19, "further-resources"]], "Acknowledgments": [[19, "acknowledgments"], [23, "acknowledgments"]], "Principles of data package": [[20, "principles-of-data-package"]], "Separation of ideas": [[20, "separation-of-ideas"]], "Package": [[20, "package"]], "Package name": [[20, "package-name"]], "Package instantiation": [[20, "package-instantiation"]], "Pinstance revision": [[20, "pinstance-revision"]], "Pinstance revision id": [[20, "pinstance-revision-id"]], "Pinstance tag": [[20, "pinstance-tag"]], "Pinstance version": [[20, "pinstance-version"]], "Package provider bundle": [[20, "package-provider-bundle"]], "Provider bundle format": [[20, "provider-bundle-format"]], "Pinstance release": [[20, "pinstance-release"]], "Prundle discovery": [[20, "prundle-discovery"]], "Prundle discovery source": [[20, "prundle-discovery-source"]], "Pinstance metadata query": [[20, "pinstance-metadata-query"]], "Pinstance metadata query source": [[20, "pinstance-metadata-query-source"]], "Pinstance installation": [[20, "pinstance-installation"]], "Data and metadata": [[20, "data-and-metadata"]], "Comparative terminology": [[20, "comparative-terminology"]], "Compared to Debian packaging": [[20, "compared-to-debian-packaging"]], "Desiderata": [[20, "desiderata"]], "Dependency management": [[20, "dependency-management"]], "Authentication and validation": [[20, "authentication-and-validation"]], "Differences from code packages": [[20, "differences-from-code-packages"]], "Some usecases": [[20, "some-usecases"]], "Discovery": [[20, "discovery"]], "Developer discussions": [[21, "developer-discussions"]], "NiBabel Developer Guidelines": [[22, "nibabel-developer-guidelines"]], "NiBabel source code": [[22, "nibabel-source-code"]], "Code Documentation": [[22, "code-documentation"]], "Git Repository": [[22, "git-repository"]], "Layout": [[22, "layout"]], "Commits": [[22, "commits"]], "Merges": [[22, "merges"]], "Testing": [[22, "testing"], [56, "testing"], [66, "testing"]], "Style guide": [[22, "style-guide"]], "Pre-commit hooks": [[22, "pre-commit-hooks"]], "Changelog": [[22, "changelog"]], "Community guidelines": [[22, "code-of-conduct"]], "Governance and Decision Making": [[23, "governance-and-decision-making"]], "Roles And Responsibilities": [[23, "roles-and-responsibilities"]], "The Community": [[23, "the-community"]], "Contributors": [[23, "contributors"]], "Core Developers": [[23, "core-developers"]], "Steering Council": [[23, "steering-council"]], "Decision Making Process": [[23, "decision-making-process"]], "Enhancement Proposals (BIAPs)": [[23, "enhancement-proposals-biaps"]], "The nibabel image object": [[24, "the-nibabel-image-object"]], "Developer documentation page": [[25, "developer-documentation-page"]], "A guide to making a nibabel release": [[26, "a-guide-to-making-a-nibabel-release"]], "Release checklist": [[26, "release-checklist"]], "Keeping track of whether images have been modified since load": [[27, "keeping-track-of-whether-images-have-been-modified-since-load"]], "Possible implementation": [[27, "possible-implementation"]], "Roadmap": [[28, "roadmap"]], "Expressive API": [[28, "expressive-api"]], "Axis and tick labels": [[28, "axis-and-tick-labels"]], "API for surface data": [[28, "api-for-surface-data"]], "Range": [[28, "range"]], "Spatial transforms": [[28, "spatial-transforms"]], "Scalefactors and intercepts": [[29, "scalefactors-and-intercepts"]], "Image use-cases in SPM": [[30, "image-use-cases-in-spm"]], "SPM image methods / functions": [[30, "spm-image-methods-functions"]], "dcm2nii algorithms": [[31, "dcm2nii-algorithms"]], "Compiling dcm2nii": [[31, "compiling-dcm2nii"]], "Some tag modifications": [[31, "some-tag-modifications"]], "Sorting slices into volumes": [[31, "sorting-slices-into-volumes"]], "DICOM concepts and implementations": [[32, "dicom-concepts-and-implementations"]], "DICOM fields": [[33, "dicom-fields"]], "Fields for ordering DICOM files into images": [[33, "fields-for-ordering-dicom-files-into-images"]], "Multi-frame images": [[33, "multi-frame-images"]], "DICOM information": [[34, "dicom-information"]], "Sample images": [[34, "sample-images"]], "Introduction to DICOM": [[35, "introduction-to-dicom"]], "DICOM is messages": [[35, "dicom-is-messages"]], "The DICOM standard": [[35, "the-dicom-standard"]], "DICOM data format": [[35, "dicom-data-format"]], "DICOM elements": [[35, "dicom-elements"]], "Attribute Tag": [[35, "attribute-tag"]], "Standard attribute tags": [[35, "standard-attribute-tags"]], "Private attribute tags": [[35, "private-attribute-tags"]], "Value Representation": [[35, "value-representation"]], "Value length": [[35, "value-length"]], "Value field": [[35, "value-field"]], "Data element tags and data dictionaries": [[35, "data-element-tags-and-data-dictionaries"]], "Value Representation in the data dictionary": [[35, "value-representation-in-the-data-dictionary"]], "Value Multiplicity in the data dictionary": [[35, "value-multiplicity-in-the-data-dictionary"]], "DICOM data structures": [[35, "dicom-data-structures"]], "A data set": [[35, "a-data-set"]], "Background - the DICOM world": [[35, "background-the-dicom-world"]], "DICOM Entities and Information Object Definitions": [[35, "dicom-entities-and-information-object-definitions"]], "DICOM services (DIMSE)": [[35, "dicom-services-dimse"]], "DICOM service object pairs (SOPs)": [[35, "dicom-service-object-pairs-sops"]], "DICOM files": [[35, "dicom-files"]], "Siemens mosaic format": [[36, "siemens-mosaic-format"]], "Getting the slices from the mosaic": [[36, "getting-the-slices-from-the-mosaic"]], "DICOM orientation for mosaic": [[36, "dicom-orientation-for-mosaic"]], "Data scaling": [[36, "data-scaling"], [62, "data-scaling"]], "DICOM Tags in the NIfTI Header": [[37, "dicom-tags-in-the-nifti-header"]], "Defining the DICOM orientation": [[38, "defining-the-dicom-orientation"]], "DICOM patient coordinate system": [[38, "dicom-patient-coordinate-system"]], "DICOM pixel data": [[38, "dicom-pixel-data"]], "Pixel spacing": [[38, "pixel-spacing"]], "DICOM voxel to patient coordinate system mapping": [[38, "dicom-voxel-to-patient-coordinate-system-mapping"]], "(i, j), columns, rows in DICOM": [[38, "i-j-columns-rows-in-dicom"]], "DICOM affines again": [[38, "dicom-affines-again"]], "DICOM affine formula": [[38, "dicom-affine-formula"]], "Getting a 3D affine from a DICOM slice or list of slices": [[38, "getting-a-3d-affine-from-a-dicom-slice-or-list-of-slices"]], "DICOM affine Definitions": [[38, "dicom-affine-definitions"]], "Derivations": [[38, "derivations"]], "3D affine formulae": [[38, "d-affine-formulae"]], "Working out the Z coordinates for a set of slices": [[38, "working-out-the-z-coordinates-for-a-set-of-slices"]], "Siemens format DICOM with CSA header": [[39, "siemens-format-dicom-with-csa-header"]], "CSA header": [[39, "csa-header"]], "CSA1": [[39, "csa1"]], "Start header": [[39, "start-header"], [39, "id2"]], "Each tag": [[39, "each-tag"], [39, "id3"]], "Each item": [[39, "each-item"], [39, "id4"]], "CSA2": [[39, "csa2"]], "SPM DICOM conversion": [[40, "spm-dicom-conversion"]], "spm_dicom_dict.mat": [[40, "spm-dicom-dict-mat"]], "spm_dicom_headers.m": [[40, "spm-dicom-headers-m"]], "File opening": [[40, "file-opening"]], "tag read for Philips Integra": [[40, "tag-read-for-philips-integra"]], "Tag length": [[40, "tag-length"]], "SQ VR type (Sequence of items type)": [[40, "sq-vr-type-sequence-of-items-type"]], "spm_dicom_convert.m": [[40, "spm-dicom-convert-m"]], "File categorization": [[40, "file-categorization"]], "Sorting files into volumes": [[40, "sorting-files-into-volumes"]], "First pass": [[40, "first-pass"]], "Second pass": [[40, "second-pass"]], "Final check": [[40, "final-check"]], "Possible volume resort": [[40, "possible-volume-resort"]], "Writing DICOM volumes": [[40, "writing-dicom-volumes"]], "Making the affine": [[40, "making-the-affine"]], "Writing the voxel data": [[40, "writing-the-voxel-data"]], "Getting Started": [[41, "getting-started"]], "Configure git": [[42, "configure-git"]], "user.name and user.email": [[42, "user-name-and-user-email"]], "Aliases": [[42, "aliases"]], "Editor": [[42, "editor"]], "Merging": [[42, "merging"]], "Fancy log output": [[42, "fancy-log-output"]], "Development workflow": [[43, "development-workflow"]], "Workflow summary": [[43, "workflow-summary"]], "Consider deleting your master branch": [[43, "consider-deleting-your-master-branch"]], "Update the mirror of trunk": [[43, "update-the-mirror-of-trunk"]], "Make a new feature branch": [[43, "make-a-new-feature-branch"]], "The editing workflow": [[43, "the-editing-workflow"]], "In more detail": [[43, "in-more-detail"]], "Ask for your changes to be reviewed or merged": [[43, "ask-for-your-changes-to-be-reviewed-or-merged"]], "Some other things you might want to do": [[43, "some-other-things-you-might-want-to-do"]], "Delete a branch on github": [[43, "delete-a-branch-on-github"]], "Several people sharing a single repository": [[43, "several-people-sharing-a-single-repository"]], "Explore your repository": [[43, "explore-your-repository"]], "Rebasing on trunk": [[43, "rebasing-on-trunk"]], "Recovering from mess-ups": [[43, "recovering-from-mess-ups"]], "Rewriting commit history": [[43, "rewriting-commit-history"]], "Following the latest source": [[44, "following-the-latest-source"]], "Get the local copy of the code": [[44, "get-the-local-copy-of-the-code"]], "Updating the code": [[44, "updating-the-code"]], "Making your own copy (fork) of nibabel": [[45, "making-your-own-copy-fork-of-nibabel"]], "Set up and configure a github account": [[45, "set-up-and-configure-a-github-account"]], "Create your own forked copy of nibabel": [[45, "create-your-own-forked-copy-of-nibabel"]], "Git for development": [[46, "git-for-development"]], "Install git": [[47, "install-git"]], "Introduction": [[48, "introduction"]], "git resources": [[49, "git-resources"]], "Tutorials and summaries": [[49, "tutorials-and-summaries"]], "Advanced git workflow": [[49, "advanced-git-workflow"]], "Manual pages online": [[49, "manual-pages-online"]], "Working with nibabel source code": [[50, "working-with-nibabel-source-code"]], "Maintainer workflow": [[51, "maintainer-workflow"]], "Integrating changes": [[51, "integrating-changes"]], "A few commits": [[51, "a-few-commits"]], "A long series of commits": [[51, "a-long-series-of-commits"]], "Check the history": [[51, "check-the-history"]], "Push to trunk": [[51, "push-to-trunk"]], "Making a patch": [[52, "making-a-patch"]], "Making patches": [[52, "making-patches"]], "Moving from patching to development": [[52, "moving-from-patching-to-development"]], "Set up your fork": [[53, "set-up-your-fork"]], "Clone your fork": [[53, "clone-your-fork"]], "Linking your repository to the upstream repo": [[53, "linking-your-repository-to-the-upstream-repo"]], "Image voxel orientation": [[54, "image-voxel-orientation"]], "Images and memory": [[55, "images-and-memory"]], "Using in_memory to check the state of the cache": [[55, "using-in-memory-to-check-the-state-of-the-cache"]], "Using uncache": [[55, "using-uncache"]], "Saving memory": [[55, "saving-memory"]], "Uncache the array": [[55, "uncache-the-array"]], "Use the array proxy instead of get_fdata()": [[55, "use-the-array-proxy-instead-of-get-fdata"]], "Use the caching keyword to get_fdata()": [[55, "use-the-caching-keyword-to-get-fdata"]], "Saving time and memory": [[55, "saving-time-and-memory"]], "NiBabel": [[56, "nibabel"], [58, "nibabel"]], "Installation": [[56, "installation"], [57, "installation"], [57, "id2"], [66, "installation"]], "Mailing List": [[56, "mailing-list"], [66, "mailing-list"]], "License": [[56, "license"], [66, "license"]], "Citation": [[56, "citation"], [66, "citation"]], "Authors and Contributors": [[56, "authors-and-contributors"]], "License reprise": [[56, "license-reprise"]], "Download and Installation": [[56, "download-and-installation"]], "Support": [[56, "support"]], "Installer and packages": [[57, "installer-and-packages"]], "pip and the Python package index": [[57, "pip-and-the-python-package-index"]], "Debian/Ubuntu": [[57, "debian-ubuntu"]], "Install a development version": [[57, "install-a-development-version"]], "Requirements": [[57, "requirements"]], "Get the development sources": [[57, "get-the-development-sources"]], "Validating your install": [[57, "validating-your-install"]], "Copyright and Licenses": [[58, "copyright-and-licenses"]], "3rd party code and data": [[58, "rd-party-code-and-data"]], "NetCDF": [[58, "netcdf"]], "Sphinx autosummary extension": [[58, "sphinx-autosummary-extension"]], "OrderedSet": [[58, "orderedset"]], "mni_icbm152_t1_tal_nlin_asym_09a": [[58, "mni-icbm152-t1-tal-nlin-asym-09a"]], "Philips PAR/REC data": [[58, "philips-par-rec-data"]], "NiBabel Manual": [[59, "nibabel-manual"]], "Radiological vs neurological conventions": [[60, "radiological-vs-neurological-conventions"]], "Neurological and radiological display convention": [[60, "neurological-and-radiological-display-convention"]], "Alignment of world and voxel axes": [[60, "alignment-of-world-and-voxel-axes"]], "Neurological / radiological voxel layout": [[60, "neurological-radiological-voxel-layout"]], "Nibabel images": [[61, "nibabel-images"]], "The image object": [[61, "the-image-object"]], "The image header": [[61, "the-image-header"]], "The image data array": [[61, "the-image-data-array"]], "Array proxies and proxy images": [[61, "array-proxies-and-proxy-images"]], "Getting the image data the easy way": [[61, "getting-the-image-data-the-easy-way"]], "Proxies and caching": [[61, "proxies-and-caching"]], "Image slicing": [[61, "image-slicing"]], "Loading and saving": [[61, "loading-and-saving"]], "Details of files and images": [[61, "details-of-files-and-images"]], "Working with NIfTI images": [[62, "working-with-nifti-images"]], "Preliminaries": [[62, "preliminaries"]], "Example NIfTI images": [[62, "example-nifti-images"]], "The NIfTI header": [[62, "the-nifti-header"]], "The NIfTI affines": [[62, "the-nifti-affines"]], "The sform affine": [[62, "the-sform-affine"]], "The qform affine": [[62, "the-qform-affine"]], "The fall-back header affine": [[62, "the-fall-back-header-affine"]], "Choosing the image affine": [[62, "choosing-the-image-affine"]], "Default sform and qform codes": [[62, "default-sform-and-qform-codes"]], "IPython notebooks for Nibabel project": [[63, "ipython-notebooks-for-nibabel-project"]], "Rotation matrix orthogonality": [[63, "rotation-matrix-orthogonality"]], "Relationship between images and io implementations": [[64, "relationship-between-images-and-io-implementations"]], "Summary and sign-off": [[64, "summary-and-sign-off"]], "Images": [[64, "images"]], "IO implementations": [[64, "io-implementations"]], "API Reference": [[65, "api-reference"]], "nibabel": [[66, "module-nibabel"]], "Quickstart": [[66, "quickstart"]], "bench": [[66, "bench"]], "get_info": [[66, "get-info"]], "test": [[66, "test"]], "_compression": [[67, "module-nibabel._compression"]], "affines": [[68, "module-nibabel.affines"]], "AffineError": [[68, "affineerror"]], "append_diag": [[68, "append-diag"]], "apply_affine": [[68, "apply-affine"]], "dot_reduce": [[68, "dot-reduce"]], "from_matvec": [[68, "from-matvec"]], "obliquity": [[68, "obliquity"]], "rescale_affine": [[68, "rescale-affine"]], "to_matvec": [[68, "to-matvec"]], "voxel_sizes": [[68, "voxel-sizes"]], "analyze": [[69, "module-nibabel.analyze"]], "The Analyze header format": [[69, "the-analyze-header-format"]], "Notes": [[69, "notes"], [74, "notes"]], "AnalyzeHeader": [[69, "analyzeheader"]], "AnalyzeImage": [[69, "analyzeimage"]], "arrayproxy": [[70, "module-nibabel.arrayproxy"]], "ArrayLike": [[70, "arraylike"]], "ArrayProxy": [[70, "id1"]], "get_obj_dtype": [[70, "get-obj-dtype"]], "is_proxy": [[70, "is-proxy"]], "reshape_dataobj": [[70, "reshape-dataobj"]], "arraywriters": [[71, "module-nibabel.arraywriters"]], "ArrayWriter": [[71, "arraywriter"]], "ScalingError": [[71, "scalingerror"]], "SlopeArrayWriter": [[71, "slopearraywriter"]], "SlopeInterArrayWriter": [[71, "slopeinterarraywriter"]], "WriterError": [[71, "writererror"]], "get_slope_inter": [[71, "get-slope-inter"]], "make_array_writer": [[71, "make-array-writer"]], "batteryrunners": [[72, "module-nibabel.batteryrunners"]], "More about checks": [[72, "more-about-checks"]], "BatteryRunner": [[72, "batteryrunner"]], "Report": [[72, "report"]], "benchmarks": [[73, "module-nibabel.benchmarks"]], "Module: benchmarks.bench_array_to_file": [[73, "module-nibabel.benchmarks.bench_array_to_file"]], "Module: benchmarks.bench_arrayproxy_slicing": [[73, "module-nibabel.benchmarks.bench_arrayproxy_slicing"]], "Module: benchmarks.bench_fileslice": [[73, "module-nibabel.benchmarks.bench_fileslice"]], "Module: benchmarks.bench_finite_range": [[73, "module-nibabel.benchmarks.bench_finite_range"]], "Module: benchmarks.bench_load_save": [[73, "module-nibabel.benchmarks.bench_load_save"]], "Module: benchmarks.butils": [[73, "module-nibabel.benchmarks.butils"]], "bench_array_to_file": [[73, "bench-array-to-file"]], "bench_arrayproxy_slicing": [[73, "bench-arrayproxy-slicing"]], "bench_fileslice": [[73, "bench-fileslice"]], "run_slices": [[73, "run-slices"]], "bench_finite_range": [[73, "bench-finite-range"]], "bench_load_save": [[73, "bench-load-save"]], "print_git_title": [[73, "print-git-title"]], "brikhead": [[74, "module-nibabel.brikhead"]], "AFNIArrayProxy": [[74, "afniarrayproxy"]], "AFNIHeader": [[74, "afniheader"]], "AFNIHeaderError": [[74, "afniheadererror"]], "AFNIImage": [[74, "afniimage"]], "AFNIImageError": [[74, "afniimageerror"]], "parse_AFNI_header": [[74, "parse-afni-header"]], "caret": [[75, "module-nibabel.caret"]], "CaretMetaData": [[75, "caretmetadata"]], "casting": [[76, "module-nibabel.casting"]], "CastingError": [[76, "castingerror"]], "FloatingError": [[76, "floatingerror"]], "able_int_type": [[76, "able-int-type"]], "as_int": [[76, "as-int"]], "best_float": [[76, "best-float"]], "ceil_exact": [[76, "ceil-exact"]], "float_to_int": [[76, "float-to-int"]], "floor_exact": [[76, "floor-exact"]], "floor_log2": [[76, "floor-log2"]], "have_binary128": [[76, "have-binary128"]], "int_abs": [[76, "int-abs"]], "int_to_float": [[76, "int-to-float"]], "longdouble_lte_float64": [[76, "longdouble-lte-float64"]], "longdouble_precision_improved": [[76, "longdouble-precision-improved"]], "ok_floats": [[76, "ok-floats"]], "on_powerpc": [[76, "on-powerpc"]], "shared_range": [[76, "shared-range"]], "type_info": [[76, "type-info"]], "ulp": [[76, "ulp"]], "cifti2": [[77, "module-nibabel.cifti2"]], "Module: cifti2.cifti2": [[77, "module-nibabel.cifti2.cifti2"]], "Module: cifti2.cifti2_axes": [[77, "module-nibabel.cifti2.cifti2_axes"]], "Creating new CIFTI-2 axes": [[77, "creating-new-cifti-2-axes"]], "Examples": [[77, "examples"]], "Module: cifti2.parse_cifti2": [[77, "module-nibabel.cifti2.parse_cifti2"]], "Cifti2BrainModel": [[77, "cifti2brainmodel"]], "Cifti2Header": [[77, "cifti2header"]], "Cifti2HeaderError": [[77, "cifti2headererror"]], "Cifti2Image": [[77, "cifti2image"]], "Cifti2Label": [[77, "cifti2label"]], "Cifti2LabelTable": [[77, "cifti2labeltable"]], "Cifti2Matrix": [[77, "cifti2matrix"]], "Cifti2MatrixIndicesMap": [[77, "cifti2matrixindicesmap"]], "Cifti2MetaData": [[77, "cifti2metadata"]], "Cifti2NamedMap": [[77, "cifti2namedmap"]], "Cifti2Parcel": [[77, "cifti2parcel"]], "Cifti2Surface": [[77, "cifti2surface"]], "Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ": [[77, "cifti2transformationmatrixvoxelindicesijktoxyz"]], "Cifti2VertexIndices": [[77, "cifti2vertexindices"]], "Cifti2Vertices": [[77, "cifti2vertices"]], "Cifti2Volume": [[77, "cifti2volume"]], "Cifti2VoxelIndicesIJK": [[77, "cifti2voxelindicesijk"]], "LimitedNifti2Header": [[77, "limitednifti2header"]], "Axis": [[77, "axis"]], "BrainModelAxis": [[77, "brainmodelaxis"]], "LabelAxis": [[77, "labelaxis"]], "ParcelsAxis": [[77, "parcelsaxis"]], "ScalarAxis": [[77, "scalaraxis"]], "SeriesAxis": [[77, "seriesaxis"]], "from_index_mapping": [[77, "from-index-mapping"]], "to_header": [[77, "to-header"]], "Cifti2Extension": [[77, "cifti2extension"]], "Cifti2Parser": [[77, "cifti2parser"]], "cmdline": [[78, "module-nibabel.cmdline"]], "Module: cmdline.conform": [[78, "module-nibabel.cmdline.conform"]], "Module: cmdline.convert": [[78, "module-nibabel.cmdline.convert"]], "Module: cmdline.dicomfs": [[78, "module-nibabel.cmdline.dicomfs"]], "Module: cmdline.diff": [[78, "module-nibabel.cmdline.diff"]], "Module: cmdline.ls": [[78, "module-nibabel.cmdline.ls"]], "Module: cmdline.nifti_dx": [[78, "module-nibabel.cmdline.nifti_dx"]], "Module: cmdline.parrec2nii": [[78, "module-nibabel.cmdline.parrec2nii"]], "Module: cmdline.roi": [[78, "module-nibabel.cmdline.roi"]], "Module: cmdline.stats": [[78, "module-nibabel.cmdline.stats"]], "Module: cmdline.tck2trk": [[78, "module-nibabel.cmdline.tck2trk"]], "Module: cmdline.trk2tck": [[78, "module-nibabel.cmdline.trk2tck"]], "Module: cmdline.utils": [[78, "module-nibabel.cmdline.utils"]], "main": [[78, "main"], [78, "id1"], [78, "id2"], [78, "id4"], [78, "id6"], [78, "id7"], [78, "id9"], [78, "id11"], [78, "id12"], [78, "id13"], [78, "id14"]], "DICOMFS": [[78, "dicomfs"]], "FileHandle": [[78, "filehandle"]], "dummy_fuse": [[78, "dummy-fuse"]], "fuse": [[78, "fuse"]], "get_opt_parser": [[78, "get-opt-parser"], [78, "id3"], [78, "id5"], [78, "id8"]], "are_values_different": [[78, "are-values-different"]], "diff": [[78, "diff"]], "display_diff": [[78, "display-diff"]], "get_data_diff": [[78, "get-data-diff"]], "get_data_hash_diff": [[78, "get-data-hash-diff"]], "get_headers_diff": [[78, "get-headers-diff"]], "proc_file": [[78, "proc-file"], [78, "id10"]], "error": [[78, "error"]], "verbose": [[78, "verbose"], [78, "id16"]], "lossless_slice": [[78, "lossless-slice"]], "parse_slice": [[78, "parse-slice"]], "sanitize": [[78, "sanitize"]], "parse_args": [[78, "parse-args"], [78, "id15"]], "ap": [[78, "ap"]], "safe_get": [[78, "safe-get"]], "table2string": [[78, "table2string"]], "data": [[79, "module-nibabel.data"]], "Bomber": [[79, "bomber"]], "BomberError": [[79, "bombererror"]], "DataError": [[79, "dataerror"], [119, "dataerror"]], "Datasource": [[79, "datasource"]], "VersionedDatasource": [[79, "versioneddatasource"]], "datasource_or_bomber": [[79, "datasource-or-bomber"]], "find_data_dir": [[79, "find-data-dir"]], "get_data_path": [[79, "get-data-path"]], "make_datasource": [[79, "make-datasource"]], "dataobj_images": [[80, "module-nibabel.dataobj_images"]], "DataobjImage": [[80, "dataobjimage"]], "deprecated": [[81, "module-nibabel.deprecated"]], "FutureWarningMixin": [[81, "futurewarningmixin"]], "ModuleProxy": [[81, "moduleproxy"]], "VisibleDeprecationWarning": [[81, "visibledeprecationwarning"]], "alert_future_error": [[81, "alert-future-error"]], "deprecator": [[82, "module-nibabel.deprecator"]], "Deprecator": [[82, "id1"]], "ExpiredDeprecationError": [[82, "expireddeprecationerror"]], "dft": [[83, "module-nibabel.dft"]], "CachingError": [[83, "cachingerror"]], "DFTError": [[83, "dfterror"]], "InstanceStackError": [[83, "instancestackerror"]], "VolumeError": [[83, "volumeerror"]], "clear_cache": [[83, "clear-cache"]], "get_studies": [[83, "get-studies"]], "update_cache": [[83, "update-cache"]], "ecat": [[84, "module-nibabel.ecat"]], "EcatHeader": [[84, "ecatheader"]], "EcatImage": [[84, "ecatimage"]], "EcatImageArrayProxy": [[84, "ecatimagearrayproxy"]], "EcatSubHeader": [[84, "ecatsubheader"]], "get_frame_order": [[84, "get-frame-order"]], "get_series_framenumbers": [[84, "get-series-framenumbers"]], "read_mlist": [[84, "read-mlist"]], "read_subheaders": [[84, "read-subheaders"]], "environment": [[85, "module-nibabel.environment"]], "get_home_dir": [[85, "get-home-dir"]], "get_nipy_system_dir": [[85, "get-nipy-system-dir"]], "get_nipy_user_dir": [[85, "get-nipy-user-dir"]], "eulerangles": [[86, "module-nibabel.eulerangles"]], "angle_axis2euler": [[86, "angle-axis2euler"]], "euler2angle_axis": [[86, "euler2angle-axis"]], "euler2mat": [[86, "euler2mat"]], "euler2quat": [[86, "euler2quat"]], "mat2euler": [[86, "mat2euler"]], "quat2euler": [[86, "quat2euler"]], "filebasedimages": [[87, "module-nibabel.filebasedimages"]], "FileBasedHeader": [[87, "filebasedheader"]], "FileBasedImage": [[87, "filebasedimage"]], "ImageFileError": [[87, "imagefileerror"]], "SerializableImage": [[87, "serializableimage"]], "fileholders": [[88, "module-nibabel.fileholders"]], "FileHolder": [[88, "fileholder"]], "FileHolderError": [[88, "fileholdererror"]], "copy_file_map": [[88, "copy-file-map"]], "filename_parser": [[89, "module-nibabel.filename_parser"]], "TypesFilenamesError": [[89, "typesfilenameserror"]], "parse_filename": [[89, "parse-filename"]], "splitext_addext": [[89, "splitext-addext"]], "types_filenames": [[89, "types-filenames"]], "fileslice": [[90, "module-nibabel.fileslice"], [90, "id1"]], "calc_slicedefs": [[90, "calc-slicedefs"]], "canonical_slicers": [[90, "canonical-slicers"]], "fill_slicer": [[90, "fill-slicer"]], "is_fancy": [[90, "is-fancy"]], "optimize_read_slicers": [[90, "optimize-read-slicers"]], "optimize_slicer": [[90, "optimize-slicer"]], "predict_shape": [[90, "predict-shape"]], "read_segments": [[90, "read-segments"]], "slice2len": [[90, "slice2len"]], "slice2outax": [[90, "slice2outax"]], "slicers2segments": [[90, "slicers2segments"]], "strided_scalar": [[90, "strided-scalar"]], "threshold_heuristic": [[90, "threshold-heuristic"]], "fileutils": [[91, "module-nibabel.fileutils"]], "read_zt_byte_strings": [[91, "read-zt-byte-strings"]], "freesurfer": [[92, "module-nibabel.freesurfer"]], "Module: freesurfer.io": [[92, "module-nibabel.freesurfer.io"]], "Module: freesurfer.mghformat": [[92, "module-nibabel.freesurfer.mghformat"]], "read_annot": [[92, "read-annot"]], "read_geometry": [[92, "read-geometry"]], "read_label": [[92, "read-label"]], "read_morph_data": [[92, "read-morph-data"]], "write_annot": [[92, "write-annot"]], "write_geometry": [[92, "write-geometry"]], "write_morph_data": [[92, "write-morph-data"]], "MGHError": [[92, "mgherror"]], "MGHHeader": [[92, "mghheader"]], "MGHImage": [[92, "mghimage"]], "funcs": [[93, "module-nibabel.funcs"]], "as_closest_canonical": [[93, "as-closest-canonical"]], "concat_images": [[93, "concat-images"]], "four_to_three": [[93, "four-to-three"]], "squeeze_image": [[93, "squeeze-image"]], "gifti": [[94, "module-nibabel.gifti"]], "Module: gifti.gifti": [[94, "module-nibabel.gifti.gifti"]], "Module: gifti.parse_gifti_fast": [[94, "module-nibabel.gifti.parse_gifti_fast"]], "Module: gifti.util": [[94, "module-nibabel.gifti.util"]], "GiftiCoordSystem": [[94, "gifticoordsystem"]], "GiftiDataArray": [[94, "giftidataarray"]], "GiftiImage": [[94, "giftiimage"]], "GiftiLabel": [[94, "giftilabel"]], "GiftiLabelTable": [[94, "giftilabeltable"]], "GiftiMetaData": [[94, "giftimetadata"]], "GiftiNVPairs": [[94, "giftinvpairs"]], "GiftiImageParser": [[94, "giftiimageparser"]], "GiftiParseError": [[94, "giftiparseerror"]], "read_data_block": [[94, "read-data-block"]], "imageclasses": [[95, "module-nibabel.imageclasses"]], "spatial_axes_first": [[95, "spatial-axes-first"]], "imageglobals": [[96, "module-nibabel.imageglobals"]], "ErrorLevel": [[96, "errorlevel"]], "LoggingOutputSuppressor": [[96, "loggingoutputsuppressor"]], "imagestats": [[97, "module-nibabel.imagestats"]], "count_nonzero_voxels": [[97, "count-nonzero-voxels"]], "mask_volume": [[97, "mask-volume"]], "loadsave": [[98, "module-nibabel.loadsave"]], "guessed_image_type": [[98, "guessed-image-type"]], "load": [[98, "load"], [103, "load"], [104, "load"], [119, "load"]], "read_img_data": [[98, "read-img-data"]], "save": [[98, "save"], [103, "save"], [104, "save"], [119, "save"]], "minc1": [[99, "module-nibabel.minc1"]], "Minc1File": [[99, "minc1file"]], "Minc1Header": [[99, "minc1header"]], "Minc1Image": [[99, "minc1image"]], "MincError": [[99, "mincerror"]], "MincHeader": [[99, "mincheader"]], "MincImageArrayProxy": [[99, "mincimagearrayproxy"]], "minc2": [[100, "module-nibabel.minc2"]], "Hdf5Bunch": [[100, "hdf5bunch"]], "Minc2File": [[100, "minc2file"]], "Minc2Header": [[100, "minc2header"]], "Minc2Image": [[100, "minc2image"]], "mriutils": [[101, "module-nibabel.mriutils"]], "MRIError": [[101, "mrierror"]], "calculate_dwell_time": [[101, "calculate-dwell-time"]], "nicom": [[102, "module-nibabel.nicom"]], "Module: nicom.ascconv": [[102, "module-nibabel.nicom.ascconv"]], "Module: nicom.csareader": [[102, "module-nibabel.nicom.csareader"]], "Module: nicom.dicomreaders": [[102, "module-nibabel.nicom.dicomreaders"]], "Module: nicom.dicomwrappers": [[102, "module-nibabel.nicom.dicomwrappers"]], "Module: nicom.dwiparams": [[102, "module-nibabel.nicom.dwiparams"]], "Module: nicom.structreader": [[102, "module-nibabel.nicom.structreader"]], "Module: nicom.utils": [[102, "module-nibabel.nicom.utils"]], "AscconvParseError": [[102, "ascconvparseerror"]], "Atom": [[102, "atom"]], "NoValue": [[102, "novalue"]], "assign2atoms": [[102, "assign2atoms"]], "obj_from_atoms": [[102, "obj-from-atoms"]], "parse_ascconv": [[102, "parse-ascconv"]], "CSAError": [[102, "csaerror"]], "CSAReadError": [[102, "csareaderror"]], "get_acq_mat_txt": [[102, "get-acq-mat-txt"]], "get_b_matrix": [[102, "get-b-matrix"]], "get_b_value": [[102, "get-b-value"]], "get_csa_header": [[102, "get-csa-header"]], "get_g_vector": [[102, "get-g-vector"]], "get_ice_dims": [[102, "get-ice-dims"]], "get_n_mosaic": [[102, "get-n-mosaic"]], "get_scalar": [[102, "get-scalar"]], "get_slice_normal": [[102, "get-slice-normal"]], "get_vector": [[102, "get-vector"]], "is_mosaic": [[102, "is-mosaic"]], "nt_str": [[102, "nt-str"]], "read": [[102, "read"]], "DicomReadError": [[102, "dicomreaderror"]], "mosaic_to_nii": [[102, "mosaic-to-nii"]], "read_mosaic_dir": [[102, "read-mosaic-dir"]], "read_mosaic_dwi_dir": [[102, "read-mosaic-dwi-dir"]], "slices_to_series": [[102, "slices-to-series"]], "MosaicWrapper": [[102, "mosaicwrapper"]], "MultiframeWrapper": [[102, "multiframewrapper"]], "SiemensWrapper": [[102, "siemenswrapper"]], "Wrapper": [[102, "wrapper"]], "WrapperError": [[102, "wrappererror"]], "WrapperPrecisionError": [[102, "wrapperprecisionerror"]], "none_or_close": [[102, "none-or-close"]], "wrapper_from_data": [[102, "wrapper-from-data"]], "wrapper_from_file": [[102, "wrapper-from-file"]], "B2q": [[102, "b2q"]], "nearest_pos_semi_def": [[102, "nearest-pos-semi-def"]], "q2bg": [[102, "q2bg"]], "Unpacker": [[102, "unpacker"]], "find_private_section": [[102, "find-private-section"]], "nifti1": [[103, "module-nibabel.nifti1"]], "Nifti1DicomExtension": [[103, "nifti1dicomextension"]], "Nifti1Extension": [[103, "nifti1extension"]], "Nifti1Extensions": [[103, "nifti1extensions"]], "Nifti1Header": [[103, "nifti1header"]], "Nifti1Image": [[103, "nifti1image"]], "Nifti1Pair": [[103, "nifti1pair"]], "Nifti1PairHeader": [[103, "nifti1pairheader"]], "nifti2": [[104, "module-nibabel.nifti2"]], "Nifti2Header": [[104, "nifti2header"]], "Nifti2Image": [[104, "nifti2image"]], "Nifti2Pair": [[104, "nifti2pair"]], "Nifti2PairHeader": [[104, "nifti2pairheader"]], "onetime": [[105, "module-nibabel.onetime"]], "References": [[105, "references"]], "OneTimeProperty": [[105, "onetimeproperty"]], "ResetMixin": [[105, "resetmixin"]], "auto_attr": [[105, "auto-attr"]], "setattr_on_read": [[105, "setattr-on-read"]], "openers": [[106, "module-nibabel.openers"]], "DeterministicGzipFile": [[106, "deterministicgzipfile"]], "Fileish": [[106, "fileish"]], "ImageOpener": [[106, "imageopener"]], "Opener": [[106, "opener"]], "optpkg": [[107, "module-nibabel.optpkg"]], "optional_package": [[107, "optional-package"]], "orientations": [[108, "module-nibabel.orientations"]], "OrientationError": [[108, "orientationerror"]], "aff2axcodes": [[108, "aff2axcodes"]], "apply_orientation": [[108, "apply-orientation"]], "axcodes2ornt": [[108, "axcodes2ornt"]], "flip_axis": [[108, "flip-axis"]], "inv_ornt_aff": [[108, "inv-ornt-aff"]], "io_orientation": [[108, "io-orientation"]], "ornt2axcodes": [[108, "ornt2axcodes"]], "ornt_transform": [[108, "ornt-transform"]], "parrec": [[109, "module-nibabel.parrec"]], "PAR file format": [[109, "par-file-format"]], "General information": [[109, "general-information"]], "Image information": [[109, "image-information"]], "Orientation": [[109, "orientation"]], "Data type": [[109, "data-type"]], "Data Sorting": [[109, "data-sorting"]], "PARRECArrayProxy": [[109, "parrecarrayproxy"]], "PARRECError": [[109, "parrecerror"]], "PARRECHeader": [[109, "parrecheader"]], "PARRECImage": [[109, "parrecimage"]], "exts2pars": [[109, "exts2pars"]], "one_line": [[109, "one-line"]], "parse_PAR_header": [[109, "parse-par-header"]], "vol_is_full": [[109, "vol-is-full"]], "vol_numbers": [[109, "vol-numbers"]], "pointset": [[110, "module-nibabel.pointset"]], "CoordinateArray": [[110, "coordinatearray"]], "Grid": [[110, "grid"]], "GridIndices": [[110, "gridindices"]], "Pointset": [[110, "id1"]], "processing": [[111, "module-nibabel.processing"]], "adapt_affine": [[111, "adapt-affine"]], "conform": [[111, "conform"]], "fwhm2sigma": [[111, "fwhm2sigma"]], "resample_from_to": [[111, "resample-from-to"]], "resample_to_output": [[111, "resample-to-output"]], "sigma2fwhm": [[111, "sigma2fwhm"]], "smooth_image": [[111, "smooth-image"]], "pydicom_compat": [[112, "module-nibabel.pydicom_compat"]], "dicom_test": [[112, "dicom-test"]], "quaternions": [[113, "module-nibabel.quaternions"]], "angle_axis2mat": [[113, "angle-axis2mat"]], "angle_axis2quat": [[113, "angle-axis2quat"]], "conjugate": [[113, "conjugate"]], "eye": [[113, "eye"]], "fillpositive": [[113, "fillpositive"]], "inverse": [[113, "inverse"]], "isunit": [[113, "isunit"]], "mat2quat": [[113, "mat2quat"]], "mult": [[113, "mult"]], "nearly_equivalent": [[113, "nearly-equivalent"]], "norm": [[113, "norm"]], "quat2angle_axis": [[113, "quat2angle-axis"]], "quat2mat": [[113, "quat2mat"]], "rotate_vector": [[113, "rotate-vector"]], "rstutils": [[114, "module-nibabel.rstutils"]], "rst_table": [[114, "rst-table"]], "spaces": [[115, "module-nibabel.spaces"]], "slice2volume": [[115, "slice2volume"]], "vox2out_vox": [[115, "vox2out-vox"]], "spatialimages": [[116, "module-nibabel.spatialimages"]], "There are several ways of writing data.": [[116, "there-are-several-ways-of-writing-data"]], "Files interface": [[116, "files-interface"]], "HasDtype": [[116, "hasdtype"]], "HeaderDataError": [[116, "headerdataerror"]], "HeaderTypeError": [[116, "headertypeerror"]], "ImageDataError": [[116, "imagedataerror"]], "SpatialFirstSlicer": [[116, "spatialfirstslicer"]], "SpatialHeader": [[116, "spatialheader"]], "SpatialImage": [[116, "spatialimage"]], "SpatialProtocol": [[116, "spatialprotocol"]], "supported_np_types": [[116, "supported-np-types"]], "spm2analyze": [[117, "module-nibabel.spm2analyze"]], "Spm2AnalyzeHeader": [[117, "spm2analyzeheader"]], "Spm2AnalyzeImage": [[117, "spm2analyzeimage"]], "spm99analyze": [[118, "module-nibabel.spm99analyze"]], "Spm99AnalyzeHeader": [[118, "spm99analyzeheader"]], "Spm99AnalyzeImage": [[118, "spm99analyzeimage"]], "SpmAnalyzeHeader": [[118, "spmanalyzeheader"]], "streamlines": [[119, "module-nibabel.streamlines"]], "Module: streamlines.array_sequence": [[119, "module-nibabel.streamlines.array_sequence"]], "Module: streamlines.header": [[119, "module-nibabel.streamlines.header"]], "Module: streamlines.tck": [[119, "module-nibabel.streamlines.tck"]], "Module: streamlines.tractogram": [[119, "module-nibabel.streamlines.tractogram"]], "Module: streamlines.tractogram_file": [[119, "module-nibabel.streamlines.tractogram_file"]], "Module: streamlines.trk": [[119, "module-nibabel.streamlines.trk"]], "Module: streamlines.utils": [[119, "module-nibabel.streamlines.utils"]], "detect_format": [[119, "detect-format"]], "is_supported": [[119, "is-supported"]], "ArraySequence": [[119, "arraysequence"]], "concatenate": [[119, "concatenate"]], "create_arraysequences_from_generator": [[119, "create-arraysequences-from-generator"]], "is_array_sequence": [[119, "is-array-sequence"]], "is_ndarray_of_int_or_bool": [[119, "is-ndarray-of-int-or-bool"]], "Field": [[119, "field"]], "TckFile": [[119, "tckfile"]], "LazyDict": [[119, "lazydict"]], "LazyTractogram": [[119, "lazytractogram"]], "PerArrayDict": [[119, "perarraydict"]], "PerArraySequenceDict": [[119, "perarraysequencedict"]], "SliceableDataDict": [[119, "sliceabledatadict"]], "Tractogram": [[119, "tractogram"]], "TractogramItem": [[119, "tractogramitem"]], "is_data_dict": [[119, "is-data-dict"]], "is_lazy_dict": [[119, "is-lazy-dict"]], "DataWarning": [[119, "datawarning"]], "ExtensionWarning": [[119, "extensionwarning"]], "HeaderError": [[119, "headererror"]], "HeaderWarning": [[119, "headerwarning"]], "TractogramFile": [[119, "tractogramfile"]], "abstractclassmethod": [[119, "abstractclassmethod"]], "TrkFile": [[119, "trkfile"]], "decode_value_from_name": [[119, "decode-value-from-name"]], "encode_value_in_name": [[119, "encode-value-in-name"]], "get_affine_rasmm_to_trackvis": [[119, "get-affine-rasmm-to-trackvis"]], "get_affine_trackvis_to_rasmm": [[119, "get-affine-trackvis-to-rasmm"]], "get_affine_from_reference": [[119, "get-affine-from-reference"]], "peek_next": [[119, "peek-next"]], "tmpdirs": [[120, "module-nibabel.tmpdirs"]], "TemporaryDirectory": [[120, "temporarydirectory"]], "InGivenDirectory": [[120, "ingivendirectory"]], "InTemporaryDirectory": [[120, "intemporarydirectory"]], "tripwire": [[121, "module-nibabel.tripwire"]], "TripWire": [[121, "id1"]], "TripWireError": [[121, "tripwireerror"]], "is_tripwire": [[121, "is-tripwire"]], "viewers": [[122, "module-nibabel.viewers"]], "OrthoSlicer3D": [[122, "orthoslicer3d"]], "volumeutils": [[123, "module-nibabel.volumeutils"]], "DtypeMapper": [[123, "dtypemapper"]], "Recoder": [[123, "recoder"]], "apply_read_scaling": [[123, "apply-read-scaling"]], "array_from_file": [[123, "array-from-file"]], "array_to_file": [[123, "array-to-file"]], "best_write_scale_ftype": [[123, "best-write-scale-ftype"]], "better_float_of": [[123, "better-float-of"]], "finite_range": [[123, "finite-range"]], "fname_ext_ul_case": [[123, "fname-ext-ul-case"]], "int_scinter_ftype": [[123, "int-scinter-ftype"]], "make_dt_codes": [[123, "make-dt-codes"]], "pretty_mapping": [[123, "pretty-mapping"]], "rec2dict": [[123, "rec2dict"]], "seek_tell": [[123, "seek-tell"]], "shape_zoom_affine": [[123, "shape-zoom-affine"]], "working_type": [[123, "working-type"]], "write_zeros": [[123, "write-zeros"]], "wrapstruct": [[124, "module-nibabel.wrapstruct"], [124, "id1"]], "Mappingness": [[124, "mappingness"]], "Consistency checks": [[124, "consistency-checks"]], "LabeledWrapStruct": [[124, "labeledwrapstruct"]], "WrapStruct": [[124, "id2"]], "WrapStructError": [[124, "wrapstructerror"]], "xmlutils": [[125, "module-nibabel.xmlutils"]], "XmlBasedHeader": [[125, "xmlbasedheader"]], "XmlParser": [[125, "xmlparser"]], "XmlSerializable": [[125, "xmlserializable"]], "General tutorials": [[126, "general-tutorials"]]}, "indexentries": {"bench() (in module nibabel)": [[66, "nibabel.bench"]], "get_info() (in module nibabel)": [[66, "nibabel.get_info"]], "module": [[66, "module-nibabel"], [67, "module-nibabel._compression"], [68, "module-nibabel.affines"], [69, "module-nibabel.analyze"], [70, "module-nibabel.arrayproxy"], [71, "module-nibabel.arraywriters"], [72, "module-nibabel.batteryrunners"], [73, "module-nibabel.benchmarks"], [73, "module-nibabel.benchmarks.bench_array_to_file"], [73, "module-nibabel.benchmarks.bench_arrayproxy_slicing"], [73, "module-nibabel.benchmarks.bench_fileslice"], [73, "module-nibabel.benchmarks.bench_finite_range"], [73, "module-nibabel.benchmarks.bench_load_save"], [73, "module-nibabel.benchmarks.butils"], [74, "module-nibabel.brikhead"], [75, "module-nibabel.caret"], [76, "module-nibabel.casting"], [77, "module-nibabel.cifti2"], [77, "module-nibabel.cifti2.cifti2"], [77, "module-nibabel.cifti2.cifti2_axes"], [77, "module-nibabel.cifti2.parse_cifti2"], [78, "module-nibabel.cmdline"], [78, "module-nibabel.cmdline.conform"], [78, "module-nibabel.cmdline.convert"], [78, "module-nibabel.cmdline.dicomfs"], [78, "module-nibabel.cmdline.diff"], [78, "module-nibabel.cmdline.ls"], [78, "module-nibabel.cmdline.nifti_dx"], [78, "module-nibabel.cmdline.parrec2nii"], [78, "module-nibabel.cmdline.roi"], [78, "module-nibabel.cmdline.stats"], [78, "module-nibabel.cmdline.tck2trk"], [78, "module-nibabel.cmdline.trk2tck"], [78, "module-nibabel.cmdline.utils"], [79, "module-nibabel.data"], [80, "module-nibabel.dataobj_images"], [81, "module-nibabel.deprecated"], [82, "module-nibabel.deprecator"], [83, "module-nibabel.dft"], [84, "module-nibabel.ecat"], [85, "module-nibabel.environment"], [86, "module-nibabel.eulerangles"], [87, "module-nibabel.filebasedimages"], [88, "module-nibabel.fileholders"], [89, "module-nibabel.filename_parser"], [90, "module-nibabel.fileslice"], [91, "module-nibabel.fileutils"], [92, "module-nibabel.freesurfer"], [92, "module-nibabel.freesurfer.io"], [92, "module-nibabel.freesurfer.mghformat"], [93, "module-nibabel.funcs"], [94, "module-nibabel.gifti"], [94, "module-nibabel.gifti.gifti"], [94, "module-nibabel.gifti.parse_gifti_fast"], [94, "module-nibabel.gifti.util"], [95, "module-nibabel.imageclasses"], [96, "module-nibabel.imageglobals"], [97, "module-nibabel.imagestats"], [98, "module-nibabel.loadsave"], [99, "module-nibabel.minc1"], [100, "module-nibabel.minc2"], [101, "module-nibabel.mriutils"], [102, "module-nibabel.nicom"], [102, "module-nibabel.nicom.ascconv"], [102, "module-nibabel.nicom.csareader"], [102, "module-nibabel.nicom.dicomreaders"], [102, "module-nibabel.nicom.dicomwrappers"], [102, "module-nibabel.nicom.dwiparams"], [102, "module-nibabel.nicom.structreader"], [102, "module-nibabel.nicom.utils"], [103, "module-nibabel.nifti1"], [104, "module-nibabel.nifti2"], [105, "module-nibabel.onetime"], [106, "module-nibabel.openers"], [107, "module-nibabel.optpkg"], [108, "module-nibabel.orientations"], [109, "module-nibabel.parrec"], [110, "module-nibabel.pointset"], [111, "module-nibabel.processing"], [112, "module-nibabel.pydicom_compat"], [113, "module-nibabel.quaternions"], [114, "module-nibabel.rstutils"], [115, "module-nibabel.spaces"], [116, "module-nibabel.spatialimages"], [117, "module-nibabel.spm2analyze"], [118, "module-nibabel.spm99analyze"], [119, "module-nibabel.streamlines"], [119, "module-nibabel.streamlines.array_sequence"], [119, "module-nibabel.streamlines.header"], [119, "module-nibabel.streamlines.tck"], [119, "module-nibabel.streamlines.tractogram"], [119, "module-nibabel.streamlines.tractogram_file"], [119, "module-nibabel.streamlines.trk"], [119, "module-nibabel.streamlines.utils"], [120, "module-nibabel.tmpdirs"], [121, "module-nibabel.tripwire"], [122, "module-nibabel.viewers"], [123, "module-nibabel.volumeutils"], [124, "module-nibabel.wrapstruct"], [125, "module-nibabel.xmlutils"]], "nibabel": [[66, "module-nibabel"]], "test() (in module nibabel)": [[66, "nibabel.test"]], "nibabel._compression": [[67, "module-nibabel._compression"]], "affineerror (class in nibabel.affines)": [[68, "nibabel.affines.AffineError"]], "__init__() (nibabel.affines.affineerror method)": [[68, "nibabel.affines.AffineError.__init__"]], "append_diag() (in module nibabel.affines)": [[68, "nibabel.affines.append_diag"]], "apply_affine() (in module nibabel.affines)": [[68, "nibabel.affines.apply_affine"]], "dot_reduce() (in module nibabel.affines)": [[68, "nibabel.affines.dot_reduce"]], "from_matvec() (in module nibabel.affines)": [[68, "nibabel.affines.from_matvec"]], "nibabel.affines": [[68, "module-nibabel.affines"]], "obliquity() (in module nibabel.affines)": [[68, "nibabel.affines.obliquity"]], "rescale_affine() (in module nibabel.affines)": [[68, "nibabel.affines.rescale_affine"]], "to_matvec() (in module nibabel.affines)": [[68, "nibabel.affines.to_matvec"]], "voxel_sizes() (in module nibabel.affines)": [[68, "nibabel.affines.voxel_sizes"]], "analyzeheader (class in nibabel.analyze)": [[69, "nibabel.analyze.AnalyzeHeader"]], "analyzeimage (class in nibabel.analyze)": [[69, "nibabel.analyze.AnalyzeImage"]], "imagearrayproxy (nibabel.analyze.analyzeimage attribute)": [[69, "nibabel.analyze.AnalyzeImage.ImageArrayProxy"]], "__init__() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.__init__"]], "__init__() (nibabel.analyze.analyzeimage method)": [[69, "nibabel.analyze.AnalyzeImage.__init__"]], "as_analyze_map() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.as_analyze_map"]], "data_from_fileobj() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.data_from_fileobj"]], "data_to_fileobj() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.data_to_fileobj"]], "default_structarr() (nibabel.analyze.analyzeheader class method)": [[69, "nibabel.analyze.AnalyzeHeader.default_structarr"]], "default_x_flip (nibabel.analyze.analyzeheader attribute)": [[69, "nibabel.analyze.AnalyzeHeader.default_x_flip"]], "files_types (nibabel.analyze.analyzeimage attribute)": [[69, "nibabel.analyze.AnalyzeImage.files_types"]], "from_file_map() (nibabel.analyze.analyzeimage class method)": [[69, "nibabel.analyze.AnalyzeImage.from_file_map"]], "from_header() (nibabel.analyze.analyzeheader class method)": [[69, "nibabel.analyze.AnalyzeHeader.from_header"]], "get_base_affine() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.get_base_affine"]], "get_best_affine() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.get_best_affine"]], "get_data_dtype() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.get_data_dtype"]], "get_data_dtype() (nibabel.analyze.analyzeimage method)": [[69, "nibabel.analyze.AnalyzeImage.get_data_dtype"]], "get_data_offset() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.get_data_offset"]], "get_data_shape() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.get_data_shape"]], "get_slope_inter() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.get_slope_inter"]], "get_zooms() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.get_zooms"]], "guessed_endian() (nibabel.analyze.analyzeheader class method)": [[69, "nibabel.analyze.AnalyzeHeader.guessed_endian"]], "has_data_intercept (nibabel.analyze.analyzeheader attribute)": [[69, "nibabel.analyze.AnalyzeHeader.has_data_intercept"]], "has_data_slope (nibabel.analyze.analyzeheader attribute)": [[69, "nibabel.analyze.AnalyzeHeader.has_data_slope"]], "header_class (nibabel.analyze.analyzeimage attribute)": [[69, "nibabel.analyze.AnalyzeImage.header_class"]], "makeable (nibabel.analyze.analyzeimage attribute)": [[69, "nibabel.analyze.AnalyzeImage.makeable"]], "may_contain_header() (nibabel.analyze.analyzeheader class method)": [[69, "nibabel.analyze.AnalyzeHeader.may_contain_header"]], "nibabel.analyze": [[69, "module-nibabel.analyze"]], "raw_data_from_fileobj() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.raw_data_from_fileobj"]], "rw (nibabel.analyze.analyzeimage attribute)": [[69, "nibabel.analyze.AnalyzeImage.rw"]], "set_data_dtype() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.set_data_dtype"]], "set_data_dtype() (nibabel.analyze.analyzeimage method)": [[69, "nibabel.analyze.AnalyzeImage.set_data_dtype"]], "set_data_offset() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.set_data_offset"]], "set_data_shape() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.set_data_shape"]], "set_slope_inter() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.set_slope_inter"]], "set_zooms() (nibabel.analyze.analyzeheader method)": [[69, "nibabel.analyze.AnalyzeHeader.set_zooms"]], "sizeof_hdr (nibabel.analyze.analyzeheader attribute)": [[69, "nibabel.analyze.AnalyzeHeader.sizeof_hdr"]], "template_dtype (nibabel.analyze.analyzeheader attribute)": [[69, "nibabel.analyze.AnalyzeHeader.template_dtype"]], "to_file_map() (nibabel.analyze.analyzeimage method)": [[69, "nibabel.analyze.AnalyzeImage.to_file_map"]], "valid_exts (nibabel.analyze.analyzeimage attribute)": [[69, "nibabel.analyze.AnalyzeImage.valid_exts"]], "arraylike (class in nibabel.arrayproxy)": [[70, "nibabel.arrayproxy.ArrayLike"]], "arrayproxy (class in nibabel.arrayproxy)": [[70, "nibabel.arrayproxy.ArrayProxy"]], "__init__() (nibabel.arrayproxy.arraylike method)": [[70, "nibabel.arrayproxy.ArrayLike.__init__"]], "__init__() (nibabel.arrayproxy.arrayproxy method)": [[70, "nibabel.arrayproxy.ArrayProxy.__init__"]], "copy() (nibabel.arrayproxy.arrayproxy method)": [[70, "nibabel.arrayproxy.ArrayProxy.copy"]], "dtype (nibabel.arrayproxy.arrayproxy property)": [[70, "nibabel.arrayproxy.ArrayProxy.dtype"]], "get_obj_dtype() (in module nibabel.arrayproxy)": [[70, "nibabel.arrayproxy.get_obj_dtype"]], "get_unscaled() (nibabel.arrayproxy.arrayproxy method)": [[70, "nibabel.arrayproxy.ArrayProxy.get_unscaled"]], "inter (nibabel.arrayproxy.arrayproxy property)": [[70, "nibabel.arrayproxy.ArrayProxy.inter"]], "is_proxy (nibabel.arrayproxy.arrayproxy property)": [[70, "nibabel.arrayproxy.ArrayProxy.is_proxy"]], "is_proxy() (in module nibabel.arrayproxy)": [[70, "nibabel.arrayproxy.is_proxy"]], "ndim (nibabel.arrayproxy.arraylike property)": [[70, "nibabel.arrayproxy.ArrayLike.ndim"]], "ndim (nibabel.arrayproxy.arrayproxy property)": [[70, "nibabel.arrayproxy.ArrayProxy.ndim"]], "nibabel.arrayproxy": [[70, "module-nibabel.arrayproxy"]], "offset (nibabel.arrayproxy.arrayproxy property)": [[70, "nibabel.arrayproxy.ArrayProxy.offset"]], "reshape() (nibabel.arrayproxy.arrayproxy method)": [[70, "nibabel.arrayproxy.ArrayProxy.reshape"]], "reshape_dataobj() (in module nibabel.arrayproxy)": [[70, "nibabel.arrayproxy.reshape_dataobj"]], "shape (nibabel.arrayproxy.arraylike attribute)": [[70, "nibabel.arrayproxy.ArrayLike.shape"]], "shape (nibabel.arrayproxy.arrayproxy property)": [[70, "nibabel.arrayproxy.ArrayProxy.shape"]], "slope (nibabel.arrayproxy.arrayproxy property)": [[70, "nibabel.arrayproxy.ArrayProxy.slope"]], "arraywriter (class in nibabel.arraywriters)": [[71, "nibabel.arraywriters.ArrayWriter"]], "scalingerror (class in nibabel.arraywriters)": [[71, "nibabel.arraywriters.ScalingError"]], "slopearraywriter (class in nibabel.arraywriters)": [[71, "nibabel.arraywriters.SlopeArrayWriter"]], "slopeinterarraywriter (class in nibabel.arraywriters)": [[71, "nibabel.arraywriters.SlopeInterArrayWriter"]], "writererror (class in nibabel.arraywriters)": [[71, "nibabel.arraywriters.WriterError"]], "__init__() (nibabel.arraywriters.arraywriter method)": [[71, "nibabel.arraywriters.ArrayWriter.__init__"]], "__init__() (nibabel.arraywriters.scalingerror method)": [[71, "nibabel.arraywriters.ScalingError.__init__"]], "__init__() (nibabel.arraywriters.slopearraywriter method)": [[71, "nibabel.arraywriters.SlopeArrayWriter.__init__"]], "__init__() (nibabel.arraywriters.slopeinterarraywriter method)": [[71, "nibabel.arraywriters.SlopeInterArrayWriter.__init__"]], "__init__() (nibabel.arraywriters.writererror method)": [[71, "nibabel.arraywriters.WriterError.__init__"]], "array (nibabel.arraywriters.arraywriter property)": [[71, "nibabel.arraywriters.ArrayWriter.array"]], "calc_scale() (nibabel.arraywriters.slopearraywriter method)": [[71, "nibabel.arraywriters.SlopeArrayWriter.calc_scale"]], "finite_range() (nibabel.arraywriters.arraywriter method)": [[71, "nibabel.arraywriters.ArrayWriter.finite_range"]], "get_slope_inter() (in module nibabel.arraywriters)": [[71, "nibabel.arraywriters.get_slope_inter"]], "has_nan (nibabel.arraywriters.arraywriter property)": [[71, "nibabel.arraywriters.ArrayWriter.has_nan"]], "inter (nibabel.arraywriters.slopeinterarraywriter property)": [[71, "nibabel.arraywriters.SlopeInterArrayWriter.inter"]], "make_array_writer() (in module nibabel.arraywriters)": [[71, "nibabel.arraywriters.make_array_writer"]], "nibabel.arraywriters": [[71, "module-nibabel.arraywriters"]], "out_dtype (nibabel.arraywriters.arraywriter property)": [[71, "nibabel.arraywriters.ArrayWriter.out_dtype"]], "reset() (nibabel.arraywriters.slopearraywriter method)": [[71, "nibabel.arraywriters.SlopeArrayWriter.reset"]], "reset() (nibabel.arraywriters.slopeinterarraywriter method)": [[71, "nibabel.arraywriters.SlopeInterArrayWriter.reset"]], "scaling_needed() (nibabel.arraywriters.arraywriter method)": [[71, "nibabel.arraywriters.ArrayWriter.scaling_needed"]], "scaling_needed() (nibabel.arraywriters.slopearraywriter method)": [[71, "nibabel.arraywriters.SlopeArrayWriter.scaling_needed"]], "slope (nibabel.arraywriters.slopearraywriter property)": [[71, "nibabel.arraywriters.SlopeArrayWriter.slope"]], "to_fileobj() (nibabel.arraywriters.arraywriter method)": [[71, "nibabel.arraywriters.ArrayWriter.to_fileobj"]], "to_fileobj() (nibabel.arraywriters.slopearraywriter method)": [[71, "nibabel.arraywriters.SlopeArrayWriter.to_fileobj"]], "to_fileobj() (nibabel.arraywriters.slopeinterarraywriter method)": [[71, "nibabel.arraywriters.SlopeInterArrayWriter.to_fileobj"]], "batteryrunner (class in nibabel.batteryrunners)": [[72, "nibabel.batteryrunners.BatteryRunner"]], "report (class in nibabel.batteryrunners)": [[72, "nibabel.batteryrunners.Report"]], "__init__() (nibabel.batteryrunners.batteryrunner method)": [[72, "nibabel.batteryrunners.BatteryRunner.__init__"]], "__init__() (nibabel.batteryrunners.report method)": [[72, "nibabel.batteryrunners.Report.__init__"]], "check_fix() (nibabel.batteryrunners.batteryrunner method)": [[72, "nibabel.batteryrunners.BatteryRunner.check_fix"]], "check_only() (nibabel.batteryrunners.batteryrunner method)": [[72, "nibabel.batteryrunners.BatteryRunner.check_only"]], "log_raise() (nibabel.batteryrunners.report method)": [[72, "nibabel.batteryrunners.Report.log_raise"]], "message (nibabel.batteryrunners.report property)": [[72, "nibabel.batteryrunners.Report.message"]], "nibabel.batteryrunners": [[72, "module-nibabel.batteryrunners"]], "write_raise() (nibabel.batteryrunners.report method)": [[72, "nibabel.batteryrunners.Report.write_raise"]], "bench_array_to_file() (in module nibabel.benchmarks.bench_array_to_file)": [[73, "nibabel.benchmarks.bench_array_to_file.bench_array_to_file"]], "bench_arrayproxy_slicing() (in module nibabel.benchmarks.bench_arrayproxy_slicing)": [[73, "nibabel.benchmarks.bench_arrayproxy_slicing.bench_arrayproxy_slicing"]], "bench_fileslice() (in module nibabel.benchmarks.bench_fileslice)": [[73, "nibabel.benchmarks.bench_fileslice.bench_fileslice"]], "bench_finite_range() (in module nibabel.benchmarks.bench_finite_range)": [[73, "nibabel.benchmarks.bench_finite_range.bench_finite_range"]], "bench_load_save() (in module nibabel.benchmarks.bench_load_save)": [[73, "nibabel.benchmarks.bench_load_save.bench_load_save"]], "nibabel.benchmarks": [[73, "module-nibabel.benchmarks"]], "nibabel.benchmarks.bench_array_to_file": [[73, "module-nibabel.benchmarks.bench_array_to_file"]], "nibabel.benchmarks.bench_arrayproxy_slicing": [[73, "module-nibabel.benchmarks.bench_arrayproxy_slicing"]], "nibabel.benchmarks.bench_fileslice": [[73, "module-nibabel.benchmarks.bench_fileslice"]], "nibabel.benchmarks.bench_finite_range": [[73, "module-nibabel.benchmarks.bench_finite_range"]], "nibabel.benchmarks.bench_load_save": [[73, "module-nibabel.benchmarks.bench_load_save"]], "nibabel.benchmarks.butils": [[73, "module-nibabel.benchmarks.butils"]], "print_git_title() (in module nibabel.benchmarks.butils)": [[73, "nibabel.benchmarks.butils.print_git_title"]], "run_slices() (in module nibabel.benchmarks.bench_fileslice)": [[73, "nibabel.benchmarks.bench_fileslice.run_slices"]], "afniarrayproxy (class in nibabel.brikhead)": [[74, "nibabel.brikhead.AFNIArrayProxy"]], "afniheader (class in nibabel.brikhead)": [[74, "nibabel.brikhead.AFNIHeader"]], "afniheadererror (class in nibabel.brikhead)": [[74, "nibabel.brikhead.AFNIHeaderError"]], "afniimage (class in nibabel.brikhead)": [[74, "nibabel.brikhead.AFNIImage"]], "afniimageerror (class in nibabel.brikhead)": [[74, "nibabel.brikhead.AFNIImageError"]], "imagearrayproxy (nibabel.brikhead.afniimage attribute)": [[74, "nibabel.brikhead.AFNIImage.ImageArrayProxy"]], "__init__() (nibabel.brikhead.afniarrayproxy method)": [[74, "nibabel.brikhead.AFNIArrayProxy.__init__"]], "__init__() (nibabel.brikhead.afniheader method)": [[74, "nibabel.brikhead.AFNIHeader.__init__"]], "__init__() (nibabel.brikhead.afniheadererror method)": [[74, "nibabel.brikhead.AFNIHeaderError.__init__"]], "__init__() (nibabel.brikhead.afniimage method)": [[74, "nibabel.brikhead.AFNIImage.__init__"]], "__init__() (nibabel.brikhead.afniimageerror method)": [[74, "nibabel.brikhead.AFNIImageError.__init__"]], "copy() (nibabel.brikhead.afniheader method)": [[74, "nibabel.brikhead.AFNIHeader.copy"]], "files_types (nibabel.brikhead.afniimage attribute)": [[74, "nibabel.brikhead.AFNIImage.files_types"]], "filespec_to_file_map() (nibabel.brikhead.afniimage class method)": [[74, "nibabel.brikhead.AFNIImage.filespec_to_file_map"]], "from_file_map() (nibabel.brikhead.afniimage class method)": [[74, "nibabel.brikhead.AFNIImage.from_file_map"]], "from_fileobj() (nibabel.brikhead.afniheader class method)": [[74, "nibabel.brikhead.AFNIHeader.from_fileobj"]], "from_header() (nibabel.brikhead.afniheader class method)": [[74, "nibabel.brikhead.AFNIHeader.from_header"]], "get_affine() (nibabel.brikhead.afniheader method)": [[74, "nibabel.brikhead.AFNIHeader.get_affine"]], "get_data_offset() (nibabel.brikhead.afniheader method)": [[74, "nibabel.brikhead.AFNIHeader.get_data_offset"]], "get_data_scaling() (nibabel.brikhead.afniheader method)": [[74, "nibabel.brikhead.AFNIHeader.get_data_scaling"]], "get_slope_inter() (nibabel.brikhead.afniheader method)": [[74, "nibabel.brikhead.AFNIHeader.get_slope_inter"]], "get_space() (nibabel.brikhead.afniheader method)": [[74, "nibabel.brikhead.AFNIHeader.get_space"]], "get_volume_labels() (nibabel.brikhead.afniheader method)": [[74, "nibabel.brikhead.AFNIHeader.get_volume_labels"]], "header_class (nibabel.brikhead.afniimage attribute)": [[74, "nibabel.brikhead.AFNIImage.header_class"]], "makeable (nibabel.brikhead.afniimage attribute)": [[74, "nibabel.brikhead.AFNIImage.makeable"]], "nibabel.brikhead": [[74, "module-nibabel.brikhead"]], "parse_afni_header() (in module nibabel.brikhead)": [[74, "nibabel.brikhead.parse_AFNI_header"]], "rw (nibabel.brikhead.afniimage attribute)": [[74, "nibabel.brikhead.AFNIImage.rw"]], "scaling (nibabel.brikhead.afniarrayproxy property)": [[74, "nibabel.brikhead.AFNIArrayProxy.scaling"]], "valid_exts (nibabel.brikhead.afniimage attribute)": [[74, "nibabel.brikhead.AFNIImage.valid_exts"]], "caretmetadata (class in nibabel.caret)": [[75, "nibabel.caret.CaretMetaData"]], "__init__() (nibabel.caret.caretmetadata method)": [[75, "nibabel.caret.CaretMetaData.__init__"]], "nibabel.caret": [[75, "module-nibabel.caret"]], "castingerror (class in nibabel.casting)": [[76, "nibabel.casting.CastingError"]], "floatingerror (class in nibabel.casting)": [[76, "nibabel.casting.FloatingError"]], "__init__() (nibabel.casting.castingerror method)": [[76, "nibabel.casting.CastingError.__init__"]], "__init__() (nibabel.casting.floatingerror method)": [[76, "nibabel.casting.FloatingError.__init__"]], "able_int_type() (in module nibabel.casting)": [[76, "nibabel.casting.able_int_type"]], "as_int() (in module nibabel.casting)": [[76, "nibabel.casting.as_int"]], "best_float() (in module nibabel.casting)": [[76, "nibabel.casting.best_float"]], "ceil_exact() (in module nibabel.casting)": [[76, "nibabel.casting.ceil_exact"]], "float_to_int() (in module nibabel.casting)": [[76, "nibabel.casting.float_to_int"]], "floor_exact() (in module nibabel.casting)": [[76, "nibabel.casting.floor_exact"]], "floor_log2() (in module nibabel.casting)": [[76, "nibabel.casting.floor_log2"]], "have_binary128() (in module nibabel.casting)": [[76, "nibabel.casting.have_binary128"]], "int_abs() (in module nibabel.casting)": [[76, "nibabel.casting.int_abs"]], "int_to_float() (in module nibabel.casting)": [[76, "nibabel.casting.int_to_float"]], "longdouble_lte_float64() (in module nibabel.casting)": [[76, "nibabel.casting.longdouble_lte_float64"]], "longdouble_precision_improved() (in module nibabel.casting)": [[76, "nibabel.casting.longdouble_precision_improved"]], "nibabel.casting": [[76, "module-nibabel.casting"]], "ok_floats() (in module nibabel.casting)": [[76, "nibabel.casting.ok_floats"]], "on_powerpc() (in module nibabel.casting)": [[76, "nibabel.casting.on_powerpc"]], "shared_range() (in module nibabel.casting)": [[76, "nibabel.casting.shared_range"]], "type_info() (in module nibabel.casting)": [[76, "nibabel.casting.type_info"]], "ulp() (in module nibabel.casting)": [[76, "nibabel.casting.ulp"]], "axis (class in nibabel.cifti2.cifti2_axes)": [[77, "nibabel.cifti2.cifti2_axes.Axis"]], "brainmodelaxis (class in nibabel.cifti2.cifti2_axes)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis"]], "characterdatahandler() (nibabel.cifti2.parse_cifti2.cifti2parser method)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Parser.CharacterDataHandler"]], "cifti2brainmodel (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2BrainModel"]], "cifti2extension (class in nibabel.cifti2.parse_cifti2)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Extension"]], "cifti2header (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2Header"]], "cifti2headererror (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2HeaderError"]], "cifti2image (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2Image"]], "cifti2label (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2Label"]], "cifti2labeltable (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2LabelTable"]], "cifti2matrix (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2Matrix"]], "cifti2matrixindicesmap (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap"]], "cifti2metadata (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2MetaData"]], "cifti2namedmap (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2NamedMap"]], "cifti2parcel (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2Parcel"]], "cifti2parser (class in nibabel.cifti2.parse_cifti2)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Parser"]], "cifti2surface (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2Surface"]], "cifti2transformationmatrixvoxelindicesijktoxyz (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ"]], "cifti2vertexindices (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2VertexIndices"]], "cifti2vertices (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2Vertices"]], "cifti2volume (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2Volume"]], "cifti2voxelindicesijk (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.Cifti2VoxelIndicesIJK"]], "endelementhandler() (nibabel.cifti2.parse_cifti2.cifti2parser method)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Parser.EndElementHandler"]], "labelaxis (class in nibabel.cifti2.cifti2_axes)": [[77, "nibabel.cifti2.cifti2_axes.LabelAxis"]], "limitednifti2header (class in nibabel.cifti2.cifti2)": [[77, "nibabel.cifti2.cifti2.LimitedNifti2Header"]], "parcelsaxis (class in nibabel.cifti2.cifti2_axes)": [[77, "nibabel.cifti2.cifti2_axes.ParcelsAxis"]], "scalaraxis (class in nibabel.cifti2.cifti2_axes)": [[77, "nibabel.cifti2.cifti2_axes.ScalarAxis"]], "seriesaxis (class in nibabel.cifti2.cifti2_axes)": [[77, "nibabel.cifti2.cifti2_axes.SeriesAxis"]], "startelementhandler() (nibabel.cifti2.parse_cifti2.cifti2parser method)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Parser.StartElementHandler"]], "__init__() (nibabel.cifti2.cifti2.cifti2brainmodel method)": [[77, "nibabel.cifti2.cifti2.Cifti2BrainModel.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2header method)": [[77, "nibabel.cifti2.cifti2.Cifti2Header.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2headererror method)": [[77, "nibabel.cifti2.cifti2.Cifti2HeaderError.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2image method)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2label method)": [[77, "nibabel.cifti2.cifti2.Cifti2Label.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2labeltable method)": [[77, "nibabel.cifti2.cifti2.Cifti2LabelTable.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2matrix method)": [[77, "nibabel.cifti2.cifti2.Cifti2Matrix.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2matrixindicesmap method)": [[77, "nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2metadata method)": [[77, "nibabel.cifti2.cifti2.Cifti2MetaData.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2namedmap method)": [[77, "nibabel.cifti2.cifti2.Cifti2NamedMap.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2parcel method)": [[77, "nibabel.cifti2.cifti2.Cifti2Parcel.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2surface method)": [[77, "nibabel.cifti2.cifti2.Cifti2Surface.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2transformationmatrixvoxelindicesijktoxyz method)": [[77, "nibabel.cifti2.cifti2.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2vertexindices method)": [[77, "nibabel.cifti2.cifti2.Cifti2VertexIndices.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2vertices method)": [[77, "nibabel.cifti2.cifti2.Cifti2Vertices.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2volume method)": [[77, "nibabel.cifti2.cifti2.Cifti2Volume.__init__"]], "__init__() (nibabel.cifti2.cifti2.cifti2voxelindicesijk method)": [[77, "nibabel.cifti2.cifti2.Cifti2VoxelIndicesIJK.__init__"]], "__init__() (nibabel.cifti2.cifti2.limitednifti2header method)": [[77, "nibabel.cifti2.cifti2.LimitedNifti2Header.__init__"]], "__init__() (nibabel.cifti2.cifti2_axes.axis method)": [[77, "nibabel.cifti2.cifti2_axes.Axis.__init__"]], "__init__() (nibabel.cifti2.cifti2_axes.brainmodelaxis method)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.__init__"]], "__init__() (nibabel.cifti2.cifti2_axes.labelaxis method)": [[77, "nibabel.cifti2.cifti2_axes.LabelAxis.__init__"]], "__init__() (nibabel.cifti2.cifti2_axes.parcelsaxis method)": [[77, "nibabel.cifti2.cifti2_axes.ParcelsAxis.__init__"]], "__init__() (nibabel.cifti2.cifti2_axes.scalaraxis method)": [[77, "nibabel.cifti2.cifti2_axes.ScalarAxis.__init__"]], "__init__() (nibabel.cifti2.cifti2_axes.seriesaxis method)": [[77, "nibabel.cifti2.cifti2_axes.SeriesAxis.__init__"]], "__init__() (nibabel.cifti2.parse_cifti2.cifti2extension method)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Extension.__init__"]], "__init__() (nibabel.cifti2.parse_cifti2.cifti2parser method)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Parser.__init__"]], "affine (nibabel.cifti2.cifti2_axes.brainmodelaxis property)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.affine"]], "affine (nibabel.cifti2.cifti2_axes.parcelsaxis property)": [[77, "nibabel.cifti2.cifti2_axes.ParcelsAxis.affine"]], "append() (nibabel.cifti2.cifti2.cifti2labeltable method)": [[77, "nibabel.cifti2.cifti2.Cifti2LabelTable.append"]], "append_cifti_vertices() (nibabel.cifti2.cifti2.cifti2parcel method)": [[77, "nibabel.cifti2.cifti2.Cifti2Parcel.append_cifti_vertices"]], "brain_models (nibabel.cifti2.cifti2.cifti2matrixindicesmap property)": [[77, "nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap.brain_models"]], "code (nibabel.cifti2.parse_cifti2.cifti2extension attribute)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Extension.code"]], "data (nibabel.cifti2.cifti2.cifti2metadata property)": [[77, "nibabel.cifti2.cifti2.Cifti2MetaData.data"]], "difference_update() (nibabel.cifti2.cifti2.cifti2metadata method)": [[77, "nibabel.cifti2.cifti2.Cifti2MetaData.difference_update"]], "files_types (nibabel.cifti2.cifti2.cifti2image attribute)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.files_types"]], "flush_chardata() (nibabel.cifti2.parse_cifti2.cifti2parser method)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Parser.flush_chardata"]], "from_axes() (nibabel.cifti2.cifti2.cifti2header class method)": [[77, "nibabel.cifti2.cifti2.Cifti2Header.from_axes"]], "from_brain_models() (nibabel.cifti2.cifti2_axes.parcelsaxis class method)": [[77, "nibabel.cifti2.cifti2_axes.ParcelsAxis.from_brain_models"]], "from_file_map() (nibabel.cifti2.cifti2.cifti2image class method)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.from_file_map"]], "from_image() (nibabel.cifti2.cifti2.cifti2image class method)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.from_image"]], "from_index_mapping() (in module nibabel.cifti2.cifti2_axes)": [[77, "nibabel.cifti2.cifti2_axes.from_index_mapping"]], "from_index_mapping() (nibabel.cifti2.cifti2_axes.brainmodelaxis class method)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.from_index_mapping"]], "from_index_mapping() (nibabel.cifti2.cifti2_axes.labelaxis class method)": [[77, "nibabel.cifti2.cifti2_axes.LabelAxis.from_index_mapping"]], "from_index_mapping() (nibabel.cifti2.cifti2_axes.parcelsaxis class method)": [[77, "nibabel.cifti2.cifti2_axes.ParcelsAxis.from_index_mapping"]], "from_index_mapping() (nibabel.cifti2.cifti2_axes.scalaraxis class method)": [[77, "nibabel.cifti2.cifti2_axes.ScalarAxis.from_index_mapping"]], "from_index_mapping() (nibabel.cifti2.cifti2_axes.seriesaxis class method)": [[77, "nibabel.cifti2.cifti2_axes.SeriesAxis.from_index_mapping"]], "from_mask() (nibabel.cifti2.cifti2_axes.brainmodelaxis class method)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.from_mask"]], "from_surface() (nibabel.cifti2.cifti2_axes.brainmodelaxis class method)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.from_surface"]], "get_axis() (nibabel.cifti2.cifti2.cifti2header method)": [[77, "nibabel.cifti2.cifti2.Cifti2Header.get_axis"]], "get_axis() (nibabel.cifti2.cifti2.cifti2matrix method)": [[77, "nibabel.cifti2.cifti2.Cifti2Matrix.get_axis"]], "get_data_dtype() (nibabel.cifti2.cifti2.cifti2image method)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.get_data_dtype"]], "get_data_shape() (nibabel.cifti2.cifti2.cifti2matrix method)": [[77, "nibabel.cifti2.cifti2.Cifti2Matrix.get_data_shape"]], "get_element() (nibabel.cifti2.cifti2_axes.brainmodelaxis method)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.get_element"]], "get_element() (nibabel.cifti2.cifti2_axes.labelaxis method)": [[77, "nibabel.cifti2.cifti2_axes.LabelAxis.get_element"]], "get_element() (nibabel.cifti2.cifti2_axes.parcelsaxis method)": [[77, "nibabel.cifti2.cifti2_axes.ParcelsAxis.get_element"]], "get_element() (nibabel.cifti2.cifti2_axes.scalaraxis method)": [[77, "nibabel.cifti2.cifti2_axes.ScalarAxis.get_element"]], "get_element() (nibabel.cifti2.cifti2_axes.seriesaxis method)": [[77, "nibabel.cifti2.cifti2_axes.SeriesAxis.get_element"]], "get_index_map() (nibabel.cifti2.cifti2.cifti2header method)": [[77, "nibabel.cifti2.cifti2.Cifti2Header.get_index_map"]], "get_index_map() (nibabel.cifti2.cifti2.cifti2matrix method)": [[77, "nibabel.cifti2.cifti2.Cifti2Matrix.get_index_map"]], "header_class (nibabel.cifti2.cifti2.cifti2image attribute)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.header_class"]], "insert() (nibabel.cifti2.cifti2.cifti2matrix method)": [[77, "nibabel.cifti2.cifti2.Cifti2Matrix.insert"]], "insert() (nibabel.cifti2.cifti2.cifti2matrixindicesmap method)": [[77, "nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap.insert"]], "insert() (nibabel.cifti2.cifti2.cifti2vertexindices method)": [[77, "nibabel.cifti2.cifti2.Cifti2VertexIndices.insert"]], "insert() (nibabel.cifti2.cifti2.cifti2vertices method)": [[77, "nibabel.cifti2.cifti2.Cifti2Vertices.insert"]], "insert() (nibabel.cifti2.cifti2.cifti2voxelindicesijk method)": [[77, "nibabel.cifti2.cifti2.Cifti2VoxelIndicesIJK.insert"]], "iter_structures() (nibabel.cifti2.cifti2_axes.brainmodelaxis method)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.iter_structures"]], "label_table (nibabel.cifti2.cifti2.cifti2namedmap property)": [[77, "nibabel.cifti2.cifti2.Cifti2NamedMap.label_table"]], "makeable (nibabel.cifti2.cifti2.cifti2image attribute)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.makeable"]], "mapped_indices (nibabel.cifti2.cifti2.cifti2header property)": [[77, "nibabel.cifti2.cifti2.Cifti2Header.mapped_indices"]], "mapped_indices (nibabel.cifti2.cifti2.cifti2matrix property)": [[77, "nibabel.cifti2.cifti2.Cifti2Matrix.mapped_indices"]], "may_contain_header() (nibabel.cifti2.cifti2.cifti2header class method)": [[77, "nibabel.cifti2.cifti2.Cifti2Header.may_contain_header"]], "metadata (nibabel.cifti2.cifti2.cifti2matrix property)": [[77, "nibabel.cifti2.cifti2.Cifti2Matrix.metadata"]], "metadata (nibabel.cifti2.cifti2.cifti2namedmap property)": [[77, "nibabel.cifti2.cifti2.Cifti2NamedMap.metadata"]], "name (nibabel.cifti2.cifti2_axes.brainmodelaxis property)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.name"]], "named_maps (nibabel.cifti2.cifti2.cifti2matrixindicesmap property)": [[77, "nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap.named_maps"]], "nibabel.cifti2": [[77, "module-nibabel.cifti2"]], "nibabel.cifti2.cifti2": [[77, "module-nibabel.cifti2.cifti2"]], "nibabel.cifti2.cifti2_axes": [[77, "module-nibabel.cifti2.cifti2_axes"]], "nibabel.cifti2.parse_cifti2": [[77, "module-nibabel.cifti2.parse_cifti2"]], "nifti_header (nibabel.cifti2.cifti2.cifti2image property)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.nifti_header"]], "number_of_mapped_indices (nibabel.cifti2.cifti2.cifti2header property)": [[77, "nibabel.cifti2.cifti2.Cifti2Header.number_of_mapped_indices"]], "parcels (nibabel.cifti2.cifti2.cifti2matrixindicesmap property)": [[77, "nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap.parcels"]], "pending_data (nibabel.cifti2.parse_cifti2.cifti2parser property)": [[77, "nibabel.cifti2.parse_cifti2.Cifti2Parser.pending_data"]], "pop_cifti2_vertices() (nibabel.cifti2.cifti2.cifti2parcel method)": [[77, "nibabel.cifti2.cifti2.Cifti2Parcel.pop_cifti2_vertices"]], "rgba (nibabel.cifti2.cifti2.cifti2label property)": [[77, "nibabel.cifti2.cifti2.Cifti2Label.rgba"]], "rw (nibabel.cifti2.cifti2.cifti2image attribute)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.rw"]], "set_data_dtype() (nibabel.cifti2.cifti2.cifti2image method)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.set_data_dtype"]], "size (nibabel.cifti2.cifti2_axes.axis property)": [[77, "nibabel.cifti2.cifti2_axes.Axis.size"]], "size (nibabel.cifti2.cifti2_axes.seriesaxis attribute)": [[77, "nibabel.cifti2.cifti2_axes.SeriesAxis.size"]], "surface_mask (nibabel.cifti2.cifti2_axes.brainmodelaxis property)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.surface_mask"]], "surfaces (nibabel.cifti2.cifti2.cifti2matrixindicesmap property)": [[77, "nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap.surfaces"]], "time (nibabel.cifti2.cifti2_axes.seriesaxis property)": [[77, "nibabel.cifti2.cifti2_axes.SeriesAxis.time"]], "to_cifti_brain_structure_name() (nibabel.cifti2.cifti2_axes.brainmodelaxis static method)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.to_cifti_brain_structure_name"]], "to_file_map() (nibabel.cifti2.cifti2.cifti2image method)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.to_file_map"]], "to_header() (in module nibabel.cifti2.cifti2_axes)": [[77, "nibabel.cifti2.cifti2_axes.to_header"]], "to_mapping() (nibabel.cifti2.cifti2_axes.brainmodelaxis method)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.to_mapping"]], "to_mapping() (nibabel.cifti2.cifti2_axes.labelaxis method)": [[77, "nibabel.cifti2.cifti2_axes.LabelAxis.to_mapping"]], "to_mapping() (nibabel.cifti2.cifti2_axes.parcelsaxis method)": [[77, "nibabel.cifti2.cifti2_axes.ParcelsAxis.to_mapping"]], "to_mapping() (nibabel.cifti2.cifti2_axes.scalaraxis method)": [[77, "nibabel.cifti2.cifti2_axes.ScalarAxis.to_mapping"]], "to_mapping() (nibabel.cifti2.cifti2_axes.seriesaxis method)": [[77, "nibabel.cifti2.cifti2_axes.SeriesAxis.to_mapping"]], "unit (nibabel.cifti2.cifti2_axes.seriesaxis property)": [[77, "nibabel.cifti2.cifti2_axes.SeriesAxis.unit"]], "update_headers() (nibabel.cifti2.cifti2.cifti2image method)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.update_headers"]], "valid_exts (nibabel.cifti2.cifti2.cifti2image attribute)": [[77, "nibabel.cifti2.cifti2.Cifti2Image.valid_exts"]], "vertex_indices (nibabel.cifti2.cifti2.cifti2brainmodel property)": [[77, "nibabel.cifti2.cifti2.Cifti2BrainModel.vertex_indices"]], "volume (nibabel.cifti2.cifti2.cifti2matrixindicesmap property)": [[77, "nibabel.cifti2.cifti2.Cifti2MatrixIndicesMap.volume"]], "volume_mask (nibabel.cifti2.cifti2_axes.brainmodelaxis property)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.volume_mask"]], "volume_shape (nibabel.cifti2.cifti2_axes.brainmodelaxis property)": [[77, "nibabel.cifti2.cifti2_axes.BrainModelAxis.volume_shape"]], "volume_shape (nibabel.cifti2.cifti2_axes.parcelsaxis property)": [[77, "nibabel.cifti2.cifti2_axes.ParcelsAxis.volume_shape"]], "voxel_indices_ijk (nibabel.cifti2.cifti2.cifti2brainmodel property)": [[77, "nibabel.cifti2.cifti2.Cifti2BrainModel.voxel_indices_ijk"]], "voxel_indices_ijk (nibabel.cifti2.cifti2.cifti2parcel property)": [[77, "nibabel.cifti2.cifti2.Cifti2Parcel.voxel_indices_ijk"]], "dicomfs (class in nibabel.cmdline.dicomfs)": [[78, "nibabel.cmdline.dicomfs.DICOMFS"]], "filehandle (class in nibabel.cmdline.dicomfs)": [[78, "nibabel.cmdline.dicomfs.FileHandle"]], "fuse (nibabel.cmdline.dicomfs.dummy_fuse attribute)": [[78, "nibabel.cmdline.dicomfs.dummy_fuse.Fuse"]], "__init__() (nibabel.cmdline.dicomfs.dicomfs method)": [[78, "nibabel.cmdline.dicomfs.DICOMFS.__init__"]], "__init__() (nibabel.cmdline.dicomfs.filehandle method)": [[78, "nibabel.cmdline.dicomfs.FileHandle.__init__"]], "__init__() (nibabel.cmdline.dicomfs.dummy_fuse method)": [[78, "nibabel.cmdline.dicomfs.dummy_fuse.__init__"]], "ap() (in module nibabel.cmdline.utils)": [[78, "nibabel.cmdline.utils.ap"]], "are_values_different() (in module nibabel.cmdline.diff)": [[78, "nibabel.cmdline.diff.are_values_different"]], "diff() (in module nibabel.cmdline.diff)": [[78, "nibabel.cmdline.diff.diff"]], "display_diff() (in module nibabel.cmdline.diff)": [[78, "nibabel.cmdline.diff.display_diff"]], "dummy_fuse (class in nibabel.cmdline.dicomfs)": [[78, "nibabel.cmdline.dicomfs.dummy_fuse"]], "error() (in module nibabel.cmdline.parrec2nii)": [[78, "nibabel.cmdline.parrec2nii.error"]], "fuse (in module nibabel.cmdline.dicomfs)": [[78, "nibabel.cmdline.dicomfs.fuse"]], "fuse_python_api (nibabel.cmdline.dicomfs.dummy_fuse attribute)": [[78, "nibabel.cmdline.dicomfs.dummy_fuse.fuse_python_api"]], "get_data_diff() (in module nibabel.cmdline.diff)": [[78, "nibabel.cmdline.diff.get_data_diff"]], "get_data_hash_diff() (in module nibabel.cmdline.diff)": [[78, "nibabel.cmdline.diff.get_data_hash_diff"]], "get_headers_diff() (in module nibabel.cmdline.diff)": [[78, "nibabel.cmdline.diff.get_headers_diff"]], "get_opt_parser() (in module nibabel.cmdline.dicomfs)": [[78, "nibabel.cmdline.dicomfs.get_opt_parser"]], "get_opt_parser() (in module nibabel.cmdline.diff)": [[78, "nibabel.cmdline.diff.get_opt_parser"]], "get_opt_parser() (in module nibabel.cmdline.ls)": [[78, "nibabel.cmdline.ls.get_opt_parser"]], "get_opt_parser() (in module nibabel.cmdline.parrec2nii)": [[78, "nibabel.cmdline.parrec2nii.get_opt_parser"]], "get_paths() (nibabel.cmdline.dicomfs.dicomfs method)": [[78, "nibabel.cmdline.dicomfs.DICOMFS.get_paths"]], "getattr() (nibabel.cmdline.dicomfs.dicomfs method)": [[78, "nibabel.cmdline.dicomfs.DICOMFS.getattr"]], "lossless_slice() (in module nibabel.cmdline.roi)": [[78, "nibabel.cmdline.roi.lossless_slice"]], "main() (in module nibabel.cmdline.conform)": [[78, "nibabel.cmdline.conform.main"]], "main() (in module nibabel.cmdline.convert)": [[78, "nibabel.cmdline.convert.main"]], "main() (in module nibabel.cmdline.dicomfs)": [[78, "nibabel.cmdline.dicomfs.main"]], "main() (in module nibabel.cmdline.diff)": [[78, "nibabel.cmdline.diff.main"]], "main() (in module nibabel.cmdline.ls)": [[78, "nibabel.cmdline.ls.main"]], "main() (in module nibabel.cmdline.nifti_dx)": [[78, "nibabel.cmdline.nifti_dx.main"]], "main() (in module nibabel.cmdline.parrec2nii)": [[78, "nibabel.cmdline.parrec2nii.main"]], "main() (in module nibabel.cmdline.roi)": [[78, "nibabel.cmdline.roi.main"]], "main() (in module nibabel.cmdline.stats)": [[78, "nibabel.cmdline.stats.main"]], "main() (in module nibabel.cmdline.tck2trk)": [[78, "nibabel.cmdline.tck2trk.main"]], "main() (in module nibabel.cmdline.trk2tck)": [[78, "nibabel.cmdline.trk2tck.main"]], "match_path() (nibabel.cmdline.dicomfs.dicomfs method)": [[78, "nibabel.cmdline.dicomfs.DICOMFS.match_path"]], "nibabel.cmdline": [[78, "module-nibabel.cmdline"]], "nibabel.cmdline.conform": [[78, "module-nibabel.cmdline.conform"]], "nibabel.cmdline.convert": [[78, "module-nibabel.cmdline.convert"]], "nibabel.cmdline.dicomfs": [[78, "module-nibabel.cmdline.dicomfs"]], "nibabel.cmdline.diff": [[78, "module-nibabel.cmdline.diff"]], "nibabel.cmdline.ls": [[78, "module-nibabel.cmdline.ls"]], "nibabel.cmdline.nifti_dx": [[78, "module-nibabel.cmdline.nifti_dx"]], "nibabel.cmdline.parrec2nii": [[78, "module-nibabel.cmdline.parrec2nii"]], "nibabel.cmdline.roi": [[78, "module-nibabel.cmdline.roi"]], "nibabel.cmdline.stats": [[78, "module-nibabel.cmdline.stats"]], "nibabel.cmdline.tck2trk": [[78, "module-nibabel.cmdline.tck2trk"]], "nibabel.cmdline.trk2tck": [[78, "module-nibabel.cmdline.trk2tck"]], "nibabel.cmdline.utils": [[78, "module-nibabel.cmdline.utils"]], "open() (nibabel.cmdline.dicomfs.dicomfs method)": [[78, "nibabel.cmdline.dicomfs.DICOMFS.open"]], "parse_args() (in module nibabel.cmdline.tck2trk)": [[78, "nibabel.cmdline.tck2trk.parse_args"]], "parse_args() (in module nibabel.cmdline.trk2tck)": [[78, "nibabel.cmdline.trk2tck.parse_args"]], "parse_slice() (in module nibabel.cmdline.roi)": [[78, "nibabel.cmdline.roi.parse_slice"]], "proc_file() (in module nibabel.cmdline.ls)": [[78, "nibabel.cmdline.ls.proc_file"]], "proc_file() (in module nibabel.cmdline.parrec2nii)": [[78, "nibabel.cmdline.parrec2nii.proc_file"]], "read() (nibabel.cmdline.dicomfs.dicomfs method)": [[78, "nibabel.cmdline.dicomfs.DICOMFS.read"]], "readdir() (nibabel.cmdline.dicomfs.dicomfs method)": [[78, "nibabel.cmdline.dicomfs.DICOMFS.readdir"]], "release() (nibabel.cmdline.dicomfs.dicomfs method)": [[78, "nibabel.cmdline.dicomfs.DICOMFS.release"]], "safe_get() (in module nibabel.cmdline.utils)": [[78, "nibabel.cmdline.utils.safe_get"]], "sanitize() (in module nibabel.cmdline.roi)": [[78, "nibabel.cmdline.roi.sanitize"]], "table2string() (in module nibabel.cmdline.utils)": [[78, "nibabel.cmdline.utils.table2string"]], "verbose() (in module nibabel.cmdline.parrec2nii)": [[78, "nibabel.cmdline.parrec2nii.verbose"]], "verbose() (in module nibabel.cmdline.utils)": [[78, "nibabel.cmdline.utils.verbose"]], "bomber (class in nibabel.data)": [[79, "nibabel.data.Bomber"]], "bombererror (class in nibabel.data)": [[79, "nibabel.data.BomberError"]], "dataerror (class in nibabel.data)": [[79, "nibabel.data.DataError"]], "datasource (class in nibabel.data)": [[79, "nibabel.data.Datasource"]], "versioneddatasource (class in nibabel.data)": [[79, "nibabel.data.VersionedDatasource"]], "__init__() (nibabel.data.bomber method)": [[79, "nibabel.data.Bomber.__init__"]], "__init__() (nibabel.data.bombererror method)": [[79, "nibabel.data.BomberError.__init__"]], "__init__() (nibabel.data.dataerror method)": [[79, "nibabel.data.DataError.__init__"]], "__init__() (nibabel.data.datasource method)": [[79, "nibabel.data.Datasource.__init__"]], "__init__() (nibabel.data.versioneddatasource method)": [[79, "nibabel.data.VersionedDatasource.__init__"]], "datasource_or_bomber() (in module nibabel.data)": [[79, "nibabel.data.datasource_or_bomber"]], "find_data_dir() (in module nibabel.data)": [[79, "nibabel.data.find_data_dir"]], "get_data_path() (in module nibabel.data)": [[79, "nibabel.data.get_data_path"]], "get_filename() (nibabel.data.datasource method)": [[79, "nibabel.data.Datasource.get_filename"]], "list_files() (nibabel.data.datasource method)": [[79, "nibabel.data.Datasource.list_files"]], "make_datasource() (in module nibabel.data)": [[79, "nibabel.data.make_datasource"]], "nibabel.data": [[79, "module-nibabel.data"]], "dataobjimage (class in nibabel.dataobj_images)": [[80, "nibabel.dataobj_images.DataobjImage"]], "__init__() (nibabel.dataobj_images.dataobjimage method)": [[80, "nibabel.dataobj_images.DataobjImage.__init__"]], "dataobj (nibabel.dataobj_images.dataobjimage property)": [[80, "nibabel.dataobj_images.DataobjImage.dataobj"]], "from_file_map() (nibabel.dataobj_images.dataobjimage class method)": [[80, "nibabel.dataobj_images.DataobjImage.from_file_map"]], "from_filename() (nibabel.dataobj_images.dataobjimage class method)": [[80, "nibabel.dataobj_images.DataobjImage.from_filename"]], "get_data() (nibabel.dataobj_images.dataobjimage method)": [[80, "nibabel.dataobj_images.DataobjImage.get_data"]], "get_fdata() (nibabel.dataobj_images.dataobjimage method)": [[80, "nibabel.dataobj_images.DataobjImage.get_fdata"]], "in_memory (nibabel.dataobj_images.dataobjimage property)": [[80, "nibabel.dataobj_images.DataobjImage.in_memory"]], "load() (nibabel.dataobj_images.dataobjimage class method)": [[80, "nibabel.dataobj_images.DataobjImage.load"]], "ndim (nibabel.dataobj_images.dataobjimage property)": [[80, "nibabel.dataobj_images.DataobjImage.ndim"]], "nibabel.dataobj_images": [[80, "module-nibabel.dataobj_images"]], "shape (nibabel.dataobj_images.dataobjimage property)": [[80, "nibabel.dataobj_images.DataobjImage.shape"]], "uncache() (nibabel.dataobj_images.dataobjimage method)": [[80, "nibabel.dataobj_images.DataobjImage.uncache"]], "futurewarningmixin (class in nibabel.deprecated)": [[81, "nibabel.deprecated.FutureWarningMixin"]], "moduleproxy (class in nibabel.deprecated)": [[81, "nibabel.deprecated.ModuleProxy"]], "visibledeprecationwarning (class in nibabel.deprecated)": [[81, "nibabel.deprecated.VisibleDeprecationWarning"]], "__init__() (nibabel.deprecated.futurewarningmixin method)": [[81, "nibabel.deprecated.FutureWarningMixin.__init__"]], "__init__() (nibabel.deprecated.moduleproxy method)": [[81, "nibabel.deprecated.ModuleProxy.__init__"]], "__init__() (nibabel.deprecated.visibledeprecationwarning method)": [[81, "nibabel.deprecated.VisibleDeprecationWarning.__init__"]], "alert_future_error() (in module nibabel.deprecated)": [[81, "nibabel.deprecated.alert_future_error"]], "nibabel.deprecated": [[81, "module-nibabel.deprecated"]], "warn_message (nibabel.deprecated.futurewarningmixin attribute)": [[81, "nibabel.deprecated.FutureWarningMixin.warn_message"]], "deprecator (class in nibabel.deprecator)": [[82, "nibabel.deprecator.Deprecator"]], "expireddeprecationerror (class in nibabel.deprecator)": [[82, "nibabel.deprecator.ExpiredDeprecationError"]], "__init__() (nibabel.deprecator.deprecator method)": [[82, "nibabel.deprecator.Deprecator.__init__"]], "__init__() (nibabel.deprecator.expireddeprecationerror method)": [[82, "nibabel.deprecator.ExpiredDeprecationError.__init__"]], "is_bad_version() (nibabel.deprecator.deprecator method)": [[82, "nibabel.deprecator.Deprecator.is_bad_version"]], "nibabel.deprecator": [[82, "module-nibabel.deprecator"]], "cachingerror (class in nibabel.dft)": [[83, "nibabel.dft.CachingError"]], "dfterror (class in nibabel.dft)": [[83, "nibabel.dft.DFTError"]], "instancestackerror (class in nibabel.dft)": [[83, "nibabel.dft.InstanceStackError"]], "volumeerror (class in nibabel.dft)": [[83, "nibabel.dft.VolumeError"]], "__init__() (nibabel.dft.cachingerror method)": [[83, "nibabel.dft.CachingError.__init__"]], "__init__() (nibabel.dft.dfterror method)": [[83, "nibabel.dft.DFTError.__init__"]], "__init__() (nibabel.dft.instancestackerror method)": [[83, "nibabel.dft.InstanceStackError.__init__"]], "__init__() (nibabel.dft.volumeerror method)": [[83, "nibabel.dft.VolumeError.__init__"]], "clear_cache() (in module nibabel.dft)": [[83, "nibabel.dft.clear_cache"]], "get_studies() (in module nibabel.dft)": [[83, "nibabel.dft.get_studies"]], "nibabel.dft": [[83, "module-nibabel.dft"]], "update_cache() (in module nibabel.dft)": [[83, "nibabel.dft.update_cache"]], "ecatheader (class in nibabel.ecat)": [[84, "nibabel.ecat.EcatHeader"]], "ecatimage (class in nibabel.ecat)": [[84, "nibabel.ecat.EcatImage"]], "ecatimagearrayproxy (class in nibabel.ecat)": [[84, "nibabel.ecat.EcatImageArrayProxy"]], "ecatsubheader (class in nibabel.ecat)": [[84, "nibabel.ecat.EcatSubHeader"]], "imagearrayproxy (nibabel.ecat.ecatimage attribute)": [[84, "nibabel.ecat.EcatImage.ImageArrayProxy"]], "__init__() (nibabel.ecat.ecatheader method)": [[84, "nibabel.ecat.EcatHeader.__init__"]], "__init__() (nibabel.ecat.ecatimage method)": [[84, "nibabel.ecat.EcatImage.__init__"]], "__init__() (nibabel.ecat.ecatimagearrayproxy method)": [[84, "nibabel.ecat.EcatImageArrayProxy.__init__"]], "__init__() (nibabel.ecat.ecatsubheader method)": [[84, "nibabel.ecat.EcatSubHeader.__init__"]], "affine (nibabel.ecat.ecatimage property)": [[84, "nibabel.ecat.EcatImage.affine"]], "data_from_fileobj() (nibabel.ecat.ecatsubheader method)": [[84, "nibabel.ecat.EcatSubHeader.data_from_fileobj"]], "default_structarr() (nibabel.ecat.ecatheader class method)": [[84, "nibabel.ecat.EcatHeader.default_structarr"]], "files_types (nibabel.ecat.ecatimage attribute)": [[84, "nibabel.ecat.EcatImage.files_types"]], "from_file_map() (nibabel.ecat.ecatimage class method)": [[84, "nibabel.ecat.EcatImage.from_file_map"]], "from_image() (nibabel.ecat.ecatimage class method)": [[84, "nibabel.ecat.EcatImage.from_image"]], "get_data_dtype() (nibabel.ecat.ecatheader method)": [[84, "nibabel.ecat.EcatHeader.get_data_dtype"]], "get_data_dtype() (nibabel.ecat.ecatimage method)": [[84, "nibabel.ecat.EcatImage.get_data_dtype"]], "get_filetype() (nibabel.ecat.ecatheader method)": [[84, "nibabel.ecat.EcatHeader.get_filetype"]], "get_frame() (nibabel.ecat.ecatimage method)": [[84, "nibabel.ecat.EcatImage.get_frame"]], "get_frame_affine() (nibabel.ecat.ecatimage method)": [[84, "nibabel.ecat.EcatImage.get_frame_affine"]], "get_frame_affine() (nibabel.ecat.ecatsubheader method)": [[84, "nibabel.ecat.EcatSubHeader.get_frame_affine"]], "get_frame_order() (in module nibabel.ecat)": [[84, "nibabel.ecat.get_frame_order"]], "get_mlist() (nibabel.ecat.ecatimage method)": [[84, "nibabel.ecat.EcatImage.get_mlist"]], "get_nframes() (nibabel.ecat.ecatsubheader method)": [[84, "nibabel.ecat.EcatSubHeader.get_nframes"]], "get_patient_orient() (nibabel.ecat.ecatheader method)": [[84, "nibabel.ecat.EcatHeader.get_patient_orient"]], "get_series_framenumbers() (in module nibabel.ecat)": [[84, "nibabel.ecat.get_series_framenumbers"]], "get_shape() (nibabel.ecat.ecatsubheader method)": [[84, "nibabel.ecat.EcatSubHeader.get_shape"]], "get_subheaders() (nibabel.ecat.ecatimage method)": [[84, "nibabel.ecat.EcatImage.get_subheaders"]], "get_zooms() (nibabel.ecat.ecatsubheader method)": [[84, "nibabel.ecat.EcatSubHeader.get_zooms"]], "guessed_endian() (nibabel.ecat.ecatheader class method)": [[84, "nibabel.ecat.EcatHeader.guessed_endian"]], "header_class (nibabel.ecat.ecatimage attribute)": [[84, "nibabel.ecat.EcatImage.header_class"]], "is_proxy (nibabel.ecat.ecatimagearrayproxy property)": [[84, "nibabel.ecat.EcatImageArrayProxy.is_proxy"]], "load() (nibabel.ecat.ecatimage class method)": [[84, "nibabel.ecat.EcatImage.load"]], "ndim (nibabel.ecat.ecatimagearrayproxy property)": [[84, "nibabel.ecat.EcatImageArrayProxy.ndim"]], "nibabel.ecat": [[84, "module-nibabel.ecat"]], "raw_data_from_fileobj() (nibabel.ecat.ecatsubheader method)": [[84, "nibabel.ecat.EcatSubHeader.raw_data_from_fileobj"]], "read_mlist() (in module nibabel.ecat)": [[84, "nibabel.ecat.read_mlist"]], "read_subheaders() (in module nibabel.ecat)": [[84, "nibabel.ecat.read_subheaders"]], "shape (nibabel.ecat.ecatimage property)": [[84, "nibabel.ecat.EcatImage.shape"]], "shape (nibabel.ecat.ecatimagearrayproxy property)": [[84, "nibabel.ecat.EcatImageArrayProxy.shape"]], "subheader_class (nibabel.ecat.ecatimage attribute)": [[84, "nibabel.ecat.EcatImage.subheader_class"]], "template_dtype (nibabel.ecat.ecatheader attribute)": [[84, "nibabel.ecat.EcatHeader.template_dtype"]], "to_file_map() (nibabel.ecat.ecatimage method)": [[84, "nibabel.ecat.EcatImage.to_file_map"]], "valid_exts (nibabel.ecat.ecatimage attribute)": [[84, "nibabel.ecat.EcatImage.valid_exts"]], "get_home_dir() (in module nibabel.environment)": [[85, "nibabel.environment.get_home_dir"]], "get_nipy_system_dir() (in module nibabel.environment)": [[85, "nibabel.environment.get_nipy_system_dir"]], "get_nipy_user_dir() (in module nibabel.environment)": [[85, "nibabel.environment.get_nipy_user_dir"]], "nibabel.environment": [[85, "module-nibabel.environment"]], "angle_axis2euler() (in module nibabel.eulerangles)": [[86, "nibabel.eulerangles.angle_axis2euler"]], "euler2angle_axis() (in module nibabel.eulerangles)": [[86, "nibabel.eulerangles.euler2angle_axis"]], "euler2mat() (in module nibabel.eulerangles)": [[86, "nibabel.eulerangles.euler2mat"]], "euler2quat() (in module nibabel.eulerangles)": [[86, "nibabel.eulerangles.euler2quat"]], "mat2euler() (in module nibabel.eulerangles)": [[86, "nibabel.eulerangles.mat2euler"]], "nibabel.eulerangles": [[86, "module-nibabel.eulerangles"]], "quat2euler() (in module nibabel.eulerangles)": [[86, "nibabel.eulerangles.quat2euler"]], "filebasedheader (class in nibabel.filebasedimages)": [[87, "nibabel.filebasedimages.FileBasedHeader"]], "filebasedimage (class in nibabel.filebasedimages)": [[87, "nibabel.filebasedimages.FileBasedImage"]], "imagefileerror (class in nibabel.filebasedimages)": [[87, "nibabel.filebasedimages.ImageFileError"]], "serializableimage (class in nibabel.filebasedimages)": [[87, "nibabel.filebasedimages.SerializableImage"]], "__init__() (nibabel.filebasedimages.filebasedheader method)": [[87, "nibabel.filebasedimages.FileBasedHeader.__init__"]], "__init__() (nibabel.filebasedimages.filebasedimage method)": [[87, "nibabel.filebasedimages.FileBasedImage.__init__"]], "__init__() (nibabel.filebasedimages.imagefileerror method)": [[87, "nibabel.filebasedimages.ImageFileError.__init__"]], "__init__() (nibabel.filebasedimages.serializableimage method)": [[87, "nibabel.filebasedimages.SerializableImage.__init__"]], "copy() (nibabel.filebasedimages.filebasedheader method)": [[87, "nibabel.filebasedimages.FileBasedHeader.copy"]], "files_types (nibabel.filebasedimages.filebasedimage attribute)": [[87, "nibabel.filebasedimages.FileBasedImage.files_types"]], "filespec_to_file_map() (nibabel.filebasedimages.filebasedimage class method)": [[87, "nibabel.filebasedimages.FileBasedImage.filespec_to_file_map"]], "from_bytes() (nibabel.filebasedimages.serializableimage class method)": [[87, "nibabel.filebasedimages.SerializableImage.from_bytes"]], "from_file_map() (nibabel.filebasedimages.filebasedimage class method)": [[87, "nibabel.filebasedimages.FileBasedImage.from_file_map"]], "from_filename() (nibabel.filebasedimages.filebasedimage class method)": [[87, "nibabel.filebasedimages.FileBasedImage.from_filename"]], "from_fileobj() (nibabel.filebasedimages.filebasedheader class method)": [[87, "nibabel.filebasedimages.FileBasedHeader.from_fileobj"]], "from_header() (nibabel.filebasedimages.filebasedheader class method)": [[87, "nibabel.filebasedimages.FileBasedHeader.from_header"]], "from_image() (nibabel.filebasedimages.filebasedimage class method)": [[87, "nibabel.filebasedimages.FileBasedImage.from_image"]], "from_stream() (nibabel.filebasedimages.serializableimage class method)": [[87, "nibabel.filebasedimages.SerializableImage.from_stream"]], "from_url() (nibabel.filebasedimages.serializableimage class method)": [[87, "nibabel.filebasedimages.SerializableImage.from_url"]], "get_filename() (nibabel.filebasedimages.filebasedimage method)": [[87, "nibabel.filebasedimages.FileBasedImage.get_filename"]], "header (nibabel.filebasedimages.filebasedimage property)": [[87, "nibabel.filebasedimages.FileBasedImage.header"]], "header_class (nibabel.filebasedimages.filebasedimage attribute)": [[87, "nibabel.filebasedimages.FileBasedImage.header_class"]], "instance_to_filename() (nibabel.filebasedimages.filebasedimage class method)": [[87, "nibabel.filebasedimages.FileBasedImage.instance_to_filename"]], "load() (nibabel.filebasedimages.filebasedimage class method)": [[87, "nibabel.filebasedimages.FileBasedImage.load"]], "make_file_map() (nibabel.filebasedimages.filebasedimage class method)": [[87, "nibabel.filebasedimages.FileBasedImage.make_file_map"]], "makeable (nibabel.filebasedimages.filebasedimage attribute)": [[87, "nibabel.filebasedimages.FileBasedImage.makeable"]], "nibabel.filebasedimages": [[87, "module-nibabel.filebasedimages"]], "path_maybe_image() (nibabel.filebasedimages.filebasedimage class method)": [[87, "nibabel.filebasedimages.FileBasedImage.path_maybe_image"]], "rw (nibabel.filebasedimages.filebasedimage attribute)": [[87, "nibabel.filebasedimages.FileBasedImage.rw"]], "set_filename() (nibabel.filebasedimages.filebasedimage method)": [[87, "nibabel.filebasedimages.FileBasedImage.set_filename"]], "to_bytes() (nibabel.filebasedimages.serializableimage method)": [[87, "nibabel.filebasedimages.SerializableImage.to_bytes"]], "to_file_map() (nibabel.filebasedimages.filebasedimage method)": [[87, "nibabel.filebasedimages.FileBasedImage.to_file_map"]], "to_filename() (nibabel.filebasedimages.filebasedimage method)": [[87, "nibabel.filebasedimages.FileBasedImage.to_filename"]], "to_stream() (nibabel.filebasedimages.serializableimage method)": [[87, "nibabel.filebasedimages.SerializableImage.to_stream"]], "valid_exts (nibabel.filebasedimages.filebasedimage attribute)": [[87, "nibabel.filebasedimages.FileBasedImage.valid_exts"]], "write_to() (nibabel.filebasedimages.filebasedheader method)": [[87, "nibabel.filebasedimages.FileBasedHeader.write_to"]], "fileholder (class in nibabel.fileholders)": [[88, "nibabel.fileholders.FileHolder"]], "fileholdererror (class in nibabel.fileholders)": [[88, "nibabel.fileholders.FileHolderError"]], "__init__() (nibabel.fileholders.fileholder method)": [[88, "nibabel.fileholders.FileHolder.__init__"]], "__init__() (nibabel.fileholders.fileholdererror method)": [[88, "nibabel.fileholders.FileHolderError.__init__"]], "copy_file_map() (in module nibabel.fileholders)": [[88, "nibabel.fileholders.copy_file_map"]], "file_like (nibabel.fileholders.fileholder property)": [[88, "nibabel.fileholders.FileHolder.file_like"]], "get_prepare_fileobj() (nibabel.fileholders.fileholder method)": [[88, "nibabel.fileholders.FileHolder.get_prepare_fileobj"]], "nibabel.fileholders": [[88, "module-nibabel.fileholders"]], "same_file_as() (nibabel.fileholders.fileholder method)": [[88, "nibabel.fileholders.FileHolder.same_file_as"]], "typesfilenameserror (class in nibabel.filename_parser)": [[89, "nibabel.filename_parser.TypesFilenamesError"]], "__init__() (nibabel.filename_parser.typesfilenameserror method)": [[89, "nibabel.filename_parser.TypesFilenamesError.__init__"]], "nibabel.filename_parser": [[89, "module-nibabel.filename_parser"]], "parse_filename() (in module nibabel.filename_parser)": [[89, "nibabel.filename_parser.parse_filename"]], "splitext_addext() (in module nibabel.filename_parser)": [[89, "nibabel.filename_parser.splitext_addext"]], "types_filenames() (in module nibabel.filename_parser)": [[89, "nibabel.filename_parser.types_filenames"]], "calc_slicedefs() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.calc_slicedefs"]], "canonical_slicers() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.canonical_slicers"]], "fileslice() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.fileslice"]], "fill_slicer() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.fill_slicer"]], "is_fancy() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.is_fancy"]], "nibabel.fileslice": [[90, "module-nibabel.fileslice"]], "optimize_read_slicers() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.optimize_read_slicers"]], "optimize_slicer() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.optimize_slicer"]], "predict_shape() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.predict_shape"]], "read_segments() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.read_segments"]], "slice2len() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.slice2len"]], "slice2outax() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.slice2outax"]], "slicers2segments() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.slicers2segments"]], "strided_scalar() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.strided_scalar"]], "threshold_heuristic() (in module nibabel.fileslice)": [[90, "nibabel.fileslice.threshold_heuristic"]], "nibabel.fileutils": [[91, "module-nibabel.fileutils"]], "read_zt_byte_strings() (in module nibabel.fileutils)": [[91, "nibabel.fileutils.read_zt_byte_strings"]], "imagearrayproxy (nibabel.freesurfer.mghformat.mghimage attribute)": [[92, "nibabel.freesurfer.mghformat.MGHImage.ImageArrayProxy"]], "mgherror (class in nibabel.freesurfer.mghformat)": [[92, "nibabel.freesurfer.mghformat.MGHError"]], "mghheader (class in nibabel.freesurfer.mghformat)": [[92, "nibabel.freesurfer.mghformat.MGHHeader"]], "mghimage (class in nibabel.freesurfer.mghformat)": [[92, "nibabel.freesurfer.mghformat.MGHImage"]], "__init__() (nibabel.freesurfer.mghformat.mgherror method)": [[92, "nibabel.freesurfer.mghformat.MGHError.__init__"]], "__init__() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.__init__"]], "__init__() (nibabel.freesurfer.mghformat.mghimage method)": [[92, "nibabel.freesurfer.mghformat.MGHImage.__init__"]], "as_byteswapped() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.as_byteswapped"]], "chk_version() (nibabel.freesurfer.mghformat.mghheader static method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.chk_version"]], "copy() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.copy"]], "data_from_fileobj() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.data_from_fileobj"]], "default_structarr() (nibabel.freesurfer.mghformat.mghheader class method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.default_structarr"]], "diagnose_binaryblock() (nibabel.freesurfer.mghformat.mghheader class method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.diagnose_binaryblock"]], "files_types (nibabel.freesurfer.mghformat.mghimage attribute)": [[92, "nibabel.freesurfer.mghformat.MGHImage.files_types"]], "filespec_to_file_map() (nibabel.freesurfer.mghformat.mghimage class method)": [[92, "nibabel.freesurfer.mghformat.MGHImage.filespec_to_file_map"]], "from_file_map() (nibabel.freesurfer.mghformat.mghimage class method)": [[92, "nibabel.freesurfer.mghformat.MGHImage.from_file_map"]], "from_fileobj() (nibabel.freesurfer.mghformat.mghheader class method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.from_fileobj"]], "from_header() (nibabel.freesurfer.mghformat.mghheader class method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.from_header"]], "get_affine() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_affine"]], "get_best_affine() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_best_affine"]], "get_data_bytespervox() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_data_bytespervox"]], "get_data_dtype() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_data_dtype"]], "get_data_offset() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_data_offset"]], "get_data_shape() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_data_shape"]], "get_data_size() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_data_size"]], "get_footer_offset() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_footer_offset"]], "get_ras2vox() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_ras2vox"]], "get_slope_inter() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_slope_inter"]], "get_vox2ras() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_vox2ras"]], "get_vox2ras_tkr() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_vox2ras_tkr"]], "get_zooms() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.get_zooms"]], "guessed_endian() (nibabel.freesurfer.mghformat.mghheader class method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.guessed_endian"]], "header_class (nibabel.freesurfer.mghformat.mghimage attribute)": [[92, "nibabel.freesurfer.mghformat.MGHImage.header_class"]], "makeable (nibabel.freesurfer.mghformat.mghimage attribute)": [[92, "nibabel.freesurfer.mghformat.MGHImage.makeable"]], "nibabel.freesurfer": [[92, "module-nibabel.freesurfer"]], "nibabel.freesurfer.io": [[92, "module-nibabel.freesurfer.io"]], "nibabel.freesurfer.mghformat": [[92, "module-nibabel.freesurfer.mghformat"]], "read_annot() (in module nibabel.freesurfer.io)": [[92, "nibabel.freesurfer.io.read_annot"]], "read_geometry() (in module nibabel.freesurfer.io)": [[92, "nibabel.freesurfer.io.read_geometry"]], "read_label() (in module nibabel.freesurfer.io)": [[92, "nibabel.freesurfer.io.read_label"]], "read_morph_data() (in module nibabel.freesurfer.io)": [[92, "nibabel.freesurfer.io.read_morph_data"]], "rw (nibabel.freesurfer.mghformat.mghimage attribute)": [[92, "nibabel.freesurfer.mghformat.MGHImage.rw"]], "set_data_dtype() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.set_data_dtype"]], "set_data_shape() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.set_data_shape"]], "set_zooms() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.set_zooms"]], "template_dtype (nibabel.freesurfer.mghformat.mghheader attribute)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.template_dtype"]], "to_file_map() (nibabel.freesurfer.mghformat.mghimage method)": [[92, "nibabel.freesurfer.mghformat.MGHImage.to_file_map"]], "valid_exts (nibabel.freesurfer.mghformat.mghimage attribute)": [[92, "nibabel.freesurfer.mghformat.MGHImage.valid_exts"]], "write_annot() (in module nibabel.freesurfer.io)": [[92, "nibabel.freesurfer.io.write_annot"]], "write_geometry() (in module nibabel.freesurfer.io)": [[92, "nibabel.freesurfer.io.write_geometry"]], "write_morph_data() (in module nibabel.freesurfer.io)": [[92, "nibabel.freesurfer.io.write_morph_data"]], "writeftr_to() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.writeftr_to"]], "writehdr_to() (nibabel.freesurfer.mghformat.mghheader method)": [[92, "nibabel.freesurfer.mghformat.MGHHeader.writehdr_to"]], "as_closest_canonical() (in module nibabel.funcs)": [[93, "nibabel.funcs.as_closest_canonical"]], "concat_images() (in module nibabel.funcs)": [[93, "nibabel.funcs.concat_images"]], "four_to_three() (in module nibabel.funcs)": [[93, "nibabel.funcs.four_to_three"]], "nibabel.funcs": [[93, "module-nibabel.funcs"]], "squeeze_image() (in module nibabel.funcs)": [[93, "nibabel.funcs.squeeze_image"]], "characterdatahandler() (nibabel.gifti.parse_gifti_fast.giftiimageparser method)": [[94, "nibabel.gifti.parse_gifti_fast.GiftiImageParser.CharacterDataHandler"]], "endelementhandler() (nibabel.gifti.parse_gifti_fast.giftiimageparser method)": [[94, "nibabel.gifti.parse_gifti_fast.GiftiImageParser.EndElementHandler"]], "gifticoordsystem (class in nibabel.gifti.gifti)": [[94, "nibabel.gifti.gifti.GiftiCoordSystem"]], "giftidataarray (class in nibabel.gifti.gifti)": [[94, "nibabel.gifti.gifti.GiftiDataArray"]], "giftiimage (class in nibabel.gifti.gifti)": [[94, "nibabel.gifti.gifti.GiftiImage"]], "giftiimageparser (class in nibabel.gifti.parse_gifti_fast)": [[94, "nibabel.gifti.parse_gifti_fast.GiftiImageParser"]], "giftilabel (class in nibabel.gifti.gifti)": [[94, "nibabel.gifti.gifti.GiftiLabel"]], "giftilabeltable (class in nibabel.gifti.gifti)": [[94, "nibabel.gifti.gifti.GiftiLabelTable"]], "giftimetadata (class in nibabel.gifti.gifti)": [[94, "nibabel.gifti.gifti.GiftiMetaData"]], "giftinvpairs (class in nibabel.gifti.gifti)": [[94, "nibabel.gifti.gifti.GiftiNVPairs"]], "giftiparseerror (class in nibabel.gifti.parse_gifti_fast)": [[94, "nibabel.gifti.parse_gifti_fast.GiftiParseError"]], "startelementhandler() (nibabel.gifti.parse_gifti_fast.giftiimageparser method)": [[94, "nibabel.gifti.parse_gifti_fast.GiftiImageParser.StartElementHandler"]], "__init__() (nibabel.gifti.gifti.gifticoordsystem method)": [[94, "nibabel.gifti.gifti.GiftiCoordSystem.__init__"]], "__init__() (nibabel.gifti.gifti.giftidataarray method)": [[94, "nibabel.gifti.gifti.GiftiDataArray.__init__"]], "__init__() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.__init__"]], "__init__() (nibabel.gifti.gifti.giftilabel method)": [[94, "nibabel.gifti.gifti.GiftiLabel.__init__"]], "__init__() (nibabel.gifti.gifti.giftilabeltable method)": [[94, "nibabel.gifti.gifti.GiftiLabelTable.__init__"]], "__init__() (nibabel.gifti.gifti.giftimetadata method)": [[94, "nibabel.gifti.gifti.GiftiMetaData.__init__"]], "__init__() (nibabel.gifti.gifti.giftinvpairs method)": [[94, "nibabel.gifti.gifti.GiftiNVPairs.__init__"]], "__init__() (nibabel.gifti.parse_gifti_fast.giftiimageparser method)": [[94, "nibabel.gifti.parse_gifti_fast.GiftiImageParser.__init__"]], "__init__() (nibabel.gifti.parse_gifti_fast.giftiparseerror method)": [[94, "nibabel.gifti.parse_gifti_fast.GiftiParseError.__init__"]], "add_gifti_data_array() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.add_gifti_data_array"]], "agg_data() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.agg_data"]], "data (nibabel.gifti.gifti.giftimetadata property)": [[94, "nibabel.gifti.gifti.GiftiMetaData.data"]], "files_types (nibabel.gifti.gifti.giftiimage attribute)": [[94, "nibabel.gifti.gifti.GiftiImage.files_types"]], "flush_chardata() (nibabel.gifti.parse_gifti_fast.giftiimageparser method)": [[94, "nibabel.gifti.parse_gifti_fast.GiftiImageParser.flush_chardata"]], "from_dict() (nibabel.gifti.gifti.giftimetadata class method)": [[94, "nibabel.gifti.gifti.GiftiMetaData.from_dict"]], "from_file_map() (nibabel.gifti.gifti.giftiimage class method)": [[94, "nibabel.gifti.gifti.GiftiImage.from_file_map"]], "from_filename() (nibabel.gifti.gifti.giftiimage class method)": [[94, "nibabel.gifti.gifti.GiftiImage.from_filename"]], "get_arrays_from_intent() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.get_arrays_from_intent"]], "get_labels_as_dict() (nibabel.gifti.gifti.giftilabeltable method)": [[94, "nibabel.gifti.gifti.GiftiLabelTable.get_labels_as_dict"]], "labeltable (nibabel.gifti.gifti.giftiimage property)": [[94, "nibabel.gifti.gifti.GiftiImage.labeltable"]], "meta (nibabel.gifti.gifti.giftiimage property)": [[94, "nibabel.gifti.gifti.GiftiImage.meta"]], "metadata (nibabel.gifti.gifti.giftidataarray property)": [[94, "nibabel.gifti.gifti.GiftiDataArray.metadata"]], "metadata (nibabel.gifti.gifti.giftimetadata property)": [[94, "nibabel.gifti.gifti.GiftiMetaData.metadata"]], "name (nibabel.gifti.gifti.giftinvpairs property)": [[94, "nibabel.gifti.gifti.GiftiNVPairs.name"]], "nibabel.gifti": [[94, "module-nibabel.gifti"]], "nibabel.gifti.gifti": [[94, "module-nibabel.gifti.gifti"]], "nibabel.gifti.parse_gifti_fast": [[94, "module-nibabel.gifti.parse_gifti_fast"]], "nibabel.gifti.util": [[94, "module-nibabel.gifti.util"]], "numda (nibabel.gifti.gifti.giftiimage property)": [[94, "nibabel.gifti.gifti.GiftiImage.numDA"]], "num_dim (nibabel.gifti.gifti.giftidataarray property)": [[94, "nibabel.gifti.gifti.GiftiDataArray.num_dim"]], "parser (nibabel.gifti.gifti.giftiimage attribute)": [[94, "nibabel.gifti.gifti.GiftiImage.parser"]], "pending_data (nibabel.gifti.parse_gifti_fast.giftiimageparser property)": [[94, "nibabel.gifti.parse_gifti_fast.GiftiImageParser.pending_data"]], "print_summary() (nibabel.gifti.gifti.gifticoordsystem method)": [[94, "nibabel.gifti.gifti.GiftiCoordSystem.print_summary"]], "print_summary() (nibabel.gifti.gifti.giftidataarray method)": [[94, "nibabel.gifti.gifti.GiftiDataArray.print_summary"]], "print_summary() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.print_summary"]], "print_summary() (nibabel.gifti.gifti.giftilabeltable method)": [[94, "nibabel.gifti.gifti.GiftiLabelTable.print_summary"]], "print_summary() (nibabel.gifti.gifti.giftimetadata method)": [[94, "nibabel.gifti.gifti.GiftiMetaData.print_summary"]], "read_data_block() (in module nibabel.gifti.parse_gifti_fast)": [[94, "nibabel.gifti.parse_gifti_fast.read_data_block"]], "remove_gifti_data_array() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.remove_gifti_data_array"]], "remove_gifti_data_array_by_intent() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.remove_gifti_data_array_by_intent"]], "rgba (nibabel.gifti.gifti.giftilabel property)": [[94, "nibabel.gifti.gifti.GiftiLabel.rgba"]], "to_bytes() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.to_bytes"]], "to_file_map() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.to_file_map"]], "to_xml() (nibabel.gifti.gifti.giftiimage method)": [[94, "nibabel.gifti.gifti.GiftiImage.to_xml"]], "valid_exts (nibabel.gifti.gifti.giftiimage attribute)": [[94, "nibabel.gifti.gifti.GiftiImage.valid_exts"]], "value (nibabel.gifti.gifti.giftinvpairs property)": [[94, "nibabel.gifti.gifti.GiftiNVPairs.value"]], "nibabel.imageclasses": [[95, "module-nibabel.imageclasses"]], "spatial_axes_first() (in module nibabel.imageclasses)": [[95, "nibabel.imageclasses.spatial_axes_first"]], "errorlevel (class in nibabel.imageglobals)": [[96, "nibabel.imageglobals.ErrorLevel"]], "loggingoutputsuppressor (class in nibabel.imageglobals)": [[96, "nibabel.imageglobals.LoggingOutputSuppressor"]], "__init__() (nibabel.imageglobals.errorlevel method)": [[96, "nibabel.imageglobals.ErrorLevel.__init__"]], "__init__() (nibabel.imageglobals.loggingoutputsuppressor method)": [[96, "nibabel.imageglobals.LoggingOutputSuppressor.__init__"]], "nibabel.imageglobals": [[96, "module-nibabel.imageglobals"]], "count_nonzero_voxels() (in module nibabel.imagestats)": [[97, "nibabel.imagestats.count_nonzero_voxels"]], "mask_volume() (in module nibabel.imagestats)": [[97, "nibabel.imagestats.mask_volume"]], "nibabel.imagestats": [[97, "module-nibabel.imagestats"]], "guessed_image_type() (in module nibabel.loadsave)": [[98, "nibabel.loadsave.guessed_image_type"]], "load() (in module nibabel.loadsave)": [[98, "nibabel.loadsave.load"]], "nibabel.loadsave": [[98, "module-nibabel.loadsave"]], "read_img_data() (in module nibabel.loadsave)": [[98, "nibabel.loadsave.read_img_data"]], "save() (in module nibabel.loadsave)": [[98, "nibabel.loadsave.save"]], "imagearrayproxy (nibabel.minc1.minc1image attribute)": [[99, "nibabel.minc1.Minc1Image.ImageArrayProxy"]], "minc1file (class in nibabel.minc1)": [[99, "nibabel.minc1.Minc1File"]], "minc1header (class in nibabel.minc1)": [[99, "nibabel.minc1.Minc1Header"]], "minc1image (class in nibabel.minc1)": [[99, "nibabel.minc1.Minc1Image"]], "mincerror (class in nibabel.minc1)": [[99, "nibabel.minc1.MincError"]], "mincheader (class in nibabel.minc1)": [[99, "nibabel.minc1.MincHeader"]], "mincimagearrayproxy (class in nibabel.minc1)": [[99, "nibabel.minc1.MincImageArrayProxy"]], "__init__() (nibabel.minc1.minc1file method)": [[99, "nibabel.minc1.Minc1File.__init__"]], "__init__() (nibabel.minc1.minc1header method)": [[99, "nibabel.minc1.Minc1Header.__init__"]], "__init__() (nibabel.minc1.minc1image method)": [[99, "nibabel.minc1.Minc1Image.__init__"]], "__init__() (nibabel.minc1.mincerror method)": [[99, "nibabel.minc1.MincError.__init__"]], "__init__() (nibabel.minc1.mincheader method)": [[99, "nibabel.minc1.MincHeader.__init__"]], "__init__() (nibabel.minc1.mincimagearrayproxy method)": [[99, "nibabel.minc1.MincImageArrayProxy.__init__"]], "data_from_fileobj() (nibabel.minc1.mincheader method)": [[99, "nibabel.minc1.MincHeader.data_from_fileobj"]], "data_layout (nibabel.minc1.mincheader attribute)": [[99, "nibabel.minc1.MincHeader.data_layout"]], "data_to_fileobj() (nibabel.minc1.mincheader method)": [[99, "nibabel.minc1.MincHeader.data_to_fileobj"]], "files_types (nibabel.minc1.minc1image attribute)": [[99, "nibabel.minc1.Minc1Image.files_types"]], "from_file_map() (nibabel.minc1.minc1image class method)": [[99, "nibabel.minc1.Minc1Image.from_file_map"]], "get_affine() (nibabel.minc1.minc1file method)": [[99, "nibabel.minc1.Minc1File.get_affine"]], "get_data_dtype() (nibabel.minc1.minc1file method)": [[99, "nibabel.minc1.Minc1File.get_data_dtype"]], "get_data_shape() (nibabel.minc1.minc1file method)": [[99, "nibabel.minc1.Minc1File.get_data_shape"]], "get_scaled_data() (nibabel.minc1.minc1file method)": [[99, "nibabel.minc1.Minc1File.get_scaled_data"]], "get_zooms() (nibabel.minc1.minc1file method)": [[99, "nibabel.minc1.Minc1File.get_zooms"]], "header_class (nibabel.minc1.minc1image attribute)": [[99, "nibabel.minc1.Minc1Image.header_class"]], "is_proxy (nibabel.minc1.mincimagearrayproxy property)": [[99, "nibabel.minc1.MincImageArrayProxy.is_proxy"]], "makeable (nibabel.minc1.minc1image attribute)": [[99, "nibabel.minc1.Minc1Image.makeable"]], "may_contain_header() (nibabel.minc1.minc1header class method)": [[99, "nibabel.minc1.Minc1Header.may_contain_header"]], "ndim (nibabel.minc1.mincimagearrayproxy property)": [[99, "nibabel.minc1.MincImageArrayProxy.ndim"]], "nibabel.minc1": [[99, "module-nibabel.minc1"]], "rw (nibabel.minc1.minc1image attribute)": [[99, "nibabel.minc1.Minc1Image.rw"]], "shape (nibabel.minc1.mincimagearrayproxy property)": [[99, "nibabel.minc1.MincImageArrayProxy.shape"]], "valid_exts (nibabel.minc1.minc1image attribute)": [[99, "nibabel.minc1.Minc1Image.valid_exts"]], "hdf5bunch (class in nibabel.minc2)": [[100, "nibabel.minc2.Hdf5Bunch"]], "minc2file (class in nibabel.minc2)": [[100, "nibabel.minc2.Minc2File"]], "minc2header (class in nibabel.minc2)": [[100, "nibabel.minc2.Minc2Header"]], "minc2image (class in nibabel.minc2)": [[100, "nibabel.minc2.Minc2Image"]], "__init__() (nibabel.minc2.hdf5bunch method)": [[100, "nibabel.minc2.Hdf5Bunch.__init__"]], "__init__() (nibabel.minc2.minc2file method)": [[100, "nibabel.minc2.Minc2File.__init__"]], "__init__() (nibabel.minc2.minc2header method)": [[100, "nibabel.minc2.Minc2Header.__init__"]], "__init__() (nibabel.minc2.minc2image method)": [[100, "nibabel.minc2.Minc2Image.__init__"]], "from_file_map() (nibabel.minc2.minc2image class method)": [[100, "nibabel.minc2.Minc2Image.from_file_map"]], "get_data_dtype() (nibabel.minc2.minc2file method)": [[100, "nibabel.minc2.Minc2File.get_data_dtype"]], "get_data_shape() (nibabel.minc2.minc2file method)": [[100, "nibabel.minc2.Minc2File.get_data_shape"]], "get_scaled_data() (nibabel.minc2.minc2file method)": [[100, "nibabel.minc2.Minc2File.get_scaled_data"]], "header_class (nibabel.minc2.minc2image attribute)": [[100, "nibabel.minc2.Minc2Image.header_class"]], "may_contain_header() (nibabel.minc2.minc2header class method)": [[100, "nibabel.minc2.Minc2Header.may_contain_header"]], "nibabel.minc2": [[100, "module-nibabel.minc2"]], "mrierror (class in nibabel.mriutils)": [[101, "nibabel.mriutils.MRIError"]], "__init__() (nibabel.mriutils.mrierror method)": [[101, "nibabel.mriutils.MRIError.__init__"]], "calculate_dwell_time() (in module nibabel.mriutils)": [[101, "nibabel.mriutils.calculate_dwell_time"]], "nibabel.mriutils": [[101, "module-nibabel.mriutils"]], "ascconvparseerror (class in nibabel.nicom.ascconv)": [[102, "nibabel.nicom.ascconv.AscconvParseError"]], "atom (class in nibabel.nicom.ascconv)": [[102, "nibabel.nicom.ascconv.Atom"]], "b2q() (in module nibabel.nicom.dwiparams)": [[102, "nibabel.nicom.dwiparams.B2q"]], "csaerror (class in nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.CSAError"]], "csareaderror (class in nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.CSAReadError"]], "dicomreaderror (class in nibabel.nicom.dicomreaders)": [[102, "nibabel.nicom.dicomreaders.DicomReadError"]], "mosaicwrapper (class in nibabel.nicom.dicomwrappers)": [[102, "nibabel.nicom.dicomwrappers.MosaicWrapper"]], "multiframewrapper (class in nibabel.nicom.dicomwrappers)": [[102, "nibabel.nicom.dicomwrappers.MultiframeWrapper"]], "novalue (class in nibabel.nicom.ascconv)": [[102, "nibabel.nicom.ascconv.NoValue"]], "siemenswrapper (class in nibabel.nicom.dicomwrappers)": [[102, "nibabel.nicom.dicomwrappers.SiemensWrapper"]], "unpacker (class in nibabel.nicom.structreader)": [[102, "nibabel.nicom.structreader.Unpacker"]], "wrapper (class in nibabel.nicom.dicomwrappers)": [[102, "nibabel.nicom.dicomwrappers.Wrapper"]], "wrappererror (class in nibabel.nicom.dicomwrappers)": [[102, "nibabel.nicom.dicomwrappers.WrapperError"]], "wrapperprecisionerror (class in nibabel.nicom.dicomwrappers)": [[102, "nibabel.nicom.dicomwrappers.WrapperPrecisionError"]], "__init__() (nibabel.nicom.ascconv.ascconvparseerror method)": [[102, "nibabel.nicom.ascconv.AscconvParseError.__init__"]], "__init__() (nibabel.nicom.ascconv.atom method)": [[102, "nibabel.nicom.ascconv.Atom.__init__"]], "__init__() (nibabel.nicom.ascconv.novalue method)": [[102, "nibabel.nicom.ascconv.NoValue.__init__"]], "__init__() (nibabel.nicom.csareader.csaerror method)": [[102, "nibabel.nicom.csareader.CSAError.__init__"]], "__init__() (nibabel.nicom.csareader.csareaderror method)": [[102, "nibabel.nicom.csareader.CSAReadError.__init__"]], "__init__() (nibabel.nicom.dicomreaders.dicomreaderror method)": [[102, "nibabel.nicom.dicomreaders.DicomReadError.__init__"]], "__init__() (nibabel.nicom.dicomwrappers.mosaicwrapper method)": [[102, "nibabel.nicom.dicomwrappers.MosaicWrapper.__init__"]], "__init__() (nibabel.nicom.dicomwrappers.multiframewrapper method)": [[102, "nibabel.nicom.dicomwrappers.MultiframeWrapper.__init__"]], "__init__() (nibabel.nicom.dicomwrappers.siemenswrapper method)": [[102, "nibabel.nicom.dicomwrappers.SiemensWrapper.__init__"]], "__init__() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.__init__"]], "__init__() (nibabel.nicom.dicomwrappers.wrappererror method)": [[102, "nibabel.nicom.dicomwrappers.WrapperError.__init__"]], "__init__() (nibabel.nicom.dicomwrappers.wrapperprecisionerror method)": [[102, "nibabel.nicom.dicomwrappers.WrapperPrecisionError.__init__"]], "__init__() (nibabel.nicom.structreader.unpacker method)": [[102, "nibabel.nicom.structreader.Unpacker.__init__"]], "affine (nibabel.nicom.dicomwrappers.wrapper property)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.affine"]], "assign2atoms() (in module nibabel.nicom.ascconv)": [[102, "nibabel.nicom.ascconv.assign2atoms"]], "b_matrix (nibabel.nicom.dicomwrappers.wrapper attribute)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.b_matrix"]], "b_matrix() (nibabel.nicom.dicomwrappers.siemenswrapper method)": [[102, "nibabel.nicom.dicomwrappers.SiemensWrapper.b_matrix"]], "b_value() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.b_value"]], "b_vector() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.b_vector"]], "find_private_section() (in module nibabel.nicom.utils)": [[102, "nibabel.nicom.utils.find_private_section"]], "get() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.get"]], "get_acq_mat_txt() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_acq_mat_txt"]], "get_b_matrix() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_b_matrix"]], "get_b_value() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_b_value"]], "get_csa_header() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_csa_header"]], "get_data() (nibabel.nicom.dicomwrappers.mosaicwrapper method)": [[102, "nibabel.nicom.dicomwrappers.MosaicWrapper.get_data"]], "get_data() (nibabel.nicom.dicomwrappers.multiframewrapper method)": [[102, "nibabel.nicom.dicomwrappers.MultiframeWrapper.get_data"]], "get_data() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.get_data"]], "get_g_vector() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_g_vector"]], "get_ice_dims() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_ice_dims"]], "get_n_mosaic() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_n_mosaic"]], "get_pixel_array() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.get_pixel_array"]], "get_scalar() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_scalar"]], "get_slice_normal() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_slice_normal"]], "get_vector() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.get_vector"]], "image_orient_patient() (nibabel.nicom.dicomwrappers.multiframewrapper method)": [[102, "nibabel.nicom.dicomwrappers.MultiframeWrapper.image_orient_patient"]], "image_orient_patient() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.image_orient_patient"]], "image_position() (nibabel.nicom.dicomwrappers.mosaicwrapper method)": [[102, "nibabel.nicom.dicomwrappers.MosaicWrapper.image_position"]], "image_position() (nibabel.nicom.dicomwrappers.multiframewrapper method)": [[102, "nibabel.nicom.dicomwrappers.MultiframeWrapper.image_position"]], "image_position() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.image_position"]], "image_shape() (nibabel.nicom.dicomwrappers.mosaicwrapper method)": [[102, "nibabel.nicom.dicomwrappers.MosaicWrapper.image_shape"]], "image_shape() (nibabel.nicom.dicomwrappers.multiframewrapper method)": [[102, "nibabel.nicom.dicomwrappers.MultiframeWrapper.image_shape"]], "image_shape() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.image_shape"]], "instance_number() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.instance_number"]], "is_csa (nibabel.nicom.dicomwrappers.siemenswrapper attribute)": [[102, "nibabel.nicom.dicomwrappers.SiemensWrapper.is_csa"]], "is_csa (nibabel.nicom.dicomwrappers.wrapper attribute)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.is_csa"]], "is_mosaic (nibabel.nicom.dicomwrappers.mosaicwrapper attribute)": [[102, "nibabel.nicom.dicomwrappers.MosaicWrapper.is_mosaic"]], "is_mosaic (nibabel.nicom.dicomwrappers.wrapper attribute)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.is_mosaic"]], "is_mosaic() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.is_mosaic"]], "is_multiframe (nibabel.nicom.dicomwrappers.multiframewrapper attribute)": [[102, "nibabel.nicom.dicomwrappers.MultiframeWrapper.is_multiframe"]], "is_multiframe (nibabel.nicom.dicomwrappers.wrapper attribute)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.is_multiframe"]], "is_same_series() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.is_same_series"]], "mosaic_to_nii() (in module nibabel.nicom.dicomreaders)": [[102, "nibabel.nicom.dicomreaders.mosaic_to_nii"]], "nearest_pos_semi_def() (in module nibabel.nicom.dwiparams)": [[102, "nibabel.nicom.dwiparams.nearest_pos_semi_def"]], "nibabel.nicom": [[102, "module-nibabel.nicom"]], "nibabel.nicom.ascconv": [[102, "module-nibabel.nicom.ascconv"]], "nibabel.nicom.csareader": [[102, "module-nibabel.nicom.csareader"]], "nibabel.nicom.dicomreaders": [[102, "module-nibabel.nicom.dicomreaders"]], "nibabel.nicom.dicomwrappers": [[102, "module-nibabel.nicom.dicomwrappers"]], "nibabel.nicom.dwiparams": [[102, "module-nibabel.nicom.dwiparams"]], "nibabel.nicom.structreader": [[102, "module-nibabel.nicom.structreader"]], "nibabel.nicom.utils": [[102, "module-nibabel.nicom.utils"]], "none_or_close() (in module nibabel.nicom.dicomwrappers)": [[102, "nibabel.nicom.dicomwrappers.none_or_close"]], "nt_str() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.nt_str"]], "obj_from_atoms() (in module nibabel.nicom.ascconv)": [[102, "nibabel.nicom.ascconv.obj_from_atoms"]], "parse_ascconv() (in module nibabel.nicom.ascconv)": [[102, "nibabel.nicom.ascconv.parse_ascconv"]], "q2bg() (in module nibabel.nicom.dwiparams)": [[102, "nibabel.nicom.dwiparams.q2bg"]], "q_vector (nibabel.nicom.dicomwrappers.wrapper attribute)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.q_vector"]], "q_vector() (nibabel.nicom.dicomwrappers.siemenswrapper method)": [[102, "nibabel.nicom.dicomwrappers.SiemensWrapper.q_vector"]], "read() (in module nibabel.nicom.csareader)": [[102, "nibabel.nicom.csareader.read"]], "read() (nibabel.nicom.structreader.unpacker method)": [[102, "nibabel.nicom.structreader.Unpacker.read"]], "read_mosaic_dir() (in module nibabel.nicom.dicomreaders)": [[102, "nibabel.nicom.dicomreaders.read_mosaic_dir"]], "read_mosaic_dwi_dir() (in module nibabel.nicom.dicomreaders)": [[102, "nibabel.nicom.dicomreaders.read_mosaic_dwi_dir"]], "rotation_matrix() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.rotation_matrix"]], "series_signature() (nibabel.nicom.dicomwrappers.multiframewrapper method)": [[102, "nibabel.nicom.dicomwrappers.MultiframeWrapper.series_signature"]], "series_signature() (nibabel.nicom.dicomwrappers.siemenswrapper method)": [[102, "nibabel.nicom.dicomwrappers.SiemensWrapper.series_signature"]], "series_signature() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.series_signature"]], "slice_indicator() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.slice_indicator"]], "slice_normal() (nibabel.nicom.dicomwrappers.siemenswrapper method)": [[102, "nibabel.nicom.dicomwrappers.SiemensWrapper.slice_normal"]], "slice_normal() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.slice_normal"]], "slices_to_series() (in module nibabel.nicom.dicomreaders)": [[102, "nibabel.nicom.dicomreaders.slices_to_series"]], "unpack() (nibabel.nicom.structreader.unpacker method)": [[102, "nibabel.nicom.structreader.Unpacker.unpack"]], "voxel_sizes() (nibabel.nicom.dicomwrappers.multiframewrapper method)": [[102, "nibabel.nicom.dicomwrappers.MultiframeWrapper.voxel_sizes"]], "voxel_sizes() (nibabel.nicom.dicomwrappers.wrapper method)": [[102, "nibabel.nicom.dicomwrappers.Wrapper.voxel_sizes"]], "wrapper_from_data() (in module nibabel.nicom.dicomwrappers)": [[102, "nibabel.nicom.dicomwrappers.wrapper_from_data"]], "wrapper_from_file() (in module nibabel.nicom.dicomwrappers)": [[102, "nibabel.nicom.dicomwrappers.wrapper_from_file"]], "nifti1dicomextension (class in nibabel.nifti1)": [[103, "nibabel.nifti1.Nifti1DicomExtension"]], "nifti1extension (class in nibabel.nifti1)": [[103, "nibabel.nifti1.Nifti1Extension"]], "nifti1extensions (class in nibabel.nifti1)": [[103, "nibabel.nifti1.Nifti1Extensions"]], "nifti1header (class in nibabel.nifti1)": [[103, "nibabel.nifti1.Nifti1Header"]], "nifti1image (class in nibabel.nifti1)": [[103, "nibabel.nifti1.Nifti1Image"]], "nifti1pair (class in nibabel.nifti1)": [[103, "nibabel.nifti1.Nifti1Pair"]], "nifti1pairheader (class in nibabel.nifti1)": [[103, "nibabel.nifti1.Nifti1PairHeader"]], "__init__() (nibabel.nifti1.nifti1dicomextension method)": [[103, "nibabel.nifti1.Nifti1DicomExtension.__init__"]], "__init__() (nibabel.nifti1.nifti1extension method)": [[103, "nibabel.nifti1.Nifti1Extension.__init__"]], "__init__() (nibabel.nifti1.nifti1extensions method)": [[103, "nibabel.nifti1.Nifti1Extensions.__init__"]], "__init__() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.__init__"]], "__init__() (nibabel.nifti1.nifti1image method)": [[103, "nibabel.nifti1.Nifti1Image.__init__"]], "__init__() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.__init__"]], "__init__() (nibabel.nifti1.nifti1pairheader method)": [[103, "nibabel.nifti1.Nifti1PairHeader.__init__"]], "as_reoriented() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.as_reoriented"]], "copy() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.copy"]], "count() (nibabel.nifti1.nifti1extensions method)": [[103, "nibabel.nifti1.Nifti1Extensions.count"]], "default_structarr() (nibabel.nifti1.nifti1header class method)": [[103, "nibabel.nifti1.Nifti1Header.default_structarr"]], "exts_klass (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.exts_klass"]], "files_types (nibabel.nifti1.nifti1image attribute)": [[103, "nibabel.nifti1.Nifti1Image.files_types"]], "from_fileobj() (nibabel.nifti1.nifti1extensions class method)": [[103, "nibabel.nifti1.Nifti1Extensions.from_fileobj"]], "from_fileobj() (nibabel.nifti1.nifti1header class method)": [[103, "nibabel.nifti1.Nifti1Header.from_fileobj"]], "from_header() (nibabel.nifti1.nifti1header class method)": [[103, "nibabel.nifti1.Nifti1Header.from_header"]], "get_best_affine() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_best_affine"]], "get_code() (nibabel.nifti1.nifti1extension method)": [[103, "nibabel.nifti1.Nifti1Extension.get_code"]], "get_codes() (nibabel.nifti1.nifti1extensions method)": [[103, "nibabel.nifti1.Nifti1Extensions.get_codes"]], "get_content() (nibabel.nifti1.nifti1extension method)": [[103, "nibabel.nifti1.Nifti1Extension.get_content"]], "get_data_dtype() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.get_data_dtype"]], "get_data_shape() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_data_shape"]], "get_dim_info() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_dim_info"]], "get_intent() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_intent"]], "get_n_slices() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_n_slices"]], "get_qform() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_qform"]], "get_qform() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.get_qform"]], "get_qform_quaternion() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_qform_quaternion"]], "get_sform() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_sform"]], "get_sform() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.get_sform"]], "get_sizeondisk() (nibabel.nifti1.nifti1extension method)": [[103, "nibabel.nifti1.Nifti1Extension.get_sizeondisk"]], "get_sizeondisk() (nibabel.nifti1.nifti1extensions method)": [[103, "nibabel.nifti1.Nifti1Extensions.get_sizeondisk"]], "get_slice_duration() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_slice_duration"]], "get_slice_times() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_slice_times"]], "get_slope_inter() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_slope_inter"]], "get_xyzt_units() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.get_xyzt_units"]], "has_data_intercept (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.has_data_intercept"]], "has_data_slope (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.has_data_slope"]], "header_class (nibabel.nifti1.nifti1image attribute)": [[103, "nibabel.nifti1.Nifti1Image.header_class"]], "header_class (nibabel.nifti1.nifti1pair attribute)": [[103, "nibabel.nifti1.Nifti1Pair.header_class"]], "is_single (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.is_single"]], "is_single (nibabel.nifti1.nifti1pairheader attribute)": [[103, "nibabel.nifti1.Nifti1PairHeader.is_single"]], "load() (in module nibabel.nifti1)": [[103, "nibabel.nifti1.load"]], "may_contain_header() (nibabel.nifti1.nifti1header class method)": [[103, "nibabel.nifti1.Nifti1Header.may_contain_header"]], "nibabel.nifti1": [[103, "module-nibabel.nifti1"]], "pair_magic (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.pair_magic"]], "pair_vox_offset (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.pair_vox_offset"]], "quaternion_threshold (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.quaternion_threshold"]], "rw (nibabel.nifti1.nifti1pair attribute)": [[103, "nibabel.nifti1.Nifti1Pair.rw"]], "save() (in module nibabel.nifti1)": [[103, "nibabel.nifti1.save"]], "set_data_dtype() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_data_dtype"]], "set_data_dtype() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.set_data_dtype"]], "set_data_shape() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_data_shape"]], "set_dim_info() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_dim_info"]], "set_intent() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_intent"]], "set_qform() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_qform"]], "set_qform() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.set_qform"]], "set_sform() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_sform"]], "set_sform() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.set_sform"]], "set_slice_duration() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_slice_duration"]], "set_slice_times() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_slice_times"]], "set_slope_inter() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_slope_inter"]], "set_xyzt_units() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.set_xyzt_units"]], "single_magic (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.single_magic"]], "single_vox_offset (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.single_vox_offset"]], "template_dtype (nibabel.nifti1.nifti1header attribute)": [[103, "nibabel.nifti1.Nifti1Header.template_dtype"]], "to_file_map() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.to_file_map"]], "update_header() (nibabel.nifti1.nifti1image method)": [[103, "nibabel.nifti1.Nifti1Image.update_header"]], "update_header() (nibabel.nifti1.nifti1pair method)": [[103, "nibabel.nifti1.Nifti1Pair.update_header"]], "valid_exts (nibabel.nifti1.nifti1image attribute)": [[103, "nibabel.nifti1.Nifti1Image.valid_exts"]], "write_to() (nibabel.nifti1.nifti1extension method)": [[103, "nibabel.nifti1.Nifti1Extension.write_to"]], "write_to() (nibabel.nifti1.nifti1extensions method)": [[103, "nibabel.nifti1.Nifti1Extensions.write_to"]], "write_to() (nibabel.nifti1.nifti1header method)": [[103, "nibabel.nifti1.Nifti1Header.write_to"]], "nifti2header (class in nibabel.nifti2)": [[104, "nibabel.nifti2.Nifti2Header"]], "nifti2image (class in nibabel.nifti2)": [[104, "nibabel.nifti2.Nifti2Image"]], "nifti2pair (class in nibabel.nifti2)": [[104, "nibabel.nifti2.Nifti2Pair"]], "nifti2pairheader (class in nibabel.nifti2)": [[104, "nibabel.nifti2.Nifti2PairHeader"]], "__init__() (nibabel.nifti2.nifti2header method)": [[104, "nibabel.nifti2.Nifti2Header.__init__"]], "__init__() (nibabel.nifti2.nifti2image method)": [[104, "nibabel.nifti2.Nifti2Image.__init__"]], "__init__() (nibabel.nifti2.nifti2pair method)": [[104, "nibabel.nifti2.Nifti2Pair.__init__"]], "__init__() (nibabel.nifti2.nifti2pairheader method)": [[104, "nibabel.nifti2.Nifti2PairHeader.__init__"]], "default_structarr() (nibabel.nifti2.nifti2header class method)": [[104, "nibabel.nifti2.Nifti2Header.default_structarr"]], "get_data_shape() (nibabel.nifti2.nifti2header method)": [[104, "nibabel.nifti2.Nifti2Header.get_data_shape"]], "header_class (nibabel.nifti2.nifti2image attribute)": [[104, "nibabel.nifti2.Nifti2Image.header_class"]], "header_class (nibabel.nifti2.nifti2pair attribute)": [[104, "nibabel.nifti2.Nifti2Pair.header_class"]], "is_single (nibabel.nifti2.nifti2pairheader attribute)": [[104, "nibabel.nifti2.Nifti2PairHeader.is_single"]], "load() (in module nibabel.nifti2)": [[104, "nibabel.nifti2.load"]], "may_contain_header() (nibabel.nifti2.nifti2header class method)": [[104, "nibabel.nifti2.Nifti2Header.may_contain_header"]], "nibabel.nifti2": [[104, "module-nibabel.nifti2"]], "pair_magic (nibabel.nifti2.nifti2header attribute)": [[104, "nibabel.nifti2.Nifti2Header.pair_magic"]], "pair_vox_offset (nibabel.nifti2.nifti2header attribute)": [[104, "nibabel.nifti2.Nifti2Header.pair_vox_offset"]], "quaternion_threshold (nibabel.nifti2.nifti2header attribute)": [[104, "nibabel.nifti2.Nifti2Header.quaternion_threshold"]], "save() (in module nibabel.nifti2)": [[104, "nibabel.nifti2.save"]], "set_data_shape() (nibabel.nifti2.nifti2header method)": [[104, "nibabel.nifti2.Nifti2Header.set_data_shape"]], "single_magic (nibabel.nifti2.nifti2header attribute)": [[104, "nibabel.nifti2.Nifti2Header.single_magic"]], "single_vox_offset (nibabel.nifti2.nifti2header attribute)": [[104, "nibabel.nifti2.Nifti2Header.single_vox_offset"]], "sizeof_hdr (nibabel.nifti2.nifti2header attribute)": [[104, "nibabel.nifti2.Nifti2Header.sizeof_hdr"]], "template_dtype (nibabel.nifti2.nifti2header attribute)": [[104, "nibabel.nifti2.Nifti2Header.template_dtype"]], "onetimeproperty (class in nibabel.onetime)": [[105, "nibabel.onetime.OneTimeProperty"]], "resetmixin (class in nibabel.onetime)": [[105, "nibabel.onetime.ResetMixin"]], "__init__() (nibabel.onetime.onetimeproperty method)": [[105, "nibabel.onetime.OneTimeProperty.__init__"]], "__init__() (nibabel.onetime.resetmixin method)": [[105, "nibabel.onetime.ResetMixin.__init__"]], "auto_attr() (in module nibabel.onetime)": [[105, "nibabel.onetime.auto_attr"]], "nibabel.onetime": [[105, "module-nibabel.onetime"]], "reset() (nibabel.onetime.resetmixin method)": [[105, "nibabel.onetime.ResetMixin.reset"]], "setattr_on_read() (in module nibabel.onetime)": [[105, "nibabel.onetime.setattr_on_read"]], "deterministicgzipfile (class in nibabel.openers)": [[106, "nibabel.openers.DeterministicGzipFile"]], "fileish (class in nibabel.openers)": [[106, "nibabel.openers.Fileish"]], "imageopener (class in nibabel.openers)": [[106, "nibabel.openers.ImageOpener"]], "opener (class in nibabel.openers)": [[106, "nibabel.openers.Opener"]], "__init__() (nibabel.openers.deterministicgzipfile method)": [[106, "nibabel.openers.DeterministicGzipFile.__init__"]], "__init__() (nibabel.openers.fileish method)": [[106, "nibabel.openers.Fileish.__init__"]], "__init__() (nibabel.openers.imageopener method)": [[106, "nibabel.openers.ImageOpener.__init__"]], "__init__() (nibabel.openers.opener method)": [[106, "nibabel.openers.Opener.__init__"]], "bz2_def (nibabel.openers.opener attribute)": [[106, "nibabel.openers.Opener.bz2_def"]], "close() (nibabel.openers.opener method)": [[106, "nibabel.openers.Opener.close"]], "close_if_mine() (nibabel.openers.opener method)": [[106, "nibabel.openers.Opener.close_if_mine"]], "closed (nibabel.openers.opener property)": [[106, "nibabel.openers.Opener.closed"]], "compress_ext_icase (nibabel.openers.opener attribute)": [[106, "nibabel.openers.Opener.compress_ext_icase"]], "compress_ext_map (nibabel.openers.imageopener attribute)": [[106, "nibabel.openers.ImageOpener.compress_ext_map"]], "compress_ext_map (nibabel.openers.opener attribute)": [[106, "nibabel.openers.Opener.compress_ext_map"]], "default_compresslevel (nibabel.openers.opener attribute)": [[106, "nibabel.openers.Opener.default_compresslevel"]], "default_level_or_option (nibabel.openers.opener attribute)": [[106, "nibabel.openers.Opener.default_level_or_option"]], "default_zst_compresslevel (nibabel.openers.opener attribute)": [[106, "nibabel.openers.Opener.default_zst_compresslevel"]], "fileno() (nibabel.openers.opener method)": [[106, "nibabel.openers.Opener.fileno"]], "fobj (nibabel.openers.opener attribute)": [[106, "nibabel.openers.Opener.fobj"]], "gz_def (nibabel.openers.opener attribute)": [[106, "nibabel.openers.Opener.gz_def"]], "mode (nibabel.openers.opener property)": [[106, "nibabel.openers.Opener.mode"]], "name (nibabel.openers.opener property)": [[106, "nibabel.openers.Opener.name"]], "nibabel.openers": [[106, "module-nibabel.openers"]], "read() (nibabel.openers.fileish method)": [[106, "nibabel.openers.Fileish.read"]], "read() (nibabel.openers.opener method)": [[106, "nibabel.openers.Opener.read"]], "readinto() (nibabel.openers.opener method)": [[106, "nibabel.openers.Opener.readinto"]], "seek() (nibabel.openers.opener method)": [[106, "nibabel.openers.Opener.seek"]], "tell() (nibabel.openers.opener method)": [[106, "nibabel.openers.Opener.tell"]], "write() (nibabel.openers.fileish method)": [[106, "nibabel.openers.Fileish.write"]], "write() (nibabel.openers.opener method)": [[106, "nibabel.openers.Opener.write"]], "zstd_def (nibabel.openers.opener attribute)": [[106, "nibabel.openers.Opener.zstd_def"]], "nibabel.optpkg": [[107, "module-nibabel.optpkg"]], "optional_package() (in module nibabel.optpkg)": [[107, "nibabel.optpkg.optional_package"]], "orientationerror (class in nibabel.orientations)": [[108, "nibabel.orientations.OrientationError"]], "__init__() (nibabel.orientations.orientationerror method)": [[108, "nibabel.orientations.OrientationError.__init__"]], "aff2axcodes() (in module nibabel.orientations)": [[108, "nibabel.orientations.aff2axcodes"]], "apply_orientation() (in module nibabel.orientations)": [[108, "nibabel.orientations.apply_orientation"]], "axcodes2ornt() (in module nibabel.orientations)": [[108, "nibabel.orientations.axcodes2ornt"]], "flip_axis() (in module nibabel.orientations)": [[108, "nibabel.orientations.flip_axis"]], "inv_ornt_aff() (in module nibabel.orientations)": [[108, "nibabel.orientations.inv_ornt_aff"]], "io_orientation() (in module nibabel.orientations)": [[108, "nibabel.orientations.io_orientation"]], "nibabel.orientations": [[108, "module-nibabel.orientations"]], "ornt2axcodes() (in module nibabel.orientations)": [[108, "nibabel.orientations.ornt2axcodes"]], "ornt_transform() (in module nibabel.orientations)": [[108, "nibabel.orientations.ornt_transform"]], "imagearrayproxy (nibabel.parrec.parrecimage attribute)": [[109, "nibabel.parrec.PARRECImage.ImageArrayProxy"]], "parrecarrayproxy (class in nibabel.parrec)": [[109, "nibabel.parrec.PARRECArrayProxy"]], "parrecerror (class in nibabel.parrec)": [[109, "nibabel.parrec.PARRECError"]], "parrecheader (class in nibabel.parrec)": [[109, "nibabel.parrec.PARRECHeader"]], "parrecimage (class in nibabel.parrec)": [[109, "nibabel.parrec.PARRECImage"]], "__init__() (nibabel.parrec.parrecarrayproxy method)": [[109, "nibabel.parrec.PARRECArrayProxy.__init__"]], "__init__() (nibabel.parrec.parrecerror method)": [[109, "nibabel.parrec.PARRECError.__init__"]], "__init__() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.__init__"]], "__init__() (nibabel.parrec.parrecimage method)": [[109, "nibabel.parrec.PARRECImage.__init__"]], "as_analyze_map() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.as_analyze_map"]], "copy() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.copy"]], "dtype (nibabel.parrec.parrecarrayproxy property)": [[109, "nibabel.parrec.PARRECArrayProxy.dtype"]], "exts2pars() (in module nibabel.parrec)": [[109, "nibabel.parrec.exts2pars"]], "files_types (nibabel.parrec.parrecimage attribute)": [[109, "nibabel.parrec.PARRECImage.files_types"]], "from_file_map() (nibabel.parrec.parrecimage class method)": [[109, "nibabel.parrec.PARRECImage.from_file_map"]], "from_filename() (nibabel.parrec.parrecimage class method)": [[109, "nibabel.parrec.PARRECImage.from_filename"]], "from_fileobj() (nibabel.parrec.parrecheader class method)": [[109, "nibabel.parrec.PARRECHeader.from_fileobj"]], "from_header() (nibabel.parrec.parrecheader class method)": [[109, "nibabel.parrec.PARRECHeader.from_header"]], "get_affine() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_affine"]], "get_bvals_bvecs() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_bvals_bvecs"]], "get_data_offset() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_data_offset"]], "get_data_scaling() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_data_scaling"]], "get_def() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_def"]], "get_echo_train_length() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_echo_train_length"]], "get_q_vectors() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_q_vectors"]], "get_rec_shape() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_rec_shape"]], "get_slice_orientation() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_slice_orientation"]], "get_sorted_slice_indices() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_sorted_slice_indices"]], "get_unscaled() (nibabel.parrec.parrecarrayproxy method)": [[109, "nibabel.parrec.PARRECArrayProxy.get_unscaled"]], "get_volume_labels() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_volume_labels"]], "get_water_fat_shift() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.get_water_fat_shift"]], "header_class (nibabel.parrec.parrecimage attribute)": [[109, "nibabel.parrec.PARRECImage.header_class"]], "is_proxy (nibabel.parrec.parrecarrayproxy property)": [[109, "nibabel.parrec.PARRECArrayProxy.is_proxy"]], "load() (nibabel.parrec.parrecimage class method)": [[109, "nibabel.parrec.PARRECImage.load"]], "makeable (nibabel.parrec.parrecimage attribute)": [[109, "nibabel.parrec.PARRECImage.makeable"]], "ndim (nibabel.parrec.parrecarrayproxy property)": [[109, "nibabel.parrec.PARRECArrayProxy.ndim"]], "nibabel.parrec": [[109, "module-nibabel.parrec"]], "one_line() (in module nibabel.parrec)": [[109, "nibabel.parrec.one_line"]], "parse_par_header() (in module nibabel.parrec)": [[109, "nibabel.parrec.parse_PAR_header"]], "rw (nibabel.parrec.parrecimage attribute)": [[109, "nibabel.parrec.PARRECImage.rw"]], "set_data_offset() (nibabel.parrec.parrecheader method)": [[109, "nibabel.parrec.PARRECHeader.set_data_offset"]], "shape (nibabel.parrec.parrecarrayproxy property)": [[109, "nibabel.parrec.PARRECArrayProxy.shape"]], "valid_exts (nibabel.parrec.parrecimage attribute)": [[109, "nibabel.parrec.PARRECImage.valid_exts"]], "vol_is_full() (in module nibabel.parrec)": [[109, "nibabel.parrec.vol_is_full"]], "vol_numbers() (in module nibabel.parrec)": [[109, "nibabel.parrec.vol_numbers"]], "coordinatearray (class in nibabel.pointset)": [[110, "nibabel.pointset.CoordinateArray"]], "grid (class in nibabel.pointset)": [[110, "nibabel.pointset.Grid"]], "gridindices (class in nibabel.pointset)": [[110, "nibabel.pointset.GridIndices"]], "pointset (class in nibabel.pointset)": [[110, "nibabel.pointset.Pointset"]], "__init__() (nibabel.pointset.coordinatearray method)": [[110, "nibabel.pointset.CoordinateArray.__init__"]], "__init__() (nibabel.pointset.grid method)": [[110, "nibabel.pointset.Grid.__init__"]], "__init__() (nibabel.pointset.gridindices method)": [[110, "nibabel.pointset.GridIndices.__init__"]], "__init__() (nibabel.pointset.pointset method)": [[110, "nibabel.pointset.Pointset.__init__"]], "affine (nibabel.pointset.pointset attribute)": [[110, "nibabel.pointset.Pointset.affine"]], "coordinates (nibabel.pointset.pointset attribute)": [[110, "nibabel.pointset.Pointset.coordinates"]], "dim (nibabel.pointset.pointset property)": [[110, "nibabel.pointset.Pointset.dim"]], "dtype (nibabel.pointset.gridindices attribute)": [[110, "nibabel.pointset.GridIndices.dtype"]], "from_image() (nibabel.pointset.grid class method)": [[110, "nibabel.pointset.Grid.from_image"]], "from_mask() (nibabel.pointset.grid class method)": [[110, "nibabel.pointset.Grid.from_mask"]], "get_coords() (nibabel.pointset.pointset method)": [[110, "nibabel.pointset.Pointset.get_coords"]], "gridshape (nibabel.pointset.gridindices attribute)": [[110, "nibabel.pointset.GridIndices.gridshape"]], "homogeneous (nibabel.pointset.pointset attribute)": [[110, "nibabel.pointset.Pointset.homogeneous"]], "n_coords (nibabel.pointset.pointset property)": [[110, "nibabel.pointset.Pointset.n_coords"]], "ndim (nibabel.pointset.coordinatearray attribute)": [[110, "nibabel.pointset.CoordinateArray.ndim"]], "ndim (nibabel.pointset.gridindices attribute)": [[110, "nibabel.pointset.GridIndices.ndim"]], "nibabel.pointset": [[110, "module-nibabel.pointset"]], "shape (nibabel.pointset.coordinatearray attribute)": [[110, "nibabel.pointset.CoordinateArray.shape"]], "shape (nibabel.pointset.gridindices attribute)": [[110, "nibabel.pointset.GridIndices.shape"]], "to_mask() (nibabel.pointset.grid method)": [[110, "nibabel.pointset.Grid.to_mask"]], "adapt_affine() (in module nibabel.processing)": [[111, "nibabel.processing.adapt_affine"]], "conform() (in module nibabel.processing)": [[111, "nibabel.processing.conform"]], "fwhm2sigma() (in module nibabel.processing)": [[111, "nibabel.processing.fwhm2sigma"]], "nibabel.processing": [[111, "module-nibabel.processing"]], "resample_from_to() (in module nibabel.processing)": [[111, "nibabel.processing.resample_from_to"]], "resample_to_output() (in module nibabel.processing)": [[111, "nibabel.processing.resample_to_output"]], "sigma2fwhm() (in module nibabel.processing)": [[111, "nibabel.processing.sigma2fwhm"]], "smooth_image() (in module nibabel.processing)": [[111, "nibabel.processing.smooth_image"]], "dicom_test() (in module nibabel.pydicom_compat)": [[112, "nibabel.pydicom_compat.dicom_test"]], "nibabel.pydicom_compat": [[112, "module-nibabel.pydicom_compat"]], "angle_axis2mat() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.angle_axis2mat"]], "angle_axis2quat() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.angle_axis2quat"]], "conjugate() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.conjugate"]], "eye() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.eye"]], "fillpositive() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.fillpositive"]], "inverse() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.inverse"]], "isunit() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.isunit"]], "mat2quat() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.mat2quat"]], "mult() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.mult"]], "nearly_equivalent() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.nearly_equivalent"]], "nibabel.quaternions": [[113, "module-nibabel.quaternions"]], "norm() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.norm"]], "quat2angle_axis() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.quat2angle_axis"]], "quat2mat() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.quat2mat"]], "rotate_vector() (in module nibabel.quaternions)": [[113, "nibabel.quaternions.rotate_vector"]], "nibabel.rstutils": [[114, "module-nibabel.rstutils"]], "rst_table() (in module nibabel.rstutils)": [[114, "nibabel.rstutils.rst_table"]], "nibabel.spaces": [[115, "module-nibabel.spaces"]], "slice2volume() (in module nibabel.spaces)": [[115, "nibabel.spaces.slice2volume"]], "vox2out_vox() (in module nibabel.spaces)": [[115, "nibabel.spaces.vox2out_vox"]], "hasdtype (class in nibabel.spatialimages)": [[116, "nibabel.spatialimages.HasDtype"]], "headerdataerror (class in nibabel.spatialimages)": [[116, "nibabel.spatialimages.HeaderDataError"]], "headertypeerror (class in nibabel.spatialimages)": [[116, "nibabel.spatialimages.HeaderTypeError"]], "imagedataerror (class in nibabel.spatialimages)": [[116, "nibabel.spatialimages.ImageDataError"]], "imageslicer (nibabel.spatialimages.spatialimage attribute)": [[116, "nibabel.spatialimages.SpatialImage.ImageSlicer"]], "spatialfirstslicer (class in nibabel.spatialimages)": [[116, "nibabel.spatialimages.SpatialFirstSlicer"]], "spatialheader (class in nibabel.spatialimages)": [[116, "nibabel.spatialimages.SpatialHeader"]], "spatialimage (class in nibabel.spatialimages)": [[116, "nibabel.spatialimages.SpatialImage"]], "spatialprotocol (class in nibabel.spatialimages)": [[116, "nibabel.spatialimages.SpatialProtocol"]], "__init__() (nibabel.spatialimages.hasdtype method)": [[116, "nibabel.spatialimages.HasDtype.__init__"]], "__init__() (nibabel.spatialimages.headerdataerror method)": [[116, "nibabel.spatialimages.HeaderDataError.__init__"]], "__init__() (nibabel.spatialimages.headertypeerror method)": [[116, "nibabel.spatialimages.HeaderTypeError.__init__"]], "__init__() (nibabel.spatialimages.imagedataerror method)": [[116, "nibabel.spatialimages.ImageDataError.__init__"]], "__init__() (nibabel.spatialimages.spatialfirstslicer method)": [[116, "nibabel.spatialimages.SpatialFirstSlicer.__init__"]], "__init__() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.__init__"]], "__init__() (nibabel.spatialimages.spatialimage method)": [[116, "nibabel.spatialimages.SpatialImage.__init__"]], "__init__() (nibabel.spatialimages.spatialprotocol method)": [[116, "nibabel.spatialimages.SpatialProtocol.__init__"]], "affine (nibabel.spatialimages.spatialimage property)": [[116, "nibabel.spatialimages.SpatialImage.affine"]], "as_reoriented() (nibabel.spatialimages.spatialimage method)": [[116, "nibabel.spatialimages.SpatialImage.as_reoriented"]], "check_slicing() (nibabel.spatialimages.spatialfirstslicer method)": [[116, "nibabel.spatialimages.SpatialFirstSlicer.check_slicing"]], "copy() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.copy"]], "data_from_fileobj() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.data_from_fileobj"]], "data_layout (nibabel.spatialimages.spatialheader attribute)": [[116, "nibabel.spatialimages.SpatialHeader.data_layout"]], "data_to_fileobj() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.data_to_fileobj"]], "default_x_flip (nibabel.spatialimages.spatialheader attribute)": [[116, "nibabel.spatialimages.SpatialHeader.default_x_flip"]], "from_header() (nibabel.spatialimages.spatialheader class method)": [[116, "nibabel.spatialimages.SpatialHeader.from_header"]], "from_image() (nibabel.spatialimages.spatialimage class method)": [[116, "nibabel.spatialimages.SpatialImage.from_image"]], "get_base_affine() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.get_base_affine"]], "get_best_affine() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.get_best_affine"]], "get_data_dtype() (nibabel.spatialimages.hasdtype method)": [[116, "nibabel.spatialimages.HasDtype.get_data_dtype"]], "get_data_dtype() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.get_data_dtype"]], "get_data_dtype() (nibabel.spatialimages.spatialimage method)": [[116, "nibabel.spatialimages.SpatialImage.get_data_dtype"]], "get_data_dtype() (nibabel.spatialimages.spatialprotocol method)": [[116, "nibabel.spatialimages.SpatialProtocol.get_data_dtype"]], "get_data_shape() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.get_data_shape"]], "get_data_shape() (nibabel.spatialimages.spatialprotocol method)": [[116, "nibabel.spatialimages.SpatialProtocol.get_data_shape"]], "get_zooms() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.get_zooms"]], "get_zooms() (nibabel.spatialimages.spatialprotocol method)": [[116, "nibabel.spatialimages.SpatialProtocol.get_zooms"]], "header_class (nibabel.spatialimages.spatialimage attribute)": [[116, "nibabel.spatialimages.SpatialImage.header_class"]], "img (nibabel.spatialimages.spatialfirstslicer attribute)": [[116, "nibabel.spatialimages.SpatialFirstSlicer.img"]], "nibabel.spatialimages": [[116, "module-nibabel.spatialimages"]], "orthoview() (nibabel.spatialimages.spatialimage method)": [[116, "nibabel.spatialimages.SpatialImage.orthoview"]], "set_data_dtype() (nibabel.spatialimages.hasdtype method)": [[116, "nibabel.spatialimages.HasDtype.set_data_dtype"]], "set_data_dtype() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.set_data_dtype"]], "set_data_dtype() (nibabel.spatialimages.spatialimage method)": [[116, "nibabel.spatialimages.SpatialImage.set_data_dtype"]], "set_data_shape() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.set_data_shape"]], "set_zooms() (nibabel.spatialimages.spatialheader method)": [[116, "nibabel.spatialimages.SpatialHeader.set_zooms"]], "slice_affine() (nibabel.spatialimages.spatialfirstslicer method)": [[116, "nibabel.spatialimages.SpatialFirstSlicer.slice_affine"]], "slicer (nibabel.spatialimages.spatialimage property)": [[116, "nibabel.spatialimages.SpatialImage.slicer"]], "supported_np_types() (in module nibabel.spatialimages)": [[116, "nibabel.spatialimages.supported_np_types"]], "update_header() (nibabel.spatialimages.spatialimage method)": [[116, "nibabel.spatialimages.SpatialImage.update_header"]], "spm2analyzeheader (class in nibabel.spm2analyze)": [[117, "nibabel.spm2analyze.Spm2AnalyzeHeader"]], "spm2analyzeimage (class in nibabel.spm2analyze)": [[117, "nibabel.spm2analyze.Spm2AnalyzeImage"]], "__init__() (nibabel.spm2analyze.spm2analyzeheader method)": [[117, "nibabel.spm2analyze.Spm2AnalyzeHeader.__init__"]], "__init__() (nibabel.spm2analyze.spm2analyzeimage method)": [[117, "nibabel.spm2analyze.Spm2AnalyzeImage.__init__"]], "get_slope_inter() (nibabel.spm2analyze.spm2analyzeheader method)": [[117, "nibabel.spm2analyze.Spm2AnalyzeHeader.get_slope_inter"]], "header_class (nibabel.spm2analyze.spm2analyzeimage attribute)": [[117, "nibabel.spm2analyze.Spm2AnalyzeImage.header_class"]], "may_contain_header() (nibabel.spm2analyze.spm2analyzeheader class method)": [[117, "nibabel.spm2analyze.Spm2AnalyzeHeader.may_contain_header"]], "nibabel.spm2analyze": [[117, "module-nibabel.spm2analyze"]], "template_dtype (nibabel.spm2analyze.spm2analyzeheader attribute)": [[117, "nibabel.spm2analyze.Spm2AnalyzeHeader.template_dtype"]], "spm99analyzeheader (class in nibabel.spm99analyze)": [[118, "nibabel.spm99analyze.Spm99AnalyzeHeader"]], "spm99analyzeimage (class in nibabel.spm99analyze)": [[118, "nibabel.spm99analyze.Spm99AnalyzeImage"]], "spmanalyzeheader (class in nibabel.spm99analyze)": [[118, "nibabel.spm99analyze.SpmAnalyzeHeader"]], "__init__() (nibabel.spm99analyze.spm99analyzeheader method)": [[118, "nibabel.spm99analyze.Spm99AnalyzeHeader.__init__"]], "__init__() (nibabel.spm99analyze.spm99analyzeimage method)": [[118, "nibabel.spm99analyze.Spm99AnalyzeImage.__init__"]], "__init__() (nibabel.spm99analyze.spmanalyzeheader method)": [[118, "nibabel.spm99analyze.SpmAnalyzeHeader.__init__"]], "default_structarr() (nibabel.spm99analyze.spmanalyzeheader class method)": [[118, "nibabel.spm99analyze.SpmAnalyzeHeader.default_structarr"]], "files_types (nibabel.spm99analyze.spm99analyzeimage attribute)": [[118, "nibabel.spm99analyze.Spm99AnalyzeImage.files_types"]], "from_file_map() (nibabel.spm99analyze.spm99analyzeimage class method)": [[118, "nibabel.spm99analyze.Spm99AnalyzeImage.from_file_map"]], "get_best_affine() (nibabel.spm99analyze.spm99analyzeheader method)": [[118, "nibabel.spm99analyze.Spm99AnalyzeHeader.get_best_affine"]], "get_origin_affine() (nibabel.spm99analyze.spm99analyzeheader method)": [[118, "nibabel.spm99analyze.Spm99AnalyzeHeader.get_origin_affine"]], "get_slope_inter() (nibabel.spm99analyze.spmanalyzeheader method)": [[118, "nibabel.spm99analyze.SpmAnalyzeHeader.get_slope_inter"]], "has_affine (nibabel.spm99analyze.spm99analyzeimage attribute)": [[118, "nibabel.spm99analyze.Spm99AnalyzeImage.has_affine"]], "has_data_intercept (nibabel.spm99analyze.spmanalyzeheader attribute)": [[118, "nibabel.spm99analyze.SpmAnalyzeHeader.has_data_intercept"]], "has_data_slope (nibabel.spm99analyze.spmanalyzeheader attribute)": [[118, "nibabel.spm99analyze.SpmAnalyzeHeader.has_data_slope"]], "header_class (nibabel.spm99analyze.spm99analyzeimage attribute)": [[118, "nibabel.spm99analyze.Spm99AnalyzeImage.header_class"]], "makeable (nibabel.spm99analyze.spm99analyzeimage attribute)": [[118, "nibabel.spm99analyze.Spm99AnalyzeImage.makeable"]], "nibabel.spm99analyze": [[118, "module-nibabel.spm99analyze"]], "rw (nibabel.spm99analyze.spm99analyzeimage attribute)": [[118, "nibabel.spm99analyze.Spm99AnalyzeImage.rw"]], "set_origin_from_affine() (nibabel.spm99analyze.spm99analyzeheader method)": [[118, "nibabel.spm99analyze.Spm99AnalyzeHeader.set_origin_from_affine"]], "set_slope_inter() (nibabel.spm99analyze.spmanalyzeheader method)": [[118, "nibabel.spm99analyze.SpmAnalyzeHeader.set_slope_inter"]], "template_dtype (nibabel.spm99analyze.spmanalyzeheader attribute)": [[118, "nibabel.spm99analyze.SpmAnalyzeHeader.template_dtype"]], "to_file_map() (nibabel.spm99analyze.spm99analyzeimage method)": [[118, "nibabel.spm99analyze.Spm99AnalyzeImage.to_file_map"]], "arraysequence (class in nibabel.streamlines.array_sequence)": [[119, "nibabel.streamlines.array_sequence.ArraySequence"]], "dimensions (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.DIMENSIONS"]], "dataerror (class in nibabel.streamlines.tractogram_file)": [[119, "nibabel.streamlines.tractogram_file.DataError"]], "datawarning (class in nibabel.streamlines.tractogram_file)": [[119, "nibabel.streamlines.tractogram_file.DataWarning"]], "endianness (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.ENDIANNESS"]], "eof_delimiter (nibabel.streamlines.tck.tckfile attribute)": [[119, "nibabel.streamlines.tck.TckFile.EOF_DELIMITER"]], "extensionwarning (class in nibabel.streamlines.tractogram_file)": [[119, "nibabel.streamlines.tractogram_file.ExtensionWarning"]], "fiber_delimiter (nibabel.streamlines.tck.tckfile attribute)": [[119, "nibabel.streamlines.tck.TckFile.FIBER_DELIMITER"]], "field (class in nibabel.streamlines.header)": [[119, "nibabel.streamlines.header.Field"]], "header_size (nibabel.streamlines.trk.trkfile attribute)": [[119, "nibabel.streamlines.trk.TrkFile.HEADER_SIZE"]], "headererror (class in nibabel.streamlines.tractogram_file)": [[119, "nibabel.streamlines.tractogram_file.HeaderError"]], "headerwarning (class in nibabel.streamlines.tractogram_file)": [[119, "nibabel.streamlines.tractogram_file.HeaderWarning"]], "lazydict (class in nibabel.streamlines.tractogram)": [[119, "nibabel.streamlines.tractogram.LazyDict"]], "lazytractogram (class in nibabel.streamlines.tractogram)": [[119, "nibabel.streamlines.tractogram.LazyTractogram"]], "magic_number (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.MAGIC_NUMBER"]], "magic_number (nibabel.streamlines.tck.tckfile attribute)": [[119, "nibabel.streamlines.tck.TckFile.MAGIC_NUMBER"]], "magic_number (nibabel.streamlines.trk.trkfile attribute)": [[119, "nibabel.streamlines.trk.TrkFile.MAGIC_NUMBER"]], "method (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.METHOD"]], "nb_points (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.NB_POINTS"]], "nb_properties_per_streamline (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.NB_PROPERTIES_PER_STREAMLINE"]], "nb_scalars_per_point (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.NB_SCALARS_PER_POINT"]], "nb_streamlines (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.NB_STREAMLINES"]], "origin (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.ORIGIN"]], "perarraydict (class in nibabel.streamlines.tractogram)": [[119, "nibabel.streamlines.tractogram.PerArrayDict"]], "perarraysequencedict (class in nibabel.streamlines.tractogram)": [[119, "nibabel.streamlines.tractogram.PerArraySequenceDict"]], "step_size (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.STEP_SIZE"]], "supports_data_per_point (nibabel.streamlines.tck.tckfile attribute)": [[119, "nibabel.streamlines.tck.TckFile.SUPPORTS_DATA_PER_POINT"]], "supports_data_per_point (nibabel.streamlines.trk.trkfile attribute)": [[119, "nibabel.streamlines.trk.TrkFile.SUPPORTS_DATA_PER_POINT"]], "supports_data_per_streamline (nibabel.streamlines.tck.tckfile attribute)": [[119, "nibabel.streamlines.tck.TckFile.SUPPORTS_DATA_PER_STREAMLINE"]], "supports_data_per_streamline (nibabel.streamlines.trk.trkfile attribute)": [[119, "nibabel.streamlines.trk.TrkFile.SUPPORTS_DATA_PER_STREAMLINE"]], "sliceabledatadict (class in nibabel.streamlines.tractogram)": [[119, "nibabel.streamlines.tractogram.SliceableDataDict"]], "tckfile (class in nibabel.streamlines.tck)": [[119, "nibabel.streamlines.tck.TckFile"]], "tractogram (class in nibabel.streamlines.tractogram)": [[119, "nibabel.streamlines.tractogram.Tractogram"]], "tractogramfile (class in nibabel.streamlines.tractogram_file)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile"]], "tractogramitem (class in nibabel.streamlines.tractogram)": [[119, "nibabel.streamlines.tractogram.TractogramItem"]], "trkfile (class in nibabel.streamlines.trk)": [[119, "nibabel.streamlines.trk.TrkFile"]], "voxel_order (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.VOXEL_ORDER"]], "voxel_sizes (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.VOXEL_SIZES"]], "voxel_to_rasmm (nibabel.streamlines.header.field attribute)": [[119, "nibabel.streamlines.header.Field.VOXEL_TO_RASMM"]], "__init__() (nibabel.streamlines.array_sequence.arraysequence method)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.__init__"]], "__init__() (nibabel.streamlines.header.field method)": [[119, "nibabel.streamlines.header.Field.__init__"]], "__init__() (nibabel.streamlines.tck.tckfile method)": [[119, "nibabel.streamlines.tck.TckFile.__init__"]], "__init__() (nibabel.streamlines.tractogram.lazydict method)": [[119, "nibabel.streamlines.tractogram.LazyDict.__init__"]], "__init__() (nibabel.streamlines.tractogram.lazytractogram method)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.__init__"]], "__init__() (nibabel.streamlines.tractogram.perarraydict method)": [[119, "nibabel.streamlines.tractogram.PerArrayDict.__init__"]], "__init__() (nibabel.streamlines.tractogram.perarraysequencedict method)": [[119, "nibabel.streamlines.tractogram.PerArraySequenceDict.__init__"]], "__init__() (nibabel.streamlines.tractogram.sliceabledatadict method)": [[119, "nibabel.streamlines.tractogram.SliceableDataDict.__init__"]], "__init__() (nibabel.streamlines.tractogram.tractogram method)": [[119, "nibabel.streamlines.tractogram.Tractogram.__init__"]], "__init__() (nibabel.streamlines.tractogram.tractogramitem method)": [[119, "nibabel.streamlines.tractogram.TractogramItem.__init__"]], "__init__() (nibabel.streamlines.tractogram_file.dataerror method)": [[119, "nibabel.streamlines.tractogram_file.DataError.__init__"]], "__init__() (nibabel.streamlines.tractogram_file.datawarning method)": [[119, "nibabel.streamlines.tractogram_file.DataWarning.__init__"]], "__init__() (nibabel.streamlines.tractogram_file.extensionwarning method)": [[119, "nibabel.streamlines.tractogram_file.ExtensionWarning.__init__"]], "__init__() (nibabel.streamlines.tractogram_file.headererror method)": [[119, "nibabel.streamlines.tractogram_file.HeaderError.__init__"]], "__init__() (nibabel.streamlines.tractogram_file.headerwarning method)": [[119, "nibabel.streamlines.tractogram_file.HeaderWarning.__init__"]], "__init__() (nibabel.streamlines.tractogram_file.tractogramfile method)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile.__init__"]], "__init__() (nibabel.streamlines.tractogram_file.abstractclassmethod method)": [[119, "nibabel.streamlines.tractogram_file.abstractclassmethod.__init__"]], "__init__() (nibabel.streamlines.trk.trkfile method)": [[119, "nibabel.streamlines.trk.TrkFile.__init__"]], "abstractclassmethod (class in nibabel.streamlines.tractogram_file)": [[119, "nibabel.streamlines.tractogram_file.abstractclassmethod"]], "affine (nibabel.streamlines.tractogram_file.tractogramfile property)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile.affine"]], "affine_to_rasmm (nibabel.streamlines.tractogram.tractogram property)": [[119, "nibabel.streamlines.tractogram.Tractogram.affine_to_rasmm"]], "append() (nibabel.streamlines.array_sequence.arraysequence method)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.append"]], "apply_affine() (nibabel.streamlines.tractogram.lazytractogram method)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.apply_affine"]], "apply_affine() (nibabel.streamlines.tractogram.tractogram method)": [[119, "nibabel.streamlines.tractogram.Tractogram.apply_affine"]], "common_shape (nibabel.streamlines.array_sequence.arraysequence property)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.common_shape"]], "concatenate() (in module nibabel.streamlines.array_sequence)": [[119, "nibabel.streamlines.array_sequence.concatenate"]], "copy() (nibabel.streamlines.array_sequence.arraysequence method)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.copy"]], "copy() (nibabel.streamlines.tractogram.lazytractogram method)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.copy"]], "copy() (nibabel.streamlines.tractogram.tractogram method)": [[119, "nibabel.streamlines.tractogram.Tractogram.copy"]], "create_arraysequences_from_generator() (in module nibabel.streamlines.array_sequence)": [[119, "nibabel.streamlines.array_sequence.create_arraysequences_from_generator"]], "create_empty_header() (nibabel.streamlines.tck.tckfile class method)": [[119, "nibabel.streamlines.tck.TckFile.create_empty_header"]], "create_empty_header() (nibabel.streamlines.tractogram_file.tractogramfile class method)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile.create_empty_header"]], "create_empty_header() (nibabel.streamlines.trk.trkfile class method)": [[119, "nibabel.streamlines.trk.TrkFile.create_empty_header"]], "data (nibabel.streamlines.tractogram.lazytractogram property)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.data"]], "data_per_point (nibabel.streamlines.tractogram.lazytractogram property)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.data_per_point"]], "data_per_point (nibabel.streamlines.tractogram.tractogram property)": [[119, "nibabel.streamlines.tractogram.Tractogram.data_per_point"]], "data_per_streamline (nibabel.streamlines.tractogram.lazytractogram property)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.data_per_streamline"]], "data_per_streamline (nibabel.streamlines.tractogram.tractogram property)": [[119, "nibabel.streamlines.tractogram.Tractogram.data_per_streamline"]], "decode_value_from_name() (in module nibabel.streamlines.trk)": [[119, "nibabel.streamlines.trk.decode_value_from_name"]], "detect_format() (in module nibabel.streamlines)": [[119, "nibabel.streamlines.detect_format"]], "encode_value_in_name() (in module nibabel.streamlines.trk)": [[119, "nibabel.streamlines.trk.encode_value_in_name"]], "extend() (nibabel.streamlines.array_sequence.arraysequence method)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.extend"]], "extend() (nibabel.streamlines.tractogram.lazytractogram method)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.extend"]], "extend() (nibabel.streamlines.tractogram.perarraydict method)": [[119, "nibabel.streamlines.tractogram.PerArrayDict.extend"]], "extend() (nibabel.streamlines.tractogram.tractogram method)": [[119, "nibabel.streamlines.tractogram.Tractogram.extend"]], "finalize_append() (nibabel.streamlines.array_sequence.arraysequence method)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.finalize_append"]], "from_data_func() (nibabel.streamlines.tractogram.lazytractogram class method)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.from_data_func"]], "from_tractogram() (nibabel.streamlines.tractogram.lazytractogram class method)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.from_tractogram"]], "get_affine_from_reference() (in module nibabel.streamlines.utils)": [[119, "nibabel.streamlines.utils.get_affine_from_reference"]], "get_affine_rasmm_to_trackvis() (in module nibabel.streamlines.trk)": [[119, "nibabel.streamlines.trk.get_affine_rasmm_to_trackvis"]], "get_affine_trackvis_to_rasmm() (in module nibabel.streamlines.trk)": [[119, "nibabel.streamlines.trk.get_affine_trackvis_to_rasmm"]], "get_data() (nibabel.streamlines.array_sequence.arraysequence method)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.get_data"]], "header (nibabel.streamlines.tractogram_file.tractogramfile property)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile.header"]], "is_array_sequence (nibabel.streamlines.array_sequence.arraysequence property)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.is_array_sequence"]], "is_array_sequence() (in module nibabel.streamlines.array_sequence)": [[119, "nibabel.streamlines.array_sequence.is_array_sequence"]], "is_correct_format() (nibabel.streamlines.tck.tckfile class method)": [[119, "nibabel.streamlines.tck.TckFile.is_correct_format"]], "is_correct_format() (nibabel.streamlines.tractogram_file.tractogramfile class method)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile.is_correct_format"]], "is_correct_format() (nibabel.streamlines.trk.trkfile class method)": [[119, "nibabel.streamlines.trk.TrkFile.is_correct_format"]], "is_data_dict() (in module nibabel.streamlines.tractogram)": [[119, "nibabel.streamlines.tractogram.is_data_dict"]], "is_lazy_dict() (in module nibabel.streamlines.tractogram)": [[119, "nibabel.streamlines.tractogram.is_lazy_dict"]], "is_ndarray_of_int_or_bool() (in module nibabel.streamlines.array_sequence)": [[119, "nibabel.streamlines.array_sequence.is_ndarray_of_int_or_bool"]], "is_sliced_view (nibabel.streamlines.array_sequence.arraysequence property)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.is_sliced_view"]], "is_supported() (in module nibabel.streamlines)": [[119, "nibabel.streamlines.is_supported"]], "load() (in module nibabel.streamlines)": [[119, "nibabel.streamlines.load"]], "load() (nibabel.streamlines.array_sequence.arraysequence class method)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.load"]], "load() (nibabel.streamlines.tck.tckfile class method)": [[119, "nibabel.streamlines.tck.TckFile.load"]], "load() (nibabel.streamlines.tractogram_file.tractogramfile class method)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile.load"]], "load() (nibabel.streamlines.trk.trkfile class method)": [[119, "nibabel.streamlines.trk.TrkFile.load"]], "nibabel.streamlines": [[119, "module-nibabel.streamlines"]], "nibabel.streamlines.array_sequence": [[119, "module-nibabel.streamlines.array_sequence"]], "nibabel.streamlines.header": [[119, "module-nibabel.streamlines.header"]], "nibabel.streamlines.tck": [[119, "module-nibabel.streamlines.tck"]], "nibabel.streamlines.tractogram": [[119, "module-nibabel.streamlines.tractogram"]], "nibabel.streamlines.tractogram_file": [[119, "module-nibabel.streamlines.tractogram_file"]], "nibabel.streamlines.trk": [[119, "module-nibabel.streamlines.trk"]], "nibabel.streamlines.utils": [[119, "module-nibabel.streamlines.utils"]], "peek_next() (in module nibabel.streamlines.utils)": [[119, "nibabel.streamlines.utils.peek_next"]], "save() (in module nibabel.streamlines)": [[119, "nibabel.streamlines.save"]], "save() (nibabel.streamlines.array_sequence.arraysequence method)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.save"]], "save() (nibabel.streamlines.tck.tckfile method)": [[119, "nibabel.streamlines.tck.TckFile.save"]], "save() (nibabel.streamlines.tractogram_file.tractogramfile method)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile.save"]], "save() (nibabel.streamlines.trk.trkfile method)": [[119, "nibabel.streamlines.trk.TrkFile.save"]], "shrink_data() (nibabel.streamlines.array_sequence.arraysequence method)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.shrink_data"]], "streamlines (nibabel.streamlines.tractogram.lazytractogram property)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.streamlines"]], "streamlines (nibabel.streamlines.tractogram.tractogram property)": [[119, "nibabel.streamlines.tractogram.Tractogram.streamlines"]], "streamlines (nibabel.streamlines.tractogram_file.tractogramfile property)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile.streamlines"]], "to_world() (nibabel.streamlines.tractogram.lazytractogram method)": [[119, "nibabel.streamlines.tractogram.LazyTractogram.to_world"]], "to_world() (nibabel.streamlines.tractogram.tractogram method)": [[119, "nibabel.streamlines.tractogram.Tractogram.to_world"]], "total_nb_rows (nibabel.streamlines.array_sequence.arraysequence property)": [[119, "nibabel.streamlines.array_sequence.ArraySequence.total_nb_rows"]], "tractogram (nibabel.streamlines.tractogram_file.tractogramfile property)": [[119, "nibabel.streamlines.tractogram_file.TractogramFile.tractogram"]], "ingivendirectory() (in module nibabel.tmpdirs)": [[120, "nibabel.tmpdirs.InGivenDirectory"]], "intemporarydirectory() (in module nibabel.tmpdirs)": [[120, "nibabel.tmpdirs.InTemporaryDirectory"]], "temporarydirectory (class in nibabel.tmpdirs)": [[120, "nibabel.tmpdirs.TemporaryDirectory"]], "__init__() (nibabel.tmpdirs.temporarydirectory method)": [[120, "nibabel.tmpdirs.TemporaryDirectory.__init__"]], "nibabel.tmpdirs": [[120, "module-nibabel.tmpdirs"]], "tripwire (class in nibabel.tripwire)": [[121, "nibabel.tripwire.TripWire"]], "tripwireerror (class in nibabel.tripwire)": [[121, "nibabel.tripwire.TripWireError"]], "__init__() (nibabel.tripwire.tripwire method)": [[121, "nibabel.tripwire.TripWire.__init__"]], "__init__() (nibabel.tripwire.tripwireerror method)": [[121, "nibabel.tripwire.TripWireError.__init__"]], "is_tripwire() (in module nibabel.tripwire)": [[121, "nibabel.tripwire.is_tripwire"]], "nibabel.tripwire": [[121, "module-nibabel.tripwire"]], "orthoslicer3d (class in nibabel.viewers)": [[122, "nibabel.viewers.OrthoSlicer3D"]], "__init__() (nibabel.viewers.orthoslicer3d method)": [[122, "nibabel.viewers.OrthoSlicer3D.__init__"]], "clim (nibabel.viewers.orthoslicer3d property)": [[122, "nibabel.viewers.OrthoSlicer3D.clim"]], "close() (nibabel.viewers.orthoslicer3d method)": [[122, "nibabel.viewers.OrthoSlicer3D.close"]], "cmap (nibabel.viewers.orthoslicer3d property)": [[122, "nibabel.viewers.OrthoSlicer3D.cmap"]], "draw() (nibabel.viewers.orthoslicer3d method)": [[122, "nibabel.viewers.OrthoSlicer3D.draw"]], "figs (nibabel.viewers.orthoslicer3d property)": [[122, "nibabel.viewers.OrthoSlicer3D.figs"]], "link_to() (nibabel.viewers.orthoslicer3d method)": [[122, "nibabel.viewers.OrthoSlicer3D.link_to"]], "n_volumes (nibabel.viewers.orthoslicer3d property)": [[122, "nibabel.viewers.OrthoSlicer3D.n_volumes"]], "nibabel.viewers": [[122, "module-nibabel.viewers"]], "position (nibabel.viewers.orthoslicer3d property)": [[122, "nibabel.viewers.OrthoSlicer3D.position"]], "set_position() (nibabel.viewers.orthoslicer3d method)": [[122, "nibabel.viewers.OrthoSlicer3D.set_position"]], "set_volume_idx() (nibabel.viewers.orthoslicer3d method)": [[122, "nibabel.viewers.OrthoSlicer3D.set_volume_idx"]], "show() (nibabel.viewers.orthoslicer3d method)": [[122, "nibabel.viewers.OrthoSlicer3D.show"]], "dtypemapper (class in nibabel.volumeutils)": [[123, "nibabel.volumeutils.DtypeMapper"]], "recoder (class in nibabel.volumeutils)": [[123, "nibabel.volumeutils.Recoder"]], "__init__() (nibabel.volumeutils.dtypemapper method)": [[123, "nibabel.volumeutils.DtypeMapper.__init__"]], "__init__() (nibabel.volumeutils.recoder method)": [[123, "nibabel.volumeutils.Recoder.__init__"]], "add_codes() (nibabel.volumeutils.recoder method)": [[123, "nibabel.volumeutils.Recoder.add_codes"]], "apply_read_scaling() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.apply_read_scaling"]], "array_from_file() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.array_from_file"]], "array_to_file() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.array_to_file"]], "best_write_scale_ftype() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.best_write_scale_ftype"]], "better_float_of() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.better_float_of"]], "fields (nibabel.volumeutils.recoder attribute)": [[123, "nibabel.volumeutils.Recoder.fields"]], "finite_range() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.finite_range"]], "fname_ext_ul_case() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.fname_ext_ul_case"]], "int_scinter_ftype() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.int_scinter_ftype"]], "keys() (nibabel.volumeutils.recoder method)": [[123, "nibabel.volumeutils.Recoder.keys"]], "make_dt_codes() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.make_dt_codes"]], "nibabel.volumeutils": [[123, "module-nibabel.volumeutils"]], "pretty_mapping() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.pretty_mapping"]], "rec2dict() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.rec2dict"]], "seek_tell() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.seek_tell"]], "shape_zoom_affine() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.shape_zoom_affine"]], "value_set() (nibabel.volumeutils.recoder method)": [[123, "nibabel.volumeutils.Recoder.value_set"]], "working_type() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.working_type"]], "write_zeros() (in module nibabel.volumeutils)": [[123, "nibabel.volumeutils.write_zeros"]], "labeledwrapstruct (class in nibabel.wrapstruct)": [[124, "nibabel.wrapstruct.LabeledWrapStruct"]], "wrapstruct (class in nibabel.wrapstruct)": [[124, "nibabel.wrapstruct.WrapStruct"]], "wrapstructerror (class in nibabel.wrapstruct)": [[124, "nibabel.wrapstruct.WrapStructError"]], "__init__() (nibabel.wrapstruct.labeledwrapstruct method)": [[124, "nibabel.wrapstruct.LabeledWrapStruct.__init__"]], "__init__() (nibabel.wrapstruct.wrapstruct method)": [[124, "nibabel.wrapstruct.WrapStruct.__init__"]], "__init__() (nibabel.wrapstruct.wrapstructerror method)": [[124, "nibabel.wrapstruct.WrapStructError.__init__"]], "as_byteswapped() (nibabel.wrapstruct.wrapstruct method)": [[124, "nibabel.wrapstruct.WrapStruct.as_byteswapped"]], "binaryblock (nibabel.wrapstruct.wrapstruct property)": [[124, "nibabel.wrapstruct.WrapStruct.binaryblock"]], "check_fix() (nibabel.wrapstruct.wrapstruct method)": [[124, "nibabel.wrapstruct.WrapStruct.check_fix"]], "copy() (nibabel.wrapstruct.wrapstruct method)": [[124, "nibabel.wrapstruct.WrapStruct.copy"]], "default_structarr() (nibabel.wrapstruct.wrapstruct class method)": [[124, "nibabel.wrapstruct.WrapStruct.default_structarr"]], "diagnose_binaryblock() (nibabel.wrapstruct.wrapstruct class method)": [[124, "nibabel.wrapstruct.WrapStruct.diagnose_binaryblock"]], "endianness (nibabel.wrapstruct.wrapstruct property)": [[124, "nibabel.wrapstruct.WrapStruct.endianness"]], "from_fileobj() (nibabel.wrapstruct.wrapstruct class method)": [[124, "nibabel.wrapstruct.WrapStruct.from_fileobj"]], "get() (nibabel.wrapstruct.wrapstruct method)": [[124, "nibabel.wrapstruct.WrapStruct.get"]], "get_value_label() (nibabel.wrapstruct.labeledwrapstruct method)": [[124, "nibabel.wrapstruct.LabeledWrapStruct.get_value_label"]], "guessed_endian() (nibabel.wrapstruct.wrapstruct class method)": [[124, "nibabel.wrapstruct.WrapStruct.guessed_endian"]], "items() (nibabel.wrapstruct.wrapstruct method)": [[124, "nibabel.wrapstruct.WrapStruct.items"]], "keys() (nibabel.wrapstruct.wrapstruct method)": [[124, "nibabel.wrapstruct.WrapStruct.keys"]], "nibabel.wrapstruct": [[124, "module-nibabel.wrapstruct"]], "structarr (nibabel.wrapstruct.wrapstruct property)": [[124, "nibabel.wrapstruct.WrapStruct.structarr"]], "template_dtype (nibabel.wrapstruct.wrapstruct attribute)": [[124, "nibabel.wrapstruct.WrapStruct.template_dtype"]], "values() (nibabel.wrapstruct.wrapstruct method)": [[124, "nibabel.wrapstruct.WrapStruct.values"]], "write_to() (nibabel.wrapstruct.wrapstruct method)": [[124, "nibabel.wrapstruct.WrapStruct.write_to"]], "characterdatahandler() (nibabel.xmlutils.xmlparser method)": [[125, "nibabel.xmlutils.XmlParser.CharacterDataHandler"]], "endelementhandler() (nibabel.xmlutils.xmlparser method)": [[125, "nibabel.xmlutils.XmlParser.EndElementHandler"]], "handler_names (nibabel.xmlutils.xmlparser attribute)": [[125, "nibabel.xmlutils.XmlParser.HANDLER_NAMES"]], "startelementhandler() (nibabel.xmlutils.xmlparser method)": [[125, "nibabel.xmlutils.XmlParser.StartElementHandler"]], "xmlbasedheader (class in nibabel.xmlutils)": [[125, "nibabel.xmlutils.XmlBasedHeader"]], "xmlparser (class in nibabel.xmlutils)": [[125, "nibabel.xmlutils.XmlParser"]], "xmlserializable (class in nibabel.xmlutils)": [[125, "nibabel.xmlutils.XmlSerializable"]], "__init__() (nibabel.xmlutils.xmlbasedheader method)": [[125, "nibabel.xmlutils.XmlBasedHeader.__init__"]], "__init__() (nibabel.xmlutils.xmlparser method)": [[125, "nibabel.xmlutils.XmlParser.__init__"]], "__init__() (nibabel.xmlutils.xmlserializable method)": [[125, "nibabel.xmlutils.XmlSerializable.__init__"]], "nibabel.xmlutils": [[125, "module-nibabel.xmlutils"]], "parse() (nibabel.xmlutils.xmlparser method)": [[125, "nibabel.xmlutils.XmlParser.parse"]], "to_xml() (nibabel.xmlutils.xmlserializable method)": [[125, "nibabel.xmlutils.XmlSerializable.to_xml"]]}}) \ No newline at end of file diff --git a/tutorials.html b/tutorials.html new file mode 100644 index 0000000000..83e5f94a29 --- /dev/null +++ b/tutorials.html @@ -0,0 +1,174 @@ + + + + + + + + Neuroimaging in Python — NiBabel 5.2.0 documentation + + + + + + + + + + + + + + +
+
+ +
+
+

NiBabel

+

Access a cacophony of neuro-imaging file formats

+
+
+ + + + + + + + \ No newline at end of file

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≺48wcGA{D$UR3 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 XR$o}44D6pHAH-_U*Jh7)JO1!rZU;uw literal 0 HcmV?d00001 diff --git a/_images/coordinate_systems-3_00.png b/_images/coordinate_systems-3_00.png new file mode 100644 index 0000000000000000000000000000000000000000..93a56cc54cfaff980ba0986586ac0283f034df04 GIT binary patch literal 45578 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≺48wcGA{D$UR3 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 XR$o}44D6pHAH-_U*Jh7)JO1!rZU;uw literal 0 HcmV?d00001 diff --git a/_images/coordinate_systems-3_01.png b/_images/coordinate_systems-3_01.png new file mode 100644 index 0000000000000000000000000000000000000000..e7ddf823b323ab17d14ac0a8b2de85ac31d71f8a GIT binary patch literal 58088 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 literal 0 HcmV?d00001 diff --git a/_images/forking_button.png b/_images/forking_button.png new file mode 100644 index 0000000000000000000000000000000000000000..d0e04134d4d086d0c78c45188848c4a0b71b157d GIT binary patch literal 13092 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 literal 0 HcmV?d00001 diff --git a/_images/illustrating_affine.png b/_images/illustrating_affine.png new file mode 100644 index 0000000000000000000000000000000000000000..f5653034770704f0cf3693e69cafea9de61b4b5e GIT binary patch literal 136815 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 literal 0 HcmV?d00001 diff --git a/_images/localizer.png b/_images/localizer.png new file mode 100644 index 0000000000000000000000000000000000000000..3ab99155722436722be281d869fb61560a35385a GIT binary patch literal 187883 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