nifti 0.0.1 → 0.0.2
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.
- data/.gitignore +18 -3
- data/CHANGELOG +10 -0
- data/LICENSE +165 -0
- data/README.markdown +30 -34
- data/Rakefile +16 -0
- data/features/n_image.feature +18 -0
- data/features/step_definitions/n_image_steps.rb +33 -0
- data/features/support/env.rb +11 -0
- data/features/support/fixtures/brain_dti.nii.gz +0 -0
- data/features/support/hooks.rb +3 -0
- data/lib/nifti.rb +1 -0
- data/lib/nifti/n_image.rb +110 -0
- data/lib/nifti/n_object.rb +17 -10
- data/lib/nifti/n_read.rb +52 -46
- data/lib/nifti/n_write.rb +29 -14
- data/lib/nifti/version.rb +1 -1
- data/nifti.gemspec +6 -3
- data/spec/custom_matchers.rb +1 -0
- data/spec/fixtures/3plLoc.nii.gz +0 -0
- data/spec/nifti/n_image_spec.rb +76 -0
- data/spec/nifti/n_object_spec.rb +23 -18
- data/spec/nifti/n_read_spec.rb +126 -60
- data/spec/nifti/n_write_spec.rb +71 -26
- data/spec/spec_helper.rb +19 -0
- metadata +111 -78
- data/COPYING +0 -674
- data/Gemfile.lock +0 -30
data/spec/custom_matchers.rb
CHANGED
Binary file
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NIFTI::NImage do
|
4
|
+
let!(:image_array) { Array.new(27,0.0) }
|
5
|
+
let!(:dim) { [3, 3, 3, 3, 1, 1, 1] }
|
6
|
+
|
7
|
+
describe 'shape' do
|
8
|
+
it 'should disconsider the first (number of dimensions) and three last elements of dim' do
|
9
|
+
NImage.new(image_array, dim).shape.should eq([3,3,3])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '[]' do
|
14
|
+
subject { NImage.new(image_array, dim) }
|
15
|
+
|
16
|
+
context 'with a Fixnum' do
|
17
|
+
context 'with a index out of range' do
|
18
|
+
it 'should raise a IndexError' do
|
19
|
+
expect{ subject[2][2][3] }.to raise_error(IndexError)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with a valid index' do
|
24
|
+
it 'should return the value' do
|
25
|
+
mod_image_array = image_array
|
26
|
+
mod_image_array[26] = 1.0
|
27
|
+
n_image = NImage.new(mod_image_array, dim)
|
28
|
+
|
29
|
+
n_image[2][2][2].should eq(1.0)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with a Range' do
|
35
|
+
context 'with a index out of range' do
|
36
|
+
it 'should raise a IndexError' do
|
37
|
+
expect{ subject[2][2][0..3] }.to raise_error(IndexError)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with a valid index' do
|
42
|
+
it 'should return the value' do
|
43
|
+
mod_image_array = image_array
|
44
|
+
mod_image_array[26] = 1.0
|
45
|
+
n_image = NImage.new(mod_image_array, dim)
|
46
|
+
|
47
|
+
n_image[2][2][0..2].should eq([0.0, 0.0, 1.0])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '[]=' do
|
54
|
+
subject { NImage.new(image_array, dim) }
|
55
|
+
|
56
|
+
context 'when setting value for a non Fixnum' do
|
57
|
+
it 'should raise an error' do
|
58
|
+
expect { subject[2]=1.0}.to raise_error(IndexError)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with an invalid index' do
|
63
|
+
it 'should raise an error' do
|
64
|
+
expect { subject[2][2][3]=1.0}.to raise_error(IndexError)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'with a valid index' do
|
69
|
+
it 'should set the value' do
|
70
|
+
subject[2][2][2] = 1.0
|
71
|
+
|
72
|
+
image_array[26].should eq(1.0)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/spec/nifti/n_object_spec.rb
CHANGED
@@ -26,36 +26,36 @@ describe NIFTI::NObject do
|
|
26
26
|
"intent_p3"=>0.0, "regular"=>"r"
|
27
27
|
}
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
# Think of these more as integration tests, since the actual reading
|
31
31
|
# is done and tested in the NRead spec
|
32
32
|
it "should read a nifti file and correctly initialize header and image" do
|
33
33
|
obj = NObject.new(NIFTI_TEST_FILE1)
|
34
|
-
|
34
|
+
|
35
35
|
obj.header.should == @valid_header
|
36
36
|
obj.extended_header.should_not be_empty
|
37
37
|
obj.extended_header.first[:esize].should == 5680
|
38
38
|
obj.extended_header.first[:ecode].should == 4
|
39
39
|
obj.extended_header.first[:data].length.should == @fixture_afni_extension_length
|
40
40
|
obj.image.should be_nil
|
41
|
-
|
41
|
+
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should read a binary string and correctly initialize header and image" do
|
45
45
|
obj = NObject.new(@string, :bin => true)
|
46
|
-
|
46
|
+
|
47
47
|
obj.header.should == @valid_header
|
48
48
|
obj.extended_header.should_not be_empty
|
49
49
|
obj.extended_header.first[:esize].should == 5680
|
50
50
|
obj.extended_header.first[:ecode].should == 4
|
51
51
|
obj.extended_header.first[:data].length.should == @fixture_afni_extension_length
|
52
52
|
obj.image.should be_nil
|
53
|
-
|
53
|
+
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it "should read a nifti file with image" do
|
57
57
|
obj = NObject.new(NIFTI_TEST_FILE1, :image => true)
|
58
|
-
|
58
|
+
|
59
59
|
obj.header.should == @valid_header
|
60
60
|
obj.extended_header.should_not be_empty
|
61
61
|
obj.extended_header.first[:esize].should == 5680
|
@@ -63,12 +63,12 @@ describe NIFTI::NObject do
|
|
63
63
|
obj.extended_header.first[:data].length.should == @fixture_afni_extension_length
|
64
64
|
obj.image.should_not be_nil
|
65
65
|
obj.image.length.should == @fixture_image_length
|
66
|
-
|
66
|
+
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
it "should read a nifti file with image as narray" do
|
70
70
|
obj = NObject.new(NIFTI_TEST_FILE1, :image => true, :narray => true)
|
71
|
-
|
71
|
+
|
72
72
|
obj.header.should == @valid_header
|
73
73
|
obj.extended_header.should_not be_empty
|
74
74
|
obj.extended_header.first[:esize].should == 5680
|
@@ -77,33 +77,38 @@ describe NIFTI::NObject do
|
|
77
77
|
obj.image.should_not be_nil
|
78
78
|
obj.image.class.should == NArray
|
79
79
|
obj.image.dim.should == 3
|
80
|
-
|
80
|
+
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
it "should retrieve image data when requested" do
|
84
84
|
obj = NObject.new(NIFTI_TEST_FILE1)
|
85
85
|
obj.get_image.length.should == @fixture_image_length
|
86
86
|
end
|
87
|
-
|
88
|
-
|
87
|
+
|
88
|
+
|
89
89
|
it "should raise an error if initialized with bad argument" do
|
90
90
|
lambda {
|
91
91
|
NObject.new(12345)
|
92
92
|
}.should raise_error ArgumentError, /Invalid argument/
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
it "should sucessfully write a NIfTI file" do
|
96
96
|
obj = NObject.new(NIFTI_TEST_FILE1, :image => true)
|
97
97
|
obj.write(@new_fixture_file_name)
|
98
98
|
File.exist?(@new_fixture_file_name).should be_true
|
99
99
|
obj.write_success.should be_true
|
100
100
|
end
|
101
|
-
|
102
|
-
it "should be able to assign an image" do
|
101
|
+
|
102
|
+
it "should be able to assign an image" do
|
103
103
|
obj = NObject.new(@string, :bin => true, :image => true)
|
104
104
|
obj.image = [0] * @fixture_image_length
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
|
+
it 'should retrieve an NImage' do
|
108
|
+
obj = NObject.new(NIFTI_TEST_FILE1)
|
109
|
+
obj.get_nimage.should be_a(NImage)
|
110
|
+
end
|
111
|
+
|
107
112
|
after :each do
|
108
113
|
File.delete @new_fixture_file_name if File.exist? @new_fixture_file_name
|
109
114
|
end
|
data/spec/nifti/n_read_spec.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe NIFTI::NRead do
|
4
|
-
before
|
5
|
-
@string = File.open(NIFTI_TEST_FILE1, 'rb').read
|
6
|
-
@stream = Stream.new(@string, false)
|
4
|
+
before do
|
7
5
|
@fixture_image_length = 983040
|
8
6
|
@fixture_afni_extension_length = 5661
|
9
7
|
@valid_header = {
|
@@ -25,65 +23,133 @@ describe NIFTI::NRead do
|
|
25
23
|
"cal_max"=>0.0, "vox_offset"=>6032.0, "slice_start"=>0,
|
26
24
|
"intent_p3"=>0.0, "regular"=>"r"
|
27
25
|
}
|
28
|
-
@n_read_obj = NRead.new(@string, :bin => true)
|
29
26
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
NRead.new(
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
27
|
+
|
28
|
+
context 'with an uncompressed file' do
|
29
|
+
before do
|
30
|
+
@string = File.open(NIFTI_TEST_FILE1, 'rb').read
|
31
|
+
@stream = Stream.new(@string, false)
|
32
|
+
@n_read_obj = NRead.new(@string, :bin => true)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should read a binary string and correctly return header variables" do
|
36
|
+
NRead.new(@string, :bin => true).hdr.should == @valid_header
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should read a nifti file and correctly return header variables" do
|
40
|
+
NRead.new(NIFTI_TEST_FILE1).hdr.should == @valid_header
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should raise IOError if header size != 348." do
|
44
|
+
str = @string.dup
|
45
|
+
str[0..4] = [0].pack("N*")
|
46
|
+
lambda {
|
47
|
+
NRead.new(str, :bin => true).hdr
|
48
|
+
}.should raise_error IOError, /Header appears to be malformed/
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should raise IOError if magic != ni1 or n+1." do
|
52
|
+
str = @string.dup
|
53
|
+
str[344..348] = ["NOPE"].pack("a*")
|
54
|
+
lambda {
|
55
|
+
NRead.new(str, :bin => true).hdr
|
56
|
+
}.should raise_error IOError, /Header appears to be malformed/
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should read image data correctly if :image option is true" do
|
60
|
+
obj = NRead.new(@string, :bin => true, :image => true)
|
61
|
+
obj.image_rubyarray.class.should == Array
|
62
|
+
obj.image_rubyarray.length.should == @fixture_image_length
|
63
|
+
# Since this is a fixture, we know exactly what the values are.
|
64
|
+
# Pick some from the middle of the string and test them.
|
65
|
+
obj.image_rubyarray[(@fixture_image_length / 2)..(@fixture_image_length/2 + 100)].should == [0, 0, 0, 0, 18, 36, 25, 23, 19, 23, 13, 14, 16, 16, 12, 16, 22, 17, 13, 17, 19, 24, 19, 14, 11, 16, 49, 81, 129, 194, 216, 175, 130, 128, 146, 154, 159, 205, 304, 391, 414, 380, 320, 281, 297, 343, 358, 322, 287, 339, 450, 493, 426, 344, 310, 285, 275, 290, 282, 283, 310, 278, 268, 222, 49, 284, 235, 172, 116, 108, 115, 112, 135, 176, 196, 200, 216, 207, 86, 30, 152, 161, 138, 117, 81, 47, 73, 207, 381, 459, 415, 346, 353, 429, 490, 503, 492, 454, 379, 304, 275]
|
66
|
+
obj.image_narray.should be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should return an narray if requested" do
|
70
|
+
obj = NRead.new(@string, :bin => true, :narray => true)
|
71
|
+
obj.image_narray.should_not be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should add an NArray Install message and not set the image_narray if NArray was not available" do
|
75
|
+
Object.expects(:const_defined?).with('NArray').returns(false)
|
76
|
+
obj = NRead.new(@string, :bin => true, :narray => true)
|
77
|
+
obj.msg.should_not be_empty
|
78
|
+
obj.msg.grep(/Please `gem install narray`/).empty?.should be_false
|
79
|
+
obj.image_narray.should be_nil
|
80
|
+
obj.image_rubyarray.size.should == @fixture_image_length
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should read extended header attributes" do
|
84
|
+
@n_read_obj.extended_header.should_not be_empty
|
85
|
+
@n_read_obj.extended_header.first[:esize].should == 5680
|
86
|
+
@n_read_obj.extended_header.first[:ecode].should == 4
|
87
|
+
@n_read_obj.extended_header.first[:data].length.should == @fixture_afni_extension_length
|
88
|
+
@n_read_obj.extended_header.first[:data].should == "<?xml version='1.0' ?>\n<AFNI_attributes\n self_idcode=\"XYZ_Fk5B7fY4srOPxYrGolqMIg\"\n NIfTI_nums=\"256,256,15,1,1,4\"\n ni_form=\"ni_group\" >\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"HISTORY_NOTE\" >\n \"[erik@nelson.medicine.wisc.edu: Fri Jan 21 10:24:14 2011] to3d -prefix 3plLoc.nii I0001.dcm I0002.dcm I0003.dcm ... I0014.dcm I0015.dcm\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"TYPESTRING\" >\n \"3DIM_HEAD_ANAT\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"IDCODE_STRING\" >\n \"XYZ_Fk5B7fY4srOPxYrGolqMIg\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"IDCODE_DATE\" >\n \"Fri Jan 21 10:24:15 2011\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"8\"\n atr_name=\"SCENE_DATA\" >\n 0\n 0\n 0\n -999\n -999\n -999\n -999\n -999\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"LABEL_1\" >\n \"3plLoc.nii+orig\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"LABEL_2\" >\n \"Viggo!\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"DATASET_NAME\" >\n \"./3plLoc.nii+orig\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"3\"\n atr_name=\"ORIENT_SPECIFIC\" >\n 0\n 3\n 4\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"3\"\n atr_name=\"ORIGIN\" >\n -119.531\n -159.531\n -25\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"3\"\n atr_name=\"DELTA\" >\n 0.9375\n 0.9375\n 12.5\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"12\"\n atr_name=\"IJK_TO_DICOM\" >\n 0.9375\n 0.9375\n 0.9375\n -360\n 0\n 0\n 0\n 0\n 0\n 0\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"12\"\n atr_name=\"IJK_TO_DICOM_REAL\" >\n 0.9375\n 0\n 0\n -119.531\n 0\n 0.9375\n 0\n -159.531\n 0\n 0\n 12.5\n -25\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"30\"\n atr_name=\"MARKS_XYZ\" >\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"MARKS_LAB\" >\n \"AC superior edge~~~~AC posterior margin~PC inferior edge~~~~First mid-sag pt~~~~Another mid-sag pt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"3\"\n atr_name=\"MARKS_HELP\" >\n \"This is the uppermost point
on the anterior commisure,
in the mid-sagittal plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~This is the rearmost point
on the anterior commisure,
in the mid-sagittal plane.
[Just a couple mm behind and
 below the AC superior edge.]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~This is the bottommost point
on the posterior commissure,
in the mid-sagittal plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~You must also specify two other points in the
mid-sagittal plane, ABOVE the corpus callosum
(i.e., in the longitudinal fissure). These
points are needed to define the vertical plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n \"~~~~~~~~~~~~~~~~~~~~~~~~You must also specify two other points in the
mid-sagittal plane, ABOVE the corpus callosum
(i.e., in the longitudinal fissure). These
points are needed to define the vertical plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n \"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"8\"\n atr_name=\"MARKS_FLAGS\" >\n 1\n 1\n 0\n 0\n 0\n 0\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"2\"\n atr_name=\"BRICK_STATS\" >\n 0\n 2402\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"8\"\n atr_name=\"DATASET_RANK\" >\n 3\n 1\n 0\n 0\n 0\n 0\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"5\"\n atr_name=\"DATASET_DIMENSIONS\" >\n 256\n 256\n 15\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"1\"\n atr_name=\"BRICK_TYPES\" >\n 1\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"1\"\n atr_name=\"BRICK_FLOAT_FACS\" >\n 0\n</AFNI_atr>\n\n</AFNI_attributes>\n"
|
89
|
+
end
|
68
90
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
91
|
+
|
92
|
+
context 'with an gzip compressed file' do
|
93
|
+
before do
|
94
|
+
@string = File.open(NIFTI_TEST_FILE1_GZ, 'rb').read
|
95
|
+
@stream = Stream.new(@string, false)
|
96
|
+
@n_read_obj = NRead.new(NIFTI_TEST_FILE1_GZ)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should read a nifti file and correctly return header variables" do
|
100
|
+
NRead.new(NIFTI_TEST_FILE1_GZ).hdr.should == @valid_header
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should raise IOError if header size != 348." do
|
104
|
+
str = @string.dup
|
105
|
+
str[0..4] = [0].pack("N*")
|
106
|
+
lambda {
|
107
|
+
NRead.new(str, :bin => true).hdr
|
108
|
+
}.should raise_error IOError, /Header appears to be malformed/
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should raise IOError if magic != ni1 or n+1." do
|
112
|
+
str = @string.dup
|
113
|
+
str[344..348] = ["NOPE"].pack("a*")
|
114
|
+
lambda {
|
115
|
+
NRead.new(str, :bin => true).hdr
|
116
|
+
}.should raise_error IOError, /Header appears to be malformed/
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should read image data correctly if :image option is true" do
|
120
|
+
obj = NRead.new(NIFTI_TEST_FILE1_GZ, :image => true)
|
121
|
+
obj.image_rubyarray.class.should == Array
|
122
|
+
obj.image_rubyarray.length.should == @fixture_image_length
|
123
|
+
# Since this is a fixture, we know exactly what the values are.
|
124
|
+
# Pick some from the middle of the string and test them.
|
125
|
+
obj.image_rubyarray[(@fixture_image_length / 2)..(@fixture_image_length/2 + 100)].should == [0, 0, 0, 0, 18, 36, 25, 23, 19, 23, 13, 14, 16, 16, 12, 16, 22, 17, 13, 17, 19, 24, 19, 14, 11, 16, 49, 81, 129, 194, 216, 175, 130, 128, 146, 154, 159, 205, 304, 391, 414, 380, 320, 281, 297, 343, 358, 322, 287, 339, 450, 493, 426, 344, 310, 285, 275, 290, 282, 283, 310, 278, 268, 222, 49, 284, 235, 172, 116, 108, 115, 112, 135, 176, 196, 200, 216, 207, 86, 30, 152, 161, 138, 117, 81, 47, 73, 207, 381, 459, 415, 346, 353, 429, 490, 503, 492, 454, 379, 304, 275]
|
126
|
+
obj.image_narray.should be_nil
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should return an narray if requested" do
|
130
|
+
obj = NRead.new(NIFTI_TEST_FILE1_GZ, :narray => true)
|
131
|
+
obj.image_narray.should_not be_nil
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should add an NArray Install message and not set the image_narray if NArray was not available" do
|
135
|
+
Object.expects(:const_defined?).with('NArray').returns(false)
|
136
|
+
obj = NRead.new(NIFTI_TEST_FILE1_GZ, :narray => true)
|
137
|
+
obj.msg.should_not be_empty
|
138
|
+
obj.msg.grep(/Please `gem install narray`/).empty?.should be_false
|
139
|
+
obj.image_narray.should be_nil
|
140
|
+
obj.image_rubyarray.size.should == @fixture_image_length
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should read extended header attributes" do
|
144
|
+
@n_read_obj.extended_header.should_not be_empty
|
145
|
+
@n_read_obj.extended_header.first[:esize].should == 5680
|
146
|
+
@n_read_obj.extended_header.first[:ecode].should == 4
|
147
|
+
@n_read_obj.extended_header.first[:data].length.should == @fixture_afni_extension_length
|
148
|
+
@n_read_obj.extended_header.first[:data].should == "<?xml version='1.0' ?>\n<AFNI_attributes\n self_idcode=\"XYZ_Fk5B7fY4srOPxYrGolqMIg\"\n NIfTI_nums=\"256,256,15,1,1,4\"\n ni_form=\"ni_group\" >\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"HISTORY_NOTE\" >\n \"[erik@nelson.medicine.wisc.edu: Fri Jan 21 10:24:14 2011] to3d -prefix 3plLoc.nii I0001.dcm I0002.dcm I0003.dcm ... I0014.dcm I0015.dcm\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"TYPESTRING\" >\n \"3DIM_HEAD_ANAT\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"IDCODE_STRING\" >\n \"XYZ_Fk5B7fY4srOPxYrGolqMIg\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"IDCODE_DATE\" >\n \"Fri Jan 21 10:24:15 2011\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"8\"\n atr_name=\"SCENE_DATA\" >\n 0\n 0\n 0\n -999\n -999\n -999\n -999\n -999\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"LABEL_1\" >\n \"3plLoc.nii+orig\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"LABEL_2\" >\n \"Viggo!\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"DATASET_NAME\" >\n \"./3plLoc.nii+orig\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"3\"\n atr_name=\"ORIENT_SPECIFIC\" >\n 0\n 3\n 4\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"3\"\n atr_name=\"ORIGIN\" >\n -119.531\n -159.531\n -25\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"3\"\n atr_name=\"DELTA\" >\n 0.9375\n 0.9375\n 12.5\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"12\"\n atr_name=\"IJK_TO_DICOM\" >\n 0.9375\n 0.9375\n 0.9375\n -360\n 0\n 0\n 0\n 0\n 0\n 0\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"12\"\n atr_name=\"IJK_TO_DICOM_REAL\" >\n 0.9375\n 0\n 0\n -119.531\n 0\n 0.9375\n 0\n -159.531\n 0\n 0\n 12.5\n -25\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"30\"\n atr_name=\"MARKS_XYZ\" >\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"MARKS_LAB\" >\n \"AC superior edge~~~~AC posterior margin~PC inferior edge~~~~First mid-sag pt~~~~Another mid-sag pt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"3\"\n atr_name=\"MARKS_HELP\" >\n \"This is the uppermost point
on the anterior commisure,
in the mid-sagittal plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~This is the rearmost point
on the anterior commisure,
in the mid-sagittal plane.
[Just a couple mm behind and
 below the AC superior edge.]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~This is the bottommost point
on the posterior commissure,
in the mid-sagittal plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~You must also specify two other points in the
mid-sagittal plane, ABOVE the corpus callosum
(i.e., in the longitudinal fissure). These
points are needed to define the vertical plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n \"~~~~~~~~~~~~~~~~~~~~~~~~You must also specify two other points in the
mid-sagittal plane, ABOVE the corpus callosum
(i.e., in the longitudinal fissure). These
points are needed to define the vertical plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n \"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"8\"\n atr_name=\"MARKS_FLAGS\" >\n 1\n 1\n 0\n 0\n 0\n 0\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"2\"\n atr_name=\"BRICK_STATS\" >\n 0\n 2402\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"8\"\n atr_name=\"DATASET_RANK\" >\n 3\n 1\n 0\n 0\n 0\n 0\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"5\"\n atr_name=\"DATASET_DIMENSIONS\" >\n 256\n 256\n 15\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"1\"\n atr_name=\"BRICK_TYPES\" >\n 1\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"1\"\n atr_name=\"BRICK_FLOAT_FACS\" >\n 0\n</AFNI_atr>\n\n</AFNI_attributes>\n"
|
149
|
+
end
|
78
150
|
end
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
@n_read_obj.extended_header.first[:esize].should == 5680
|
83
|
-
@n_read_obj.extended_header.first[:ecode].should == 4
|
84
|
-
@n_read_obj.extended_header.first[:data].length.should == @fixture_afni_extension_length
|
85
|
-
@n_read_obj.extended_header.first[:data].should == "<?xml version='1.0' ?>\n<AFNI_attributes\n self_idcode=\"XYZ_Fk5B7fY4srOPxYrGolqMIg\"\n NIfTI_nums=\"256,256,15,1,1,4\"\n ni_form=\"ni_group\" >\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"HISTORY_NOTE\" >\n \"[erik@nelson.medicine.wisc.edu: Fri Jan 21 10:24:14 2011] to3d -prefix 3plLoc.nii I0001.dcm I0002.dcm I0003.dcm ... I0014.dcm I0015.dcm\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"TYPESTRING\" >\n \"3DIM_HEAD_ANAT\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"IDCODE_STRING\" >\n \"XYZ_Fk5B7fY4srOPxYrGolqMIg\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"IDCODE_DATE\" >\n \"Fri Jan 21 10:24:15 2011\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"8\"\n atr_name=\"SCENE_DATA\" >\n 0\n 0\n 0\n -999\n -999\n -999\n -999\n -999\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"LABEL_1\" >\n \"3plLoc.nii+orig\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"LABEL_2\" >\n \"Viggo!\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"DATASET_NAME\" >\n \"./3plLoc.nii+orig\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"3\"\n atr_name=\"ORIENT_SPECIFIC\" >\n 0\n 3\n 4\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"3\"\n atr_name=\"ORIGIN\" >\n -119.531\n -159.531\n -25\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"3\"\n atr_name=\"DELTA\" >\n 0.9375\n 0.9375\n 12.5\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"12\"\n atr_name=\"IJK_TO_DICOM\" >\n 0.9375\n 0.9375\n 0.9375\n -360\n 0\n 0\n 0\n 0\n 0\n 0\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"12\"\n atr_name=\"IJK_TO_DICOM_REAL\" >\n 0.9375\n 0\n 0\n -119.531\n 0\n 0.9375\n 0\n -159.531\n 0\n 0\n 12.5\n -25\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"30\"\n atr_name=\"MARKS_XYZ\" >\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n -999999\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"1\"\n atr_name=\"MARKS_LAB\" >\n \"AC superior edge~~~~AC posterior margin~PC inferior edge~~~~First mid-sag pt~~~~Another mid-sag pt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"String\"\n ni_dimen=\"3\"\n atr_name=\"MARKS_HELP\" >\n \"This is the uppermost point
on the anterior commisure,
in the mid-sagittal plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~This is the rearmost point
on the anterior commisure,
in the mid-sagittal plane.
[Just a couple mm behind and
 below the AC superior edge.]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~This is the bottommost point
on the posterior commissure,
in the mid-sagittal plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~You must also specify two other points in the
mid-sagittal plane, ABOVE the corpus callosum
(i.e., in the longitudinal fissure). These
points are needed to define the vertical plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n \"~~~~~~~~~~~~~~~~~~~~~~~~You must also specify two other points in the
mid-sagittal plane, ABOVE the corpus callosum
(i.e., in the longitudinal fissure). These
points are needed to define the vertical plane.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n \"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"8\"\n atr_name=\"MARKS_FLAGS\" >\n 1\n 1\n 0\n 0\n 0\n 0\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"2\"\n atr_name=\"BRICK_STATS\" >\n 0\n 2402\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"8\"\n atr_name=\"DATASET_RANK\" >\n 3\n 1\n 0\n 0\n 0\n 0\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"5\"\n atr_name=\"DATASET_DIMENSIONS\" >\n 256\n 256\n 15\n 0\n 0\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"int\"\n ni_dimen=\"1\"\n atr_name=\"BRICK_TYPES\" >\n 1\n</AFNI_atr>\n\n<AFNI_atr\n ni_type=\"float\"\n ni_dimen=\"1\"\n atr_name=\"BRICK_FLOAT_FACS\" >\n 0\n</AFNI_atr>\n\n</AFNI_attributes>\n"
|
151
|
+
|
152
|
+
context 'without narray' do
|
153
|
+
|
86
154
|
end
|
87
|
-
|
88
|
-
|
89
155
|
end
|
data/spec/nifti/n_write_spec.rb
CHANGED
@@ -3,7 +3,6 @@ require 'spec_helper'
|
|
3
3
|
describe NIFTI::NWrite do
|
4
4
|
before :all do
|
5
5
|
@n_object = NObject.new(NIFTI_TEST_FILE1)
|
6
|
-
@new_fixture_file_name = '5PlLoc.nii'
|
7
6
|
@fixture_image_length = 983040
|
8
7
|
@fixture_afni_extension_length = 5661
|
9
8
|
@valid_header = {
|
@@ -26,31 +25,77 @@ describe NIFTI::NWrite do
|
|
26
25
|
"intent_p3"=>0.0, "regular"=>"r"
|
27
26
|
}
|
28
27
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
28
|
+
|
29
|
+
context 'writing to an uncompressed file' do
|
30
|
+
before do
|
31
|
+
@new_fixture_file_name = '5PlLoc.nii'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should write a NIfTI file" do
|
35
|
+
obj = NObject.new(NIFTI_TEST_FILE1, :image => true)
|
36
|
+
w = NWrite.new(obj, @new_fixture_file_name)
|
37
|
+
w.write
|
38
|
+
w.msg.should be_empty
|
39
|
+
File.exist?(@new_fixture_file_name).should be_true
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should write back an identical file if no changes were made" do
|
43
|
+
obj = NObject.new(NIFTI_TEST_FILE1, :image => true)
|
44
|
+
w = NWrite.new(obj, @new_fixture_file_name)
|
45
|
+
w.write
|
46
|
+
@new_fixture_file_name.should be_same_file_as NIFTI_TEST_FILE1
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should write a new image after changing some variables" do
|
50
|
+
obj = NObject.new(NIFTI_TEST_FILE1, :image => true)
|
51
|
+
obj.header['qoffset_x'] = obj.header['qoffset_x'] + 1
|
52
|
+
w = NWrite.new(obj, @new_fixture_file_name)
|
53
|
+
w.write
|
54
|
+
@new_fixture_file_name.should_not be_same_file_as NIFTI_TEST_FILE1
|
55
|
+
end
|
56
|
+
|
57
|
+
after :each do
|
58
|
+
File.delete @new_fixture_file_name if File.exist? @new_fixture_file_name
|
59
|
+
end
|
51
60
|
end
|
52
|
-
|
53
|
-
|
54
|
-
|
61
|
+
|
62
|
+
context 'writing to a compressed file' do
|
63
|
+
before do
|
64
|
+
@new_fixture_file_name = '5PlLoc.nii.gz'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should write a NIfTI file" do
|
68
|
+
obj = NObject.new(NIFTI_TEST_FILE1, :image => true)
|
69
|
+
w = NWrite.new(obj, @new_fixture_file_name)
|
70
|
+
w.write
|
71
|
+
w.msg.should be_empty
|
72
|
+
File.exist?(@new_fixture_file_name).should be_true
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should write back an identical file if no changes were made" do
|
76
|
+
obj = NObject.new(NIFTI_TEST_FILE1, :image => true)
|
77
|
+
|
78
|
+
w = NWrite.new(obj, @new_fixture_file_name)
|
79
|
+
w.write
|
80
|
+
writen_obj = NObject.new(@new_fixture_file_name, :image => true)
|
81
|
+
|
82
|
+
# for some reason be_same_file_as fails for gziped images
|
83
|
+
# but we can make sure of it opening the file again and comparing the data
|
84
|
+
writen_obj.get_image.should eq(obj.get_image)
|
85
|
+
writen_obj.header.should eq(obj.header)
|
86
|
+
writen_obj.extended_header.should eq(obj.extended_header)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should write a new image after changing some variables" do
|
90
|
+
obj = NObject.new(NIFTI_TEST_FILE1, :image => true)
|
91
|
+
obj.header['qoffset_x'] = obj.header['qoffset_x'] + 1
|
92
|
+
w = NWrite.new(obj, @new_fixture_file_name)
|
93
|
+
w.write
|
94
|
+
@new_fixture_file_name.should_not be_same_file_as NIFTI_TEST_FILE1_GZ
|
95
|
+
end
|
96
|
+
|
97
|
+
after :each do
|
98
|
+
File.delete @new_fixture_file_name if File.exist? @new_fixture_file_name
|
99
|
+
end
|
55
100
|
end
|
56
101
|
end
|