find_beads 0.9.5-java → 0.9.6-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.
Files changed (3) hide show
  1. data/lib/find_beads/version.rb +1 -1
  2. data/lib/find_beads.rb +167 -153
  3. metadata +13 -20
@@ -26,7 +26,7 @@
26
26
 
27
27
  module FindBeads
28
28
 
29
- VERSION = '0.9.5'
29
+ VERSION = '0.9.6'
30
30
 
31
31
  end
32
32
 
data/lib/find_beads.rb CHANGED
@@ -29,19 +29,16 @@ require 'rimageanalysistools/get_image'
29
29
  require 'rimageanalysistools/image_shortcuts'
30
30
  require 'rimageanalysistools/create_parameters'
31
31
  require 'rimageanalysistools/graythresh'
32
-
33
32
  require 'trollop'
34
-
35
33
  require 'matrix'
36
-
37
- java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageFactory
34
+ require 'ostruct'
35
+ require 'csv'
38
36
 
39
37
  ##
40
38
  # Functions for segmenting and quantifying beads.
41
39
  #
42
40
  module FindBeads
43
-
44
-
41
+ java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageFactory
45
42
  java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageCoordinate
46
43
  java_import Java::edu.stanford.cfuller.imageanalysistools.image.ImageSet
47
44
  java_import Java::edu.stanford.cfuller.imageanalysistools.meta.parameters.ParameterDictionary
@@ -66,30 +63,22 @@ module FindBeads
66
63
  # two-element arrays containing the x,y-coordinates of the centroids of these regions.
67
64
  #
68
65
  def self.centroids(mask)
69
-
70
66
  cens = {}
71
67
 
72
68
  mask.each do |ic|
73
-
74
69
  next unless mask[ic] > 0
75
-
76
70
  cens[mask[ic]] = [0.0, 0.0] unless cens[mask[ic]]
77
-
78
71
  cens[mask[ic]][0] += ic[:x]
79
72
  cens[mask[ic]][1] += ic[:y]
80
-
81
73
  end
82
74
 
83
75
  h = Histogram.new(mask)
84
76
 
85
77
  cens.each_key do |k|
86
-
87
78
  cens[k].map! { |e| e / h.getCounts(k) }
88
-
89
79
  end
90
80
 
91
81
  cens
92
-
93
82
  end
94
83
 
95
84
 
@@ -109,15 +98,10 @@ module FindBeads
109
98
  # the other points were specified)
110
99
  #
111
100
  def self.project_point_onto_vector(origin, point_to_project, point_on_line)
112
-
113
101
  unit_vec = (Vector[*point_on_line] - Vector[*origin]).normalize
114
-
115
102
  proj_vec = Vector[*point_to_project] - Vector[*origin]
116
-
117
103
  projected = unit_vec * (proj_vec.inner_product(unit_vec)) + Vector[*origin]
118
-
119
104
  projected.to_a
120
-
121
105
  end
122
106
 
123
107
 
@@ -132,58 +116,33 @@ module FindBeads
132
116
  # @return [Boolean] whether the point is on the border between two regions.
133
117
  #
134
118
  def self.is_on_voronoi_border?(points, ic)
135
-
136
119
  x = ic[:x]
137
120
  y = ic[:y]
138
-
139
121
  closest_index = 0
140
122
  next_index = 0
141
123
  closest_dist = Float::MAX
142
124
  next_dist = Float::MAX
143
125
 
144
-
145
126
  points.each_with_index do |p, i|
146
-
147
127
  dist = Math.hypot(p[0] - x, p[1] - y)
148
128
 
149
129
  if dist < closest_dist then
150
-
151
130
  next_dist = closest_dist
152
-
153
131
  next_index = closest_index
154
-
155
132
  closest_dist = dist
156
-
157
133
  closest_index = i
158
-
159
134
  elsif dist < next_dist then
160
-
161
135
  next_dist = dist
162
-
163
136
  next_index = i
164
-
165
137
  end
166
-
167
138
  end
168
139
 
169
140
  proj_point = project_point_onto_vector(points[closest_index], [x,y], points[next_index])
170
-
171
141
  next_dist_proj = Math.hypot(points[next_index][0]-proj_point[0], points[next_index][1]-proj_point[1])
172
142
  closest_dist_proj = Math.hypot(points[closest_index][0]-proj_point[0], points[closest_index][1]-proj_point[1])
173
-
174
-
175
143
  cutoff = 1.01*Math.sqrt(2)
176
144
 
177
- if next_dist_proj - closest_dist_proj < cutoff then
178
-
179
- true
180
-
181
- else
182
-
183
- false
184
-
185
- end
186
-
145
+ (next_dist_proj - closest_dist_proj < cutoff)
187
146
  end
188
147
 
189
148
  ##
@@ -199,27 +158,18 @@ module FindBeads
199
158
  # @return [void]
200
159
  #
201
160
  def self.recursive_threshold(p, im, mask)
202
-
203
161
  h = Histogram.new(mask)
204
-
205
162
  changed = false
206
-
207
163
  discard_list = {}
208
164
 
209
165
  1.upto(h.getMaxValue) do |i|
210
-
211
166
  if h.getCounts(i) > p[:max_size].to_i then
212
-
213
167
  values = []
214
168
 
215
169
  im.each do |ic|
216
-
217
170
  if mask[ic] == i then
218
-
219
171
  values << im[ic]
220
-
221
172
  end
222
-
223
173
  end
224
174
 
225
175
  thresh = RImageAnalysisTools.graythresh(values)
@@ -227,46 +177,27 @@ module FindBeads
227
177
  im.each do |ic|
228
178
 
229
179
  if mask[ic] == i and im[ic] <= thresh then
230
-
231
180
  mask[ic] = 0
232
-
233
181
  changed = true
234
-
235
182
  end
236
-
237
183
  end
238
-
239
184
  elsif h.getCounts(i) > 0 and h.getCounts(i) < p[:min_size].to_i then
240
-
241
185
  discard_list[i] = true
242
-
243
186
  end
244
-
245
187
  end
246
188
 
247
189
  im.each do |ic|
248
-
249
190
  if discard_list[im[ic]] then
250
-
251
191
  mask[ic] = 0
252
-
253
192
  changed = true
254
-
255
193
  end
256
-
257
194
  end
258
195
 
259
-
260
196
  if changed then
261
-
262
197
  lf = LabelFilter.new
263
-
264
198
  lf.apply(mask)
265
-
266
199
  recursive_threshold(p, im, mask)
267
-
268
200
  end
269
-
270
201
  end
271
202
 
272
203
  ##
@@ -276,9 +207,7 @@ module FindBeads
276
207
  # @param [Fixnum] rad the radius of the bead in units of pixels.
277
208
  #
278
209
  def self.calculate_max_size_from_radius(rad)
279
-
280
210
  ((rad+1)**2 * 3.2).to_i
281
-
282
211
  end
283
212
 
284
213
  ##
@@ -291,9 +220,7 @@ module FindBeads
291
220
  # @param @see #calculate_max_size_from_radius
292
221
  #
293
222
  def self.calculate_min_size_from_radius(rad)
294
-
295
223
  (0.96* (rad+1)**2).to_i
296
-
297
224
  end
298
225
 
299
226
  ##
@@ -301,9 +228,11 @@ module FindBeads
301
228
  #
302
229
  # @param [Image] im the image to segment
303
230
  # @param [Hash] opts a hash of commandline arguments.
231
+ # @param [OpenStruct, #centroids=] centroid_storage an optional object
232
+ # to which the bead centroids will be fed using #centroids=
233
+ # default=nil, causes them not to be set
304
234
  #
305
- def self.mask_from_image(im, opts)
306
-
235
+ def self.mask_from_image(im, opts, centroid_storage = nil)
307
236
  seg_ch = nil
308
237
  seg_pl = nil
309
238
  rad = nil
@@ -320,49 +249,36 @@ module FindBeads
320
249
 
321
250
  min_size = calculate_min_size_from_radius(rad)
322
251
  max_size = calculate_max_size_from_radius(rad)
323
-
324
- sizes = ImageCoordinate.cloneCoord(im.getDimensionSizes)
325
252
 
253
+ sizes = ImageCoordinate.cloneCoord(im.getDimensionSizes)
326
254
  sizes[:c] = 1
327
255
  sizes[:z] = 1
328
256
 
329
257
  im0 = ImageCoordinate.createCoordXYZCT(0,0,0,0,0)
330
-
331
258
  im0[:c] = seg_ch
332
259
  im0[:z] = seg_pl
333
260
 
334
261
  to_seg = im.subImage(sizes, im0).writableInstance
335
-
336
262
  p = RImageAnalysisTools.create_parameter_dictionary(min_size: min_size, max_size: max_size)
337
-
338
263
  im_cp = ImageFactory.create_writable(to_seg)
339
264
 
340
265
  mstf = MaximumSeparabilityThresholdingFilter.new
341
-
342
266
  lf = LabelFilter.new
343
-
344
267
  saf = SizeAbsoluteFilter.new
345
268
 
346
269
  filters = []
347
-
348
270
  filters << mstf
349
-
350
271
  filters << lf
351
272
 
352
273
  filters.each do |f|
353
-
354
274
  f.setParameters(p)
355
275
  f.setReferenceImage(im_cp)
356
276
  f.apply(to_seg)
357
-
358
277
  end
359
278
 
360
279
  recursive_threshold(p, im_cp, to_seg)
361
-
362
280
  saf.setParameters(p)
363
-
364
281
  saf.apply(to_seg)
365
-
366
282
  cens = centroids(to_seg)
367
283
 
368
284
  final_mask = ImageFactory.create_writable(to_seg)
@@ -370,51 +286,156 @@ module FindBeads
370
286
  radius = rad
371
287
 
372
288
  final_mask.each do |ic|
373
-
374
289
  final_mask[ic] = 0
375
-
376
290
  end
377
291
 
378
292
  final_mask.each do |ic|
379
-
380
293
  x = ic[:x]
381
294
  y = ic[:y]
382
295
 
383
296
  cens.each_key do |k|
384
-
385
297
  if Math.hypot(cens[k][0] - x, cens[k][1] - y) <= radius then
386
-
387
298
  final_mask[ic] = k
388
-
389
299
  end
390
-
391
300
  end
392
-
393
301
  end
394
302
 
395
-
396
303
  final_mask.each do |ic|
397
-
398
304
  next unless final_mask[ic] > 0
399
305
 
400
306
  if is_on_voronoi_border?(cens.values, ic) then
401
-
402
307
  final_mask[ic] = 0
403
-
404
308
  end
405
-
406
309
  end
407
310
 
408
311
  lf.apply(final_mask)
409
-
410
312
  saf.apply(final_mask)
411
-
412
313
  lf.apply(final_mask)
413
314
 
315
+ remapped_cens = {}
316
+ cen_coord = ImageCoordinate[0,0,0,0,0]
317
+
318
+ cens.each do |k, cen|
319
+ cen_coord[:x] = cen[0]
320
+ cen_coord[:y] = cen[1]
321
+ val = final_mask[cen_coord]
322
+
323
+ if val > 0 then
324
+ remapped_cens[val] = cen
325
+ end
326
+ end
327
+
328
+ cen_coord.recycle
329
+
330
+ if centroid_storage then
331
+ centroid_storage.centroids= remapped_cens
332
+ end
333
+
414
334
  final_mask
415
335
 
416
336
  end
417
337
 
338
+ ##
339
+ # Swaps the x and y coordinates of an ImageCoordinate in place relative to a supplied origin.
340
+ #
341
+ # @param [ImageCoordinate] coord the coordinate whose components will be swapped.
342
+ # @param [Numeric] cen_x the x-coordinate of the origin relative to which the swap will be calculated
343
+ # @param [Numeric] cen_y the y-coordinate of the origin relative to which the swap will be calculated
344
+ #
345
+ # @return [ImageCoordinate] coord
346
+ #
347
+ def self.mirror_coord!(coord, cen_x, cen_y)
348
+ rel_x = coord[:x] - cen_x
349
+ rel_y = coord[:y] - cen_y
350
+ coord[:x] = (rel_y + cen_x).round.to_i
351
+ coord[:y] = (rel_x + cen_y).round.to_i
352
+ coord
353
+ end
354
+
355
+ ##
356
+ # Computes the two-channel correlation for a single bead.
357
+ #
358
+ # @param [Image] mask the mask of labeled, segmented beads
359
+ # @param [Image] im the image of the beads (single z-section, multiple channels)
360
+ # @param [Integer] ch0 the (0-based) index of the first channel of the correlation
361
+ # @param [Integer] ch1 the (0-based) index of the second channel of the correlation
362
+ # @param [Array] cen an array containing the x,y coordinates of the centroid of the current bead
363
+ # @param [Integer] id the label of the current bead in the mask
364
+ # @param [Numeric] bead_radius the radius of a bead
365
+ # @param [Boolean] do_normalization whether to normalize to the geometric mean of the autocorrelations of the two channels
366
+ #
367
+ # @return [Hash] a hash containing components :norm_corr (the background-subtracted, normalized correlation), :corr (the
368
+ # non-normalized, non-subtracted two-channel correlation), and :bg_corr (the non-normalized background
369
+ # two-channel correlation, calculated by rotating one channel of the bead 90 degrees around the bead centroid)
370
+ #
371
+ def self.compute_single_bead_correlation(mask, im, ch0, ch1, cen, id, bead_radius, do_normalization)
372
+ normalization = if do_normalization then
373
+ auto_00 = compute_single_bead_correlation(mask, im, ch0, ch0, cen, id, bead_radius, false)[:norm_corr]
374
+ auto_11 = compute_single_bead_correlation(mask, im, ch1, ch1, cen, id, bead_radius, false)[:norm_corr]
375
+ Math.sqrt(auto_00 * auto_11)*(auto_00.abs/auto_00)
376
+ else
377
+ 1
378
+ end
379
+
380
+ box_lower = ImageCoordinate[cen[0] - bead_radius - 1, cen[1] - bead_radius - 1,0,0,0]
381
+ box_upper = ImageCoordinate[cen[0] + bead_radius + 2, cen[1] + bead_radius + 2,1,1,1]
382
+ mask.setBoxOfInterest(box_lower, box_upper)
383
+
384
+ ch_coord = ImageCoordinate[0,0,0,0,0]
385
+ corr_sum = 0
386
+ bg_sum = 0
387
+ count = 0
388
+ bg_count = 0
389
+
390
+ mask.each do |ic|
391
+ next unless mask[ic] == id
392
+ ch_coord.setCoord(ic)
393
+ ch_coord[:c] = ch0
394
+ val = im[ch_coord]
395
+ ch_coord[:c] = ch1
396
+ corr_sum += val * im[ch_coord]
397
+ count += 1
398
+ mirror_coord!(ch_coord, cen[0], cen[1])
399
+ if im.inBounds(ch_coord) then
400
+ bg_sum += val * im[ch_coord]
401
+ bg_count += 1
402
+ end
403
+ end
404
+
405
+ mask.clearBoxOfInterest
406
+ box_lower.recycle
407
+ box_upper.recycle
408
+ ch_coord.recycle
409
+
410
+ {norm_corr: (corr_sum/count - bg_sum/bg_count)/normalization , corr: corr_sum/count, bg_corr: bg_sum/bg_count}
411
+
412
+ end
413
+
414
+ ##
415
+ # Runs a correlation analysis between two channels of the image. This is done by directly
416
+ # computing the correlation for each bead and then computing an effective background by
417
+ # swapping the x- and y- axes of one channel within each bead.
418
+ #
419
+ # @param [Image] mask the mask of the beads
420
+ # @param [Integer] ch0 the first channel for the correlation
421
+ # @param [Integer] ch1 the second channel for the correlation
422
+ # @param [Hash] cens a hash mapping bead labels in the mask to the centroids of the beads
423
+ # @param [Hash] opts the options hash
424
+ #
425
+ # @return [Hash] a hash mapping :norm_corr, :corr, and :bg_corr to a hash mapping bead labels to their measurements
426
+ #
427
+ def self.compute_correlation(mask, im, ch0, ch1, cens, opts)
428
+ result = {norm_corr: {}, corr: {}, bg_corr: {}}
429
+ cens.each do |id, cen|
430
+ corr_for_bead = compute_single_bead_correlation(mask, im, ch0, ch1, cen, id, opts[:beadradius], true)
431
+ result[:norm_corr][id] = corr_for_bead[:norm_corr]
432
+ result[:corr][id] = corr_for_bead[:corr]
433
+ result[:bg_corr][id] = corr_for_bead[:bg_corr]
434
+ end
435
+ result
436
+ end
437
+
438
+
418
439
  ##
419
440
  # Writes the output data and mask to files.
420
441
  #
@@ -423,36 +444,44 @@ module FindBeads
423
444
  # @param [Image] mask the mask to write
424
445
  #
425
446
  def self.write_output(fn_orig, quant_str, mask)
426
-
427
447
  mask_dir = "output_mask"
428
-
429
448
  quant_dir = "quantification"
430
-
431
449
  mask_ext = "_mask.ome.tif"
432
-
433
450
  quant_ext = "_quant.txt"
434
451
 
435
452
  dir = File.dirname(fn_orig)
436
-
437
453
  base = File.basename(fn_orig)
438
-
439
454
  base = base.gsub(".ome.tif", "")
440
-
441
455
  mask_dir = File.expand_path(mask_dir, dir)
442
-
443
456
  quant_dir = File.expand_path(quant_dir, dir)
444
-
445
457
  Dir.mkdir(mask_dir) unless Dir.exist?(mask_dir)
446
458
  Dir.mkdir(quant_dir) unless Dir.exist?(quant_dir)
447
459
 
448
460
  mask.writeToFile(File.expand_path(base + mask_ext, mask_dir))
449
461
 
450
462
  File.open(File.expand_path(base + quant_ext, quant_dir), 'w') do |f|
451
-
452
463
  f.puts(quant_str)
453
-
454
464
  end
465
+ end
455
466
 
467
+ ##
468
+ # Organizes the correlation data into a csv string where each row is a bead and each column is a measurement.
469
+ # Also creates a header row.
470
+ #
471
+ # @param [Hash] corr_output a hash formatted like the output of FindBeads.compute_correlation
472
+ #
473
+ # @return [String] a string containing the same data in csv format.
474
+ #
475
+ def self.format_correlation_output(corr_output)
476
+ header_row = ["bead index", "normalized, corrected correlation", "correlation", "background correlation"]
477
+
478
+ CSV.generate do |csv|
479
+ csv << header_row
480
+
481
+ corr_output[:corr].each_key do |id|
482
+ csv << [id, corr_output[:norm_corr][id], corr_output[:corr][id], corr_output[:bg_corr][id]]
483
+ end
484
+ end
456
485
  end
457
486
 
458
487
  ##
@@ -462,60 +491,60 @@ module FindBeads
462
491
  # @param [Hash] opts a hash of command line options.
463
492
  #
464
493
  def self.process_file(fn, opts=nil)
465
-
466
494
  puts "processing #{fn}"
467
495
 
468
- im = RImageAnalysisTools.get_image(fn)
469
-
470
- mask = mask_from_image(im, opts)
496
+ cens = if opts and opts[:correlation_channels] then
497
+ OpenStruct.new
498
+ else
499
+ nil
500
+ end
471
501
 
502
+ im = RImageAnalysisTools.get_image(fn)
503
+ mask = mask_from_image(im, opts, cens)
472
504
  proj = Java::edu.stanford.cfuller.imageanalysistools.frontend.MaximumIntensityProjection.projectImage(im)
473
-
474
505
  ims = proj.splitChannels
475
-
476
506
  is = ImageSet.new(ParameterDictionary.emptyDictionary)
477
507
 
478
508
  ims.each do |imc|
479
-
480
509
  is.addImageWithImage(imc)
481
-
482
510
  end
483
511
 
484
- met = IntensityPerPixelMetric.new
485
-
486
- q = met.quantify(mask, is)
487
-
488
- outdat = Java::edu.stanford.cfuller.imageanalysistools.frontend.LocalAnalysis.generateDataOutputString(q, nil)
512
+ outdat = if opts and opts[:correlation_channels] then
513
+ q = compute_correlation(mask, proj, opts[:correlation_channels][0], opts[:correlation_channels][1], cens.centroids, opts)
514
+ format_correlation_output(q)
515
+ else
516
+ met = IntensityPerPixelMetric.new
517
+ q = met.quantify(mask, is)
518
+ Java::edu.stanford.cfuller.imageanalysistools.frontend.LocalAnalysis.generateDataOutputString(q, nil)
519
+ end
489
520
 
490
521
  write_output(fn, outdat, mask)
491
-
492
522
  end
493
523
 
494
524
  ##
495
525
  # Runs the bead finding on a file or directory, and grabs options from the command line.
496
526
  #
497
527
  def self.run_find_beads
498
-
499
528
  opts = Trollop::options do
500
-
501
529
  opt :dir, "Directory to process", :type => :string
502
530
  opt :file, "File to process", :type => :string
503
531
  opt :segchannel, "Channel on which to segment (0-indexed)", :type => :integer, :default => DEFAULT_SEG_CH
504
532
  opt :segplane, "Plane on which to segment (0-indexed)", :type => :integer, :default => DEFAULT_SEG_PL
505
533
  opt :max_threads, "Maximum number of paralell execution threads", :type => :integer, :default => DEFAULT_THREADS
506
534
  opt :beadradius, "Radius of the bead in pixels", :type => :float, :default => DEFAULT_BEAD_RADIUS
535
+ opt :correlation_channels, "Runs correlation between the specified two comma separated channels", :type => :string, :default => nil
536
+ end
507
537
 
538
+ if opts[:correlation_channels] then
539
+ opts[:correlation_channels] = opts[:correlation_channels].gsub("\s+", "").split(",").map(&:to_i)
508
540
  end
509
541
 
510
542
  if opts[:dir] then
511
-
512
543
  fod = opts[:dir]
513
-
514
544
  sleep_time_s = 0.5
515
545
  threads = []
516
546
 
517
547
  Dir.foreach(fod) do |f|
518
-
519
548
  until threads.count { |t| t.alive? } < opts[:max_threads] do
520
549
  sleep sleep_time_s
521
550
  end
@@ -523,39 +552,24 @@ module FindBeads
523
552
  fn = File.expand_path(f, fod)
524
553
 
525
554
  if File.file?(fn) then
526
-
527
555
  begin
528
-
529
556
  threads << Thread.new do
530
-
531
557
  process_file(fn, opts)
532
-
533
558
  end
534
559
 
535
560
  rescue Exception => e
536
-
537
561
  puts "Unable to process #{fn}:"
538
562
  puts e.message
539
-
540
563
  end
541
-
542
564
  end
543
-
544
565
  end
545
566
 
546
567
  threads.each { |t| t.join }
547
-
548
568
  end
549
569
 
550
-
551
-
552
570
  if opts[:file] then
553
-
554
571
  process_file(opts[:file], opts)
555
-
556
572
  end
557
-
558
573
  end
559
-
560
574
  end
561
575
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: find_beads
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.5
4
+ version: 0.9.6
5
5
  prerelease:
6
6
  platform: java
7
7
  authors:
@@ -15,17 +15,15 @@ dependencies:
15
15
  name: rimageanalysistools
16
16
  version_requirements: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">="
18
+ - - '>='
19
19
  - !ruby/object:Gem::Version
20
- version: !binary |-
21
- MA==
20
+ version: '0'
22
21
  none: false
23
22
  requirement: !ruby/object:Gem::Requirement
24
23
  requirements:
25
- - - ">="
24
+ - - '>='
26
25
  - !ruby/object:Gem::Version
27
- version: !binary |-
28
- MA==
26
+ version: '0'
29
27
  none: false
30
28
  prerelease: false
31
29
  type: :runtime
@@ -33,17 +31,15 @@ dependencies:
33
31
  name: trollop
34
32
  version_requirements: !ruby/object:Gem::Requirement
35
33
  requirements:
36
- - - ">="
34
+ - - '>='
37
35
  - !ruby/object:Gem::Version
38
- version: !binary |-
39
- MA==
36
+ version: '0'
40
37
  none: false
41
38
  requirement: !ruby/object:Gem::Requirement
42
39
  requirements:
43
- - - ">="
40
+ - - '>='
44
41
  - !ruby/object:Gem::Version
45
- version: !binary |-
46
- MA==
42
+ version: '0'
47
43
  none: false
48
44
  prerelease: false
49
45
  type: :runtime
@@ -67,17 +63,15 @@ require_paths:
67
63
  - lib
68
64
  required_ruby_version: !ruby/object:Gem::Requirement
69
65
  requirements:
70
- - - ">="
66
+ - - '>='
71
67
  - !ruby/object:Gem::Version
72
- version: !binary |-
73
- MA==
68
+ version: '0'
74
69
  none: false
75
70
  required_rubygems_version: !ruby/object:Gem::Requirement
76
71
  requirements:
77
- - - ">="
72
+ - - '>='
78
73
  - !ruby/object:Gem::Version
79
- version: !binary |-
80
- MA==
74
+ version: '0'
81
75
  none: false
82
76
  requirements:
83
77
  - jruby
@@ -87,4 +81,3 @@ signing_key:
87
81
  specification_version: 3
88
82
  summary: Segments and quantifies beads in microscopy images
89
83
  test_files: []
90
- has_rdoc: