find_beads 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.
- data/lib/find_beads/bead_clumps.rb +226 -0
- data/lib/find_beads/version.rb +1 -1
- data/lib/find_beads.rb +18 -1
- metadata +2 -1
@@ -0,0 +1,226 @@
|
|
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
|
+
require 'set'
|
24
|
+
|
25
|
+
module FindBeads
|
26
|
+
|
27
|
+
module BeadClumping
|
28
|
+
|
29
|
+
class Edge
|
30
|
+
|
31
|
+
def initialize(v0, v1)
|
32
|
+
@v0 = v0
|
33
|
+
@v1 = v1
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_accessor :v0, :v1
|
37
|
+
|
38
|
+
def connected_to?(v)
|
39
|
+
v == @v0 or v == @v1
|
40
|
+
end
|
41
|
+
|
42
|
+
def ==(e)
|
43
|
+
(e.v0 == @v0 and e.v1 == @v1) or (e.v1 == @v0 and e.v0 == @v1)
|
44
|
+
end
|
45
|
+
|
46
|
+
alias eql? ==
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
class Vertex
|
51
|
+
|
52
|
+
def initialize(label)
|
53
|
+
@edges = Set.new
|
54
|
+
@label = label
|
55
|
+
end
|
56
|
+
|
57
|
+
def connect(v)
|
58
|
+
e = Edge.new(self, v)
|
59
|
+
@edges << e
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_edge(e)
|
63
|
+
@edges << e if (e.v0 == self or e.v1 == self)
|
64
|
+
end
|
65
|
+
|
66
|
+
def connected_to?(v)
|
67
|
+
e.Edge.new(self, v)
|
68
|
+
@edges.include?(e)
|
69
|
+
end
|
70
|
+
|
71
|
+
def include?(e)
|
72
|
+
@edges.include?(e)
|
73
|
+
end
|
74
|
+
|
75
|
+
def each(&b)
|
76
|
+
@edges.each &b
|
77
|
+
end
|
78
|
+
|
79
|
+
attr_accessor :edges, :label
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
class Graph
|
84
|
+
|
85
|
+
def initialize
|
86
|
+
@vertices = {}
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_vertex(v)
|
90
|
+
@vertices[v.label]= v
|
91
|
+
end
|
92
|
+
|
93
|
+
def new_vertex(l)
|
94
|
+
@vertices[l] = Vertex.new(l)
|
95
|
+
end
|
96
|
+
|
97
|
+
def vertex(label)
|
98
|
+
@vertices[label]
|
99
|
+
end
|
100
|
+
|
101
|
+
def each(&b)
|
102
|
+
@vertices.each &b
|
103
|
+
end
|
104
|
+
|
105
|
+
alias [] vertex
|
106
|
+
|
107
|
+
def direct_connected?(l0, l1)
|
108
|
+
self[l0].connected_to? self[l1]
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_edge_between(l0, l1)
|
112
|
+
self[l0].connect(self[l1])
|
113
|
+
end
|
114
|
+
|
115
|
+
def connected?(l0, l1)
|
116
|
+
sg = get_connected_subgraph(l0)
|
117
|
+
sg.include?(self[l1])
|
118
|
+
end
|
119
|
+
|
120
|
+
def build_connected_dfs(current, visited)
|
121
|
+
|
122
|
+
visited << current
|
123
|
+
|
124
|
+
current.each do |e|
|
125
|
+
|
126
|
+
[:v0, :v1].each do |vi|
|
127
|
+
|
128
|
+
v = e.send(vi)
|
129
|
+
|
130
|
+
if v.nil?
|
131
|
+
|
132
|
+
puts e.inspect
|
133
|
+
|
134
|
+
raise
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
unless visited.include?(v) then
|
139
|
+
|
140
|
+
build_connected_dfs(v, visited)
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
visited
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_connected_subgraph(l0)
|
153
|
+
|
154
|
+
build_connected_dfs(self[l0], Set.new)
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
def self.get_points_within_distance(point, points_list, distance_cutoff)
|
162
|
+
|
163
|
+
close = []
|
164
|
+
|
165
|
+
points_list.each do |p|
|
166
|
+
|
167
|
+
next if point == p
|
168
|
+
|
169
|
+
if (Vector[*point] - Vector[*p]).norm < distance_cutoff then
|
170
|
+
|
171
|
+
close << p
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
close
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.construct_adjacency_graph(points, distance_cutoff)
|
182
|
+
|
183
|
+
g = Graph.new
|
184
|
+
|
185
|
+
points.each_with_index do |p, i|
|
186
|
+
|
187
|
+
g.new_vertex(i+1)
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
points.each_with_index do |p, i|
|
192
|
+
|
193
|
+
close = get_points_within_distance(p, points, distance_cutoff)
|
194
|
+
|
195
|
+
close.each do |c|
|
196
|
+
|
197
|
+
g.add_edge_between(i+1, points.index(c) + 1)
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
g
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
def self.count_disjoint_subgraphs(graph)
|
209
|
+
|
210
|
+
subgraphs = Set.new
|
211
|
+
|
212
|
+
graph.each do |l, vert|
|
213
|
+
|
214
|
+
subgraphs << graph.get_connected_subgraph(l)
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
subgraphs.size
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
|
data/lib/find_beads/version.rb
CHANGED
data/lib/find_beads.rb
CHANGED
@@ -56,6 +56,7 @@ module FindBeads
|
|
56
56
|
DEFAULT_SEG_CH = 2
|
57
57
|
DEFAULT_SEG_PL = 8
|
58
58
|
DEFAULT_BEAD_RADIUS = 24.0
|
59
|
+
DEFAULT_THREADS = 1
|
59
60
|
|
60
61
|
##
|
61
62
|
# Finds the centroid of each unique-greylevel region in a mask.
|
@@ -501,6 +502,7 @@ module FindBeads
|
|
501
502
|
opt :file, "File to process", :type => :string
|
502
503
|
opt :segchannel, "Channel on which to segment (0-indexed)", :type => :integer, :default => DEFAULT_SEG_CH
|
503
504
|
opt :segplane, "Plane on which to segment (0-indexed)", :type => :integer, :default => DEFAULT_SEG_PL
|
505
|
+
opt :max_threads, "Maximum number of paralell execution threads", :type => :integer, :default => DEFAULT_THREADS
|
504
506
|
opt :beadradius, "Radius of the bead in pixels", :type => :float, :default => DEFAULT_BEAD_RADIUS
|
505
507
|
|
506
508
|
end
|
@@ -509,15 +511,26 @@ module FindBeads
|
|
509
511
|
|
510
512
|
fod = opts[:dir]
|
511
513
|
|
514
|
+
sleep_time_s = 0.5
|
515
|
+
threads = []
|
516
|
+
|
512
517
|
Dir.foreach(fod) do |f|
|
513
518
|
|
519
|
+
until threads.count { |t| t.alive? } < opts[:max_threads] do
|
520
|
+
sleep sleep_time_s
|
521
|
+
end
|
522
|
+
|
514
523
|
fn = File.expand_path(f, fod)
|
515
524
|
|
516
525
|
if File.file?(fn) then
|
517
526
|
|
518
527
|
begin
|
519
528
|
|
520
|
-
|
529
|
+
threads << Thread.new do
|
530
|
+
|
531
|
+
process_file(fn, opts)
|
532
|
+
|
533
|
+
end
|
521
534
|
|
522
535
|
rescue Exception => e
|
523
536
|
|
@@ -530,8 +543,12 @@ module FindBeads
|
|
530
543
|
|
531
544
|
end
|
532
545
|
|
546
|
+
threads.each { |t| t.join }
|
547
|
+
|
533
548
|
end
|
534
549
|
|
550
|
+
|
551
|
+
|
535
552
|
if opts[:file] then
|
536
553
|
|
537
554
|
process_file(opts[:file], opts)
|
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.5
|
5
5
|
prerelease:
|
6
6
|
platform: java
|
7
7
|
authors:
|
@@ -56,6 +56,7 @@ extra_rdoc_files: []
|
|
56
56
|
files:
|
57
57
|
- lib/find_beads.rb
|
58
58
|
- lib/find_beads/version.rb
|
59
|
+
- lib/find_beads/bead_clumps.rb
|
59
60
|
- bin/find_beads
|
60
61
|
homepage: http://github.com/cjfuller/find_beads
|
61
62
|
licenses:
|