imagedata 3.8.15__tar.gz → 3.9.0.dev3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/CHANGELOG.md +25 -0
  2. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/PKG-INFO +1 -1
  3. imagedata-3.9.0.dev3/VERSION.txt +1 -0
  4. imagedata-3.9.0.dev3/data/nifti/ep2d_RSI_b0_500_1500_6dir_20241202111754_3.nii.gz +0 -0
  5. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Sorting.rst +22 -1
  6. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/archives/__init__.py +1 -3
  7. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/axis.py +5 -1
  8. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/collection.py +4 -9
  9. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/formats/__init__.py +3 -1
  10. imagedata-3.9.0.dev3/src/imagedata/formats/dicomlib/datatypes.py +269 -0
  11. imagedata-3.9.0.dev3/src/imagedata/formats/dicomlib/instance.py +352 -0
  12. imagedata-3.9.0.dev3/src/imagedata/formats/dicomlib/sorting.py +443 -0
  13. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/formats/dicomplugin.py +294 -1195
  14. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/formats/matplugin.py +1 -1
  15. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/header.py +0 -1
  16. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/readdata.py +5 -4
  17. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/series.py +12 -6
  18. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata.egg-info/PKG-INFO +1 -1
  19. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata.egg-info/SOURCES.txt +4 -0
  20. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_dicom.py +83 -34
  21. imagedata-3.9.0.dev3/tests/test_formats_dicom_duplicate.py +156 -0
  22. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_series.py +38 -8
  23. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tox.ini +2 -2
  24. imagedata-3.8.15/VERSION.txt +0 -1
  25. imagedata-3.8.15/src/imagedata/formats/dicomlib/instance.py +0 -43
  26. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/.readthedocs.yaml +0 -0
  27. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/.travis.yml +0 -0
  28. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/CONTRIBUTING.rst +0 -0
  29. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/LICENSE.txt +0 -0
  30. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/MANIFEST.in +0 -0
  31. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/Makefile +0 -0
  32. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/README.rst +0 -0
  33. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/5D.zip +0 -0
  34. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/6D_TE_TIME_FA.zip +0 -0
  35. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/RSI_6D.zip +0 -0
  36. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/TI/TI_1.MR.0021.0001.2021.06.08.10.04.29.806302.203193459.IMA +0 -0
  37. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/TI/TI_1.MR.0022.0001.2021.06.08.10.04.29.806302.203195509.IMA +0 -0
  38. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/TI/TI_1.MR.0023.0001.2021.06.08.10.04.29.806302.203197559.IMA +0 -0
  39. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/TI/TI_1.MR.0024.0001.2021.06.08.10.04.29.806302.203199609.IMA +0 -0
  40. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/TI/TI_1.MR.0025.0001.2021.06.08.10.04.29.806302.203201659.IMA +0 -0
  41. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/cohort.zip +0 -0
  42. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/cor_hf.zip +0 -0
  43. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/cor_oblique.zip +0 -0
  44. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/cor_rl.zip +0 -0
  45. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0001.2019.02.07.14.42.45.461288.172175570.IMA +0 -0
  46. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0002.2019.02.07.14.42.45.461288.172174503.IMA +0 -0
  47. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0003.2019.02.07.14.42.45.461288.172175624.IMA +0 -0
  48. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0004.2019.02.07.14.42.45.461288.172174557.IMA +0 -0
  49. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0005.2019.02.07.14.42.45.461288.172175678.IMA +0 -0
  50. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0006.2019.02.07.14.42.45.461288.172174611.IMA +0 -0
  51. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0007.2019.02.07.14.42.45.461288.172175732.IMA +0 -0
  52. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0008.2019.02.07.14.42.45.461288.172174665.IMA +0 -0
  53. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0009.2019.02.07.14.42.45.461288.172175786.IMA +0 -0
  54. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0010.2019.02.07.14.42.45.461288.172174719.IMA +0 -0
  55. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0011.2019.02.07.14.42.45.461288.172175840.IMA +0 -0
  56. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0012.2019.02.07.14.42.45.461288.172174773.IMA +0 -0
  57. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0013.2019.02.07.14.42.45.461288.172175894.IMA +0 -0
  58. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0014.2019.02.07.14.42.45.461288.172174827.IMA +0 -0
  59. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0015.2019.02.07.14.42.45.461288.172175948.IMA +0 -0
  60. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0016.2019.02.07.14.42.45.461288.172174881.IMA +0 -0
  61. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0017.2019.02.07.14.42.45.461288.172176002.IMA +0 -0
  62. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0018.2019.02.07.14.42.45.461288.172174935.IMA +0 -0
  63. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0019.2019.02.07.14.42.45.461288.172176056.IMA +0 -0
  64. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0020.2019.02.07.14.42.45.461288.172174989.IMA +0 -0
  65. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0021.2019.02.07.14.42.45.461288.172176110.IMA +0 -0
  66. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0022.2019.02.07.14.42.45.461288.172175043.IMA +0 -0
  67. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0023.2019.02.07.14.42.45.461288.172176164.IMA +0 -0
  68. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0024.2019.02.07.14.42.45.461288.172175097.IMA +0 -0
  69. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0025.2019.02.07.14.42.45.461288.172176218.IMA +0 -0
  70. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0026.2019.02.07.14.42.45.461288.172175151.IMA +0 -0
  71. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0027.2019.02.07.14.42.45.461288.172176272.IMA +0 -0
  72. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0028.2019.02.07.14.42.45.461288.172175205.IMA +0 -0
  73. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0029.2019.02.07.14.42.45.461288.172176326.IMA +0 -0
  74. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0030.2019.02.07.14.42.45.461288.172175516.IMA +0 -0
  75. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0031.2019.02.07.14.42.45.461288.172175588.IMA +0 -0
  76. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0032.2019.02.07.14.42.45.461288.172174521.IMA +0 -0
  77. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0033.2019.02.07.14.42.45.461288.172175642.IMA +0 -0
  78. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0034.2019.02.07.14.42.45.461288.172174575.IMA +0 -0
  79. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0035.2019.02.07.14.42.45.461288.172175696.IMA +0 -0
  80. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0036.2019.02.07.14.42.45.461288.172174629.IMA +0 -0
  81. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0037.2019.02.07.14.42.45.461288.172175750.IMA +0 -0
  82. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0038.2019.02.07.14.42.45.461288.172174683.IMA +0 -0
  83. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0039.2019.02.07.14.42.45.461288.172175804.IMA +0 -0
  84. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0040.2019.02.07.14.42.45.461288.172174737.IMA +0 -0
  85. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0041.2019.02.07.14.42.45.461288.172175858.IMA +0 -0
  86. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0042.2019.02.07.14.42.45.461288.172174791.IMA +0 -0
  87. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0043.2019.02.07.14.42.45.461288.172175912.IMA +0 -0
  88. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0044.2019.02.07.14.42.45.461288.172174845.IMA +0 -0
  89. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0045.2019.02.07.14.42.45.461288.172175966.IMA +0 -0
  90. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0046.2019.02.07.14.42.45.461288.172174899.IMA +0 -0
  91. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0047.2019.02.07.14.42.45.461288.172176020.IMA +0 -0
  92. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0048.2019.02.07.14.42.45.461288.172174953.IMA +0 -0
  93. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0049.2019.02.07.14.42.45.461288.172176074.IMA +0 -0
  94. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0050.2019.02.07.14.42.45.461288.172175007.IMA +0 -0
  95. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0051.2019.02.07.14.42.45.461288.172176128.IMA +0 -0
  96. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0052.2019.02.07.14.42.45.461288.172175061.IMA +0 -0
  97. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0053.2019.02.07.14.42.45.461288.172176182.IMA +0 -0
  98. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0054.2019.02.07.14.42.45.461288.172175115.IMA +0 -0
  99. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0055.2019.02.07.14.42.45.461288.172176236.IMA +0 -0
  100. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0056.2019.02.07.14.42.45.461288.172175169.IMA +0 -0
  101. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0057.2019.02.07.14.42.45.461288.172176290.IMA +0 -0
  102. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0058.2019.02.07.14.42.45.461288.172175480.IMA +0 -0
  103. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0059.2019.02.07.14.42.45.461288.172176344.IMA +0 -0
  104. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0060.2019.02.07.14.42.45.461288.172175534.IMA +0 -0
  105. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0061.2019.02.07.14.42.45.461288.172175606.IMA +0 -0
  106. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0062.2019.02.07.14.42.45.461288.172174539.IMA +0 -0
  107. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0063.2019.02.07.14.42.45.461288.172175660.IMA +0 -0
  108. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0064.2019.02.07.14.42.45.461288.172174593.IMA +0 -0
  109. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0065.2019.02.07.14.42.45.461288.172175714.IMA +0 -0
  110. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0066.2019.02.07.14.42.45.461288.172174647.IMA +0 -0
  111. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0067.2019.02.07.14.42.45.461288.172175768.IMA +0 -0
  112. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0068.2019.02.07.14.42.45.461288.172174701.IMA +0 -0
  113. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0069.2019.02.07.14.42.45.461288.172175822.IMA +0 -0
  114. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0070.2019.02.07.14.42.45.461288.172174755.IMA +0 -0
  115. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0071.2019.02.07.14.42.45.461288.172175876.IMA +0 -0
  116. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0072.2019.02.07.14.42.45.461288.172174809.IMA +0 -0
  117. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0073.2019.02.07.14.42.45.461288.172175930.IMA +0 -0
  118. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0074.2019.02.07.14.42.45.461288.172174863.IMA +0 -0
  119. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0075.2019.02.07.14.42.45.461288.172175984.IMA +0 -0
  120. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0076.2019.02.07.14.42.45.461288.172174917.IMA +0 -0
  121. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0077.2019.02.07.14.42.45.461288.172176038.IMA +0 -0
  122. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0078.2019.02.07.14.42.45.461288.172174971.IMA +0 -0
  123. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0079.2019.02.07.14.42.45.461288.172176092.IMA +0 -0
  124. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0080.2019.02.07.14.42.45.461288.172175025.IMA +0 -0
  125. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0081.2019.02.07.14.42.45.461288.172176146.IMA +0 -0
  126. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0082.2019.02.07.14.42.45.461288.172175079.IMA +0 -0
  127. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0083.2019.02.07.14.42.45.461288.172176200.IMA +0 -0
  128. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0084.2019.02.07.14.42.45.461288.172175133.IMA +0 -0
  129. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0085.2019.02.07.14.42.45.461288.172176254.IMA +0 -0
  130. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0086.2019.02.07.14.42.45.461288.172175187.IMA +0 -0
  131. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0087.2019.02.07.14.42.45.461288.172176308.IMA +0 -0
  132. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0088.2019.02.07.14.42.45.461288.172175498.IMA +0 -0
  133. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0089.2019.02.07.14.42.45.461288.172176362.IMA +0 -0
  134. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/dwi/PHANTOM_T1.MR._.0007.0090.2019.02.07.14.42.45.461288.172175552.IMA +0 -0
  135. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/ep2d_RSI_b0_500_1500_6dir.zip +0 -0
  136. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/lena_color.dcm +0 -0
  137. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/sag_ap.zip +0 -0
  138. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/sag_hf.zip +0 -0
  139. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/sag_oblique.zip +0 -0
  140. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/srdoc103.zip +0 -0
  141. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time/time00/Image_00019.dcm +0 -0
  142. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time/time00/Image_00020.dcm +0 -0
  143. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time/time00/Image_00021.dcm +0 -0
  144. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time/time01/Image_00019.dcm +0 -0
  145. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time/time01/Image_00020.dcm +0 -0
  146. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time/time01/Image_00021.dcm +0 -0
  147. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time/time02/Image_00019.dcm +0 -0
  148. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time/time02/Image_00020.dcm +0 -0
  149. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time/time02/Image_00021.dcm +0 -0
  150. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time.zip +0 -0
  151. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time_all/Image_00000.dcm +0 -0
  152. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time_all/Image_00001.dcm +0 -0
  153. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time_all/Image_00002.dcm +0 -0
  154. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time_all/Image_00003.dcm +0 -0
  155. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time_all/Image_00004.dcm +0 -0
  156. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time_all/Image_00005.dcm +0 -0
  157. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time_all/Image_00006.dcm +0 -0
  158. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time_all/Image_00007.dcm +0 -0
  159. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/time_all/Image_00008.dcm +0 -0
  160. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/tra_oblique.zip +0 -0
  161. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/dicom/tra_rl.zip +0 -0
  162. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/itk/time/Image_00000.mha +0 -0
  163. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/itk/time/Image_00001.mha +0 -0
  164. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/itk/time/Image_00002.mha +0 -0
  165. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/itk/time.zip +0 -0
  166. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/lena_color.gif +0 -0
  167. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/lena_color.jpg +0 -0
  168. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/mat/time/Image_00000.mat +0 -0
  169. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/mat/time.zip +0 -0
  170. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/cor_hf.nii.gz +0 -0
  171. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/cor_oblique.nii.gz +0 -0
  172. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/cor_rl.nii.gz +0 -0
  173. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/sag_ap.nii.gz +0 -0
  174. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/sag_hf.nii.gz +0 -0
  175. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/sag_oblique.nii.gz +0 -0
  176. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/time/time_all_fl3d_dynamic_20190207140517_14.json +0 -0
  177. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/time/time_all_fl3d_dynamic_20190207140517_14.nii.gz +0 -0
  178. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/time_all/time_all_fl3d_dynamic_20190207140517_14.json +0 -0
  179. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/time_all/time_all_fl3d_dynamic_20190207140517_14.nii.gz +0 -0
  180. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/time_all.zip +0 -0
  181. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/tra_oblique.nii.gz +0 -0
  182. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/nifti/tra_rl.nii.gz +0 -0
  183. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/pdf/A_Lovers_Complaint.pdf +0 -0
  184. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/pdf/pages/A_Lovers_Complaint_1.pdf +0 -0
  185. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/pdf/pages/A_Lovers_Complaint_2.pdf +0 -0
  186. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/pdf/pages/A_Lovers_Complaint_3.pdf +0 -0
  187. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/pdf/pages/A_Lovers_Complaint_4.pdf +0 -0
  188. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/pdf/pages/A_Lovers_Complaint_5.pdf +0 -0
  189. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/pdf/pages/A_Lovers_Complaint_6.pdf +0 -0
  190. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/text.txt +0 -0
  191. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/tree/file0 +0 -0
  192. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/tree/file1 +0 -0
  193. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/tree/file2 +0 -0
  194. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/vertices/vertices2d.pickle +0 -0
  195. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/vertices/vertices3d.pickle +0 -0
  196. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/data/vertices/vertices4d.pickle +0 -0
  197. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReference.rst +0 -0
  198. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReferenceApps.rst +0 -0
  199. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReferenceAppsDiffusion.rst +0 -0
  200. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReferenceArchives.rst +0 -0
  201. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReferenceCollections.rst +0 -0
  202. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReferenceFormats.rst +0 -0
  203. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReferenceImagedata.rst +0 -0
  204. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReferenceSeries.rst +0 -0
  205. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReferenceTransports.rst +0 -0
  206. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/APIReferenceViewer.rst +0 -0
  207. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Anonymization.rst +0 -0
  208. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Collections.rst +0 -0
  209. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Colors.rst +0 -0
  210. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/CommandLine.rst +0 -0
  211. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/DICOMAttributes.rst +0 -0
  212. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/DeveloperDocumentation.rst +0 -0
  213. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Examples.rst +0 -0
  214. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Figure_Architecture.png +0 -0
  215. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Input_output.rst +0 -0
  216. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Installation.rst +0 -0
  217. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Introduction.rst +0 -0
  218. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Makefile +0 -0
  219. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Non_image_dicom_objects.rst +0 -0
  220. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Notebook.rst +0 -0
  221. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Options.rst +0 -0
  222. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Plugin_Architecture.docx +0 -0
  223. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Plugin_Architecture.png +0 -0
  224. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Plugins.rst +0 -0
  225. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/README +0 -0
  226. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Segmentation.rst +0 -0
  227. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Tutorial.rst +0 -0
  228. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/UserGuide.rst +0 -0
  229. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/Viewing.rst +0 -0
  230. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/conf.py +0 -0
  231. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/fuse_mask_blend.png +0 -0
  232. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/index.rst +0 -0
  233. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/make.bat +0 -0
  234. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/requirements.txt +0 -0
  235. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/modules.rst +0 -0
  236. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/setup.rst +0 -0
  237. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/src.imagedata.apps.Siemens.rst +0 -0
  238. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/src.imagedata.apps.rst +0 -0
  239. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/src.imagedata.archives.rst +0 -0
  240. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/src.imagedata.formats.dicomlib.rst +0 -0
  241. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/src.imagedata.formats.rst +0 -0
  242. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/src.imagedata.rst +0 -0
  243. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/src.imagedata.transports.rst +0 -0
  244. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/src.rst +0 -0
  245. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/source/tests.rst +0 -0
  246. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/docs/transformation.tex +0 -0
  247. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/paper.bib +0 -0
  248. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/paper.md +0 -0
  249. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/pylintrc +0 -0
  250. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/pyproject.toml +0 -0
  251. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/setup.cfg +0 -0
  252. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/__init__.py +0 -0
  253. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/__init__.py +0 -0
  254. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/apps/Siemens/ROI.py +0 -0
  255. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/apps/Siemens/__init__.py +0 -0
  256. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/apps/Siemens/draw_antialiased.py +0 -0
  257. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/apps/Siemens/evidence2mask.py +0 -0
  258. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/apps/Siemens/evidence_main.py +0 -0
  259. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/apps/__init__.py +0 -0
  260. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/apps/diffusion.py +0 -0
  261. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/archives/abstractarchive.py +0 -0
  262. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/archives/filesystemarchive.py +0 -0
  263. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/archives/zipfilearchive.py +0 -0
  264. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/cmdline.py +0 -0
  265. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/formats/abstractplugin.py +0 -0
  266. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/formats/dicomlib/__init__.py +0 -0
  267. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/formats/dicomlib/uid.py +0 -0
  268. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/formats/itkplugin.py +0 -0
  269. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/formats/niftiplugin.py +0 -0
  270. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/image_data.py +0 -0
  271. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/list_plugins.py +0 -0
  272. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/transports/__init__.py +0 -0
  273. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/transports/abstracttransport.py +0 -0
  274. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/transports/dicomtransport.py +0 -0
  275. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/transports/filetransport.py +0 -0
  276. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/transports/xnattransport.py +0 -0
  277. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata/viewer.py +0 -0
  278. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata.egg-info/dependency_links.txt +0 -0
  279. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata.egg-info/entry_points.txt +0 -0
  280. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata.egg-info/requires.txt +0 -0
  281. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/src/imagedata.egg-info/top_level.txt +0 -0
  282. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/techstack.md +0 -0
  283. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/techstack.yml +0 -0
  284. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/__init__.py +0 -0
  285. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/compare_headers.py +0 -0
  286. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_archive_file.py +0 -0
  287. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_archive_zip.py +0 -0
  288. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_axis.py +0 -0
  289. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_collections.py +0 -0
  290. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_dicom_color.py +0 -0
  291. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_dicom_template.py +0 -0
  292. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_dicom_zip.py +0 -0
  293. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_itk.py +0 -0
  294. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_itk_template.py +0 -0
  295. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_itk_zip.py +0 -0
  296. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_mat.py +0 -0
  297. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_mat_zip.py +0 -0
  298. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_nifti.py +0 -0
  299. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_formats_nifti_zip.py +0 -0
  300. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_image_data.py +0 -0
  301. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_series_ufunc.py +0 -0
  302. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_transport_dicomtransport.py +0 -0
  303. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_transport_filetransport.py +0 -0
  304. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_transport_xnattransport.py +0 -0
  305. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_version.py +0 -0
  306. {imagedata-3.8.15 → imagedata-3.9.0.dev3}/tests/test_viewer.py +0 -0
@@ -6,6 +6,31 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  <!--next-version-placeholder-->
9
+ ## [v3.9.0-dev3] - 2026-05-21
10
+ ### Fixed
11
+ * Series.__getitem__(): Slice the tags even when there is no tag axis.
12
+ * DICOMPLUGIN._join_axes(): Only accept tag axes of length > 1.
13
+
14
+ ## [v3.9.0-dev2] - 2026-05-20
15
+ * Support for python 3.14
16
+
17
+ ## [v3.9.0-rc1] - 2026-05-20
18
+ ### Added
19
+ * VariableAxis: Accept list of tuples as values.
20
+ * DICOMPlugin: Implement setting DTI tuple (b, bvector).
21
+ ### Fixed
22
+ * Sorting av duplicate tags fixed.
23
+
24
+ ## [v3.9.0-rc0] - 2026-05-19
25
+ ### Added
26
+ * DICOMPlugin: Sort DTI series where tags are (b, bvector) tuple.
27
+ ### Changed
28
+ * DICOMPlugin: Refactored sorting of n-dimensional datasets.
29
+
30
+ ## [v3.8.16-dev0] - 2026-05-15
31
+ ### Changed
32
+ * DICOMPlugin: Refactored sorting of n-dimensional datasets.
33
+
9
34
  ## [v3.8.15] - 2026-05-15
10
35
 
11
36
  ## [v3.8.15-dev4] - 2026-05-15
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: imagedata
3
- Version: 3.8.15
3
+ Version: 3.9.0.dev3
4
4
  Summary: Read/write medical image data
5
5
  Author-email: Erling Andersen <Erling.Andersen@Helse-Bergen.NO>
6
6
  Maintainer-email: Erling Andersen <Erling.Andersen@Helse-Bergen.NO>
@@ -0,0 +1 @@
1
+ 3.9.0-dev3
@@ -36,6 +36,7 @@ Several sort criteria are predefined:
36
36
  * triggertime: Sort on Trigger Time
37
37
  * b: Sort on MR diffusion b-value
38
38
  * bvector: Sort on MR diffusion b vector
39
+ * dti: Sort on MR DTI (b, b vector) tuple
39
40
  * fa: Sort on MR Flip Angle
40
41
  * te: Sort on MR Echo Time
41
42
 
@@ -103,6 +104,25 @@ Trigger Time is the sorting criteria:
103
104
  trigger=get_TriggerTime)
104
105
  )
105
106
 
107
+ MRI DTI sorting
108
+ ---------------
109
+
110
+ MRI diffusion tensor images (DTI) are sorted on diffusion b-value and b-vectors.
111
+ The tags (b, bvector) are tuples.
112
+
113
+ .. code-block:: python
114
+
115
+ img = Series('dti', input_order='dti', input_format='dicom')
116
+ tags = img.tags[0]
117
+ for idx in np.ndindex(tags.shape):
118
+ try:
119
+ b, bvector = tags[idx]
120
+ except TypeError:
121
+ continue
122
+ dti = img[idx]
123
+ print(b, bvector, dti.shape)
124
+
125
+
106
126
  N-dimensional sorting
107
127
  ---------------------
108
128
 
@@ -115,7 +135,8 @@ A dynamic dual-echo MR acquisition can be sorted on time and echo time into a 5D
115
135
 
116
136
  img = Series('dyn_dual_echo', input_order='time,te')
117
137
 
118
- In particular, MR RSI diffusion data can be sorted on `b` value and `b` vector:
138
+ In particular, MR RSI diffusion data can be sorted on `b` value and `b` vector
139
+ (remember that the `dti` sort criteria can be used to sort these data as 4D):
119
140
 
120
141
  .. code-block:: python
121
142
 
@@ -3,12 +3,10 @@
3
3
  Standard plugins provide support for local filesystem and zip archives.
4
4
  """
5
5
 
6
- # Copyright (c) 2018-2024 Erling Andersen, Haukeland University Hospital, Bergen, Norway
6
+ # Copyright (c) 2018-2026 Erling Andersen, Haukeland University Hospital, Bergen, Norway
7
7
 
8
- import os.path
9
8
  import logging
10
9
  import urllib.parse
11
- import fnmatch
12
10
  from ..transports import Transport
13
11
 
14
12
  logger = logging.getLogger(__name__)
@@ -258,7 +258,11 @@ class VariableAxis(Axis):
258
258
 
259
259
  def __init__(self, name: str, values: Sequence) -> None:
260
260
  super(VariableAxis, self).__init__(name)
261
- if issubclass(type(values[0]), Sequence):
261
+ if issubclass(type(values[0]), tuple):
262
+ self._values = np.ndarray(len(values), dtype=tuple)
263
+ for i, value in enumerate(values):
264
+ self._values[i] = value
265
+ elif issubclass(type(values[0]), Sequence):
262
266
  self._values = np.ndarray(len(values), dtype=np.ndarray)
263
267
  for i, value in enumerate(values):
264
268
  self._values[i] = np.array(value)
@@ -453,9 +453,7 @@ class Study(IndexedDict):
453
453
  raise Exception(_url) from e
454
454
 
455
455
  def anonymize(self, uid_table: dict = {}, actions: dict = {}, **kwargs):
456
- _actions = {
457
-
458
- } | actions
456
+ _actions = {} | actions
459
457
  rules = anonymization_rules | kwargs
460
458
  if rules['studyTime'] is None:
461
459
  rules['studyTime'] = self.studyTime
@@ -667,9 +665,7 @@ class Patient(IndexedDict):
667
665
  raise Exception(_url) from e
668
666
 
669
667
  def anonymize(self, uid_table: dict = {}, actions: dict = {}, **kwargs):
670
- _actions = {
671
-
672
- } | actions
668
+ _actions = {} | actions
673
669
  rules = anonymization_rules | kwargs
674
670
  _copy = Patient(None)
675
671
  for _rule in rules:
@@ -851,10 +847,9 @@ class Cohort(IndexedDict):
851
847
  _series.write(_url, opts=opts, formats=formats)
852
848
  except Exception as e:
853
849
  raise Exception(_url) from e
854
- def anonymize(self, uid_table: dict = {}, actions: dict = {}, **kwargs):
855
- _actions = {
856
850
 
857
- } | actions
851
+ def anonymize(self, uid_table: dict = {}, actions: dict = {}, **kwargs):
852
+ _actions = {} | actions
858
853
  rules = anonymization_rules | kwargs
859
854
  _copy = Cohort(None)
860
855
  for _rule in rules:
@@ -3,7 +3,7 @@
3
3
  Standard plugins provides support for DICOM and Nifti image file formats.
4
4
  """
5
5
 
6
- # Copyright (c) 2013-2024 Erling Andersen, Haukeland University Hospital, Bergen, Norway
6
+ # Copyright (c) 2013-2026 Erling Andersen, Haukeland University Hospital, Bergen, Norway
7
7
 
8
8
  import os
9
9
  import sys
@@ -23,11 +23,13 @@ INPUT_ORDER_TIME = 'time'
23
23
  INPUT_ORDER_TRIGGERTIME = 'triggertime'
24
24
  INPUT_ORDER_B = 'b'
25
25
  INPUT_ORDER_BVECTOR = 'bvector'
26
+ INPUT_ORDER_DTI = 'dti'
26
27
  INPUT_ORDER_RSI = 'rsi'
27
28
  INPUT_ORDER_FA = 'fa'
28
29
  INPUT_ORDER_TE = 'te'
29
30
  INPUT_ORDER_FAULTY = 'faulty'
30
31
  input_order_set = {INPUT_ORDER_NONE, INPUT_ORDER_TIME, INPUT_ORDER_B, INPUT_ORDER_BVECTOR,
32
+ INPUT_ORDER_DTI,
31
33
  INPUT_ORDER_RSI, INPUT_ORDER_FA, INPUT_ORDER_TRIGGERTIME,
32
34
  INPUT_ORDER_TE, INPUT_ORDER_FAULTY}
33
35
 
@@ -0,0 +1,269 @@
1
+ """
2
+ Data types
3
+ ==========
4
+
5
+ SourceList: A list of source input urls.
6
+ SourceList is list[dict].
7
+ - 'archive' : archive plugin
8
+ - 'files' : list of file names or regexp. May be empty list.
9
+ SourceList is provided by a calling party.
10
+
11
+ class ObjectList: A list of all source objects.
12
+ ObjectList is list[tuple[AbstractArchive, Member]]
13
+ ObjectList is collected by self._get_dicom_files().
14
+ - _get_dicom_files() collects all DICOM objects from input sources.
15
+ The DICOM objects are not sorted.
16
+
17
+ class DatasetList: A list of all source Instance objects.
18
+ DatasetList is list[Instance]
19
+ DatasetList is collected by self._extract_member.
20
+
21
+ class DatasetDict: The source Instances are sorted according to SeriesUID.
22
+ DatasetDict is defaultdict[SeriesUID, DatasetList]
23
+ DatasetDict is collected by self._catalog_on_instance_uid(), and
24
+ processed by self._select_imaging_datasets() and
25
+ self._select_non_imaging_datasets().
26
+ - _catalog_on_instance_uid() takes an ObjectList and sort objects on
27
+ SeriesUID.
28
+ - _select_imaging_datasets() takes a DatasetDict and return the imaging
29
+ datasets only.
30
+ - _select_non_imaging_datasets() takes a DatasetDict and return the
31
+ non-imaging datasets only.
32
+
33
+ class SortedDatasetList: Collection of DatasetLists for each slice location (float).
34
+ Sorted by slice location and tag.
35
+ SortedDatasetList is defaultdict[float, DatasetList]
36
+ SortedDatasetList is constructed by self._sort_dataset_geometry(),
37
+ and collected by self._sort_datasets().
38
+ SortedDatasetList is processed by self._get_headers._extract_all_tags(),
39
+ self._sort_dataset_geometry(), and _verify_spacing().
40
+ SortedHeaderDict is collected by self._get_headers()
41
+ and self._get_non_image_headers().
42
+
43
+ class SortedData: A tuple of SortedDatasetList and Header.
44
+ SortedDataDict is collected by self._sort_datasets() (see
45
+ SortedDataDict).
46
+
47
+ class SortedDataDict: Collection of SortedData, key is SeriesUID.
48
+ SortedDataDict is defaultdict[SeriesUID, SortedData]
49
+ SortedDataDict is collected by self._sort_datasets() (see
50
+ SortedDatasetList).
51
+ self._process_image_members() NOT in use.
52
+
53
+ class SortedHeaderDict: Collection of Headers, key is SeriesUID.
54
+ SortedHeaderDict is dict[SeriesUID, Header]
55
+ SortedHeaderDict is collected by self._get_headers()
56
+ and self._get_non_image_headers().
57
+
58
+ class PixelDict: Collection of pixel data arrays, key is SeriesUID.
59
+ PixelDict is dict[SeriesUID, np.ndarray]
60
+ PixelDict is collected by self._construct_pixel_arrays().
61
+ """
62
+
63
+ import logging
64
+ from collections import defaultdict, namedtuple
65
+ import numpy as np
66
+ from ...archives.abstractarchive import AbstractArchive, Member
67
+ from .instance import Instance
68
+ from ...header import Header
69
+
70
+
71
+ logger = logging.getLogger(__name__)
72
+
73
+
74
+ # Type definitions
75
+ SourceList = list[dict]
76
+
77
+ SeriesUID = namedtuple('SeriesUID', 'patientID, studyInstanceUID, seriesInstanceUID, ' +
78
+ 'acquisitionNumber, echoNumber', defaults=(None, None))
79
+
80
+
81
+ # Class definitions
82
+ class ObjectList(list):
83
+ """ObjectList is list[tuple[AbstractArchive, Member]]"""
84
+
85
+ def __init__(self):
86
+ super().__init__()
87
+
88
+ def append(self, *args):
89
+ for arg in args:
90
+ assert isinstance(arg, tuple), self.__doc__
91
+ assert len(arg) == 2, self.__doc__
92
+ assert isinstance(arg[0], AbstractArchive), self.__doc__
93
+ assert isinstance(arg[1], Member), self.__doc__
94
+ super().append(*args)
95
+
96
+
97
+ class DatasetList(list):
98
+ """DatasetList is list[Instance]"""
99
+
100
+ def __init__(self):
101
+ super().__init__()
102
+
103
+ def __str__(self):
104
+ """Get printable description of series"""
105
+ dataset = self[0]
106
+ try:
107
+ message = '{} ({})'.format(dataset.SeriesDescription, dataset.SeriesNumber)
108
+ except AttributeError:
109
+ try:
110
+ message = '{} ({})'.format('', dataset.SeriesNumber)
111
+ except AttributeError:
112
+ message = '{}'.format(dataset.SeriesInstanceUID)
113
+ return message
114
+
115
+ def append(self, *args):
116
+ for arg in args:
117
+ assert isinstance(arg, Instance), self.__doc__
118
+ super().append(*args)
119
+
120
+ def getDicomAttribute(self, tag):
121
+ instance: Instance = self[0]
122
+ return instance[tag].value
123
+
124
+ def getDicomAttributeValues(self, tag) -> list:
125
+ values = []
126
+ instance: Instance
127
+ for instance in self:
128
+ try:
129
+ values.append(instance[tag].value)
130
+ except KeyError:
131
+ pass
132
+ return values
133
+
134
+ def get_image_orientation_patient(self) -> np.ndarray:
135
+ instance: Instance = self[0]
136
+ return instance.get_image_orientation_patient()
137
+
138
+ def get_image_position_patient(self) -> np.ndarray:
139
+ instance: Instance = self[0]
140
+ return instance.get_image_position_patient()
141
+
142
+
143
+ class DatasetDict(defaultdict):
144
+ """DatasetDict is defaultdict[SeriesUID, DatasetList]"""
145
+
146
+ def __init__(self):
147
+ super().__init__(DatasetList)
148
+
149
+ def __setitem__(self, key, value):
150
+ assert isinstance(key, SeriesUID), self.__doc__
151
+ assert isinstance(value, DatasetList), self.__doc__
152
+ super().__setitem__(key, value)
153
+
154
+
155
+ class SortedDatasetList(defaultdict):
156
+ """SortedDatasetList is defaultdict[float, DatasetList]"""
157
+
158
+ def __init__(self):
159
+ super().__init__(DatasetList)
160
+ self.axes = None
161
+ self.spacing = None
162
+ self.transformationMatrix = None
163
+ self.imagePositions = None
164
+
165
+ def __setitem__(self, key, value):
166
+ assert isinstance(key, float), self.__doc__
167
+ assert isinstance(value, DatasetList), self.__doc__
168
+ super().__setitem__(key, value)
169
+
170
+ def __str__(self):
171
+ """Get printable description of series"""
172
+ dataset: DatasetList = self[next(iter(self))][0]
173
+ try:
174
+ message = '{} ({})'.format(dataset.SeriesDescription, dataset.SeriesNumber)
175
+ except AttributeError:
176
+ try:
177
+ message = '{} ({})'.format('', dataset.SeriesNumber)
178
+ except AttributeError:
179
+ message = '{}'.format(dataset.SeriesInstanceUID)
180
+ return message
181
+
182
+ def get_headers(self) -> Header:
183
+ """Extract DICOM attributes
184
+
185
+ Args:
186
+ self: DICOMPlugin instance
187
+ sorted_dataset_list: SortedDatasetList
188
+ hdr: existing header (Header)
189
+ message: series description
190
+ opts:
191
+ Returns:
192
+ hdr: header
193
+ - seriesNumber
194
+ - seriesDescription
195
+ - imageType
196
+ - spacing
197
+ - orientation
198
+ - imagePositions
199
+ - axes
200
+ - modality, laterality, protocolName, bodyPartExamined
201
+ - seriesDate, seriesTime, patientPosition
202
+ """
203
+ dataset = self[next(iter(self))][0]
204
+ hdr = Header()
205
+ hdr.input_format = 'dicom'
206
+ dataset.copy_attributes_to_header(hdr)
207
+
208
+ # Extract geometry
209
+ hdr.axes = self.axes
210
+ hdr.orientation = dataset.get_image_orientation_patient()
211
+ hdr.imagePositions = self.imagePositions
212
+ hdr.transformationMatrix = self.transformationMatrix
213
+ hdr.spacing = self.spacing
214
+
215
+ hdr.color = False
216
+ if 'SamplesPerPixel' in dataset and dataset.SamplesPerPixel == 3:
217
+ hdr.color = True
218
+
219
+ # Testing IPP and transformationMatrix
220
+ T0 = hdr.transformationMatrix[:3, 3]
221
+ ipp = np.array(T0)
222
+ warned = False
223
+ for i in range(len(self)):
224
+ if not warned and not np.allclose(ipp, hdr.imagePositions[i], rtol=1e-3):
225
+ logger.warning(f'{self}: DICOM ImagePosition is inconsistent with ImageOrientation')
226
+ warned = True
227
+ ipp += hdr.transformationMatrix[:3, 0]
228
+ return hdr
229
+
230
+
231
+ SortedData = tuple[SortedDatasetList, Header]
232
+
233
+
234
+ class SortedDataDict(defaultdict):
235
+ """SortedDataDict is defaultdict[SeriesUID, SortedData]"""
236
+
237
+ def __init__(self):
238
+ super().__init__(lambda: SortedData)
239
+
240
+ def __setitem__(self, key, value):
241
+ assert isinstance(key, SeriesUID), self.__doc__
242
+ assert isinstance(value, tuple), self.__doc__
243
+ super().__setitem__(key, value)
244
+
245
+
246
+ class SortedHeaderDict(dict):
247
+ """SortedHeaderDict is dict[SeriesUID, Header]"""
248
+
249
+ def __init__(self):
250
+ super().__init__()
251
+
252
+ def __setitem__(self, key, value):
253
+ assert isinstance(key, SeriesUID), self.__doc__
254
+ assert isinstance(value, Header), self.__doc__
255
+ super().__setitem__(key, value)
256
+
257
+
258
+ class PixelDict(dict):
259
+ """PixelDict is dict[SeriesUID, np.ndarray]"""
260
+
261
+ def __init__(self):
262
+ super().__init__()
263
+
264
+ def __setitem__(self, key, value):
265
+ assert isinstance(key, SeriesUID), self.__doc__
266
+ assert isinstance(value, np.ndarray), self.__doc__
267
+ super().__setitem__(key, value)
268
+
269
+