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.
- data/lib/find_beads/version.rb +1 -1
- data/lib/find_beads.rb +167 -153
- metadata +13 -20
data/lib/find_beads/version.rb
CHANGED
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
|
-
|
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
|
-
|
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
|
-
|
469
|
-
|
470
|
-
|
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
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
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.
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|