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.
@@ -25,7 +25,4 @@
25
25
  #++
26
26
 
27
27
  require 'rimageanalysistools'
28
-
29
28
  require 'cicada/cicada_main'
30
-
31
-
@@ -24,52 +24,34 @@
24
24
  # * ***** END LICENSE BLOCK ***** */
25
25
  #++
26
26
 
27
- require 'cicada/correction/position_corrector'
28
27
  require 'rimageanalysistools'
29
28
  require 'rimageanalysistools/image_shortcuts'
30
29
  require 'rimageanalysistools/create_parameters'
31
30
 
31
+ require 'cicada/correction/position_corrector'
32
+
32
33
  java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageFactory
33
34
 
34
35
  module Cicada
35
-
36
36
  class AberrationMap
37
37
 
38
38
  def self.generate(c, bounds_x, bounds_y, params)
39
-
40
39
  size_x = bounds_x[1] - bounds_x[0]
41
40
  size_y = bounds_y[1] - bounds_y[0]
42
-
43
41
  ab_map = ImageFactory.createWritable(ImageCoordinate[size_x, size_y, 3,1, 1], 0.0)
44
-
45
42
  ab_map.setBoxOfInterest(ImageCoordinate[0,0,0,0,0], ImageCoordinate[size_x, size_y, 1, 1, 1])
46
-
47
43
  ic2 = ImageCoordinate[0,0,0,0,0]
48
-
49
44
  dist_conv = [params[:pixelsize_nm].to_f, params[:pixelsize_nm].to_f, params[:z_sectionsize_nm].to_f]
50
45
 
51
46
  ab_map.each do |ic|
52
-
53
47
  ic2.setCoord(ic)
54
-
55
48
  corr = c.correct_position(ic[:x] + bounds_x[0], ic[:y] + bounds_y[0])
56
-
57
49
  0.upto(2) do |dim|
58
-
59
50
  ic2[:z] = dim
60
-
61
51
  ab_map[ic2] = corr[dim] * dist_conv[dim]
62
-
63
52
  end
64
-
65
53
  end
66
-
67
54
  ab_map
68
-
69
55
  end
70
-
71
56
  end
72
-
73
57
  end
74
-
75
-
@@ -1,7 +1,7 @@
1
1
  #--
2
2
  # /* ***** BEGIN LICENSE BLOCK *****
3
3
  # *
4
- # * Copyright (c) 2012 Colin J. Fuller
4
+ # * Copyright (c) 2012, 2013 Colin J. Fuller
5
5
  # *
6
6
  # * Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  # * of this software and associated documentation files (the Software), to deal
@@ -24,29 +24,28 @@
24
24
  # * ***** END LICENSE BLOCK ***** */
25
25
  #++
26
26
 
27
- require 'cicada/file_interaction'
28
- require 'cicada/correction/correction'
29
- require 'cicada/correction/position_corrector'
30
- require 'cicada/fitting/p3d_fitter'
31
27
  require 'ostruct'
32
28
  require 'logger'
33
29
 
34
-
30
+ require 'facets/math/sum'
35
31
  require 'rimageanalysistools'
36
32
  require 'rimageanalysistools/image_shortcuts'
37
33
  require 'rimageanalysistools/create_parameters'
34
+ require 'edu/stanford/cfuller/imageanalysistools/resources/common_methods'
38
35
 
39
- require 'facets/math/sum'
36
+ require 'cicada/file_interaction'
37
+ require 'cicada/correction/correction'
38
+ require 'cicada/correction/position_corrector'
39
+ require 'cicada/correction/in_situ_correction'
40
+ require 'cicada/fitting/p3d_fitter'
40
41
 
41
- require 'edu/stanford/cfuller/imageanalysistools/resources/common_methods'
42
+ java_import Java::java.util.concurrent.Executors
42
43
 
43
44
  java_import Java::edu.stanford.cfuller.imageanalysistools.filter.ImageSubtractionFilter
44
45
  java_import Java::edu.stanford.cfuller.imageanalysistools.image.Histogram
45
46
  java_import Java::edu.stanford.cfuller.imageanalysistools.fitting.GaussianImageObject
46
47
  java_import Java::edu.stanford.cfuller.imageanalysistools.meta.parameters.ParameterDictionary
47
48
 
48
- java_import Java::java.util.concurrent.Executors
49
-
50
49
 
51
50
  module Cicada
52
51
 
@@ -75,23 +74,16 @@ module Cicada
75
74
  # containing all the parameters for the analysis.
76
75
  #
77
76
  def initialize(p)
78
-
79
77
  @parameters = p
80
-
81
- @parameters = RImageAnalysisTools.create_parameter_dictionary(p) unless @parameters.is_a? ParameterDictionary
82
-
78
+ #@parameters = RImageAnalysisTools.create_parameter_dictionary(p) unless @parameters.is_a? ParameterDictionary
83
79
  @failures = {r2: 0, edge: 0, sat: 0, sep: 0, err: 0}
84
80
 
85
81
  if @parameters[:darkcurrent_image] then
86
-
87
82
  @dark_image = FileInteraction.load_image(@parameters[:darkcurrent_image])
88
-
89
83
  end
90
84
 
91
85
  set_up_logging
92
-
93
86
  end
94
-
95
87
 
96
88
  ##
97
89
  # Load the position data from disk if this is requested in the specified parameters. If this
@@ -101,18 +93,13 @@ module Cicada
101
93
  # this should be recalculated or if the file cannot be found.
102
94
  #
103
95
  def load_position_data
104
-
105
96
  if @parameters[:precomputed_position_data] and FileInteraction.position_file_exists?(@parameters) then
106
-
107
97
  return FileInteraction.read_position_data(@parameters)
108
-
109
98
  end
110
99
 
111
100
  nil
112
-
113
101
  end
114
102
 
115
-
116
103
  ##
117
104
  # Loads the image and mask from an image and mask pair and darkcurrent corrects the
118
105
  # image if specified in the parameters.
@@ -124,23 +111,16 @@ module Cicada
124
111
  # @return [void]
125
112
  #
126
113
  def load_and_dark_correct_image(im_set)
127
-
128
114
  im_set.image = FileInteraction.load_image(im_set.image_fn)
129
115
  im_set.mask = FileInteraction.load_image(im_set.mask_fn)
130
116
 
131
117
  if (@dark_image) then
132
-
133
118
  im_set.image = im_set.image.writableInstance
134
-
135
119
  isf = ImageSubtractionFilter.new
136
-
137
120
  isf.setSubtractPlanarImage(true)
138
-
139
121
  isf.setReferenceImage(@dark_image)
140
122
  isf.apply(im_set.image)
141
-
142
- end
143
-
123
+ end
144
124
  end
145
125
 
146
126
  ##
@@ -152,23 +132,14 @@ module Cicada
152
132
  # @return [void]
153
133
  #
154
134
  def submit_single_object(obj, queue)
155
-
156
135
  queue.submit do
157
-
158
136
  @logger.debug { "Processing object #{obj.getLabel}" }
159
-
160
137
  begin
161
-
162
138
  obj.fitPosition(@parameters)
163
-
164
139
  rescue => e
165
-
166
140
  logger.error { "error while processing object #{obj.label}: #{e.message}" }
167
-
168
141
  end
169
-
170
142
  end
171
-
172
143
  end
173
144
 
174
145
  ##
@@ -181,56 +152,39 @@ module Cicada
181
152
  # (one per unique greylevel in the mask).
182
153
  #
183
154
  def fit_objects_in_single_image(im_set)
184
-
185
155
  objs = []
186
-
187
156
  load_and_dark_correct_image(im_set)
188
157
 
189
158
  unless im_set.image and im_set.mask then
190
-
191
159
  logger.error { "Unable to process image #{im_set.image_fn}." }
192
-
193
160
  return objs
194
-
195
161
  end
196
162
 
197
163
  h = Histogram.new(im_set.mask)
198
-
199
164
  max_threads = 1
200
-
201
165
  if @parameters[:max_threads] then
202
166
  max_threads = @parameters[:max_threads].to_i
203
167
  end
204
-
205
168
  thread_queue = Executors.newFixedThreadPool(max_threads)
206
169
 
207
170
  1.upto(h.getMaxValue) do |i|
208
-
209
171
  obj = GaussianImageObject.new(i, image_shallow_copy(im_set.mask), image_shallow_copy(im_set.image), ParameterDictionary.new(@parameters))
210
-
211
172
  obj.setImageID(im_set.image_fn)
212
-
213
173
  objs << obj
214
-
215
174
  end
216
175
 
217
176
  objs.each do |obj|
218
-
219
177
  submit_single_object(obj, thread_queue)
220
-
221
178
  end
222
179
 
223
180
  thread_queue.shutdown
224
-
225
181
  until thread_queue.isTerminated do
226
182
  sleep 0.4
227
183
  end
228
184
 
229
185
  objs
230
-
231
186
  end
232
187
 
233
-
234
188
  ##
235
189
  # Checks whether the fitting was successful for a given object according to several criteria:
236
190
  # whether the fitting finished without error, whether the R^2 value of the fit is above the
@@ -243,14 +197,10 @@ module Cicada
243
197
  # @return [Boolean] whether the fitting was successful by all criteria.
244
198
  #
245
199
  def check_fit(to_check)
246
-
247
200
  checks = [:check_r2, :check_edges, :check_saturation, :check_separation, :check_error]
248
-
249
201
  to_check.finishedFitting and checks.all? { |c| self.send(c, to_check) }
250
-
251
202
  end
252
203
 
253
-
254
204
  ##
255
205
  # Checks whether the fit R^2 value is below the specified cutoff.
256
206
  #
@@ -258,25 +208,17 @@ module Cicada
258
208
  # @return [Boolean] whether the fitting was successful by this criterion.
259
209
  #
260
210
  def check_r2(to_check)
261
-
262
211
  return true unless @parameters[:residual_cutoff]
263
212
 
264
213
  to_check.getFitR2ByChannel.each do |r2|
265
-
266
- if r2 < @parameters[:residual_cutoff].to_f then
267
-
214
+ if r2 < @parameters[:residual_cutoff].to_f then
268
215
  @failures[:r2] += 1
269
-
270
216
  @logger.debug { "check failed for object #{to_check.getLabel} R^2 = #{r2}" }
271
-
272
217
  return false
273
-
274
218
  end
275
-
276
219
  end
277
220
 
278
221
  true
279
-
280
222
  end
281
223
 
282
224
  ##
@@ -285,9 +227,7 @@ module Cicada
285
227
  # @return (see #check_r2)
286
228
  #
287
229
  def check_edges(to_check)
288
-
289
230
  eps = 0.1
290
-
291
231
  border_size = @parameters[:im_border_size].to_f
292
232
  z_size = @parameters[:half_z_size].to_f
293
233
 
@@ -296,62 +236,42 @@ module Cicada
296
236
  range_z = z_size...(to_check.getParent.getDimensionSizes[:z] - z_size)
297
237
 
298
238
  to_check.getFitParametersByChannel.each do |fp|
299
-
300
239
  x = fp.getPosition(ImageCoordinate::X)
301
240
  y = fp.getPosition(ImageCoordinate::Y)
302
241
  z = fp.getPosition(ImageCoordinate::Z)
303
-
242
+
304
243
  ok = (range_x.include?(x) and range_y.include?(y) and (range_z.include?(z) or to_check.getParent.getDimensionSizes[:z] == 1))
305
-
306
- unless ok then
307
-
244
+ unless ok then
308
245
  @failures[:edge] += 1
309
-
310
246
  @logger.debug { "check failed for object #{to_check.getLabel} position: #{x}, #{y}, #{z}" }
311
-
312
247
  return false
313
-
314
248
  end
315
-
316
249
  end
317
250
 
318
251
  true
319
-
320
252
  end
321
253
 
322
-
323
254
  ##
324
255
  # Checks whether the camera has saturated in the object.
325
256
  # @param (see #check_fit)
326
257
  # @return (see #check_r2)
327
258
  #
328
259
  def check_saturation(to_check)
329
-
330
260
  if @parameters[:max_greylevel_cutoff] then
331
-
332
261
  to_check.boxImages
333
-
334
262
  cutoff = @parameters[:max_greylevel_cutoff].to_f
335
-
336
263
  to_check.getParent.each do |ic|
337
264
 
338
265
  if to_check.getParent[ic] > cutoff then
339
-
340
266
  to_check.unboxImages
341
267
  @failures[:sat] += 1
342
-
343
268
  @logger.debug { "check failed for object #{to_check.getLabel} greylevel: #{to_check.getParent[ic]}" }
344
-
345
269
  return false
346
-
347
270
  end
348
-
349
271
  end
350
-
351
272
  end
352
-
353
- true
354
273
 
274
+ true
355
275
  end
356
276
 
357
277
  ##
@@ -365,43 +285,30 @@ module Cicada
365
285
  # @return (see #check_r2)
366
286
  #
367
287
  def check_separation(to_check)
368
-
369
288
  if @parameters[:distance_cutoff] then
370
-
371
289
  size_c = to_check.getFitParametersByChannel.size
372
-
373
290
  xy_pixelsize_2 = @parameters[:pixelsize_nm].to_f**2
374
-
375
291
  z_sectionsize_2 = @parameters[:z_sectionsize_nm].to_f**2
376
292
 
377
293
  0.upto(size_c-1) do |ci|
378
294
  0.upto(size_c-1) do |cj|
379
-
380
295
  fp1 = to_check.getFitParametersByChannel.get(ci)
381
296
  fp2 = to_check.getFitParametersByChannel.get(cj)
382
-
383
297
  ijdist = xy_pixelsize_2 * (fp1.getPosition(ImageCoordinate::X) - fp2.getPosition(ImageCoordinate::X))**2 +
384
298
  xy_pixelsize_2 * (fp1.getPosition(ImageCoordinate::Y) - fp2.getPosition(ImageCoordinate::Y))**2 +
385
299
  z_sectionsize_2 * (fp1.getPosition(ImageCoordinate::Z) - fp2.getPosition(ImageCoordinate::Z))**2
386
-
387
300
  ijdist = ijdist**0.5
388
301
 
389
302
  if (ijdist > @parameters[:distance_cutoff].to_f) then
390
-
391
303
  @failures[:sep] += 1
392
304
  @logger.debug { "check failed for object #{to_check.getLabel} with distance: #{ijdist}" }
393
-
394
305
  return false
395
-
396
306
  end
397
-
398
307
  end
399
308
  end
400
-
401
309
  end
402
310
 
403
311
  true
404
-
405
312
  end
406
313
 
407
314
 
@@ -413,33 +320,21 @@ module Cicada
413
320
  # @return (see #check_r2)
414
321
  #
415
322
  def check_error(to_check)
416
-
417
323
  if @parameters[:fit_error_cutoff] then
418
-
419
324
  total_error = 0
420
-
421
325
  to_check.getFitErrorByChannel.each do |d|
422
-
423
326
  total_error += d**2
424
-
425
327
  end
426
-
427
328
  total_error = total_error**0.5
428
329
 
429
330
  if total_error > @parameters[:fit_error_cutoff].to_f or total_error.nan? then
430
-
431
331
  @failures[:err] += 1
432
-
433
332
  @logger.debug { "check failed for object #{to_check.getLabel} with total fitting error: #{total_error}" }
434
-
435
333
  return false
436
-
437
334
  end
438
-
439
335
  end
440
336
 
441
337
  true
442
-
443
338
  end
444
339
 
445
340
  ##
@@ -449,27 +344,17 @@ module Cicada
449
344
  # @return (void)
450
345
  #
451
346
  def set_up_logging
452
-
453
347
  if @parameters[:log_to_file] then
454
-
455
348
  @logger = Logger.new(@parameters[:log_to_file])
456
-
457
349
  else
458
-
459
350
  @logger = Logger.new(STDOUT)
460
-
461
351
  end
462
352
 
463
353
  if @parameters[:log_detailed_messages] then
464
-
465
354
  @logger.sev_threshold = Logger::DEBUG
466
-
467
355
  else
468
-
469
356
  @logger.sev_threshold = Logger::INFO
470
-
471
357
  end
472
-
473
358
  end
474
359
 
475
360
  ##
@@ -480,41 +365,26 @@ module Cicada
480
365
  # successfully fit objects that have passed all checks are included.
481
366
  #
482
367
  def load_or_fit_image_objects
483
-
484
368
  image_objects = load_position_data
485
-
486
369
  unless image_objects then
487
-
488
370
  image_objects = []
489
-
490
371
  to_process = FileInteraction.list_files(@parameters)
491
-
492
- to_process.each do |im_set|
493
-
372
+
373
+ to_process.each do |im_set|
494
374
  objs = fit_objects_in_single_image(im_set)
495
-
496
- objs.each do |o|
497
-
375
+ objs.each do |o|
498
376
  if check_fit(o) then
499
-
500
377
  image_objects << o
501
-
502
378
  end
503
-
504
379
  o.nullifyImages
505
-
506
380
  end
507
-
508
381
  end
509
382
 
510
383
  log_fitting_failures
511
-
512
384
  end
513
385
 
514
386
  puts "number of image objects: #{image_objects.size}"
515
-
516
387
  image_objects
517
-
518
388
  end
519
389
 
520
390
 
@@ -524,15 +394,10 @@ module Cicada
524
394
  # @return [void]
525
395
  #
526
396
  def log_fitting_failures
527
-
528
397
  @logger.info { "fitting failures by type:" }
529
-
530
398
  @failures.each_key do |k|
531
-
532
399
  @logger.info { FAILURE_REASONS[k] + ": " + @failures[k].to_s }
533
-
534
400
  end
535
-
536
401
  end
537
402
 
538
403
 
@@ -545,13 +410,9 @@ module Cicada
545
410
  # @return [List<ImageObject>] the fitted or loaded image objects
546
411
  #
547
412
  def do_and_save_fits
548
-
549
413
  image_objects = load_or_fit_image_objects
550
-
551
414
  FileInteraction.write_position_data(image_objects, @parameters)
552
-
553
415
  image_objects
554
-
555
416
  end
556
417
 
557
418
 
@@ -561,84 +422,57 @@ module Cicada
561
422
  # @return [void]
562
423
  #
563
424
  def go
564
-
565
- image_objects = do_and_save_fits
566
-
425
+ image_objects = do_and_save_fits
567
426
  pc = PositionCorrector.new(@parameters)
568
427
  pc.logger= @logger
569
428
 
570
- c = pc.generate_correction(image_objects)
571
-
572
- tre = 0.0
573
-
574
- if @parameters[:determine_tre] and @parameters[:determine_correction] then
575
-
576
- self.logger.info("calculating tre")
577
-
578
- tre = pc.determine_tre(image_objects)
579
-
580
- c.tre= tre
581
-
582
- else
583
-
584
- tre = c.tre
429
+ if @parameters[:correct_images] then
430
+ c = pc.generate_correction(image_objects)
585
431
 
432
+ tre = 0.0
433
+ if @parameters[:determine_tre] and @parameters[:determine_correction] then
434
+ self.logger.info("calculating tre")
435
+ tre = pc.determine_tre(image_objects)
436
+ c.tre= tre
437
+ else
438
+ tre = c.tre
439
+ end
440
+ c.write_to_file(FileInteraction.correction_filename(@parameters))
586
441
  end
587
-
588
442
 
589
- c.write_to_file(FileInteraction.correction_filename(@parameters))
590
-
591
-
592
-
593
443
  diffs = pc.apply_correction(c, image_objects)
594
-
595
444
  corrected_image_objects = []
596
-
597
445
  image_objects.each do |iobj|
598
-
599
- if iobj.getCorrectionSuccessful then
600
-
446
+ if iobj.getCorrectionSuccessful or not @parameters[:correct_images] then
601
447
  corrected_image_objects << iobj
602
-
603
448
  end
604
-
605
449
  end
606
-
607
450
  FileInteraction.write_position_data(corrected_image_objects, @parameters)
608
-
609
-
610
451
  image_objects = corrected_image_objects
611
-
452
+
612
453
  df= P3DFitter.new(@parameters)
613
-
614
454
  fitparams = df.fit(image_objects, diffs)
615
-
616
455
  @logger.info { "p3d fit parameters: #{fitparams.join(', ')}" }
617
456
 
618
- if @parameters[:in_situ_aberr_corr_basename] and @parameters[:in_situ_aberr_corr_channel] then
619
-
620
- slopes = pc.determine_in_situ_aberration_correction
621
-
622
- vector_diffs = pc.apply_in_situ_aberration_correction(image_objects, slopes)
623
-
457
+ if @parameters[:in_situ_aberr_corr_basename_set] and @parameters[:in_situ_aberr_corr_channel] then
458
+ isc_iobjs = FileInteraction.read_in_situ_corr_data(@parameters)
459
+ isc = InSituCorrection.new(@parameters[:reference_channel].to_i,
460
+ @parameters[:in_situ_aberr_corr_channel].to_i,
461
+ @parameters[:channel_to_correct].to_i,
462
+ isc_iobjs,
463
+ @parameters[:disable_in_situ_corr_constant_offset])
464
+ vector_diffs = isc.apply(image_objects)
465
+ vector_diffs.map! { |v| pc.apply_scale(v) }
624
466
  scalar_diffs = get_scalar_diffs_from_vector(vector_diffs)
625
-
626
467
  corr_fit_params = df.fit(image_objects, scalar_diffs)
627
-
628
- FileInteraction.write_differences(diffs, @parameters)
468
+ FileInteraction.write_differences(scalar_diffs, @parameters)
629
469
 
630
470
  if corr_fit_params then
631
-
632
- @logger.info { "p3d fit parameters after in situ correction: #{fitparams.join(', ') }" }
633
-
471
+ @logger.info { "p3d fit parameters after in situ correction: #{corr_fit_params.join(', ') }" }
634
472
  else
635
-
636
473
  @logger.info { "unable to fit after in situ correction" }
637
-
638
474
  end
639
-
640
475
  end
641
-
642
476
  end
643
477
 
644
478
  ##
@@ -650,16 +484,11 @@ module Cicada
650
484
  # @return [Array] an array of the norms of the vectors provided.
651
485
  #
652
486
  def get_scalar_diffs_from_vector(vector_diffs)
653
-
654
487
  vector_diffs.map do |vd|
655
-
656
488
  Math.sqrt(Math.sum(vd) { |e| e**2 })
657
-
658
489
  end
659
-
660
490
  end
661
491
 
662
-
663
492
  ##
664
493
  # Reads a parameters file and creates a parameter dictionary.
665
494
  #
@@ -668,13 +497,9 @@ module Cicada
668
497
  # @return [ParameterDictionary] the parsed parameters
669
498
  #
670
499
  def self.parse_parameter_file(fn)
671
-
672
500
  java_import Java::edu.stanford.cfuller.imageanalysistools.meta.AnalysisMetadataParserFactory
673
-
674
501
  parser = AnalysisMetadataParserFactory.createParserForFile(fn)
675
-
676
502
  parser.parseFileToParameterDictionary(fn)
677
-
678
503
  end
679
504
 
680
505
  ##
@@ -685,18 +510,11 @@ module Cicada
685
510
  # @return [void]
686
511
  #
687
512
  def self.run_from_parameter_file(fn)
688
-
689
513
  p = parse_parameter_file(fn)
690
-
691
514
  c = new(p)
692
-
693
515
  c.go
694
-
695
- end
696
-
697
-
516
+ end
698
517
  end
699
-
700
518
  end
701
519
 
702
520
  ##
@@ -704,13 +522,5 @@ end
704
522
  # specified on the command line.
705
523
  #
706
524
  if __FILE__ == $0 then
707
-
708
525
  Cicada::CicadaMain.run_from_parameter_file(ARGV[0])
709
-
710
526
  end
711
-
712
-
713
-
714
-
715
-
716
-