my $self = shift;
my $flag_matrix = shift;
my $exon_matrix = shift;
unless ($flag_matrix and
$flag_matrix->isa('Bio::EnsEMBL::IdMapping::ScoredMappingMatrix')) {
throw('Need a transcript Bio::EnsEMBL::IdMapping::ScoredMappingMatrix.');
}
unless ($exon_matrix and
$exon_matrix->isa('Bio::EnsEMBL::IdMapping::ScoredMappingMatrix')) {
throw('Need an exon Bio::EnsEMBL::IdMapping::ScoredMappingMatrix.');
}
my $transcript_score_threshold =
$self->conf->param('transcript_score_threshold') || 0;
# create a new scoring matrix which will replace the flag matrix
-DUMP_PATH => $flag_matrix->dump_path,
-CACHE_FILE => $flag_matrix->cache_file_name,
);
# initialise progress logger
my $i;
my $num_transcripts =
scalar(keys %{ $self->cache->get_by_name('transcripts_by_id', 'source') });
my $progress_id = $self->logger->init_progress($num_transcripts, 100);
$self->logger->info("Creating score matrix from flag matrix...\n", 1);
# debug
my $fmt_d1 = "%-14s%-15s%-14s%-14s%-14s\n";
my $fmt_d2 = "%.6f";
# loop over source transcripts
foreach my $source_transcript (values %{ $self->cache->get_by_name('transcripts_by_id', 'source') }) {
# log progress
$self->logger->log_progress($progress_id, ++$i, 1);
# We are only interested in scoring with exons that are in the target
# transcript. The ScoredMappingMatrix may contain scores for exons that
# aren't in this transcript so create a hash of the target transcript's
# exons
my %source_exons =
map { $_->id => 1 }
@{ $source_transcript->get_all_Exons };
my $source_transcript_length = $source_transcript->length;
# get all corresponding target transcripts from the flag matrix
foreach my $target_transcript_id (@{ $flag_matrix->get_targets_for_source($source_transcript->id) }) {
my $target_transcript = $self->cache->get_by_key('transcripts_by_id', 'target', $target_transcript_id);
my $source_transcript_score = 0;
my $target_transcript_score = 0;
my $target_transcript_length = $target_transcript->length;
my %target_exons =
map { $_->id => 1 }
@{ $target_transcript->get_all_Exons };
# now loop over source exons and find the highest scoring target exon
# belonging to the target transcript
foreach my $source_exon (@{ $source_transcript->get_all_Exons }) {
my $max_source_score = -1;
foreach my $target_exon_id (@{ $exon_matrix->get_targets_for_source($source_exon->id) }) {
next unless ($target_exons{$target_exon_id});
my $score = $exon_matrix->get_score($source_exon->id,
$target_exon_id);
$max_source_score = $score if ($score > $max_source_score);
}
if ($max_source_score > 0) {
$source_transcript_score += ($max_source_score * $source_exon->length);
}
}
# now do the same for target exons
foreach my $target_exon (@{ $target_transcript->get_all_Exons }) {
my $max_target_score = -1;
foreach my $source_exon_id (@{ $exon_matrix->get_sources_for_target($target_exon->id) }) {
next unless ($source_exons{$source_exon_id});
my $score = $exon_matrix->get_score(
$source_exon_id, $target_exon->id);
$max_target_score = $score if ($score > $max_target_score);
}
if ($max_target_score > 0) {
$target_transcript_score += ($max_target_score * $target_exon->length);
}
}
#
# calculate transcript score and add to scoring matrix
#
if (($source_transcript_length + $target_transcript_length) > 0) {
# sanity check
if (($source_transcript_score > $source_transcript_length) or
($target_transcript_score > $target_transcript_length)) {
$self->logger->warning("Score > length for source ($source_transcript_score <> $source_transcript_length) or target ($target_transcript_score <> $target_transcript_length).\n", 1);
} else {
my $source_transcript_biotype_group = $self->get_biotype_group($source_transcript->biotype());
my $target_transcript_biotype_group = $self->get_biotype_group($target_transcript->biotype());
# debug
$self->logger->info($source_transcript->id.":".$target_transcript->id.
" source score: $source_transcript_score".
" source length: $source_transcript_length".
" source biotype:" . $source_transcript->biotype() .
" source group: $source_transcript_biotype_group".
" target score: $target_transcript_score".
" target biotype:" . $target_transcript->biotype() .
" target group: $target_transcript_biotype_group".
" target length: $target_transcript_length\n");
my $transcript_score =
($source_transcript_score + $target_transcript_score) /
($source_transcript_length + $target_transcript_length);
## Add penalty if biotypes are different
if ($source_transcript->biotype() ne $target_transcript->biotype()) {
$transcript_score = $transcript_score * 0.9;
}
## Add penalty if biotype groups are different
if ($source_transcript_biotype_group ne $target_transcript_biotype_group) {
$transcript_score = $transcript_score * 0.8;
}
# everything is fine, add score to matrix
if ($transcript_score > $transcript_score_threshold) {
$matrix->add_score($source_transcript->id, $target_transcript->id,
$transcript_score);
}
}
} else {
$self->logger->warning("Combined length of source (".$source_transcript->id.") and target (".$target_transcript->id.") transcript is zero!\n", 1);
}
}
}
$self->logger->info("\n");
return $matrix;
}