File Coverage

Bio/MapIO/fpc.pm
Criterion Covered Total %
statement 197 231 85.2
branch 84 120 70.0
condition 19 33 57.5
subroutine 10 11 90.9
pod 2 2 100.0
total 312 397 78.5


line stmt bran cond sub pod time code
1             # fpc.pm,v 1.2.2.1 2005/10/09 15:16:27 jason Exp
2             #
3             # BioPerl module for Bio::MapIO::fpc
4             #
5             # Please direct questions and support issues to
6             #
7             # Cared for by Gaurav Gupta
8             #
9             # Copyright AGCoL
10             #
11             # You may distribute this module under the same terms as perl itself
12              
13             # POD documentation - main docs before the code
14              
15             =head1 NAME
16              
17             Bio::MapIO::fpc - A FPC Map reader
18              
19             =head1 SYNOPSIS
20              
21             # do not use this object directly it is accessed through the Bio::MapIO system
22              
23             use Bio::MapIO;
24              
25             -format : specifies the format of the file format is "fpc",
26             -file : specifies the name of the .fpc file
27             -readcor : boolean argument, indicating if .cor is to be read
28             or not. It looks for the .cor file in the same path
29             as .fpc file.
30             0 : doesn't read .cor file
31             1 : reads the .cor file
32             [default 0]
33             -verbose : indicates the process of loading of fpc file
34             my $mapio = Bio::MapIO->new(-format => "fpc",
35             -file => "rice.fpc",
36             -readcor => 0,
37             -verbose => 0);
38              
39             my $map = $mapio->next_map();
40              
41             foreach my $marker ( $map->each_markerid() ) {
42             # loop through the markers associated with the map
43             # likewise for contigs, clones, etc.
44             }
45              
46              
47             =head1 DESCRIPTION
48              
49             This object contains code for parsing and processing FPC files and creating
50             L object from it.
51              
52             For faster access and better optimization, the data is stored internally in
53             hashes. The corresponding objects are created on request.
54              
55             We handle reading of the FPC ourselves, since MapIO module of Bioperl adds
56             too much overhead.
57              
58             =cut
59              
60             # Let the code begin...
61              
62             package Bio::MapIO::fpc;
63 2     2   12 use strict;
  2         4  
  2         58  
64 2     2   312 use POSIX;
  2         8245  
  2         20  
65              
66 2     2   5277 use Bio::Map::Physical;
  2         6  
  2         73  
67 2     2   110 use Bio::Map::Clone;
  2         5  
  2         46  
68 2     2   13 use Bio::Map::Contig;
  2         4  
  2         55  
69 2     2   13 use Bio::Map::FPCMarker;
  2         5  
  2         38  
70 2     2   8 use Bio::Range;
  2         3  
  2         41  
71              
72 2     2   7 use base qw(Bio::MapIO);
  2         4  
  2         4784  
73              
74             my $_readcor;
75              
76             =head1 Initializer
77              
78             =head2 _initialize
79              
80             Title : _initialize
81             Usage : called implicitly
82             Function: calls the SUPER::_initialize
83             Returns : nothing
84             Args : species, readcor
85              
86             =cut
87              
88             sub _initialize{
89 2     2   9 my ($self,@args) = @_;
90 2         3 my $species;
91 2         17 $self->SUPER::_initialize(@args);
92 2         7 ($species,$_readcor) = $self->_rearrange([qw(SPECIES READCOR)], @args);
93 2 100       10 $_readcor = 0 unless (defined($_readcor));
94             }
95              
96             =head1 Access Methods
97              
98             These methods let you get and set the member variables
99              
100             =head2 next_map
101              
102             Title : next_map
103             Usage : my $fpcmap = $mapio->next_map();
104             Function: gets the fpcmap from MapIO
105             Returns : object of type L
106             Args : none
107              
108             =cut
109              
110             sub next_map{
111              
112 2     2 1 9 my ($self) = @_;
113              
114 2         4 my $line;
115 2         13 my ($name,$fpcver,$moddate,$moduser,$contigcnt,$clonecnt,$markerscnt,
116             $bandcnt,$marker,$seqclone);
117 2         0 my ($corfile,$corindex,$BUFFER);
118 2         0 my @cordata;
119 2         0 my %fpcmarker;
120 2         0 my ($contig, $contigNumber);
121 2         3 my $curClone = 0;
122 2         2 my $curMarker = 0;
123 2         4 my $curContig = 0;
124 2         6 my %_clones;
125             my %_markers;
126 2         0 my %_contigs;
127 2         4 my $ctgzeropos = 1;
128              
129 2         25 my $map = Bio::Map::Physical->new('-units' => 'CB',
130             '-type' => 'physical');
131              
132 2         9 my $filename = $self->file();
133 2         5 my $fh = $self->{'_filehandle'};
134              
135 2 50       6 if (defined($_readcor)) {
136 2         10 $map->core_exists($_readcor);
137             }
138             else {
139 0         0 $map->core_exists(0);
140             }
141              
142 2 100       6 if ($map->core_exists()) {
143 1         4 $corfile = substr($filename,0,length($filename)-3)."cor";
144 1 50       22 if (open my $CORE, '<', $corfile) {
145 1         12 while( read($CORE, $BUFFER, 2) ) {
146 9772         15260 push @cordata, unpack('n*', $BUFFER);
147             }
148             }
149             else {
150 0         0 $map->core_exists(0);
151             }
152             }
153              
154             ## Read in the header
155 2         49 while (defined($line = <$fh>)) {
156 20         34 chomp($line);
157              
158 20 100       65 if ($line =~ m{^//\s+fpc\s+project\s+(.+)}) { $map->name($1); }
  2         44  
159 20 100       57 if ($line =~ m{^//\s+([\d.]+)}) {
160 2         12 my $version = $1;
161 2         13 $version =~ /((\d+)\.(\d+))(.*)/;
162 2         19 $map->version($1);
163 2 50       15 if ($line =~ /User:\s+(.+)/) { $map->modification_user($1); }
  2         9  
164             }
165              
166 20 100       48 if ($line =~ m{^//\s+Framework\s+(\w+)\s+(\w+)\s+([-\w]+)\s+(\w+)\s+(\w+)\s+(.+)$})
167             {
168 2 50       21 $map->group_type($3) if ($2 eq "Label");
169 2 50       18 $map->group_abbr($5) if ($4 eq "Abbrev");
170             }
171              
172 20 100       101 last unless ($line =~ m{^//});
173             }
174              
175 2 50 33     9 if (!defined($map->group_type()) || !defined($map->group_abbr()) ) {
176 0         0 $map->group_type("Chromosome");
177 0         0 $map->group_abbr("Chr");
178             }
179              
180 2         14 $_contigs{0}{'range'}{'end'} = 0;
181 2         7 $_contigs{0}{'range'}{'start'} = 0;
182              
183             ## Read in the clone data
184 2         12 while (defined($line = <$fh>)) {
185 975         1212 $marker = 0;
186 975         944 $contig = 0;
187 975         935 $seqclone = 0;
188 975         977 $contigNumber = 0;
189              
190 975         1404 my ($type,$name);
191 975         0 my (@amatch,@pmatch,@ematch);
192              
193 975         982 my $bandsread = 0;
194              
195 975 100       1462 last if ($line =~ /^Markerdata/);
196              
197              
198 973         2913 $line =~ /^(\w+)\s+:\s+"(.+)"/;
199              
200             ## these will be set if we did find the clone line
201 973         2166 ($type, $name) = ($1, $2);
202              
203 973 100       1630 if ($name =~ /sd1/) {
204 30         37 $seqclone = 1;
205             }
206              
207 973         2730 $_clones{$name}{'type'} = $type;
208 973         1253 $_clones{$name}{'contig'} = 0;
209 973         1252 $_contigs{'0'}{'clones'}{$name} = 0;
210              
211 973         955 my $temp;
212              
213             ## Loop through the following lines, getting attributes for clone
214 973   66     3997 while (defined($line = <$fh>) && $line !~ /^\s*\n$/) {
215              
216 7259 100 66     33401 if ($line =~ /^Map "ctg(\d+)" Ends (Left|Right) ([-\d]+)/) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
217 965         2070 $_clones{$name}{'contig'} = $1;
218 965         1721 $_contigs{$1}{'clones'}{$name} = 0;
219              
220 965         1534 delete($_contigs{'0'}{'clones'}{$name});
221              
222 965         1261 $temp = $3;
223 965         1022 $contigNumber = $1;
224 965         2035 $line = <$fh>;
225 965         2455 $line =~ /^Map "ctg(\d+)" Ends (Left|Right) ([\d]+)/;
226 965         2226 $_clones{$name}{'range'}{'start'} = $temp;
227              
228             $_contigs{$contigNumber}{'range'}{'start'} = $temp
229             if (!exists($_contigs{$contigNumber}{'range'}{'start'})
230 965 100 100     3439 || $_contigs{$contigNumber}{'range'}{'start'}
231             > $temp );
232              
233 965         2004 $_clones{$name}{'range'}{'end'} = $3;
234              
235             $_contigs{$contigNumber}{'range'}{'end'} = $3
236             if (!exists($_contigs{$contigNumber}{'range'}{'end'})
237 965 100 100     6164 || $_contigs{$contigNumber}{'range'}{'end'} < $3 );
238              
239             }
240             elsif ($line =~ /^([a-zA-Z]+)_match_to_\w+\s+"(.+)"/) {
241 440         1167 my $matchtype = "match" . lc(substr($1, 0, 1));
242 440         2613 $_clones{$name}{$matchtype}{$2} = 0;
243             }
244             elsif ($line =~ /^Positive_(\w+)\s+"(.+)"/) {
245 1079         2706 $_clones{$name}{'markers'}{$2} = 0;
246 1079         2460 $_markers{$2}{'clones'}{$name} = 0;
247 1079         1791 $_markers{$2}{'type'} = $1;
248 1079         1738 $_markers{$2}{'contigs'}{$contigNumber} = 0;
249 1079         5098 $_contigs{$contigNumber}{'markers'}{$2} = 0;
250             }
251             elsif ($line =~ /^Bands\s+(\d+)\s+(\d+)/ && !$bandsread) {
252 973         1210 my $i = 0;
253 973         968 my @numbands;
254 973         928 $bandsread = 1;
255              
256 973 100       2150 if ($map->core_exists()) {
257 355         679 while($i<$2){
258 9772         11709 push(@numbands,$cordata[($1-1)+$i]);
259 9772         12357 $i++;
260             }
261 355         551 $_clones{$name}{'bands'} = \@numbands;
262             }
263             else {
264 618         1723 push(@numbands,$1,$2);
265 618         1107 $_clones{$name}{'bands'} = \@numbands;
266             }
267 973 100       5339 if (exists($_contigs{0}{'clones'}{$name})) {
268 8         17 $_clones{$name}{'range'}{'start'} = $ctgzeropos;
269 8         18 $_clones{$name}{'range'}{'end'} = $ctgzeropos + $2;
270 8         14 $_contigs{0}{'range'}{'end'} = $ctgzeropos + $2;
271 8         36 $ctgzeropos += $2;
272             }
273             }
274             elsif ($line =~ /^Gel_number\s+(.+)/) {
275 973         4773 $_clones{$name}{'gel'} = $1;
276             }
277             elsif ($line =~ /^Remark\s+"(.+)"/) {
278 135         339 $_clones{$name}{'remark'} .= $1;
279 135         184 $_clones{$name}{'remark'} .= "\n";
280 135 100       248 if($seqclone == 1 ) {
281 123 100       506 if( $1 =~ /\,\s+Chr(\d+)\s+/){
282 30         170 $_clones{$name}{'group'} = $1;
283             }
284             }
285             }
286             elsif ($line =~ /^Fp_number\s+"(.+)"/) {
287 549         3032 $_clones{$name}{'fp_number'} = $1;
288             }
289             elsif ($line =~ /^Shotgun\s+(\w+)\s+(\w+)/) {
290 37         105 $_clones{$name}{'sequence_type'} = $1;
291 37         195 $_clones{$name}{'sequence_status'} = $2;
292             }
293             elsif ($line =~ /^Fpc_remark\s+"(.+)"/) {
294 162         329 $_clones{$name}{'fpc_remark'} .= $1;
295 162         622 $_clones{$name}{'fpc_remark'} .= "\n";
296             }
297             }
298              
299 973         1130 $curClone++;
300 973 50 33     2082 print "Adding clone $curClone...\n\r"
301             if ($self->verbose() && $curClone % 1000 == 0);
302             }
303              
304 2         15 $map->_setCloneRef(\%_clones);
305 2         43 $line = <$fh>;
306              
307 2   33     26 while (defined($line = <$fh>) && $line !~ /Contigdata/) {
308 167         227 my ($type,$name);
309              
310 167 100       524 last if ($line !~ /^Marker_(\w+)\s+:\s+"(.+)"/);
311              
312 165         369 ($type, $name) = ($1, $2);
313              
314 165         422 $_markers{$name}{'type'} = $type;
315 165         228 $_markers{$name}{'group'} = 0;
316 165         193 $_markers{$name}{'global'} = 0;
317 165         198 $_markers{$name}{'anchor'} = 0;
318              
319 165   66     720 while (defined($line = <$fh>) && $line !~ /^\s*\n$/) {
320 490 50       2224 if ($line =~ /^Global_position\s+([\d.]+)\s*(Frame)?/) {
    100          
    100          
    50          
    100          
321 0         0 my $position = $1 - floor($1/1000)*1000;
322 0         0 $position = sprintf("%.2f",$position);
323              
324 0         0 $_markers{$name}{'global'} = $position;
325 0         0 $_markers{$name}{'group'} = floor($1/1000);
326 0         0 $_markers{$name}{'anchor'} = 1;
327              
328 0 0       0 if(defined($2)) {
329 0         0 $_markers{$name}{'framework'} = 1;
330             }
331             else {
332 0         0 $_markers{$name}{'framework'} = 0;
333             }
334             }
335             elsif ($line =~ /^Anchor_bin\s+"([\w\d.]+)"/) {
336 48         99 my $grpmatch = $1;
337 48         130 my $grptype = $map->group_type();
338              
339 48         117 $grpmatch =~ /(\d+|\w)(.*)/;
340              
341 48         62 my ($group,$subgroup);
342 48         74 $group = $1;
343 48         58 $subgroup = $2;
344              
345 48 50       80 $subgroup = substr($subgroup,1) if ($subgroup =~ /^\./);
346              
347 48         82 $_markers{$name}{'group'} = $group;
348 48         268 $_markers{$name}{'subgroup'} = $subgroup;
349             }
350             elsif ($line =~ /^Anchor_pos\s+([\d.]+)\s+(F|P)?/){
351 48         122 $_markers{$name}{'global'} = $1;
352 48         65 $_markers{$name}{'anchor'} = 1;
353              
354 48 100       86 if ($2 eq 'F') {
355 26         126 $_markers{$name}{'framework'} = 1;
356             }
357             else {
358 22         131 $_markers{$name}{'framework'} = 0;
359             }
360             }
361             elsif ($line =~ /^anchor$/) {
362 0         0 $_markers{$name}{'anchor'} = 1;
363             }
364             elsif ($line =~ /^Remark\s+"(.+)"/) {
365 64         155 $_markers{$name}{'remark'} .= $1;
366 64         237 $_markers{$name}{'remark'} .= "\n";
367             }
368             }
369 165         195 $curMarker++;
370 165 50 33     312 print "Adding Marker $curMarker...\n"
371             if ($self->verbose() && $curMarker % 1000 == 0);
372             }
373              
374 2         14 $map->_setMarkerRef(\%_markers);
375              
376 2         8 my $ctgname;
377 2         9 my $grpabbr = $map->group_abbr();
378 2         28 my $chr_remark;
379              
380 2         6 $_contigs{0}{'group'} = 0;
381              
382 2         12 while (defined($line = <$fh>)) {
383              
384 31 100 66     491 if ($line =~ /^Ctg(\d+)/) {
    50          
    100          
    100          
    100          
385 12         18 $ctgname = $1;
386 12         18 $_contigs{$ctgname}{'group'} = 0;
387 12         13 $_contigs{$ctgname}{'anchor'} = 0;
388 12         16 $_contigs{$ctgname}{'position'} = 0;
389              
390 12 50       36 if ($line =~ /#\w*(.*)\w*$/) {
391 12         26 $_contigs{$ctgname}{'remark'} = $1;
392 12 50       35 if ($line =~ /#\s+Chr(\d+)\s+/) {
393 0         0 $_contigs{$ctgname}{'group'} = $1;
394 0         0 $_contigs{$ctgname}{'anchor'} = 1;
395             }
396             }
397             }
398             elsif ($line =~ /^Chr_remark\s+"(-|\+|Chr(\d+))\s+(.+)"$/) {
399              
400 0         0 $_contigs{$ctgname}{'anchor'} = 1;
401 0 0       0 $_contigs{$ctgname}{'chr_remark'} = $3 if(defined($3));
402              
403 0 0       0 if (defined($2)) {
404 0         0 $_contigs{$ctgname}{'group'} = $2;
405             }
406             else {
407 0         0 $_contigs{$ctgname}{'group'} = "?";
408             }
409             }
410             elsif ($line =~ /^User_remark\s+"(.+)"/) {
411 2         7 $_contigs{$ctgname}{'usr_remark'} = $1;
412             }
413             elsif ($line =~ /^Trace_remark\s+"(.+)"/) {
414 1         5 $_contigs{$ctgname}{'trace_remark'} = $1;
415             }
416             elsif ($grpabbr && $line =~ /^Chr_remark\s+"(\W|$grpabbr((\d+)|(\w+)|([.\w\d]+)))\s*(\{(.*)\}|\[(.*)\])?"\s+(Pos\s+((\d.)+|NaN))(NOEDIT)?/)
417             {
418 4         10 my $grpmatch = $2;
419 4         9 my $pos = $10;
420 4 50       34 if ($pos eq "NaN") {
421 0         0 $pos = 0;
422 0         0 print "Warning: Nan encountered for Contig position \n";
423             }
424 4         15 $_contigs{$ctgname}{'chr_remark'} = $6;
425 4         6 $_contigs{$ctgname}{'position'} = $pos;
426 4         6 $_contigs{$ctgname}{'subgroup'} = 0;
427              
428 4 50       11 if (defined($grpmatch)) {
429 4         7 $_contigs{$ctgname}{'anchor'} = 1;
430              
431 4 50       8 if ($grpmatch =~ /((\d+)((\D\d.\d+)|(.\d+)))|((\w+)(\.\d+))/) {
432              
433 0         0 my ($group,$subgroup);
434 0 0       0 $group = $2 if($grpabbr eq "Chr");
435 0 0       0 $subgroup = $3 if($grpabbr eq "Chr");
436              
437 0 0       0 $group = $7 if($grpabbr eq "Lg");
438 0 0       0 $subgroup = $8 if($grpabbr eq "Lg");
439              
440 0 0       0 $subgroup = substr($subgroup,1) if ($subgroup =~ /^\./);
441 0         0 $_contigs{$ctgname}{'group'} = $group;
442 0         0 $_contigs{$ctgname}{'subgroup'} = $subgroup;
443              
444             }
445             else {
446 4         8 $_contigs{$ctgname}{'group'} = $grpmatch;
447             }
448             }
449             else {
450 0         0 $_contigs{$ctgname}{'anchor'} = 1;
451 0         0 $_contigs{$ctgname}{'group'} = "?";
452             }
453             }
454 31         36 $curContig++;
455 31 50 33     50 print "Adding Contig $curContig...\n"
456             if ($self->verbose() && $curContig % 100 == 0);
457             }
458              
459 2         14 $map->_setContigRef(\%_contigs);
460 2         13 $map->_calc_markerposition();
461 2 50       21 $map->_calc_contigposition() if ($map->version() < 7.0);
462 2 50       11 $map->_calc_contiggroup() if ($map->version() == 4.6);
463              
464 2         313 return $map;
465             }
466              
467              
468             =head2 write_map
469              
470             Title : write_map
471             Usage : $mapio->write_map($map);
472             Function: Write a map out
473             Returns : none
474             Args : Bio::Map::MapI
475              
476             =cut
477              
478             sub write_map{
479 0     0 1   my ($self,@args) = @_;
480 0           $self->throw_not_implemented();
481             }
482              
483             1;
484              
485             =head1 FEEDBACK
486              
487             =head2 Mailing Lists
488              
489             User feedback is an integral part of the evolution of this and other
490             Bioperl modules. Send your comments and suggestions preferably to
491             the Bioperl mailing list. Your participation is much appreciated.
492              
493             bioperl-l@bioperl.org - General discussion
494             http://bioperl.org/wiki/Mailing_lists - About the mailing lists
495              
496             =head2 Support
497              
498             Please direct usage questions or support issues to the mailing list:
499              
500             I
501              
502             rather than to the module maintainer directly. Many experienced and
503             reponsive experts will be able look at the problem and quickly
504             address it. Please include a thorough description of the problem
505             with code and data examples if at all possible.
506              
507             =head2 Reporting Bugs
508              
509             Report bugs to the Bioperl bug tracking system to help us keep track
510             of the bugs and their resolution. Bug reports can be submitted via the
511             web:
512              
513             https://github.com/bioperl/bioperl-live/issues
514              
515             =head1 AUTHOR - Gaurav Gupta
516              
517             Email gaurav@genome.arizona.edu
518              
519             =head1 PROJECT LEADERS
520              
521             Jamie Hatfield jamie@genome.arizona.edu
522              
523             Dr. Cari Soderlund cari@genome.arizona.edu
524              
525             =head1 PROJECT DESCRIPTION
526              
527             The project was done in Arizona Genomics Computational Laboratory
528             (AGCoL) at University of Arizona.
529              
530             This work was funded by USDA-IFAFS grant #11180 titled "Web Resources
531             for the Computation and Display of Physical Mapping Data".
532              
533             For more information on this project, please refer:
534             http://www.genome.arizona.edu
535              
536             =head1 APPENDIX
537              
538             The rest of the documentation details each of the object methods.
539             Internal methods are usually preceded with a _
540              
541             =cut