nifti 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|