]> git.donarmstrong.com Git - biopieces.git/blob - bp_bin/order_pairs3
added verbose info to order_pairs3
[biopieces.git] / bp_bin / order_pairs3
1 #!/usr/bin/env ruby
2
3 # Copyright (C) 2007-2012 Martin A. Hansen.
4
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 # http://www.gnu.org/copyleft/gpl.html
20
21 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
22
23 # This program is part of the Biopieces framework (www.biopieces.org).
24
25 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
26
27 # Order records with pair end sequence data.
28
29 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
30
31
32 require 'pp'
33 require 'maasha/biopieces'
34
35 def files_merge(file_in1, file_in2)
36   file_out = "#{file_in1}.merge"
37
38   in1, out1 = Biopieces.open(file_in1, file_out)
39   in2, out2 = Biopieces.open(file_in2)
40
41   record1 = in1.get_entry
42   record2 = in2.get_entry
43
44   while 1
45     if record1 and record2
46       if record1[:SEQ_NAME] < record2[:SEQ_NAME]
47         out1.puts record1
48         record1 = in1.get_entry
49       else
50         out1.puts record2
51         record2 = in2.get_entry
52       end
53     elsif record1
54       out1.puts record1
55       record1 = in1.get_entry
56     elsif record2
57       out1.puts record2
58       record2 = in2.get_entry
59     else
60       break
61     end
62   end
63
64   File.rename(file_out, file_in1)
65   File.delete(file_in2)
66 end
67
68 casts = []
69 casts << {:long=>'block_size', :short=>'b', :type=>'uint', :mandatory=>false, :default=>10_000_000, :allowed=>nil, :disallowed=>'0'}
70
71 options = Biopieces.options_parse(ARGV, casts)
72 tmpdir  = Biopieces.mktmpdir
73
74 Biopieces.open(options[:stream_in], options[:stream_out]) do |input, output|
75   block = []
76   file_count = 0
77   block_size = 0
78
79   input.each do |record|
80     block << record
81
82     block_size += record.to_s.size
83
84     if block_size >= options[:block_size]
85       block.sort_by! { |r| r[:SEQ_NAME] }
86
87       tmpfile = File.join(tmpdir, "#{file_count}.stream")
88
89       $stderr.puts "Writing tmp file #{tmpfile}" if options[:verbose]
90       Biopieces.open(nil, tmpfile) do |tmpin, tmpout|
91         block.each { |r| tmpout.puts r }
92       end
93
94       block       = []
95       block_size  = 0
96       file_count += 1
97     end
98   end
99
100   block.sort_by! { |r| r[:SEQ_NAME] }
101
102   tmpfile = File.join(tmpdir, "#{file_count}.stream")
103
104   $stderr.puts "Writing tmp file #{tmpfile}" if options[:verbose]
105   Biopieces.open(nil, tmpfile) do |tmpin, tmpout|
106     block.each { |r| tmpout.puts r }
107   end
108 end
109
110 while files = Dir.glob(File.join(tmpdir, "*.stream")) and files.size > 1
111   0.step(files.size - 2, 2) do |i|
112     $stderr.puts "Merging files #{files[i]} #{files[i + 1]}" if options[:verbose]
113     files_merge(files[i], files[i + 1])
114   end
115 end
116
117 Biopieces.open(File.join(tmpdir, "0.stream"), options[:stream_out]) do |input, output|
118   record1 = input.get_entry
119   record2 = input.get_entry
120
121   while record1 and record2
122     case record1[:SEQ_NAME]
123     when /^(.+)\/(\d)$/   # Illumina 1.5
124       name1 = $1
125       pair1 = $2.to_i
126     when /^(.+) (\d):/    # Illumina 1.8
127       name1 = $1
128       pair1 = $2.to_i
129     else
130       $stderr.puts "WARNING: Unmatched sequence name: #{record1[:SEQ_NAME]}"
131     end
132
133     case record2[:SEQ_NAME]
134     when /^(.+)\/(\d)$/   # Illumina 1.5
135       name2 = $1
136       pair2 = $2.to_i
137     when /^(.+) (\d):/    # Illumina 1.8
138       name2 = $1
139       pair2 = $2.to_i
140     else
141       $stderr.puts "WARNING: Unmatched sequence name: #{record1[:SEQ_NAME]}"
142     end
143
144     if name1 == name2 and (pair1 - pair2).abs == 1
145       record1[:ORDER] = "paired"
146       record2[:ORDER] = "paired"
147       output.puts record1
148       output.puts record2
149       record1 = input.get_entry
150       record2 = input.get_entry
151     else
152       record1[:ORDER] = "orphan #{pair1}"
153       output.puts record1
154       record1 = record2
155       record2 = input.get_entry
156     end
157   end
158 end
159
160 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
161
162
163 __END__