cicada 0.9.4-java → 0.9.5-java

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.
@@ -0,0 +1,30 @@
1
+ #--
2
+ # Copyright (c) 2013 Colin J. Fuller
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the Software), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ # SOFTWARE.
21
+ #++
22
+
23
+ module Cicada
24
+ ##
25
+ # An error indicating that a position cannot be corrected (possibly due to incomplete
26
+ # coverage in the correction dataset).
27
+ class UnableToCorrectError < StandardError
28
+ end
29
+ end
30
+
@@ -55,28 +55,18 @@ module Cicada
55
55
  # image objects.
56
56
  #
57
57
  def self.serialize_image_objects(image_objects)
58
-
59
58
  doc = REXML::Document.new
60
-
61
-
62
59
  doc.add_element "root"
63
60
 
64
61
  image_objects.each do |iobj|
65
-
66
62
  in_doc = REXML::Document.new iobj.writeToXMLString
67
-
68
63
  in_doc.root.elements[1, "serialized_form"].text = Base64.encode64(Marshal.dump(iobj))
69
-
70
64
  doc.root.add in_doc.elements[1,"image_object"]
71
-
72
65
  end
73
66
 
74
67
  output = ""
75
-
76
68
  doc.write(output, 2)
77
-
78
69
  output
79
-
80
70
  end
81
71
 
82
72
  ##
@@ -89,15 +79,7 @@ module Cicada
89
79
  # @return [ImageObject] the encoded ImageObject
90
80
  #
91
81
  def self.image_object_from_bytes(bin_data)
92
-
93
82
  Marshal.load(bin_data)
94
-
95
- #j_bytes = bin_data.to_java_bytes
96
-
97
- #oi = Java::java.io.ObjectInputStream.new(Java::java.io.ByteArrayInputStream.new(j_bytes))
98
-
99
- #oi.readObject
100
-
101
83
  end
102
84
 
103
85
  ##
@@ -109,23 +91,16 @@ module Cicada
109
91
  # @return [Array<ImageObject>] the image objects encoded in the string
110
92
  #
111
93
  def self.unserialize_image_objects(data)
112
-
113
94
  objs = []
114
-
115
95
  doc = REXML::Document.new data
116
96
 
117
97
  doc.elements.each("*/image_object/serialized_form") do |el|
118
-
119
98
  bin_data = Base64.decode64(el.text)
120
-
121
99
  objs << image_object_from_bytes(bin_data)
122
-
123
100
  end
124
101
 
125
102
  objs
126
-
127
103
  end
128
-
129
104
  end
130
105
 
131
106
 
@@ -133,7 +108,6 @@ module Cicada
133
108
  # A collection of methods for interacting with input and output files for cicada.
134
109
  #
135
110
  class FileInteraction
136
-
137
111
  # parameters required by the methods in this class
138
112
  REQUIRED_PARAMETERS = [:dirname_set, :basename_set, :mask_relative_dirname, :mask_extra_extension, :data_directory, :correction_date, :output_positions_to_directory]
139
113
 
@@ -155,7 +129,6 @@ module Cicada
155
129
  # separator used in the parameter file for multiple files, directories, etc.
156
130
  MULTI_NAME_SEP = ","
157
131
 
158
-
159
132
  ##
160
133
  # Loads an image from the specified file.
161
134
  #
@@ -164,12 +137,9 @@ module Cicada
164
137
  # @return [ReadOnlyImage] the image at the specified filename
165
138
  #
166
139
  def self.load_image(image_fn)
167
-
168
140
  RImageAnalysisTools.get_image(image_fn)
169
-
170
141
  end
171
142
 
172
-
173
143
  ##
174
144
  # Gets the filename to which / from which image object positions will be written /
175
145
  # read from a parameter dictionary.
@@ -182,7 +152,6 @@ module Cicada
182
152
  File.expand_path(p[:basename_set].split(MULTI_NAME_SEP)[0] + POS_XML_EXTENSION, dir)
183
153
  end
184
154
 
185
-
186
155
  ##
187
156
  # Gets the filename to which human-friendly-formatted object positions will be written.
188
157
  #
@@ -195,7 +164,6 @@ module Cicada
195
164
  File.expand_path(p[:basename_set].split(MULTI_NAME_SEP)[0] + POS_HUMAN_EXTENSION, dir)
196
165
  end
197
166
 
198
-
199
167
  ##
200
168
  # Gets the filename of data to use for in situ correction from a parameter dictionary.
201
169
  #
@@ -205,7 +173,7 @@ module Cicada
205
173
  # @return [String] the absolute path to the in situ correction data file
206
174
  #
207
175
  def self.in_situ_corr_data_filename(p)
208
- dir = [:data_directory]
176
+ dir = p[:data_directory]
209
177
  File.expand_path(p[:in_situ_aberr_corr_basename_set].split(MULTI_NAME_SEP)[0] + POS_XML_EXTENSION, dir)
210
178
  end
211
179
 
@@ -229,15 +197,11 @@ module Cicada
229
197
  # @return [Array<ImageObject>] the image objects contained in the file.
230
198
  #
231
199
  def self.unserialize_position_data_file(fn)
232
-
233
200
  data_str = nil
234
-
235
201
  File.open(fn) do |f|
236
202
  data_str = f.read
237
203
  end
238
-
239
204
  Serialization.unserialize_image_objects(data_str)
240
-
241
205
  end
242
206
 
243
207
  ##
@@ -248,11 +212,8 @@ module Cicada
248
212
  # @return [Array<ImageObject>] the image objects associated with the analysis
249
213
  #
250
214
  def self.read_position_data(p)
251
-
252
215
  fn = FileInteraction.position_data_filename(p)
253
-
254
216
  FileInteraction.unserialize_position_data_file(fn)
255
-
256
217
  end
257
218
 
258
219
  ##
@@ -265,11 +226,8 @@ module Cicada
265
226
  # @return [Array<ImageObject>] the image objects for in situ correction associated with the analysis
266
227
  #
267
228
  def self.read_in_situ_corr_data(p)
268
-
269
229
  fn = FileInteraction.in_situ_corr_data_filename(p)
270
-
271
230
  FileInteraction.unserialize_position_data_file(fn)
272
-
273
231
  end
274
232
 
275
233
  ##
@@ -281,35 +239,22 @@ module Cicada
281
239
  # which return each image's filename and its paired mask's filename respectively.
282
240
  #
283
241
  def self.list_files(p)
284
-
285
242
  dirnames = p[:dirname_set].split(MULTI_NAME_SEP)
286
243
  basenames = p[:basename_set].split(MULTI_NAME_SEP)
287
-
288
244
  image_sets = []
289
245
 
290
246
  dirnames.each do |d|
291
-
292
247
  mask_dirname = File.join(d, p[:mask_relative_dirname])
293
-
294
248
  Dir.foreach(d) do |f|
295
-
296
- if basenames.any? { |e| f.match(e) } then
297
-
249
+ if basenames.any? { |e| f.match(e) } then
298
250
  im = File.expand_path(f, d)
299
251
  msk = File.expand_path(f + p[:mask_extra_extension], mask_dirname)
300
-
301
- current = OpenStruct.new(image_fn: im, mask_fn: msk)
302
-
252
+ current = OpenStruct.new(image_fn: im, mask_fn: msk)
303
253
  image_sets << current
304
-
305
254
  end
306
-
307
255
  end
308
-
309
- end
310
-
256
+ end
311
257
  image_sets
312
-
313
258
  end
314
259
 
315
260
  ##
@@ -321,15 +266,10 @@ module Cicada
321
266
  # @return [void]
322
267
  #
323
268
  def self.write_position_data(image_objects, p)
324
-
325
269
  fn = position_data_filename(p)
326
-
327
270
  write_position_data_file(image_objects,fn)
328
-
329
271
  fn2 = human_friendly_position_data_filename(p)
330
-
331
- write_human_friendly_position_data_file(image_objects, fn2)
332
-
272
+ write_human_friendly_position_data_file(image_objects, fn2)
333
273
  end
334
274
 
335
275
  ##
@@ -341,13 +281,9 @@ module Cicada
341
281
  # @return [void]
342
282
  #
343
283
  def self.write_position_data_file(image_objects, fn)
344
-
345
284
  File.open(fn, 'w') do |f|
346
-
347
285
  f.write(Serialization.serialize_image_objects(image_objects))
348
-
349
286
  end
350
-
351
287
  end
352
288
 
353
289
  ##
@@ -357,39 +293,25 @@ module Cicada
357
293
  # @see write_position_data_file
358
294
  #
359
295
  def self.write_human_friendly_position_data_file(image_objects, fn)
360
-
361
296
  CSV.open(fn, 'wb') do |csv|
362
-
363
297
  obj = image_objects[0]
364
-
365
298
  n_channels = obj.getFitParametersByChannel.size
366
-
367
299
  headers = ["object_id"]
368
300
  n_channels.times do |i|
369
301
  headers.concat(["pos#{i}_x", "pos#{i}_y", "pos#{i}_z"])
370
302
  end
371
-
372
303
  csv << headers
373
304
 
374
305
  image_objects.each do |im_obj|
375
-
376
306
  row = [im_obj.getLabel]
377
-
378
307
  n_channels.times do |i|
379
-
380
308
  row.concat(im_obj.getPositionForChannel(i).toArray)
381
-
382
309
  end
383
-
384
310
  csv << row
385
-
386
311
  end
387
-
388
312
  end
389
-
390
313
  end
391
314
 
392
-
393
315
  ##
394
316
  # Gets the filename for storing/reading the correction based upon the supplied parameter dictionary.
395
317
  #
@@ -398,12 +320,9 @@ module Cicada
398
320
  # @return [String] the filename for the correction file.
399
321
  #
400
322
  def self.correction_filename(p)
401
-
402
323
  dir = p[:data_directory]
403
324
  fn = p[:correction_date]
404
-
405
325
  File.expand_path(fn + CORR_XML_EXTENSION, dir)
406
-
407
326
  end
408
327
 
409
328
  ##
@@ -415,25 +334,13 @@ module Cicada
415
334
  # @return [void]
416
335
  #
417
336
  def self.write_differences(diffs, p)
418
-
419
337
  dirname = p[:output_positions_to_directory]
420
-
421
338
  fn = File.expand_path(p[:basename_set] + DIFFS_TXT_EXTENSION, dirname)
422
-
423
339
  File.open(fn, 'w') do |f|
424
-
425
340
  diffs.each do |d|
426
-
427
341
  f.puts(d.to_s)
428
-
429
342
  end
430
-
431
343
  end
432
-
433
344
  end
434
-
435
345
  end
436
-
437
346
  end
438
-
439
-
@@ -23,7 +23,6 @@
23
23
  # * ***** END LICENSE BLOCK ***** */
24
24
 
25
25
  require 'rimageanalysistools'
26
-
27
26
  require 'facets/math/mean'
28
27
  require 'facets/math/std'
29
28
 
@@ -34,7 +33,6 @@ module Cicada
34
33
  # to some distribution.
35
34
  #
36
35
  class DistributionFitter
37
-
38
36
  attr_accessor :parameters
39
37
 
40
38
  ##
@@ -44,9 +42,7 @@ module Cicada
44
42
  # @param [ParameterDictionary, Hash] params a hash-like object containing the parameters
45
43
  #
46
44
  def initialize(params)
47
-
48
45
  @parameters = params
49
-
50
46
  end
51
47
 
52
48
  ##
@@ -63,7 +59,6 @@ module Cicada
63
59
  def fit(objects, diffs)
64
60
  nil
65
61
  end
66
-
67
62
  end
68
63
 
69
64
  ##
@@ -74,24 +69,20 @@ module Cicada
74
69
  #
75
70
  #
76
71
  class P3DObjectiveFunction
77
-
78
72
  include Java::edu.stanford.cfuller.imageanalysistools.fitting.ObjectiveFunction
79
73
 
80
74
  ##
81
75
  # Constructs an empty P3DObjectiveFunction.
82
76
  #
83
77
  def initialize
84
-
85
78
  @r = nil
86
79
  @s = nil
87
80
  @min_prob = nil
88
81
  @use_min_prob = false
89
82
  @should_fit_s = true
90
-
91
83
  end
92
84
 
93
85
  attr_accessor :r, :use_min_prob, :should_fit_s
94
-
95
86
  attr_reader :s, :min_prob
96
87
 
97
88
  ##
@@ -117,10 +108,8 @@ module Cicada
117
108
  # @return [void]
118
109
  #
119
110
  def min_prob=(min_prob)
120
-
121
111
  @min_prob = min_prob
122
112
  @use_min_prob = true
123
-
124
113
  end
125
114
 
126
115
  ##
@@ -133,9 +122,7 @@ module Cicada
133
122
  # @return [Float] the probability density at the given point
134
123
  #
135
124
  def p3d(r, m, s)
136
-
137
125
  (Math.sqrt(2.0/Math::PI)*r/(2*m*s))*(Math.exp(-1 * (m-r)**2/(2*s**2)) - Math.exp( -1 * (m+r)**2/(2*s**2)))
138
-
139
126
  end
140
127
 
141
128
  ##
@@ -148,47 +135,32 @@ module Cicada
148
135
  # @return [Float] the negative log-likelihood of the data.
149
136
  #
150
137
  def evaluate(point)
151
-
152
138
  point = point.toArray unless point.is_a? Array
153
-
154
139
  m = point[0]
155
140
  s = point[1]
156
141
  s = @s unless @should_fit_s
157
-
158
142
  return Float::MAX if (m < 0 or s < 0)
159
143
 
160
144
  r.reduce(0.0) do |sum, ri|
161
-
162
145
  temp_neg_log_p = -1.0*Math.log( p3d(ri, m, s))
163
-
164
- if (@use_min_prob and temp_neg_log_p > @min_prob) then
165
-
146
+ if (@use_min_prob and temp_neg_log_p > @min_prob) then
166
147
  sum + @min_prob
167
-
168
148
  else
169
-
170
149
  sum + temp_neg_log_p
171
-
172
150
  end
173
-
174
- end
175
-
151
+ end
176
152
  end
177
-
178
153
  end
179
-
180
154
 
181
155
  ##
182
156
  # A distribution fitter that fits data to a P3D distribution.
183
157
  #
184
158
  class P3DFitter < DistributionFitter
185
-
186
159
  # parameters required by the methods in this class
187
160
  REQUIRED_PARAMETERS = []
188
161
 
189
162
  # parmeters used but not required in this class or only required for optional functionality
190
163
  OPTIONAL_PARAMETERS = [:robust_p3d_fit_cutoff]
191
-
192
164
 
193
165
  ##
194
166
  # Fits the P3D mean- and standard-deviation-like parameters to the data.
@@ -199,36 +171,22 @@ module Cicada
199
171
  # @return [Array] a two-element array containing the mean- and standard-deviation-like parameters.
200
172
  #
201
173
  def fit(objects, diffs)
202
-
203
174
  of = P3DObjectiveFunction.new
204
-
205
175
  of.r = diffs
206
-
207
176
  tol = 1e-12
208
-
209
177
  nmm = Java::edu.stanford.cfuller.imageanalysistools.fitting.NelderMeadMinimizer.new(tol)
210
-
211
178
  initial_mean = Math.mean(diffs)
212
-
213
179
  initial_width = Math.std(diffs)
214
-
215
180
  starting_point = Java::org.apache.commons.math3.linear.ArrayRealVector.new(2, 0.0)
216
-
217
181
  starting_point.setEntry(0, initial_mean)
218
182
  starting_point.setEntry(1, initial_width)
219
-
220
- if @parameters[:robust_p3d_fit_cutoff] then
221
-
183
+ if @parameters[:robust_p3d_fit_cutoff] then
222
184
  of.min_prob= @parmaeters[:robust_p3d_fit_cutoff].to_f
223
-
224
185
  end
225
186
 
226
187
  nmm.optimize(of, starting_point).toArray.to_a
227
-
228
188
  end
229
-
230
189
  end
231
-
232
190
  end
233
191
 
234
192