Mercurial > repos > mahtabm > ensembl
comparison variant_effect_predictor/Bio/EnsEMBL/DBSQL/TranscriptAdaptor.pm @ 0:1f6dce3d34e0
Uploaded
| author | mahtabm |
|---|---|
| date | Thu, 11 Apr 2013 02:01:53 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:1f6dce3d34e0 |
|---|---|
| 1 =head1 LICENSE | |
| 2 | |
| 3 Copyright (c) 1999-2012 The European Bioinformatics Institute and | |
| 4 Genome Research Limited. All rights reserved. | |
| 5 | |
| 6 This software is distributed under a modified Apache license. | |
| 7 For license details, please see | |
| 8 | |
| 9 http://www.ensembl.org/info/about/code_licence.html | |
| 10 | |
| 11 =head1 CONTACT | |
| 12 | |
| 13 Please email comments or questions to the public Ensembl | |
| 14 developers list at <dev@ensembl.org>. | |
| 15 | |
| 16 Questions may also be sent to the Ensembl help desk at | |
| 17 <helpdesk@ensembl.org>. | |
| 18 | |
| 19 =cut | |
| 20 | |
| 21 =head1 NAME | |
| 22 | |
| 23 Bio::EnsEMBL::DBSQL::TranscriptAdaptor - An adaptor which performs database | |
| 24 interaction relating to the storage and retrieval of Transcripts | |
| 25 | |
| 26 =head1 SYNOPSIS | |
| 27 | |
| 28 use Bio::EnsEMBL::Registry; | |
| 29 | |
| 30 Bio::EnsEMBL::Registry->load_registry_from_db( | |
| 31 -host => 'ensembldb.ensembl.org', | |
| 32 -user => 'anonymous' | |
| 33 ); | |
| 34 | |
| 35 $transcript_adaptor = | |
| 36 Bio::EnsEMBL::Registry->get_adaptor( 'Human', 'Core', | |
| 37 'Transcript' ); | |
| 38 | |
| 39 $transcript = $transcript_adaptor->fetch_by_dbID(1234); | |
| 40 | |
| 41 $transcript = | |
| 42 $transcript_adaptor->fetch_by_stable_id('ENST00000201961'); | |
| 43 | |
| 44 $slice = | |
| 45 $slice_adaptor->fetch_by_region( 'Chromosome', '3', 1, 1000000 ); | |
| 46 @transcripts = @{ $transcript_adaptor->fetch_all_by_Slice($slice) }; | |
| 47 | |
| 48 ($transcript) = | |
| 49 @{ $transcript_adaptor->fetch_all_by_external_name('NP_065811.1') }; | |
| 50 | |
| 51 =head1 DESCRIPTION | |
| 52 | |
| 53 This adaptor provides a means to retrieve and store information related | |
| 54 to Transcripts. Primarily this involves the retrieval or storage of | |
| 55 Bio::EnsEMBL::Transcript objects from a database. | |
| 56 | |
| 57 See Bio::EnsEMBL::Transcript for details of the Transcript class. | |
| 58 | |
| 59 =cut | |
| 60 | |
| 61 package Bio::EnsEMBL::DBSQL::TranscriptAdaptor; | |
| 62 | |
| 63 use strict; | |
| 64 | |
| 65 use Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor; | |
| 66 use Bio::EnsEMBL::Gene; | |
| 67 use Bio::EnsEMBL::Exon; | |
| 68 use Bio::EnsEMBL::Transcript; | |
| 69 use Bio::EnsEMBL::Translation; | |
| 70 use Bio::EnsEMBL::Utils::Exception qw( deprecate throw warning ); | |
| 71 | |
| 72 use vars qw(@ISA); | |
| 73 @ISA = qw( Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor ); | |
| 74 | |
| 75 | |
| 76 # _tables | |
| 77 # | |
| 78 # Description: PROTECTED implementation of superclass abstract method. | |
| 79 # Returns the names, aliases of the tables to use for queries. | |
| 80 # Returntype : list of listrefs of strings | |
| 81 # Exceptions : none | |
| 82 # Caller : internal | |
| 83 # Status : Stable | |
| 84 | |
| 85 sub _tables { | |
| 86 return ( | |
| 87 [ 'transcript', 't' ], | |
| 88 [ 'xref', 'x' ], | |
| 89 [ 'external_db', 'exdb' ] ); | |
| 90 } | |
| 91 | |
| 92 | |
| 93 #_columns | |
| 94 # | |
| 95 # Description: PROTECTED implementation of superclass abstract method. | |
| 96 # Returns a list of columns to use for queries. | |
| 97 # Returntype : list of strings | |
| 98 # Exceptions : none | |
| 99 # Caller : internal | |
| 100 # Status : Stable | |
| 101 | |
| 102 sub _columns { | |
| 103 my ($self) = @_; | |
| 104 | |
| 105 my $created_date = | |
| 106 $self->db()->dbc()->from_date_to_seconds("created_date"); | |
| 107 my $modified_date = | |
| 108 $self->db()->dbc()->from_date_to_seconds("modified_date"); | |
| 109 | |
| 110 return ( | |
| 111 't.transcript_id', 't.seq_region_id', | |
| 112 't.seq_region_start', 't.seq_region_end', | |
| 113 't.seq_region_strand', 't.analysis_id', | |
| 114 't.gene_id', 't.is_current', | |
| 115 't.stable_id', 't.version', | |
| 116 $created_date, $modified_date, | |
| 117 't.description', 't.biotype', | |
| 118 't.status', 'exdb.db_name', | |
| 119 'exdb.status', 'exdb.db_display_name', | |
| 120 'x.xref_id', 'x.display_label', | |
| 121 'x.dbprimary_acc', 'x.version', | |
| 122 'x.description', 'x.info_type', | |
| 123 'x.info_text' | |
| 124 ); | |
| 125 } | |
| 126 | |
| 127 sub _left_join { | |
| 128 return ( | |
| 129 [ 'xref', "x.xref_id = t.display_xref_id" ], | |
| 130 [ 'external_db', "exdb.external_db_id = x.external_db_id" ] | |
| 131 ); | |
| 132 } | |
| 133 | |
| 134 | |
| 135 =head2 fetch_by_stable_id | |
| 136 | |
| 137 Arg [1] : String $stable_id | |
| 138 The stable id of the transcript to retrieve | |
| 139 Example : my $tr = $tr_adaptor->fetch_by_stable_id('ENST00000309301'); | |
| 140 Description: Retrieves a transcript via its stable id. | |
| 141 Returntype : Bio::EnsEMBL::Transcript | |
| 142 Exceptions : none | |
| 143 Caller : general | |
| 144 Status : Stable | |
| 145 | |
| 146 =cut | |
| 147 | |
| 148 sub fetch_by_stable_id { | |
| 149 my ($self, $stable_id) = @_; | |
| 150 | |
| 151 my $constraint = "t.stable_id = ? AND t.is_current = 1"; | |
| 152 | |
| 153 $self->bind_param_generic_fetch($stable_id,SQL_VARCHAR); | |
| 154 | |
| 155 my ($transcript) = @{ $self->generic_fetch($constraint) }; | |
| 156 | |
| 157 return $transcript; | |
| 158 } | |
| 159 | |
| 160 | |
| 161 sub fetch_all { | |
| 162 my ($self) = @_; | |
| 163 | |
| 164 my $constraint = 't.biotype != "LRG_gene" and t.is_current = 1'; | |
| 165 my @trans = @{ $self->generic_fetch($constraint) }; | |
| 166 return \@trans ; | |
| 167 } | |
| 168 | |
| 169 =head2 fetch_all_versions_by_stable_id | |
| 170 | |
| 171 Arg [1] : String $stable_id | |
| 172 The stable ID of the transcript to retrieve | |
| 173 Example : my $tr = $tr_adaptor->fetch_all_version_by_stable_id | |
| 174 ('ENST00000309301'); | |
| 175 Description : Similar to fetch_by_stable_id, but retrieves all versions of a | |
| 176 transcript stored in the database. | |
| 177 Returntype : listref of Bio::EnsEMBL::Transcript objects | |
| 178 Exceptions : if we cant get the gene in given coord system | |
| 179 Caller : general | |
| 180 Status : At Risk | |
| 181 | |
| 182 =cut | |
| 183 | |
| 184 sub fetch_all_versions_by_stable_id { | |
| 185 my ($self, $stable_id) = @_; | |
| 186 | |
| 187 my $constraint = "t.stable_id = ?"; | |
| 188 | |
| 189 $self->bind_param_generic_fetch($stable_id,SQL_VARCHAR); | |
| 190 | |
| 191 return $self->generic_fetch($constraint); | |
| 192 } | |
| 193 | |
| 194 | |
| 195 =head2 fetch_by_translation_stable_id | |
| 196 | |
| 197 Arg [1] : String $transl_stable_id | |
| 198 The stable identifier of the translation of the transcript to | |
| 199 retrieve | |
| 200 Example : my $tr = $tr_adaptor->fetch_by_translation_stable_id | |
| 201 ('ENSP00000311007'); | |
| 202 Description: Retrieves a Transcript object using the stable identifier of | |
| 203 its translation. | |
| 204 Returntype : Bio::EnsEMBL::Transcript | |
| 205 Exceptions : none | |
| 206 Caller : general | |
| 207 Status : Stable | |
| 208 | |
| 209 =cut | |
| 210 | |
| 211 sub fetch_by_translation_stable_id { | |
| 212 my ($self, $transl_stable_id ) = @_; | |
| 213 | |
| 214 my $sth = $self->prepare(qq( | |
| 215 SELECT t.transcript_id | |
| 216 FROM translation tl, | |
| 217 transcript t | |
| 218 WHERE tl.stable_id = ? | |
| 219 AND tl.transcript_id = t.transcript_id | |
| 220 AND t.is_current = 1 | |
| 221 )); | |
| 222 | |
| 223 $sth->bind_param(1, $transl_stable_id, SQL_VARCHAR); | |
| 224 $sth->execute(); | |
| 225 | |
| 226 my ($id) = $sth->fetchrow_array; | |
| 227 $sth->finish; | |
| 228 if ($id){ | |
| 229 return $self->fetch_by_dbID($id); | |
| 230 } else { | |
| 231 return undef; | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 | |
| 236 =head2 fetch_by_translation_id | |
| 237 | |
| 238 Arg [1] : Int $id | |
| 239 The internal identifier of the translation whose transcript | |
| 240 is to be retrieved | |
| 241 Example : my $tr = $tr_adaptor->fetch_by_translation_id($transl->dbID); | |
| 242 Description: Given the internal identifier of a translation this method | |
| 243 retrieves the transcript associated with that translation. | |
| 244 If the transcript cannot be found undef is returned instead. | |
| 245 Returntype : Bio::EnsEMBL::Transcript or undef | |
| 246 Exceptions : none | |
| 247 Caller : general | |
| 248 Status : Stable | |
| 249 | |
| 250 =cut | |
| 251 | |
| 252 sub fetch_by_translation_id { | |
| 253 my ( $self, $p_dbID ) = @_; | |
| 254 | |
| 255 if ( !defined($p_dbID) ) { | |
| 256 throw("dbID argument is required"); | |
| 257 } | |
| 258 | |
| 259 my $sth = | |
| 260 $self->prepare( "SELECT transcript_id " | |
| 261 . "FROM translation " | |
| 262 . "WHERE translation_id = ?" ); | |
| 263 | |
| 264 $sth->bind_param( 1, $p_dbID, SQL_INTEGER ); | |
| 265 $sth->execute(); | |
| 266 | |
| 267 my ($dbID) = $sth->fetchrow_array(); | |
| 268 $sth->finish(); | |
| 269 | |
| 270 if ($dbID) { | |
| 271 return $self->fetch_by_dbID($dbID); | |
| 272 } | |
| 273 | |
| 274 return undef; | |
| 275 } | |
| 276 | |
| 277 =head2 fetch_all_by_Gene | |
| 278 | |
| 279 Arg [1] : Bio::EnsEMBL::Gene $gene | |
| 280 The gene to fetch transcripts of | |
| 281 Example : my $gene = $gene_adaptor->fetch_by_stable_id('ENSG0000123'); | |
| 282 my @transcripts = { $tr_adaptor->fetch_all_by_Gene($gene) }; | |
| 283 Description: Retrieves Transcript objects for given gene. Puts Genes slice | |
| 284 in each Transcript. | |
| 285 Returntype : Listref of Bio::EnsEMBL::Transcript objects | |
| 286 Exceptions : none | |
| 287 Caller : Gene->get_all_Transcripts() | |
| 288 Status : Stable | |
| 289 | |
| 290 =cut | |
| 291 | |
| 292 sub fetch_all_by_Gene { | |
| 293 my ( $self, $gene ) = @_; | |
| 294 | |
| 295 my $constraint = "t.gene_id = " . $gene->dbID(); | |
| 296 | |
| 297 # Use the fetch_all_by_Slice_constraint method because it handles the | |
| 298 # difficult Haps/PARs and coordinate remapping. | |
| 299 | |
| 300 # Get a slice that entirely overlaps the gene. This is because we | |
| 301 # want all transcripts to be retrieved, not just ones overlapping | |
| 302 # the slice the gene is on (the gene may only partially overlap the | |
| 303 # slice). For speed reasons, only use a different slice if necessary | |
| 304 # though. | |
| 305 | |
| 306 my $gslice = $gene->slice(); | |
| 307 | |
| 308 if ( !defined($gslice) ) { | |
| 309 throw("Gene must have attached slice to retrieve transcripts."); | |
| 310 } | |
| 311 | |
| 312 my $slice; | |
| 313 | |
| 314 if ( $gene->start() < 1 || $gene->end() > $gslice->length() ) { | |
| 315 if ( $gslice->is_circular() ) { | |
| 316 $slice = $gslice; | |
| 317 } else { | |
| 318 $slice = $self->db->get_SliceAdaptor->fetch_by_Feature($gene); | |
| 319 } | |
| 320 } else { | |
| 321 $slice = $gslice; | |
| 322 } | |
| 323 | |
| 324 my $transcripts = | |
| 325 $self->fetch_all_by_Slice_constraint( $slice, $constraint ); | |
| 326 | |
| 327 if ( $slice != $gslice ) { | |
| 328 my @out; | |
| 329 foreach my $tr ( @{$transcripts} ) { | |
| 330 push( @out, $tr->transfer($gslice) ); | |
| 331 } | |
| 332 $transcripts = \@out; | |
| 333 } | |
| 334 | |
| 335 my $canonical_t = $gene->canonical_transcript(); | |
| 336 | |
| 337 foreach my $t ( @{$transcripts} ) { | |
| 338 if ( $t->equals($canonical_t) ) { | |
| 339 $t->is_canonical(1); | |
| 340 last; | |
| 341 } | |
| 342 } | |
| 343 | |
| 344 return $transcripts; | |
| 345 } ## end sub fetch_all_by_Gene | |
| 346 | |
| 347 | |
| 348 =head2 fetch_all_by_Slice | |
| 349 | |
| 350 Arg [1] : Bio::EnsEMBL::Slice $slice | |
| 351 The slice to fetch transcripts on | |
| 352 Arg [2] : (optional) Boolean $load_exons | |
| 353 If true, exons will be loaded immediately rather than | |
| 354 lazy loaded later | |
| 355 Arg [3] : (optional) String $logic_name | |
| 356 The logic name of the type of features to obtain | |
| 357 ARG [4] : (optional) String $constraint | |
| 358 An extra contraint. | |
| 359 Example : my @transcripts = @{ $tr_adaptor->fetch_all_by_Slice($slice) }; | |
| 360 Description: Overrides superclass method to optionally load exons | |
| 361 immediately rather than lazy-loading them later. This | |
| 362 is more efficient when there are a lot of transcripts whose | |
| 363 exons are going to be used. | |
| 364 Returntype : Listref of Bio::EnsEMBL::Transcript objects | |
| 365 Exceptions : thrown if exon cannot be placed on transcript slice | |
| 366 Caller : Slice::get_all_Transcripts | |
| 367 Status : Stable | |
| 368 | |
| 369 =cut | |
| 370 | |
| 371 sub fetch_all_by_Slice { | |
| 372 my ( $self, $slice, $load_exons, $logic_name, $constraint ) = @_; | |
| 373 | |
| 374 my $transcripts; | |
| 375 if ( defined($constraint) && $constraint ne '' ) { | |
| 376 $transcripts = $self->SUPER::fetch_all_by_Slice_constraint( $slice, | |
| 377 't.is_current = 1 AND ' . $constraint, $logic_name ); | |
| 378 } else { | |
| 379 $transcripts = $self->SUPER::fetch_all_by_Slice_constraint( $slice, | |
| 380 't.is_current = 1', $logic_name ); | |
| 381 } | |
| 382 | |
| 383 # if there are 0 or 1 transcripts still do lazy-loading | |
| 384 if ( !$load_exons || @$transcripts < 2 ) { | |
| 385 return $transcripts; | |
| 386 } | |
| 387 | |
| 388 # preload all of the exons now, instead of lazy loading later | |
| 389 # faster than 1 query per transcript | |
| 390 | |
| 391 # first check if the exons are already preloaded | |
| 392 # @todo FIXME: Should test all exons. | |
| 393 if ( exists( $transcripts->[0]->{'_trans_exon_array'} ) ) { | |
| 394 return $transcripts; | |
| 395 } | |
| 396 | |
| 397 # get extent of region spanned by transcripts | |
| 398 my ( $min_start, $max_end ); | |
| 399 foreach my $tr (@$transcripts) { | |
| 400 if ( !defined($min_start) || $tr->seq_region_start() < $min_start ) | |
| 401 { | |
| 402 $min_start = $tr->seq_region_start(); | |
| 403 } | |
| 404 if ( !defined($max_end) || $tr->seq_region_end() > $max_end ) { | |
| 405 $max_end = $tr->seq_region_end(); | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 my $ext_slice; | |
| 410 | |
| 411 if ( $min_start >= $slice->start() && $max_end <= $slice->end() ) { | |
| 412 $ext_slice = $slice; | |
| 413 } else { | |
| 414 my $sa = $self->db()->get_SliceAdaptor(); | |
| 415 $ext_slice = $sa->fetch_by_region( | |
| 416 $slice->coord_system->name(), $slice->seq_region_name(), | |
| 417 $min_start, $max_end, | |
| 418 $slice->strand(), $slice->coord_system->version() ); | |
| 419 } | |
| 420 | |
| 421 # associate exon identifiers with transcripts | |
| 422 | |
| 423 my %tr_hash = map { $_->dbID => $_ } @{$transcripts}; | |
| 424 | |
| 425 my $tr_id_str = join( ',', keys(%tr_hash) ); | |
| 426 | |
| 427 my $sth = | |
| 428 $self->prepare( "SELECT transcript_id, exon_id, rank " | |
| 429 . "FROM exon_transcript " | |
| 430 . "WHERE transcript_id IN ($tr_id_str)" ); | |
| 431 | |
| 432 $sth->execute(); | |
| 433 | |
| 434 my ( $tr_id, $ex_id, $rank ); | |
| 435 $sth->bind_columns( \( $tr_id, $ex_id, $rank ) ); | |
| 436 | |
| 437 my %ex_tr_hash; | |
| 438 | |
| 439 while ( $sth->fetch() ) { | |
| 440 $ex_tr_hash{$ex_id} ||= []; | |
| 441 push( @{ $ex_tr_hash{$ex_id} }, [ $tr_hash{$tr_id}, $rank ] ); | |
| 442 } | |
| 443 | |
| 444 my $ea = $self->db()->get_ExonAdaptor(); | |
| 445 my $exons = $ea->fetch_all_by_Slice_constraint( | |
| 446 $ext_slice, | |
| 447 sprintf( "e.exon_id IN (%s)", | |
| 448 join( ',', sort { $a <=> $b } keys(%ex_tr_hash) ) ) ); | |
| 449 | |
| 450 # move exons onto transcript slice, and add them to transcripts | |
| 451 foreach my $ex ( @{$exons} ) { | |
| 452 my $new_ex; | |
| 453 if ( $slice != $ext_slice ) { | |
| 454 $new_ex = $ex->transfer($slice); | |
| 455 if ( !defined($new_ex) ) { | |
| 456 throw("Unexpected. " | |
| 457 . "Exon could not be transfered onto Transcript slice." ); | |
| 458 } | |
| 459 } else { | |
| 460 $new_ex = $ex; | |
| 461 } | |
| 462 | |
| 463 foreach my $row ( @{ $ex_tr_hash{ $new_ex->dbID() } } ) { | |
| 464 my ( $tr, $rank ) = @{$row}; | |
| 465 $tr->add_Exon( $new_ex, $rank ); | |
| 466 } | |
| 467 } | |
| 468 | |
| 469 my $tla = $self->db()->get_TranslationAdaptor(); | |
| 470 | |
| 471 # load all of the translations at once | |
| 472 $tla->fetch_all_by_Transcript_list($transcripts); | |
| 473 | |
| 474 return $transcripts; | |
| 475 } ## end sub fetch_all_by_Slice | |
| 476 | |
| 477 | |
| 478 =head2 fetch_all_by_external_name | |
| 479 | |
| 480 Arg [1] : String $external_name | |
| 481 An external identifier of the transcript to be obtained | |
| 482 Arg [2] : (optional) String $external_db_name | |
| 483 The name of the external database from which the | |
| 484 identifier originates. | |
| 485 Arg [3] : Boolean override. Force SQL regex matching for users | |
| 486 who really do want to find all 'NM%' | |
| 487 Example : my @transcripts = | |
| 488 @{ $tr_adaptor->fetch_all_by_external_name( 'NP_065811.1') }; | |
| 489 my @more_transcripts = | |
| 490 @{$tr_adaptor->fetch_all_by_external_name( 'NP_0658__._')}; | |
| 491 Description: Retrieves all transcripts which are associated with | |
| 492 an external identifier such as a GO term, Swissprot | |
| 493 identifer, etc. Usually there will only be a single | |
| 494 transcript returned in the list reference, but not | |
| 495 always. Transcripts are returned in their native | |
| 496 coordinate system, i.e. the coordinate system in which | |
| 497 they are stored in the database. If they are required | |
| 498 in another coordinate system the Transcript::transfer or | |
| 499 Transcript::transform method can be used to convert them. | |
| 500 If no transcripts with the external identifier are found, | |
| 501 a reference to an empty list is returned. | |
| 502 SQL wildcards % and _ are supported in the $external_name | |
| 503 but their use is somewhat restricted for performance reasons. | |
| 504 Users that really do want % and _ in the first three characters | |
| 505 should use argument 3 to prevent optimisations | |
| 506 Returntype : listref of Bio::EnsEMBL::Transcript | |
| 507 Exceptions : none | |
| 508 Caller : general | |
| 509 Status : Stable | |
| 510 | |
| 511 =cut | |
| 512 | |
| 513 sub fetch_all_by_external_name { | |
| 514 my ( $self, $external_name, $external_db_name, $override) = @_; | |
| 515 | |
| 516 my $entryAdaptor = $self->db->get_DBEntryAdaptor(); | |
| 517 | |
| 518 my @ids = | |
| 519 $entryAdaptor->list_transcript_ids_by_extids( $external_name, | |
| 520 $external_db_name, $override ); | |
| 521 | |
| 522 return $self->fetch_all_by_dbID_list( \@ids ); | |
| 523 } | |
| 524 | |
| 525 =head2 fetch_all_by_GOTerm | |
| 526 | |
| 527 Arg [1] : Bio::EnsEMBL::OntologyTerm | |
| 528 The GO term for which transcripts should be fetched. | |
| 529 | |
| 530 Example: @transcripts = @{ | |
| 531 $transcript_adaptor->fetch_all_by_GOTerm( | |
| 532 $go_adaptor->fetch_by_accession('GO:0030326') ) }; | |
| 533 | |
| 534 Description : Retrieves a list of transcripts that are | |
| 535 associated with the given GO term, or with any of | |
| 536 its descendent GO terms. The transcripts returned | |
| 537 are in their native coordinate system, i.e. in | |
| 538 the coordinate system in which they are stored | |
| 539 in the database. If another coordinate system | |
| 540 is required then the Transcript::transfer or | |
| 541 Transcript::transform method can be used. | |
| 542 | |
| 543 Return type : listref of Bio::EnsEMBL::Transcript | |
| 544 Exceptions : Throws of argument is not a GO term | |
| 545 Caller : general | |
| 546 Status : Stable | |
| 547 | |
| 548 =cut | |
| 549 | |
| 550 sub fetch_all_by_GOTerm { | |
| 551 my ( $self, $term ) = @_; | |
| 552 | |
| 553 assert_ref( $term, 'Bio::EnsEMBL::OntologyTerm' ); | |
| 554 if ( $term->ontology() ne 'GO' ) { | |
| 555 throw('Argument is not a GO term'); | |
| 556 } | |
| 557 | |
| 558 my $entryAdaptor = $self->db->get_DBEntryAdaptor(); | |
| 559 | |
| 560 my %unique_dbIDs; | |
| 561 foreach my $accession ( map { $_->accession() } | |
| 562 ( $term, @{ $term->descendants() } ) ) | |
| 563 { | |
| 564 my @ids = | |
| 565 $entryAdaptor->list_transcript_ids_by_extids( $accession, 'GO' ); | |
| 566 foreach my $dbID (@ids) { $unique_dbIDs{$dbID} = 1 } | |
| 567 } | |
| 568 | |
| 569 my @result = @{ | |
| 570 $self->fetch_all_by_dbID_list( | |
| 571 [ sort { $a <=> $b } keys(%unique_dbIDs) ] | |
| 572 ) }; | |
| 573 | |
| 574 return \@result; | |
| 575 } ## end sub fetch_all_by_GOTerm | |
| 576 | |
| 577 =head2 fetch_all_by_GOTerm_accession | |
| 578 | |
| 579 Arg [1] : String | |
| 580 The GO term accession for which genes should be | |
| 581 fetched. | |
| 582 | |
| 583 Example : | |
| 584 | |
| 585 @genes = | |
| 586 @{ $gene_adaptor->fetch_all_by_GOTerm_accession( | |
| 587 'GO:0030326') }; | |
| 588 | |
| 589 Description : Retrieves a list of genes that are associated with | |
| 590 the given GO term, or with any of its descendent | |
| 591 GO terms. The genes returned are in their native | |
| 592 coordinate system, i.e. in the coordinate system | |
| 593 in which they are stored in the database. If | |
| 594 another coordinate system is required then the | |
| 595 Gene::transfer or Gene::transform method can be | |
| 596 used. | |
| 597 | |
| 598 Return type : listref of Bio::EnsEMBL::Gene | |
| 599 Exceptions : Throws of argument is not a GO term accession | |
| 600 Caller : general | |
| 601 Status : Stable | |
| 602 | |
| 603 =cut | |
| 604 | |
| 605 sub fetch_all_by_GOTerm_accession { | |
| 606 my ( $self, $accession ) = @_; | |
| 607 | |
| 608 if ( $accession !~ /^GO:/ ) { | |
| 609 throw('Argument is not a GO term accession'); | |
| 610 } | |
| 611 | |
| 612 my $goAdaptor = | |
| 613 Bio::EnsEMBL::Registry->get_adaptor( 'Multi', 'Ontology', | |
| 614 'OntologyTerm' ); | |
| 615 | |
| 616 my $term = $goAdaptor->fetch_by_accession($accession); | |
| 617 | |
| 618 return $self->fetch_all_by_GOTerm($term); | |
| 619 } | |
| 620 | |
| 621 =head2 fetch_by_display_label | |
| 622 | |
| 623 Arg [1] : String $label - display label of transcript to fetch | |
| 624 Example : my $tr = $tr_adaptor->fetch_by_display_label("BRCA2"); | |
| 625 Description: Returns the transcript which has the given display label or | |
| 626 undef if there is none. If there are more than 1, only the first | |
| 627 is reported. | |
| 628 Returntype : Bio::EnsEMBL::Transcript | |
| 629 Exceptions : none | |
| 630 Caller : general | |
| 631 Status : Stable | |
| 632 | |
| 633 =cut | |
| 634 | |
| 635 sub fetch_by_display_label { | |
| 636 my $self = shift; | |
| 637 my $label = shift; | |
| 638 | |
| 639 my $constraint = "x.display_label = ? AND t.is_current = 1"; | |
| 640 | |
| 641 $self->bind_param_generic_fetch($label,SQL_VARCHAR); | |
| 642 | |
| 643 my ($transcript) = @{ $self->generic_fetch($constraint) }; | |
| 644 | |
| 645 return $transcript; | |
| 646 } | |
| 647 | |
| 648 | |
| 649 =head2 fetch_all_by_exon_stable_id | |
| 650 | |
| 651 Arg [1] : String $stable_id | |
| 652 The stable id of an exon in a transcript | |
| 653 Example : my $tr = $tr_adaptor->fetch_all_by_exon_stable_id | |
| 654 ('ENSE00000309301'); | |
| 655 Description: Retrieves a list of transcripts via an exon stable id. | |
| 656 Returntype : Listref of Bio::EnsEMBL::Transcript objects | |
| 657 Exceptions : none | |
| 658 Caller : general | |
| 659 Status : Stable | |
| 660 | |
| 661 =cut | |
| 662 | |
| 663 sub fetch_all_by_exon_stable_id { | |
| 664 my ($self, $stable_id) = @_; | |
| 665 | |
| 666 my @trans ; | |
| 667 | |
| 668 my $sth = $self->prepare(qq( | |
| 669 SELECT t.transcript_id | |
| 670 FROM exon_transcript et, exon e, transcript t | |
| 671 WHERE e.exon_id = et.exon_id | |
| 672 AND et.transcript_id = t.transcript_id | |
| 673 AND e.stable_id = ? | |
| 674 AND t.is_current = 1 | |
| 675 )); | |
| 676 | |
| 677 $sth->bind_param(1, $stable_id, SQL_VARCHAR); | |
| 678 $sth->execute(); | |
| 679 | |
| 680 while( my $id = $sth->fetchrow_array ) { | |
| 681 my $transcript = $self->fetch_by_dbID($id); | |
| 682 push(@trans, $transcript) if $transcript; | |
| 683 } | |
| 684 | |
| 685 if (!@trans) { | |
| 686 return undef; | |
| 687 } | |
| 688 | |
| 689 return \@trans; | |
| 690 } | |
| 691 | |
| 692 =head2 fetch_all_by_biotype | |
| 693 | |
| 694 Arg [1] : String $biotype | |
| 695 listref of $biotypes | |
| 696 The biotype of the gene to retrieve. You can also have a reference | |
| 697 to a list of biotypes in the event of needing several. | |
| 698 Example : $transcript = $transcript_adaptor->fetch_all_by_biotype('pseudogene'); | |
| 699 $transcript = $transcript_adaptor->fetch_all_by_biotype(['protein_coding','ambiguous_orf']); | |
| 700 Description: Retrieves an array reference of transcript objects from the | |
| 701 database via its biotype or biotypes. | |
| 702 The transcript will be retrieved in its native coordinate system | |
| 703 (i.e. in the coordinate system it is stored in the database). | |
| 704 It may be converted to a different coordinate system through a | |
| 705 call to transform() or transfer(). If the transcript is not found | |
| 706 undef is returned instead. | |
| 707 Returntype : listref of Bio::EnsEMBL::Transcript | |
| 708 Exceptions : if we cant get the transcript in given coord system | |
| 709 Caller : general | |
| 710 Status : Stable | |
| 711 | |
| 712 =cut | |
| 713 | |
| 714 sub fetch_all_by_biotype { | |
| 715 my ($self, $biotype) = @_; | |
| 716 | |
| 717 if (!defined $biotype){ | |
| 718 throw("Biotype or listref of biotypes expected"); | |
| 719 } | |
| 720 my $constraint; | |
| 721 if (ref($biotype) eq 'ARRAY'){ | |
| 722 $constraint = "t.biotype IN ("; | |
| 723 foreach my $b (@{$biotype}){ | |
| 724 $constraint .= "?,"; | |
| 725 $self->bind_param_generic_fetch($b,SQL_VARCHAR); | |
| 726 } | |
| 727 chop($constraint); #remove last , from expression | |
| 728 $constraint .= ") and t.is_current = 1"; | |
| 729 | |
| 730 } | |
| 731 else{ | |
| 732 $constraint = "t.biotype = ? and t.is_current = 1"; | |
| 733 $self->bind_param_generic_fetch($biotype,SQL_VARCHAR); | |
| 734 } | |
| 735 my @transcripts = @{ $self->generic_fetch($constraint) }; | |
| 736 return \@transcripts ; | |
| 737 } | |
| 738 | |
| 739 | |
| 740 =head2 store | |
| 741 | |
| 742 Arg [1] : Bio::EnsEMBL::Transcript $transcript | |
| 743 The transcript to be written to the database | |
| 744 Arg [2] : Int $gene_dbID | |
| 745 The identifier of the gene that this transcript is associated | |
| 746 with | |
| 747 Arg [3] : DEPRECATED (optional) Int $analysis_id | |
| 748 The analysis_id to use when storing this gene. This is for | |
| 749 backward compatibility only and used to fall back to the gene | |
| 750 analysis_id if no analysis object is attached to the transcript | |
| 751 (which you should do for new code). | |
| 752 Example : $transID = $tr_adaptor->store($transcript, $gene->dbID); | |
| 753 Description: Stores a transcript in the database and returns the new | |
| 754 internal identifier for the stored transcript. | |
| 755 Returntype : Int | |
| 756 Exceptions : none | |
| 757 Caller : general | |
| 758 Status : Stable | |
| 759 | |
| 760 =cut | |
| 761 | |
| 762 sub store { | |
| 763 my ( $self, $transcript, $gene_dbID, $analysis_id ) = @_; | |
| 764 | |
| 765 if ( !ref($transcript) | |
| 766 || !$transcript->isa('Bio::EnsEMBL::Transcript') ) | |
| 767 { | |
| 768 throw("$transcript is not a EnsEMBL transcript - not storing"); | |
| 769 } | |
| 770 | |
| 771 my $db = $self->db(); | |
| 772 | |
| 773 if ( $transcript->is_stored($db) ) { | |
| 774 return $transcript->dbID(); | |
| 775 } | |
| 776 | |
| 777 # Force lazy-loading of exons and ensure coords are correct. | |
| 778 $transcript->recalculate_coordinates(); | |
| 779 | |
| 780 my $is_current = ( defined( $transcript->is_current() ) | |
| 781 ? $transcript->is_current() | |
| 782 : 1 ); | |
| 783 | |
| 784 # store analysis | |
| 785 my $analysis = $transcript->analysis(); | |
| 786 my $new_analysis_id; | |
| 787 | |
| 788 if ($analysis) { | |
| 789 if ( $analysis->is_stored($db) ) { | |
| 790 $new_analysis_id = $analysis->dbID; | |
| 791 } else { | |
| 792 $new_analysis_id = $db->get_AnalysisAdaptor->store($analysis); | |
| 793 } | |
| 794 } elsif ($analysis_id) { | |
| 795 # Fall back to analysis passed in (usually from gene) if analysis | |
| 796 # wasn't set explicitely for the transcript. This is deprectated | |
| 797 # though. | |
| 798 warning( "You should explicitely attach " | |
| 799 . "an analysis object to the Transcript. " | |
| 800 . "Will fall back to Gene analysis, " | |
| 801 . "but this behaviour is deprecated." ); | |
| 802 $new_analysis_id = $analysis_id; | |
| 803 } else { | |
| 804 throw("Need an analysis_id to store the Transcript."); | |
| 805 } | |
| 806 | |
| 807 # | |
| 808 # Store exons - this needs to be done before the possible transfer | |
| 809 # of the transcript to another slice (in _prestore()). Transfering | |
| 810 # results in copies being made of the exons and we need to preserve | |
| 811 # the object identity of the exons so that they are not stored twice | |
| 812 # by different transcripts. | |
| 813 # | |
| 814 my $exons = $transcript->get_all_Exons(); | |
| 815 my $exonAdaptor = $db->get_ExonAdaptor(); | |
| 816 foreach my $exon ( @{$exons} ) { | |
| 817 $exonAdaptor->store($exon); | |
| 818 } | |
| 819 | |
| 820 my $original_translation = $transcript->translation(); | |
| 821 my $original = $transcript; | |
| 822 my $seq_region_id; | |
| 823 ( $transcript, $seq_region_id ) = $self->_pre_store($transcript); | |
| 824 | |
| 825 # First store the transcript without a display xref. The display xref | |
| 826 # needs to be set after xrefs are stored which needs to happen after | |
| 827 # transcript is stored. | |
| 828 | |
| 829 # | |
| 830 # Store transcript | |
| 831 # | |
| 832 my $store_transcript_sql = qq( | |
| 833 INSERT INTO transcript | |
| 834 SET gene_id = ?, | |
| 835 analysis_id = ?, | |
| 836 seq_region_id = ?, | |
| 837 seq_region_start = ?, | |
| 838 seq_region_end = ?, | |
| 839 seq_region_strand = ?, | |
| 840 biotype = ?, | |
| 841 status = ?, | |
| 842 description = ?, | |
| 843 is_current = ?, | |
| 844 canonical_translation_id = ? | |
| 845 ); | |
| 846 | |
| 847 if ( defined( $transcript->stable_id() ) ) { | |
| 848 | |
| 849 my $created = $self->db->dbc->from_seconds_to_date($transcript->created_date()); | |
| 850 my $modified = $self->db->dbc->from_seconds_to_date($transcript->modified_date()); | |
| 851 $store_transcript_sql .= ", stable_id = ?, version = ?, created_date = " . $created . " , modified_date = " . $modified; | |
| 852 | |
| 853 } | |
| 854 | |
| 855 my $tst = $self->prepare($store_transcript_sql); | |
| 856 $tst->bind_param( 1, $gene_dbID, SQL_INTEGER ); | |
| 857 $tst->bind_param( 2, $new_analysis_id, SQL_INTEGER ); | |
| 858 $tst->bind_param( 3, $seq_region_id, SQL_INTEGER ); | |
| 859 $tst->bind_param( 4, $transcript->start(), SQL_INTEGER ); | |
| 860 $tst->bind_param( 5, $transcript->end(), SQL_INTEGER ); | |
| 861 $tst->bind_param( 6, $transcript->strand(), SQL_TINYINT ); | |
| 862 $tst->bind_param( 7, $transcript->biotype(), SQL_VARCHAR ); | |
| 863 $tst->bind_param( 8, $transcript->status(), SQL_VARCHAR ); | |
| 864 $tst->bind_param( 9, $transcript->description(), SQL_LONGVARCHAR ); | |
| 865 $tst->bind_param( 10, $is_current, SQL_TINYINT ); | |
| 866 | |
| 867 # If the transcript has a translation, this is updated later: | |
| 868 $tst->bind_param( 11, undef, SQL_INTEGER ); | |
| 869 | |
| 870 if ( defined( $transcript->stable_id() ) ) { | |
| 871 | |
| 872 $tst->bind_param( 12, $transcript->stable_id(), SQL_VARCHAR ); | |
| 873 my $version = ($transcript->version()) ? $transcript->version() : 1; | |
| 874 $tst->bind_param( 13, $version, SQL_INTEGER ); | |
| 875 } | |
| 876 | |
| 877 | |
| 878 $tst->execute(); | |
| 879 $tst->finish(); | |
| 880 | |
| 881 my $transc_dbID = $tst->{'mysql_insertid'}; | |
| 882 | |
| 883 # | |
| 884 # Store translation | |
| 885 # | |
| 886 | |
| 887 my $alt_translations = | |
| 888 $transcript->get_all_alternative_translations(); | |
| 889 my $translation = $transcript->translation(); | |
| 890 | |
| 891 if ( defined($translation) ) { | |
| 892 # Make sure that the start and end exon are set correctly. | |
| 893 my $start_exon = $translation->start_Exon(); | |
| 894 my $end_exon = $translation->end_Exon(); | |
| 895 | |
| 896 if ( !defined($start_exon) ) { | |
| 897 throw("Translation does not define a start exon."); | |
| 898 } | |
| 899 | |
| 900 if ( !defined($end_exon) ) { | |
| 901 throw("Translation does not defined an end exon."); | |
| 902 } | |
| 903 | |
| 904 # If the dbID is not set, this means the exon must have been a | |
| 905 # different object in memory than the the exons of the transcript. | |
| 906 # Try to find the matching exon in all of the exons we just stored. | |
| 907 if ( !defined( $start_exon->dbID() ) ) { | |
| 908 my $key = $start_exon->hashkey(); | |
| 909 ($start_exon) = grep { $_->hashkey() eq $key } @$exons; | |
| 910 | |
| 911 if ( defined($start_exon) ) { | |
| 912 $translation->start_Exon($start_exon); | |
| 913 } else { | |
| 914 throw( "Translation's start_Exon does not appear " | |
| 915 . "to be one of the exons in " | |
| 916 . "its associated Transcript" ); | |
| 917 } | |
| 918 } | |
| 919 | |
| 920 if ( !defined( $end_exon->dbID() ) ) { | |
| 921 my $key = $end_exon->hashkey(); | |
| 922 ($end_exon) = grep { $_->hashkey() eq $key } @$exons; | |
| 923 | |
| 924 if ( defined($end_exon) ) { | |
| 925 $translation->end_Exon($end_exon); | |
| 926 } else { | |
| 927 throw( "Translation's end_Exon does not appear " | |
| 928 . "to be one of the exons in " | |
| 929 . "its associated Transcript." ); | |
| 930 } | |
| 931 } | |
| 932 | |
| 933 my $old_dbid = $translation->dbID(); | |
| 934 $db->get_TranslationAdaptor()->store( $translation, $transc_dbID ); | |
| 935 | |
| 936 # Need to update the canonical_translation_id for this transcript. | |
| 937 | |
| 938 my $sth = $self->prepare( | |
| 939 q( | |
| 940 UPDATE transcript | |
| 941 SET canonical_translation_id = ? | |
| 942 WHERE transcript_id = ?) | |
| 943 ); | |
| 944 | |
| 945 $sth->bind_param( 1, $translation->dbID(), SQL_INTEGER ); | |
| 946 $sth->bind_param( 2, $transc_dbID, SQL_INTEGER ); | |
| 947 | |
| 948 $sth->execute(); | |
| 949 | |
| 950 # Set values of the original translation, we may have copied it when | |
| 951 # we transformed the transcript. | |
| 952 $original_translation->dbID( $translation->dbID() ); | |
| 953 $original_translation->adaptor( $translation->adaptor() ); | |
| 954 } ## end if ( defined($translation...)) | |
| 955 | |
| 956 # | |
| 957 # Store the alternative translations, if there are any. | |
| 958 # | |
| 959 | |
| 960 if ( defined($alt_translations) | |
| 961 && scalar( @{$alt_translations} ) > 0 ) | |
| 962 { | |
| 963 foreach my $alt_translation ( @{$alt_translations} ) { | |
| 964 my $start_exon = $alt_translation->start_Exon(); | |
| 965 my $end_exon = $alt_translation->end_Exon(); | |
| 966 | |
| 967 if ( !defined($start_exon) ) { | |
| 968 throw("Translation does not define a start exon."); | |
| 969 } elsif ( !defined($end_exon) ) { | |
| 970 throw("Translation does not defined an end exon."); | |
| 971 } | |
| 972 | |
| 973 if ( !defined( $start_exon->dbID() ) ) { | |
| 974 my $key = $start_exon->hashkey(); | |
| 975 ($start_exon) = grep { $_->hashkey() eq $key } @{$exons}; | |
| 976 | |
| 977 if ( defined($start_exon) ) { | |
| 978 $alt_translation->start_Exon($start_exon); | |
| 979 } else { | |
| 980 throw( "Translation's start_Exon does not appear " | |
| 981 . "to be one of the exon in" | |
| 982 . "its associated Transcript" ); | |
| 983 } | |
| 984 } elsif ( !defined( $end_exon->dbID() ) ) { | |
| 985 my $key = $end_exon->hashkey(); | |
| 986 ($end_exon) = grep { $_->hashkey() eq $key } @$exons; | |
| 987 | |
| 988 if ( defined($end_exon) ) { | |
| 989 $translation->end_Exon($end_exon); | |
| 990 } else { | |
| 991 throw( "Translation's end_Exon does not appear " | |
| 992 . "to be one of the exons in " | |
| 993 . "its associated Transcript." ); | |
| 994 } | |
| 995 } | |
| 996 | |
| 997 $db->get_TranslationAdaptor() | |
| 998 ->store( $alt_translation, $transc_dbID ); | |
| 999 } ## end foreach my $alt_translation... | |
| 1000 } ## end if ( defined($alt_translations...)) | |
| 1001 | |
| 1002 # | |
| 1003 # Store the xrefs/object xref mapping. | |
| 1004 # | |
| 1005 my $dbEntryAdaptor = $db->get_DBEntryAdaptor(); | |
| 1006 | |
| 1007 foreach my $dbe ( @{ $transcript->get_all_DBEntries() } ) { | |
| 1008 $dbEntryAdaptor->store( $dbe, $transc_dbID, "Transcript", 1 ); | |
| 1009 } | |
| 1010 | |
| 1011 # | |
| 1012 # Update transcript to point to display xref if it is set. | |
| 1013 # | |
| 1014 if ( my $dxref = $transcript->display_xref() ) { | |
| 1015 my $dxref_id; | |
| 1016 | |
| 1017 if ( $dxref->is_stored($db) ) { | |
| 1018 $dxref_id = $dxref->dbID(); | |
| 1019 } else { | |
| 1020 $dxref_id = $dbEntryAdaptor->exists($dxref); | |
| 1021 } | |
| 1022 | |
| 1023 if ( defined($dxref_id) ) { | |
| 1024 my $sth = | |
| 1025 $self->prepare( "UPDATE transcript " | |
| 1026 . "SET display_xref_id = ? " | |
| 1027 . "WHERE transcript_id = ?" ); | |
| 1028 $sth->bind_param( 1, $dxref_id, SQL_INTEGER ); | |
| 1029 $sth->bind_param( 2, $transc_dbID, SQL_INTEGER ); | |
| 1030 $sth->execute(); | |
| 1031 $dxref->dbID($dxref_id); | |
| 1032 $dxref->adaptor($dbEntryAdaptor); | |
| 1033 $sth->finish(); | |
| 1034 } else { | |
| 1035 warning(sprintf( | |
| 1036 "Display_xref %s:%s is not stored in database.\n" | |
| 1037 . "Not storing relationship to this transcript.", | |
| 1038 $dxref->dbname(), $dxref->display_id() ) ); | |
| 1039 $dxref->dbID(undef); | |
| 1040 $dxref->adaptor(undef); | |
| 1041 } | |
| 1042 } ## end if ( my $dxref = $transcript...) | |
| 1043 | |
| 1044 # | |
| 1045 # Link transcript to exons in exon_transcript table | |
| 1046 # | |
| 1047 my $etst = $self->prepare( | |
| 1048 "INSERT INTO exon_transcript (exon_id,transcript_id,rank) " | |
| 1049 . "VALUES (?,?,?)" ); | |
| 1050 my $rank = 1; | |
| 1051 foreach my $exon ( @{ $transcript->get_all_Exons } ) { | |
| 1052 $etst->bind_param( 1, $exon->dbID, SQL_INTEGER ); | |
| 1053 $etst->bind_param( 2, $transc_dbID, SQL_INTEGER ); | |
| 1054 $etst->bind_param( 3, $rank, SQL_INTEGER ); | |
| 1055 $etst->execute(); | |
| 1056 $rank++; | |
| 1057 } | |
| 1058 | |
| 1059 $etst->finish(); | |
| 1060 | |
| 1061 # Now the supporting evidence | |
| 1062 my $tsf_adaptor = $db->get_TranscriptSupportingFeatureAdaptor(); | |
| 1063 $tsf_adaptor->store( $transc_dbID, | |
| 1064 $transcript->get_all_supporting_features() ); | |
| 1065 | |
| 1066 # store transcript attributes if there are any | |
| 1067 my $attr_adaptor = $db->get_AttributeAdaptor(); | |
| 1068 | |
| 1069 $attr_adaptor->store_on_Transcript( $transc_dbID, | |
| 1070 $transcript->get_all_Attributes() ); | |
| 1071 | |
| 1072 # store the IntronSupportingEvidence features | |
| 1073 my $ise_adaptor = $db->get_IntronSupportingEvidenceAdaptor(); | |
| 1074 my $intron_supporting_evidence = $transcript->get_all_IntronSupportingEvidence(); | |
| 1075 foreach my $ise (@{$intron_supporting_evidence}) { | |
| 1076 $ise_adaptor->store($ise); | |
| 1077 $ise_adaptor->store_transcript_linkage($ise, $transcript, $transc_dbID); | |
| 1078 } | |
| 1079 | |
| 1080 # Update the original transcript object - not the transfered copy that | |
| 1081 # we might have created. | |
| 1082 $original->dbID($transc_dbID); | |
| 1083 $original->adaptor($self); | |
| 1084 | |
| 1085 return $transc_dbID; | |
| 1086 } ## end sub store | |
| 1087 | |
| 1088 | |
| 1089 =head2 get_Interpro_by_transid | |
| 1090 | |
| 1091 Arg [1] : String $trans_stable_id | |
| 1092 The stable if of the transcript to obtain | |
| 1093 Example : @i = $tr_adaptor->get_Interpro_by_transid($trans->stable_id()); | |
| 1094 Description: Gets interpro accession numbers by transcript stable id. | |
| 1095 A hack really - we should have a much more structured | |
| 1096 system than this. | |
| 1097 Returntype : listref of strings (Interpro_acc:description) | |
| 1098 Exceptions : none | |
| 1099 Caller : domainview? , GeneView | |
| 1100 Status : Stable | |
| 1101 | |
| 1102 =cut | |
| 1103 | |
| 1104 sub get_Interpro_by_transid { | |
| 1105 my ($self,$trans_stable_id) = @_; | |
| 1106 | |
| 1107 my $sth = $self->prepare(qq( | |
| 1108 SELECT STRAIGHT_JOIN i.interpro_ac, x.description | |
| 1109 FROM transcript t, | |
| 1110 translation tl, | |
| 1111 protein_feature pf, | |
| 1112 interpro i, | |
| 1113 xref x | |
| 1114 WHERE t.stable_id = ? | |
| 1115 AND tl.transcript_id = t.transcript_id | |
| 1116 AND tl.translation_id = pf.translation_id | |
| 1117 AND i.id = pf.hit_name | |
| 1118 AND i.interpro_ac = x.dbprimary_acc | |
| 1119 AND t.is_current = 1 | |
| 1120 )); | |
| 1121 | |
| 1122 $sth->bind_param(1, $trans_stable_id, SQL_VARCHAR); | |
| 1123 $sth->execute(); | |
| 1124 | |
| 1125 my @out; | |
| 1126 my %h; | |
| 1127 while( (my $arr = $sth->fetchrow_arrayref()) ) { | |
| 1128 if( $h{$arr->[0]} ) { next; } | |
| 1129 $h{$arr->[0]}=1; | |
| 1130 my $string = $arr->[0] .":".$arr->[1]; | |
| 1131 push(@out,$string); | |
| 1132 } | |
| 1133 | |
| 1134 return \@out; | |
| 1135 } | |
| 1136 | |
| 1137 =head2 is_Transcript_canonical() | |
| 1138 | |
| 1139 Arg [1] : Bio::EnsEMBL::Transcript $transcript | |
| 1140 The transcript to query with | |
| 1141 Example : $tr_adaptor->is_Transcript_canonical($transcript); | |
| 1142 Description : Returns a boolean if the given transcript is considered | |
| 1143 canonical with respect to a gene | |
| 1144 Returntype : Boolean | |
| 1145 Exceptions : None | |
| 1146 Caller : Bio::EnsEMBL::Transcript | |
| 1147 Status : Beta | |
| 1148 | |
| 1149 | |
| 1150 =cut | |
| 1151 | |
| 1152 sub is_Transcript_canonical { | |
| 1153 my ($self, $transcript) = @_; | |
| 1154 return $self->dbc()->sql_helper()->execute_single_result( | |
| 1155 -SQL => 'select count(*) from gene where canonical_transcript_id =?', | |
| 1156 -PARAMS => [$transcript->dbID()] | |
| 1157 ); | |
| 1158 } | |
| 1159 | |
| 1160 | |
| 1161 =head2 remove | |
| 1162 | |
| 1163 Arg [1] : Bio::EnsEMBL::Transcript $transcript | |
| 1164 The transcript to remove from the database | |
| 1165 Example : $tr_adaptor->remove($transcript); | |
| 1166 Description: Removes a transcript completely from the database, and all | |
| 1167 associated information. | |
| 1168 This method is usually called by the GeneAdaptor::remove method | |
| 1169 because this method will not preform the removal of genes | |
| 1170 which are associated with this transcript. Do not call this | |
| 1171 method directly unless you know there are no genes associated | |
| 1172 with the transcript! | |
| 1173 Returntype : none | |
| 1174 Exceptions : throw on incorrect arguments | |
| 1175 warning if transcript is not in this database | |
| 1176 Caller : GeneAdaptor::remove | |
| 1177 Status : Stable | |
| 1178 | |
| 1179 =cut | |
| 1180 | |
| 1181 sub remove { | |
| 1182 my $self = shift; | |
| 1183 my $transcript = shift; | |
| 1184 | |
| 1185 if(!ref($transcript) || !$transcript->isa('Bio::EnsEMBL::Transcript')) { | |
| 1186 throw("Bio::EnsEMBL::Transcript argument expected"); | |
| 1187 } | |
| 1188 | |
| 1189 # sanity check: make sure nobody tries to slip past a prediction transcript | |
| 1190 # which inherits from transcript but actually uses different tables | |
| 1191 if($transcript->isa('Bio::EnsEMBL::PredictionTranscript')) { | |
| 1192 throw("TranscriptAdaptor can only remove Transcripts " . | |
| 1193 "not PredictionTranscripts"); | |
| 1194 } | |
| 1195 | |
| 1196 if ( !$transcript->is_stored($self->db()) ) { | |
| 1197 warning("Cannot remove transcript ". $transcript->dbID .". Is not stored ". | |
| 1198 "in this database."); | |
| 1199 return; | |
| 1200 } | |
| 1201 | |
| 1202 # remove the supporting features of this transcript | |
| 1203 | |
| 1204 my $prot_adp = $self->db->get_ProteinAlignFeatureAdaptor; | |
| 1205 my $dna_adp = $self->db->get_DnaAlignFeatureAdaptor; | |
| 1206 | |
| 1207 my $sfsth = $self->prepare("SELECT feature_type, feature_id " . | |
| 1208 "FROM transcript_supporting_feature " . | |
| 1209 "WHERE transcript_id = ?"); | |
| 1210 | |
| 1211 $sfsth->bind_param(1, $transcript->dbID, SQL_INTEGER); | |
| 1212 $sfsth->execute(); | |
| 1213 | |
| 1214 # statements to check for shared align_features | |
| 1215 my $sth1 = $self->prepare("SELECT count(*) FROM supporting_feature " . | |
| 1216 "WHERE feature_type = ? AND feature_id = ?"); | |
| 1217 my $sth2 = $self->prepare("SELECT count(*) " . | |
| 1218 "FROM transcript_supporting_feature " . | |
| 1219 "WHERE feature_type = ? AND feature_id = ?"); | |
| 1220 | |
| 1221 SUPPORTING_FEATURE: | |
| 1222 while(my ($type, $feature_id) = $sfsth->fetchrow()){ | |
| 1223 | |
| 1224 # only remove align_feature if this is the last reference to it | |
| 1225 $sth1->bind_param(1, $type, SQL_VARCHAR); | |
| 1226 $sth1->bind_param(2, $feature_id, SQL_INTEGER); | |
| 1227 $sth1->execute; | |
| 1228 $sth2->bind_param(1, $type, SQL_VARCHAR); | |
| 1229 $sth2->bind_param(2, $feature_id, SQL_INTEGER); | |
| 1230 $sth2->execute; | |
| 1231 my ($count1) = $sth1->fetchrow; | |
| 1232 my ($count2) = $sth2->fetchrow; | |
| 1233 if ($count1 + $count2 > 1) { | |
| 1234 #warn "transcript: shared feature, not removing $type|$feature_id\n"; | |
| 1235 next SUPPORTING_FEATURE; | |
| 1236 } | |
| 1237 | |
| 1238 #warn "transcript: removing $type|$feature_id\n"; | |
| 1239 | |
| 1240 if($type eq 'protein_align_feature'){ | |
| 1241 my $f = $prot_adp->fetch_by_dbID($feature_id); | |
| 1242 $prot_adp->remove($f); | |
| 1243 } | |
| 1244 elsif($type eq 'dna_align_feature'){ | |
| 1245 my $f = $dna_adp->fetch_by_dbID($feature_id); | |
| 1246 $dna_adp->remove($f); | |
| 1247 } | |
| 1248 else { | |
| 1249 warning("Unknown supporting feature type $type. Not removing feature."); | |
| 1250 } | |
| 1251 } | |
| 1252 $sfsth->finish(); | |
| 1253 $sth1->finish(); | |
| 1254 $sth2->finish(); | |
| 1255 | |
| 1256 # delete the association to supporting features | |
| 1257 | |
| 1258 $sfsth = $self->prepare("DELETE FROM transcript_supporting_feature WHERE transcript_id = ?"); | |
| 1259 $sfsth->bind_param(1, $transcript->dbID, SQL_INTEGER); | |
| 1260 $sfsth->execute(); | |
| 1261 $sfsth->finish(); | |
| 1262 | |
| 1263 # delete the associated IntronSupportingEvidence and if the ISE had no more | |
| 1264 # linked transcripts remove it | |
| 1265 my $ise_adaptor = $self->db->get_IntronSupportingEvidenceAdaptor(); | |
| 1266 foreach my $ise (@{$transcript->get_all_IntronSupportingEvidence()}) { | |
| 1267 $ise_adaptor->remove_transcript_linkage($ise, $transcript); | |
| 1268 if(! $ise->has_linked_transcripts()) { | |
| 1269 $ise_adaptor->remove($ise); | |
| 1270 } | |
| 1271 } | |
| 1272 | |
| 1273 # remove all xref linkages to this transcript | |
| 1274 | |
| 1275 my $dbeAdaptor = $self->db->get_DBEntryAdaptor(); | |
| 1276 foreach my $dbe (@{$transcript->get_all_DBEntries}) { | |
| 1277 $dbeAdaptor->remove_from_object($dbe, $transcript, 'Transcript'); | |
| 1278 } | |
| 1279 | |
| 1280 # remove the attributes associated with this transcript | |
| 1281 my $attrib_adp = $self->db->get_AttributeAdaptor; | |
| 1282 $attrib_adp->remove_from_Transcript($transcript); | |
| 1283 | |
| 1284 # remove the translation associated with this transcript | |
| 1285 | |
| 1286 my $translationAdaptor = $self->db->get_TranslationAdaptor(); | |
| 1287 if( defined($transcript->translation()) ) { | |
| 1288 $translationAdaptor->remove( $transcript->translation ); | |
| 1289 } | |
| 1290 | |
| 1291 # remove exon associations to this transcript | |
| 1292 | |
| 1293 my $exonAdaptor = $self->db->get_ExonAdaptor(); | |
| 1294 foreach my $exon ( @{$transcript->get_all_Exons()} ) { | |
| 1295 # get the number of transcript references to this exon | |
| 1296 # only remove the exon if this is the last transcript to | |
| 1297 # reference it | |
| 1298 | |
| 1299 my $sth = $self->prepare( "SELECT count(*) | |
| 1300 FROM exon_transcript | |
| 1301 WHERE exon_id = ?" ); | |
| 1302 $sth->bind_param(1, $exon->dbID, SQL_INTEGER); | |
| 1303 $sth->execute(); | |
| 1304 my ($count) = $sth->fetchrow_array(); | |
| 1305 $sth->finish(); | |
| 1306 | |
| 1307 if($count == 1){ | |
| 1308 $exonAdaptor->remove( $exon ); | |
| 1309 } | |
| 1310 } | |
| 1311 | |
| 1312 my $sth = $self->prepare( "DELETE FROM exon_transcript | |
| 1313 WHERE transcript_id = ?" ); | |
| 1314 $sth->bind_param(1, $transcript->dbID, SQL_INTEGER); | |
| 1315 $sth->execute(); | |
| 1316 $sth->finish(); | |
| 1317 | |
| 1318 | |
| 1319 $sth = $self->prepare( "DELETE FROM transcript | |
| 1320 WHERE transcript_id = ?" ); | |
| 1321 $sth->bind_param(1, $transcript->dbID, SQL_INTEGER); | |
| 1322 $sth->execute(); | |
| 1323 $sth->finish(); | |
| 1324 | |
| 1325 $transcript->dbID(undef); | |
| 1326 $transcript->adaptor(undef); | |
| 1327 | |
| 1328 return; | |
| 1329 } | |
| 1330 | |
| 1331 | |
| 1332 =head2 update | |
| 1333 | |
| 1334 Arg [1] : Bio::EnsEMBL::Transcript $transcript | |
| 1335 The transcript to update | |
| 1336 Example : $tr_adaptor->update($transcript); | |
| 1337 Description: Updates a transcript in the database. | |
| 1338 Returntype : None | |
| 1339 Exceptions : thrown if the $transcript is not a Bio::EnsEMBL::Transcript. | |
| 1340 warn if the method is called on a transcript that does not exist | |
| 1341 in the database. | |
| 1342 Should warn if trying to update the number of attached exons, but | |
| 1343 this is a far more complex process and is not yet implemented. | |
| 1344 Caller : general | |
| 1345 Status : Stable | |
| 1346 | |
| 1347 =cut | |
| 1348 | |
| 1349 sub update { | |
| 1350 my ( $self, $transcript ) = @_; | |
| 1351 | |
| 1352 if ( !defined($transcript) | |
| 1353 || !ref($transcript) | |
| 1354 || !$transcript->isa('Bio::EnsEMBL::Transcript') ) | |
| 1355 { | |
| 1356 throw("Must update a transcript object, not a $transcript"); | |
| 1357 } | |
| 1358 | |
| 1359 my $update_transcript_sql = qq( | |
| 1360 UPDATE transcript | |
| 1361 SET analysis_id = ?, | |
| 1362 display_xref_id = ?, | |
| 1363 description = ?, | |
| 1364 biotype = ?, | |
| 1365 status = ?, | |
| 1366 is_current = ?, | |
| 1367 canonical_translation_id = ? | |
| 1368 WHERE transcript_id = ? | |
| 1369 ); | |
| 1370 | |
| 1371 my $display_xref = $transcript->display_xref(); | |
| 1372 my $display_xref_id; | |
| 1373 | |
| 1374 if ( defined($display_xref) && $display_xref->dbID() ) { | |
| 1375 $display_xref_id = $display_xref->dbID(); | |
| 1376 } else { | |
| 1377 $display_xref_id = undef; | |
| 1378 } | |
| 1379 | |
| 1380 my $sth = $self->prepare($update_transcript_sql); | |
| 1381 | |
| 1382 $sth->bind_param( 1, $transcript->analysis()->dbID(), SQL_INTEGER ); | |
| 1383 $sth->bind_param( 2, $display_xref_id, SQL_INTEGER ); | |
| 1384 $sth->bind_param( 3, $transcript->description(), SQL_LONGVARCHAR ); | |
| 1385 $sth->bind_param( 4, $transcript->biotype(), SQL_VARCHAR ); | |
| 1386 $sth->bind_param( 5, $transcript->status(), SQL_VARCHAR ); | |
| 1387 $sth->bind_param( 6, $transcript->is_current(), SQL_TINYINT ); | |
| 1388 $sth->bind_param( 7, ( | |
| 1389 defined( $transcript->translation() ) | |
| 1390 ? $transcript->translation()->dbID() | |
| 1391 : undef ), | |
| 1392 SQL_INTEGER ); | |
| 1393 $sth->bind_param( 8, $transcript->dbID(), SQL_INTEGER ); | |
| 1394 | |
| 1395 $sth->execute(); | |
| 1396 } ## end sub update | |
| 1397 | |
| 1398 | |
| 1399 =head2 list_dbIDs | |
| 1400 | |
| 1401 Example : @transcript_ids = @{ $t_adaptor->list_dbIDs }; | |
| 1402 Description: Gets a list of internal ids for all transcripts in the db. | |
| 1403 Arg[1] : <optional> int. not 0 for the ids to be sorted by the seq_region. Returntype : Listref of Ints | |
| 1404 Exceptions : none | |
| 1405 Caller : general | |
| 1406 Status : Stable | |
| 1407 | |
| 1408 =cut | |
| 1409 | |
| 1410 sub list_dbIDs { | |
| 1411 my ($self, $ordered) = @_; | |
| 1412 | |
| 1413 return $self->_list_dbIDs("transcript",undef, $ordered); | |
| 1414 } | |
| 1415 | |
| 1416 | |
| 1417 =head2 list_stable_ids | |
| 1418 | |
| 1419 Example : @stable_trans_ids = @{ $transcript_adaptor->list_stable_ids }; | |
| 1420 Description: Gets a list of stable ids for all transcripts in the current | |
| 1421 database. | |
| 1422 Returntype : Listref of Strings | |
| 1423 Exceptions : none | |
| 1424 Caller : general | |
| 1425 Status : Stable | |
| 1426 | |
| 1427 =cut | |
| 1428 | |
| 1429 sub list_stable_ids { | |
| 1430 my ($self) = @_; | |
| 1431 | |
| 1432 return $self->_list_dbIDs("transcript", "stable_id"); | |
| 1433 } | |
| 1434 | |
| 1435 | |
| 1436 #_objs_from_sth | |
| 1437 | |
| 1438 # Arg [1] : StatementHandle $sth | |
| 1439 # Arg [2] : Bio::EnsEMBL::AssemblyMapper $mapper | |
| 1440 # Arg [3] : Bio::EnsEMBL::Slice $dest_slice | |
| 1441 # Description: PROTECTED implementation of abstract superclass method. | |
| 1442 # Responsible for the creation of Transcripts. | |
| 1443 # Returntype : Listref of Bio::EnsEMBL::Transcripts in target coord system | |
| 1444 # Exceptions : none | |
| 1445 # Caller : internal | |
| 1446 # Status : Stable | |
| 1447 | |
| 1448 sub _objs_from_sth { | |
| 1449 my ($self, $sth, $mapper, $dest_slice) = @_; | |
| 1450 | |
| 1451 # | |
| 1452 # This code is ugly because an attempt has been made to remove as many | |
| 1453 # function calls as possible for speed purposes. Thus many caches and | |
| 1454 # a fair bit of gymnastics is used. | |
| 1455 # | |
| 1456 | |
| 1457 my $sa = $self->db()->get_SliceAdaptor(); | |
| 1458 my $aa = $self->db->get_AnalysisAdaptor(); | |
| 1459 my $dbEntryAdaptor = $self->db()->get_DBEntryAdaptor(); | |
| 1460 | |
| 1461 my @transcripts; | |
| 1462 my %analysis_hash; | |
| 1463 my %slice_hash; | |
| 1464 my %sr_name_hash; | |
| 1465 my %sr_cs_hash; | |
| 1466 | |
| 1467 my ( | |
| 1468 $transcript_id, $seq_region_id, $seq_region_start, | |
| 1469 $seq_region_end, $seq_region_strand, $analysis_id, | |
| 1470 $gene_id, $is_current, $stable_id, | |
| 1471 $version, $created_date, $modified_date, | |
| 1472 $description, $biotype, $status, | |
| 1473 $external_db, $external_status, $external_db_name, | |
| 1474 $xref_id, $xref_display_label, $xref_primary_acc, | |
| 1475 $xref_version, $xref_description, $xref_info_type, | |
| 1476 $xref_info_text | |
| 1477 ); | |
| 1478 | |
| 1479 $sth->bind_columns( | |
| 1480 \( | |
| 1481 $transcript_id, $seq_region_id, $seq_region_start, | |
| 1482 $seq_region_end, $seq_region_strand, $analysis_id, | |
| 1483 $gene_id, $is_current, $stable_id, | |
| 1484 $version, $created_date, $modified_date, | |
| 1485 $description, $biotype, $status, | |
| 1486 $external_db, $external_status, $external_db_name, | |
| 1487 $xref_id, $xref_display_label, $xref_primary_acc, | |
| 1488 $xref_version, $xref_description, $xref_info_type, | |
| 1489 $xref_info_text | |
| 1490 ) ); | |
| 1491 | |
| 1492 my $asm_cs; | |
| 1493 my $cmp_cs; | |
| 1494 my $asm_cs_vers; | |
| 1495 my $asm_cs_name; | |
| 1496 my $cmp_cs_vers; | |
| 1497 my $cmp_cs_name; | |
| 1498 if($mapper) { | |
| 1499 $asm_cs = $mapper->assembled_CoordSystem(); | |
| 1500 $cmp_cs = $mapper->component_CoordSystem(); | |
| 1501 $asm_cs_name = $asm_cs->name(); | |
| 1502 $asm_cs_vers = $asm_cs->version(); | |
| 1503 $cmp_cs_name = $cmp_cs->name(); | |
| 1504 $cmp_cs_vers = $cmp_cs->version(); | |
| 1505 } | |
| 1506 | |
| 1507 my $dest_slice_start; | |
| 1508 my $dest_slice_end; | |
| 1509 my $dest_slice_strand; | |
| 1510 my $dest_slice_length; | |
| 1511 my $dest_slice_cs; | |
| 1512 my $dest_slice_sr_name; | |
| 1513 my $dest_slice_sr_id; | |
| 1514 | |
| 1515 my $asma; | |
| 1516 if($dest_slice) { | |
| 1517 $dest_slice_start = $dest_slice->start(); | |
| 1518 $dest_slice_end = $dest_slice->end(); | |
| 1519 $dest_slice_strand = $dest_slice->strand(); | |
| 1520 $dest_slice_length = $dest_slice->length(); | |
| 1521 $dest_slice_cs = $dest_slice->coord_system(); | |
| 1522 $dest_slice_sr_name = $dest_slice->seq_region_name(); | |
| 1523 $dest_slice_sr_id = $dest_slice->get_seq_region_id(); | |
| 1524 $asma = $self->db->get_AssemblyMapperAdaptor(); | |
| 1525 } | |
| 1526 | |
| 1527 FEATURE: while($sth->fetch()) { | |
| 1528 | |
| 1529 #get the analysis object | |
| 1530 my $analysis = $analysis_hash{$analysis_id} ||= | |
| 1531 $aa->fetch_by_dbID($analysis_id); | |
| 1532 #need to get the internal_seq_region, if present | |
| 1533 $seq_region_id = $self->get_seq_region_id_internal($seq_region_id); | |
| 1534 my $slice = $slice_hash{"ID:".$seq_region_id}; | |
| 1535 my $dest_mapper = $mapper; | |
| 1536 | |
| 1537 if(!$slice) { | |
| 1538 $slice = $sa->fetch_by_seq_region_id($seq_region_id); | |
| 1539 $slice_hash{"ID:".$seq_region_id} = $slice; | |
| 1540 $sr_name_hash{$seq_region_id} = $slice->seq_region_name(); | |
| 1541 $sr_cs_hash{$seq_region_id} = $slice->coord_system(); | |
| 1542 } | |
| 1543 | |
| 1544 #obtain a mapper if none was defined, but a dest_seq_region was | |
| 1545 if(!$dest_mapper && $dest_slice && | |
| 1546 !$dest_slice_cs->equals($slice->coord_system)) { | |
| 1547 $dest_mapper = $asma->fetch_by_CoordSystems($dest_slice_cs, | |
| 1548 $slice->coord_system); | |
| 1549 $asm_cs = $dest_mapper->assembled_CoordSystem(); | |
| 1550 $cmp_cs = $dest_mapper->component_CoordSystem(); | |
| 1551 $asm_cs_name = $asm_cs->name(); | |
| 1552 $asm_cs_vers = $asm_cs->version(); | |
| 1553 $cmp_cs_name = $cmp_cs->name(); | |
| 1554 $cmp_cs_vers = $cmp_cs->version(); | |
| 1555 } | |
| 1556 | |
| 1557 my $sr_name = $sr_name_hash{$seq_region_id}; | |
| 1558 my $sr_cs = $sr_cs_hash{$seq_region_id}; | |
| 1559 # | |
| 1560 # remap the feature coordinates to another coord system | |
| 1561 # if a mapper was provided | |
| 1562 # | |
| 1563 if($dest_mapper) { | |
| 1564 | |
| 1565 if (defined $dest_slice && $dest_mapper->isa('Bio::EnsEMBL::ChainedAssemblyMapper') ) { | |
| 1566 ( $seq_region_id, $seq_region_start, | |
| 1567 $seq_region_end, $seq_region_strand ) | |
| 1568 = | |
| 1569 $dest_mapper->map( $sr_name, $seq_region_start, $seq_region_end, | |
| 1570 $seq_region_strand, $sr_cs, 1, $dest_slice); | |
| 1571 | |
| 1572 } else { | |
| 1573 | |
| 1574 ( $seq_region_id, $seq_region_start, | |
| 1575 $seq_region_end, $seq_region_strand ) | |
| 1576 = $dest_mapper->fastmap( $sr_name, $seq_region_start, | |
| 1577 $seq_region_end, $seq_region_strand, | |
| 1578 $sr_cs ); | |
| 1579 } | |
| 1580 | |
| 1581 #skip features that map to gaps or coord system boundaries | |
| 1582 next FEATURE if(!defined($seq_region_id)); | |
| 1583 | |
| 1584 #get a slice in the coord system we just mapped to | |
| 1585 if($asm_cs == $sr_cs || ($cmp_cs != $sr_cs && $asm_cs->equals($sr_cs))) { | |
| 1586 $slice = $slice_hash{"ID:".$seq_region_id} ||= | |
| 1587 $sa->fetch_by_seq_region_id($seq_region_id); | |
| 1588 } else { | |
| 1589 $slice = $slice_hash{"ID:".$seq_region_id} ||= | |
| 1590 $sa->fetch_by_seq_region_id($seq_region_id); | |
| 1591 } | |
| 1592 } | |
| 1593 | |
| 1594 # | |
| 1595 # If a destination slice was provided convert the coords. | |
| 1596 # | |
| 1597 if (defined($dest_slice)) { | |
| 1598 if ( $dest_slice_strand == 1 ) { | |
| 1599 $seq_region_start = $seq_region_start - $dest_slice_start + 1; | |
| 1600 $seq_region_end = $seq_region_end - $dest_slice_start + 1; | |
| 1601 | |
| 1602 if ( $dest_slice->is_circular ) { | |
| 1603 if ( $seq_region_start > $seq_region_end ) { | |
| 1604 # Looking at a feature overlapping the chromsome origin. | |
| 1605 if ( $seq_region_end > $dest_slice_start ) { | |
| 1606 # Looking at the region in the beginning of the chromosome | |
| 1607 $seq_region_start -= $dest_slice->seq_region_length(); | |
| 1608 } | |
| 1609 if ( $seq_region_end < 0 ) { | |
| 1610 $seq_region_end += $dest_slice->seq_region_length(); | |
| 1611 } | |
| 1612 } else { | |
| 1613 if ( $dest_slice_start > $dest_slice_end | |
| 1614 && $seq_region_end < 0 ) | |
| 1615 { | |
| 1616 # Looking at the region overlapping the chromosome | |
| 1617 # origin and a feature which is at the beginning of the | |
| 1618 # chromosome. | |
| 1619 $seq_region_start += $dest_slice->seq_region_length(); | |
| 1620 $seq_region_end += $dest_slice->seq_region_length(); | |
| 1621 } | |
| 1622 } | |
| 1623 } | |
| 1624 } else { | |
| 1625 if ( $dest_slice->is_circular() | |
| 1626 && $seq_region_start > $seq_region_end ) | |
| 1627 { | |
| 1628 if ( $seq_region_end > $dest_slice_start ) { | |
| 1629 # Looking at the region in the beginning of the chromosome. | |
| 1630 $seq_region_start = $dest_slice_end - $seq_region_end + 1; | |
| 1631 $seq_region_end = | |
| 1632 $seq_region_end - | |
| 1633 $dest_slice->seq_region_length() - | |
| 1634 $dest_slice_start + 1; | |
| 1635 } else { | |
| 1636 my $tmp_seq_region_start = $seq_region_start; | |
| 1637 $seq_region_start = | |
| 1638 $dest_slice_end - | |
| 1639 $seq_region_end - | |
| 1640 $dest_slice->seq_region_length() + 1; | |
| 1641 $seq_region_end = | |
| 1642 $dest_slice_end - $tmp_seq_region_start + 1; | |
| 1643 } | |
| 1644 | |
| 1645 } else { | |
| 1646 my $tmp_seq_region_start = $seq_region_start; | |
| 1647 $seq_region_start = $dest_slice_end - $seq_region_end + 1; | |
| 1648 $seq_region_end = $dest_slice_end - $tmp_seq_region_start + 1; | |
| 1649 } | |
| 1650 | |
| 1651 $seq_region_strand = -$seq_region_strand; | |
| 1652 } ## end else [ if ( $dest_slice_strand...)] | |
| 1653 | |
| 1654 # Throw away features off the end of the requested slice | |
| 1655 if ( $seq_region_end < 1 | |
| 1656 || $seq_region_start > $dest_slice_length | |
| 1657 || ( $dest_slice_sr_id ne $seq_region_id ) ) | |
| 1658 { | |
| 1659 next FEATURE; | |
| 1660 } | |
| 1661 | |
| 1662 $slice = $dest_slice; | |
| 1663 } | |
| 1664 | |
| 1665 my $display_xref; | |
| 1666 | |
| 1667 if ($xref_id) { | |
| 1668 $display_xref = Bio::EnsEMBL::DBEntry->new_fast( { | |
| 1669 'dbID' => $xref_id, | |
| 1670 'display_id' => $xref_display_label, | |
| 1671 'primary_id' => $xref_primary_acc, | |
| 1672 'version' => $xref_version, | |
| 1673 'description' => $xref_description, | |
| 1674 'info_type' => $xref_info_type, | |
| 1675 'info_text' => $xref_info_text, | |
| 1676 'adaptor' => $dbEntryAdaptor, | |
| 1677 'db_display_name' => $external_db_name, | |
| 1678 'dbname' => $external_db | |
| 1679 } ); | |
| 1680 } | |
| 1681 | |
| 1682 | |
| 1683 # Finally, create the new Transcript. | |
| 1684 push( | |
| 1685 @transcripts, | |
| 1686 $self->_create_feature_fast( | |
| 1687 'Bio::EnsEMBL::Transcript', | |
| 1688 { | |
| 1689 'analysis' => $analysis, | |
| 1690 'start' => $seq_region_start, | |
| 1691 'end' => $seq_region_end, | |
| 1692 'strand' => $seq_region_strand, | |
| 1693 'adaptor' => $self, | |
| 1694 'slice' => $slice, | |
| 1695 'dbID' => $transcript_id, | |
| 1696 'stable_id' => $stable_id, | |
| 1697 'version' => $version, | |
| 1698 'created_date' => $created_date || undef, | |
| 1699 'modified_date' => $modified_date || undef, | |
| 1700 'external_name' => $xref_display_label, | |
| 1701 'external_db' => $external_db, | |
| 1702 'external_status' => $external_status, | |
| 1703 'external_display_name' => $external_db_name, | |
| 1704 'display_xref' => $display_xref, | |
| 1705 'description' => $description, | |
| 1706 'biotype' => $biotype, | |
| 1707 'status' => $status, | |
| 1708 'is_current' => $is_current, | |
| 1709 'edits_enabled' => 1 | |
| 1710 } ) ); | |
| 1711 | |
| 1712 } | |
| 1713 | |
| 1714 return \@transcripts; | |
| 1715 } | |
| 1716 | |
| 1717 | |
| 1718 =head2 fetch_all_by_exon_supporting_evidence | |
| 1719 | |
| 1720 Arg [1] : String $hit_name | |
| 1721 Name of supporting feature | |
| 1722 Arg [2] : String $feature_type | |
| 1723 one of "dna_align_feature" or "protein_align_feature" | |
| 1724 Arg [3] : (optional) Bio::Ensembl::Analysis | |
| 1725 Example : $tr = $tr_adaptor->fetch_all_by_exon_supporting_evidence | |
| 1726 ('XYZ', 'dna_align_feature'); | |
| 1727 Description: Gets all the transcripts with exons which have a specified hit | |
| 1728 on a particular type of feature. Optionally filter by analysis. | |
| 1729 Returntype : Listref of Bio::EnsEMBL::Transcript objects | |
| 1730 Exceptions : If feature_type is not of correct type. | |
| 1731 Caller : general | |
| 1732 Status : Stable | |
| 1733 | |
| 1734 =cut | |
| 1735 | |
| 1736 sub fetch_all_by_exon_supporting_evidence { | |
| 1737 my ($self, $hit_name, $feature_type, $analysis) = @_; | |
| 1738 | |
| 1739 if($feature_type !~ /(dna)|(protein)_align_feature/) { | |
| 1740 throw("feature type must be dna_align_feature or protein_align_feature"); | |
| 1741 } | |
| 1742 | |
| 1743 my $anal_from = ""; | |
| 1744 $anal_from = ", analysis a " if ($analysis); | |
| 1745 my $anal_where = ""; | |
| 1746 $anal_where = "AND a.analysis_id = f.analysis_id AND a.analysis_id=? " | |
| 1747 if ($analysis); | |
| 1748 | |
| 1749 my $sql = qq( | |
| 1750 SELECT DISTINCT(t.transcript_id) | |
| 1751 FROM transcript t, | |
| 1752 exon_transcript et, | |
| 1753 supporting_feature sf, | |
| 1754 $feature_type f | |
| 1755 $anal_from | |
| 1756 WHERE t.transcript_id = et.transcript_id | |
| 1757 AND t.is_current = 1 | |
| 1758 AND et.exon_id = sf.exon_id | |
| 1759 AND sf.feature_id = f.${feature_type}_id | |
| 1760 AND sf.feature_type = ? | |
| 1761 AND f.hit_name=? | |
| 1762 $anal_where | |
| 1763 ); | |
| 1764 | |
| 1765 my $sth = $self->prepare($sql); | |
| 1766 | |
| 1767 $sth->bind_param(1, $feature_type, SQL_VARCHAR); | |
| 1768 $sth->bind_param(2, $hit_name, SQL_VARCHAR); | |
| 1769 $sth->bind_param(3, $analysis->dbID(), SQL_INTEGER) if ($analysis); | |
| 1770 | |
| 1771 $sth->execute(); | |
| 1772 | |
| 1773 my @transcripts; | |
| 1774 | |
| 1775 while( my $id = $sth->fetchrow_array ) { | |
| 1776 my $transcript = $self->fetch_by_dbID( $id ); | |
| 1777 push(@transcripts, $transcript) if $transcript; | |
| 1778 } | |
| 1779 | |
| 1780 return \@transcripts; | |
| 1781 } | |
| 1782 | |
| 1783 | |
| 1784 =head2 fetch_all_by_transcript_supporting_evidence | |
| 1785 | |
| 1786 Arg [1] : String $hit_name | |
| 1787 Name of supporting feature | |
| 1788 Arg [2] : String $feature_type | |
| 1789 one of "dna_align_feature" or "protein_align_feature" | |
| 1790 Arg [3] : (optional) Bio::Ensembl::Analysis | |
| 1791 Example : $transcripts = $transcript_adaptor->fetch_all_by_transcript_supporting_evidence('XYZ', 'dna_align_feature'); | |
| 1792 Description: Gets all the transcripts with evidence from a specified hit_name on a particular type of feature, stored in the | |
| 1793 transcript_supporting_feature table. Optionally filter by analysis. For hits stored in the supporting_feature | |
| 1794 table (linked to exons) use fetch_all_by_exon_supporting_evidence instead. | |
| 1795 Returntype : Listref of Bio::EnsEMBL::Transcript objects | |
| 1796 Exceptions : If feature_type is not of correct type. | |
| 1797 Caller : general | |
| 1798 Status : Stable | |
| 1799 | |
| 1800 =cut | |
| 1801 | |
| 1802 sub fetch_all_by_transcript_supporting_evidence { | |
| 1803 | |
| 1804 my ($self, $hit_name, $feature_type, $analysis) = @_; | |
| 1805 | |
| 1806 if($feature_type !~ /(dna)|(protein)_align_feature/) { | |
| 1807 throw("feature type must be dna_align_feature or protein_align_feature"); | |
| 1808 } | |
| 1809 | |
| 1810 my $anal_from = ""; | |
| 1811 $anal_from = ", analysis a " if ($analysis); | |
| 1812 my $anal_where = ""; | |
| 1813 $anal_where = "AND a.analysis_id = f.analysis_id AND a.analysis_id=? " | |
| 1814 if ($analysis); | |
| 1815 | |
| 1816 my $sql = qq( | |
| 1817 SELECT DISTINCT(t.transcript_id) | |
| 1818 FROM transcript t, | |
| 1819 transcript_supporting_feature sf, | |
| 1820 $feature_type f | |
| 1821 $anal_from | |
| 1822 WHERE t.transcript_id = sf.transcript_id | |
| 1823 AND t.is_current = 1 | |
| 1824 AND sf.feature_id = f.${feature_type}_id | |
| 1825 AND sf.feature_type = ? | |
| 1826 AND f.hit_name=? | |
| 1827 $anal_where | |
| 1828 ); | |
| 1829 | |
| 1830 my $sth = $self->prepare($sql); | |
| 1831 | |
| 1832 $sth->bind_param(1, $feature_type, SQL_VARCHAR); | |
| 1833 $sth->bind_param(2, $hit_name, SQL_VARCHAR); | |
| 1834 $sth->bind_param(3, $analysis->dbID(), SQL_INTEGER) if ($analysis); | |
| 1835 | |
| 1836 $sth->execute(); | |
| 1837 | |
| 1838 my @transcripts; | |
| 1839 | |
| 1840 while( my $id = $sth->fetchrow_array ) { | |
| 1841 my $transcript = $self->fetch_by_dbID( $id ); | |
| 1842 push(@transcripts, $transcript) if $transcript; | |
| 1843 } | |
| 1844 | |
| 1845 return \@transcripts; | |
| 1846 } | |
| 1847 | |
| 1848 | |
| 1849 ########################## | |
| 1850 # # | |
| 1851 # DEPRECATED METHODS # | |
| 1852 # # | |
| 1853 ########################## | |
| 1854 | |
| 1855 | |
| 1856 =head2 get_display_xref | |
| 1857 | |
| 1858 Description: DEPRECATED. Use $transcript->display_xref() instead. | |
| 1859 | |
| 1860 =cut | |
| 1861 | |
| 1862 sub get_display_xref { | |
| 1863 my ($self, $transcript) = @_; | |
| 1864 | |
| 1865 deprecate("display_xref should be retreived from Transcript object directly."); | |
| 1866 | |
| 1867 if ( !defined $transcript ) { | |
| 1868 throw("Must call with a Transcript object"); | |
| 1869 } | |
| 1870 | |
| 1871 my $sth = $self->prepare(qq( | |
| 1872 SELECT e.db_name, | |
| 1873 x.display_label, | |
| 1874 e.db_external_name, | |
| 1875 x.xref_id | |
| 1876 FROM transcript t, | |
| 1877 xref x, | |
| 1878 external_db e | |
| 1879 WHERE t.transcript_id = ? | |
| 1880 AND t.display_xref_id = x.xref_id | |
| 1881 AND x.external_db_id = e.external_db_id | |
| 1882 )); | |
| 1883 | |
| 1884 $sth->bind_param(1, $transcript->dbID, SQL_INTEGER); | |
| 1885 $sth->execute(); | |
| 1886 | |
| 1887 my ($db_name, $display_label, $xref_id, $display_db_name ) = | |
| 1888 $sth->fetchrow_array(); | |
| 1889 | |
| 1890 if ( !defined $xref_id ) { | |
| 1891 return undef; | |
| 1892 } | |
| 1893 | |
| 1894 my $db_entry = Bio::EnsEMBL::DBEntry->new( | |
| 1895 -dbid => $xref_id, | |
| 1896 -adaptor => $self->db->get_DBEntryAdaptor(), | |
| 1897 -dbname => $db_name, | |
| 1898 -display_id => $display_label | |
| 1899 -db_display_name => $display_db_name | |
| 1900 ); | |
| 1901 | |
| 1902 return $db_entry; | |
| 1903 } | |
| 1904 | |
| 1905 | |
| 1906 =head2 get_stable_entry_info | |
| 1907 | |
| 1908 Description: DEPRECATED. Use $transcript->stable_id() instead. | |
| 1909 | |
| 1910 =cut | |
| 1911 | |
| 1912 sub get_stable_entry_info { | |
| 1913 my ($self, $transcript) = @_; | |
| 1914 | |
| 1915 deprecate("Stable ids should be loaded directly now"); | |
| 1916 | |
| 1917 unless ( defined $transcript && ref $transcript && | |
| 1918 $transcript->isa('Bio::EnsEMBL::Transcript') ) { | |
| 1919 throw("Needs a Transcript object, not a $transcript"); | |
| 1920 } | |
| 1921 | |
| 1922 my $sth = $self->prepare(qq( | |
| 1923 SELECT stable_id, version | |
| 1924 FROM transcript | |
| 1925 WHERE transcript_id = ? | |
| 1926 )); | |
| 1927 | |
| 1928 $sth->bind_param(1, $transcript->dbID, SQL_INTEGER); | |
| 1929 $sth->execute(); | |
| 1930 | |
| 1931 my @array = $sth->fetchrow_array(); | |
| 1932 $transcript->{'_stable_id'} = $array[0]; | |
| 1933 $transcript->{'_version'} = $array[1]; | |
| 1934 | |
| 1935 return 1; | |
| 1936 } | |
| 1937 | |
| 1938 | |
| 1939 =head2 fetch_all_by_DBEntry | |
| 1940 | |
| 1941 Description: DEPRECATED. Use fetch_all_by_external_name() instead. | |
| 1942 | |
| 1943 =cut | |
| 1944 | |
| 1945 sub fetch_all_by_DBEntry { | |
| 1946 my $self = shift; | |
| 1947 deprecate('Use fetch_all_by_external_name instead.'); | |
| 1948 return $self->fetch_all_by_external_name(@_); | |
| 1949 } | |
| 1950 | |
| 1951 | |
| 1952 1; |
