3 See the NOTICE file distributed with
this work
for additional information
4 regarding copyright ownership.
6 Licensed under the Apache License, Version 2.0 (the
"License");
7 you may not use
this file except in compliance with the License.
8 You may obtain a copy of the License at
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an
"AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License
for the specific language governing permissions and
16 limitations under the License.
23 Please email comments or questions to the
public Ensembl
24 developers list at <http:
26 Questions may also be sent to the Ensembl help desk at
37 $dafa = $registry->get_adaptor(
'Human',
'Core',
'DnaAlignFeature' );
41 $dafa->store(@features);
45 This is an adaptor responsible
for the retrieval and storage of
46 DnaDnaAlignFeatures from the database. This adaptor inherits most of its
55 package Bio::EnsEMBL::DBSQL::DnaAlignFeatureAdaptor;
68 Example : @tabs = $self->_tables
69 Description: PROTECTED implementation of the
abstract method inherited from
71 Returntype : list of listrefs of strings
81 return ([
'dna_align_feature',
'daf'],[
'external_db',
'exdb']);
86 return ([
'external_db',
"exdb.external_db_id = daf.external_db_id"]);
92 Example : @columns = $self->_columns
93 Description: PROTECTED implementation of
abstract superclass method.
94 Returns a list of columns that are needed
for object creation.
95 Returntype : list of strings
105 #warning, implementation of _objs_from_sth method depends on order of list
106 return qw(daf.dna_align_feature_id
111 daf.seq_region_strand
124 exdb.db_display_name);
130 Arg [1] : list of Bio::EnsEMBL::DnaAlignFeatures @feats
131 the features to store in the database
132 Example : $dna_align_feature_adaptor->store(@features);
133 Description: Stores a list of DnaAlignFeatures in the database
135 Exceptions :
throw if any of the provided features cannot be stored
137 * The feature does not have an associate Slice
138 * The feature does not have an associated analysis
139 * The Slice the feature is associated with is on a seq_region
140 unknown to
this database
141 A warning is given
if:
142 * The feature has already been stored in
this db
149 my ( $self, @feats ) = @_;
151 throw(
"Must call store with features")
if ( scalar(@feats) == 0 );
153 my @tabs = $self->_tables;
154 my ($tablename) = @{ $tabs[0] };
156 my $db = $self->db();
157 my $analysis_adaptor = $db->get_AnalysisAdaptor();
159 my $sth = $self->prepare(
160 "INSERT INTO $tablename (seq_region_id, seq_region_start,
161 seq_region_end, seq_region_strand,
162 hit_start, hit_end, hit_strand, hit_name,
163 cigar_line, analysis_id, score, evalue,
164 perc_ident, external_db_id, hcoverage, align_type)
165 VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" # 16 arguments, external_data removed and align_type added
169 foreach my $feat (@feats) {
170 if ( !ref $feat || !$feat->isa(
"Bio::EnsEMBL::DnaDnaAlignFeature") )
172 throw(
"feature must be a Bio::EnsEMBL::DnaDnaAlignFeature, not a [". ref($feat).
"]." );
175 if ( $feat->is_stored($db) ) {
176 warning(
"DnaDnaAlignFeature [".$feat->dbID().
"] is already stored in this database." );
180 my $hstart = $feat->hstart();
181 my $hend = $feat->hend();
182 my $hstrand = $feat->hstrand();
183 $self->_check_start_end_strand( $hstart, $hend, $hstrand, $feat->hslice );
185 my $cigar_string = $feat->cigar_string();
186 if ( !$cigar_string ) {
187 $cigar_string = $feat->length() .
'M';
188 warning(
"DnaDnaAlignFeature does not define a cigar_string.\n"
189 .
"Assuming ungapped block with cigar_line=$cigar_string ." );
191 my $align_type = $feat->align_type();
193 my $hseqname = $feat->hseqname();
195 throw(
"DnaDnaAlignFeature must define an hseqname.");
198 if ( !defined( $feat->analysis ) ) {
200 "An analysis must be attached to the features to be stored.");
203 #store the analysis if it has not been stored yet
204 if ( !$feat->analysis->is_stored($db) ) {
205 $analysis_adaptor->store( $feat->analysis() );
208 my $original = $feat;
210 ( $feat, $seq_region_id ) = $self->_pre_store($feat);
212 $sth->bind_param( 1, $seq_region_id, SQL_INTEGER );
213 $sth->bind_param( 2, $feat->start, SQL_INTEGER );
214 $sth->bind_param( 3, $feat->end, SQL_INTEGER );
215 $sth->bind_param( 4, $feat->strand, SQL_TINYINT );
216 $sth->bind_param( 5, $hstart, SQL_INTEGER );
217 $sth->bind_param( 6, $hend, SQL_INTEGER );
218 $sth->bind_param( 7, $hstrand, SQL_TINYINT );
219 $sth->bind_param( 8, $hseqname, SQL_VARCHAR );
220 $sth->bind_param( 9, $cigar_string, SQL_LONGVARCHAR );
221 $sth->bind_param( 10, $feat->analysis->dbID, SQL_INTEGER );
222 $sth->bind_param( 11, $feat->score, SQL_DOUBLE );
223 $sth->bind_param( 12, $feat->p_value, SQL_DOUBLE );
224 $sth->bind_param( 13, $feat->percent_id, SQL_FLOAT );
225 $sth->bind_param( 14, $feat->external_db_id, SQL_INTEGER );
226 $sth->bind_param( 15, $feat->hcoverage, SQL_DOUBLE );
227 $sth->bind_param( 16, $feat->align_type, SQL_VARCHAR);
230 my $dbId = $self->last_insert_id(
"${tablename}_id", undef, $tablename);
232 # store attributes if there are any
233 my $attr_adaptor = $db->get_AttributeAdaptor();
234 $attr_adaptor->store_on_DnaDnaAlignFeature($dbId, $feat->get_all_Attributes);
236 $original->dbID( $dbId );
237 $original->adaptor($self);
238 } ## end
foreach my $feat (@feats)
246 Arg [1] : A feature $feature
247 Example : $feature_adaptor->remove($feature);
248 Description: This removes a feature from the database. The table the
249 feature is removed from is defined by the
abstract method
250 _tablename, and the primary key of the table is assumed
251 to be _tablename() .
'_id'. The feature argument must
252 be an
object implementing the dbID method, and
for the
253 feature to be removed from the database a dbID value must
256 Exceptions : thrown
if $feature arg does not implement dbID(), or
if
257 $feature->dbID is not a
true value
265 my ($self, $feature) = @_;
267 if(!$feature || !ref($feature) || !$feature->isa(
'Bio::EnsEMBL::Feature')) {
268 throw(
'Feature argument is required');
271 if(!$feature->is_stored($self->db)) {
272 throw(
"This feature is not stored in this database");
275 my @tabs = $self->_tables;
276 my ($table) = @{$tabs[0]};
278 my $sth = $self->prepare(
"DELETE FROM $table WHERE ${table}_id = ?");
279 $sth->bind_param(1,$feature->dbID,SQL_INTEGER);
282 # remove the attributes associated with this feature
283 my $attrib_adaptor = $self->db->get_AttributeAdaptor;
284 $attrib_adaptor->remove_from_DnaDnaAlignFeature($feature);
286 #unset the feature dbID ad adaptor
287 $feature->dbID(undef);
288 $feature->adaptor(undef);
294 =head2 _objs_from_sth
296 Arg [1] : DBI statement handle $sth
297 an exectuted DBI statement handle generated by selecting
298 the columns specified by _columns() from the table specified
300 Example : @dna_dna_align_feats = $self->_obj_from_hashref
301 Description: PROTECTED implementation of superclass abstract method.
302 Creates DnaDnaAlignFeature objects from a DBI hashref
303 Returntype : listref of
Bio::
EnsEMBL::DnaDnaAlignFeatures
305 Caller :
Bio::
EnsEMBL::BaseFeatureAdaptor::generic_fetch
311 my ( $self, $sth, $mapper, $dest_slice ) = @_;
314 # This code is ugly because an attempt has been made to remove as many
315 # function calls as possible for speed purposes. Thus many caches and
316 # a fair bit of gymnastics is used.
319 # In case of userdata we need the features on the dest_slice. In case
320 # of get_all_supporting_features dest_slice is not provided.
321 my $sa = ( $dest_slice
322 ? $dest_slice->adaptor()
323 : $self->db()->get_SliceAdaptor() );
324 my $aa = $self->db->get_AnalysisAdaptor();
332 my ( $dna_align_feature_id, $seq_region_id,
333 $analysis_id, $seq_region_start,
334 $seq_region_end, $seq_region_strand,
335 $hit_start, $hit_end,
336 $hit_name, $hit_strand,
337 $cigar_line, $evalue,
339 $external_db_id, $hcoverage,
341 $external_db_name, $external_display_db_name );
343 $sth->bind_columns( \( $dna_align_feature_id, $seq_region_id,
344 $analysis_id, $seq_region_start,
345 $seq_region_end, $seq_region_strand,
346 $hit_start, $hit_end,
347 $hit_name, $hit_strand,
348 $cigar_line, $evalue,
350 $external_db_id, $hcoverage,
352 $external_db_name, $external_display_db_name )
355 my $dest_slice_start;
357 my $dest_slice_strand;
358 my $dest_slice_length;
360 my $dest_slice_sr_name;
361 my $dest_slice_sr_id;
365 $dest_slice_start = $dest_slice->start();
366 $dest_slice_end = $dest_slice->end();
367 $dest_slice_strand = $dest_slice->strand();
368 $dest_slice_length = $dest_slice->length();
369 $dest_slice_cs = $dest_slice->coord_system();
370 $dest_slice_sr_name = $dest_slice->seq_region_name();
371 $dest_slice_sr_id = $dest_slice->get_seq_region_id();
372 $asma = $self->db->get_AssemblyMapperAdaptor();
375 FEATURE:
while($sth->fetch()) {
377 #get the analysis object
378 my $analysis = $analysis_hash{$analysis_id} ||= $aa->fetch_by_dbID($analysis_id);
379 $analysis_hash{$analysis_id} = $analysis;
381 #need to get the internal_seq_region, if present
382 $seq_region_id = $self->get_seq_region_id_internal($seq_region_id);
383 my $slice = $slice_hash{
"ID:".$seq_region_id};
386 $slice = $sa->fetch_by_seq_region_id($seq_region_id);
387 $slice_hash{
"ID:".$seq_region_id} = $slice;
388 $sr_name_hash{$seq_region_id} = $slice->seq_region_name();
389 $sr_cs_hash{$seq_region_id} = $slice->coord_system();
392 #obtain a mapper if none was defined, but a dest_seq_region was
393 if(!$mapper && $dest_slice && !$dest_slice_cs->equals($slice->coord_system)) {
394 $mapper = $asma->fetch_by_CoordSystems($dest_slice_cs, $slice->coord_system);
397 my $sr_name = $sr_name_hash{$seq_region_id};
398 my $sr_cs = $sr_cs_hash{$seq_region_id};
401 # remap the feature coordinates to another coord system
402 # if a mapper was provided
407 if (defined $dest_slice && $mapper->isa(
'Bio::EnsEMBL::ChainedAssemblyMapper') ) {
408 ($seq_region_id, $seq_region_start, $seq_region_end, $seq_region_strand) =
409 $mapper->map($sr_name, $seq_region_start, $seq_region_end, $seq_region_strand, $sr_cs, 1, $dest_slice);
412 ($seq_region_id, $seq_region_start, $seq_region_end, $seq_region_strand) =
413 $mapper->fastmap($sr_name, $seq_region_start, $seq_region_end, $seq_region_strand, $sr_cs);
416 #skip features that map to gaps or coord system boundaries
417 next FEATURE
if (!defined($seq_region_id));
419 #get a slice in the coord system we just mapped to
420 $slice = $slice_hash{
"ID:".$seq_region_id} ||= $sa->fetch_by_seq_region_id($seq_region_id);
424 # If a destination slice was provided convert the coords.
426 if (defined($dest_slice)) {
427 my $seq_region_len = $dest_slice->seq_region_length();
429 if ( $dest_slice_strand == 1 ) {
430 $seq_region_start = $seq_region_start - $dest_slice_start + 1;
431 $seq_region_end = $seq_region_end - $dest_slice_start + 1;
433 if ( $dest_slice->is_circular ) {
434 # Handle circular chromosomes.
436 if ( $seq_region_start > $seq_region_end ) {
437 # Looking at a feature overlapping the chromosome origin.
439 if ( $seq_region_end > $dest_slice_start ) {
440 # Looking at the region in the beginning of the chromosome
441 $seq_region_start -= $seq_region_len;
443 if ( $seq_region_end < 0 ) {
444 $seq_region_end += $seq_region_len;
447 if ($dest_slice_start > $dest_slice_end && $seq_region_end < 0) {
448 # Looking at the region overlapping the chromosome
449 # origin and a feature which is at the beginning of the
451 $seq_region_start += $seq_region_len;
452 $seq_region_end += $seq_region_len;
458 my $start = $dest_slice_end - $seq_region_end + 1;
459 my $end = $dest_slice_end - $seq_region_start + 1;
461 if ($dest_slice->is_circular()) {
463 if ($dest_slice_start > $dest_slice_end) {
464 # slice spans origin or replication
466 if ($seq_region_start >= $dest_slice_start) {
467 $end += $seq_region_len;
468 $start += $seq_region_len
if $seq_region_end > $dest_slice_start;
470 } elsif ($seq_region_start <= $dest_slice_end) {
472 } elsif ($seq_region_end >= $dest_slice_start) {
473 $start += $seq_region_len;
474 $end += $seq_region_len;
476 } elsif ($seq_region_end <= $dest_slice_end) {
477 $end += $seq_region_len
if $end < 0;
479 } elsif ($seq_region_start > $seq_region_end) {
480 $end += $seq_region_len;
485 if ($seq_region_start <= $dest_slice_end and $seq_region_end >= $dest_slice_start) {
487 } elsif ($seq_region_start > $seq_region_end) {
488 if ($seq_region_start <= $dest_slice_end) {
489 $start -= $seq_region_len;
490 } elsif ($seq_region_end >= $dest_slice_start) {
491 $end += $seq_region_len;
497 $seq_region_start = $start;
498 $seq_region_end = $end;
499 $seq_region_strand *= -1;
501 } ## end
else [
if ( $dest_slice_strand...)]
503 # Throw away features off the end of the requested slice or on
504 # different seq_region.
505 if ($seq_region_end < 1
506 || $seq_region_start > $dest_slice_length
507 || ($dest_slice_sr_id != $seq_region_id)) {
510 $slice = $dest_slice;
513 # Finally, create the new DnaAlignFeature.
515 $self->_create_feature_fast(
516 'Bio::EnsEMBL::DnaDnaAlignFeature', {
518 'start' => $seq_region_start,
519 'end' => $seq_region_end,
520 'strand' => $seq_region_strand,
521 'hseqname' => $hit_name,
522 'hstart' => $hit_start,
524 'hstrand' => $hit_strand,
526 'p_value' => $evalue,
527 'percent_id' => $perc_ident,
528 'cigar_string' => $cigar_line,
529 'analysis' => $analysis,
531 'dbID' => $dna_align_feature_id,
532 'external_db_id' => $external_db_id,
533 'hcoverage' => $hcoverage,
534 'align_type' => $align_type,
535 'dbname' => $external_db_name,
536 'db_display_name' => $external_display_db_name
539 } ## end
while ( $sth->fetch() )
542 } ## end sub _objs_from_sth
547 Example : @feature_ids = @{$dna_align_feature_adaptor->list_dbIDs()};
548 Description: Gets an array of
internal ids
for all dna align features in
550 Arg[1] : <optional>
int. not 0
for the ids to be sorted by the seq_region.
551 Returntype : list of ints
559 my ($self, $ordered) = @_;
561 return $self->_list_dbIDs(
"dna_align_feature",undef, $ordered);