cicada 0.9.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,133 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2013 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+ require 'matrix'
28
+
29
+ ##
30
+ # Extension to the standard library Matrix class making them mutable.
31
+ #
32
+ #class MMatrix < Matrix #disabled until the bug fix for the issue in the standard library that prevents useful subclasses is released
33
+
34
+ class MMatrix < Matrix
35
+ end
36
+
37
+ class Matrix
38
+ ##
39
+ # Replaces a row in this matrix by copying the entries from another vector.
40
+ #
41
+ # @param [Integer] i the index of the row to replace
42
+ # @param [Vector, Array] other the vector or array whose contents will be copied
43
+ # to the specified row.
44
+ #
45
+ def replace_row(i, other)
46
+
47
+ column_size.times do |j|
48
+
49
+ self[i, j]= other[j]
50
+
51
+ end
52
+
53
+ end
54
+
55
+ ##
56
+ # Replaces a column in this matrix by copying the entries from another vector.
57
+ #
58
+ # @param [Integer] j the index of the column to replace
59
+ # @param [Vector, Array] other the vector or array whose contents will be copied
60
+ # to the specified column.
61
+ #
62
+ def replace_column(j, other)
63
+
64
+ row_size.times do |i|
65
+
66
+ self[i, j]= other[i]
67
+
68
+ end
69
+
70
+ end
71
+
72
+ public :[]=
73
+
74
+ end
75
+
76
+ ##
77
+ # Extension to the standard library Vector class making them mutable and adding
78
+ # some additional functionality.
79
+ #
80
+ class MVector < Vector
81
+
82
+ ##
83
+ # Generates a zero vector of specified size.
84
+ #
85
+ # @param [Integer] size the size of the zero vector
86
+ #
87
+ # @return [MVector] a mutable vector of specified size containing all 0.0
88
+ #
89
+ def MVector.zero(size)
90
+
91
+ elements(Array.new(size, 0.0), false)
92
+
93
+ end
94
+
95
+ ##
96
+ # Generates a unit vector of specified size.
97
+ #
98
+ # @param [Integer] size the size of the unit vector
99
+ #
100
+ # @return [MVector] a mutable vector of specified size containing all 1.0
101
+ #
102
+ def MVector.unit(size)
103
+
104
+ MVector.elements(Array.new(size, 1.0), false)
105
+
106
+ end
107
+
108
+ ##
109
+ # Replaces the contents of this vector with the contents of another vector. This will not
110
+ # change the size of the current vector and will replace entries only up to the current size.
111
+ #
112
+ # @param [Vector<Numeric>, Array<Numeric>] other a vector (or array, or other indexable
113
+ # collection) with at least as many elements as this vector; its entries will replace
114
+ # this vector's entries
115
+ #
116
+ # @return [void]
117
+ #
118
+ def replace(other)
119
+
120
+ self.each_with_index do |e,i|
121
+
122
+ self[i] = other[i]
123
+
124
+ end
125
+
126
+ end
127
+
128
+
129
+ public :[]=
130
+
131
+
132
+ end
133
+
@@ -0,0 +1,33 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2013 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+ module Cicada
28
+
29
+ VERSION = "0.9.0"
30
+
31
+ end
32
+
33
+
@@ -0,0 +1,114 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2013 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+ require 'cicada/correction/correction'
28
+
29
+ require 'spec_helper'
30
+
31
+ describe Cicada::Correction do
32
+
33
+ XY_SIZE_NM = 80.0
34
+ Z_SIZE_NM = 100.0
35
+
36
+ DISTANCE_CONVERSIONS = Vector[XY_SIZE_NM, XY_SIZE_NM, Z_SIZE_NM]
37
+
38
+ def expected_aberr(x,y)
39
+
40
+ x_aberr = (1024 - (x)*4 -1)*0.01/80.0/4
41
+ y_aberr = (1024 - (y)*4 -1)*0.01/80.0/4
42
+ z_aberr = (((x)*4+1)*0.04 + (1024 - (y)*4-1)*0.04)/100.0/2
43
+
44
+ Vector[x_aberr, y_aberr, z_aberr]
45
+
46
+ end
47
+
48
+ def get_diff_from_expected(x_test, y_test, c)
49
+
50
+ corr = c.correct_position(x_test, y_test)
51
+
52
+ exp = expected_aberr(x_test, y_test)
53
+
54
+ corr = corr.map2(DISTANCE_CONVERSIONS) { |e1, e2| e1*e2 }
55
+
56
+ exp = exp.map2(DISTANCE_CONVERSIONS) { |e1, e2| e1*e2 }
57
+
58
+ (corr - exp).norm
59
+
60
+ end
61
+
62
+ it "should calculate the right correction given a position" do
63
+
64
+ c = Cicada::Correction.read_from_file(CORR_FN)
65
+
66
+ x = [99.75, 20.0, 122.0, 37.98, 200.0, 223.44]
67
+ y = [54.75, 90.0, 220.0, 77.43, 189.0, 120.30]
68
+
69
+ expected_error = [1.671,
70
+ 1.103,
71
+ 0.459,
72
+ 1.286,
73
+ 1.243,
74
+ 2.385] #values based on java implementation
75
+
76
+
77
+ allowed_error = 0.001
78
+
79
+ diffs = []
80
+
81
+ x.each_index do |i|
82
+
83
+ diffs << get_diff_from_expected(x[i], y[i], c)
84
+
85
+ end
86
+
87
+ remaining_error = expected_error.ewise - diffs
88
+
89
+ remaining_error.map! { |e| e.abs }
90
+
91
+ remaining_error.each do |e|
92
+
93
+ e.should be < allowed_error
94
+
95
+ end
96
+
97
+ end
98
+
99
+
100
+ it "should be the same after writing to and reading from XML" do
101
+
102
+ c = Cicada::Correction.read_from_file(CORR_FN)
103
+
104
+ xml_string = c.write_to_xml
105
+
106
+ ref_string = Cicada::Correction.read_from_xml(xml_string).write_to_xml
107
+
108
+ xml_string.should == ref_string
109
+
110
+ end
111
+
112
+
113
+ end
114
+
@@ -0,0 +1,169 @@
1
+ #--
2
+ # /* ***** BEGIN LICENSE BLOCK *****
3
+ # *
4
+ # * Copyright (c) 2013 Colin J. Fuller
5
+ # *
6
+ # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # * of this software and associated documentation files (the Software), to deal
8
+ # * in the Software without restriction, including without limitation the rights
9
+ # * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # * copies of the Software, and to permit persons to whom the Software is
11
+ # * furnished to do so, subject to the following conditions:
12
+ # *
13
+ # * The above copyright notice and this permission notice shall be included in
14
+ # * all copies or substantial portions of the Software.
15
+ # *
16
+ # * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # * SOFTWARE.
23
+ # *
24
+ # * ***** END LICENSE BLOCK ***** */
25
+ #++
26
+
27
+ require 'spec_helper'
28
+
29
+ require 'cicada/correction/position_corrector'
30
+ require 'cicada/cicada_main'
31
+
32
+ require 'rimageanalysistools/create_parameters'
33
+
34
+ require 'ostruct'
35
+
36
+ describe Cicada::PositionCorrector do
37
+
38
+ before :each do
39
+
40
+ @p = {reference_channel: 0, channel_to_correct: 1, half_box_size: 3, half_z_size: 5, pixelsize_nm: 80, z_sectionsize_nm: 100, num_points: 36, num_wavelengths: 3, log_detailed_messages: true, max_threads: 10, photons_per_greylevel: 0.125, determine_correction: true, fit_error_cutoff: 10, correct_images: true}
41
+
42
+ end
43
+
44
+ it "should generate a correction correctly" do
45
+
46
+ pc = Cicada::PositionCorrector.new(@p)
47
+
48
+ iobjs = load_iobjs
49
+
50
+ c = pc.generate_correction(iobjs)
51
+
52
+ xml_string = c.write_to_xml
53
+
54
+ c_ref = load_correction
55
+
56
+ ref_string = c_ref.write_to_xml
57
+
58
+ xml_string.should == ref_string
59
+
60
+ end
61
+
62
+
63
+ it "should be able to correct image objects" do
64
+
65
+ iobjs = load_iobjs
66
+
67
+ iobjs_orig = iobjs
68
+
69
+ iobjs = iobjs.select { |e| e.getLabel % 10 == 0 }
70
+
71
+ pc = Cicada::PositionCorrector.new(@p)
72
+
73
+ c = load_correction
74
+
75
+ diffs = pc.apply_correction(c, iobjs)
76
+
77
+ expected = [0.9648537061749035,
78
+ 0.5709395379024668,
79
+ 0.8858793228753269,
80
+ 1.0188179855284514,
81
+ 0.9905469052645519,
82
+ 1.5904787247607233,
83
+ 0.7160781864125757,
84
+ 0.6880017962144355,
85
+ 0.6415597673221431] #this is based on matching values to the java implementation
86
+
87
+ expected.each_index do |i|
88
+
89
+ expected[i].should == diffs[i]
90
+
91
+ end
92
+
93
+ end
94
+
95
+
96
+ it "should correctly calculate the target registration error (TRE)" do
97
+
98
+ pc = Cicada::PositionCorrector.new(@p)
99
+
100
+ tre = pc.determine_tre(load_iobjs)
101
+
102
+ expected_tre = 1.407 #value from java implementation
103
+
104
+ allowed_error = 0.001
105
+
106
+ (tre - expected_tre).abs.should be < allowed_error
107
+
108
+ end
109
+
110
+ it "should be able to calculate coefficients for the in situ correction" do
111
+
112
+ @p[:correct_images] = false
113
+ @p[:channel_to_correct] = 2
114
+ @p[:in_situ_aberr_corr_channel] = 1
115
+
116
+ pc = Cicada::PositionCorrector.new(@p)
117
+
118
+ corr = pc.generate_in_situ_correction_from_iobjs(load_iobjs)
119
+
120
+ x_corr = corr[0]
121
+ y_corr = corr[1]
122
+ z_corr = corr[2]
123
+
124
+ #these values match the java implementation; input values for image generation (pre-noise) were 1.32 slope and 0.05625 x,y intercept and 0.1125 z intercept
125
+ expected_x = [1.28, 0.057]
126
+ expected_y = [1.15, 0.058]
127
+ expected_z = [1.32, 0.119]
128
+
129
+ allowed_err = [0.01, 0.001]
130
+
131
+ (expected_x[0] - x_corr[0]).abs.should be < allowed_err[0]
132
+ (expected_x[1] - x_corr[1]).abs.should be < allowed_err[1]
133
+ (expected_y[0] - y_corr[0]).abs.should be < allowed_err[0]
134
+ (expected_y[1] - y_corr[1]).abs.should be < allowed_err[1]
135
+ (expected_z[0] - z_corr[0]).abs.should be < allowed_err[0]
136
+ (expected_z[1] - z_corr[1]).abs.should be < allowed_err[1]
137
+
138
+ end
139
+
140
+
141
+ it "should be able to apply the in situ correction" do
142
+
143
+ @p[:correct_images] = false
144
+ @p[:channel_to_correct] = 2
145
+ @p[:in_situ_aberr_corr_channel] = 1
146
+
147
+ pc = Cicada::PositionCorrector.new(@p)
148
+
149
+ corr = pc.generate_in_situ_correction_from_iobjs(load_iobjs)
150
+
151
+ corrected = pc.apply_in_situ_correction(load_iobjs, corr)
152
+
153
+ corrected.map! { |c| pc.apply_scale(c) }
154
+
155
+ averages = [0, 0, 0]
156
+
157
+ averages = corrected.reduce(averages) { |a, e| a.ewise + e.to_a }
158
+
159
+ averages.map! { |e| e/corrected.length }
160
+
161
+ Vector[*averages].norm.should be < 0.5
162
+
163
+ end
164
+
165
+
166
+
167
+
168
+ end
169
+