| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # | 
| 2 |  |  |  |  |  |  | # Copyright (c) 1997-2001 bioperl, Chad Matsalla. All Rights Reserved. | 
| 3 |  |  |  |  |  |  | #           This module is free software; you can redistribute it and/or | 
| 4 |  |  |  |  |  |  | #           modify it under the same terms as Perl itself. | 
| 5 |  |  |  |  |  |  | # | 
| 6 |  |  |  |  |  |  | # Copyright Chad Matsalla | 
| 7 |  |  |  |  |  |  | # | 
| 8 |  |  |  |  |  |  | # You may distribute this module under the same terms as perl itself | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | # POD documentation - main docs before the code | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | =head1 NAME | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | Bio::SeqIO::scf - .scf file input/output stream | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | Do not use this module directly. Use it via the Bio::SeqIO class, see | 
| 19 |  |  |  |  |  |  | L for more information. | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | This object can transform .scf files to and from Bio::Seq::SequenceTrace | 
| 24 |  |  |  |  |  |  | objects.  Mechanisms are present to retrieve trace data from scf | 
| 25 |  |  |  |  |  |  | files. | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | =head1 FEEDBACK | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | =head2 Mailing Lists | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | User feedback is an integral part of the evolution of this and other | 
| 32 |  |  |  |  |  |  | Bioperl modules. Send your comments and suggestions preferably to one | 
| 33 |  |  |  |  |  |  | of the Bioperl mailing lists.  Your participation is much appreciated. | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | bioperl-l@bioperl.org                  - General discussion | 
| 36 |  |  |  |  |  |  | http://bioperl.org/wiki/Mailing_lists  - About the mailing lists | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | =head2 Support | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | Please direct usage questions or support issues to the mailing list: | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | I | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | rather than to the module maintainer directly. Many experienced and | 
| 45 |  |  |  |  |  |  | reponsive experts will be able look at the problem and quickly | 
| 46 |  |  |  |  |  |  | address it. Please include a thorough description of the problem | 
| 47 |  |  |  |  |  |  | with code and data examples if at all possible. | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | =head2 Reporting Bugs | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | Report bugs to the Bioperl bug tracking system to help us keep track | 
| 52 |  |  |  |  |  |  | the bugs and their resolution.  Bug reports can be submitted via | 
| 53 |  |  |  |  |  |  | the web: | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | https://github.com/bioperl/bioperl-live/issues | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | =head1 AUTHOR Chad Matsalla | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | Chad Matsalla | 
| 60 |  |  |  |  |  |  | bioinformatics@dieselwurks.com | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | =head1 CONTRIBUTORS | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | Jason Stajich, jason@bioperl.org | 
| 65 |  |  |  |  |  |  | Tony Cox, avc@sanger.ac.uk | 
| 66 |  |  |  |  |  |  | Heikki Lehvaslaiho, heikki-at-bioperl-dot-org | 
| 67 |  |  |  |  |  |  | Nancy Hansen, nhansen at mail.nih.gov | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | =head1 APPENDIX | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | The rest of the documentation details each of the object | 
| 72 |  |  |  |  |  |  | methods. Internal methods are usually preceded with a _ | 
| 73 |  |  |  |  |  |  |  | 
| 74 |  |  |  |  |  |  | =cut | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | # Let the code begin... | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | package Bio::SeqIO::scf; | 
| 79 | 1 |  |  | 1 |  | 542 | use vars qw($DEFAULT_QUALITY); | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 40 |  | 
| 80 | 1 |  |  | 1 |  | 3 | use strict; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 16 |  | 
| 81 | 1 |  |  | 1 |  | 253 | use Bio::Seq::SeqFactory; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 24 |  | 
| 82 | 1 |  |  | 1 |  | 359 | use Bio::Seq::SequenceTrace; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 49 |  | 
| 83 | 1 |  |  | 1 |  | 352 | use Bio::Annotation::Comment; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 21 |  | 
| 84 | 1 |  |  | 1 |  | 5 | use Dumpvalue; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 31 |  | 
| 85 |  |  |  |  |  |  |  | 
| 86 |  |  |  |  |  |  | my $dumper = Dumpvalue->new(); | 
| 87 |  |  |  |  |  |  | $dumper->veryCompact(1); | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | BEGIN { | 
| 90 | 1 |  |  | 1 |  | 13 | $DEFAULT_QUALITY= 10; | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  |  | 
| 93 | 1 |  |  | 1 |  | 3 | use base qw(Bio::SeqIO); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 360 |  | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | sub _initialize { | 
| 96 | 25 |  |  | 25 |  | 50 | my($self,@args) = @_; | 
| 97 | 25 |  |  |  |  | 70 | $self->SUPER::_initialize(@args); | 
| 98 | 25 | 50 |  |  |  | 232 | if( ! defined $self->sequence_factory ) { | 
| 99 | 25 |  |  |  |  | 87 | $self->sequence_factory(Bio::Seq::SeqFactory->new | 
| 100 |  |  |  |  |  |  | (-verbose => $self->verbose(), | 
| 101 |  |  |  |  |  |  | -type => 'Bio::Seq::Quality')); | 
| 102 |  |  |  |  |  |  | } | 
| 103 | 25 |  |  |  |  | 69 | binmode $self->_fh; # for the Win32/Mac crowds | 
| 104 |  |  |  |  |  |  | } | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | =head2 next_seq() | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | Title   : next_seq() | 
| 109 |  |  |  |  |  |  | Usage   : $scf = $stream->next_seq() | 
| 110 |  |  |  |  |  |  | Function: returns the next scf sequence in the stream | 
| 111 |  |  |  |  |  |  | Returns : a Bio::Seq::SequenceTrace object | 
| 112 |  |  |  |  |  |  | Args    : NONE | 
| 113 |  |  |  |  |  |  | Notes   : Fills the interface specification for SeqIO. | 
| 114 |  |  |  |  |  |  | The SCF specification does not provide for having more then | 
| 115 |  |  |  |  |  |  | one sequence in a given scf. So once the filehandle has been open | 
| 116 |  |  |  |  |  |  | and passed to SeqIO do not expect to run this function more then | 
| 117 |  |  |  |  |  |  | once on a given scf unless you embraced and extended the SCF | 
| 118 |  |  |  |  |  |  | standard.  SCF comments are accessible through the Bio::SeqI | 
| 119 |  |  |  |  |  |  | interface method annotation(). | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | =cut | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | #' | 
| 124 |  |  |  |  |  |  | sub next_seq { | 
| 125 | 15 |  |  | 15 | 1 | 69 | my ($self) = @_; | 
| 126 | 15 |  |  |  |  | 35 | my ($seq, $seqc, $fh, $buffer, $offset, $length, $read_bytes, @read, | 
| 127 |  |  |  |  |  |  | %names); | 
| 128 |  |  |  |  |  |  | # set up a filehandle to read in the scf | 
| 129 | 15 | 50 |  |  |  | 45 | return if $self->{_readfile}; | 
| 130 | 15 |  |  |  |  | 33 | $fh = $self->_fh(); | 
| 131 | 15 | 50 |  |  |  | 40 | unless ($fh) {      # simulate the <> function | 
| 132 | 0 | 0 | 0 |  |  | 0 | if ( !fileno(ARGV) or eof(ARGV) ) { | 
| 133 | 0 | 0 |  |  |  | 0 | return unless my $ARGV = shift; | 
| 134 | 0 | 0 |  |  |  | 0 | open(ARGV,$ARGV) or | 
| 135 |  |  |  |  |  |  | $self->throw("Could not open $ARGV for SCF stream reading $!"); | 
| 136 |  |  |  |  |  |  | } | 
| 137 | 0 |  |  |  |  | 0 | $fh = \*ARGV; | 
| 138 |  |  |  |  |  |  | } | 
| 139 | 15 | 50 |  |  |  | 266 | return unless read $fh, $buffer, 128; # no exception; probably end of file | 
| 140 |  |  |  |  |  |  | # now, the master data structure will be the creator | 
| 141 | 15 |  |  |  |  | 26 | my $creator; | 
| 142 |  |  |  |  |  |  | # he first thing to do is parse the header. This is common | 
| 143 |  |  |  |  |  |  | # among all versions of scf. | 
| 144 |  |  |  |  |  |  | # the rest of the the information is different between the | 
| 145 |  |  |  |  |  |  | # the different versions of scf. | 
| 146 |  |  |  |  |  |  |  | 
| 147 | 15 |  |  |  |  | 57 | $creator->{header} = $self->_get_header($buffer); | 
| 148 | 15 | 100 |  |  |  | 61 | if ($creator->{header}->{'version'} lt "3.00") { | 
| 149 | 4 |  |  |  |  | 22 | $self->debug("scf.pm is working with a version 2 scf.\n"); | 
| 150 |  |  |  |  |  |  | # first gather the trace information | 
| 151 |  |  |  |  |  |  | $length = $creator->{header}->{'samples'} * | 
| 152 | 4 |  |  |  |  | 11 | $creator->{header}->{sample_size}*4; | 
| 153 |  |  |  |  |  |  | $buffer = $self->read_from_buffer($fh, $buffer, $length, | 
| 154 | 4 |  |  |  |  | 20 | $creator->{header}->{samples_offset}); | 
| 155 |  |  |  |  |  |  | # @read = unpack "n$length",$buffer; | 
| 156 |  |  |  |  |  |  | # these traces need to be split | 
| 157 |  |  |  |  |  |  | # returns a reference to a hash | 
| 158 |  |  |  |  |  |  | $creator->{traces} = $self->_parse_v2_traces( | 
| 159 | 4 |  |  |  |  | 19 | $buffer,$creator->{header}->{sample_size}); | 
| 160 |  |  |  |  |  |  | # now go and get the base information | 
| 161 | 4 |  |  |  |  | 17 | $offset = $creator->{header}->{bases_offset}; | 
| 162 | 4 |  |  |  |  | 15 | $length = ($creator->{header}->{bases} * 12); | 
| 163 | 4 |  |  |  |  | 60 | seek $fh,$offset,0; | 
| 164 | 4 |  |  |  |  | 40 | $buffer = $self->read_from_buffer($fh,$buffer,$length,$creator->{header}->{bases_offset}); | 
| 165 |  |  |  |  |  |  | # now distill the information into its fractions. | 
| 166 |  |  |  |  |  |  | # the old way : $self->_set_v2_bases($buffer); | 
| 167 |  |  |  |  |  |  | # ref to an array, ref to a hash, string | 
| 168 |  |  |  |  |  |  | ($creator->{peak_indices}, | 
| 169 |  |  |  |  |  |  | $creator->{qualities}, | 
| 170 |  |  |  |  |  |  | $creator->{sequence}, | 
| 171 | 4 |  |  |  |  | 21 | $creator->{accuracies}) = $self->_parse_v2_bases($buffer); | 
| 172 |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  | } else { | 
| 174 | 11 |  |  |  |  | 54 | $self->debug("scf.pm is working with a version 3+ scf.\n"); | 
| 175 | 11 |  |  |  |  | 18 | my $transformed_read; | 
| 176 | 11 |  |  |  |  | 23 | my $current_read_position = $creator->{header}->{sample_offset}; | 
| 177 |  |  |  |  |  |  | $length = $creator->{header}->{'samples'}* | 
| 178 | 11 |  |  |  |  | 28 | $creator->{header}->{sample_size}; | 
| 179 |  |  |  |  |  |  | # $dumper->dumpValue($creator->{header}); | 
| 180 | 11 |  |  |  |  | 30 | foreach (qw(a c g t)) { | 
| 181 | 44 |  |  |  |  | 350 | $buffer = $self->read_from_buffer($fh,$buffer,$length,$current_read_position); | 
| 182 | 44 |  |  |  |  | 87 | my $byte = "n"; | 
| 183 | 44 | 50 |  |  |  | 162 | if ($creator->{header}->{sample_size} == 1) { | 
| 184 | 0 |  |  |  |  | 0 | $byte = "c"; | 
| 185 |  |  |  |  |  |  | } | 
| 186 | 44 |  |  |  |  | 33128 | @read = unpack "${byte}${length}",$buffer; | 
| 187 |  |  |  |  |  |  | # this little spurt of nonsense is because | 
| 188 |  |  |  |  |  |  | # the trace values are given in the binary | 
| 189 |  |  |  |  |  |  | # file as unsigned shorts but they really | 
| 190 |  |  |  |  |  |  | # are signed deltas. 30000 is an arbitrary number | 
| 191 |  |  |  |  |  |  | # (will there be any traces with a given | 
| 192 |  |  |  |  |  |  | # point greater then 30000? I hope not. | 
| 193 |  |  |  |  |  |  | # once the read is read, it must be changed | 
| 194 |  |  |  |  |  |  | # from relative | 
| 195 | 44 |  |  |  |  | 6450 | foreach (@read) { | 
| 196 | 424924 | 100 |  |  |  | 454504 | if ($_ > 30000) { | 
| 197 | 142333 |  |  |  |  | 97107 | $_ -= 65536; | 
| 198 |  |  |  |  |  |  | } | 
| 199 |  |  |  |  |  |  | } | 
| 200 | 44 |  |  |  |  | 497 | $transformed_read = $self->_delta(\@read,"backward"); | 
| 201 |  |  |  |  |  |  | # For 8-bit data we need to emulate a signed/unsigned | 
| 202 |  |  |  |  |  |  | # cast that is implicit in the C implementations..... | 
| 203 | 44 | 50 |  |  |  | 23310 | if ($creator->{header}->{sample_size} == 1) { | 
| 204 | 0 |  |  |  |  | 0 | foreach (@{$transformed_read}) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 205 | 0 | 0 |  |  |  | 0 | $_ += 256 if ($_ < 0); | 
| 206 |  |  |  |  |  |  | } | 
| 207 |  |  |  |  |  |  | } | 
| 208 | 44 |  |  |  |  | 71 | $current_read_position += $length; | 
| 209 | 44 |  |  |  |  | 77 | $creator->{'traces'}->{$_} = join(' ',@{$transformed_read}); | 
|  | 44 |  |  |  |  | 59013 |  | 
| 210 |  |  |  |  |  |  | } | 
| 211 |  |  |  |  |  |  |  | 
| 212 |  |  |  |  |  |  | # now go and get the peak index information | 
| 213 | 11 |  |  |  |  | 46 | $offset = $creator->{header}->{bases_offset}; | 
| 214 | 11 |  |  |  |  | 36 | $length = ($creator->{header}->{bases} * 4); | 
| 215 | 11 |  |  |  |  | 89 | $buffer = $self->read_from_buffer($fh,$buffer,$length,$offset); | 
| 216 | 11 |  |  |  |  | 51 | $creator->{peak_indices} = $self->_get_v3_peak_indices($buffer); | 
| 217 | 11 |  |  |  |  | 25 | $offset += $length; | 
| 218 |  |  |  |  |  |  | # now go and get the accuracy information | 
| 219 | 11 |  |  |  |  | 34 | $buffer = $self->read_from_buffer($fh,$buffer,$length,$offset); | 
| 220 | 11 |  |  |  |  | 39 | $creator->{accuracies} = $self->_get_v3_base_accuracies($buffer); | 
| 221 |  |  |  |  |  |  | # OK, now go and get the base information. | 
| 222 | 11 |  |  |  |  | 26 | $offset += $length; | 
| 223 | 11 |  |  |  |  | 18 | $length = $creator->{header}->{bases}; | 
| 224 | 11 |  |  |  |  | 28 | $buffer = $self->read_from_buffer($fh,$buffer,$length,$offset); | 
| 225 | 11 |  |  |  |  | 52 | $creator->{'sequence'} = unpack("a$length",$buffer); | 
| 226 |  |  |  |  |  |  | # now, finally, extract the calls from the accuracy information. | 
| 227 |  |  |  |  |  |  | $creator->{qualities} = $self->_get_v3_quality( | 
| 228 | 11 |  |  |  |  | 47 | $creator->{'sequence'},$creator->{accuracies}); | 
| 229 |  |  |  |  |  |  | } | 
| 230 |  |  |  |  |  |  | # now go and get the comment information | 
| 231 | 15 |  |  |  |  | 62 | $offset = $creator->{header}->{comments_offset}; | 
| 232 | 15 |  |  |  |  | 109 | seek $fh,$offset,0; | 
| 233 | 15 |  |  |  |  | 32 | $length = $creator->{header}->{comment_size}; | 
| 234 | 15 |  |  |  |  | 85 | $buffer = $self->read_from_buffer($fh,$buffer,$length); | 
| 235 | 15 |  |  |  |  | 63 | $creator->{comments} = $self->_get_comments($buffer); | 
| 236 | 74 |  |  |  |  | 91 | my @name_comments = grep {$_->tagname() eq 'NAME'} | 
| 237 | 15 |  |  |  |  | 69 | $creator->{comments}->get_Annotations('comment'); | 
| 238 | 15 |  |  |  |  | 24 | my $name_comment; | 
| 239 | 15 | 100 |  |  |  | 39 | if (@name_comments){ | 
| 240 | 7 |  |  |  |  | 20 | $name_comment = $name_comments[0]->as_text(); | 
| 241 | 7 |  |  |  |  | 35 | $name_comment =~ s/^Comment:\s+//; | 
| 242 |  |  |  |  |  |  | } | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | my $swq = Bio::Seq::Quality->new( | 
| 245 |  |  |  |  |  |  | -seq  =>   $creator->{'sequence'}, | 
| 246 | 15 |  |  |  |  | 151 | -qual =>    $creator->{'qualities'}, | 
| 247 |  |  |  |  |  |  | -id   =>    $name_comment | 
| 248 |  |  |  |  |  |  | ); | 
| 249 |  |  |  |  |  |  | my $returner = Bio::Seq::SequenceTrace->new( | 
| 250 |  |  |  |  |  |  | -swq      =>   $swq, | 
| 251 |  |  |  |  |  |  | -trace_a  =>   $creator->{'traces'}->{'a'}, | 
| 252 |  |  |  |  |  |  | -trace_t  =>   $creator->{'traces'}->{'t'}, | 
| 253 |  |  |  |  |  |  | -trace_g  =>   $creator->{'traces'}->{'g'}, | 
| 254 |  |  |  |  |  |  | -trace_c  =>   $creator->{'traces'}->{'c'}, | 
| 255 |  |  |  |  |  |  | -accuracy_a    => $creator->{'accuracies'}->{'a'}, | 
| 256 |  |  |  |  |  |  | -accuracy_t    => $creator->{'accuracies'}->{'t'}, | 
| 257 |  |  |  |  |  |  | -accuracy_g    => $creator->{'accuracies'}->{'g'}, | 
| 258 |  |  |  |  |  |  | -accuracy_c    => $creator->{'accuracies'}->{'c'}, | 
| 259 | 15 |  |  |  |  | 297 | -peak_indices  => $creator->{'peak_indices'} | 
| 260 |  |  |  |  |  |  | ); | 
| 261 |  |  |  |  |  |  |  | 
| 262 | 15 |  |  |  |  | 94 | $returner->annotation($creator->{'comments'}); # add SCF comments | 
| 263 | 15 |  |  |  |  | 31 | $self->{'_readfile'} = 1; | 
| 264 | 15 |  |  |  |  | 2668 | return $returner; | 
| 265 |  |  |  |  |  |  | } | 
| 266 |  |  |  |  |  |  |  | 
| 267 |  |  |  |  |  |  |  | 
| 268 |  |  |  |  |  |  | =head2 _get_v3_quality() | 
| 269 |  |  |  |  |  |  |  | 
| 270 |  |  |  |  |  |  | Title   : _get_v3_quality() | 
| 271 |  |  |  |  |  |  | Usage   : $self->_get_v3_quality() | 
| 272 |  |  |  |  |  |  | Function: Set the base qualities from version3 scf | 
| 273 |  |  |  |  |  |  | Returns : Nothing. Alters $self. | 
| 274 |  |  |  |  |  |  | Args    : None. | 
| 275 |  |  |  |  |  |  | Notes   : | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | =cut | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  | #' | 
| 280 |  |  |  |  |  |  | sub _get_v3_quality { | 
| 281 | 11 |  |  | 11 |  | 29 | my ($self,$sequence,$accuracies) = @_; | 
| 282 | 11 |  |  |  |  | 661 | my @bases = split//,$sequence; | 
| 283 | 11 |  |  |  |  | 11 | my (@qualities,$currbase,$currqual,$counter); | 
| 284 | 11 |  |  |  |  | 47 | for ($counter=0; $counter <= $#bases ; $counter++) { | 
| 285 | 7639 |  |  |  |  | 5388 | $currbase = lc($bases[$counter]); | 
| 286 | 7639 | 100 |  |  |  | 9714 | if ($currbase eq "a") { $currqual = $accuracies->{'a'}->[$counter]; } | 
|  | 1733 | 100 |  |  |  | 1375 |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 287 | 2691 |  |  |  |  | 1970 | elsif ($currbase eq "c") { $currqual = $accuracies->{'c'}->[$counter]; } | 
| 288 | 1227 |  |  |  |  | 970 | elsif ($currbase eq "g") { $currqual = $accuracies->{'g'}->[$counter]; } | 
| 289 | 1988 |  |  |  |  | 1463 | elsif ($currbase eq "t") { $currqual = $accuracies->{'t'}->[$counter]; } | 
| 290 | 0 |  |  |  |  | 0 | else { $currqual = "unknown"; } | 
| 291 | 7639 |  |  |  |  | 9320 | push @qualities,$currqual; | 
| 292 |  |  |  |  |  |  | } | 
| 293 | 11 |  |  |  |  | 6432 | return \@qualities; | 
| 294 |  |  |  |  |  |  | } | 
| 295 |  |  |  |  |  |  |  | 
| 296 |  |  |  |  |  |  | =head2 _get_v3_peak_indices($buffer) | 
| 297 |  |  |  |  |  |  |  | 
| 298 |  |  |  |  |  |  | Title   : _get_v3_peak_indices($buffer) | 
| 299 |  |  |  |  |  |  | Usage   : $self->_get_v3_peak_indices($buffer); | 
| 300 |  |  |  |  |  |  | Function: Unpacks the base accuracies for version3 scf | 
| 301 |  |  |  |  |  |  | Returns : Nothing. Alters $self | 
| 302 |  |  |  |  |  |  | Args    : A scalar containing binary data. | 
| 303 |  |  |  |  |  |  | Notes   : | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  | =cut | 
| 306 |  |  |  |  |  |  |  | 
| 307 |  |  |  |  |  |  | sub _get_v3_peak_indices { | 
| 308 | 11 |  |  | 11 |  | 26 | my ($self,$buffer) = @_; | 
| 309 | 11 |  |  |  |  | 20 | my $length = length($buffer); | 
| 310 | 11 |  |  |  |  | 568 | my @read = unpack "N$length",$buffer; | 
| 311 | 11 |  |  |  |  | 1414 | return join(' ',@read); | 
| 312 |  |  |  |  |  |  | } | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  | =head2 _get_v3_base_accuracies($buffer) | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | Title   : _get_v3_base_accuracies($buffer) | 
| 317 |  |  |  |  |  |  | Usage   : $self->_get_v3_base_accuracies($buffer) | 
| 318 |  |  |  |  |  |  | Function: Set the base accuracies for version 3 scf's | 
| 319 |  |  |  |  |  |  | Returns : Nothing. Alters $self. | 
| 320 |  |  |  |  |  |  | Args    : A scalar containing binary data. | 
| 321 |  |  |  |  |  |  | Notes   : | 
| 322 |  |  |  |  |  |  |  | 
| 323 |  |  |  |  |  |  | =cut | 
| 324 |  |  |  |  |  |  |  | 
| 325 |  |  |  |  |  |  | #' | 
| 326 |  |  |  |  |  |  | sub _get_v3_base_accuracies { | 
| 327 | 11 |  |  | 11 |  | 16 | my ($self,$buffer) = @_; | 
| 328 | 11 |  |  |  |  | 22 | my $length = length($buffer); | 
| 329 | 11 |  |  |  |  | 24 | my $qlength = $length/4; | 
| 330 | 11 |  |  |  |  | 22 | my $offset = 0; | 
| 331 | 11 |  |  |  |  | 10 | my (@qualities,@sorter,$counter,$round,$last_base,$accuracies,$currbase); | 
| 332 | 11 |  |  |  |  | 28 | foreach $currbase (qw(a c g t)) { | 
| 333 | 44 |  |  |  |  | 31 | my @read; | 
| 334 | 44 |  |  |  |  | 54 | $last_base = $offset + $qlength; | 
| 335 | 44 |  |  |  |  | 68 | for (;$offset < $last_base; $offset += $qlength) { | 
| 336 |  |  |  |  |  |  | # a bioperler (perhaps me?) changed the unpack string to include 'n' rather than 'C' | 
| 337 |  |  |  |  |  |  | # on 040322 I think that 'C' is correct. please email chad if you would like to accuse me of being incorrect | 
| 338 | 44 |  |  |  |  | 1529 | @read = unpack "C$qlength", substr($buffer,$offset,$qlength); | 
| 339 | 44 |  |  |  |  | 616 | $accuracies->{$currbase} = \@read; | 
| 340 |  |  |  |  |  |  | } | 
| 341 |  |  |  |  |  |  | } | 
| 342 | 11 |  |  |  |  | 41 | return $accuracies; | 
| 343 |  |  |  |  |  |  | } | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  |  | 
| 346 |  |  |  |  |  |  | =head2 _get_comments($buffer) | 
| 347 |  |  |  |  |  |  |  | 
| 348 |  |  |  |  |  |  | Title   : _get_comments($buffer) | 
| 349 |  |  |  |  |  |  | Usage   : $self->_get_comments($buffer); | 
| 350 |  |  |  |  |  |  | Function: Gather the comments section from the scf and parse it into its | 
| 351 |  |  |  |  |  |  | components. | 
| 352 |  |  |  |  |  |  | Returns : a Bio::Annotation::Collection object | 
| 353 |  |  |  |  |  |  | Args    : The buffer. It is expected that the buffer contains a binary | 
| 354 |  |  |  |  |  |  | string for the comments section of an scf file according to | 
| 355 |  |  |  |  |  |  | the scf file specifications. | 
| 356 |  |  |  |  |  |  | Notes   : | 
| 357 |  |  |  |  |  |  |  | 
| 358 |  |  |  |  |  |  | =cut | 
| 359 |  |  |  |  |  |  |  | 
| 360 |  |  |  |  |  |  | sub _get_comments { | 
| 361 | 15 |  |  | 15 |  | 59 | my ($self,$buffer) = @_; | 
| 362 | 15 |  |  |  |  | 254 | my $comments = Bio::Annotation::Collection->new(); | 
| 363 | 15 |  |  |  |  | 33 | my $size = length($buffer); | 
| 364 | 15 |  |  |  |  | 78 | my $comments_retrieved = unpack "a$size",$buffer; | 
| 365 | 15 |  |  |  |  | 134 | $comments_retrieved =~ s/\0//; | 
| 366 | 15 |  |  |  |  | 98 | my @comments_split = split/\n/,$comments_retrieved; | 
| 367 | 15 | 100 |  |  |  | 41 | if (@comments_split) { | 
| 368 | 13 |  |  |  |  | 56 | foreach (@comments_split) { | 
| 369 | 100 |  |  |  |  | 394 | /(\w+)=(.*)/; | 
| 370 | 100 | 100 | 33 |  |  | 395 | if ($1 && $2) { | 
| 371 | 74 |  |  |  |  | 113 | my ($tagname, $text) = ($1, $2); | 
| 372 | 74 |  |  |  |  | 305 | my $comment_obj = Bio::Annotation::Comment->new( | 
| 373 |  |  |  |  |  |  | -text => $text, | 
| 374 |  |  |  |  |  |  | -tagname => $tagname); | 
| 375 |  |  |  |  |  |  |  | 
| 376 | 74 |  |  |  |  | 176 | $comments->add_Annotation('comment', $comment_obj); | 
| 377 |  |  |  |  |  |  | } | 
| 378 |  |  |  |  |  |  | } | 
| 379 |  |  |  |  |  |  | } | 
| 380 | 15 |  |  |  |  | 36 | $self->{'comments'} = $comments; | 
| 381 | 15 |  |  |  |  | 48 | return $comments; | 
| 382 |  |  |  |  |  |  | } | 
| 383 |  |  |  |  |  |  |  | 
| 384 |  |  |  |  |  |  | =head2 _get_header() | 
| 385 |  |  |  |  |  |  |  | 
| 386 |  |  |  |  |  |  | Title   : _get_header($buffer) | 
| 387 |  |  |  |  |  |  | Usage   : $self->_get_header($buffer); | 
| 388 |  |  |  |  |  |  | Function: Gather the header section from the scf and parse it into its | 
| 389 |  |  |  |  |  |  | components. | 
| 390 |  |  |  |  |  |  | Returns : Reference to a hash containing the header components. | 
| 391 |  |  |  |  |  |  | Args    : The buffer. It is expected that the buffer contains a binary | 
| 392 |  |  |  |  |  |  | string for the header section of an scf file according to the | 
| 393 |  |  |  |  |  |  | scf file specifications. | 
| 394 |  |  |  |  |  |  | Notes   : None. | 
| 395 |  |  |  |  |  |  |  | 
| 396 |  |  |  |  |  |  | =cut | 
| 397 |  |  |  |  |  |  |  | 
| 398 |  |  |  |  |  |  | sub _get_header { | 
| 399 | 15 |  |  | 15 |  | 20 | my ($self,$buffer) = @_; | 
| 400 | 15 |  |  |  |  | 19 | my $header; | 
| 401 |  |  |  |  |  |  | ($header->{'scf'}, | 
| 402 |  |  |  |  |  |  | $header->{'samples'}, | 
| 403 |  |  |  |  |  |  | $header->{'sample_offset'}, | 
| 404 |  |  |  |  |  |  | $header->{'bases'}, | 
| 405 |  |  |  |  |  |  | $header->{'bases_left_clip'}, | 
| 406 |  |  |  |  |  |  | $header->{'bases_right_clip'}, | 
| 407 |  |  |  |  |  |  | $header->{'bases_offset'}, | 
| 408 |  |  |  |  |  |  | $header->{'comment_size'}, | 
| 409 |  |  |  |  |  |  | $header->{'comments_offset'}, | 
| 410 |  |  |  |  |  |  | $header->{'version'}, | 
| 411 |  |  |  |  |  |  | $header->{'sample_size'}, | 
| 412 |  |  |  |  |  |  | $header->{'code_set'}, | 
| 413 | 15 |  |  |  |  | 194 | @{$header->{'header_spare'}} ) = unpack "a4 NNNNNNNN a4 NN N20", $buffer; | 
|  | 15 |  |  |  |  | 82 |  | 
| 414 |  |  |  |  |  |  |  | 
| 415 | 15 |  |  |  |  | 49 | $self->{'header'} = $header; | 
| 416 | 15 |  |  |  |  | 29 | return $header; | 
| 417 |  |  |  |  |  |  | } | 
| 418 |  |  |  |  |  |  |  | 
| 419 |  |  |  |  |  |  | =head2 _parse_v2_bases($buffer) | 
| 420 |  |  |  |  |  |  |  | 
| 421 |  |  |  |  |  |  | Title   : _parse_v2_bases($buffer) | 
| 422 |  |  |  |  |  |  | Usage   : $self->_parse_v2_bases($buffer); | 
| 423 |  |  |  |  |  |  | Function: Gather the bases section from the scf and parse it into its | 
| 424 |  |  |  |  |  |  | components. | 
| 425 |  |  |  |  |  |  | Returns : | 
| 426 |  |  |  |  |  |  | Args    : The buffer. It is expected that the buffer contains a binary | 
| 427 |  |  |  |  |  |  | string for the bases section of an scf file according to the | 
| 428 |  |  |  |  |  |  | scf file specifications. | 
| 429 |  |  |  |  |  |  | Notes   : None. | 
| 430 |  |  |  |  |  |  |  | 
| 431 |  |  |  |  |  |  | =cut | 
| 432 |  |  |  |  |  |  |  | 
| 433 |  |  |  |  |  |  | sub _parse_v2_bases { | 
| 434 | 4 |  |  | 4 |  | 8 | my ($self,$buffer) = @_; | 
| 435 | 4 |  |  |  |  | 7 | my $length = length($buffer); | 
| 436 | 4 |  |  |  |  | 8 | my ($offset2,$currbuff,$currbase,$currqual,$sequence,@qualities,@indices); | 
| 437 | 0 |  |  |  |  | 0 | my (@read,$harvester,$accuracies); | 
| 438 | 4 |  |  |  |  | 16 | for ($offset2=0;$offset2<$length;$offset2+=12) { | 
| 439 | 3734 |  |  |  |  | 10833 | @read = unpack "N C C C C a C3", substr($buffer,$offset2,$length); | 
| 440 | 3734 |  |  |  |  | 3250 | push @indices,$read[0]; | 
| 441 | 3734 |  |  |  |  | 2610 | $currbase = lc($read[5]); | 
| 442 | 3734 | 100 |  |  |  | 5157 | if ($currbase eq "a") { $currqual = $read[1]; } | 
|  | 828 | 100 |  |  |  | 581 |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 443 | 1238 |  |  |  |  | 867 | elsif ($currbase eq "c") { $currqual = $read[2]; } | 
| 444 | 710 |  |  |  |  | 490 | elsif ($currbase eq "g") { $currqual = $read[3]; } | 
| 445 | 958 |  |  |  |  | 662 | elsif ($currbase eq "t") { $currqual = $read[4]; } | 
| 446 | 0 |  |  |  |  | 0 | else { $currqual = "UNKNOWN"; } | 
| 447 | 3734 |  |  |  |  | 2249 | push @{$accuracies->{"a"}},$read[1]; | 
|  | 3734 |  |  |  |  | 3271 |  | 
| 448 | 3734 |  |  |  |  | 2213 | push @{$accuracies->{"c"}},$read[2]; | 
|  | 3734 |  |  |  |  | 2916 |  | 
| 449 | 3734 |  |  |  |  | 2118 | push @{$accuracies->{"g"}},$read[3]; | 
|  | 3734 |  |  |  |  | 2817 |  | 
| 450 | 3734 |  |  |  |  | 2117 | push @{$accuracies->{"t"}},$read[4]; | 
|  | 3734 |  |  |  |  | 2747 |  | 
| 451 |  |  |  |  |  |  |  | 
| 452 | 3734 |  |  |  |  | 2486 | $sequence .= $currbase; | 
| 453 | 3734 |  |  |  |  | 5116 | push @qualities,$currqual; | 
| 454 |  |  |  |  |  |  | } | 
| 455 | 4 |  |  |  |  | 56 | return (\@indices,\@qualities,$sequence,$accuracies) | 
| 456 |  |  |  |  |  |  | } | 
| 457 |  |  |  |  |  |  |  | 
| 458 |  |  |  |  |  |  | =head2 _parse_v2_traces(\@traces_array) | 
| 459 |  |  |  |  |  |  |  | 
| 460 |  |  |  |  |  |  | Title   : _pares_v2_traces(\@traces_array) | 
| 461 |  |  |  |  |  |  | Usage   : $self->_parse_v2_traces(\@traces_array); | 
| 462 |  |  |  |  |  |  | Function: Parses an scf Version2 trace array into its base components. | 
| 463 |  |  |  |  |  |  | Returns : Nothing. Modifies $self. | 
| 464 |  |  |  |  |  |  | Args    : A reference to an array of the unpacked traces section of an | 
| 465 |  |  |  |  |  |  | scf version2 file. | 
| 466 |  |  |  |  |  |  |  | 
| 467 |  |  |  |  |  |  | =cut | 
| 468 |  |  |  |  |  |  |  | 
| 469 |  |  |  |  |  |  | sub _parse_v2_traces { | 
| 470 | 4 |  |  | 4 |  | 7 | my ($self,$buffer,$sample_size) = @_; | 
| 471 | 4 |  |  |  |  | 5 | my $byte; | 
| 472 | 4 | 50 |  |  |  | 9 | if ($sample_size == 1) { $byte = "c"; } | 
|  | 0 |  |  |  |  | 0 |  | 
| 473 | 4 |  |  |  |  | 8 | else { $byte = "n"; } | 
| 474 | 4 |  |  |  |  | 7 | my $length = CORE::length($buffer); | 
| 475 | 4 |  |  |  |  | 15497 | my @read = unpack "${byte}${length}",$buffer; | 
| 476 |  |  |  |  |  |  | # this will be an array to the reference holding the array | 
| 477 | 4 |  |  |  |  | 3363 | my $traces; | 
| 478 | 4 |  |  |  |  | 11 | my $array = 0; | 
| 479 | 4 |  |  |  |  | 53 | for (my $offset2 = 0; $offset2< scalar(@read); $offset2+=4) { | 
| 480 | 46000 |  |  |  |  | 25935 | push @{$traces->{'a'}},$read[$offset2]; | 
|  | 46000 |  |  |  |  | 38324 |  | 
| 481 | 46000 |  |  |  |  | 26567 | push @{$traces->{'c'}},$read[$offset2+1]; | 
|  | 46000 |  |  |  |  | 38220 |  | 
| 482 | 46000 |  |  |  |  | 24949 | push @{$traces->{'g'}},$read[$offset2+3]; | 
|  | 46000 |  |  |  |  | 37541 |  | 
| 483 | 46000 |  |  |  |  | 26236 | push @{$traces->{'t'}},$read[$offset2+2]; | 
|  | 46000 |  |  |  |  | 69101 |  | 
| 484 |  |  |  |  |  |  | } | 
| 485 | 4 |  |  |  |  | 3505 | return $traces; | 
| 486 |  |  |  |  |  |  | } | 
| 487 |  |  |  |  |  |  |  | 
| 488 |  |  |  |  |  |  |  | 
| 489 |  |  |  | 0 | 0 |  | sub get_trace_deprecated_use_the_sequencetrace_object_instead { | 
| 490 |  |  |  |  |  |  | # my ($self,$base_channel,$traces) = @_; | 
| 491 |  |  |  |  |  |  | # $base_channel =~ tr/a-z/A-Z/; | 
| 492 |  |  |  |  |  |  | # if ($base_channel !~ /A|T|G|C/) { | 
| 493 |  |  |  |  |  |  | #   $self->throw("You tried to ask for a base channel that wasn't A,T,G, or C. Ask for one of those next time."); | 
| 494 |  |  |  |  |  |  | ##} elsif ($base_channel) { | 
| 495 |  |  |  |  |  |  | #  my @temp = split(' ',$self->{'traces'}->{$base_channel}); | 
| 496 |  |  |  |  |  |  | #return \@temp; | 
| 497 |  |  |  |  |  |  | #} | 
| 498 |  |  |  |  |  |  | } | 
| 499 |  |  |  |  |  |  |  | 
| 500 |  |  |  |  |  |  | sub _deprecated_get_peak_indices_deprecated_use_the_sequencetrace_object_instead { | 
| 501 | 0 |  |  | 0 |  | 0 | my ($self) = shift; | 
| 502 | 0 |  |  |  |  | 0 | my @temp = split(' ',$self->{'parsed'}->{'peak_indices'}); | 
| 503 | 0 |  |  |  |  | 0 | return \@temp; | 
| 504 |  |  |  |  |  |  | } | 
| 505 |  |  |  |  |  |  |  | 
| 506 |  |  |  |  |  |  |  | 
| 507 |  |  |  |  |  |  | =head2 get_header() | 
| 508 |  |  |  |  |  |  |  | 
| 509 |  |  |  |  |  |  | Title   : get_header() | 
| 510 |  |  |  |  |  |  | Usage   : %header = %{$obj->get_header()}; | 
| 511 |  |  |  |  |  |  | Function: Return the header for this scf. | 
| 512 |  |  |  |  |  |  | Returns : A reference to a hash containing the header for this scf. | 
| 513 |  |  |  |  |  |  | Args    : None. | 
| 514 |  |  |  |  |  |  | Notes   : | 
| 515 |  |  |  |  |  |  |  | 
| 516 |  |  |  |  |  |  | =cut | 
| 517 |  |  |  |  |  |  |  | 
| 518 |  |  |  |  |  |  | sub get_header { | 
| 519 | 1 |  |  | 1 | 1 | 587 | my ($self) = shift; | 
| 520 | 1 |  |  |  |  | 14 | return $self->{'header'}; | 
| 521 |  |  |  |  |  |  | } | 
| 522 |  |  |  |  |  |  |  | 
| 523 |  |  |  |  |  |  | =head2 get_comments() | 
| 524 |  |  |  |  |  |  |  | 
| 525 |  |  |  |  |  |  | Title   : get_comments() | 
| 526 |  |  |  |  |  |  | Usage   : %comments = %{$obj->get_comments()}; | 
| 527 |  |  |  |  |  |  | Function: Return the comments for this scf. | 
| 528 |  |  |  |  |  |  | Returns : A Bio::Annotation::Collection object | 
| 529 |  |  |  |  |  |  | Args    : None. | 
| 530 |  |  |  |  |  |  | Notes   : | 
| 531 |  |  |  |  |  |  |  | 
| 532 |  |  |  |  |  |  | =cut | 
| 533 |  |  |  |  |  |  |  | 
| 534 |  |  |  |  |  |  | sub get_comments { | 
| 535 | 1 |  |  | 1 | 1 | 3 | my ($self) = shift; | 
| 536 | 1 |  |  |  |  | 3 | return $self->{'comments'}; | 
| 537 |  |  |  |  |  |  | } | 
| 538 |  |  |  |  |  |  |  | 
| 539 |  |  |  |  |  |  | sub _dump_traces_outgoing_deprecated_use_the_sequencetrace_object { | 
| 540 | 0 |  |  | 0 |  | 0 | my ($self,$transformed) = @_; | 
| 541 | 0 |  |  |  |  | 0 | my (@sA,@sT,@sG,@sC); | 
| 542 | 0 | 0 |  |  |  | 0 | if ($transformed) { | 
| 543 | 0 |  |  |  |  | 0 | @sA = @{$self->{'text'}->{'t_samples_a'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 544 | 0 |  |  |  |  | 0 | @sC = @{$self->{'text'}->{'t_samples_c'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 545 | 0 |  |  |  |  | 0 | @sG = @{$self->{'text'}->{'t_samples_g'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 546 | 0 |  |  |  |  | 0 | @sT = @{$self->{'text'}->{'t_samples_t'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 547 |  |  |  |  |  |  | } | 
| 548 |  |  |  |  |  |  | else { | 
| 549 | 0 |  |  |  |  | 0 | @sA = @{$self->{'text'}->{'samples_a'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 550 | 0 |  |  |  |  | 0 | @sC = @{$self->{'text'}->{'samples_c'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 551 | 0 |  |  |  |  | 0 | @sG = @{$self->{'text'}->{'samples_g'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 552 | 0 |  |  |  |  | 0 | @sT = @{$self->{'text'}->{'samples_t'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 553 |  |  |  |  |  |  | } | 
| 554 | 0 |  |  |  |  | 0 | print ("Count\ta\tc\tg\tt\n"); | 
| 555 | 0 |  |  |  |  | 0 | for (my $curr=0; $curr < scalar(@sG); $curr++) { | 
| 556 | 0 |  |  |  |  | 0 | print("$curr\t$sA[$curr]\t$sC[$curr]\t$sG[$curr]\t$sT[$curr]\n"); | 
| 557 |  |  |  |  |  |  | } | 
| 558 | 0 |  |  |  |  | 0 | return; | 
| 559 |  |  |  |  |  |  | } | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  | 0 |  |  | sub _dump_traces_incoming_deprecated_use_the_sequencetrace_object { | 
| 562 |  |  |  |  |  |  | # my ($self) = @_; | 
| 563 |  |  |  |  |  |  | # my (@sA,@sT,@sG,@sC); | 
| 564 |  |  |  |  |  |  | # @sA = @{$self->{'traces'}->{'A'}}; | 
| 565 |  |  |  |  |  |  | # @sC = @{$self->{'traces'}->{'C'}}; | 
| 566 |  |  |  |  |  |  | # @sG = @{$self->{'traces'}->{'G'}}; | 
| 567 |  |  |  |  |  |  | # @sT = @{$self->{'traces'}->{'T'}}; | 
| 568 |  |  |  |  |  |  | # @sA = @{$self->get_trace('A')}; | 
| 569 |  |  |  |  |  |  | # @sC = @{$self->get_trace('C')}; | 
| 570 |  |  |  |  |  |  | # @sG = @{$self->get_trace('G')}; | 
| 571 |  |  |  |  |  |  | # @sT = @{$self->get_trace('t')}; | 
| 572 |  |  |  |  |  |  | # print ("Count\ta\tc\tg\tt\n"); | 
| 573 |  |  |  |  |  |  | # for (my $curr=0; $curr < scalar(@sG); $curr++) { | 
| 574 |  |  |  |  |  |  | #   print("$curr\t$sA[$curr]\t$sC[$curr]\t$sG[$curr]\t$sT[$curr]\n"); | 
| 575 |  |  |  |  |  |  | #} | 
| 576 |  |  |  |  |  |  | #return; | 
| 577 |  |  |  |  |  |  | } | 
| 578 |  |  |  |  |  |  |  | 
| 579 |  |  |  |  |  |  | =head2 write_seq | 
| 580 |  |  |  |  |  |  |  | 
| 581 |  |  |  |  |  |  | Title   : write_seq(-target => $swq, ) | 
| 582 |  |  |  |  |  |  | Usage   : $obj->write_seq( | 
| 583 |  |  |  |  |  |  | -target => $swq, | 
| 584 |  |  |  |  |  |  | -version => 2, | 
| 585 |  |  |  |  |  |  | -CONV => "Bioperl-Chads Mighty SCF writer."); | 
| 586 |  |  |  |  |  |  | Function: Write out an scf. | 
| 587 |  |  |  |  |  |  | Returns : Nothing. | 
| 588 |  |  |  |  |  |  | Args    : Requires: a reference to a Bio::Seq::Quality object to form the | 
| 589 |  |  |  |  |  |  | basis for the scf. | 
| 590 |  |  |  |  |  |  | if -version is provided, it should be "2" or "3". A SCF of that | 
| 591 |  |  |  |  |  |  | version will be written. | 
| 592 |  |  |  |  |  |  | Any other arguments are assumed to be comments and are put into | 
| 593 |  |  |  |  |  |  | the comments section of the scf. Read the specifications for scf | 
| 594 |  |  |  |  |  |  | to decide what might be good to put in here. | 
| 595 |  |  |  |  |  |  |  | 
| 596 |  |  |  |  |  |  | Notes   : | 
| 597 |  |  |  |  |  |  | For best results, use a SequenceTrace object. | 
| 598 |  |  |  |  |  |  | The things that you need to write an scf: | 
| 599 |  |  |  |  |  |  | a) sequence | 
| 600 |  |  |  |  |  |  | b) quality | 
| 601 |  |  |  |  |  |  | c) peak indices | 
| 602 |  |  |  |  |  |  | d) traces | 
| 603 |  |  |  |  |  |  | - You _can_ write an scf with just a and b by passing in a | 
| 604 |  |  |  |  |  |  | Bio::Seq::Quality object- false traces will be synthesized | 
| 605 |  |  |  |  |  |  | for you. | 
| 606 |  |  |  |  |  |  |  | 
| 607 |  |  |  |  |  |  | =cut | 
| 608 |  |  |  |  |  |  |  | 
| 609 |  |  |  |  |  |  | sub write_seq { | 
| 610 | 10 |  |  | 10 | 1 | 3525 | my ($self,%args) = @_; | 
| 611 | 10 |  |  |  |  | 35 | my %comments; | 
| 612 | 10 |  |  |  |  | 11 | my ($label,$arg); | 
| 613 | 10 |  |  |  |  | 64 | my ($swq) = $self->_rearrange([qw(TARGET)], %args); | 
| 614 | 10 |  |  |  |  | 21 | my $writer_fodder; | 
| 615 | 10 | 50 |  |  |  | 88 | if (ref($swq) =~ /Bio::Seq::SequenceTrace|Bio::Seq::Quality/) { | 
| 616 | 10 | 100 |  |  |  | 29 | if (ref($swq) eq "Bio::Seq::Quality") { | 
| 617 |  |  |  |  |  |  | # this means that the object *has no trace data* | 
| 618 |  |  |  |  |  |  | # we might as well synthesize some now, ok? | 
| 619 | 2 |  |  |  |  | 15 | $swq = Bio::Seq::SequenceTrace->new( | 
| 620 |  |  |  |  |  |  | -swq     =>   $swq | 
| 621 |  |  |  |  |  |  | ); | 
| 622 |  |  |  |  |  |  | } | 
| 623 |  |  |  |  |  |  | } | 
| 624 |  |  |  |  |  |  | else  { | 
| 625 | 0 |  |  |  |  | 0 | $self->throw("You must pass a Bio::Seq::Quality or a Bio::Seq::SequenceTrace object to write_seq as a parameter named \"target\""); | 
| 626 |  |  |  |  |  |  | } | 
| 627 |  |  |  |  |  |  | # all of the rest of the arguments are comments for the scf | 
| 628 | 10 |  |  |  |  | 50 | foreach $arg (sort keys %args) { | 
| 629 | 23 | 100 |  |  |  | 69 | next if ($arg =~ /target/i); | 
| 630 | 13 |  |  |  |  | 25 | ($label = $arg) =~ s/^\-//; | 
| 631 | 13 |  |  |  |  | 23 | $writer_fodder->{comments}->{$label} = $args{$arg}; | 
| 632 |  |  |  |  |  |  | } | 
| 633 | 10 | 50 |  |  |  | 38 | if (!$comments{'NAME'}) { $comments{'NAME'} = $swq->id(); } | 
|  | 10 |  |  |  |  | 35 |  | 
| 634 |  |  |  |  |  |  | # HA! Bwahahahaha. | 
| 635 | 10 | 50 |  |  |  | 47 | $writer_fodder->{comments}->{'CONV'} = "Bioperl-Chads Mighty SCF writer." unless defined $comments{'CONV'}; | 
| 636 |  |  |  |  |  |  | # now deal with the version of scf they want to write | 
| 637 | 10 | 100 |  |  |  | 24 | if ($writer_fodder->{comments}->{version}) { | 
| 638 | 1 | 50 | 33 |  |  | 9 | if ($writer_fodder->{comments}->{version} != 2 && $writer_fodder->{comments}->{version} != 3) { | 
|  |  | 50 |  |  |  |  |  | 
| 639 | 0 |  |  |  |  | 0 | $self->warn("This module can only write version 2.0 or 3.0 scf's. Writing a version 2.0 scf by default."); | 
| 640 | 0 |  |  |  |  | 0 | $writer_fodder->{header}->{version} = "2.00"; | 
| 641 |  |  |  |  |  |  | } | 
| 642 |  |  |  |  |  |  | elsif ($writer_fodder->{comments}->{'version'} > 2) { | 
| 643 | 0 |  |  |  |  | 0 | $writer_fodder->{header}->{'version'} = "3.00"; | 
| 644 |  |  |  |  |  |  | } | 
| 645 |  |  |  |  |  |  | else { | 
| 646 | 1 |  |  |  |  | 3 | $writer_fodder->{header}->{version} = "2"; | 
| 647 |  |  |  |  |  |  | } | 
| 648 |  |  |  |  |  |  | } | 
| 649 |  |  |  |  |  |  | else { | 
| 650 | 9 |  |  |  |  | 25 | $writer_fodder->{header}->{'version'} = "3.00"; | 
| 651 |  |  |  |  |  |  | } | 
| 652 |  |  |  |  |  |  | # set a few things in the header | 
| 653 | 10 |  |  |  |  | 20 | $writer_fodder->{'header'}->{'magic'} = ".scf"; | 
| 654 | 10 |  |  |  |  | 19 | $writer_fodder->{'header'}->{'sample_size'} = "2"; | 
| 655 | 10 |  |  |  |  | 30 | $writer_fodder->{'header'}->{'bases'} = length($swq->seq()); | 
| 656 | 10 |  |  |  |  | 20 | $writer_fodder->{'header'}->{'bases_left_clip'} = "0"; | 
| 657 | 10 |  |  |  |  | 23 | $writer_fodder->{'header'}->{'bases_right_clip'} = "0"; | 
| 658 | 10 |  |  |  |  | 20 | $writer_fodder->{'header'}->{'sample_size'} = "2"; | 
| 659 | 10 |  |  |  |  | 17 | $writer_fodder->{'header'}->{'code_set'} = "9"; | 
| 660 | 10 |  |  |  |  | 20 | @{$writer_fodder->{'header'}->{'spare'}} = qw(0 0 0 0 0 0 0 0 0 0 | 
|  | 10 |  |  |  |  | 82 |  | 
| 661 |  |  |  |  |  |  | 0 0 0 0 0 0 0 0 0 0); | 
| 662 | 10 |  |  |  |  | 20 | $writer_fodder->{'header'}->{'samples_offset'} = "128"; | 
| 663 | 10 |  |  |  |  | 34 | $writer_fodder->{'header'}->{'samples'} = $swq->trace_length(); | 
| 664 |  |  |  |  |  |  | # create the binary for the comments and file it in writer_fodder | 
| 665 |  |  |  |  |  |  | $writer_fodder->{comments} =  $self->_get_binary_comments( | 
| 666 | 10 |  |  |  |  | 40 | $writer_fodder->{comments}); | 
| 667 |  |  |  |  |  |  | # create the binary and the strings for the traces, bases, | 
| 668 |  |  |  |  |  |  | # offsets (if necessary), and accuracies (if necessary) | 
| 669 |  |  |  |  |  |  | $writer_fodder->{traces} = $self->_get_binary_traces( | 
| 670 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'version'}, | 
| 671 | 10 |  |  |  |  | 54 | $swq,$writer_fodder->{'header'}->{'sample_size'}); | 
| 672 | 10 |  |  |  |  | 24 | my ($b_base_offsets,$b_base_accuracies,$samples_size,$bases_size); | 
| 673 |  |  |  |  |  |  | # | 
| 674 |  |  |  |  |  |  | # version 2 | 
| 675 |  |  |  |  |  |  | # | 
| 676 | 10 | 100 |  |  |  | 78 | if ($writer_fodder->{'header'}->{'version'} == 2) { | 
| 677 |  |  |  |  |  |  | $writer_fodder->{bases} = $self->_get_binary_bases( | 
| 678 |  |  |  |  |  |  | 2, | 
| 679 |  |  |  |  |  |  | $swq, | 
| 680 | 1 |  |  |  |  | 9 | $writer_fodder->{'header'}->{'sample_size'}); | 
| 681 | 1 |  |  |  |  | 4 | $samples_size = CORE::length($writer_fodder->{traces}->{'binary'}); | 
| 682 | 1 |  |  |  |  | 3 | $bases_size = CORE::length($writer_fodder->{bases}->{binary}); | 
| 683 | 1 |  |  |  |  | 7 | $writer_fodder->{'header'}->{'bases_offset'} = 128 + $samples_size; | 
| 684 | 1 |  |  |  |  | 4 | $writer_fodder->{'header'}->{'comments_offset'} = 128 + | 
| 685 |  |  |  |  |  |  | $samples_size + $bases_size; | 
| 686 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'comments_size'} = | 
| 687 | 1 |  |  |  |  | 4 | length($writer_fodder->{'comments'}->{binary}); | 
| 688 | 1 |  |  |  |  | 4 | $writer_fodder->{'header'}->{'private_size'} = "0"; | 
| 689 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'private_offset'} = 128 + | 
| 690 |  |  |  |  |  |  | $samples_size + $bases_size + | 
| 691 | 1 |  |  |  |  | 6 | $writer_fodder->{'header'}->{'comments_size'}; | 
| 692 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'binary'} = | 
| 693 | 1 |  |  |  |  | 6 | $self->_get_binary_header($writer_fodder->{header}); | 
| 694 | 1 | 50 |  |  |  | 8 | $dumper->dumpValue($writer_fodder) if $self->verbose > 0; | 
| 695 | 1 | 50 |  |  |  | 10 | $self->_print ($writer_fodder->{'header'}->{'binary'}) | 
| 696 |  |  |  |  |  |  | or print("Could not write binary header...\n"); | 
| 697 | 1 | 50 |  |  |  | 4 | $self->_print ($writer_fodder->{'traces'}->{'binary'}) | 
| 698 |  |  |  |  |  |  | or print("Could not write binary traces...\n"); | 
| 699 | 1 | 50 |  |  |  | 6 | $self->_print ($writer_fodder->{'bases'}->{'binary'}) | 
| 700 |  |  |  |  |  |  | or print("Could not write binary base structures...\n"); | 
| 701 | 1 | 50 |  |  |  | 5 | $self->_print ($writer_fodder->{'comments'}->{'binary'}) | 
| 702 |  |  |  |  |  |  | or print("Could not write binary comments...\n"); | 
| 703 |  |  |  |  |  |  | } | 
| 704 |  |  |  |  |  |  | else { | 
| 705 |  |  |  |  |  |  | ($writer_fodder->{peak_indices}, | 
| 706 |  |  |  |  |  |  | $writer_fodder->{accuracies}, | 
| 707 |  |  |  |  |  |  | $writer_fodder->{bases}, | 
| 708 |  |  |  |  |  |  | $writer_fodder->{reserved} ) = | 
| 709 |  |  |  |  |  |  | $self->_get_binary_bases( | 
| 710 |  |  |  |  |  |  | 3, | 
| 711 |  |  |  |  |  |  | $swq, | 
| 712 | 9 |  |  |  |  | 64 | $writer_fodder->{'header'}->{'sample_size'} | 
| 713 |  |  |  |  |  |  | ); | 
| 714 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'bases_offset'} = 128 + | 
| 715 | 9 |  |  |  |  | 32 | length($writer_fodder->{'traces'}->{'binary'}); | 
| 716 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'comments_size'} = | 
| 717 | 9 |  |  |  |  | 31 | length($writer_fodder->{'comments'}->{'binary'}); | 
| 718 |  |  |  |  |  |  | # this is: | 
| 719 |  |  |  |  |  |  | # bases_offset + base_offsets + accuracies + called_bases + | 
| 720 |  |  |  |  |  |  | # reserved | 
| 721 | 9 |  |  |  |  | 28 | $writer_fodder->{'header'}->{'private_size'} = "0"; | 
| 722 |  |  |  |  |  |  |  | 
| 723 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'comments_offset'} = | 
| 724 |  |  |  |  |  |  | 128+length($writer_fodder->{'traces'}->{'binary'})+ | 
| 725 |  |  |  |  |  |  | length($writer_fodder->{'peak_indices'}->{'binary'})+ | 
| 726 |  |  |  |  |  |  | length($writer_fodder->{'accuracies'}->{'binary'})+ | 
| 727 |  |  |  |  |  |  | length($writer_fodder->{'bases'}->{'binary'})+ | 
| 728 | 9 |  |  |  |  | 46 | length($writer_fodder->{'reserved'}->{'binary'}); | 
| 729 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'private_offset'} = | 
| 730 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'comments_offset'} + | 
| 731 | 9 |  |  |  |  | 20 | $writer_fodder->{'header'}->{'comments_size'}; | 
| 732 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'spare'}->[1] = | 
| 733 |  |  |  |  |  |  | $writer_fodder->{'header'}->{'comments_offset'} + | 
| 734 | 9 |  |  |  |  | 23 | length($writer_fodder->{'comments'}->{'binary'}); | 
| 735 |  |  |  |  |  |  | $writer_fodder->{header}->{binary} = | 
| 736 | 9 |  |  |  |  | 35 | $self->_get_binary_header($writer_fodder->{header}); | 
| 737 | 9 | 50 |  |  |  | 93 | $self->_print ($writer_fodder->{'header'}->{'binary'}) | 
| 738 |  |  |  |  |  |  | or print("Couldn't write header\n"); | 
| 739 | 9 | 50 |  |  |  | 32 | $self->_print ($writer_fodder->{'traces'}->{'binary'}) | 
| 740 |  |  |  |  |  |  | or print("Couldn't write samples\n"); | 
| 741 | 9 | 50 |  |  |  | 41 | $self->_print ($writer_fodder->{'peak_indices'}->{'binary'}) | 
| 742 |  |  |  |  |  |  | or print("Couldn't write peak offsets\n"); | 
| 743 | 9 | 50 |  |  |  | 35 | $self->_print ($writer_fodder->{'accuracies'}->{'binary'}) | 
| 744 |  |  |  |  |  |  | or print("Couldn't write accuracies\n"); | 
| 745 | 9 | 50 |  |  |  | 31 | $self->_print ($writer_fodder->{'bases'}->{'binary'}) | 
| 746 |  |  |  |  |  |  | or print("Couldn't write called_bases\n"); | 
| 747 | 9 | 50 |  |  |  | 30 | $self->_print ($writer_fodder->{'reserved'}->{'binary'}) | 
| 748 |  |  |  |  |  |  | or print("Couldn't write reserved\n"); | 
| 749 | 9 | 50 |  |  |  | 26 | $self->_print ($writer_fodder->{'comments'}->{'binary'}) | 
| 750 |  |  |  |  |  |  | or print ("Couldn't write comments\n"); | 
| 751 |  |  |  |  |  |  | } | 
| 752 |  |  |  |  |  |  |  | 
| 753 |  |  |  |  |  |  | # kinda unnecessary, given the close() below, but maybe that'll go | 
| 754 |  |  |  |  |  |  | # away someday. | 
| 755 | 10 | 50 | 33 |  |  | 48 | $self->flush if $self->_flush_on_write && defined $self->_fh; | 
| 756 |  |  |  |  |  |  |  | 
| 757 | 10 |  |  |  |  | 42 | $self->close(); | 
| 758 | 10 |  |  |  |  | 5564 | return 1; | 
| 759 |  |  |  |  |  |  | } | 
| 760 |  |  |  |  |  |  |  | 
| 761 |  |  |  |  |  |  |  | 
| 762 |  |  |  |  |  |  |  | 
| 763 |  |  |  |  |  |  |  | 
| 764 |  |  |  |  |  |  |  | 
| 765 |  |  |  |  |  |  | =head2 _get_binary_header() | 
| 766 |  |  |  |  |  |  |  | 
| 767 |  |  |  |  |  |  | Title   : _get_binary_header(); | 
| 768 |  |  |  |  |  |  | Usage   : $self->_get_binary_header(); | 
| 769 |  |  |  |  |  |  | Function: Provide the binary string that will be used as the header for | 
| 770 |  |  |  |  |  |  | a scfv2 document. | 
| 771 |  |  |  |  |  |  | Returns : A binary string. | 
| 772 |  |  |  |  |  |  | Args    : None. Uses the entries in the $self->{'header'} hash. These | 
| 773 |  |  |  |  |  |  | are set on construction of the object (hopefully correctly!). | 
| 774 |  |  |  |  |  |  | Notes   : | 
| 775 |  |  |  |  |  |  |  | 
| 776 |  |  |  |  |  |  | =cut | 
| 777 |  |  |  |  |  |  |  | 
| 778 |  |  |  |  |  |  | sub _get_binary_header { | 
| 779 | 10 |  |  | 10 |  | 19 | my ($self,$header) = @_; | 
| 780 |  |  |  |  |  |  | my $binary = pack "a4 NNNNNNNN a4 NN N20", | 
| 781 |  |  |  |  |  |  | ( | 
| 782 |  |  |  |  |  |  | $header->{'magic'}, | 
| 783 |  |  |  |  |  |  | $header->{'samples'}, | 
| 784 |  |  |  |  |  |  | $header->{'samples_offset'}, | 
| 785 |  |  |  |  |  |  | $header->{'bases'}, | 
| 786 |  |  |  |  |  |  | $header->{'bases_left_clip'}, | 
| 787 |  |  |  |  |  |  | $header->{'bases_right_clip'}, | 
| 788 |  |  |  |  |  |  | $header->{'bases_offset'}, | 
| 789 |  |  |  |  |  |  | $header->{'comments_size'}, | 
| 790 |  |  |  |  |  |  | $header->{'comments_offset'}, | 
| 791 |  |  |  |  |  |  | $header->{'version'}, | 
| 792 |  |  |  |  |  |  | $header->{'sample_size'}, | 
| 793 |  |  |  |  |  |  | $header->{'code_set'}, | 
| 794 | 10 |  |  |  |  | 48 | @{$header->{'spare'}} | 
|  | 10 |  |  |  |  | 106 |  | 
| 795 |  |  |  |  |  |  | ); | 
| 796 | 10 |  |  |  |  | 39 | return $binary; | 
| 797 |  |  |  |  |  |  | } | 
| 798 |  |  |  |  |  |  |  | 
| 799 |  |  |  |  |  |  | =head2 _get_binary_traces($version,$ref) | 
| 800 |  |  |  |  |  |  |  | 
| 801 |  |  |  |  |  |  | Title   : _set_binary_tracesbases($version,$ref) | 
| 802 |  |  |  |  |  |  | Usage   : $self->_set_binary_tracesbases($version,$ref); | 
| 803 |  |  |  |  |  |  | Function: Constructs the trace and base strings for all scfs | 
| 804 |  |  |  |  |  |  | Returns : Nothing. Alters self. | 
| 805 |  |  |  |  |  |  | Args    : $version - "2" or "3" | 
| 806 |  |  |  |  |  |  | $sequence - a scalar containing arbitrary sequence data | 
| 807 |  |  |  |  |  |  | $ref - a reference to either a SequenceTraces or a | 
| 808 |  |  |  |  |  |  | SequenceWithQuality object. | 
| 809 |  |  |  |  |  |  | Notes   : This is a really complicated thing. | 
| 810 |  |  |  |  |  |  |  | 
| 811 |  |  |  |  |  |  | =cut | 
| 812 |  |  |  |  |  |  |  | 
| 813 |  |  |  |  |  |  | sub _get_binary_traces { | 
| 814 | 10 |  |  | 10 |  | 19 | my ($self,$version,$ref,$sample_size) = @_; | 
| 815 |  |  |  |  |  |  | # ref _should_ be a Bio::Seq::SequenceTrace, but might be a | 
| 816 |  |  |  |  |  |  | # Bio::Seq::Quality | 
| 817 | 10 |  |  |  |  | 10 | my $returner; | 
| 818 | 10 |  |  |  |  | 19 | my $sequence = $ref->seq(); | 
| 819 | 10 |  |  |  |  | 18 | my $sequence_length = length($sequence); | 
| 820 |  |  |  |  |  |  | # first of all, do we need to synthesize the trace? | 
| 821 |  |  |  |  |  |  | # if so, call synthesize_base | 
| 822 | 10 |  |  |  |  | 11 | my ($traceobj,@traces,$current); | 
| 823 | 10 | 50 |  |  |  | 34 | if ( ref($ref) eq "Bio::Seq::Quality" ) { | 
| 824 | 0 |  |  |  |  | 0 | $traceobj = Bio::Seq::Quality->new( | 
| 825 |  |  |  |  |  |  | -target   =>   $ref | 
| 826 |  |  |  |  |  |  | ); | 
| 827 | 0 |  |  |  |  | 0 | $traceobj->_synthesize_traces(); | 
| 828 |  |  |  |  |  |  | } | 
| 829 |  |  |  |  |  |  | else { | 
| 830 | 10 |  |  |  |  | 14 | $traceobj = $ref; | 
| 831 | 10 | 100 |  |  |  | 66 | if ($version eq "2") { | 
|  |  | 50 |  |  |  |  |  | 
| 832 | 1 |  |  |  |  | 4 | my $trace_length = $traceobj->trace_length(); | 
| 833 | 1 |  |  |  |  | 4 | for ($current = 1; $current <= $trace_length; $current++) { | 
| 834 | 14107 |  |  |  |  | 13802 | foreach (qw(a c g t)) { | 
| 835 | 56428 |  |  |  |  | 76867 | push @traces,$traceobj->trace_value_at($_,$current); | 
| 836 |  |  |  |  |  |  | } | 
| 837 |  |  |  |  |  |  | } | 
| 838 |  |  |  |  |  |  | } | 
| 839 |  |  |  |  |  |  | elsif ($version == 3) { | 
| 840 | 9 |  |  |  |  | 24 | foreach my $current_trace (qw(a c g t)) { | 
| 841 | 36 |  |  |  |  | 54 | my @trace = @{$traceobj->trace($current_trace)}; | 
|  | 36 |  |  |  |  | 254 |  | 
| 842 | 36 |  |  |  |  | 123 | foreach (@trace) { | 
| 843 | 245300 | 50 |  |  |  | 278375 | if ($_ > 30000) { | 
| 844 | 0 |  |  |  |  | 0 | $_ -= 65536; | 
| 845 |  |  |  |  |  |  | } | 
| 846 |  |  |  |  |  |  | } | 
| 847 | 36 |  |  |  |  | 285 | my $transformed = $self->_delta(\@trace,"forward"); | 
| 848 | 36 | 50 |  |  |  | 135 | if($sample_size == 1){ | 
| 849 | 0 |  |  |  |  | 0 | foreach (@{$transformed}) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 850 | 0 | 0 |  |  |  | 0 | $_ += 256 if ($_ < 0); | 
| 851 |  |  |  |  |  |  | } | 
| 852 |  |  |  |  |  |  | } | 
| 853 | 36 |  |  |  |  | 57 | push @traces,@{$transformed}; | 
|  | 36 |  |  |  |  | 36985 |  | 
| 854 |  |  |  |  |  |  | } | 
| 855 |  |  |  |  |  |  | } | 
| 856 |  |  |  |  |  |  | } | 
| 857 | 10 |  |  |  |  | 80 | $returner->{version} = $version; | 
| 858 | 10 |  |  |  |  | 30 | $returner->{string} = \@traces; | 
| 859 | 10 |  |  |  |  | 19 | my $length_of_traces = scalar(@traces); | 
| 860 | 10 |  |  |  |  | 19 | my $byte; | 
| 861 | 10 | 50 |  |  |  | 34 | if ($sample_size == 1) { $byte = "c"; } else { $byte = "n"; } | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 10 |  |  |  |  | 17 |  | 
| 862 |  |  |  |  |  |  | # an unsigned integer should be I, but this is too long | 
| 863 |  |  |  |  |  |  | # | 
| 864 | 10 |  |  |  |  | 5842 | $returner->{binary} = pack "n${length_of_traces}",@traces; | 
| 865 | 10 |  |  |  |  | 36 | $returner->{length} = CORE::length($returner->{binary}); | 
| 866 | 10 |  |  |  |  | 60 | return $returner; | 
| 867 |  |  |  |  |  |  | } | 
| 868 |  |  |  |  |  |  |  | 
| 869 |  |  |  |  |  |  |  | 
| 870 |  |  |  |  |  |  | sub _get_binary_bases { | 
| 871 | 10 |  |  | 10 |  | 25 | my ($self,$version,$trace,$sample_size) = @_; | 
| 872 | 10 |  |  |  |  | 12 | my $byte; | 
| 873 | 10 | 50 |  |  |  | 31 | if ($sample_size == 1) { $byte = "c"; } else { $byte = "n"; } | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 10 |  |  |  |  | 18 |  | 
| 874 | 10 |  |  |  |  | 15 | my ($returner,@current_row,$current_base,$string,$binary); | 
| 875 | 10 |  |  |  |  | 53 | my $length = $trace->length(); | 
| 876 | 10 | 100 |  |  |  | 23 | if ($version == 2) { | 
| 877 | 1 |  |  |  |  | 3 | $returner->{'version'} = "2"; | 
| 878 | 1 |  |  |  |  | 7 | for (my $current_base =1; $current_base <= $length; $current_base++) { | 
| 879 | 1106 |  |  |  |  | 737 | my @current_row; | 
| 880 | 1106 |  |  |  |  | 1414 | push @current_row,$trace->peak_index_at($current_base); | 
| 881 | 1106 |  |  |  |  | 1495 | push @current_row,$trace->accuracy_at("a",$current_base); | 
| 882 | 1106 |  |  |  |  | 1339 | push @current_row,$trace->accuracy_at("c",$current_base); | 
| 883 | 1106 |  |  |  |  | 1337 | push @current_row,$trace->accuracy_at("g",$current_base); | 
| 884 | 1106 |  |  |  |  | 1365 | push @current_row,$trace->accuracy_at("t",$current_base); | 
| 885 | 1106 |  |  |  |  | 1293 | push @current_row,$trace->baseat($current_base); | 
| 886 | 1106 |  |  |  |  | 934 | push @current_row,0,0,0; | 
| 887 | 1106 |  |  |  |  | 615 | push @{$returner->{string}},@current_row; | 
|  | 1106 |  |  |  |  | 1857 |  | 
| 888 | 1106 |  |  |  |  | 3200 | $returner->{binary} .= pack "N C C C C a C3",@current_row; | 
| 889 |  |  |  |  |  |  | } | 
| 890 | 1 |  |  |  |  | 8 | return $returner; | 
| 891 |  |  |  |  |  |  | } | 
| 892 |  |  |  |  |  |  | else { | 
| 893 | 9 |  |  |  |  | 30 | $returner->{'version'} = "3.00"; | 
| 894 | 9 |  |  |  |  | 35 | $returner->{peak_indices}->{string} = $trace->peak_indices(); | 
| 895 | 9 |  |  |  |  | 16 | my $length = scalar(@{$returner->{peak_indices}->{string}}); | 
|  | 9 |  |  |  |  | 20 |  | 
| 896 |  |  |  |  |  |  | $returner->{peak_indices}->{binary} = | 
| 897 | 9 |  |  |  |  | 24 | pack "N$length",@{$returner->{peak_indices}->{string}}; | 
|  | 9 |  |  |  |  | 348 |  | 
| 898 |  |  |  |  |  |  | $returner->{peak_indices}->{length} = | 
| 899 | 9 |  |  |  |  | 18 | CORE::length($returner->{peak_indices}->{binary}); | 
| 900 | 9 |  |  |  |  | 15 | my @accuracies; | 
| 901 | 9 |  |  |  |  | 28 | foreach my $base (qw(a c g t)) { | 
| 902 | 36 |  |  |  |  | 73 | $returner->{accuracies}->{$base} = $trace->accuracies($base); | 
| 903 | 36 |  |  |  |  | 47 | push @accuracies,@{$trace->accuracies($base)}; | 
|  | 36 |  |  |  |  | 49 |  | 
| 904 |  |  |  |  |  |  | } | 
| 905 | 9 |  |  |  |  | 34 | $returner->{sequence} = $trace->seq(); | 
| 906 | 9 |  |  |  |  | 16 | $length = scalar(@accuracies); | 
| 907 |  |  |  |  |  |  | # this really is "c" for samplesize == 2 | 
| 908 | 9 |  |  |  |  | 352 | $returner->{accuracies}->{binary} = pack "C${length}",@accuracies; | 
| 909 |  |  |  |  |  |  | $returner->{accuracies}->{length} = | 
| 910 | 9 |  |  |  |  | 21 | CORE::length($returner->{accuracies}->{binary}); | 
| 911 | 9 |  |  |  |  | 28 | $length = $trace->seq_obj()->length(); | 
| 912 | 9 |  |  |  |  | 39 | for (my $count=0; $count< $length; $count++) { | 
| 913 | 4629 |  |  |  |  | 2396 | push @{$returner->{reserved}->{string}},0,0,0; | 
|  | 4629 |  |  |  |  | 7248 |  | 
| 914 |  |  |  |  |  |  | } | 
| 915 |  |  |  |  |  |  | } | 
| 916 | 9 |  |  |  |  | 19 | $length = scalar(@{$returner->{reserved}->{string}}); | 
|  | 9 |  |  |  |  | 28 |  | 
| 917 |  |  |  |  |  |  | # this _must_ be "c" | 
| 918 |  |  |  |  |  |  | $returner->{'reserved'}->{'binary'} = | 
| 919 | 9 |  |  |  |  | 25 | pack "c$length",@{$returner->{reserved}->{string}}; | 
|  | 9 |  |  |  |  | 274 |  | 
| 920 |  |  |  |  |  |  | $returner->{'reserved'}->{'length'} = | 
| 921 | 9 |  |  |  |  | 29 | CORE::length($returner->{'reserved'}->{'binary'}); | 
| 922 |  |  |  |  |  |  | # $returner->{'bases'}->{'string'} = $trace->seq(); | 
| 923 | 9 |  |  |  |  | 115 | my @bases = split('',$trace->seq()); | 
| 924 | 9 |  |  |  |  | 31 | $length = $trace->length(); | 
| 925 | 9 |  |  |  |  | 24 | $returner->{'bases'}->{'binary'} = $trace->seq(); | 
| 926 |  |  |  |  |  |  | # print("Returning this:\n"); | 
| 927 |  |  |  |  |  |  | # $dumper->dumpValue($returner); | 
| 928 |  |  |  |  |  |  | return ($returner->{peak_indices}, | 
| 929 |  |  |  |  |  |  | $returner->{accuracies}, | 
| 930 |  |  |  |  |  |  | $returner->{bases}, | 
| 931 | 9 |  |  |  |  | 253 | $returner->{reserved}); | 
| 932 |  |  |  |  |  |  |  | 
| 933 |  |  |  |  |  |  | } | 
| 934 |  |  |  |  |  |  |  | 
| 935 |  |  |  |  |  |  |  | 
| 936 |  |  |  |  |  |  | =head2 _make_trace_string($version) | 
| 937 |  |  |  |  |  |  |  | 
| 938 |  |  |  |  |  |  | Title   : _make_trace_string($version) | 
| 939 |  |  |  |  |  |  | Usage   : $self->_make_trace_string($version) | 
| 940 |  |  |  |  |  |  | Function: Merges trace data for the four bases to produce an scf | 
| 941 |  |  |  |  |  |  | trace string. _requires_ $version | 
| 942 |  |  |  |  |  |  | Returns : Nothing. Alters $self. | 
| 943 |  |  |  |  |  |  | Args    : $version - a version number. "2" or "3" | 
| 944 |  |  |  |  |  |  | Notes   : | 
| 945 |  |  |  |  |  |  |  | 
| 946 |  |  |  |  |  |  | =cut | 
| 947 |  |  |  |  |  |  |  | 
| 948 |  |  |  |  |  |  | sub _make_trace_string { | 
| 949 | 0 |  |  | 0 |  | 0 | my ($self,$version) = @_; | 
| 950 | 0 |  |  |  |  | 0 | my @traces; | 
| 951 |  |  |  |  |  |  | my @traces_view; | 
| 952 | 0 |  |  |  |  | 0 | my @as = @{$self->{'text'}->{'samples_a'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 953 | 0 |  |  |  |  | 0 | my @cs = @{$self->{'text'}->{'samples_c'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 954 | 0 |  |  |  |  | 0 | my @gs = @{$self->{'text'}->{'samples_g'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 955 | 0 |  |  |  |  | 0 | my @ts = @{$self->{'text'}->{'samples_t'}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 956 | 0 | 0 |  |  |  | 0 | if ($version == 2) { | 
|  |  | 0 |  |  |  |  |  | 
| 957 | 0 |  |  |  |  | 0 | for (my $curr=0; $curr < scalar(@as); $curr++) { | 
| 958 | 0 | 0 |  |  |  | 0 | $as[$curr] = $DEFAULT_QUALITY unless defined $as[$curr]; | 
| 959 | 0 | 0 |  |  |  | 0 | $cs[$curr] = $DEFAULT_QUALITY unless defined $cs[$curr]; | 
| 960 | 0 | 0 |  |  |  | 0 | $gs[$curr] = $DEFAULT_QUALITY unless defined $gs[$curr]; | 
| 961 | 0 | 0 |  |  |  | 0 | $ts[$curr] = $DEFAULT_QUALITY unless defined $ts[$curr]; | 
| 962 | 0 |  |  |  |  | 0 | push @traces,($as[$curr],$cs[$curr],$gs[$curr],$ts[$curr]); | 
| 963 |  |  |  |  |  |  | } | 
| 964 |  |  |  |  |  |  | } | 
| 965 |  |  |  |  |  |  | elsif ($version == 3) { | 
| 966 | 0 |  |  |  |  | 0 | @traces = (@as,@cs,@gs,@ts); | 
| 967 |  |  |  |  |  |  | } | 
| 968 |  |  |  |  |  |  | else { | 
| 969 | 0 |  |  |  |  | 0 | $self->throw("No idea what version required to make traces here. You gave #$version#  Bailing."); | 
| 970 |  |  |  |  |  |  | } | 
| 971 | 0 |  |  |  |  | 0 | my $length = scalar(@traces); | 
| 972 | 0 |  |  |  |  | 0 | $self->{'text'}->{'samples_all'} = \@traces; | 
| 973 |  |  |  |  |  |  |  | 
| 974 |  |  |  |  |  |  | } | 
| 975 |  |  |  |  |  |  |  | 
| 976 |  |  |  |  |  |  | =head2 _get_binary_comments(\@comments) | 
| 977 |  |  |  |  |  |  |  | 
| 978 |  |  |  |  |  |  | Title   : _get_binary_comments(\@comments) | 
| 979 |  |  |  |  |  |  | Usage   : $self->_get_binary_comments(\@comments); | 
| 980 |  |  |  |  |  |  | Function: Provide a binary string that will be the comments section of | 
| 981 |  |  |  |  |  |  | the scf file. See the scf specifications for detailed | 
| 982 |  |  |  |  |  |  | specifications for the comments section of an scf file. Hint: | 
| 983 |  |  |  |  |  |  | CODE=something\nBODE=something\n\0 | 
| 984 |  |  |  |  |  |  | Returns : | 
| 985 |  |  |  |  |  |  | Args    : A reference to an array containing comments. | 
| 986 |  |  |  |  |  |  | Notes   : None. | 
| 987 |  |  |  |  |  |  |  | 
| 988 |  |  |  |  |  |  | =cut | 
| 989 |  |  |  |  |  |  |  | 
| 990 |  |  |  |  |  |  | sub _get_binary_comments { | 
| 991 | 10 |  |  | 10 |  | 18 | my ($self,$rcomments) = @_; | 
| 992 | 10 |  |  |  |  | 10 | my $returner; | 
| 993 | 10 |  |  |  |  | 14 | my $comments_string = ''; | 
| 994 | 10 |  |  |  |  | 45 | my %comments = %$rcomments; | 
| 995 | 10 |  |  |  |  | 33 | foreach my $key (sort keys %comments) { | 
| 996 | 21 |  | 50 |  |  | 39 | $comments{$key} ||= ''; | 
| 997 | 21 |  |  |  |  | 45 | $comments_string .= "$key=$comments{$key}\n"; | 
| 998 |  |  |  |  |  |  | } | 
| 999 | 10 |  |  |  |  | 17 | $comments_string .= "\n\0"; | 
| 1000 | 10 |  |  |  |  | 16 | my $length = CORE::length($comments_string); | 
| 1001 | 10 |  |  |  |  | 24 | $returner->{length} = $length; | 
| 1002 | 10 |  |  |  |  | 23 | $returner->{string} = $comments_string; | 
| 1003 | 10 |  |  |  |  | 75 | $returner->{binary} = pack "A$length",$comments_string; | 
| 1004 | 10 |  |  |  |  | 26 | return $returner; | 
| 1005 |  |  |  |  |  |  | } | 
| 1006 |  |  |  |  |  |  |  | 
| 1007 |  |  |  |  |  |  | #=head2 _fill_missing_data($swq) | 
| 1008 |  |  |  |  |  |  | # | 
| 1009 |  |  |  |  |  |  | # Title   : _fill_missing_data($swq) | 
| 1010 |  |  |  |  |  |  | # Usage   : $self->_fill_missing_data($swq); | 
| 1011 |  |  |  |  |  |  | # Function: If the $swq with quality has no qualities, set all qualities | 
| 1012 |  |  |  |  |  |  | #      to 0. | 
| 1013 |  |  |  |  |  |  | #      If the $swq has no sequence, set the sequence to N's. | 
| 1014 |  |  |  |  |  |  | # Returns : Nothing. Modifies the Bio::Seq::Quality that was passed as an | 
| 1015 |  |  |  |  |  |  | #      argument. | 
| 1016 |  |  |  |  |  |  | # Args    : A reference to a Bio::Seq::Quality | 
| 1017 |  |  |  |  |  |  | # Notes   : None. | 
| 1018 |  |  |  |  |  |  | # | 
| 1019 |  |  |  |  |  |  | #=cut | 
| 1020 |  |  |  |  |  |  | # | 
| 1021 |  |  |  |  |  |  | ##' | 
| 1022 |  |  |  |  |  |  | #sub _fill_missing_data { | 
| 1023 |  |  |  |  |  |  | #    my ($self,$swq) = @_; | 
| 1024 |  |  |  |  |  |  | #    my $qual_obj = $swq->qual_obj(); | 
| 1025 |  |  |  |  |  |  | #    my $seq_obj = $swq->seq_obj(); | 
| 1026 |  |  |  |  |  |  | #    if ($qual_obj->length() == 0 && $seq_obj->length() != 0) { | 
| 1027 |  |  |  |  |  |  | #   my $fake_qualities = ("$DEFAULT_QUALITY ")x$seq_obj->length(); | 
| 1028 |  |  |  |  |  |  | #   $swq->qual($fake_qualities); | 
| 1029 |  |  |  |  |  |  | #    } | 
| 1030 |  |  |  |  |  |  | #    if ($seq_obj->length() == 0 && $qual_obj->length != 0) { | 
| 1031 |  |  |  |  |  |  | #   my $sequence = ("N")x$qual_obj->length(); | 
| 1032 |  |  |  |  |  |  | #   $swq->seq($sequence); | 
| 1033 |  |  |  |  |  |  | #    } | 
| 1034 |  |  |  |  |  |  | #} | 
| 1035 |  |  |  |  |  |  |  | 
| 1036 |  |  |  |  |  |  | =head2 _delta(\@trace_data,$direction) | 
| 1037 |  |  |  |  |  |  |  | 
| 1038 |  |  |  |  |  |  | Title   : _delta(\@trace_data,$direction) | 
| 1039 |  |  |  |  |  |  | Usage   : $self->_delta(\@trace_data,$direction); | 
| 1040 |  |  |  |  |  |  | Function: | 
| 1041 |  |  |  |  |  |  | Returns : A reference to an array containing modified trace values. | 
| 1042 |  |  |  |  |  |  | Args    : A reference to an array containing trace data and a string | 
| 1043 |  |  |  |  |  |  | indicating the direction of conversion. ("forward" or | 
| 1044 |  |  |  |  |  |  | "backward"). | 
| 1045 |  |  |  |  |  |  | Notes   : This code is taken from the specification for SCF3.2. | 
| 1046 |  |  |  |  |  |  | http://www.mrc-lmb.cam.ac.uk/pubseq/manual/formats_unix_4.html | 
| 1047 |  |  |  |  |  |  |  | 
| 1048 |  |  |  |  |  |  | =cut | 
| 1049 |  |  |  |  |  |  |  | 
| 1050 |  |  |  |  |  |  |  | 
| 1051 |  |  |  |  |  |  | sub _delta { | 
| 1052 | 80 |  |  | 80 |  | 344 | my ($self,$rsamples,$direction) = @_; | 
| 1053 | 80 |  |  |  |  | 42508 | my @samples = @$rsamples; | 
| 1054 |  |  |  |  |  |  | # /* If job == DELTA_IT: | 
| 1055 |  |  |  |  |  |  | # *  change a series of sample points to a series of delta delta values: | 
| 1056 |  |  |  |  |  |  | # *  ie change them in two steps: | 
| 1057 |  |  |  |  |  |  | # *  first: delta = current_value - previous_value | 
| 1058 |  |  |  |  |  |  | # *  then: delta_delta = delta - previous_delta | 
| 1059 |  |  |  |  |  |  | # * else | 
| 1060 |  |  |  |  |  |  | # *  do the reverse | 
| 1061 |  |  |  |  |  |  | # */ | 
| 1062 |  |  |  |  |  |  | # int i; | 
| 1063 |  |  |  |  |  |  | # uint_2 p_delta, p_sample; | 
| 1064 |  |  |  |  |  |  |  | 
| 1065 | 80 |  |  |  |  | 204 | my ($i,$num_samples,$p_delta,$p_sample,@samples_converted,$p_sample1,$p_sample2); | 
| 1066 | 80 |  |  |  |  | 116 | my $SLOW_BUT_CLEAR = 0; | 
| 1067 | 80 |  |  |  |  | 133 | $num_samples = scalar(@samples); | 
| 1068 |  |  |  |  |  |  | # c-programmers are funny people with their single-letter variables | 
| 1069 |  |  |  |  |  |  |  | 
| 1070 | 80 | 100 |  |  |  | 426 | if ( $direction eq "forward" ) { | 
|  |  | 50 |  |  |  |  |  | 
| 1071 | 36 | 50 |  |  |  | 68 | if($SLOW_BUT_CLEAR){ | 
| 1072 | 0 |  |  |  |  | 0 | $p_delta  = 0; | 
| 1073 | 0 |  |  |  |  | 0 | for ($i=0; $i < $num_samples; $i++) { | 
| 1074 | 0 |  |  |  |  | 0 | $p_sample = $samples[$i]; | 
| 1075 | 0 |  |  |  |  | 0 | $samples[$i] = $samples[$i] - $p_delta; | 
| 1076 | 0 |  |  |  |  | 0 | $p_delta  = $p_sample; | 
| 1077 |  |  |  |  |  |  | } | 
| 1078 | 0 |  |  |  |  | 0 | $p_delta  = 0; | 
| 1079 | 0 |  |  |  |  | 0 | for ($i=0; $i < $num_samples; $i++) { | 
| 1080 | 0 |  |  |  |  | 0 | $p_sample = $samples[$i]; | 
| 1081 | 0 |  |  |  |  | 0 | $samples[$i] = $samples[$i] - $p_delta; | 
| 1082 | 0 |  |  |  |  | 0 | $p_delta  = $p_sample; | 
| 1083 |  |  |  |  |  |  | } | 
| 1084 |  |  |  |  |  |  | } else { | 
| 1085 | 36 |  |  |  |  | 146 | for ($i = $num_samples-1; $i > 1; $i--){ | 
| 1086 | 245228 |  |  |  |  | 326998 | $samples[$i] = $samples[$i] - 2*$samples[$i-1] + $samples[$i-2]; | 
| 1087 |  |  |  |  |  |  | } | 
| 1088 | 36 |  |  |  |  | 86 | $samples[1] = $samples[1] - 2*$samples[0]; | 
| 1089 |  |  |  |  |  |  | } | 
| 1090 |  |  |  |  |  |  | } | 
| 1091 |  |  |  |  |  |  | elsif ($direction eq "backward") { | 
| 1092 | 44 | 50 |  |  |  | 130 | if($SLOW_BUT_CLEAR){ | 
| 1093 | 0 |  |  |  |  | 0 | $p_sample = 0; | 
| 1094 | 0 |  |  |  |  | 0 | for ($i=0; $i < $num_samples; $i++) { | 
| 1095 | 0 |  |  |  |  | 0 | $samples[$i] = $samples[$i] + $p_sample; | 
| 1096 | 0 |  |  |  |  | 0 | $p_sample = $samples[$i]; | 
| 1097 |  |  |  |  |  |  | } | 
| 1098 | 0 |  |  |  |  | 0 | $p_sample = 0; | 
| 1099 | 0 |  |  |  |  | 0 | for ($i=0; $i < $num_samples; $i++) { | 
| 1100 | 0 |  |  |  |  | 0 | $samples[$i] = $samples[$i] + $p_sample; | 
| 1101 | 0 |  |  |  |  | 0 | $p_sample = $samples[$i]; | 
| 1102 |  |  |  |  |  |  | } | 
| 1103 |  |  |  |  |  |  | } else { | 
| 1104 | 44 |  |  |  |  | 126 | $p_sample1 = $p_sample2 = 0; | 
| 1105 | 44 |  |  |  |  | 232 | for ($i = 0; $i < $num_samples; $i++){ | 
| 1106 | 424924 |  |  |  |  | 260843 | $p_sample1 = $p_sample1 + $samples[$i]; | 
| 1107 | 424924 |  |  |  |  | 255264 | $samples[$i] = $p_sample1 + $p_sample2; | 
| 1108 | 424924 |  |  |  |  | 472578 | $p_sample2 = $samples[$i]; | 
| 1109 |  |  |  |  |  |  | } | 
| 1110 |  |  |  |  |  |  |  | 
| 1111 |  |  |  |  |  |  | } | 
| 1112 |  |  |  |  |  |  | } | 
| 1113 |  |  |  |  |  |  | else { | 
| 1114 | 0 |  |  |  |  | 0 | $self->warn("Bad direction. Use \"forward\" or \"backward\"."); | 
| 1115 |  |  |  |  |  |  | } | 
| 1116 | 80 |  |  |  |  | 651 | return \@samples; | 
| 1117 |  |  |  |  |  |  | } | 
| 1118 |  |  |  |  |  |  |  | 
| 1119 |  |  |  |  |  |  | =head2 _unpack_magik($buffer) | 
| 1120 |  |  |  |  |  |  |  | 
| 1121 |  |  |  |  |  |  | Title   : _unpack_magik($buffer) | 
| 1122 |  |  |  |  |  |  | Usage   : $self->_unpack_magik($buffer) | 
| 1123 |  |  |  |  |  |  | Function: What unpack specification should be used? Try them all. | 
| 1124 |  |  |  |  |  |  | Returns : Nothing. | 
| 1125 |  |  |  |  |  |  | Args    : A buffer containing arbitrary binary data. | 
| 1126 |  |  |  |  |  |  | Notes   : Eliminate the ambiguity and the guesswork. Used in the | 
| 1127 |  |  |  |  |  |  | adaptation of _delta(), mostly. | 
| 1128 |  |  |  |  |  |  |  | 
| 1129 |  |  |  |  |  |  | =cut | 
| 1130 |  |  |  |  |  |  |  | 
| 1131 |  |  |  |  |  |  | sub _unpack_magik { | 
| 1132 | 0 |  |  | 0 |  | 0 | my ($self,$buffer) = @_; | 
| 1133 | 0 |  |  |  |  | 0 | my $length = length($buffer); | 
| 1134 | 0 |  |  |  |  | 0 | my (@read,$counter); | 
| 1135 | 0 |  |  |  |  | 0 | foreach (qw(c C s S i I l L n N v V)) { | 
| 1136 | 0 |  |  |  |  | 0 | @read = unpack "$_$length", $buffer; | 
| 1137 | 0 |  |  |  |  | 0 | for ($counter=0; $counter < 20; $counter++) { | 
| 1138 | 0 |  |  |  |  | 0 | print("$read[$counter]\n"); | 
| 1139 |  |  |  |  |  |  | } | 
| 1140 |  |  |  |  |  |  | } | 
| 1141 |  |  |  |  |  |  | } | 
| 1142 |  |  |  |  |  |  |  | 
| 1143 |  |  |  |  |  |  | =head2 read_from_buffer($filehandle,$buffer,$length) | 
| 1144 |  |  |  |  |  |  |  | 
| 1145 |  |  |  |  |  |  | Title   : read_from_buffer($filehandle,$buffer,$length) | 
| 1146 |  |  |  |  |  |  | Usage   : $self->read_from_buffer($filehandle,$buffer,$length); | 
| 1147 |  |  |  |  |  |  | Function: Read from the buffer. | 
| 1148 |  |  |  |  |  |  | Returns : $buffer, containing a read of $length | 
| 1149 |  |  |  |  |  |  | Args    : a filehandle, a buffer, and a read length | 
| 1150 |  |  |  |  |  |  | Notes   : I just got tired of typing | 
| 1151 |  |  |  |  |  |  | "unless (length($buffer) == $length)" so I put it here. | 
| 1152 |  |  |  |  |  |  |  | 
| 1153 |  |  |  |  |  |  | =cut | 
| 1154 |  |  |  |  |  |  |  | 
| 1155 |  |  |  |  |  |  | sub read_from_buffer { | 
| 1156 | 100 |  |  | 100 | 1 | 397 | my ($self,$fh,$buffer,$length,$start_position) = @_; | 
| 1157 |  |  |  |  |  |  | # print("Reading from a buffer!!! length($length) "); | 
| 1158 | 100 | 100 |  |  |  | 342 | if ($start_position) { | 
| 1159 |  |  |  |  |  |  | # print(" startposition($start_position)(".sprintf("%X", $start_position).")\n"); | 
| 1160 |  |  |  |  |  |  | } | 
| 1161 |  |  |  |  |  |  | # print("\n"); | 
| 1162 | 100 | 100 |  |  |  | 267 | if ($start_position) { | 
| 1163 |  |  |  |  |  |  | # print("seeking to this position in the file: (".$start_position.")\n"); | 
| 1164 | 81 |  |  |  |  | 549 | seek ($fh,$start_position,0); | 
| 1165 |  |  |  |  |  |  | # print("done. here is where I am now: (".tell($fh).")\n"); | 
| 1166 |  |  |  |  |  |  | } | 
| 1167 |  |  |  |  |  |  | else { | 
| 1168 |  |  |  |  |  |  | # print("You did not specify a start position. Going from this position (the current position) (".tell($fh).")\n"); | 
| 1169 |  |  |  |  |  |  | } | 
| 1170 | 100 |  |  |  |  | 2435 | read $fh, $buffer, $length; | 
| 1171 | 100 | 50 |  |  |  | 293 | unless (length($buffer) == $length) { | 
| 1172 | 0 |  |  |  |  | 0 | $self->warn("The read was incomplete! Trying harder."); | 
| 1173 | 0 |  |  |  |  | 0 | my $missing_length = $length - length($buffer); | 
| 1174 | 0 |  |  |  |  | 0 | my $buffer2; | 
| 1175 | 0 |  |  |  |  | 0 | read $fh,$buffer2,$missing_length; | 
| 1176 | 0 |  |  |  |  | 0 | $buffer .= $buffer2; | 
| 1177 | 0 | 0 |  |  |  | 0 | if (length($buffer) != $length) { | 
| 1178 | 0 |  |  |  |  | 0 | $self->throw("Unexpected end of file while reading from SCF file. I should have read $length but instead got ".length($buffer)."! Current file position is ".tell($fh)."."); | 
| 1179 |  |  |  |  |  |  | } | 
| 1180 |  |  |  |  |  |  | } | 
| 1181 |  |  |  |  |  |  |  | 
| 1182 | 100 |  |  |  |  | 382 | return $buffer; | 
| 1183 |  |  |  |  |  |  | } | 
| 1184 |  |  |  |  |  |  |  | 
| 1185 |  |  |  |  |  |  | =head2 _dump_keys() | 
| 1186 |  |  |  |  |  |  |  | 
| 1187 |  |  |  |  |  |  | Title   : _dump_keys() | 
| 1188 |  |  |  |  |  |  | Usage   : &_dump_keys($a_reference_to_some_hash) | 
| 1189 |  |  |  |  |  |  | Function: Dump out the keys in a hash. | 
| 1190 |  |  |  |  |  |  | Returns : Nothing. | 
| 1191 |  |  |  |  |  |  | Args    : A reference to a hash. | 
| 1192 |  |  |  |  |  |  | Notes   : A debugging method. | 
| 1193 |  |  |  |  |  |  |  | 
| 1194 |  |  |  |  |  |  | =cut | 
| 1195 |  |  |  |  |  |  |  | 
| 1196 |  |  |  |  |  |  | sub _dump_keys { | 
| 1197 | 0 |  |  | 0 |  |  | my $rhash = shift; | 
| 1198 | 0 | 0 |  |  |  |  | if ($rhash !~ /HASH/) { | 
| 1199 | 0 |  |  |  |  |  | print("_dump_keys: that was not a hash.\nIt was #$rhash# which was this reference:".ref($rhash)."\n"); | 
| 1200 | 0 |  |  |  |  |  | return; | 
| 1201 |  |  |  |  |  |  | } | 
| 1202 | 0 |  |  |  |  |  | print("_dump_keys: The keys for $rhash are:\n"); | 
| 1203 | 0 |  |  |  |  |  | foreach (sort keys %$rhash) { | 
| 1204 | 0 |  |  |  |  |  | print("$_\n"); | 
| 1205 |  |  |  |  |  |  | } | 
| 1206 |  |  |  |  |  |  | } | 
| 1207 |  |  |  |  |  |  |  | 
| 1208 |  |  |  |  |  |  | =head2 _dump_base_accuracies() | 
| 1209 |  |  |  |  |  |  |  | 
| 1210 |  |  |  |  |  |  | Title   : _dump_base_accuracies() | 
| 1211 |  |  |  |  |  |  | Usage   : $self->_dump_base_accuracies(); | 
| 1212 |  |  |  |  |  |  | Function: Dump out the v3 base accuracies in an easy to read format. | 
| 1213 |  |  |  |  |  |  | Returns : Nothing. | 
| 1214 |  |  |  |  |  |  | Args    : None. | 
| 1215 |  |  |  |  |  |  | Notes   : A debugging method. | 
| 1216 |  |  |  |  |  |  |  | 
| 1217 |  |  |  |  |  |  | =cut | 
| 1218 |  |  |  |  |  |  |  | 
| 1219 |  |  |  |  |  |  | sub _dump_base_accuracies { | 
| 1220 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 1221 | 0 |  |  |  |  |  | print("Dumping base accuracies! for v3\n"); | 
| 1222 | 0 |  |  |  |  |  | print("There are this many elements in a,c,g,t:\n"); | 
| 1223 | 0 |  |  |  |  |  | print(scalar(@{$self->{'text'}->{'v3_base_accuracy_a'}}).",".scalar(@{$self->{'text'}->{'v3_base_accuracy_c'}}).",".scalar(@{$self->{'text'}->{'v3_base_accuracy_g'}}).",".scalar(@{$self->{'text'}->{'v3_base_accuracy_t'}})."\n"); | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 1224 | 0 |  |  |  |  |  | my $number_traces = scalar(@{$self->{'text'}->{'v3_base_accuracy_a'}}); | 
|  | 0 |  |  |  |  |  |  | 
| 1225 | 0 |  |  |  |  |  | for (my $counter=0; $counter < $number_traces; $counter++ ) { | 
| 1226 | 0 |  |  |  |  |  | print("$counter\t"); | 
| 1227 | 0 |  |  |  |  |  | print $self->{'text'}->{'v3_base_accuracy_a'}->[$counter]."\t"; | 
| 1228 | 0 |  |  |  |  |  | print $self->{'text'}->{'v3_base_accuracy_c'}->[$counter]."\t"; | 
| 1229 | 0 |  |  |  |  |  | print $self->{'text'}->{'v3_base_accuracy_g'}->[$counter]."\t"; | 
| 1230 | 0 |  |  |  |  |  | print $self->{'text'}->{'v3_base_accuracy_t'}->[$counter]."\t"; | 
| 1231 | 0 |  |  |  |  |  | print("\n"); | 
| 1232 |  |  |  |  |  |  | } | 
| 1233 |  |  |  |  |  |  | } | 
| 1234 |  |  |  |  |  |  |  | 
| 1235 |  |  |  |  |  |  | =head2 _dump_peak_indices_incoming() | 
| 1236 |  |  |  |  |  |  |  | 
| 1237 |  |  |  |  |  |  | Title   : _dump_peak_indices_incoming() | 
| 1238 |  |  |  |  |  |  | Usage   : $self->_dump_peak_indices_incoming(); | 
| 1239 |  |  |  |  |  |  | Function: Dump out the v3 peak indices in an easy to read format. | 
| 1240 |  |  |  |  |  |  | Returns : Nothing. | 
| 1241 |  |  |  |  |  |  | Args    : None. | 
| 1242 |  |  |  |  |  |  | Notes   : A debugging method. | 
| 1243 |  |  |  |  |  |  |  | 
| 1244 |  |  |  |  |  |  | =cut | 
| 1245 |  |  |  |  |  |  |  | 
| 1246 |  |  |  |  |  |  | sub _dump_peak_indices_incoming { | 
| 1247 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 1248 | 0 |  |  |  |  |  | print("Dump peak indices incoming!\n"); | 
| 1249 | 0 |  |  |  |  |  | my $length = $self->{'bases'}; | 
| 1250 | 0 |  |  |  |  |  | print("The length is $length\n"); | 
| 1251 | 0 |  |  |  |  |  | for (my $count=0; $count < $length; $count++) { | 
| 1252 | 0 |  |  |  |  |  | print("$count\t$self->{parsed}->{peak_indices}->[$count]\n"); | 
| 1253 |  |  |  |  |  |  | } | 
| 1254 |  |  |  |  |  |  | } | 
| 1255 |  |  |  |  |  |  |  | 
| 1256 |  |  |  |  |  |  | =head2 _dump_base_accuracies_incoming() | 
| 1257 |  |  |  |  |  |  |  | 
| 1258 |  |  |  |  |  |  | Title   : _dump_base_accuracies_incoming() | 
| 1259 |  |  |  |  |  |  | Usage   : $self->_dump_base_accuracies_incoming(); | 
| 1260 |  |  |  |  |  |  | Function: Dump out the v3 base accuracies in an easy to read format. | 
| 1261 |  |  |  |  |  |  | Returns : Nothing. | 
| 1262 |  |  |  |  |  |  | Args    : None. | 
| 1263 |  |  |  |  |  |  | Notes   : A debugging method. | 
| 1264 |  |  |  |  |  |  |  | 
| 1265 |  |  |  |  |  |  | =cut | 
| 1266 |  |  |  |  |  |  |  | 
| 1267 |  |  |  |  |  |  | sub _dump_base_accuracies_incoming { | 
| 1268 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 1269 | 0 |  |  |  |  |  | print("Dumping base accuracies! for v3\n"); | 
| 1270 |  |  |  |  |  |  | # print("There are this many elements in a,c,g,t:\n"); | 
| 1271 |  |  |  |  |  |  | # print(scalar(@{$self->{'parsed'}->{'v3_base_accuracy_a'}}).",".scalar(@{$self->{'text'}->{'v3_base_accuracy_c'}}).",".scalar(@{$self->{'text'}->{'v3_base_accuracy_g'}}).",".scalar(@{$self->{'text'}->{'v3_base_accuracy_t'}})."\n"); | 
| 1272 | 0 |  |  |  |  |  | my $number_traces = $self->{'bases'}; | 
| 1273 | 0 |  |  |  |  |  | for (my $counter=0; $counter < $number_traces; $counter++ ) { | 
| 1274 | 0 |  |  |  |  |  | print("$counter\t"); | 
| 1275 | 0 |  |  |  |  |  | foreach (qw(A T G C)) { | 
| 1276 | 0 |  |  |  |  |  | print $self->{'parsed'}->{'base_accuracies'}->{$_}->[$counter]."\t"; | 
| 1277 |  |  |  |  |  |  | } | 
| 1278 | 0 |  |  |  |  |  | print("\n"); | 
| 1279 |  |  |  |  |  |  | } | 
| 1280 |  |  |  |  |  |  | } | 
| 1281 |  |  |  |  |  |  |  | 
| 1282 |  |  |  |  |  |  |  | 
| 1283 |  |  |  |  |  |  | =head2 _dump_comments() | 
| 1284 |  |  |  |  |  |  |  | 
| 1285 |  |  |  |  |  |  | Title   : _dump_comments() | 
| 1286 |  |  |  |  |  |  | Usage   : $self->_dump_comments(); | 
| 1287 |  |  |  |  |  |  | Function: Debug dump the comments section from the scf. | 
| 1288 |  |  |  |  |  |  | Returns : Nothing. | 
| 1289 |  |  |  |  |  |  | Args    : Nothing. | 
| 1290 |  |  |  |  |  |  | Notes   : None. | 
| 1291 |  |  |  |  |  |  |  | 
| 1292 |  |  |  |  |  |  | =cut | 
| 1293 |  |  |  |  |  |  |  | 
| 1294 |  |  |  |  |  |  | sub _dump_comments { | 
| 1295 | 0 |  |  | 0 |  |  | my ($self) = @_; | 
| 1296 | 0 |  |  |  |  |  | warn ("SCF comments:\n"); | 
| 1297 | 0 |  |  |  |  |  | foreach my $k (keys %{$self->{'comments'}}) { | 
|  | 0 |  |  |  |  |  |  | 
| 1298 | 0 |  |  |  |  |  | warn ("\t {$k} ==> ", $self->{'comments'}->{$k}, "\n"); | 
| 1299 |  |  |  |  |  |  | } | 
| 1300 |  |  |  |  |  |  | } | 
| 1301 |  |  |  |  |  |  |  | 
| 1302 |  |  |  |  |  |  |  | 
| 1303 |  |  |  |  |  |  |  | 
| 1304 |  |  |  |  |  |  | 1; | 
| 1305 |  |  |  |  |  |  | __END__ |