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;
69 Example : @tabs = $self->_tables
70 Description: PROTECTED implementation of the
abstract method inherited from
72 Returntype : list of listrefs of strings
82 return ([
'dna_align_feature',
'daf'],[
'external_db',
'exdb']);
87 return ([
'external_db',
"exdb.external_db_id = daf.external_db_id"]);
93 Example : @columns = $self->_columns
94 Description: PROTECTED implementation of
abstract superclass method.
95 Returns a list of columns that are needed
for object creation.
96 Returntype : list of strings
106 #warning, implementation of _objs_from_sth method depends on order of list
107 return qw(daf.dna_align_feature_id
112 daf.seq_region_strand
125 exdb.db_display_name);
131 Arg [1] : list of Bio::EnsEMBL::DnaAlignFeatures @feats
132 the features to store in the database
133 Example : $dna_align_feature_adaptor->store(@features);
134 Description: Stores a list of DnaAlignFeatures in the database
136 Exceptions :
throw if any of the provided features cannot be stored
138 * The feature does not have an associate Slice
139 * The feature does not have an associated analysis
140 * The Slice the feature is associated with is on a seq_region
141 unknown to
this database
142 A warning is given
if:
143 * The feature has already been stored in
this db
150 my ( $self, @feats ) = @_;
152 throw(
"Must call store with features")
if ( scalar(@feats) == 0 );
154 my @tabs = $self->_tables;
155 my ($tablename) = @{ $tabs[0] };
157 my $db = $self->db();
158 my $analysis_adaptor = $db->get_AnalysisAdaptor();
160 my $sth = $self->prepare(
161 "INSERT INTO $tablename (seq_region_id, seq_region_start,
162 seq_region_end, seq_region_strand,
163 hit_start, hit_end, hit_strand, hit_name,
164 cigar_line, analysis_id, score, evalue,
165 perc_ident, external_db_id, hcoverage, align_type)
166 VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" # 16 arguments, external_data removed and align_type added
170 foreach my $feat (@feats) {
171 if ( !ref $feat || !$feat->isa(
"Bio::EnsEMBL::DnaDnaAlignFeature") )
173 throw(
"feature must be a Bio::EnsEMBL::DnaDnaAlignFeature, not a [". ref($feat).
"]." );
176 if ( $feat->is_stored($db) ) {
177 warning(
"DnaDnaAlignFeature [".$feat->dbID().
"] is already stored in this database." );
181 my $hstart = $feat->hstart();
182 my $hend = $feat->hend();
183 my $hstrand = $feat->hstrand();
184 $self->_check_start_end_strand( $hstart, $hend, $hstrand, $feat->hslice );
186 my $cigar_string = $feat->cigar_string();
187 if ( !$cigar_string ) {
188 $cigar_string = $feat->length() .
'M';
189 warning(
"DnaDnaAlignFeature does not define a cigar_string.\n"
190 .
"Assuming ungapped block with cigar_line=$cigar_string ." );
192 my $align_type = $feat->align_type();
194 my $hseqname = $feat->hseqname();
196 throw(
"DnaDnaAlignFeature must define an hseqname.");
199 if ( !defined( $feat->analysis ) ) {
201 "An analysis must be attached to the features to be stored.");
204 #store the analysis if it has not been stored yet
205 if ( !$feat->analysis->is_stored($db) ) {
206 $analysis_adaptor->store( $feat->analysis() );
209 my $original = $feat;
211 ( $feat, $seq_region_id ) = $self->_pre_store($feat);
213 $sth->bind_param( 1, $seq_region_id, SQL_INTEGER );
214 $sth->bind_param( 2, $feat->start, SQL_INTEGER );
215 $sth->bind_param( 3, $feat->end, SQL_INTEGER );
216 $sth->bind_param( 4, $feat->strand, SQL_TINYINT );
217 $sth->bind_param( 5, $hstart, SQL_INTEGER );
218 $sth->bind_param( 6, $hend, SQL_INTEGER );
219 $sth->bind_param( 7, $hstrand, SQL_TINYINT );
220 $sth->bind_param( 8, $hseqname, SQL_VARCHAR );
221 $sth->bind_param( 9, $cigar_string, SQL_LONGVARCHAR );
222 $sth->bind_param( 10, $feat->analysis->dbID, SQL_INTEGER );
223 $sth->bind_param( 11, $feat->score, SQL_DOUBLE );
224 $sth->bind_param( 12, $feat->p_value, SQL_DOUBLE );
225 $sth->bind_param( 13, $feat->percent_id, SQL_FLOAT );
226 $sth->bind_param( 14, $feat->external_db_id, SQL_INTEGER );
227 $sth->bind_param( 15, $feat->hcoverage, SQL_DOUBLE );
228 $sth->bind_param( 16, $feat->align_type, SQL_VARCHAR);
231 my $dbId = $self->last_insert_id(
"${tablename}_id", undef, $tablename);
233 # store attributes if there are any
234 my $attr_adaptor = $db->get_AttributeAdaptor();
235 $attr_adaptor->store_on_DnaDnaAlignFeature($dbId, $feat->get_all_Attributes);
237 $original->dbID( $dbId );
238 $original->adaptor($self);
239 } ## end
foreach my $feat (@feats)
247 Arg [1] : A feature $feature
248 Example : $feature_adaptor->remove($feature);
249 Description: This removes a feature from the database. The table the
250 feature is removed from is defined by the
abstract method
251 _tablename, and the primary key of the table is assumed
252 to be _tablename() .
'_id'. The feature argument must
253 be an
object implementing the dbID method, and
for the
254 feature to be removed from the database a dbID value must
257 Exceptions : thrown
if $feature arg does not implement dbID(), or
if
258 $feature->dbID is not a
true value
266 my ($self, $feature) = @_;
268 if(!$feature || !ref($feature) || !$feature->isa(
'Bio::EnsEMBL::Feature')) {
269 throw(
'Feature argument is required');
272 if(!$feature->is_stored($self->db)) {
273 throw(
"This feature is not stored in this database");
276 my @tabs = $self->_tables;
277 my ($table) = @{$tabs[0]};
279 my $sth = $self->prepare(
"DELETE FROM $table WHERE ${table}_id = ?");
280 $sth->bind_param(1,$feature->dbID,SQL_INTEGER);
283 # remove the attributes associated with this feature
284 my $attrib_adaptor = $self->db->get_AttributeAdaptor;
285 $attrib_adaptor->remove_from_DnaDnaAlignFeature($feature);
287 #unset the feature dbID ad adaptor
288 $feature->dbID(undef);
289 $feature->adaptor(undef);
295 =head2 _objs_from_sth
297 Arg [1] : DBI statement handle $sth
298 an exectuted DBI statement handle generated by selecting
299 the columns specified by _columns() from the table specified
301 Example : @dna_dna_align_feats = $self->_obj_from_hashref
302 Description: PROTECTED implementation of superclass abstract method.
303 Creates DnaDnaAlignFeature objects from a DBI hashref
304 Returntype : listref of
Bio::
EnsEMBL::DnaDnaAlignFeatures
306 Caller :
Bio::
EnsEMBL::BaseFeatureAdaptor::generic_fetch
312 my ( $self, $sth, $mapper, $dest_slice ) = @_;
315 # This code is ugly because an attempt has been made to remove as many
316 # function calls as possible for speed purposes. Thus many caches and
317 # a fair bit of gymnastics is used.
320 # In case of userdata we need the features on the dest_slice. In case
321 # of get_all_supporting_features dest_slice is not provided.
322 my $sa = ( $dest_slice
323 ? $dest_slice->adaptor()
324 : $self->db()->get_SliceAdaptor() );
325 my $aa = $self->db->get_AnalysisAdaptor();
333 my ( $dna_align_feature_id, $seq_region_id,
334 $analysis_id, $seq_region_start,
335 $seq_region_end, $seq_region_strand,
336 $hit_start, $hit_end,
337 $hit_name, $hit_strand,
338 $cigar_line, $evalue,
340 $external_db_id, $hcoverage,
342 $external_db_name, $external_display_db_name );
344 $sth->bind_columns( \( $dna_align_feature_id, $seq_region_id,
345 $analysis_id, $seq_region_start,
346 $seq_region_end, $seq_region_strand,
347 $hit_start, $hit_end,
348 $hit_name, $hit_strand,
349 $cigar_line, $evalue,
351 $external_db_id, $hcoverage,
353 $external_db_name, $external_display_db_name )
356 my $dest_slice_start;
358 my $dest_slice_strand;
359 my $dest_slice_length;
361 my $dest_slice_sr_name;
362 my $dest_slice_sr_id;
366 $dest_slice_start = $dest_slice->start();
367 $dest_slice_end = $dest_slice->end();
368 $dest_slice_strand = $dest_slice->strand();
369 $dest_slice_length = $dest_slice->length();
370 $dest_slice_cs = $dest_slice->coord_system();
371 $dest_slice_sr_name = $dest_slice->seq_region_name();
372 $dest_slice_sr_id = $dest_slice->get_seq_region_id();
373 $asma = $self->db->get_AssemblyMapperAdaptor();
376 FEATURE:
while($sth->fetch()) {
378 #get the analysis object
379 my $analysis = $analysis_hash{$analysis_id} ||= $aa->fetch_by_dbID($analysis_id);
380 $analysis_hash{$analysis_id} = $analysis;
382 #need to get the internal_seq_region, if present
383 $seq_region_id = $self->get_seq_region_id_internal($seq_region_id);
384 my $slice = $slice_hash{
"ID:".$seq_region_id};
387 $slice = $sa->fetch_by_seq_region_id($seq_region_id);
388 $slice_hash{
"ID:".$seq_region_id} = $slice;
389 $sr_name_hash{$seq_region_id} = $slice->seq_region_name();
390 $sr_cs_hash{$seq_region_id} = $slice->coord_system();
393 #obtain a mapper if none was defined, but a dest_seq_region was
394 if(!$mapper && $dest_slice && !$dest_slice_cs->equals($slice->coord_system)) {
395 $mapper = $asma->fetch_by_CoordSystems($dest_slice_cs, $slice->coord_system);
398 my $sr_name = $sr_name_hash{$seq_region_id};
399 my $sr_cs = $sr_cs_hash{$seq_region_id};
402 # remap the feature coordinates to another coord system
403 # if a mapper was provided
408 if (defined $dest_slice && $mapper->isa(
'Bio::EnsEMBL::ChainedAssemblyMapper') ) {
409 ($seq_region_id, $seq_region_start, $seq_region_end, $seq_region_strand) =
410 $mapper->map($sr_name, $seq_region_start, $seq_region_end, $seq_region_strand, $sr_cs, 1, $dest_slice);
413 ($seq_region_id, $seq_region_start, $seq_region_end, $seq_region_strand) =
414 $mapper->fastmap($sr_name, $seq_region_start, $seq_region_end, $seq_region_strand, $sr_cs);
417 #skip features that map to gaps or coord system boundaries
418 next FEATURE
if (!defined($seq_region_id));
420 #get a slice in the coord system we just mapped to
421 $slice = $slice_hash{
"ID:".$seq_region_id} ||= $sa->fetch_by_seq_region_id($seq_region_id);
425 # If a destination slice was provided convert the coords.
427 if (defined($dest_slice)) {
428 my $seq_region_len = $dest_slice->seq_region_length();
430 if ( $dest_slice_strand == 1 ) {
431 $seq_region_start = $seq_region_start - $dest_slice_start + 1;
432 $seq_region_end = $seq_region_end - $dest_slice_start + 1;
434 if ( $dest_slice->is_circular ) {
435 # Handle circular chromosomes.
437 if ( $seq_region_start > $seq_region_end ) {
438 # Looking at a feature overlapping the chromosome origin.
440 if ( $seq_region_end > $dest_slice_start ) {
441 # Looking at the region in the beginning of the chromosome
442 $seq_region_start -= $seq_region_len;
444 if ( $seq_region_end < 0 ) {
445 $seq_region_end += $seq_region_len;
448 if ($dest_slice_start > $dest_slice_end && $seq_region_end < 0) {
449 # Looking at the region overlapping the chromosome
450 # origin and a feature which is at the beginning of the
452 $seq_region_start += $seq_region_len;
453 $seq_region_end += $seq_region_len;
459 my $start = $dest_slice_end - $seq_region_end + 1;
460 my $end = $dest_slice_end - $seq_region_start + 1;
462 if ($dest_slice->is_circular()) {
464 if ($dest_slice_start > $dest_slice_end) {
465 # slice spans origin or replication
467 if ($seq_region_start >= $dest_slice_start) {
468 $end += $seq_region_len;
469 $start += $seq_region_len
if $seq_region_end > $dest_slice_start;
471 } elsif ($seq_region_start <= $dest_slice_end) {
473 } elsif ($seq_region_end >= $dest_slice_start) {
474 $start += $seq_region_len;
475 $end += $seq_region_len;
477 } elsif ($seq_region_end <= $dest_slice_end) {
478 $end += $seq_region_len
if $end < 0;
480 } elsif ($seq_region_start > $seq_region_end) {
481 $end += $seq_region_len;
486 if ($seq_region_start <= $dest_slice_end and $seq_region_end >= $dest_slice_start) {
488 } elsif ($seq_region_start > $seq_region_end) {
489 if ($seq_region_start <= $dest_slice_end) {
490 $start -= $seq_region_len;
491 } elsif ($seq_region_end >= $dest_slice_start) {
492 $end += $seq_region_len;
498 $seq_region_start = $start;
499 $seq_region_end = $end;
500 $seq_region_strand *= -1;
502 } ## end
else [
if ( $dest_slice_strand...)]
504 # Throw away features off the end of the requested slice or on
505 # different seq_region.
506 if ($seq_region_end < 1
507 || $seq_region_start > $dest_slice_length
508 || ($dest_slice_sr_id != $seq_region_id)) {
511 $slice = $dest_slice;
514 # Finally, create the new DnaAlignFeature.
516 $self->_create_feature_fast(
517 'Bio::EnsEMBL::DnaDnaAlignFeature', {
519 'start' => $seq_region_start,
520 'end' => $seq_region_end,
521 'strand' => $seq_region_strand,
522 'hseqname' => $hit_name,
523 'hstart' => $hit_start,
525 'hstrand' => $hit_strand,
527 'p_value' => $evalue,
528 'percent_id' => $perc_ident,
529 'cigar_string' => $cigar_line,
530 'analysis' => $analysis,
532 'dbID' => $dna_align_feature_id,
533 'external_db_id' => $external_db_id,
534 'hcoverage' => $hcoverage,
535 'align_type' => $align_type,
536 'dbname' => $external_db_name,
537 'db_display_name' => $external_display_db_name
540 } ## end
while ( $sth->fetch() )
543 } ## end sub _objs_from_sth
548 Example : @feature_ids = @{$dna_align_feature_adaptor->list_dbIDs()};
549 Description: Gets an array of
internal ids
for all dna align features in
551 Arg[1] : <optional>
int. not 0
for the ids to be sorted by the seq_region.
552 Returntype : list of ints
560 my ($self, $ordered) = @_;
562 return $self->_list_dbIDs(
"dna_align_feature",undef, $ordered);