0
|
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::SlicingEventAdaptor - Database adaptor for the retrieval and
|
|
24 storage of SplicingEvent objects
|
|
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 $se_adaptor =
|
|
36 Bio::EnsEMBL::Registry->get_adaptor( "human", "core", "SplicingEvent" );
|
|
37
|
|
38 $se = $se_adaptor->fetch_by_dbID(12);
|
|
39
|
|
40 $slice_adaptor =
|
|
41 Bio::EnsEMBL::Registry->get_adaptor( "human", "core", "slice" );
|
|
42
|
|
43 $slice =
|
|
44 $slice_adaptor->fetch_by_region( 'chromosome', '1', 1, 1000000 );
|
|
45
|
|
46 @ase = @{ $se_adaptor->fetch_all_by_Slice($slice) };
|
|
47
|
|
48 =head1 DESCRIPTION
|
|
49
|
|
50 This is a database aware adaptor for the retrieval and storage ofSlicingEvents
|
|
51 objects.
|
|
52
|
|
53 =head1 METHODS
|
|
54
|
|
55 =cut
|
|
56 package Bio::EnsEMBL::DBSQL::SplicingEventAdaptor;
|
|
57
|
|
58 use strict;
|
|
59
|
|
60 use Bio::EnsEMBL::Utils::Exception qw( deprecate throw warning );
|
|
61 use Bio::EnsEMBL::DBSQL::SliceAdaptor;
|
|
62 use Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor;
|
|
63 use Bio::EnsEMBL::DBSQL::DBAdaptor;
|
|
64 use Bio::EnsEMBL::SplicingEvent;
|
|
65
|
|
66 use vars '@ISA';
|
|
67 @ISA = qw(Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor);
|
|
68
|
|
69
|
|
70 =head2 list_dbIDs
|
|
71
|
|
72 Example : @gene_ids = @{$gene_adaptor->list_dbIDs()};
|
|
73 Description: Gets an array of internal ids for all genes in the current db
|
|
74 Arg[1] : <optional> int. not 0 for the ids to be sorted by the seq_region.
|
|
75 Returntype : Listref of Ints
|
|
76 Exceptions : none
|
|
77 Caller : general
|
|
78 Status : Stable
|
|
79
|
|
80 =cut
|
|
81
|
|
82 sub list_dbIDs {
|
|
83 my ($self,$ordered) = @_;
|
|
84
|
|
85 return $self->_list_dbIDs("splicing_event", undef, $ordered);
|
|
86 }
|
|
87
|
|
88
|
|
89 =head2 fetch_all_by_Slice
|
|
90
|
|
91 Arg [1] : Bio::EnsEMBL::Slice $slice
|
|
92 The slice to fetch genes on.
|
|
93 Arg [2] : type of Transcript event
|
|
94 Arg [3] : (optional) boolean $load_features
|
|
95 If true, transcript will be loaded immediately rather
|
|
96 than lazy loaded later.
|
|
97 =cut
|
|
98
|
|
99 sub fetch_all_by_Slice {
|
|
100 my ( $self, $slice, $type, $load_features ) = @_;
|
|
101
|
|
102 my $constraint = '';
|
|
103
|
|
104 if ( defined($type) ) {
|
|
105 $constraint .= sprintf( " AND at.code = %s",
|
|
106 $self->dbc()->db_handle()->quote($type) );
|
|
107 }
|
|
108
|
|
109 my $tes =
|
|
110 $self->SUPER::fetch_all_by_Slice_constraint( $slice, $constraint );
|
|
111
|
|
112 # Is there any use in having a splice event without the pairs and
|
|
113 # features??
|
|
114
|
|
115 if ( !$load_features || scalar( @{$tes} ) < 2 ) {
|
|
116 return $tes;
|
|
117 }
|
|
118
|
|
119 # Load pairs and features.
|
|
120 foreach my $te ( @{$tes} ) {
|
|
121 $te->get_all_Features();
|
|
122 $te->get_all_Pairs();
|
|
123 }
|
|
124
|
|
125 return $tes;
|
|
126 } ## end sub fetch_all_by_Slice
|
|
127
|
|
128
|
|
129 sub fetch_all_by_Gene {
|
|
130 my ( $self, $gene ) = @_;
|
|
131
|
|
132 my $sth = $self->dbc->prepare(
|
|
133 q(
|
|
134 SELECT se.splicing_event_id,
|
|
135 se.seq_region_id,
|
|
136 se.seq_region_start,
|
|
137 se.seq_region_end,
|
|
138 se.seq_region_strand,
|
|
139 se.name,
|
|
140 at.code
|
|
141 FROM splicing_event se
|
|
142 JOIN attrib_type at USING (attrib_type_id)
|
|
143 WHERE se.gene_id =) . $gene->dbID() );
|
|
144
|
|
145 $sth->execute();
|
|
146
|
|
147 my ( $splicing_event_id, $seq_region_id, $seq_region_start,
|
|
148 $seq_region_end, $seq_region_strand, $name, $type );
|
|
149
|
|
150 $sth->bind_columns(
|
|
151 \( $splicing_event_id, $seq_region_id, $seq_region_start,
|
|
152 $seq_region_end, $seq_region_strand, $name,
|
|
153 $type ) );
|
|
154
|
|
155 my @splicing_events;
|
|
156
|
|
157 my $sa = $self->db()->get_SliceAdaptor();
|
|
158
|
|
159 while ( $sth->fetch() ) {
|
|
160 my $slice =
|
|
161 $sa->fetch_by_seq_region_id( $seq_region_id,
|
|
162 $seq_region_start,
|
|
163 $seq_region_end,
|
|
164 $seq_region_strand );
|
|
165
|
|
166 push( @splicing_events,
|
|
167 $self->_create_feature_fast( 'Bio::EnsEMBL::SplicingEvent', {
|
|
168 'start' => $seq_region_start,
|
|
169 'end' => $seq_region_end,
|
|
170 'strand' => $seq_region_strand,
|
|
171 'adaptor' => $self,
|
|
172 'slice' => $slice,
|
|
173 'dbID' => $splicing_event_id,
|
|
174 'name' => $name,
|
|
175 'gene_id' => $gene->dbID(),
|
|
176 'type' => $type } ) );
|
|
177 }
|
|
178
|
|
179 foreach my $te (@splicing_events) {
|
|
180 $te->get_all_Features();
|
|
181 $te->get_all_Pairs();
|
|
182 }
|
|
183
|
|
184 return \@splicing_events;
|
|
185 } ## end sub fetch_all_by_Gene
|
|
186
|
|
187 sub fetch_all_by_Exon {
|
|
188 my ( $self, $exon ) = @_;
|
|
189
|
|
190 my $sth = $self->dbc()->prepare(
|
|
191 q(
|
|
192 SELECT DISTINCT splicing_event_id
|
|
193 FROM splicing_event_feature
|
|
194 WHERE exon_id =) . $exon->dbID() );
|
|
195
|
|
196 $sth->execute();
|
|
197
|
|
198 my $se_id;
|
|
199 $sth->bind_col( 1, \$se_id );
|
|
200
|
|
201 my @list;
|
|
202 while ( $sth->fetch() ) {
|
|
203 push( @list, $se_id );
|
|
204 }
|
|
205
|
|
206 $sth = $self->dbc->prepare(
|
|
207 q(
|
|
208 SELECT se.splicing_event_id,
|
|
209 se.seq_region_id,
|
|
210 se.seq_region_start,
|
|
211 se.seq_region_end,
|
|
212 se.seq_region_strand,
|
|
213 se.name,
|
|
214 at.code,
|
|
215 se.gene_id
|
|
216 FROM splicing_event se
|
|
217 JOIN attrib_type at USING (attrib_type_id)
|
|
218 WHERE se.splicing_event_id in ) . '(' . join( ',', @list ) . ')' );
|
|
219
|
|
220 $sth->execute();
|
|
221
|
|
222 my ( $splicing_event_id, $seq_region_id, $seq_region_start,
|
|
223 $seq_region_end, $seq_region_strand, $name, $type, $gene_id );
|
|
224
|
|
225 $sth->bind_columns(
|
|
226 \( $splicing_event_id, $seq_region_id, $seq_region_start,
|
|
227 $seq_region_end, $seq_region_strand, $name,
|
|
228 $type, $gene_id ) );
|
|
229
|
|
230 my @splicing_events;
|
|
231
|
|
232 my $sa = $self->db->get_SliceAdaptor();
|
|
233
|
|
234 while ( $sth->fetch ) {
|
|
235 my $slice =
|
|
236 $sa->fetch_by_seq_region_id( $seq_region_id,
|
|
237 $seq_region_start,
|
|
238 $seq_region_end,
|
|
239 $seq_region_strand );
|
|
240
|
|
241 push( @splicing_events,
|
|
242 $self->_create_feature_fast( 'Bio::EnsEMBL::SplicingEvent', {
|
|
243 'start' => $seq_region_start,
|
|
244 'end' => $seq_region_end,
|
|
245 'strand' => $seq_region_strand,
|
|
246 'adaptor' => $self,
|
|
247 'slice' => $slice,
|
|
248 'dbID' => $splicing_event_id,
|
|
249 'name' => $name,
|
|
250 'gene_id' => $gene_id,
|
|
251 'type' => $type } ) );
|
|
252 }
|
|
253
|
|
254 foreach my $te (@splicing_events) {
|
|
255 $te->get_all_Features();
|
|
256 $te->get_all_Pairs();
|
|
257 }
|
|
258
|
|
259 return \@splicing_events;
|
|
260 } ## end sub fetch_all_by_Exon
|
|
261
|
|
262 sub fetch_all_by_Transcript {
|
|
263 my ( $self, $transcript ) = @_;
|
|
264
|
|
265 my $sth = $self->dbc->prepare(
|
|
266 q(
|
|
267 SELECT DISTINCT splicing_event_id
|
|
268 FROM splicing_event_feature
|
|
269 WHERE transcript_id =) . $transcript->dbID() );
|
|
270
|
|
271 $sth->execute();
|
|
272
|
|
273 my $se_id;
|
|
274 $sth->bind_col( 1, \$se_id );
|
|
275
|
|
276 my @list;
|
|
277 while ( $sth->fetch() ) {
|
|
278 push( @list, $se_id );
|
|
279 }
|
|
280
|
|
281 $sth = $self->dbc->prepare(
|
|
282 q(
|
|
283 SELECT se.splicing_event_id,
|
|
284 se.seq_region_id,
|
|
285 se.seq_region_start,
|
|
286 se.seq_region_end,
|
|
287 se.seq_region_strand,
|
|
288 se.name,
|
|
289 at.code,
|
|
290 se.gene_id
|
|
291 FROM splicing_event se
|
|
292 JOIN attrib_type at USING (attrib_type_id)
|
|
293 WHERE se.splicing_event_id in ) . '(' . join( ',', @list ) . ')' );
|
|
294
|
|
295 $sth->execute();
|
|
296
|
|
297 my ( $splicing_event_id, $seq_region_id, $seq_region_start,
|
|
298 $seq_region_end, $seq_region_strand, $name, $type, $gene_id );
|
|
299
|
|
300 $sth->bind_columns(
|
|
301 \( $splicing_event_id, $seq_region_id, $seq_region_start,
|
|
302 $seq_region_end, $seq_region_strand, $name,
|
|
303 $type, $gene_id ) );
|
|
304
|
|
305 my @splicing_events;
|
|
306
|
|
307 my $sa = $self->db()->get_SliceAdaptor();
|
|
308
|
|
309 while ( $sth->fetch() ) {
|
|
310 my $slice =
|
|
311 $sa->fetch_by_seq_region_id( $seq_region_id,
|
|
312 $seq_region_start,
|
|
313 $seq_region_end,
|
|
314 $seq_region_strand );
|
|
315
|
|
316 push( @splicing_events,
|
|
317 $self->_create_feature_fast( 'Bio::EnsEMBL::SplicingEvent', {
|
|
318 'start' => $seq_region_start,
|
|
319 'end' => $seq_region_end,
|
|
320 'strand' => $seq_region_strand,
|
|
321 'adaptor' => $self,
|
|
322 'slice' => $slice,
|
|
323 'dbID' => $splicing_event_id,
|
|
324 'name' => $name,
|
|
325 'gene_id' => $gene_id,
|
|
326 'type' => $type } ) );
|
|
327 }
|
|
328
|
|
329 foreach my $te (@splicing_events) {
|
|
330 $te->get_all_Features();
|
|
331 $te->get_all_Pairs();
|
|
332 }
|
|
333
|
|
334 return \@splicing_events;
|
|
335 } ## end sub fetch_all_by_Transcript
|
|
336
|
|
337 # _tables
|
|
338 # Arg [1] : none
|
|
339 # Description: PROTECTED implementation of superclass abstract method.
|
|
340 # Returns the names, aliases of the tables to use for queries.
|
|
341 # Returntype : list of listrefs of strings
|
|
342 # Exceptions : none
|
|
343 # Caller : internal
|
|
344 # Status : At Risk
|
|
345
|
|
346 sub _tables {
|
|
347 return ( [ 'splicing_event', 'se' ], [ 'attrib_type', 'at' ] );
|
|
348 }
|
|
349
|
|
350 # _columns
|
|
351 # Arg [1] : none
|
|
352 # Example : none
|
|
353 # Description: PROTECTED implementation of superclass abstract method.
|
|
354 # Returns a list of columns to use for queries.
|
|
355 # Returntype : list of strings
|
|
356 # Exceptions : none
|
|
357 # Caller : internal
|
|
358 # Status : At Risk
|
|
359
|
|
360 sub _columns {
|
|
361 return ( 'se.splicing_event_id', 'se.seq_region_id',
|
|
362 'se.seq_region_start', 'se.seq_region_end',
|
|
363 'se.seq_region_strand', 'se.name',
|
|
364 'se.gene_id', 'at.code' );
|
|
365 }
|
|
366
|
|
367 sub _left_join {
|
|
368 return ( [ 'attrib_type', 'at.attrib_type_id = se.attrib_type_id' ] );
|
|
369 }
|
|
370
|
|
371 sub _objs_from_sth {
|
|
372 my ( $self, $sth, $mapper, $dest_slice ) = @_;
|
|
373
|
|
374 my ( $splicing_event_id, $seq_region_id, $seq_region_start,
|
|
375 $seq_region_end, $seq_region_strand, $name, $gene_id, $type );
|
|
376
|
|
377 $sth->bind_columns(
|
|
378 \( $splicing_event_id, $seq_region_id, $seq_region_start,
|
|
379 $seq_region_end, $seq_region_strand, $name,
|
|
380 $gene_id, $type ) );
|
|
381
|
|
382 my $sa = $self->db()->get_SliceAdaptor();
|
|
383
|
|
384 my @splicing_events;
|
|
385 my %slice_hash;
|
|
386 my %sr_name_hash;
|
|
387 my %sr_cs_hash;
|
|
388
|
|
389 my $asm_cs;
|
|
390 my $cmp_cs;
|
|
391 my $asm_cs_vers;
|
|
392 my $asm_cs_name;
|
|
393 my $cmp_cs_vers;
|
|
394 my $cmp_cs_name;
|
|
395
|
|
396 if ( defined($mapper) ) {
|
|
397 $asm_cs = $mapper->assembled_CoordSystem();
|
|
398 $cmp_cs = $mapper->component_CoordSystem();
|
|
399 $asm_cs_name = $asm_cs->name();
|
|
400 $asm_cs_vers = $asm_cs->version();
|
|
401 $cmp_cs_name = $cmp_cs->name();
|
|
402 $cmp_cs_vers = $cmp_cs->version();
|
|
403 }
|
|
404
|
|
405 my $dest_slice_start;
|
|
406 my $dest_slice_end;
|
|
407 my $dest_slice_strand;
|
|
408 my $dest_slice_length;
|
|
409 my $dest_slice_cs;
|
|
410 my $dest_slice_sr_name;
|
|
411 my $dest_slice_sr_id;
|
|
412 my $asma;
|
|
413
|
|
414 if ( defined($dest_slice) ) {
|
|
415 $dest_slice_start = $dest_slice->start();
|
|
416 $dest_slice_end = $dest_slice->end();
|
|
417 $dest_slice_strand = $dest_slice->strand();
|
|
418 $dest_slice_length = $dest_slice->length();
|
|
419 $dest_slice_cs = $dest_slice->coord_system();
|
|
420 $dest_slice_sr_name = $dest_slice->seq_region_name();
|
|
421 $dest_slice_sr_id = $dest_slice->get_seq_region_id();
|
|
422 $asma = $self->db->get_AssemblyMapperAdaptor();
|
|
423 }
|
|
424
|
|
425 FEATURE:
|
|
426 while ( $sth->fetch() ) {
|
|
427 # Need to get the internal_seq_region, if present.
|
|
428 $seq_region_id = $self->get_seq_region_id_internal($seq_region_id);
|
|
429
|
|
430 my $slice = $slice_hash{ "ID:" . $seq_region_id };
|
|
431 my $dest_mapper = $mapper;
|
|
432
|
|
433 if ( !$slice ) {
|
|
434 $slice = $sa->fetch_by_seq_region_id($seq_region_id);
|
|
435 $slice_hash{ "ID:" . $seq_region_id } = $slice;
|
|
436 $sr_name_hash{$seq_region_id} = $slice->seq_region_name();
|
|
437 $sr_cs_hash{$seq_region_id} = $slice->coord_system();
|
|
438 }
|
|
439
|
|
440 # Obtain a mapper if none was defined, but a dest_seq_region was.
|
|
441 if ( !defined($dest_mapper)
|
|
442 && defined($dest_slice)
|
|
443 && !$dest_slice_cs->equals( $slice->coord_system ) )
|
|
444 {
|
|
445 $dest_mapper =
|
|
446 $asma->fetch_by_CoordSystems( $dest_slice_cs,
|
|
447 $slice->coord_system );
|
|
448 $asm_cs = $dest_mapper->assembled_CoordSystem();
|
|
449 $cmp_cs = $dest_mapper->component_CoordSystem();
|
|
450 $asm_cs_name = $asm_cs->name();
|
|
451 $asm_cs_vers = $asm_cs->version();
|
|
452 $cmp_cs_name = $cmp_cs->name();
|
|
453 $cmp_cs_vers = $cmp_cs->version();
|
|
454 }
|
|
455
|
|
456 my $sr_name = $sr_name_hash{$seq_region_id};
|
|
457 my $sr_cs = $sr_cs_hash{$seq_region_id};
|
|
458
|
|
459 # Remap the feature coordinates to another coord system if a mapper
|
|
460 # was provided.
|
|
461 if ( defined($dest_mapper) ) {
|
|
462
|
|
463 if (defined $dest_slice && $dest_mapper->isa('Bio::EnsEMBL::ChainedAssemblyMapper') ) {
|
|
464 ( $seq_region_id, $seq_region_start,
|
|
465 $seq_region_end, $seq_region_strand )
|
|
466 =
|
|
467 $dest_mapper->map( $sr_name, $seq_region_start, $seq_region_end,
|
|
468 $seq_region_strand, $sr_cs, 1, $dest_slice);
|
|
469
|
|
470 } else {
|
|
471
|
|
472 ( $seq_region_id, $seq_region_start,
|
|
473 $seq_region_end, $seq_region_strand )
|
|
474 = $dest_mapper->fastmap( $sr_name, $seq_region_start,
|
|
475 $seq_region_end, $seq_region_strand,
|
|
476 $sr_cs );
|
|
477 }
|
|
478
|
|
479 # Skip features that map to gaps or coord system boundaries.
|
|
480 if ( !defined($seq_region_id) ) { next FEATURE }
|
|
481
|
|
482 # Get a slice in the coord system we just mapped to.
|
|
483 $slice = $slice_hash{ "ID:" . $seq_region_id } ||=
|
|
484 $sa->fetch_by_seq_region_id($seq_region_id);
|
|
485 }
|
|
486
|
|
487 # If a destination slice was provided convert the coords. If the
|
|
488 # dest_slice starts at 1 and is foward strand, nothing needs doing.
|
|
489 if ( defined($dest_slice) ) {
|
|
490 if ( $dest_slice_start != 1 || $dest_slice_strand != 1 ) {
|
|
491 if ( $dest_slice_strand == 1 ) {
|
|
492 $seq_region_start = $seq_region_start - $dest_slice_start + 1;
|
|
493 $seq_region_end = $seq_region_end - $dest_slice_start + 1;
|
|
494 } else {
|
|
495 my $tmp_seq_region_start = $seq_region_start;
|
|
496 $seq_region_start = $dest_slice_end - $seq_region_end + 1;
|
|
497 $seq_region_end = $dest_slice_end - $tmp_seq_region_start + 1;
|
|
498 $seq_region_strand = -$seq_region_strand;
|
|
499 }
|
|
500 }
|
|
501
|
|
502 # Throw away features off the end of the requested slice.
|
|
503 if ( $seq_region_end < 1
|
|
504 || $seq_region_start > $dest_slice_length
|
|
505 || ( $dest_slice_sr_id != $seq_region_id ) )
|
|
506 {
|
|
507 next FEATURE;
|
|
508 }
|
|
509
|
|
510 $slice = $dest_slice;
|
|
511 }
|
|
512
|
|
513 # Finally, create the new splicing_event.
|
|
514 push( @splicing_events,
|
|
515 $self->_create_feature_fast( 'Bio::EnsEMBL::SplicingEvent', {
|
|
516 'start' => $seq_region_start,
|
|
517 'end' => $seq_region_end,
|
|
518 'strand' => $seq_region_strand,
|
|
519 'adaptor' => $self,
|
|
520 'slice' => $slice,
|
|
521 'dbID' => $splicing_event_id,
|
|
522 'name' => $name,
|
|
523 'gene_id' => $gene_id,
|
|
524 'type' => $type } ) );
|
|
525
|
|
526 } ## end while ( $sth->fetch() )
|
|
527
|
|
528 return \@splicing_events;
|
|
529 } ## end sub _objs_from_sth
|
|
530
|
|
531
|
|
532 1;
|