diff --git a/modules/Bio/EnsEMBL/DBSQL/UnmappedObjectAdaptor.pm b/modules/Bio/EnsEMBL/DBSQL/UnmappedObjectAdaptor.pm new file mode 100644 index 0000000000000000000000000000000000000000..843b25b0c4284f638bf149ad0db2c8811d4064ca --- /dev/null +++ b/modules/Bio/EnsEMBL/DBSQL/UnmappedObjectAdaptor.pm @@ -0,0 +1,398 @@ +# +# Ensembl module for Bio::EnsEMBL::DBSQL::DensityFeatureAdaptor +# +# Copyright EMBL/EBI +# +# You may distribute this module under the same terms as perl itself + +# POD documentation - main docs before the code + +=head1 NAME + +Bio::EnsEMBL::DBSQL::UnmappedObjectAdaptor + +=head1 SYNOPSIS + +my $uoa = $database_adaptor->get_UnmappedObjectAdaptor(); + + +my $missed = @{$uoa->fetch_all_by_type('xref'); + +=head1 DESCRIPTION + +Unmapped ObjectAdaptor - An adaptor responsible for the creation, editing, +retrieval of Unmapped Objects. These being the Objects that where not mapped +in a specific process i.e. xref, cDNA, Markers. + +=head1 CONTACT + +Post questions to the Ensembl developer list. + +=head1 METHODS + +=cut + +package Bio::EnsEMBL::DBSQL::UnmappedObjectAdaptor; +use vars qw(@ISA); +use strict; + + +use POSIX; +use Bio::EnsEMBL::Utils::Cache; +use Bio::EnsEMBL::Utils::Exception qw(throw warning); +use Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor; +use Bio::EnsEMBL::UnmappedObject; +use Bio::EnsEMBL::Analysis; +@ISA = qw(Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor); + +our %desc_to_id; + +=head2 new + + Arg [1] : list of args @args + Superclass constructor arguments + Example : none + Description: Constructor which just initializes internal cache structures + Returntype : Bio::EnsEMBL::DBSQL::UnmappedObjectAdaptor + Exceptions : none + Caller : implementing subclass constructors + Status : At Risk + +=cut + +sub new { + my $caller = shift; + + my $class = ref($caller) || $caller; + + my $self = $class->SUPER::new(@_); + + my $sth = $self->prepare("select unmapped_reason_id, full_description from unmapped_reason"); + + $sth->execute(); + my ($id, $desc); + $sth->bind_columns(\$id, \$desc); + while($sth->fetch()) { + $desc_to_id{$desc} = $id; + } + $sth->finish; + + return $self; +} + + +# _tables +# Arg [1] : none +# Description: PROTECTED implementation of superclass abstract method +# returns the names, aliases of the tables to use for queries +# Returntype : list of listrefs of strings +# Exceptions : none +# Caller : internal +# Status : At Risk +sub _tables { + my $self = shift; + + return (['unmapped_object', 'uo'], + ['unmapped_reason', 'ur']); +} + + +# _columns +# Arg [1] : none +# Example : none +# Description: PROTECTED implementation of superclass abstract method +# returns a list of columns to use for queries +# Returntype : list of strings +# Exceptions : none +# Caller : internal +# Status : At Risk + +sub _columns { + my $self = shift; + + return qw(uo.unmapped_object_id uo.type uo.analysis_id uo.external_db_id + uo.identifier uo.unmapped_reason_id uo.query_score uo.target_score + uo.ensembl_id uo.ensembl_object_type + ur.summary_description ur.full_description); +} + + +sub _straight_join { + return( [ 'unmapped_object', "uo.unmapped_reason_id = ur.unmapped_reason_id" ]); +} + +sub _left_join { + return( [ 'unmapped_object', "uo.unmapped_reason_id = ur.unmapped_reason_id" ]); +} + +=head2 list_dbIDs + + Arg [1] : none + Example : @unmapped_object_ids = @{$unmapped_object_adaptor->list_dbIDs()}; + Description: Gets an array of internal ids for all unmapped_objects in the current db + Returntype : list of ints + Exceptions : none + Caller : ? + Status : Stable + +=cut + +sub list_dbIDs { + my ($self) = @_; + + return $self->_list_dbIDs("unmapped_object"); +} + +=head2 list_unmapped_reasons + + Arg [1] : none + Example : @unmapped_object_reason+ids = + @{$unmapped_object_adaptor->list_unmapped_reasons()}; + Description: Gets an array of internal ids for all unmapped_objects in the current db + Returntype : list of ints + Exceptions : none + Caller : ? + Status : Stable + +=cut + +sub list_unmapped_reasons { + my ($self) = @_; + + return $self->_list_dbIDs("unmapped_reason"); +} + + +# _objs_from_sth + +# Arg [1] : StatementHandle $sth +# Example : none +# Description: PROTECTED implementation of abstract superclass method. +# responsible for the creation of UnmappedObjects +# Returntype : listref of Bio::EnsEMBL::UnmappedObjects +# Exceptions : none +# Caller : internal +# Status : At Risk + +sub _objs_from_sth { + my ($self, $sth) = @_; + + my($unmapped_object_id, $type, $analysis_id, $external_db_id, $identifier, + $unmapped_reason_id, $query_score, $target_score, $ensembl_id, + $ensembl_object_type, $summary, $full_desc); + + $sth->bind_columns(\$unmapped_object_id,\$type, \$analysis_id, + \$external_db_id, \$identifier, \$unmapped_reason_id, + \$query_score, \$target_score, \$ensembl_id, + \$ensembl_object_type, \$summary, \$full_desc); + + my $analysis_adaptor = $self->db->get_AnalysisAdaptor(); + + my @features; + while($sth->fetch()) { + my $analysis = $analysis_adaptor->fetch_by_dbID($analysis_id); + + print "$identifier\n"; + push @features, Bio::EnsEMBL::UnmappedObject->new + (-unmapped_object_id => $unmapped_object_id, + -unmapped_reason_id => $unmapped_reason_id, + -type => $type, + -analysis => $analysis, + -external_db_id => $external_db_id, + -identifier => $identifier, + -query_score => $query_score, + -target_score => $target_score, + -ensembl_id => $ensembl_id, + -ensembl_object_type => $ensembl_object_type, + -summary => $summary, + -full_desc => $full_desc); + } + return \@features; +} + + + +=head2 store + + Arg [1] : list of Bio::EnsEMBL::UnmappedObjects @uo + the simple features to store in the database + Example : $ou_adaptor->store(@uo); + Description: Stores a list of unmapped objects in the database + Returntype : none + Exceptions : thrown if no Analysis, or no list of objects to store. + Caller : general + Status : Stable + +=cut + +sub store{ + my ($self,@uos) = @_; + + if( scalar(@uos) == 0 ) { + throw("Must call store with list of UnmappedObjects"); + } + + + my $db = $self->db(); + my $analysis_adaptor = $db->get_AnalysisAdaptor(); + + my $sth_reason = $self->prepare + ("INSERT INTO unmapped_reason (summary_description, full_description)". + " VALUES (?,?)"); + + my $sth_unmapped_object = $self->prepare + ("INSERT INTO unmapped_object (type, analysis_id, external_db_id, + identifier, unmapped_reason_id, query_score, target_score, + ensembl_id, ensembl_object_type)". + " VALUES (?,?,?,?,?,?,?,?,?)"); + + FEATURE: foreach my $uo ( @uos ) { + + if( !ref $uo || !$uo->isa("Bio::EnsEMBL::UnmappedObject") ) { + throw("UnmappedObject must be an Ensembl UnmappedObject, " . + "not a [".ref($uo)."]"); + } + if($uo->is_stored($db)){ + next; + } + + my $analysis = $uo->analysis(); + throw("UnmappedObject must have an analysis object.".$uo->analysis."\n") if(!defined($analysis)); + + my $analysis_id; + if($analysis->is_stored($db)) { + $analysis_id = $analysis->dbID(); + } else { + $analysis_id = $db->get_AnalysisAdaptor->store($analysis); + } + + #First check to see unmapped reason is stored + if(!defined($desc_to_id{$uo->{'description'}})){ + $sth_reason->bind_param(1,$uo->{'summary'},SQL_VARCHAR); + $sth_reason->bind_param(2,$uo->{'description'},SQL_VARCHAR); + $sth_reason->execute(); + $uo->{'unmapped_reason_id'} = $desc_to_id{$uo->{'description'}} + = $sth_reason->{'mysql_insertid'}; + + } + else{ + $uo->{'unmapped_reason_id'} = $desc_to_id{$uo->{'description'}} ; + } + $sth_unmapped_object->bind_param(1,$uo->{'type'},SQL_VARCHAR); + $sth_unmapped_object->bind_param(2,$uo->analysis->dbID,SQL_INTEGER); + $sth_unmapped_object->bind_param(3,$uo->{'external_db_id'},SQL_INTEGER); + $sth_unmapped_object->bind_param(4,$uo->{'identifier'},SQL_VARCHAR); + $sth_unmapped_object->bind_param(5,$uo->{'unmapped_reason_id'},SQL_VARCHAR); + $sth_unmapped_object->bind_param(6,$uo->{'query_score'},SQL_DOUBLE); + $sth_unmapped_object->bind_param(7,$uo->{'target_score'},SQL_DOUBLE); + $sth_unmapped_object->bind_param(8,$uo->{'ensembl_id'},SQL_INTEGER); + $sth_unmapped_object->bind_param(9,$uo->{'ensembl_object_type'},SQL_VARCHAR); + $sth_unmapped_object->execute(); + $uo->dbID($sth_unmapped_object->{'mysql_insertid'}); + } + $sth_reason->finish(); + return; +} + + +=head2 fetch_all_by_type + + Arg [1] : string type. The type of unmapped objects + Example : @unmapped_object = @{$uoa->fetch_all_by_type('xref')}; + Description : Retrieves all the unmapped object for a particular + type. e.g. 'xref','cDNA', 'marker' + Returntype : Array ref of Bio::EnsEMBL::UnmappedObject + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub fetch_all_by_type { + my ($self, $type) = @_; + + unless($type) { + throw("type argument is required"); + } + $self->generic_fetch("uo.type = \'$type\'"); + +} + +=head2 fetch_all_by_analysis + + Arg [1] : Bio:EnsEMBL::Analysis object + Arg [2] : (optional) string database name + Example : @unmapped_object = @{$uoa->fetch_all_by_analysis($analysis)}; + Description : Retrieves all the unmapped object for a particular + analysis type with the the option of a particular + database type. + Returntype : array ref of Bio::EnsEMBL::UnmappedObject + Exceptions : thorws if first argument is not an anaylisi object + Caller : general + Status : At Risk + +=cut + +sub fetch_all_by_analysis { + my ($self, $analysis,$dbname) = @_; + + unless($analysis) { + throw("analysis argument is required"); + } + my $constraint = "uo.analysis_id = ".$analysis->dbID; + if(defined($dbname)){ + my $db_id =0; + my $sth = $self->prepare('select external_db_id from external_db where db_name like "'. + $dbname.'"'); + $sth->execute; + $sth->bind_columns(\$db_id); + $sth->fetch(); + if(!defined($db_id) or $db_id == 0){ + throw("$dbname could not be found in the external database table\n"); + } + $constraint .= " AND uo.external_db_id = $db_id"; + } + print $constraint."\n"; + $self->generic_fetch($constraint); + +} + +=head2 fetch_by_identifier + + Arg [1] : string type. The type of unmapped objects + Arg [2] : (optional) string database name + Example : @unmapped_object = @{$uoa->fetch_by_identifier('Q123345')}; + Description : Retrieves the unmapped object for a particular + identifier/accession + Returntype : array ref of Bio::EnsEMBL::UnmappedObject + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub fetch_by_identifier { + my ($self, $identifier, $dbname) = @_; + + unless($identifier) { + throw("identifier argument is required"); + } + my $constraint = 'uo.identifier like "'.$identifier.'"'; + if(defined($dbname)){ + my $db_id =0; + my $sth = $self->prepare('select external_db_id from external_db where db_name like "'. + $dbname.'"'); + $sth->execute; + $sth->bind_columns(\$db_id); + $sth->fetch(); + if(!defined($db_id) or $db_id == 0){ + throw("$dbname could not be found in the external database table\n"); + } + $constraint .= " AND uo.external_db_id = $db_id"; + } + print $constraint."\n"; + $self->generic_fetch($constraint); + +} + +1; diff --git a/modules/Bio/EnsEMBL/UnmappedObject.pm b/modules/Bio/EnsEMBL/UnmappedObject.pm new file mode 100644 index 0000000000000000000000000000000000000000..a2e265edb787d9ad2dde4f72929f9223f30d8282 --- /dev/null +++ b/modules/Bio/EnsEMBL/UnmappedObject.pm @@ -0,0 +1,402 @@ +# +# Ensembl module for Bio::EnsEMBL::UnmappedObject +# +# You may distribute this module under the same terms as perl itself + +# POD documentation - main docs before the code + +=head1 NAME + +Bio:EnsEMBL::UnmappedObject - A object representing why a particular entity +was NOT mapped to the ensembl. + +=head1 SYNOPSIS + +use Bio::EnsEMBL::UnmappedObject; + +my $uo = Bio::EnsEMBL::UnmappedObject->new ( + -type => 'xref', + -analysis => $analysis, + -external_db_id => 4100, + -identifier => "Q12345", + -query_score => 45.5, + -target_score => 29.2, + -ensembl_id => 122346, + -ensembl_type => 'Translation", + -summary => "match failed for exonerate", + -full_desc => "match failed for the xref exonerate run as mtch was below threshold of 90"); + + +=head1 DESCRIPTION + +UnmappedObjects represent entities NOT mapped to ensembl. Therefore this should help +users to find out why certain accessions etc can not be found. + +This module is part of the Ensembl project http://www.ensembl.org + +=head1 CONTACT + +Post comments/questions to the ensembl development list: ensembl-dev@ebi.ac.uk + +=head1 METHODS + +=cut + + + +use strict; +use warnings; + +package Bio::EnsEMBL::UnmappedObject; + +use Bio::EnsEMBL::Utils::Argument qw(rearrange); +use Bio::EnsEMBL::Utils::Exception qw(throw); +use Bio::EnsEMBL::Storable; + +use vars qw(@ISA); + +@ISA = qw(Bio::EnsEMBL::Storable); + + +=head2 new + + Arg [TYPE] : the type of mapping i.e. 'xref','cDNA' + Arg [ANALYSIS] : Analysis object. + Arg [EXTERNAL_DB_ID] : id for the external db id this identifier is from + Arg [IDENTIFIER] : name of the identifier i.e. accession + Arg [QUERY_SCORE] : (optional) The query score + Arg [TARGET_SCORE] : (optional) The target score + Arg [SUMMARY] : The summary reason for not mapping. + Arg [FULL_DESC] : The Full description of why it did not map. + Arg [ENSEMBL_ID] : (optional) internal ensembl id for the best match + Arg [ENSEMBL_OBJECT_TYPE] : (optional) the type of object for the best match + Example : see SYNOPSIS + Returntype : Bio::EnsEMBL::UnmappedObject + Exceptions : If any of the none optional args are missing + Caller : general + Status : At Risk + +=cut + +sub new { + my $caller = shift; + + #allow constructor to be called as class or object method + my $class = ref($caller) || $caller; + + + + my ($dbID, $unmapped_reason_id, $type, $analysis, $ex_db_id, $identifier, + $query_score, $target_score, $summary, $full_desc, + $ensembl_id, $ensembl_object_type) = + rearrange([qw(UNMAPPED_OBJECT_ID UNMAPPED_REASON_ID TYPE ANALYSIS + EXTERNAL_DB_ID IDENTIFIER QUERY_SCORE TARGET_SCORE + SUMMARY FULL_DESC ENSEMBL_ID ENSEMBL_OBJECT_TYPE)], @_); + + my $self = $class->SUPER::new(@_); + if($analysis) { + if(!ref($analysis) || !$analysis->isa('Bio::EnsEMBL::Analysis')) { + throw('-ANALYSIS argument must be a Bio::EnsEMBL::Analysis not '. + $analysis); + } + } + else{ + throw('-ANALYSIS argument must be given'); + } + $self->{'analysis'} = $analysis; + $self->{'dbID'} = $dbID if (defined($dbID)); + $self->{'description'} = $full_desc || throw('FULL_DESC must be given'); + $self->{'summary'} = $summary || throw('SUMMARY must be given'); + $self->{'type'} = $type || throw('TYPE must be given'); + $self->{'external_db_id'} = $ex_db_id || throw('EXTERNAL_DB_ID must be given'); + $self->{'identifier'} = $identifier || throw('IDENTIFIER must be given'); + $self->{'query_score'} = $query_score if(defined($query_score)); + $self->{'target_score'} = $target_score if(defined($target_score)); + $self->{'ensembl_id'} = $ensembl_id if(defined($ensembl_id)); + $self->{'ensembl_object_type'} = $ensembl_object_type + if(defined($ensembl_object_type)); + $self->{'unmapped_reason_id'} = $unmapped_reason_id + if(defined($unmapped_reason_id)); + return $self; +} + +=head2 new_fast + + Arg [...] : none + Example : $feature = Bio::EnsEMBL::UnmappedObject->new_fast(); + Description: Creates a new Unmapped Object. + Returntype : Bio::EnsEMBL::UnmappedObject + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub new_fast{ + my $caller = shift; + + #allow constructor to be called as class or object method + my $class = ref($caller) || $caller; + + my $self = $class->SUPER::new(@_); + + return $self; +} + +=head2 description + + Arg [1] : (optional) * to be set to + Example : print $unmappedObject->description."\n"; + Description : Basic getter/setter for description + ReturnType : String + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub description{ + my $self = shift; + + if(@_) { + my $des = shift; + $self->{'description'} = $des; + } + + return $self->{'description'}; +} + +=head2 summary + + Arg [1] : (optional) summary to be set to + Example : print $unmappedObject->summary."\n"; + Description : Basic getter/setter for summary + ReturnType : String + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub summary{ + my $self = shift; + + if(@_) { + my $des = shift; + $self->{'summary'} = $des; + } + + return $self->{'summary'}; +} + +=head2 type + + Arg [1] : (optional) type to be set to + Example : print $unmappedObject->type."\n"; + Description : Basic getter/setter for type + ReturnType : String + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub type{ + my $self = shift; + + if(@_) { + my $arg = shift; + $self->{'type'} = $arg; + } + + return $self->{'type'}; +} + +=head2 ensembl_object_type + + Arg [1] : (optional) ensembl object type to be set to + Example : print $unmappedObject->ensembl_object_type."\n"; + Description : Basic getter/setter for ensembl object type + ReturnType : String + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub ensembl_object_type{ + my $self = shift; + + if(@_) { + my $arg = shift; + $self->{'ensembl_object_type'} = $arg; + } + + return $self->{'ensembl_object_type'}; +} + +=head2 ensembl_id + + Arg [1] : (optional) ensembl id to be set to + Example : print $unmappedObject->ensembl_id."\n"; + Description : Basic getter/setter for ensembl id + ReturnType : String + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub ensembl_id{ + my $self = shift; + + if(@_) { + my $arg = shift; + $self->{'ensembl_id'} = $arg; + } + + return $self->{'ensembl_id'}; +} + +=head2 external_db_id + + Arg [1] : (optional) external_db_id to be set to + Example : print $unmappedObject->external_db_id."\n"; + Description : Basic getter/setter for external_db_id + ReturnType : int + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub external_db_id{ + my $self = shift; + + if(@_) { + my $arg = shift; + $self->{'external_db_id'} = $arg; + } + + return $self->{'external_db_id'}; +} + +=head2 identifier + + Arg [1] : (optional) identifier to be set to + Example : print $unmappedObject->identifier."\n"; + Description : Basic getter/setter for identifier + ReturnType : String + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub identifier{ + my $self = shift; + + if(@_) { + my $arg = shift; + $self->{'identifier'} = $arg; + } + + return $self->{'identifier'}; +} + +=head2 query_score + + Arg [1] : (optional) query_score to be set to + Example : print $unmappedObject->query_score."\n"; + Description : Basic getter/setter for query_score + ReturnType : float + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub query_score{ + my $self = shift; + + if(@_) { + my $arg = shift; + $self->{'query_score'} = $arg; + } + + return $self->{'query_score'}; +} + +=head2 target_score + + Arg [1] : (optional) target_score to be set to + Example : print $unmappedObject->target_score."\n"; + Description : Basic getter/setter for target_score + ReturnType : float + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub target_score{ + my $self = shift; + + if(@_) { + my $arg = shift; + $self->{'target_score'} = $arg; + } + + return $self->{'target_score'}; +} + +=head2 unmapped_reason_id + + Arg [1] : (optional) unmapped_reason_id to be set to + Example : print $unmappedObject->unmapped_reason_id."\n"; + Description : Basic getter/setter for unmapped_reason_id + ReturnType : int + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub unmapped_reason_id{ + my $self = shift; + + if(@_) { + my $arg = shift; + $self->{'unmapped_reason_id'} = $arg; + } + + return $self->{'unmapped_reason_id'}; +} + +=head2 analysis + + Arg [1] : (optional) analysis to be set to + Example : print $unmappedObject->analysis->logic_name."\n"; + Description : Basic getter/setter for analysis + ReturnType : Bio::EnsEMBL::Analysis + Exceptions : none + Caller : general + Status : At Risk + +=cut + +sub analysis { + my $self = shift; + + if(@_) { + my $an = shift; + if(defined($an) && (!ref($an) || !$an->isa('Bio::EnsEMBL::Analysis'))) { + throw('analysis argument must be a Bio::EnsEMBL::Analysis'); + } + $self->{'analysis'} = $an; + } + + return $self->{'analysis'}; +} + +1;