|
21 | 21 | Nifti1Pair, Nifti1Extension, Nifti1Extensions,
|
22 | 22 | data_type_codes, extension_codes, slice_order_codes)
|
23 | 23 |
|
| 24 | +from .test_arraywriters import rt_err_estimate, IUINT_TYPES |
| 25 | + |
24 | 26 | from numpy.testing import assert_array_equal, assert_array_almost_equal
|
25 | 27 | from nose.tools import (assert_true, assert_false, assert_equal,
|
26 | 28 | assert_raises)
|
@@ -688,4 +690,66 @@ def test_affines_init():
|
688 | 690 | assert_array_equal(new_hdr.get_zooms(), [3, 4, 5])
|
689 | 691 |
|
690 | 692 |
|
691 |
| - |
| 693 | +def round_trip(img): |
| 694 | + stio = BytesIO() |
| 695 | + img.file_map['image'].fileobj = stio |
| 696 | + img.to_file_map() |
| 697 | + return Nifti1Image.from_file_map(img.file_map) |
| 698 | + |
| 699 | + |
| 700 | +def test_float_int_min_max(): |
| 701 | + # Conversion between float and int |
| 702 | + # Parallel test to arraywriters |
| 703 | + aff = np.eye(4) |
| 704 | + for in_dt in (np.float32, np.float64): |
| 705 | + finf = np.finfo(in_dt) |
| 706 | + arr = np.array([finf.min, finf.max], dtype=in_dt) |
| 707 | + for out_dt in IUINT_TYPES: |
| 708 | + img = Nifti1Image(arr, aff) |
| 709 | + img_back = round_trip(img) |
| 710 | + arr_back_sc = img_back.get_data() |
| 711 | + assert_true(np.allclose(arr, arr_back_sc)) |
| 712 | + |
| 713 | + |
| 714 | +def test_float_int_spread(): |
| 715 | + # Test rounding error for spread of values |
| 716 | + # Parallel test to arraywriters |
| 717 | + powers = np.arange(-10, 10, 0.5) |
| 718 | + arr = np.concatenate((-10**powers, 10**powers)) |
| 719 | + aff = np.eye(4) |
| 720 | + for in_dt in (np.float32, np.float64): |
| 721 | + arr_t = arr.astype(in_dt) |
| 722 | + for out_dt in IUINT_TYPES: |
| 723 | + img = Nifti1Image(arr_t, aff) |
| 724 | + img_back = round_trip(img) |
| 725 | + arr_back_sc = img_back.get_data() |
| 726 | + slope, inter = img_back.get_header().get_slope_inter() |
| 727 | + # Get estimate for error |
| 728 | + max_miss = rt_err_estimate(arr_t, arr_back_sc.dtype, slope, inter) |
| 729 | + # Simulate allclose test with large atol |
| 730 | + diff = np.abs(arr_t - arr_back_sc) |
| 731 | + rdiff = diff / np.abs(arr_t) |
| 732 | + assert_true(np.all((diff <= max_miss) | (rdiff <= 1e-5))) |
| 733 | + |
| 734 | + |
| 735 | +def test_rt_bias(): |
| 736 | + # Check for bias in round trip |
| 737 | + # Parallel test to arraywriters |
| 738 | + rng = np.random.RandomState(20111214) |
| 739 | + mu, std, count = 100, 10, 100 |
| 740 | + arr = rng.normal(mu, std, size=(count,)) |
| 741 | + eps = np.finfo(np.float32).eps |
| 742 | + aff = np.eye(4) |
| 743 | + for in_dt in (np.float32, np.float64): |
| 744 | + arr_t = arr.astype(in_dt) |
| 745 | + for out_dt in IUINT_TYPES: |
| 746 | + img = Nifti1Image(arr_t, aff) |
| 747 | + img_back = round_trip(img) |
| 748 | + arr_back_sc = img_back.get_data() |
| 749 | + slope, inter = img_back.get_header().get_slope_inter() |
| 750 | + bias = np.mean(arr_t - arr_back_sc) |
| 751 | + # Get estimate for error |
| 752 | + max_miss = rt_err_estimate(arr_t, arr_back_sc.dtype, slope, inter) |
| 753 | + # Hokey use of max_miss as a std estimate |
| 754 | + bias_thresh = np.max([max_miss / np.sqrt(count), eps]) |
| 755 | + assert_true(np.abs(bias) < bias_thresh) |
0 commit comments