Skip to content

Commit c907b45

Browse files
authored
Merge branch 'master' into update-data-per-streamline
2 parents e3ffb71 + 0e925ab commit c907b45

28 files changed

+275
-135
lines changed

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "monthly"
7+
groups:
8+
actions-infrastructure:
9+
patterns:
10+
- "actions/*"

.github/workflows/test.yml

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
- uses: actions/checkout@v4
4545
with:
4646
fetch-depth: 0
47-
- uses: actions/setup-python@v4
47+
- uses: actions/setup-python@v5
4848
with:
4949
python-version: 3
5050
- run: pip install --upgrade build twine
@@ -54,12 +54,12 @@ jobs:
5454
- name: Build git archive
5555
run: mkdir archive && git archive -v -o archive/nibabel-archive.tgz HEAD
5656
- name: Upload sdist and wheel artifacts
57-
uses: actions/upload-artifact@v3
57+
uses: actions/upload-artifact@v4
5858
with:
5959
name: dist
6060
path: dist/
6161
- name: Upload git archive artifact
62-
uses: actions/upload-artifact@v3
62+
uses: actions/upload-artifact@v4
6363
with:
6464
name: archive
6565
path: archive/
@@ -73,17 +73,17 @@ jobs:
7373
steps:
7474
- name: Download sdist and wheel artifacts
7575
if: matrix.package != 'archive'
76-
uses: actions/download-artifact@v3
76+
uses: actions/download-artifact@v4
7777
with:
7878
name: dist
7979
path: dist/
8080
- name: Download git archive artifact
8181
if: matrix.package == 'archive'
82-
uses: actions/download-artifact@v3
82+
uses: actions/download-artifact@v4
8383
with:
8484
name: archive
8585
path: archive/
86-
- uses: actions/setup-python@v4
86+
- uses: actions/setup-python@v5
8787
with:
8888
python-version: 3
8989
- name: Display Python version
@@ -147,7 +147,7 @@ jobs:
147147
submodules: recursive
148148
fetch-depth: 0
149149
- name: Set up Python ${{ matrix.python-version }}
150-
uses: actions/setup-python@v4
150+
uses: actions/setup-python@v5
151151
with:
152152
python-version: ${{ matrix.python-version }}
153153
architecture: ${{ matrix.architecture }}
@@ -162,14 +162,15 @@ jobs:
162162
run: tox c
163163
- name: Run tox
164164
run: tox -v --exit-and-dump-after 1200
165-
- uses: codecov/codecov-action@v3
165+
- uses: codecov/codecov-action@v4
166166
if: ${{ always() }}
167167
with:
168168
files: cov.xml
169+
token: ${{ secrets.CODECOV_TOKEN }}
169170
- name: Upload pytest test results
170-
uses: actions/upload-artifact@v3
171+
uses: actions/upload-artifact@v4
171172
with:
172-
name: pytest-results-${{ matrix.os }}-${{ matrix.python-version }}
173+
name: pytest-results-${{ matrix.os }}-${{ matrix.python-version }}-${{ matrix.dependencies }}-${{ matrix.architecture }}
173174
path: test-results.xml
174175
if: ${{ always() }}
175176

@@ -183,7 +184,7 @@ jobs:
183184
steps:
184185
- uses: actions/checkout@v4
185186
- name: Set up Python ${{ matrix.python-version }}
186-
uses: actions/setup-python@v4
187+
uses: actions/setup-python@v5
187188
with:
188189
python-version: 3
189190
- name: Display Python version
@@ -204,7 +205,7 @@ jobs:
204205
id-token: write
205206
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
206207
steps:
207-
- uses: actions/download-artifact@v3
208+
- uses: actions/download-artifact@v4
208209
with:
209210
name: dist
210211
path: dist/

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@
1919
[submodule "nibabel-data/nitest-dicom"]
2020
path = nibabel-data/nitest-dicom
2121
url = https://github.com/effigies/nitest-dicom
22+
[submodule "nibabel-data/dcm_qa_xa30"]
23+
path = nibabel-data/dcm_qa_xa30
24+
url = https://github.com/neurolabusc/dcm_qa_xa30.git

.zenodo.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@
270270
"orcid": "0000-0003-1076-5122"
271271
},
272272
{
273-
"affiliation": "Universit\u00e9 de Sherbrooke",
273+
"affiliation": "Brigham and Women's Hospital, Mass General Brigham/Harvard Medical School",
274274
"name": "Legarreta, Jon Haitz",
275275
"orcid": "0000-0002-9661-1396"
276276
},

Changelog

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,28 @@ Eric Larson (EL), Demian Wassermann, Stephan Gerhard and Ross Markello (RM).
2525

2626
References like "pr/298" refer to github pull request numbers.
2727

28+
5.2.1 (Monday 26 February 2024)
29+
===============================
30+
31+
Bug-fix release in the 5.2.x series.
32+
33+
Enhancements
34+
------------
35+
* Support "flat" ASCII-encoded GIFTI DataArrays (pr/1298) (PM, reviewed by CM)
36+
37+
Bug fixes
38+
---------
39+
* Tolerate missing ``git`` when reporting version info (pr/1286) (CM, reviewed by
40+
Yuri Victorovich)
41+
* Handle Siemens XA30 derived DWI DICOMs (pr/1296) (CM, reviewed by YOH and
42+
Mathias Goncalves)
43+
44+
Maintenance
45+
-----------
46+
* Add tool for generating GitHub-friendly release notes (pr/1284) (CM)
47+
* Accommodate pytest 8 changes (pr/1297) (CM)
48+
49+
2850
5.2.0 (Monday 11 December 2023)
2951
===============================
3052

nibabel-data/dcm_qa_xa30

Submodule dcm_qa_xa30 added at 89b2509

nibabel/_compression.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from .optpkg import optional_package
1818

1919
if ty.TYPE_CHECKING: # pragma: no cover
20-
import indexed_gzip # type: ignore[import-not-found]
20+
import indexed_gzip # type: ignore[import]
2121
import pyzstd
2222

2323
HAVE_INDEXED_GZIP = True

nibabel/affines.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ def rescale_affine(affine, shape, zooms, new_shape=None):
365365
A new affine transform with the specified voxel sizes
366366
367367
"""
368-
shape = np.array(shape, copy=False)
368+
shape = np.asarray(shape)
369369
new_shape = np.array(new_shape if new_shape is not None else shape)
370370

371371
s = voxel_sizes(affine)

nibabel/benchmarks/bench_arrayproxy_slicing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
# if memory_profiler is installed, we get memory usage results
2828
try:
29-
from memory_profiler import memory_usage # type: ignore[import-not-found]
29+
from memory_profiler import memory_usage # type: ignore[import]
3030
except ImportError:
3131
memory_usage = None
3232

nibabel/casting.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ def int_abs(arr):
611611
>>> int_abs(np.array([-128, 127], dtype=np.float32))
612612
array([128., 127.], dtype=float32)
613613
"""
614-
arr = np.array(arr, copy=False)
614+
arr = np.asarray(arr)
615615
dt = arr.dtype
616616
if dt.kind == 'u':
617617
return arr

nibabel/cmdline/dicomfs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class dummy_fuse:
2525

2626

2727
try:
28-
import fuse # type: ignore[import-not-found]
28+
import fuse # type: ignore[import]
2929

3030
uid = os.getuid()
3131
gid = os.getgid()

nibabel/gifti/gifti.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ def agg_data(self, intent_code=None):
745745
>>> triangles_2 = surf_img.agg_data('triangle')
746746
>>> triangles_3 = surf_img.agg_data(1009) # Numeric code for pointset
747747
>>> print(np.array2string(triangles))
748-
[0 1 2]
748+
[[0 1 2]]
749749
>>> np.array_equal(triangles, triangles_2)
750750
True
751751
>>> np.array_equal(triangles, triangles_3)

nibabel/gifti/parse_gifti_fast.py

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,21 @@ def read_data_block(darray, fname, data, mmap):
6868
if mmap is True:
6969
mmap = 'c'
7070
enclabel = gifti_encoding_codes.label[darray.encoding]
71-
dtype = data_type_codes.type[darray.datatype]
7271

72+
if enclabel not in ('ASCII', 'B64BIN', 'B64GZ', 'External'):
73+
raise GiftiParseError(f'Unknown encoding {darray.encoding}')
74+
75+
# Encode the endianness in the dtype
76+
byteorder = gifti_endian_codes.byteorder[darray.endian]
77+
dtype = data_type_codes.dtype[darray.datatype].newbyteorder(byteorder)
78+
79+
shape = tuple(darray.dims)
80+
order = array_index_order_codes.npcode[darray.ind_ord]
81+
82+
# GIFTI_ENCODING_ASCII
7383
if enclabel == 'ASCII':
74-
# GIFTI_ENCODING_ASCII
75-
c = StringIO(data)
76-
da = np.loadtxt(c, dtype=dtype)
77-
return da # independent of the endianness
78-
elif enclabel not in ('B64BIN', 'B64GZ', 'External'):
79-
return 0
80-
81-
# GIFTI_ENCODING_EXTBIN
84+
return np.loadtxt(StringIO(data), dtype=dtype, ndmin=1).reshape(shape, order=order)
85+
8286
# We assume that the external data file is raw uncompressed binary, with
8387
# the data type/endianness/ordering specified by the other DataArray
8488
# attributes
@@ -94,53 +98,41 @@ def read_data_block(darray, fname, data, mmap):
9498
newarr = None
9599
if mmap:
96100
try:
97-
newarr = np.memmap(
101+
return np.memmap(
98102
ext_fname,
99103
dtype=dtype,
100104
mode=mmap,
101105
offset=darray.ext_offset,
102-
shape=tuple(darray.dims),
106+
shape=shape,
107+
order=order,
103108
)
104109
# If the memmap fails, we ignore the error and load the data into
105110
# memory below
106111
except (AttributeError, TypeError, ValueError):
107112
pass
108113
# mmap=False or np.memmap failed
109114
if newarr is None:
110-
# We can replace this with a call to np.fromfile in numpy>=1.17,
111-
# as an "offset" parameter was added in that version.
112-
with open(ext_fname, 'rb') as f:
113-
f.seek(darray.ext_offset)
114-
nbytes = np.prod(darray.dims) * dtype().itemsize
115-
buff = f.read(nbytes)
116-
newarr = np.frombuffer(buff, dtype=dtype)
115+
return np.fromfile(
116+
ext_fname,
117+
dtype=dtype,
118+
count=np.prod(darray.dims),
119+
offset=darray.ext_offset,
120+
).reshape(shape, order=order)
117121

118122
# Numpy arrays created from bytes objects are read-only.
119123
# Neither b64decode nor decompress will return bytearrays, and there
120124
# are not equivalents to fobj.readinto to allow us to pass them, so
121125
# there is not a simple way to avoid making copies.
122126
# If this becomes a problem, we should write a decoding interface with
123127
# a tunable chunk size.
128+
dec = base64.b64decode(data.encode('ascii'))
129+
if enclabel == 'B64BIN':
130+
buff = bytearray(dec)
124131
else:
125-
dec = base64.b64decode(data.encode('ascii'))
126-
if enclabel == 'B64BIN':
127-
# GIFTI_ENCODING_B64BIN
128-
buff = bytearray(dec)
129-
else:
130-
# GIFTI_ENCODING_B64GZ
131-
buff = bytearray(zlib.decompress(dec))
132-
del dec
133-
newarr = np.frombuffer(buff, dtype=dtype)
134-
135-
sh = tuple(darray.dims)
136-
if len(newarr.shape) != len(sh):
137-
newarr = newarr.reshape(sh, order=array_index_order_codes.npcode[darray.ind_ord])
138-
139-
# check if we need to byteswap
140-
required_byteorder = gifti_endian_codes.byteorder[darray.endian]
141-
if required_byteorder in ('big', 'little') and required_byteorder != sys.byteorder:
142-
newarr = newarr.byteswap()
143-
return newarr
132+
# GIFTI_ENCODING_B64GZ
133+
buff = bytearray(zlib.decompress(dec))
134+
del dec
135+
return np.frombuffer(buff, dtype=dtype).reshape(shape, order=order)
144136

145137

146138
def _str2int(in_str):
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE GIFTI SYSTEM "http://www.nitrc.org/frs/download.php/115/gifti.dtd">
3+
<GIFTI Version="1.0" NumberOfDataArrays="2">
4+
<MetaData>
5+
<MD>
6+
<Name><![CDATA[Caret-Version]]></Name>
7+
<Value><![CDATA[5.512]]></Value>
8+
</MD>
9+
<MD>
10+
<Name><![CDATA[date]]></Name>
11+
<Value><![CDATA[Thu Dec 27 14:27:43 2007]]></Value>
12+
</MD>
13+
<MD>
14+
<Name><![CDATA[encoding]]></Name>
15+
<Value><![CDATA[XML]]></Value>
16+
</MD>
17+
</MetaData>
18+
<LabelTable/>
19+
<DataArray Intent="NIFTI_INTENT_POINTSET"
20+
DataType="NIFTI_TYPE_FLOAT32"
21+
ArrayIndexingOrder="RowMajorOrder"
22+
Dimensionality="2"
23+
Dim0="10"
24+
Dim1="3"
25+
Encoding="ASCII"
26+
Endian="LittleEndian"
27+
ExternalFileName=""
28+
ExternalFileOffset="">
29+
<MetaData>
30+
<MD>
31+
<Name><![CDATA[AnatomicalStructurePrimary]]></Name>
32+
<Value><![CDATA[CortexLeft]]></Value>
33+
</MD>
34+
<MD>
35+
<Name><![CDATA[AnatomicalStructureSecondary]]></Name>
36+
<Value><![CDATA[Pial]]></Value>
37+
</MD>
38+
<MD>
39+
<Name><![CDATA[GeometricType]]></Name>
40+
<Value><![CDATA[Anatomical]]></Value>
41+
</MD>
42+
<MD>
43+
<Name><![CDATA[UniqueID]]></Name>
44+
<Value><![CDATA[{70e032e9-4123-47ee-965d-5b29107cbd83}]]></Value>
45+
</MD>
46+
</MetaData>
47+
<CoordinateSystemTransformMatrix>
48+
<DataSpace><![CDATA[NIFTI_XFORM_TALAIRACH]]></DataSpace>
49+
<TransformedSpace><![CDATA[NIFTI_XFORM_TALAIRACH]]></TransformedSpace>
50+
<MatrixData>1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000</MatrixData>
51+
</CoordinateSystemTransformMatrix>
52+
<Data>155.17539978 135.58103943 98.30715179 140.33973694 190.0491333 73.24776459 157.3598938 196.97969055 83.65809631 171.46174622 137.43661499 78.4709549 148.54592896 97.06752777 65.96373749 123.45701599 111.46841431 66.3571167 135.30892944 202.28720093 36.38148499 178.28155518 162.59469604 37.75128937 178.11087036 115.28820038 57.17986679 142.81582642 82.82115173 31.02205276</Data>
53+
</DataArray>
54+
<DataArray Intent="NIFTI_INTENT_TRIANGLE"
55+
DataType="NIFTI_TYPE_INT32"
56+
ArrayIndexingOrder="RowMajorOrder"
57+
Dimensionality="2"
58+
Dim0="10"
59+
Dim1="3"
60+
Encoding="ASCII"
61+
Endian="LittleEndian"
62+
ExternalFileName=""
63+
ExternalFileOffset="">
64+
<MetaData>
65+
<MD>
66+
<Name><![CDATA[TopologicalType]]></Name>
67+
<Value><![CDATA[CLOSED]]></Value>
68+
</MD>
69+
<MD>
70+
<Name><![CDATA[UniqueID]]></Name>
71+
<Value><![CDATA[{747d8015-455b-43ad-82ac-dcfb7606004a}]]></Value>
72+
</MD>
73+
</MetaData>
74+
<Data>6402 17923 25602 14085 25602 17923 25602 14085 4483 17923 1602 14085 4483 25603 25602 25604 25602 25603 25602 25604 6402 25603 3525 25604 1123 17922 12168 25604 12168 17922 </Data>
75+
</DataArray>
76+
</GIFTI>

0 commit comments

Comments
 (0)