|
2 | 2 | """
|
3 | 3 | import warnings
|
4 | 4 | import sys
|
| 5 | +from io import BytesIO |
5 | 6 |
|
6 | 7 | import numpy as np
|
7 | 8 |
|
|
12 | 13 | GiftiCoordSystem)
|
13 | 14 | from nibabel.gifti.gifti import data_tag
|
14 | 15 | from nibabel.nifti1 import data_type_codes
|
| 16 | +from nibabel.fileholders import FileHolder |
15 | 17 |
|
16 | 18 | from numpy.testing import (assert_array_almost_equal,
|
17 | 19 | assert_array_equal)
|
@@ -275,3 +277,114 @@ def test_data_tag_deprecated():
|
275 | 277 | warnings.filterwarnings('once', category=DeprecationWarning)
|
276 | 278 | data_tag(np.array([]), 'ASCII', '%i', 1)
|
277 | 279 | assert_equal(len(w), 1)
|
| 280 | + |
| 281 | + |
| 282 | +def test_gifti_round_trip(): |
| 283 | + # From section 14.4 in GIFTI Surface Data Format Version 1.0 |
| 284 | + # (with some adaptations) |
| 285 | + |
| 286 | + test_data = b'''<?xml version="1.0" encoding="UTF-8"?> |
| 287 | +<!DOCTYPE GIFTI SYSTEM "http://www.nitrc.org/frs/download.php/1594/gifti.dtd"> |
| 288 | +<GIFTI |
| 289 | +xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| 290 | +xsi:noNamespaceSchemaLocation="http://www.nitrc.org/frs/download.php/1303/GIFTI_Caret.xsd" |
| 291 | +Version="1.0" |
| 292 | +NumberOfDataArrays="2"> |
| 293 | +<MetaData> |
| 294 | +<MD> |
| 295 | +<Name><![CDATA[date]]></Name> |
| 296 | +<Value><![CDATA[Thu Nov 15 09:05:22 2007]]></Value> |
| 297 | +</MD> |
| 298 | +</MetaData> |
| 299 | +<LabelTable/> |
| 300 | +<DataArray Intent="NIFTI_INTENT_POINTSET" |
| 301 | +DataType="NIFTI_TYPE_FLOAT32" |
| 302 | +ArrayIndexingOrder="RowMajorOrder" |
| 303 | +Dimensionality="2" |
| 304 | +Dim0="4" |
| 305 | +Dim1="3" |
| 306 | +Encoding="ASCII" |
| 307 | +Endian="LittleEndian" |
| 308 | +ExternalFileName="" |
| 309 | +ExternalFileOffset=""> |
| 310 | +<CoordinateSystemTransformMatrix> |
| 311 | +<DataSpace><![CDATA[NIFTI_XFORM_TALAIRACH]]></DataSpace> |
| 312 | +<TransformedSpace><![CDATA[NIFTI_XFORM_TALAIRACH]]></TransformedSpace> |
| 313 | +<MatrixData> |
| 314 | +1.000000 0.000000 0.000000 0.000000 |
| 315 | +0.000000 1.000000 0.000000 0.000000 |
| 316 | +0.000000 0.000000 1.000000 0.000000 |
| 317 | +0.000000 0.000000 0.000000 1.000000 |
| 318 | +</MatrixData> |
| 319 | +</CoordinateSystemTransformMatrix> |
| 320 | +<Data> |
| 321 | +10.5 0 0 |
| 322 | +0 20.5 0 |
| 323 | +0 0 30.5 |
| 324 | +0 0 0 |
| 325 | +</Data> |
| 326 | +</DataArray> |
| 327 | +<DataArray Intent="NIFTI_INTENT_TRIANGLE" |
| 328 | +DataType="NIFTI_TYPE_INT32" |
| 329 | +ArrayIndexingOrder="RowMajorOrder" |
| 330 | +Dimensionality="2" |
| 331 | +Dim0="4" |
| 332 | +Dim1="3" |
| 333 | +Encoding="ASCII" |
| 334 | +Endian="LittleEndian" |
| 335 | +ExternalFileName="" ExternalFileOffset=""> |
| 336 | +<Data> |
| 337 | +0 1 2 |
| 338 | +1 2 3 |
| 339 | +0 1 3 |
| 340 | +0 2 3 |
| 341 | +</Data> |
| 342 | +</DataArray> |
| 343 | +</GIFTI>''' |
| 344 | + |
| 345 | + exp_verts = np.zeros((4, 3)) |
| 346 | + exp_verts[0, 0] = 10.5 |
| 347 | + exp_verts[1, 1] = 20.5 |
| 348 | + exp_verts[2, 2] = 30.5 |
| 349 | + exp_faces = np.asarray([[0, 1, 2], [1, 2, 3], [0, 1, 3], [0, 2, 3]], |
| 350 | + dtype=np.int32) |
| 351 | + |
| 352 | + def _check_gifti(gio): |
| 353 | + vertices = gio.get_arrays_from_intent('NIFTI_INTENT_POINTSET')[0].data |
| 354 | + faces = gio.get_arrays_from_intent('NIFTI_INTENT_TRIANGLE')[0].data |
| 355 | + assert_array_equal(vertices, exp_verts) |
| 356 | + assert_array_equal(faces, exp_faces) |
| 357 | + |
| 358 | + bio = BytesIO() |
| 359 | + fmap = dict(image=FileHolder(fileobj=bio)) |
| 360 | + |
| 361 | + bio.write(test_data) |
| 362 | + bio.seek(0) |
| 363 | + gio = GiftiImage.from_file_map(fmap) |
| 364 | + _check_gifti(gio) |
| 365 | + # Write and read again |
| 366 | + bio.seek(0) |
| 367 | + gio.to_file_map(fmap) |
| 368 | + bio.seek(0) |
| 369 | + gio2 = GiftiImage.from_file_map(fmap) |
| 370 | + _check_gifti(gio2) |
| 371 | + |
| 372 | + |
| 373 | +def test_data_array_round_trip(): |
| 374 | + # Test valid XML generated from new in-memory array |
| 375 | + # See: https://github.com/nipy/nibabel/issues/469 |
| 376 | + verts = np.zeros((4, 3), np.float32) |
| 377 | + verts[0, 0] = 10.5 |
| 378 | + verts[1, 1] = 20.5 |
| 379 | + verts[2, 2] = 30.5 |
| 380 | + |
| 381 | + vertices = GiftiDataArray(verts) |
| 382 | + img = GiftiImage() |
| 383 | + img.add_gifti_data_array(vertices) |
| 384 | + bio = BytesIO() |
| 385 | + fmap = dict(image=FileHolder(fileobj=bio)) |
| 386 | + bio.write(img.to_xml()) |
| 387 | + bio.seek(0) |
| 388 | + gio = GiftiImage.from_file_map(fmap) |
| 389 | + vertices = gio.darrays[0].data |
| 390 | + assert_array_equal(vertices, verts) |
0 commit comments