my ($self) = @_;
my $dbi = $self->xref->dbc;
my @names = $self->get_priority_names($dbi);
print "The following will be processed as priority xrefs\n" if($self->verbose);
foreach my $name (@names){
print "\t$name\n" if($self->verbose);
}
my $update_ox_sth = $dbi->prepare('update object_xref set ox_status = "FAILED_PRIORITY" where object_xref_id = ?');
my $update_x_sth = $dbi->prepare("update xref set dumped = 'NO_DUMP_ANOTHER_PRIORITY' where xref_id = ?");
# 1) Set to failed all those that have no object xrefs.
my $f_sql =(<<FSQL);
SELECT x.xref_id
FROM source s, xref x
LEFT JOIN object_xref ox ON ox.xref_id = x.xref_id
WHERE x.source_id = s.source_id
AND s.name = ?
AND ox.object_xref_id is null
FSQL
my $f_sth = $dbi->prepare($f_sql);
foreach my $name (@names){
$f_sth->execute($name);
my ($xref_id);
$f_sth->bind_columns(\$xref_id);
while($f_sth->fetch()){
$update_x_sth->execute($xref_id);
}
}
$f_sth->finish;
#
# Now ALL object_xrefs have an identity_xref :-)
# So we can do a straight join and treat all info_types the same way.
#
my $new_sql =(<<NEWS);
SELECT ox.object_xref_id, x.accession, x.xref_id, (ix.query_identity + ix.target_identity) as identity, ox.ox_status, ox.ensembl_object_type, ensembl_id, info_type
FROM object_xref ox, xref x, source s, identity_xref ix
WHERE ox.object_xref_id = ix.object_xref_id
AND ox.xref_id = x.xref_id
AND s.source_id = x.source_id
AND s.name = ?
ORDER BY x.accession DESC, s.priority ASC , identity DESC, x.xref_id DESC
NEWS
my $new_sth = $dbi->prepare($new_sql);
#
# Query to copy identity_xref values from one xref to another
# This is to keep alignment information event if alignment was not the best match
#
my $idx_copy_sql = (<<IDXCP);
UPDATE identity_xref SET query_identity = ?, target_identity = ?, hit_start = ?, hit_end = ?, translation_start = ?, translation_end = ?, cigar_line = ?, score = ?, evalue = ?
WHERE object_xref_id = ?;
IDXCP
my $idx_copy_sth = $dbi->prepare($idx_copy_sql);
#
# Query to copy synonyms from one xref to another
#
my $syn_copy_sql = (<<SYNCP);
INSERT IGNORE INTO synonym (SELECT ?, synonym FROM synonym
WHERE xref_id = ?);
SYNCP
my $syn_copy_sth = $dbi->prepare($syn_copy_sql);
my $best_ox_sth = $dbi->prepare("SELECT object_xref_id FROM object_xref WHERE xref_id = ? and ensembl_object_type = ? and ensembl_id = ?");
my $seq_score_sql = (<<SEQCP);
SELECT query_identity, target_identity, hit_start, hit_end, translation_start, translation_end, cigar_line, score, evalue
FROM identity_xref WHERE object_xref_id = ?
SEQCP
my $seq_score_sth = $dbi->prepare($seq_score_sql);
foreach my $name (@names){
$new_sth->execute($name);
my ($object_xref_id, $acc, $xref_id, $identity, $status, $object_type, $ensembl_id, $info_type);
$new_sth->bind_columns(\$object_xref_id, \$acc, \$xref_id, \$identity, \$status, \$object_type, \$ensembl_id, \$info_type);
my $last_acc = "";
my $last_name = "";
my $best_xref_id = undef;
my @best_ensembl_id = undef;
my $last_xref_id = 0;
my $seen = 0;
my @gone; # list of xref_ids that we've already seen for this accession
while($new_sth->fetch){
if($last_acc eq $acc){
if($xref_id != $best_xref_id){
# We've already seen
this accession before, and
this xref_id is not the best one
$seen = ($xref_id == $last_xref_id);
$last_xref_id = $xref_id;
# If xref is a sequence_match, we want to copy the alignment identity_xref to prioritised mappings of the same ensembl_id
if ($info_type eq 'SEQUENCE_MATCH') {
my ($query_identity, $target_identity, $hit_start, $hit_end, $translation_start, $translation_end, $cigar_line, $score, $evalue, $best_object_xref_id);
$seq_score_sth->execute($object_xref_id);
$seq_score_sth->bind_columns(\$query_identity, \$target_identity, \$hit_start, \$hit_end, \$translation_start, \$translation_end, \$cigar_line, \$score, \$evalue);
$seq_score_sth->fetch();
$best_ox_sth->execute($best_xref_id, $object_type, $ensembl_id);
$best_ox_sth->bind_columns(\$best_object_xref_id);
$best_ox_sth->fetch();
$idx_copy_sth->execute($query_identity, $target_identity, $hit_start, $hit_end, $translation_start, $translation_end, $cigar_line, $score, $evalue, $best_object_xref_id);
}
# If the xref is marked DUMP_OUT, set it to FAILED_PRIORITY
if($status eq "DUMP_OUT"){
$update_ox_sth->execute($object_xref_id);
## If it is the first time processing this xref_id, also process dependents and update status
if (!$seen) {
$update_x_sth->execute($xref_id);
# Copy synonyms across if they are missing
$syn_copy_sth->execute($best_xref_id, $xref_id);
$self->process_dependents($xref_id, $best_xref_id, $dbi);
}
}
else{ # not DUMP_OUT
$update_x_sth->execute($xref_id);
}
} else {
# Alignment did not pass, dismiss
if ($status eq 'FAILED_CUTOFF') {
next;
}
## There might be several mappings for the best priority
push @best_ensembl_id, $ensembl_id;
}
if(@gone){ #best priority failed so another one now found so set dumped;
if($last_name eq $acc){
foreach my $d (@gone){
$update_x_sth->execute($d);
}
}
}
}
else{ # NEW xref_id
if($status eq "DUMP_OUT"){
$last_acc = $acc;
$best_xref_id = $xref_id;
@best_ensembl_id = ($ensembl_id);
if(@gone and $last_name eq $acc){
foreach my $d (@gone){
$update_x_sth->execute($d);
}
@gone=();
}
}
else{ # new xref_id not DUMP_OUT
if ($last_name ne $acc) { @gone = () } #
new accession
push @gone, $xref_id;
$last_name = $acc;
}
}
}
}
$new_sth->finish;
$update_ox_sth->finish;
$update_x_sth->finish;
$seq_score_sth->finish;
$best_ox_sth->finish;
$idx_copy_sth->finish;
$syn_copy_sth->finish;
my $sth = $dbi->prepare("insert into process_status (status, date) values('prioritys_flagged',now())");
$sth->execute();
$sth->finish;
}