cicada 0.9.4-java → 0.9.5-java

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