3 # BioPerl module for Bio::Map::Physical
5 # Cared for by Sendu Bala <bix@sendu.me.uk>
9 # You may distribute this module under the same terms as perl itself
11 # POD documentation - main docs before the code
15 Bio::Map::Physical - A class for handling a Physical Map (such as FPC)
21 # accquire a Bio::Map::Physical using Bio::MapIO::fpc
22 my $mapio = Bio::MapIO->new(-format => "fpc",-file => "rice.fpc",
25 my $physical = $mapio->next_map();
27 # get all the markers ids
28 foreach my $marker ( $physical->each_markerid() ) {
29 print "Marker $marker\n";
31 # acquire the marker object using Bio::Map::FPCMarker
32 my $markerobj = $physical->get_markerobj($marker);
34 # get all the clones hit by this marker
35 foreach my $clone ($markerobj->each_cloneid() ) {
42 This class is basically a continer class for a collection of Contig maps and
43 other physical map information.
45 Bio::Map::Physical has been tailored to work for FPC physical maps, but
46 could probably be used for others as well (with the appropriate MapIO
49 This class also has some methods with specific functionalities:
51 print_gffstyle() : Generates GFF; either Contigwise[Default] or
54 print_contiglist() : Prints the list of Contigs, markers that hit the
55 contig, the global position and whether the marker
56 is a placement (<P>) or a Framework (<F>) marker.
58 print_markerlist() : Prints the markers list; contig and corresponding
61 matching_bands() : Given two clones [and tolerence], this method
62 calculates how many matching bands do they have.
64 coincidence_score() : Given two clones [,tolerence and gellen], this
65 method calculates the Sulston Coincidence score.
67 For faster access and better optimization, the data is stored internally in
68 hashes. The corresponding objects are created on request.
74 User feedback is an integral part of the evolution of this and other
75 Bioperl modules. Send your comments and suggestions preferably to
76 the Bioperl mailing list. Your participation is much appreciated.
78 bioperl-l@bioperl.org - General discussion
79 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
83 Report bugs to the Bioperl bug tracking system to help us keep track
84 of the bugs and their resolution. Bug reports can be submitted via the
87 http://bugzilla.open-bio.org/
89 =head1 AUTHOR - Gaurav Gupta
91 Email gaurav@genome.arizona.edu
95 Sendu Bala bix@sendu.me.uk
97 =head1 PROJECT LEADERS
99 Jamie Hatfield jamie@genome.arizona.edu
100 Dr. Cari Soderlund cari@genome.arizona.edu
102 =head1 PROJECT DESCRIPTION
104 The project was done in Arizona Genomics Computational Laboratory (AGCoL)
105 at University of Arizona.
107 This work was funded by USDA-IFAFS grant #11180 titled "Web Resources for
108 the Computation and Display of Physical Mapping Data".
110 For more information on this project, please refer:
111 http://www.genome.arizona.edu
115 The rest of the documentation details each of the object methods.
116 Internal methods are usually preceded with a _
120 # Let the code begin...
122 package Bio
::Map
::Physical
;
123 use vars
qw($MAPCOUNT);
128 use Bio::Map::Contig;
129 use Bio::Map::FPCMarker;
131 use base qw(Bio::Map::SimpleMap);
132 BEGIN { $MAPCOUNT = 1; }
134 =head1 Access Methods
136 These methods let you get and set the member variables
141 Usage : my $version = $map->version();
142 Function: Get/set the version of the program used to
144 Returns : scalar representing the version
145 Args : none to get, OR string to set
150 my ($self,$value) = @_;
151 if (defined($value)) {
152 $self->{'_version'} = $value;
154 return $self->{'_version'};
157 =head2 modification_user
159 Title : modification_user
160 Usage : my $modification_user = $map->modification_user();
161 Function: Get/set the name of the user who last modified this map
162 Returns : scalar representing the username
163 Args : none to get, OR string to set
167 sub modification_user
{
168 my ($self,$value) = @_;
169 if (defined($value)) {
170 $self->{'_modification_user'} = $value;
172 return $self->{'_modification_user'};
178 Usage : $map->group_type($grptype);
179 my $grptype = $map->group_type();
180 Function: Get/set the group type of this map
181 Returns : scalar representing the group type
182 Args : none to get, OR string to set
187 my ($self,$value) = @_;
188 if (defined($value)) {
189 $self->{'_grouptype'} = $value;
191 return $self->{'_grouptype'};
197 Usage : $map->group_abbr($grpabbr);
198 my $grpabbr = $map->group_abbr();
199 Function: get/set the group abbrev of this map
200 Returns : string representing the group abbrev
201 Args : none to get, OR string to set
206 my ($self,$value) = @_;
207 if (defined($value)) {
208 $self->{'_groupabbr'} = $value;
210 return $self->{'_groupabbr'};
216 Usage : my $core_exists = $map->core_exists();
217 Function: Get/set if the FPC file is accompanied by COR file
219 Args : none to get, OR 1|0 to set
224 my ($self,$value) = @_;
225 if (defined($value)) {
226 $self->{'_corexists'} = $value ?
1 : 0;
228 return $self->{'_corexists'};
234 Usage : my @clones = $map->each_cloneid();
235 Function: returns an array of clone names
236 Returns : list of clone names
243 return keys %{$self->{'_clones'}};
249 Usage : my $cloneobj = $map->get_cloneobj('CLONEA');
250 Function: returns an object of the clone given in the argument
251 Returns : object of the clone
252 Args : scalar representing the clone name
257 my ($self,$clone) = @_;
259 return 0 if(!defined($clone));
260 return if($clone eq "");
261 return if(!exists($self->{'_clones'}{$clone}));
263 my ($type,$contig,$bands,$gel,$group,$remark,$fp_number);
264 my ($sequence_type,$sequence_status,$fpc_remark,@amatch,@pmatch,@ematch,
265 $startrange,$endrange);
266 my %clones = %{$self->{'_clones'}{$clone}};
269 if (ref($clones{'clone'}) eq 'Bio::Map::Clone') {
270 return $clones{'clone'};
273 $type = $clones{'type'} if (exists($clones{'type'}));
274 @markers = (keys %{$clones{'markers'}}) if (exists($clones{'markers'}));
275 $contig = $clones{'contig'} if (exists($clones{'contig'}));
276 $bands = $clones{'bands'} if (exists($clones{'bands'}));
277 $gel = $clones{'gel'} if (exists($clones{'gel'}));
278 $group = $clones{'group'} if (exists($clones{'group'}));
279 $remark = $clones{'remark'} if (exists($clones{'remark'}));
281 $fp_number = $clones{'fp_number'} if (exists($clones{'fp_number'}));
282 $fpc_remark = $clones{'fpc_remark'} if (exists($clones{'fpc_remark'}));
284 $sequence_type = $clones{'sequence_type'}
285 if (exists($clones{'sequence_type'}));
286 $sequence_status = $clones{'sequence_status'}
287 if (exists($clones{'sequence_status'} ));
289 @amatch = (keys %{$clones{'matcha'}}) if (exists($clones{'matcha'}));
290 @ematch = (keys %{$clones{'matche'}}) if (exists($clones{'matche'}));
291 @pmatch = (keys %{$clones{'matchp'}}) if (exists($clones{'matchp'}));
293 $startrange = $clones{'range'}{'start'}
294 if (exists($clones{'range'}{'start'}));
295 $endrange = $clones{'range'}{'end'}
296 if (exists($clones{'range'}{'end'}));
298 #*** why doesn't it call Bio::Map::Clone->new ? Seems dangerous...
299 my $cloneobj = bless( {
301 _markers
=> \
@markers,
308 _fpnumber
=> $fp_number,
309 _sequencetype
=> $sequence_type,
310 _sequencestatus
=> $sequence_status,
311 _fpcremark
=> $fpc_remark,
315 _range
=> Bio
::Range
->new(-start
=> $startrange,
317 }, 'Bio::Map::Clone');
319 $self->{'_clones'}{$clone}{'clone'} = $cloneobj;
325 Title : each_markerid
326 Usage : my @markers = $map->each_markerid();
327 Function: returns list of marker names
328 Returns : list of marker names
335 return keys (%{$self->{'_markers'}});
340 Title : get_markerobj
341 Usage : my $markerobj = $map->get_markerobj('MARKERA');
342 Function: returns an object of the marker given in the argument
343 Returns : object of the marker
344 Args : scalar representing the marker name
349 my ($self,$marker) = @_;
351 return 0 if(!defined($marker));
352 return if($marker eq "");
353 return if(!exists($self->{'_markers'}{$marker}));
355 my ($global,$framework,$group,$anchor,$remark,$type,$linkage,$subgroup);
356 my %mkr = %{$self->{'_markers'}{$marker}};
358 return $mkr{'marker'} if (ref($mkr{'marker'}) eq 'Bio::Map::FPCMarker');
360 $type = $mkr{'type'} if(exists($mkr{'type'}));
361 $global = $mkr{'global'} if(exists($mkr{'global'} ));
362 $framework = $mkr{'framework'} if(exists($mkr{'framework'}));
363 $anchor = $mkr{'anchor'} if(exists($mkr{'anchor'}));
364 $group = $mkr{'group'} if(exists($mkr{'group'}));
365 $subgroup = $mkr{'subgroup'} if(exists($mkr{'subgroup'}));
366 $remark = $mkr{'remark'} if(exists($mkr{'remark'}));
368 my %clones = %{$mkr{'clones'}};
369 my %contigs = %{$mkr{'contigs'}};
371 my %markerpos = %{$mkr{'posincontig'}} if(exists($mkr{'posincontig'}));
373 #*** why doesn't it call Bio::Map::FPCMarker->new ? Seems dangerous...
374 my $markerobj = bless( {
378 _frame
=> $framework,
380 _subgroup
=> $subgroup,
384 _contigs
=> \
%contigs,
385 _position
=> \
%markerpos,
386 }, 'Bio::Map::FPCMarker');
388 $self->{'_markers'}{$marker}{'marker'} = $markerobj;
394 Title : each_contigid
395 Usage : my @contigs = $map->each_contigid();
396 Function: returns a list of contigs (numbers)
397 Returns : list of contigs
404 return keys (%{$self->{'_contigs'}});
409 Title : get_contigobj
410 Usage : my $contigobj = $map->get_contigobj('CONTIG1');
411 Function: returns an object of the contig given in the argument
412 Returns : object of the contig
413 Args : scalar representing the contig number
418 my ($self,$contig) = @_;
420 return 0 if(!defined($contig));
421 return if($contig eq "");
422 return if(!exists($self->{'_contigs'}{$contig}));
424 my ($group,$anchor,$uremark,$tremark,$cremark,$startrange,$endrange,
426 my %ctg = %{$self->{'_contigs'}{$contig}};
427 my (%position, %pos);
429 return $ctg{'contig'} if (ref($ctg{'contig'}) eq 'Bio::Map::Contig');
431 $group = $ctg{'group'} if (exists($ctg{'group'}));
432 $subgroup = $ctg{'subgroup'} if (exists($ctg{'subgroup'}));
433 $anchor = $ctg{'anchor'} if (exists($ctg{'anchor'}));
434 $cremark = $ctg{'chr_remark'} if (exists($ctg{'chr_remark'}));
435 $uremark = $ctg{'usr_remark'} if (exists($ctg{'usr_remark'}));
436 $tremark = $ctg{'trace_remark'} if (exists($ctg{'trace_remark'}));
438 $startrange = $ctg{'range'}{'start'}
439 if (exists($ctg{'range'}{'start'}));
440 $endrange = $ctg{'range'}{'end'}
441 if (exists($ctg{'range'}{'end'}));
443 my %clones = %{$ctg{'clones'}} if (exists($ctg{'clones'}));
444 my %markers = %{$ctg{'markers'}} if (exists($ctg{'markers'}));
446 my $pos = $ctg{'position'};
448 #*** why doesn't it call Bio::Map::Contig->new ? Seems dangerous...
449 my $contigobj = bless( {
451 _subgroup
=> $subgroup,
453 _markers
=> \
%markers,
456 _cremark
=> $cremark,
457 _uremark
=> $uremark,
458 _tremark
=> $tremark,
460 _range
=> Bio
::Range
->new(-start
=> $startrange,
462 }, 'Bio::Map::Contig');
464 $self->{'_contigs'}{$contig}{'contig'} = $contigobj;
468 =head2 matching_bands
470 Title : matching_bands
471 Usage : $self->matching_bands('cloneA','cloneB',[$tol]);
472 Function: given two clones [and tolerence], this method calculates how many
473 matching bands do they have.
474 (this method is ported directly from FPC)
475 Returns : scalar representing the number of matching bands
476 Args : names of the clones ('cloneA', 'cloneB') [Default tolerence=7]
481 my($self,$cloneA,$cloneB,$tol) = @_;
482 my($lstart,$kband,$match,$diff,$i,$j);
484 return 0 if(!defined($cloneA) || !defined($cloneB) ||
485 !($self->core_exists()));
487 $tol = 7 if (!defined($tol));
489 my %_clones = %{$self->{'_clones'}};
491 my @bandsA = @
{$_clones{$cloneA}{'bands'}};
492 my @bandsB = @
{$_clones{$cloneB}{'bands'}};
497 for ($i=0; $i<scalar(@bandsA);$i++) {
498 $kband = $bandsA[$i];
499 for ($j = $lstart; $j<scalar(@bandsB); $j++) {
500 $diff = $kband - $bandsB[$j];
501 if (abs($diff) <= $tol ) {
515 =head2 coincidence_score
517 Title : coincidence_score
518 Usage : $self->coincidence_score('cloneA','cloneB'[,$tol,$gellen]);
519 Function: given two clones [,tolerence and gellen], this method calculates
520 the Sulston Coincidence score.
521 (this method is ported directly from FPC)
522 Returns : scalar representing the Sulston coincidence score.
523 Args : names of the clones ('cloneA', 'cloneB')
524 [Default tol=7 gellen=3300.0]
528 sub coincidence_score
{
529 my($self,$cloneA,$cloneB,$tol,$gellen) = @_;
531 return 0 if(!defined($cloneA) || !defined($cloneB) ||
532 !($self->core_exists()));
534 my %_clones = %{$self->{'_clones'}};
536 my $numbandsA = scalar(@
{$_clones{$cloneA}{'bands'}});
537 my $numbandsB = scalar(@
{$_clones{$cloneB}{'bands'}});
539 my ($nL,$nH,$m,$i,$psmn,$pp,$pa,$pb,$t,$c,$a,$n);
543 $gellen = 3300.0 if (!defined($gellen));
544 $tol = 7 if (!defined($tol));
546 if ($numbandsA > $numbandsB) {
555 $m = $self->matching_bands($cloneA, $cloneB,$tol);
559 for ($i=2; $i<=$nL; $i++) {
560 $logfact[$i] = $logfact[$i - 1] + log($i);
563 $psmn = 1.0 - ((2*$tol)/$gellen);
570 for ($n = $m; $n <= $nL; $n++) {
571 $c = $logfact[$nL] - $logfact[$nL - $n] - $logfact[$n];
572 $a = exp($c + ($n * $pb) + (($nL - $n) * $pa));
576 $score = sprintf("%.e",$t);
580 =head2 print_contiglist
582 Title : print_contiglist
583 Usage : $map->print_contiglist([showall]); #[Default 0]
584 Function: prints the list of contigs, markers that hit the contig, the
585 global position and whether the marker is a placement (P) or
586 a Framework (F) marker.
588 Args : [showall] [Default 0], 1 includes all the discrepant markers
592 sub print_contiglist
{
593 my ($self,$showall) = @_;
596 $showall = 0 if (!defined($showall));
597 my %_contigs = %{$self->{'_contigs'}};
598 my %_markers = %{$self->{'_markers'}};
599 my %_clones = %{$self->{'_clones'}};
601 my @contigs = $self->each_contigid();
602 my @sortedcontigs = sort {$a <=> $b } @contigs;
604 print "\n\nContig List\n\n";
605 foreach my $contig (@sortedcontigs) {
609 my $ctgAnchor = $_contigs{$contig}{'anchor'};
610 my $ctgGroup = $_contigs{$contig}{'group'};
612 my @mkr = keys ( %{$_contigs{$contig}{'markers'}} );
614 foreach my $marker (@mkr) {
615 my $mrkGroup = $_markers{$marker}{'group'};
616 my $mrkGlobal = $_markers{$marker}{'global'};
617 my $mrkFramework = $_markers{$marker}{'framework'};
618 my $mrkAnchor = $_markers{$marker}{'anchor'};
620 if($ctgGroup =~ /\d+|\w/ && $ctgGroup != 0) {
621 if ($mrkGroup eq $ctgGroup) {
622 if ($mrkFramework == 0) {
623 $pos = $mrkGlobal."P";
626 $pos = $mrkGlobal."F";
628 $list{$marker} = $pos;
630 elsif ($showall == 1) {
631 my $chr = $self->group_abbr().$mrkGroup;
632 $alist{$marker} = $chr;
635 elsif ($showall == 1 && $ctgGroup !~ /\d+/) {
636 my $chr = $self->group_abbr().$mrkGroup;
637 $alist{$marker} = $chr;
642 $chr = $self->group_abbr().$ctgGroup if ($ctgGroup =~ /\d+|\w/);
644 if ($showall == 1 ) {
646 print " ctg$contig ", $chr, " "
647 if ($_contigs{$contig}{'group'} !~ /\d+|\w/);
649 elsif ($ctgGroup =~ /\d+|\w/ && $ctgGroup ne 0){
650 print " ctg",$contig, " ",$chr, " ";
653 while (my ($k,$v) = each %list) {
657 print "\n" if ($showall == 0 && $ctgGroup =~ /\d+|\w/ &&
661 while (my ($k,$v) = each %alist) {
669 =head2 print_markerlist
671 Title : print_markerlist
672 Usage : $map->print_markerlist();
673 Function : prints the marker list; contig and corresponding number of
674 clones for each marker.
680 sub print_markerlist
{
683 my %_contigs = %{$self->{'_contigs'}};
684 my %_markers = %{$self->{'_markers'}};
685 my %_clones = %{$self->{'_clones'}};
687 print "Marker List\n\n";
689 foreach my $marker ($self->each_markerid()) {
690 print " ",$marker, " ";
693 my %mclones = %{$_markers{$marker}{'clones'}};
695 foreach my $clone (%mclones) {
696 if (exists($_clones{$clone}{'contig'}) ) {
697 my $ctg = $_clones{$clone}{'contig'};
699 if (exists($list{$ctg})) {
700 my $clonehits = $list{$ctg};
702 $list{$ctg} = $clonehits;
709 while (my ($k,$v) = each %list) {
716 =head2 print_gffstyle
718 Title : print_gffstyle
719 Usage : $map->print_gffstyle([style]);
720 Function : prints GFF; either Contigwise (default) or Groupwise
722 Args : [style] default = 0 contigwise, else
723 1 groupwise (chromosome-wise).
728 my ($self,$style) = @_;
730 $style = 0 if(!defined($style));
732 my %_contigs = %{$self->{'_contigs'}};
733 my %_markers = %{$self->{'_markers'}};
734 my %_clones = %{$self->{'_clones'}};
737 my ($depth, $save_depth);
744 # Calculate the position for the marker in the contig
746 my @contigs = $self->each_contigid();
747 my @sortedcontigs = sort {$a <=> $b } @contigs;
754 foreach my $contig (@sortedcontigs) {
755 if($_contigs{$contig}{'range'} ) {
756 $offset = $_contigs{$contig}{'range'}{'start'};
759 $offset = $offset * -1;
760 $gffcontigs{$contig}{'start'} = 1;
761 $gffcontigs{$contig}{'end'} =
762 ($_contigs{$contig}{'range'}{'end'} +
763 $offset ) * $basepair + 1;
767 $gffcontigs{$contig}{'start'} =
768 $_contigs{$contig}{'range'}{'start'} * $basepair;
769 $gffcontigs{$contig}{'end'} =
770 $_contigs{$contig}{'range'}{'end'} * $basepair;
774 $gffcontigs{$contig}{'start'} = 1;
775 $gffcontigs{$contig}{'end'} = 1;
778 my @clones = keys %{$_contigs{$contig}{'clones'}};
779 foreach my $clone (@clones) {
780 if(exists ($_clones{$clone}{'range'}) ) {
781 my $gffclone = $clone;
783 $gffclone =~ s/sd1$//;
785 $gffclones{$gffclone}{'start'} =
786 (($_clones{$clone}{'range'}{'start'} + $offset) *
789 $gffclones{$gffclone}{'end'} =
790 (($_clones{$clone}{'range'}{'end'}
791 + $offset) * $basepair + 1);
795 my %markers = %{$_clones{$clone}{'markers'}}
796 if (exists($_clones{$clone}{'markers'}));
798 while (my ($k,$v) = each %markers) {
799 $gffmarkers{$contig}{$k} =
800 ( ( $_clones{$clone}{'range'}{'start'} +
801 $_clones{$clone}{'range'}{'end'} ) / 2 ) *
808 my %markers = %{$_contigs{$contig}{'markers'}}
809 if (exists($_contigs{$contig}{'markers'}));
811 while (my ($k,$v) = each %markers) {
812 $gffmarkers{$contig}{$k} = ($v + $offset) * $basepair + 1;
818 foreach my $contig (@sortedcontigs) {
820 if(exists ($_contigs{$contig}{'range'} ) ) {
821 print join("\t","ctg$contig","assembly","contig",
822 $gffcontigs{$contig}{'start'},
823 $gffcontigs{$contig}{'end'},".",".",".",
824 "Sequence \"ctg$contig\"; Name \"ctg$contig\"\n"
828 my @clones = (keys %{$_contigs{$contig}{'clones'}} );
830 foreach my $clone (@clones) {
831 if(exists ($_clones{$clone}{'range'}) ) {
832 print join("\t","ctg$contig","FPC");
834 my $type = $_clones{$clone}{'type'};
836 if($clone =~ /sd1$/) {
840 print join ("\t","\t$type",$gffclones{$clone}{'start'},
841 $gffclones{$clone}{'end'},".",".",".",
842 "$type \"$clone\"; Name \"$clone\"");
844 my @markers = keys %{$_clones{$clone}{'markers'}};
845 print "; Marker_hit" if (scalar(@markers));
847 foreach my $mkr(@markers) {
848 if (exists($_markers{$mkr}{'framework'})) {
849 print " \"$mkr ",$_markers{$mkr}{'group'}," ",
850 $_markers{$mkr}{'global'},"\"";
853 print " \"$mkr 0 0\"";
856 print "; Contig_hit \"",$_clones{$clone}{'contig'},"\" "
857 if (defined($_clones{$clone}{'contig'}));
862 if (exists ($_contigs{$contig}{'markers'}) ) {
863 my %list = %{$_contigs{$contig}{'markers'}};
865 while (my ($k,$v) = each %list) {
866 print "ctg", $contig, "\tFPC\t";
867 my $position = $gffmarkers{$contig}{$k};
871 $type = "electronicmarker"
872 if ($_markers{$k}{'type'} eq "eMRK");
874 if( exists($_markers{$k}{'framework'})) {
875 $type = "frameworkmarker"
876 if($_markers{$k}{'framework'} == 1);
878 $type = "placementmarker"
879 if($_markers{$k}{'framework'} == 0);
882 print join ("\t","$type",$position,$position,".",".",
883 ".","$type \"$k\"; Name \"$k\"");
886 my @clones = keys %{$_markers{$k}{'clones'}};
888 foreach my $cl (@clones) {
889 push (@clonelist, $cl)
890 if($_clones{$cl}{'contig'} == $contig);
894 print("; Contig_hit
\"ctg
$contig - ",scalar(@clonelist),
895 "\" (@clonelist)\n");
902 my $margin = 2 * $basepair;
903 my $displacement = 0;
906 foreach my $contig (@sortedcontigs) {
908 my $chr = $_contigs{$contig}{'group'};
909 $chr = 0 if ($chr !~ /\d+|\w+/);
911 $recordchr->{group} = $chr;
912 $recordchr->{contig} = $contig;
913 $recordchr->{position} = $_contigs{$contig}{'position'};
915 push @grouplist, $recordchr;
918 my @chr = keys (%{$_groups{'group'}});
921 if ($self->group_type eq 'Chromosome') {
922 @sortedchr = sort { $a->{'group'} <=> $b->{'group'}
924 $a->{'contig'} <=> $b->{'contig'}
928 @sortedchr = sort { $a->{'group'} cmp $b->{'group'}
930 $a->{'contig'} cmp $b->{'contig'}
936 foreach my $chr (@sortedchr) {
937 my $chrname = $self->group_abbr().$chr->{'group'};
939 if ($lastchr eq -1 || $chr->{'group'} ne $lastchr ) {
940 $lastchr = $chr->{'group'} if ($lastchr eq -1);
943 # caluclate the end position of the contig
948 if ($chr->{contig} != 0) {
949 foreach my $ch (@sortedchr) {
950 if ($ch->{'group'} eq $chr->{'group'}) {
951 if($ch->{'contig'} != 0) {
952 my $ctg = $ch->{'contig'}
953 if($ch->{'contig'} != 0);
955 $chrend += $gffcontigs{$ctg}->{'end'};
960 $chrend += ($ctgcount-1) * $margin;
963 $chrend = $gffcontigs{'0'}->{'end'};
966 $chrname = $self->group_abbr()."ctg0
"
967 if ($chr->{'contig'} == 0);
969 print join ("\t", $chrname,"assembly
","Chromosome
",1,
970 "$chrend",".",".",".",
971 "Sequence
\"$chrname\"; Name
\"$chrname\"\n");
974 print join ("\t", $chrname,"assembly
","Chromosome
",1,
975 "$chrend",".",".",".",
976 "Sequence
\"$chrname\"; Name
\"$chrname\"\n")
977 if ($chr->{'group'} ne $lastchr && $chr->{'group'} eq 0 );
979 $lastchr = $chr->{'group'};
980 $lastchr = -1 if ($chr->{'contig'} == 0);
982 my $contig = $chr->{'contig'};
984 if(exists ($_contigs{$contig}{'range'} ) ) {
986 print join ("\t",$chrname, "FPC
","contig
",
987 $gffcontigs{$contig}{'start'}+$displacement,
988 $gffcontigs{$contig}{'end'}+$displacement,
990 "contig
\"ctg
$contig\"; Name
\"ctg
$contig\"\n");
993 my @clones = (keys %{$_contigs{$contig}{'clones'}} );
994 foreach my $clone (@clones) {
995 if(exists ($_clones{$clone}{'range'}) ) {
996 print join ("\t",$chrname,"FPC
");
997 my $type = $_clones{$clone}{'type'};
999 if ($clone =~ /sd1$/) {
1001 $type = "sequenced
";
1004 print join ("\t","\t$type",$gffclones{$clone}{'start'}
1005 +$displacement,$gffclones{$clone}{'end'}
1006 +$displacement,".",".",".",
1007 "$type \"$clone\"; Name
\"$clone\"");
1009 my @markers = keys %{$_clones{$clone}{'markers'}};
1010 print "; Marker_hit
" if (scalar(@markers));
1012 foreach my $mkr(@markers) {
1013 if (exists($_markers{$mkr}{'framework'})) {
1014 print " \"$mkr ",$_markers{$mkr}{'group'}," ",
1015 $_markers{$mkr}{'global'},"\"";
1018 print (" \"$mkr 0 0\"");
1021 print "; Contig_hit
\"",$_clones{$clone}{'contig'},"\" "
1022 if (defined($_clones{$clone}{'contig'}));
1027 if (exists ($_contigs{$contig}{'markers'}) ) {
1028 my %list = %{$_contigs{$contig}{'markers'}};
1030 while (my ($k,$v) = each %list) {
1031 print join ("\t",$chrname,"FPC
");
1032 my $type = "marker
";
1034 $type = "electronicmarker
"
1035 if ($_markers{$k}{'type'} eq "eMRK
");
1037 if( exists($_markers{$k}{'framework'})) {
1038 $type = "frameworkmarker
"
1039 if($_markers{$k}{'framework'} == 1);
1041 $type = "placementmarker
"
1042 if($_markers{$k}{'framework'} == 0);
1045 print join ("\t","\t$type",$gffmarkers{$contig}{$k}
1046 + $displacement,$gffmarkers{$contig}{$k}
1047 + $displacement,".",".",".",
1048 "$type \"$k\"; Name
\"$k\"");
1051 my @clones = keys %{$_markers{$k}{'clones'}};
1053 foreach my $cl (@clones) {
1054 push (@clonelist, $cl)
1055 if($_clones{$cl}{'contig'} == $contig);
1059 print("; Contig_hit \"ctg$contig - ",
1060 scalar(@clonelist),"\" (@clonelist)\n");
1063 $displacement += $margin + $gffcontigs{$contig}{'end'};
1068 =head2 _calc_markerposition
1070 Title : _calc_markerposition
1071 Usage : $map->_calc_markerposition();
1072 Function: Calculates the position of the marker in the contig
1078 sub _calc_markerposition
{
1080 my %_contigs = %{$self->{'_contigs'}};
1081 my %_markers = %{$self->{'_markers'}};
1082 my %_clones = %{$self->{'_clones'}};
1085 my ($depth, $save_depth);
1092 # Calculate the position for the marker in the contig
1094 my @contigs = $self->each_contigid();
1095 my @sortedcontigs = sort {$a <=> $b } @contigs;
1100 foreach my $marker ($self->each_markerid()) {
1101 my (@ctgmarker, @sortedctgmarker);
1103 my @clones = (keys %{$_markers{$marker}{'clones'}})
1104 if (exists ($_markers{$marker}{'clones'} ));
1106 foreach my $clone (@clones) {
1108 $record->{contig
} = $_clones{$clone}{'contig'};
1109 $record->{start
} = $_clones{$clone}{'range'}{'start'};
1110 $record->{end
} = $_clones{$clone}{'range'}{'end'};
1111 push @ctgmarker,$record;
1114 # sorting by contig and left position
1115 @sortedctgmarker = sort { $a->{'contig'} <=> $b->{'contig'}
1117 $b->{'start'} <=> $a->{'start'}
1122 for ($i=0; $i < scalar(@sortedctgmarker); $i++) {
1123 if ($ctg != $sortedctgmarker[$i]->{'contig'}) {
1125 $ctg = $sortedctgmarker[$i]->{'contig'};
1128 if ($depth > $save_depth){
1129 $pos = ($x + $y) >> 1;
1130 $_contigs{$ctg}{'markers'}{$marker} = $pos;
1131 $_markers{$marker}{'posincontig'}{$ctg} = $pos;
1135 $ctg = $sortedctgmarker[$i]->{'contig'};
1136 $x = $sortedctgmarker[$i]->{'start'};
1137 $y = $sortedctgmarker[$i]->{'end'};
1140 $pos = ($x + $y) >> 1;
1141 $_contigs{$ctg}{'markers'}{$marker} = $pos;
1142 $_markers{$marker}{'posincontig'}{$ctg} = $pos;
1144 $depth = $save_depth = 1;
1146 elsif ($sortedctgmarker[$i] <= $y) {
1147 $stack[$depth++] = $sortedctgmarker[$i]->{'end'};
1149 if ($x < $sortedctgmarker[$i]->{'start'} ) {
1150 $x = $sortedctgmarker[$i]->{'start'};
1153 if ($y > $sortedctgmarker[$i]->{'end'}) {
1154 $y = $sortedctgmarker[$i]->{'end'};
1158 if ($depth > $save_depth) {
1159 $save_depth = $depth;
1160 $pos = ($x + $y) >> 1;
1161 $_contigs{$ctg}{'markers'}{$marker} = $pos;
1162 $_markers{$marker}{'posincontig'}{$ctg} = $pos;
1165 $x = $sortedctgmarker[$i]->{'start'};
1166 $y = $sortedctgmarker[$i]->{'end'};
1167 $stack[$depth++] = $y;
1169 for($j=-1, $k=0, $s=0; $s<$depth; $s++) {
1170 if ($stack[$s] <$x) {
1172 $j = $s if ($j == -1);
1177 $y = $stack[$s] if ($y > $stack[$s]);
1178 if ($stack[$j] == -1) {
1179 $stack[$j] = $stack[$s];
1181 while ($stack[$j] != -1) {$j++;}
1190 if ($depth > $save_depth) {
1191 $pos = ($x + $y) >> 1;
1192 $_contigs{$ctg}{'markers'}{$marker} = $pos;
1193 $_markers{$marker}{'posincontig'}{$ctg} = $pos;
1199 =head2 _calc_contigposition
1201 Title : _calc_contigposition
1202 Usage : $map->_calc_contigposition();
1203 Function: calculates the position of the contig in the group
1209 sub _calc_contigposition
{
1212 my %_contigs = %{$self->{'_contigs'}};
1213 my %_markers = %{$self->{'_markers'}};
1214 my %_clones = %{$self->{'_clones'}};
1216 my @contigs = $self->each_contigid();
1217 my @sortedcontigs = sort {$a <=> $b } @contigs;
1219 foreach my $contig (@sortedcontigs) {
1223 if (exists($_contigs{$contig}{'group'}) ) {
1225 my %weightedmarkers;
1226 my @mkrs = keys (%{$_contigs{$contig}{'markers'}})
1227 if (exists($_contigs{$contig}{'markers'})) ;
1229 my $chr = $_contigs{$contig}{'group'};
1230 $chr = 0 if ($_contigs{$contig}{'group'} =~ /\?/);
1232 foreach my $mkr (@mkrs) {
1233 if (exists($_markers{$mkr}{'group'})) {
1234 if ( $_markers{$mkr}{'group'} == $chr ) {
1235 my @mkrclones = keys( %{$_markers{$mkr}{'clones'}});
1236 my $clonescount = 0;
1237 foreach my $clone (@mkrclones) {
1239 if ($_clones{$clone}{'contig'} == $contig);
1241 $weightedmarkers{$_markers{$mkr}{'global'}} =
1247 my $weightedctgsum = 0;
1250 while (my ($mpos,$hits) = each %weightedmarkers) {
1251 $weightedctgsum += ($mpos * $hits);
1252 $totalhits += $hits;
1255 $position = sprintf("%.2f",$weightedctgsum / $totalhits)
1256 if ($totalhits != 0);
1258 $_contigs{$contig}{'position'} = $position;
1263 =head2 _calc_contiggroup
1265 Title : _calc_contiggroup
1266 Usage : $map->_calc_contiggroup();
1267 Function: calculates the group of the contig
1273 sub _calc_contiggroup
{
1275 my %_contig = %{$self->{'_contigs'}};
1276 my @contigs = $self->each_contigid();
1278 foreach my $ctg (@contigs) {
1279 my $chr = floor
($ctg/1000);
1280 $_contig{$ctg}{'group'} = $chr;
1284 =head2 _setI<E<lt>TypeE<gt>>Ref
1286 Title : _set<Type>Ref
1287 Usage : These are used for initializing the reference of the hash in
1288 Bio::MapIO (fpc.pm) to the corresponding hash in Bio::Map
1289 (physical.pm). Should be used only from Bio::MapIO System.
1290 $map->setCloneRef(\%_clones);
1291 $map->setMarkerRef(\%_markers);
1292 $map->setContigRef(\%_contigs);
1293 Function: sets the hash references to the corresponding hashes
1295 Args : reference of the hash.
1300 my ($self, $ref) = @_;
1301 %{$self->{'_clones'}} = %{$ref};
1305 my ($self, $ref) = @_;
1306 %{$self->{'_markers'}} = %{$ref};
1310 my ($self, $ref) = @_;
1311 %{$self->{'_contigs'}} = %{$ref};