iroki_lib 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,28 @@
1
+ # Copyright 2016 Ryan Moore
2
+ # Contact: moorer@udel.edu
3
+ #
4
+ # This file is part of IrokiLib.
5
+ #
6
+ # IrokiLib is free software: you can redistribute it and/or modify it
7
+ # under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # IrokiLib is distributed in the hope that it will be useful, but
12
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with IrokiLib. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module IrokiLib
20
+ module CoreExt
21
+ module Hash
22
+ def duplicate_values? hash
23
+ values = hash.values
24
+ values.count != 1 && values.count != values.uniq.count
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ module IrokiLib
2
+ module CoreExt
3
+ module String
4
+
5
+ def hex? str
6
+ str.match(/^#[0-9A-Fa-f]{6}$/)
7
+ end
8
+
9
+ def clean str
10
+ str.gsub(/[^\p{Alnum}_]+/, "_").gsub(/_+/, "_")
11
+ end
12
+
13
+ def has_color? name
14
+ name.match(/(.*)(\[&!color="#[0-9A-Fa-f]{6}"\])/)
15
+ end
16
+ alias already_checked? has_color?
17
+
18
+ def clean_name name
19
+ if name.nil?
20
+ nil
21
+ else
22
+ if (match = has_color? name)
23
+ name = match[1]
24
+ color = match[2]
25
+
26
+ clean(name) + color
27
+ else
28
+ clean(name)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,231 @@
1
+ # Copyright 2016 Ryan Moore
2
+ # Contact: moorer@udel.edu
3
+ #
4
+ # This file is part of IrokiLib.
5
+ #
6
+ # IrokiLib is free software: you can redistribute it and/or modify it
7
+ # under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # IrokiLib is distributed in the hope that it will be useful, but
12
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with IrokiLib. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ require "bio"
20
+
21
+ module IrokiLib
22
+ module Main
23
+ def self.main(color_branches: nil,
24
+ color_taxa_names: nil,
25
+ exact: nil,
26
+ remove_bootstraps_below: nil,
27
+ color_map_f: nil,
28
+ name_map_f: nil,
29
+ auto_color: nil,
30
+ display_auto_color_options: nil,
31
+ newick_f: nil,
32
+ out_f: nil)
33
+
34
+
35
+
36
+ if display_auto_color_options
37
+ puts "\n Choices for --auto-color ..."
38
+ print " basic, basic_light, basic_dark, funky, funky_light, " +
39
+ "funky_dark\n\n"
40
+ exit
41
+ end
42
+
43
+ auto_color_options =
44
+ ["basic", "basic_light", "basic_dark",
45
+ "funky", "funky_light", "funky_dark",]
46
+
47
+
48
+ if(!auto_color.nil? &&
49
+ !auto_color_options.include?(auto_color))
50
+ puts "\n Choices for --auto-color ..."
51
+ print " basic, basic_light, basic_dark, funky, funky_light, " +
52
+ "funky_dark\n\n"
53
+
54
+ Trollop.die :auto_color, "#{auto_color} is not a valid option"
55
+ end
56
+
57
+ case auto_color
58
+ when nil
59
+ auto_colors = BASIC
60
+ when "basic"
61
+ auto_colors = BASIC
62
+ when "basic_light"
63
+ auto_colors = BASIC_LIGHT
64
+ when "basic_dark"
65
+ auto_colors = BASIC_DARK
66
+ when "funky"
67
+ auto_colors = FUNKY
68
+ when "funky_light"
69
+ auto_colors = FUNKY_LIGHT
70
+ when "funky_dark"
71
+ auto_colors = FUNKY_DARK
72
+ end
73
+
74
+ # color_branches = true
75
+ # color_taxa_names = true
76
+ # exact = false
77
+ # color_map_f = "test_files/500.patterns_with_name_map"
78
+ # name_map_f = "test_files/500.name_map"
79
+ # ARGV[0] = "test_files/500.zetas.tre"
80
+ newick = check_file newick_f, :newick
81
+
82
+ color_f = nil
83
+ if color_taxa_names || color_branches
84
+ color_f = check_file color_map_f, :color_map_f
85
+ end
86
+
87
+ check = color_map_f &&
88
+ !color_taxa_names &&
89
+ !color_branches
90
+
91
+ abort_if check,
92
+ "A pattern file was provided without specifying " +
93
+ "any coloring options"
94
+
95
+
96
+ # if passed color other than one defined, return black
97
+ black = "#000000"
98
+ red = "#FF1300"
99
+ yellow = "#FFD700"
100
+ blue = "#5311FF"
101
+ green = "#00FF2C"
102
+ color2hex = Hash.new "[&!color=\"#{black}\"]"
103
+ color2hex.merge!({
104
+ "black" => "[&!color=\"#{black}\"]",
105
+ "red" => "[&!color=\"#{red}\"]",
106
+ "blue" => "[&!color=\"#{blue}\"]",
107
+ "yellow" => "[&!color=\"#{yellow}\"]",
108
+ "green" => "[&!color=\"#{green}\"]"
109
+ })
110
+
111
+ # check if complementary colors requested
112
+ if color_f
113
+ colors = Set.new
114
+ File.open(color_f).each_line do |line|
115
+ _, color = line.chomp.split "\t"
116
+
117
+ colors << color
118
+ end
119
+
120
+ auto_color = colors.all? { |color| color.match /\A[0-4]\Z/ }
121
+ end
122
+
123
+ # get the color patterns
124
+ if color_f
125
+ patterns = {}
126
+ File.open(color_f).each_line do |line|
127
+ pattern, color = line.chomp.split "\t"
128
+
129
+ color = "black" if color.nil? || color.empty?
130
+
131
+ if name_map_f || color_taxa_names || color_branches
132
+ pattern = clean_name pattern
133
+ end
134
+
135
+ if !exact
136
+ pattern = Regexp.new pattern
137
+ end
138
+
139
+ if auto_color
140
+ patterns[pattern] = "[&!color=\"#{auto_colors[color]}\"]"
141
+ else
142
+ if hex? color
143
+ patterns[pattern] = "[&!color=\"#{color}\"]"
144
+ else
145
+ patterns[pattern] = color2hex[color]
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+ treeio = Bio::FlatFile.open(Bio::Newick, newick)
152
+
153
+ newick = treeio.next_entry
154
+ tree = newick.tree
155
+
156
+ # do this first cos everything after will use the "new" names
157
+ if name_map_f
158
+ name_map = parse_name_map name_map_f
159
+
160
+ tree.collect_node! do |node|
161
+ unless node.name.nil?
162
+ # every name is cleaned no matter what
163
+ node.name = clean node.name
164
+
165
+ if name_map.has_key?(node.name)
166
+ node.name = name_map[node.name]
167
+ end
168
+ end
169
+
170
+ node
171
+ end
172
+ end
173
+
174
+ if color_taxa_names
175
+ leaves = tree.leaves.map do |n|
176
+ name = clean_name n.name
177
+
178
+ if (color = add_color_to_leaf_branch(patterns, name, exact))
179
+ name + color
180
+ else
181
+ name
182
+ end
183
+ end
184
+ else
185
+ leaves = tree.leaves.map { |n| clean_name n.name }
186
+ end
187
+
188
+ if color_branches
189
+ total = tree.nodes.count
190
+ n = 0
191
+ tree.collect_node! do |node|
192
+ n += 1
193
+ $stderr.printf "Node: %d of %d\r", n, total
194
+
195
+ color_nodes patterns, tree, node, exact
196
+ end
197
+ end
198
+ $stderr.puts
199
+
200
+ if remove_bootstraps_below
201
+ tree.collect_node! do |node|
202
+ if node.bootstrap && node.bootstrap < remove_bootstraps_below
203
+ node.bootstrap_string = ""
204
+ end
205
+
206
+ node
207
+ end
208
+ end
209
+
210
+
211
+
212
+ tre_str = tree.newick(indent: false).gsub(/'/, '')
213
+
214
+ nexus = "#NEXUS
215
+ begin taxa;
216
+ dimensions ntax=#{leaves.count};
217
+ taxlabels
218
+ #{leaves.join("\n")}
219
+ ;
220
+ end;
221
+
222
+ begin trees;
223
+ tree tree_1 = [&R] #{tre_str}
224
+ end;
225
+
226
+ #{FIG}"
227
+
228
+ File.open(out_f, "w") { |f| f.puts nexus }
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,103 @@
1
+ # Copyright 2016 Ryan Moore
2
+ # Contact: moorer@udel.edu
3
+ #
4
+ # This file is part of IrokiLib.
5
+ #
6
+ # IrokiLib is free software: you can redistribute it and/or modify it
7
+ # under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # IrokiLib is distributed in the hope that it will be useful, but
12
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with IrokiLib. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module IrokiLib
20
+ module Utils
21
+ include AbortIf
22
+ include IrokiLib::CoreExt::String
23
+
24
+ def leaf? tree, node
25
+ tree.children(node).empty?
26
+ end
27
+
28
+ def add_color_to_leaf_branch patterns, node, exact
29
+ num_matches = 0
30
+ color = nil
31
+ already_matched = false
32
+
33
+ if exact # treat patterns as string matching
34
+ node_s = node.to_s
35
+ if patterns.has_key? node_s
36
+ color = patterns[node_s]
37
+
38
+ return color
39
+ else
40
+ return nil
41
+ end
42
+ else
43
+ node_s = node.to_s
44
+
45
+ patterns.each do |pattern, this_color|
46
+ if node_s =~ pattern
47
+ abort_if already_matched,
48
+ "Non specific matching for #{node_s}"
49
+
50
+ color = this_color
51
+ already_matched = true
52
+ end
53
+ end
54
+
55
+ return color
56
+ end
57
+ end
58
+
59
+ def get_color node
60
+ begin
61
+ node.name.match(/\[&!color="#[0-9A-Fa-f]{6}"\]/)[0]
62
+ rescue NoMethodError => e
63
+ nil
64
+ end
65
+ end
66
+
67
+ def color_nodes patterns, tree, node, exact
68
+ # # check if it needs color, if so set the color
69
+ # color = add_color_to_leaf_branch patterns, node, exact
70
+
71
+ # clean the name no matter what
72
+ node.name = clean_name node.name
73
+
74
+ # if its a leaf that hasnt been checked & needs color
75
+ if leaf?(tree, node) && !already_checked?(node.name) # && color
76
+ # check if it needs color, if so set the color
77
+
78
+ # NOTE: this was originally before cleaning the node name a
79
+ # couple lines up, does it matter that it is after?
80
+ color = add_color_to_leaf_branch patterns, node, exact
81
+
82
+ # add color to the name
83
+ node.name = node.name + color if color
84
+ elsif !leaf?(tree, node)
85
+ children = tree.children(node) # get the children
86
+ children_colors = []
87
+ children.each do |child|
88
+ # recurse to color the child if needed
89
+ color_nodes patterns, tree, child, exact
90
+ children_colors << get_color(child) # add color of the child
91
+ end
92
+
93
+ # if all the children have the same color
94
+ if children_colors.uniq.count == 1
95
+ # set the branch node to only the color name
96
+ node.name = children_colors[0]
97
+ end
98
+ end
99
+
100
+ return node
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,21 @@
1
+ # Copyright 2016 Ryan Moore
2
+ # Contact: moorer@udel.edu
3
+ #
4
+ # This file is part of IrokiLib.
5
+ #
6
+ # IrokiLib is free software: you can redistribute it and/or modify it
7
+ # under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # IrokiLib is distributed in the hope that it will be useful, but
12
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with IrokiLib. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module IrokiLib
20
+ VERSION = "0.0.1"
21
+ end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iroki_lib
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Moore
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-04-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.6'
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 4.6.4
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '4.6'
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 4.6.4
75
+ - !ruby/object:Gem::Dependency
76
+ name: yard
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.8.7.6
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.8.7.6
89
+ - !ruby/object:Gem::Dependency
90
+ name: coveralls
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.8.11
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 0.8.11
103
+ - !ruby/object:Gem::Dependency
104
+ name: abort_if
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 0.1.0
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.1.0
117
+ - !ruby/object:Gem::Dependency
118
+ name: bio
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '1.5'
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '1.5'
131
+ description: Library code for Iroki, a phylogenetic tree customization program.
132
+ email:
133
+ - moorer@udel.edu
134
+ executables: []
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - ".gitignore"
139
+ - ".rspec"
140
+ - ".ruby-version"
141
+ - ".travis.yml"
142
+ - CODE_OF_CONDUCT.md
143
+ - COPYING
144
+ - Gemfile
145
+ - Guardfile
146
+ - README.md
147
+ - Rakefile
148
+ - bin/console
149
+ - bin/setup
150
+ - iroki_lib.gemspec
151
+ - lib/iroki_lib.rb
152
+ - lib/iroki_lib/color/color.rb
153
+ - lib/iroki_lib/const/const.rb
154
+ - lib/iroki_lib/core_ext/file/file.rb
155
+ - lib/iroki_lib/core_ext/hash/hash.rb
156
+ - lib/iroki_lib/core_ext/string/string.rb
157
+ - lib/iroki_lib/main/main.rb
158
+ - lib/iroki_lib/utils/utils.rb
159
+ - lib/iroki_lib/version.rb
160
+ homepage: https://github.com/mooreryan/iroki_lib
161
+ licenses:
162
+ - 'GPLv3: http://www.gnu.org/licenses/gpl.txt'
163
+ metadata: {}
164
+ post_install_message:
165
+ rdoc_options: []
166
+ require_paths:
167
+ - lib
168
+ required_ruby_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: 2.2.4
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: '0'
178
+ requirements: []
179
+ rubyforge_project:
180
+ rubygems_version: 2.4.8
181
+ signing_key:
182
+ specification_version: 4
183
+ summary: Library code for Iroki, a phylogenetic tree customization program.
184
+ test_files: []
185
+ has_rdoc: