1 | #! /usr/bin/env ruby |
---|
2 | |
---|
3 | #version 2, 2009/01/24 |
---|
4 | |
---|
5 | |
---|
6 | if ARGV.length == 1 |
---|
7 | scale = 1.0 |
---|
8 | elsif ARGV.length == 2 |
---|
9 | scale = ARGV.shift.to_f |
---|
10 | else |
---|
11 | STDERR.puts "USAGE: newick2mafft.rb scale input_tree > output" |
---|
12 | exit |
---|
13 | end |
---|
14 | |
---|
15 | if scale <= 0.0 then |
---|
16 | STDERR.puts "Inappropriate scale, #{scale.to_s}" |
---|
17 | exit |
---|
18 | end |
---|
19 | |
---|
20 | STDERR.puts "scale = " + scale.to_s |
---|
21 | |
---|
22 | infp = File.open( ARGV.shift, "r" ) |
---|
23 | |
---|
24 | tree = "" |
---|
25 | while line = infp.gets |
---|
26 | tree += line.strip |
---|
27 | break if tree =~ /;$/ |
---|
28 | end |
---|
29 | infp.close |
---|
30 | |
---|
31 | |
---|
32 | #tree = tree.gsub( /_.*?:/, ":" ).gsub(/[0-9]\.[0-9]*e-[0-9][0-9]/, "0").gsub(/\[.*?\]/,"").gsub(/ /, "").gsub(/:\-[0-9\.]+/, ":0.0" ) |
---|
33 | tree = tree.gsub( /_.*?:/, ":" ).gsub(/[0-9]\.[0-9]*e-[0-9][0-9]/, "0").gsub(/\[.*?\]/,"").gsub(/ /, "") |
---|
34 | |
---|
35 | |
---|
36 | STDERR.puts "Initial tree = " + tree |
---|
37 | |
---|
38 | def resolve( tree ) |
---|
39 | |
---|
40 | |
---|
41 | while 1 |
---|
42 | # p tree |
---|
43 | tree.sub!( /\,([0-9]+):(\-?[0-9\.]+)\,([0-9]+):(\-?[0-9\.]+)/, ",XXX" ) |
---|
44 | hit1 = $1 |
---|
45 | hit2 = $2 |
---|
46 | hit3 = $3 |
---|
47 | hit4 = $4 |
---|
48 | |
---|
49 | # p hit1 |
---|
50 | # p hit2 |
---|
51 | # p hit3 |
---|
52 | # p hit4 |
---|
53 | |
---|
54 | # puts "introduce XXX" |
---|
55 | # p tree |
---|
56 | |
---|
57 | break unless tree.index(/XXX/) |
---|
58 | |
---|
59 | poshit = tree.index(/XXX/) |
---|
60 | # puts "poshit=" + poshit.to_s |
---|
61 | |
---|
62 | i = poshit |
---|
63 | height = 0 |
---|
64 | while i >= 0 |
---|
65 | break if height == 0 && tree[i..i] == '(' |
---|
66 | if tree[i..i] == ')' then |
---|
67 | height += 1 |
---|
68 | elsif tree[i..i] == '(' then |
---|
69 | height -= 1 |
---|
70 | end |
---|
71 | i -= 1 |
---|
72 | end |
---|
73 | |
---|
74 | poskakko = i |
---|
75 | # puts "poskakko = " + poskakko.to_s |
---|
76 | zenhan = tree[0..poskakko] |
---|
77 | zenhan = "" if poskakko == -1 |
---|
78 | # puts "zenhan = " + zenhan |
---|
79 | |
---|
80 | treelen = tree.length |
---|
81 | tree = zenhan + "(" + tree[poskakko+1..treelen] |
---|
82 | # puts "add (" |
---|
83 | # p tree |
---|
84 | tree.sub!( /XXX/, "#{hit1}:#{hit2}):0,#{hit3}:#{hit4}" ) |
---|
85 | |
---|
86 | # p tree |
---|
87 | end |
---|
88 | |
---|
89 | |
---|
90 | return tree |
---|
91 | |
---|
92 | end |
---|
93 | |
---|
94 | memi = [-1,-1] |
---|
95 | leni = [-1,-1] |
---|
96 | |
---|
97 | while tree.index( /\(/ ) |
---|
98 | |
---|
99 | tree = resolve( tree ) |
---|
100 | |
---|
101 | tree.sub!( /\(([0-9]+):(\-?[0-9\.]+),([0-9]+):(\-?[0-9\.]+)\)/, "XXX" ) |
---|
102 | memi[0] = $1.to_i |
---|
103 | leni[0] = $2.to_f * scale |
---|
104 | memi[1] = $3.to_i |
---|
105 | leni[1] = $4.to_f * scale |
---|
106 | |
---|
107 | if leni[0] > 10 || leni[1] > 10 then |
---|
108 | STDERR.puts "" |
---|
109 | STDERR.puts "Please check the scale of branch length!" |
---|
110 | STDERR.puts "The unit of branch lengths must be 'substitution/site'" |
---|
111 | STDERR.puts "If the unit is 'substition' in your tree, please" |
---|
112 | STDERR.puts "use the scale argument," |
---|
113 | STDERR.puts "% newick2mafft scale in > out" |
---|
114 | STDERR.puts "where scale = 1/(alignment length)" |
---|
115 | STDERR.puts "" |
---|
116 | exit 1 |
---|
117 | end |
---|
118 | |
---|
119 | # STDERR.puts "subtree = " + $& |
---|
120 | |
---|
121 | if memi[1] < memi[0] then |
---|
122 | memi.reverse! |
---|
123 | leni.reverse! |
---|
124 | end |
---|
125 | |
---|
126 | tree.sub!( /XXX/, memi[0].to_s ) |
---|
127 | |
---|
128 | # STDERR.puts "Tree = " + tree |
---|
129 | |
---|
130 | printf( "%5d %5d %10.5f %10.5f\n", memi[0], memi[1], leni[0], leni[1] ) |
---|
131 | |
---|
132 | end |
---|