3 See the NOTICE file distributed with
this work
for additional information
4 regarding copyright ownership.
6 Licensed under the Apache License, Version 2.0 (the
"License");
7 you may not use
this file except in compliance with the License.
8 You may obtain a copy of the License at
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an
"AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License
for the specific language governing permissions and
16 limitations under the License.
23 Please email comments or questions to the
public Ensembl
24 developers list at <http:
26 Questions may also be sent to the Ensembl help desk at
37 Do not use
this module
if you can avoid it. It has been replaced by
39 become very bloated, and quite unweildy. It was decided to replace
40 it completely with a smaller, light-weight feature
class rather than
41 attempting to refactor this class, and maintain strict backwards
44 Part of the complexity of this class was in its extensive
45 inheritance. As an example the following is a simplified inheritance
46 heirarchy that was present for
Bio::EnsEMBL::DnaAlignFeature:
48 Bio::EnsEMBL::DnaAlignFeature
57 easier to understand and maintain.
64 # Let the code begin...
78 my($caller,@args) = @_;
83 bless $self, ref $caller;
88 $self->{
'_gsf_tag_hash'} = {};
89 $self->{
'_gsf_sub_array'} = [];
90 $self->{
'_parse_h'} = {};
91 $self->{
'_is_splittable'} = 0;
93 my ($start,$end,$strand,$frame,$score,$analysis,$seqname, $source_tag,
94 $primary_tag, $percent_id, $p_value, $phase, $end_phase) =
111 # $gff_string && $self->_from_gff_string($gff_string);
113 if ( defined $analysis && $analysis ne
"") { $self->analysis($analysis)};
114 if ( defined ($start) && $start ne
"" ) { $self->start($start)};
115 if ( defined ($end ) && $end ne
"" ) { $self->end($end)}
116 if ( defined $strand && $strand ne
"") { $self->strand($strand)}
117 if ( defined $frame && $frame ne
"") { $self->frame($frame)}
118 if ( defined $score && $score ne
"") { $self->score($score)}
119 if ( defined $seqname && $seqname ne
"") { $self->seqname($seqname)};
120 if ( defined $percent_id && $percent_id ne
""){ $self->percent_id($percent_id)};
121 if ( defined $p_value && $p_value ne
"") { $self->p_value($p_value)};
122 if ( defined $phase && $phase ne
"") { $self->phase($phase)};
123 if ( defined $end_phase && $end_phase ne
"") { $self->end_phase($end_phase)};
125 return $self; # success - we hope!
137 Usage : $start = $feat->start
139 Function: Get/set on the start coordinate of the feature
147 my ($self,$value) = @_;
149 if (defined($value)) {
150 if ($value !~ /^\-?\d+/ ) {
151 $self->throw(
"$value is not a valid start");
154 $self->{
'_gsf_start'} = $value
157 return $self->{
'_gsf_start'};
164 Usage : $end = $feat->end
166 Function: get/set on the end coordinate of the feature
174 my ($self,$value) = @_;
176 if (defined($value)) {
177 if( $value !~ /^\-?\d+/ ) {
178 $self->throw(
"[$value] is not a valid end");
181 $self->{
'_gsf_end'} = $value;
184 return $self->{
'_gsf_end'};
200 my ($self,@args) = @_;
202 return $self->end - $self->start +1;
209 Usage : $strand = $feat->strand()
210 $feat->strand($strand)
211 Function: get/set on strand information, being 1,-1 or 0
219 my ($self,$value) = @_;
221 if (defined($value)) {
222 if( $value eq
'+' ) { $value = 1; }
223 if( $value eq
'-' ) { $value = -1; }
224 if( $value eq
'.' ) { $value = 0; }
226 if( $value != -1 && $value != 1 && $value != 0 ) {
227 $self->throw(
"$value is not a valid strand info");
229 $self->{
'_gsf_strand'} = $value;
232 return $self->{
'_gsf_strand'};
240 Arg [3] : (optional)
int $strand
241 Example : $feature->move(100, 200, -1);
242 Description: Moves a feature to a different location. This is faster
243 then calling 3 seperate accesors in a large loop.
246 Caller : BaseFeatureAdaptor
251 my ($self, $start, $end, $strand) = @_;
253 $self->{
'_gsf_start'} = $start;
254 $self->{
'_gsf_end'} = $end;
255 if(defined $strand) {
256 $self->{
'_gsf_strand'} = $strand;
264 Usage : $score = $feat->score()
266 Function: get/set on score information
268 Args : none
if get, the
new value
if set
274 my ($self,$value) = @_;
276 if(defined ($value) ) {
277 if( $value !~ /^[+-]?\d+\.?\d*(e-\d+)?/ ) {
278 $self->throw(
"'$value' is not a valid score");
280 $self->{
'_gsf_score'} = $value;
283 return $self->{
'_gsf_score'};
289 Usage : $frame = $feat->frame()
291 Function: get/set on frame information
293 Args : none
if get, the
new value
if set
299 my ($self,$value) = @_;
301 if (defined($value)) {
302 if( $value != 1 && $value != 2 && $value != 3 ) {
303 $self->throw(
"'$value' is not a valid frame");
305 $self->{
'_gsf_frame'} = $value;
308 return $self->{
'_gsf_frame'};
314 Usage : $tag = $feat->primary_tag()
315 $feat->primary_tag(
'exon')
316 Function: get/set on the primary tag
for a feature,
325 my ($self,$arg) = @_;
327 unless($self->analysis) {
331 return $self->analysis->gff_feature();
337 Usage : $tag = $feat->source_tag()
338 $feat->source_tag(
'genscan');
339 Function: Returns the source tag
for a feature,
348 my ($self,$arg) = @_;
350 unless($self->analysis) {
354 return $self->analysis->gff_source();
361 Usage : $sf->analysis();
362 Function: Store details of the program/database
363 and versions used to create
this feature.
373 my ($self,$value) = @_;
375 if (defined($value)) {
376 unless(ref($value) && $value->isa(
'Bio::EnsEMBL::Analysis')) {
377 $self->throw(
"Analysis is not a Bio::EnsEMBL::Analysis object "
378 .
"but a $value object");
381 $self->{_analysis} = $value;
383 #if _analysis is not defined, create a new analysis object
384 unless(defined $self->{_analysis}) {
389 return $self->{_analysis};
395 Usage : $sf->validate;
396 Function: Checks whether all the data is present in the
408 $self->vthrow(
"Seqname not defined in feature") unless defined($self->seqname);
409 $self->vthrow(
"start not defined in feature") unless defined($self->start);
410 $self->vthrow(
"end not defined in feature") unless defined($self->end);
411 $self->vthrow(
"strand not defined in feature") unless defined($self->strand);
412 $self->vthrow(
"score not defined in feature") unless defined($self->score);
413 $self->vthrow(
"analysis not defined in feature") unless defined($self->analysis);
415 if ($self->end < $self->start) {
416 $self->vthrow(
"End coordinate < start coordinate");
424 my ($self,$message) = @_;
426 print(STDERR
"Error validating feature [$message]\n");
427 print(STDERR
" Seqname : [" . $self->{_seqname} .
"]\n");
428 print(STDERR
" Start : [" . $self->{_gsf_start} .
"]\n");
429 print(STDERR
" End : [" . $self->{_gsf_end} .
"]\n");
430 print(STDERR
" Strand : [" .
431 ((defined ($self->{_gsf_strand})) ? $self->{_gsf_strand} :
"undefined") .
"]\n");
433 print(STDERR
" Score : [" . $self->{_gsf_score} .
"]\n");
435 print(STDERR
" Analysis : [" . $self->{_analysis}->dbID .
"]\n");
437 $self->throw(
"Invalid feature - see dump on STDERR");
441 =head2 validate_prot_feature
443 Title : validate_prot_feature
453 # Shouldn't this go as "validate" into Pro_SeqFeature?
454 sub validate_prot_feature{
455 my ($self,$num) = @_;
456 $self->throw(
"Seqname not defined in feature") unless defined($self->seqname);
457 $self->throw(
"start not defined in feature") unless defined($self->start);
458 $self->throw(
"end not defined in feature") unless defined($self->end);
460 $self->throw(
"score not defined in feature") unless defined($self->score);
461 $self->throw(
"percent_id not defined in feature") unless defined($self->percent_id);
462 $self->throw(
"evalue not defined in feature") unless defined($self->p_value);
464 $self->throw(
"analysis not defined in feature") unless defined($self->analysis);
469 # These methods are specified in the SeqFeatureI interface but we don't want
470 # people to store data in them. These are just here in order to keep
471 # existing code working
477 Usage : $value = $self->has_tag(
'some_tag')
478 Function: Returns the value of the tag (undef
if
487 my ($self,$tag) = (shift, shift);
489 return exists $self->{
'_gsf_tag_hash'}->{$tag};
494 Title : add_tag_value
495 Usage : $self->add_tag_value(
'note',
"this is a note");
497 Args : tag (
string) and value (any scalar)
503 my ($self,$tag,$value) = @_;
505 if( !defined $self->{
'_gsf_tag_hash'}->{$tag} ) {
506 $self->{
'_gsf_tag_hash'}->{$tag} = [];
509 push(@{$self->{
'_gsf_tag_hash'}->{$tag}},$value);
512 =head2 each_tag_value
514 Title : each_tag_value
525 my ($self,$tag) = @_;
526 if( ! exists $self->{
'_gsf_tag_hash'}->{$tag} ) {
527 $self->throw(
"asking for tag value that does not exist $tag");
530 return @{$self->{
'_gsf_tag_hash'}->{$tag}};
537 Usage : @tags = $feat->all_tags()
538 Function: gives all tags
for this feature
539 Returns : an array of strings
546 my ($self,@args) = @_;
548 return keys %{$self->{
'_gsf_tag_hash'}};
555 Arg [1] :
string $seqname
556 Example : $seqname = $self->seqname();
557 Description: Obtains the seqname of
this features sequence. This is set
558 automatically when a sequence with a name is attached, or may
562 Caller : general, attach_seq
567 my ($self,$seqname) = @_;
569 my $seq = $self->contig();
571 if(defined $seqname) {
572 $self->{_seqname} = $seqname;
574 if($seq && ref $seq && $seq->can(
'name')) {
575 $self->{_seqname} = $seq->name();
579 return $self->{_seqname};
586 Usage : $sf->attach_seq($seq)
587 Function: Attaches a Bio::PrimarySeqI
object to
this feature. This
588 Bio::PrimarySeqI
object is
for the *entire* sequence: ie
598 my ($self, $seq) = @_;
605 Example : $tseq = $sf->seq()
606 Function: returns the sequence (
if any )
for this feature truncated to the range spanning the feature
607 Returns : a Bio::PrimarySeq object (I reckon)
612 my ($self,$arg) = @_;
615 $self->throw(
"Calling SeqFeature::Generic->seq with an argument. " .
616 "You probably want attach_seq");
619 if( ! exists $self->{
'_gsf_seq'} ) {
623 # assumming our seq object is sensible, it should not have to yank
624 # the entire sequence out here.
626 my $seq = $self->{
'_gsf_seq'}->trunc($self->start(),$self->end());
629 if( $self->strand == -1 ) {
631 # ok. this does not work well (?)
632 #print STDERR "Before revcom", $seq->str, "\n";
634 #print STDERR "After revcom", $seq->str, "\n";
643 Usage : $whole_seq = $sf->entire_seq()
644 Function: gives the entire sequence that
this seqfeature is attached to
655 return $self->contig;
659 =head2 sub_SeqFeature
661 Title : sub_SeqFeature
662 Usage : @feats = $feat->sub_SeqFeature();
663 Function: Returns an array of sub Sequence Features
673 if ( $self->{
'_gsf_sub_array'} ) {
674 return @{ $self->{
'_gsf_sub_array'} };
680 =head2 add_sub_SeqFeature
682 Title : add_sub_SeqFeature
683 Usage : $feat->add_sub_SeqFeature($subfeat);
684 $feat->add_sub_SeqFeature($subfeat,
'EXPAND')
685 Function: adds a SeqFeature into the subSeqFeature array.
686 with no
'EXPAND' qualifer, subfeat will be tested
687 as to whether it lies inside the parent, and
throw
690 If EXPAND is used, the parents start/end/strand will
691 be adjusted so that it grows to accommodate the
new
694 Args : An
object which has the SeqFeatureI interface
699 sub add_sub_SeqFeature{
700 my ($self,$feat,$expand) = @_;
702 if( !$feat->isa(
'Bio::SeqFeatureI') ) {
703 $self->warn(
"$feat does not implement Bio::SeqFeatureI. Will add it anyway, but beware...");
706 if( $expand eq
'EXPAND' ) {
707 # if this doesn't have start/end set - forget it!
708 if( !defined $self->start && !defined $self->end ) {
709 $self->start($feat->start());
710 $self->end($feat->end());
711 $self->strand($feat->strand);
714 if( $feat->start < $self->start ) {
715 $start = $feat->start;
718 if( $feat->end > $self->end ) {
722 $self->start($start);
727 if( !defined($feat->start()) || !defined($feat->end()) ||
728 !defined($self->start()) || !defined($self->end())) {
729 $self->throw(
"This SeqFeature and the sub_SeqFeature must define".
732 if($feat->start() > $feat->end() || $self->start() > $self->end()) {
733 $self->throw(
"This SeqFeature and the sub_SeqFeature must have " .
734 "start that is less than or equal to end.");
736 if($feat->start() < $self->start() || $feat->end() > $self->end() ) {
737 $self->throw(
"$feat is not contained within parent feature, " .
738 "and expansion is not valid");
742 push(@{$self->{
'_gsf_sub_array'}},$feat);
746 =head2 flush_sub_SeqFeature
748 Title : flush_sub_SeqFeature
749 Usage : $sf->flush_sub_SeqFeature
750 Function: Removes all sub SeqFeature
751 (
if you want to remove only a subset, take
752 an array of them all, flush them, and add
753 back only the guys you want)
761 sub flush_sub_SeqFeature {
764 $self->{
'_gsf_sub_array'} = []; # zap the array implicitly.
769 my ($self,$value) = @_;
771 if (defined($value)) {
772 $self->{_id} = $value;
782 Usage : $pid = $feat->percent_id()
783 $feat->percent_id($pid)
784 Function: get/set on percentage identity information
786 Args : none
if get, the
new value
if set
791 my ($self,$value) = @_;
795 $self->{_percent_id} = $value;
798 return $self->{_percent_id};
804 Usage : $p_val = $feat->p_value()
805 $feat->p_value($p_val)
806 Function: get/set on p value information
808 Args : none
if get, the
new value
if set
813 my ($self,$value) = @_;
817 $self->{_p_value} = $value;
820 return $self->{_p_value};
826 Usage : $phase = $feat->phase()
828 Function: get/set on start phase of predicted
exon feature
830 Args : none
if get, 0,1 or 2
if set.
835 my ($self, $value) = @_;
837 if (defined($value) )
839 $self->throw(
"Valid values for Phase are [0,1,2]")
if ($value < 0 || $value > 2);
840 $self->{_phase} = $value;
843 return $self->{_phase};
849 Usage : $end_phase = $feat->end_phase()
850 $feat->end_phase($end_phase)
851 Function: returns end_phase based on phase and length of feature
853 Args : none
if get, 0,1 or 2
if set.
858 my ($self, $value) = @_;
862 $self->throw(
"Valid values for Phase are [0,1,2]")
if ($value < 0 || $value > 2);
863 $self->{_end_phase} = $value;
866 return $self->{_end_phase};
877 if ((defined $self->strand)&&($self->strand == -1)) {
881 $str .= (defined $self->seqname) ? $self->seqname.
"\t" :
"\t";
882 $str .= (defined $self->source_tag) ? $self->source_tag.
"\t" :
"\t";
883 $str .= (defined $self->primary_tag) ? $self->primary_tag.
"\t" :
"\t";
884 $str .= (defined $self->start) ? $self->start.
"\t" :
"\t";
885 $str .= (defined $self->end) ? $self->end.
"\t" :
"\t";
886 $str .= (defined $self->score) ? $self->score.
"\t" :
"\t";
887 $str .= (defined $self->strand) ? $strand.
"\t" :
".\t";
888 $str .= (defined $self->phase) ? $self->phase.
"\t" :
".\t";
890 $str .= (defined $self->end_phase) ? $self->end_phase.
"\t" :
".\t";
900 Usage : $pid = $feat->external_db()
901 $feat->external_db($dbid)
902 Function: get/set
for an external db
accession number (e.g.: Interpro)
904 Args : none
if get, the
new value
if set
909 my ($self,$value) = @_;
913 $self->{
'_external_db'} = $value;
916 return $self->{
'_external_db'};
923 Arg [1] : Bio::PrimarySeqI $seq
924 Example : $seq = $self->contig;
925 Description: Accessor to attach/retrieve a sequence to/from a feature
926 Returntype : Bio::PrimarySeqI
933 my ($self, $arg) = @_;
936 unless (defined $arg && ref $arg && $arg->isa(
"Bio::PrimarySeqI")) {
937 $self->throw(
"Must attach Bio::PrimarySeqI objects to SeqFeatures");
940 $self->{
'_gsf_seq'} = $arg;
942 # attach to sub features if they want it
944 foreach my $sf ($self->sub_SeqFeature) {
945 if ($sf->can(
"attach_seq")) {
946 $sf->attach_seq($arg);
950 #print STDERR "contig is ".$self->{'_gsf_seq'}." with name ".$self->{'_gsf_seq'}->name."\n" unless(!$self->{'_gsf_seq'});
951 # my ($p, $f, $l) = caller;
952 # print STDERR "Caller = ".$f." ".$l."\n";
953 return $self->{
'_gsf_seq'};
959 my ($self, $arg) = @_;
962 $self->{
'_is_splittable'} = $arg;
964 return $self->{
'_is_splittable'};
969 my ($self, $slice) = @_;
971 unless (defined $slice) {
973 if ((defined $self->contig) &&
974 ($self->contig->isa(
"Bio::EnsEMBL::RawContig"))) {
976 # we are already in rawcontig coords, nothing needs to be done
981 # transform to raw_contig coords from Slice coords
982 return $self->_transform_to_RawContig();
986 if (defined $self->contig) {
988 if ($self->contig->isa(
"Bio::EnsEMBL::RawContig")) {
990 # transform to slice coords from raw contig coords
991 return $self->_transform_to_Slice($slice);
993 elsif ($self->contig->isa(
"Bio::EnsEMBL::Slice" ) or $self->contig->isa(
"Bio::EnsEMBL::LRGSlice" )) {
995 # transform to slice coords from other slice coords
996 return $self->_transform_between_Slices($slice);
1000 # Unknown contig type
1001 $self->throw(
"Cannot transform unknown contig type @{[$self->contig]}");
1006 #Can't convert to slice coords without a contig to work with
1007 return $self->throw(
"Object's contig is not defined - cannot transform");
1013 sub _transform_to_Slice {
1014 my ($self, $slice) = @_;
1016 $self->throw(
"can't transform coordinates of $self without a contig defined")
1017 unless $self->contig;
1019 unless($self->contig->adaptor) {
1020 $self->throw(
"cannot transform coordinates of $self without adaptor " .
1021 "attached to contig");
1024 my $dbh = $self->contig->adaptor->db;
1027 $dbh->get_AssemblyMapperAdaptor->fetch_by_type($slice->assembly_type);
1028 my $rca = $dbh->get_RawContigAdaptor;
1030 my @mapped = $mapper->map_coordinates_to_assembly(
1031 $self->contig->dbID,
1038 $self->throw(
"couldn't map $self to Slice");
1041 unless (@mapped == 1) {
1042 $self->throw(
"$self should only map to one chromosome - " .
1043 "something bad has happened ...");
1046 if ($mapped[0]->isa(
"Bio::EnsEMBL::Mapper::Gap")) {
1047 $self->warn(
"feature lies on gap\n");
1051 if( ! defined $slice->chr_name() ) {
1052 my $slice_adaptor = $slice->adaptor();
1053 %$slice = %{$slice_adaptor->fetch_by_chr_name( $mapped[0]->
id() )};
1056 # mapped coords are on chromosome - need to convert to slice
1057 if($slice->strand == 1) {
1058 $self->start ($mapped[0]->start - $slice->chr_start + 1);
1059 $self->end ($mapped[0]->end - $slice->chr_start + 1);
1060 $self->strand ($mapped[0]->strand);
1062 $self->start ($slice->chr_end - $mapped[0]->end + 1);
1063 $self->end ($slice->chr_end - $mapped[0]->start + 1);
1064 $self->strand ($mapped[0]->strand * -1);
1067 $self->seqname($mapped[0]->
id);
1069 #set the contig to the slice
1070 $self->contig($slice);
1076 sub _transform_between_Slices {
1077 my ($self, $to_slice) = @_;
1079 my $from_slice = $self->contig;
1081 $self->throw(
"New contig [$to_slice] is not a Bio::EnsEMBL::Slice")
1082 unless ($to_slice->isa(
"Bio::EnsEMBL::Slice") or $to_slice->isa(
"Bio::EnsEMBL::LRGSlice") );
1084 if ((my $c1 = $from_slice->chr_name) ne (my $c2 = $to_slice->chr_name)) {
1085 $self->warn(
"Can't transform between chromosomes: $c1 and $c2");
1089 my($start, $end, $strand);
1091 #first convert to assembly coords
1092 if($from_slice->strand == 1) {
1093 $start = $from_slice->chr_start + $self->start - 1;
1094 $end = $from_slice->chr_start + $self->end - 1;
1095 $strand = $self->strand;
1097 $start = $from_slice->chr_end - $self->end + 1;
1098 $end = $from_slice->chr_end - $self->start + 1;
1099 $strand = $self->strand;
1102 #now convert to the other slice's coords
1103 if($to_slice->strand == 1) {
1104 $self->start ($start - $to_slice->chr_start + 1);
1105 $self->end ($end - $to_slice->chr_start + 1);
1106 $self->strand($strand);
1108 $self->start ($to_slice->chr_end - $end + 1);
1109 $self->end ($to_slice->chr_end - $start + 1);
1110 $self->strand($strand * -1);
1113 $self->contig($to_slice);
1119 sub _transform_to_RawContig {
1122 #print STDERR "transforming ".$self." to raw contig coords\n";
1123 $self->throw(
"can't transform coordinates of $self without a contig defined")
1124 unless $self->contig;
1126 my $slice = $self->contig;
1128 unless($slice->adaptor) {
1129 $self->throw(
"can't transform coordinates of $self without an adaptor " .
1130 "attached to the feature's slice");
1133 my $dbh = $slice->adaptor->db;
1136 $dbh->get_AssemblyMapperAdaptor->fetch_by_type($slice->assembly_type);
1137 my $rca = $dbh->get_RawContigAdaptor;
1139 #first convert the features coordinates to assembly coordinates
1140 my($start, $end, $strand);
1141 if($slice->strand == 1) {
1142 $start = $slice->chr_start + $self->start - 1;
1143 $end = $slice->chr_start + $self->end - 1;
1144 $strand = $self->strand;
1146 $start = $slice->chr_end - $self->end + 1;
1147 $end = $slice->chr_end - $self->start + 1;
1148 $strand = $self->strand * -1;
1151 #convert the assembly coordinates to RawContig coordinates
1152 my @mapped = $mapper->map_coordinates_to_rawcontig(
1160 $self->throw(
"couldn't map $self");
1166 if ($mapped[0]->isa(
"Bio::EnsEMBL::Mapper::Gap")) {
1167 $self->warn(
"feature lies on gap\n");
1171 my $rc = $rca->fetch_by_dbID($mapped[0]->
id);
1173 $self->start ($mapped[0]->start);
1174 $self->end ($mapped[0]->end);
1175 $self->strand ($mapped[0]->strand);
1176 $self->seqname ($mapped[0]->
id);
1177 #print STDERR "setting contig to be ".$mapped[0]->id."\n";
1178 $self->contig($rca->fetch_by_dbID($mapped[0]->id));
1184 # more than one object returned from mapper
1185 # possibly more than one RawContig in region
1187 my (@gaps, @coords);
1189 foreach my $m (@mapped) {
1191 if ($m->isa(
"Bio::EnsEMBL::Mapper::Gap")) {
1194 elsif ($m->isa(
"Bio::EnsEMBL::Mapper::Coordinate")) {
1199 # case where only one RawContig maps
1202 $self->start ($coords[0]->start);
1203 $self->end ($coords[0]->end);
1204 $self->strand ($coords[0]->strand);
1205 $self->seqname($coords[0]->
id);
1206 #print STDERR "2 setting contig to be ".$coords[0]->id."\n";
1207 $self->contig ($rca->fetch_by_dbID($coords[0]->id));
1209 $self->warn(
"Feature [$self] truncated as lies partially on a gap");
1213 unless ($self->is_splittable) {
1214 $self->warn(
"Feature spans >1 raw contig - can't split\n");
1219 my $obj = ref $self;
1221 SPLIT:
foreach my $map (@mapped) {
1223 if ($map->isa(
"Bio::EnsEMBL::Mapper::Gap")) {
1224 $self->warn(
"piece of evidence lies on gap\n");
1228 my $feat = $obj->new;
1230 $feat->start ($map->start);
1231 $feat->end ($map->end);
1232 $feat->strand ($map->strand);
1233 #print STDERR "3 setting contig to be ".$mapped[0]->id."\n";
1234 $feat->contig ($rca->fetch_by_dbID($map->id));
1235 $feat->adaptor($self->adaptor)
if $self->adaptor();
1236 $feat->display_label($self->display_label)
if($self->can(
'display_label'));
1237 $feat->analysis($self->analysis);