Raw content of Bio::EnsEMBL::Map::DBSQL::MarkerFeatureAdaptor =head1 LICENSE Copyright (c) 1999-2009 The European Bioinformatics Institute and Genome Research Limited. All rights reserved. This software is distributed under a modified Apache license. For license details, please see /info/about/code_licence.html =head1 CONTACT Please email comments or questions to the public Ensembl developers list at <ensembl-dev@ebi.ac.uk>. Questions may also be sent to the Ensembl help desk at <helpdesk@ensembl.org>. =cut =head1 NAME Bio::EnsEMBL::Map::DBSQL::MarkerFeatureAdaptor =head1 SYNOPSIS =head1 DESCRIPTION This object is responisble for all database interaction involving marker features including the fetching and storing of marker features. The bulk of this objects' methods are inherited from Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor =head1 METHODS =cut package Bio::EnsEMBL::Map::DBSQL::MarkerFeatureAdaptor; use strict; use Bio::EnsEMBL::Map::MarkerFeature; use Bio::EnsEMBL::Map::Marker; use Bio::EnsEMBL::Map::MarkerSynonym; use Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor; use Bio::EnsEMBL::Utils::Exception qw(throw warning); use vars qw(@ISA); @ISA = qw(Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor); =head2 fetch_all_by_Marker Arg [1] : Bio::EnsEMBL::Map::Marker Example : @ms = @{$marker_feature_adaptor->fetch_by_Marker($mrkr)}; Description: Retrieves a list of MarkerFeatures for a given marker Returntype : listref of Bio::EnsEMBL::MarkerFeatures Exceptions : none Caller : general Status : stable =cut sub fetch_all_by_Marker { my $self = shift; my $marker = shift; my $constraint = 'm.marker_id = ' . $marker->dbID; return $self->generic_fetch($constraint, @_); } =head2 fetch_all_by_Slice_and_priority Arg [1] : Bio::EnsEMBL::Slice $slice Arg [2] : (optional) int $priority Arg [3] : (optional) int $map_weight Arg [3] : (optional) string $logic_name Example : @feats = @{$mfa->fetch_all_by_Slice_and_priority($slice,80,2)}; Description: Retrieves all marker features above a specified threshold priority which overlap the provided slice, below a a specified map_weight. Returntype : listref of Bio::EnsEMBL::Map::MarkerFeatures in slice coords Exceptions : none Caller : general Status : stable =cut sub fetch_all_by_Slice_and_priority { my ($self, $slice, $priority, $map_weight, @args) = @_; my $constraint = ''; if(defined $priority) { $constraint = "m.priority > $priority"; } if(defined $map_weight) { if($constraint) { $constraint .= " AND mf.map_weight < $map_weight"; } else { $constraint = "mf.map_weight < $map_weight"; } } return $self->fetch_all_by_Slice_constraint($slice, $constraint, @args); } =head2 fetch_all_by_RawContig_and_priority Description: DEPRECATED use fetch_all_by_Slice_and_priority instead =cut sub fetch_all_by_RawContig_and_priority { deprecate('Use fetch_all_by_Slice_and_priority() instead.'); fetch_all_by_Slice_and_priority(@_); } sub fetch_all_by_Slice_and_score { my $self = shift; throw('fetch_all_by_Slice_and_score should not be' . 'used to fetch marker_features'); } sub _columns { my $self = shift; return ('mf.marker_feature_id', 'mf.marker_id', 'mf.seq_region_id', 'mf.seq_region_start', 'mf.seq_region_end', 'mf.analysis_id', 'mf.map_weight', 'm.left_primer', 'm.right_primer', 'm.min_primer_dist', 'm.max_primer_dist', 'm.priority', 'm.type', 'ms.marker_synonym_id', 'ms.name', 'ms.source'); } sub _tables { my $self = shift; return (['marker_feature', 'mf'], #primary table ['marker', 'm'], ['marker_synonym', 'ms']); } sub _left_join { my $self = shift; return ( [ 'marker_synonym', 'm.display_marker_synonym_id = ms.marker_synonym_id' ] ); } sub _default_where_clause { my $self = shift; return ('mf.marker_id = m.marker_id'); } sub _objs_from_sth { my ($self, $sth, $mapper, $dest_slice) = @_; my ($marker_feature_id, $marker_id, $seq_region_id, $seq_region_start, $seq_region_end, $analysis_id, $map_weight, $left_primer, $right_primer, $min_primer_dist, $max_primer_dist, $priority, $type, $ms_id, $ms_name, $ms_source); #warning: ordering depends on _columns function implementation $sth->bind_columns(\$marker_feature_id, \$marker_id, \$seq_region_id, \$seq_region_start, \$seq_region_end, \$analysis_id, \$map_weight, \$left_primer, \$right_primer, \$min_primer_dist, \$max_primer_dist, \$priority, \$type, \$ms_id, \$ms_name, \$ms_source); my @out = (); my %marker_cache; my %slice_hash; # my %sr_name_hash; my %sr_cs_hash; my %analysis_cache; my $marker_adp = $self->db->get_MarkerAdaptor; my $sa = $self->db->get_SliceAdaptor; my $analysis_adp = $self->db->get_AnalysisAdaptor; my $asm_cs; my $cmp_cs; my $asm_cs_vers; my $asm_cs_name; my $cmp_cs_vers; my $cmp_cs_name; if($mapper) { $asm_cs = $mapper->assembled_CoordSystem(); $cmp_cs = $mapper->component_CoordSystem(); $asm_cs_name = $asm_cs->name(); $asm_cs_vers = $asm_cs->version(); $cmp_cs_name = $cmp_cs->name(); $cmp_cs_vers = $cmp_cs->version(); } my $dest_slice_start; my $dest_slice_end; my $dest_slice_strand; my $dest_slice_length; if($dest_slice) { $dest_slice_start = $dest_slice->start(); $dest_slice_end = $dest_slice->end(); $dest_slice_strand = $dest_slice->strand(); $dest_slice_length = $dest_slice->length(); } FEATURE: while($sth->fetch) { #create a new marker unless this one has been seen already my $marker; if(!($marker = $marker_cache{$marker_id})) { #create a new marker synonym for the display synonym (if defined) my $ms; if($ms_id) { $ms = Bio::EnsEMBL::Map::MarkerSynonym->new ($ms_id, $ms_source, $ms_name); } #create a new marker $marker = Bio::EnsEMBL::Map::Marker->new ($marker_id, $marker_adp, $left_primer, $right_primer, $min_primer_dist, $max_primer_dist, $priority, $type, $ms); $marker_cache{$marker_id} = $marker; } #get the slice object my $slice = $slice_hash{$seq_region_id}; if(!$slice) { $slice = $sa->fetch_by_seq_region_id($seq_region_id); $slice_hash{$seq_region_id} = $slice; # $sr_name_hash{$seq_region_id} = $slice->seq_region_name(); $sr_cs_hash{$seq_region_id} = $slice->coord_system(); } #retrieve analysis my $analysis; unless($analysis = $analysis_cache{$analysis_id}) { $analysis = $analysis_adp->fetch_by_dbID($analysis_id); $analysis_cache{$analysis_id} = $analysis; } # # remap the feature coordinates to another coord system # if a mapper was provided # if($mapper) { # my $sr_name = $sr_name_hash{$seq_region_id}; my $sr_cs = $sr_cs_hash{$seq_region_id}; ($seq_region_id,$seq_region_start,$seq_region_end) = $mapper->fastmap($slice->seq_region_name(), $seq_region_start, $seq_region_end, 0, $sr_cs); #skip features that map to gaps or coord system boundaries next FEATURE if(!defined($seq_region_id)); #get a slice in the coord system we just mapped to $slice = $slice_hash{"$seq_region_id"} ||= $sa->fetch_by_seq_region_id($seq_region_id); } # # If a destination slice was provided convert the coords # If the dest_slice starts at 1 and is foward strand, nothing needs doing # if($dest_slice) { if($dest_slice_start != 1 || $dest_slice_strand != 1) { if($dest_slice_strand == 1) { $seq_region_start = $seq_region_start - $dest_slice_start + 1; $seq_region_end = $seq_region_end - $dest_slice_start + 1; } else { my $tmp_seq_region_start = $seq_region_start; $seq_region_start = $dest_slice_end - $seq_region_end + 1; $seq_region_end = $dest_slice_end - $tmp_seq_region_start + 1; } #throw away features off the end of the requested slice if($seq_region_end < 1 || $seq_region_start > $dest_slice_length) { next FEATURE; } } $slice = $dest_slice; } #now create a new marker_feature using the marker push @out, Bio::EnsEMBL::Map::MarkerFeature->new ($marker_feature_id, $self, $seq_region_start, $seq_region_end, $slice, $analysis, $marker_id, $map_weight, $marker); } return \@out; } =head2 store Arg [1] : Bio::EnsEMBL::Map::MarkerFeature Example : $marker_feature_adaptor->store(@marker_features); Description: Stores a list of marker features in this database. The dbID and adaptor of each marker will be set on successful storing. Returntype : none Exceptions : thrown if not all data needed for storing is populated in the marker features Caller : general Status : stable =cut sub store { my ($self, @mfs) = @_; foreach my $mf (@mfs) { # # Sanity checking! # if(!ref($mf) || !$mf->isa('Bio::EnsEMBL::Map::MarkerFeature')) { $self->throw("Incorrect argument [$mf] to store. Expected " . 'Bio::EnsEMBL::Map::MarkerFeature'); } #don't store this feature if it has already been stored if($mf->is_stored($self->db())) { warning('MarkerFeature ['.$mf->dbID.'] is already stored in this DB.'); next; } # Get/test the marker my $marker = $mf->marker; if(!$marker || !ref($marker) || !$marker->isa('Bio::EnsEMBL::Map::Marker')) { throw('Cannot store MarkerFeature without an associated Marker'); } #store the marker if it has not been stored yet if(!$marker->is_stored($self->db())) { my $marker_adaptor = $self->db->get_adaptor('Marker'); $marker_adaptor->store($marker); } my $marker_id = $marker->dbID || throw('Associated Marker must have dbID to store MarkerFeature'); # Get/test the analysis my $analysis = $mf->analysis; if(!$analysis || !ref($analysis) || !$analysis->isa('Bio::EnsEMBL::Analysis')) { throw('Cannot store MarkerFeature without an associated Analysis'); } #store the analysis if it has not been stored yet if(!$analysis->is_stored($self->db())) { my $analysis_adaptor = $self->db->get_adaptor('Analysis'); $analysis_adaptor->store($mf->analysis()); } my $analysis_id = $analysis->dbID || throw('Associated Analysis must have dbID to store MarkerFeature'); # Store the marker feature itself my $original = $mf; my $seq_region_id; ($mf, $seq_region_id) = $self->_pre_store($mf); my $sth = $self->prepare("INSERT INTO marker_feature (marker_id, seq_region_id, seq_region_start, seq_region_end, analysis_id, map_weight) VALUES (?, ?, ?, ?, ?, ?)"); $sth->execute($marker_id, $seq_region_id, $mf->start, $mf->end, $analysis_id, $mf->map_weight || 0); my $dbID = $sth->{'mysql_insertid'}; $original->dbID($dbID); $original->adaptor($self); } } 1;