Bio-MUST-Core
view release on metacpan or search on metacpan
lib/Bio/MUST/Core/IdList.pm view on Meta::CPAN
return { map { $_->full_id => $i++ } $self->all_seq_ids };
}
## use critic
after 'add_id' => sub {
my $self = shift;
# check if there are indeed ids not yet in private hash
# Note: this might not be the case when adding ids in an empty list
my $n = $self->count_ids;
my $i = $self->count_indices;
return if $n == $i;
# update private hash from internal array
$self->set_index(
map { $_->full_id => $i++ } ($self->all_seq_ids)[$i..$n-1]
);
return;
};
sub all_seq_ids {
my $self = shift;
return map { SeqId->new( full_id => $_ ) } $self->all_ids;
}
sub negative_list {
my $self = shift;
my $listable = shift;
# filter out seq ids that are in the original list
my @ids = map { $_->full_id } $listable->all_seq_ids;
return $self->new( ids => [ grep { not $self->is_listed($_) } @ids ] );
}
# IdList-based Ali factory methods
sub reordered_ali { ## no critic (RequireArgUnpacking)
return shift->_ali_from_list_(1, @_);
}
sub filtered_ali { ## no critic (RequireArgUnpacking)
return shift->_ali_from_list_(0, @_);
}
sub _ali_from_list_ {
my $self = shift;
my $reorder = shift;
my $ali = shift;
my $lookup = shift; # optional IdList indexing the Ali
# override passed lookup with internal lookup if available
# Note: this allows Stash lookups to be used transparently
$lookup = $ali->lookup if $ali->can('lookup');
# TODO: warn for missing ids in Ali?
# create new Ali object (extending header comment)
# TODO: allow custom comments
my $new_ali = Ali->new(
comments => [ $ali->all_comments,
'built by ' . ($reorder ? 'reordered_ali' : 'filtered_ali')
],
);
# case 1: use lookup when available
if (defined $lookup) {
### Using lookup...
# get slot list from lookup
# Note1: Since this list follows the list in $self it is 'reordered'.
# We thus sort it by ascending slot if the Ali order must be kept.
# Note2: We go through SeqId objects to correctly handle MUST ids
my @ids = map { $_->full_id } $self->all_seq_ids;
my @slots = $lookup->index_for(@ids);
@slots = sort { $a <=> $b } @slots unless $reorder;
# populate new Ali with deep copies of Seqs in slot list
$new_ali->add_seq( $ali->get_seq($_)->clone ) for @slots;
}
# case 2: scan all seqs to find those that are listed
else {
SEQ:
for my $seq ($ali->all_seqs) {
next SEQ unless $self->is_listed($seq->full_id);
# add Seq to new Ali honoring either IdList order...
if ($reorder) {
$new_ali->set_seq(
$self->index_for($seq->full_id), $seq->clone
);
next SEQ;
}
# ...or original Ali order
$new_ali->add_seq($seq->clone);
}
# when reordering an Ali, ensure that new Ali does not contain
# empty slots due to some missing ids in the original Ali
$new_ali->_set_seqs(
[ $new_ali->filter_seqs( sub { defined } ) ]
) if $reorder;
}
return $new_ali;
}
# I/O methods
( run in 1.134 second using v1.01-cache-2.11-cpan-39bf76dae61 )