comparison variant_effect_predictor/Bio/EnsEMBL/Funcgen/RegulatoryFeature.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
2 =head1 LICENSE
3
4 Copyright (c) 1999-2012 The European Bioinformatics Institute and
5 Genome Research Limited. All rights reserved.
6
7 This software is distributed under a modified Apache license.
8 For license details, please see
9
10 http://www.ensembl.org/info/about/code_licence.html
11
12 =head1 CONTACT
13
14 Please email comments or questions to the public Ensembl
15 developers list at <ensembl-dev@ebi.ac.uk>.
16
17 Questions may also be sent to the Ensembl help desk at
18 <helpdesk@ensembl.org>.
19
20 =head1 NAME
21
22 Bio::EnsEMBL::Funcgen::RegulatoryFeature
23
24 =head1 SYNOPSIS
25
26 use Bio::EnsEMBL::Registry;
27 use Bio::EnsEMBL::Funcgen::RegulatoryFeature;
28 my $reg = Bio::EnsEMBL::Registry->load_adaptors_from_db
29 (
30 -host => 'ensembldb.ensembl.org',
31 -user => 'anonymous'
32 );
33
34 my $regfeat_adaptor = $reg->get_adaptor($species, 'funcgen', 'RegulatoryFeature');
35
36
37 ### Creating/storing a RegulatoryFeature Set ###
38 my $feature = Bio::EnsEMBL::Funcgen::RegulatoryFeature->new
39 (
40 -SLICE => $chr_1_slice,
41 -START => 1_000_000,
42 -END => 1_000_024,
43 -STRAND => 0,
44 -DISPLAY_LABEL => $text,
45 -FEATURE_SET => $fset,
46 -FEATURE_TYPE => $reg_ftype,
47 -ATTRIBUTE_CACHE => \%attr_cache,
48 );
49
50 my ($stored_feat) = @{$regfeat_adaptor->store([$feature])};
51
52
53 ### Fetching some RegualtoryFeatures
54 my @regfeats = @{$regfeat_adaptor->fetch_all_by_Slice_FeatureSets($slice, \@fsets)};
55
56
57 ### Print the bound and core loci
58 print join(' - ', ($reg_feat->bound_start,
59 $reg_feat->start,
60 $reg_feat->end,
61 $reg_feat->bound_end)."\n";
62
63
64 ### Getting some supporting evidence for a RegualtoryFeatures
65 my @reg_attrs = @{$reg_feat->regulatory_attributes('annotated')};
66
67
68 =head1 DESCRIPTION
69
70 A RegulatoryFeature object represents the output of the Ensembl RegulatoryBuild:
71 http://www.ensembl.org/info/docs/funcgen/regulatory_build.html
72
73 It is comprises many possible histone, transcription factor, polymerase and open
74 chromatin features, which have been combined to provide a summary view and
75 classification of the regulatory status at a given loci.
76
77
78 =head1 SEE ALSO
79
80 Bio::EnsEMBL:Funcgen::DBSQL::RegulatoryFeatureAdaptor
81 Bio::EnsEMBL::Funcgen::SetFeature
82
83 =cut
84
85
86 package Bio::EnsEMBL::Funcgen::RegulatoryFeature;
87
88 use Bio::EnsEMBL::Utils::Argument qw( rearrange );
89 use Bio::EnsEMBL::Utils::Exception qw( throw );
90 use strict;
91 use warnings;
92
93 use base qw(Bio::EnsEMBL::Funcgen::SetFeature); #@ISA
94
95
96 =head2 new
97
98 Arg [-SLICE] : Bio::EnsEMBL::Slice - The slice on which this feature is located.
99 Arg [-START] : int - The start coordinate of this feature relative to the start of the slice
100 it is sitting on. Coordinates start at 1 and are inclusive.
101 Arg [-END] : int -The end coordinate of this feature relative to the start of the slice
102 it is sitting on. Coordinates start at 1 and are inclusive.
103 Arg [-FEATURE_SET] : Bio::EnsEMBL::Funcgen::FeatureSet - Regulatory Feature set
104 Arg [-FEATURE_TYPE] : Bio::EnsEMBL::Funcgen::FeatureType - Regulatory Feature sub type
105 Arg [-BINARY_STRING] : (optional) string - Regulatory Build binary string
106 Arg [-STABLE_ID] : (optional) string - Stable ID for this RegualtoryFeature e.g. ENSR00000000001
107 Arg [-DISPLAY_LABEL] : (optional) string - Display label for this feature
108 Arg [-ATTRIBUTE_CACHE] : (optional) HASHREF of feature class dbID|Object lists
109 Arg [-PROJECTED] : (optional) boolean - Flag to specify whether this feature has been projected or not
110 Arg [-dbID] : (optional) int - Internal database ID.
111 Arg [-ADAPTOR] : (optional) Bio::EnsEMBL::DBSQL::BaseAdaptor - Database adaptor.
112
113 Example : my $feature = Bio::EnsEMBL::Funcgen::RegulatoryFeature->new(
114 -SLICE => $chr_1_slice,
115 -START => 1000000,
116 -END => 1000024,
117 -DISPLAY_LABEL => $text,
118 -FEATURE_SET => $fset,
119 -FEATURE_TYPE => $reg_ftype,
120 -ATTRIBUTE_CACHE => \%attr_cache,
121 );
122
123
124 Description: Constructor for RegulatoryFeature objects.
125 Returntype : Bio::EnsEMBL::Funcgen::RegulatoryFeature
126 Exceptions : None
127 Caller : General
128 Status : Stable
129
130 =cut
131
132 sub new {
133 my $caller = shift;
134 my $class = ref($caller) || $caller;
135 my $self = $class->SUPER::new(@_);
136
137 my ($stable_id, $attr_cache, $bin_string, $projected)
138 = rearrange(['STABLE_ID', 'ATTRIBUTE_CACHE', 'BINARY_STRING', 'PROJECTED'], @_);
139
140 #None of these are mandatory at creation
141 #under different use cases
142 $self->{binary_string} = $bin_string if defined $bin_string;
143 $self->{stable_id} = $stable_id if defined $stable_id;
144 $self->{projected} = $projected if defined $projected;
145 $self->attribute_cache($attr_cache) if $attr_cache;
146
147 return $self;
148 }
149
150
151 =head2 display_label
152
153 Example : my $label = $feature->display_label();
154 Description: Getter for the display label of this feature.
155 Returntype : String
156 Exceptions : None
157 Caller : General
158 Status : Stable
159
160 =cut
161
162 sub display_label {
163 my $self = shift;
164
165 if(! defined $self->{'display_label'}){
166 $self->{'display_label'} = $self->feature_type->name.' Regulatory Feature';
167
168 if( defined $self->cell_type ){
169 $self->{'display_label'} .= ' - '.$self->cell_type->name;
170 }
171 }
172
173 return $self->{display_label};
174 }
175
176 =head2 display_id
177
178 Example : print $feature->display_id();
179 Description: This method returns a string that is considered to be
180 the 'display' identifier. In this case the stable Id is
181 preferred
182 Returntype : String
183 Exceptions : none
184 Caller : web drawing code, Region Report tool
185 Status : Stable
186
187 =cut
188
189 sub display_id { return $_[0]->{stable_id}; }
190
191
192 =head2 binary_string
193
194 Arg [1] : optional string - binary string from regulatory build
195 Example : my $bin_string = $feature->binary_string();
196 Description: Getter and setter for the binary_string for this feature.
197 Returntype : String
198 Exceptions : None
199 Caller : General
200 Status : At Risk - May change to BLOB, remove setter functionality
201
202 =cut
203
204 sub binary_string{
205 my ($self, $bin_string) = @_;
206
207 if (defined $bin_string){
208 #added v67
209 warn "RegualtoryFeature::binary_string setter functionality is being removed\n";
210 $self->{binary_string} = $bin_string;
211 }
212
213 return $self->{binary_string};
214 }
215
216
217 =head2 stable_id
218
219 Arg [1] : (optional) string - stable_id e.g ENSR00000000001
220 Example : my $stable_id = $feature->stable_id();
221 Description: Getter and setter for the stable_id attribute for this feature.
222 Returntype : string
223 Exceptions : None
224 Caller : General
225 Status : At risk - setter functionality to be removed
226
227 =cut
228
229 sub stable_id {
230 my $self = shift;
231
232 if (@_){
233 #added v67
234 warn "RegualtoryFeature::stable_id setter functionality is being removed\n";
235 $self->{stable_id} = shift;
236 }
237
238 return $self->{stable_id};
239 }
240
241
242 =head2 regulatory_attributes
243
244 Arg [1] : String (optional) - Class of feature e.g. annotated or motif
245 Example : print "Regulatory Attributes:\n\t".join("\n\t", (map $_->feature_type->name, @{$feature->regulatory_attributes()}))."\n";
246 Description: Getter for the regulatory_attributes for this feature.
247 Returntype : ARRAYREF
248 Exceptions : Throws if feature class not valid
249 Caller : General
250 Status : At Risk
251
252 =cut
253
254
255 sub regulatory_attributes{
256 my ($self, $feature_class) = @_;
257
258 #Incorporating the MFs like this does cause some redundancy in the DB
259 #But will speed up display of the RegFeat image including the MFs
260 #Redefine the cache to have class keys e.g. TFBS, OpenChromatin, Histone Mods
261 #Can't do this as we need the table key to be able to fetch the features
262 #Really need something to be able to draw the image first, then create the zmenu details later.
263
264 my %adaptors = (
265 'annotated' => $self->adaptor->db->get_AnnotatedFeatureAdaptor,
266 'motif' => $self->adaptor->db->get_MotifFeatureAdaptor,
267 #external
268 );
269
270 my @fclasses;
271
272 if(defined $feature_class){
273
274 if(exists $adaptors{lc($feature_class)}){
275 @fclasses = (lc($feature_class));
276 }
277 else{
278 throw("The feature class you specified is not valid:\t$feature_class\n".
279 "Please use one of:\t".join(', ', keys %adaptors));
280 }
281 }
282 else{
283 @fclasses = keys %adaptors;
284 }
285
286 foreach my $fclass(@fclasses){
287 #Now structured as hash to facilitate faster has_attribute method
288 #Very little difference to array based cache
289
290 my @attr_dbIDs = keys %{$self->{'attribute_cache'}{$fclass}};
291
292
293 if(scalar(@attr_dbIDs) > 0){
294
295 if( ! ( ref($self->{'regulatory_attributes'}{$fclass}->[0]) &&
296 ref($self->{'regulatory_attributes'}{$fclass}->[0])->isa('Bio::EnsEMBL::Feature') )){
297
298 $adaptors{$fclass}->force_reslice(1);#So we don't lose attrs which aren't on the slice
299 $self->{'regulatory_attributes'}{$fclass} = $adaptors{$fclass}->fetch_all_by_dbID_list(\@attr_dbIDs, $self->slice);
300
301 #Having problems here if we are trying to project between Y PAR and X
302 #Current dest_slice mapping code simply changes the start end values assuming the slice is correct
303 #currently no test for seq_region name match
304
305
306 #foreach my $attr(@{ $self->{'regulatory_attributes'}{$fclass}}){
307 # warn "$attr ".$attr->dbID." ".$attr->feature_Slice->name."\n";
308 #}
309
310
311 $adaptors{$fclass}->force_reslice(0);
312
313 #Problems here with attrs not being returning when they do not lie on dest slice
314 #i.e. core projected to cell line, but dest slice only over laps a region of the core which
315 #actually has no attrs.
316 #either use the feature_Slice and reslice everthing to the dest slice
317 #or skip test in attr obj_frm_sth?
318 #
319
320 #This method transfers to the query slice, do not use fetch_by_dbID
321 #It also should use _final_clause
322 #This is currently only specified in the MotifFeatureAdaptor
323 #as these are required to be sorted to relate to the structure string
324
325 #but we are stll storing in has where order is not preserved!!
326 #so this will not match order of underlying strcture!
327
328 #separate so we can have ordered array returned
329 #do we need redundant caches?
330 #defo need db id cache for 'has' methods
331
332 #foreach my $attr(@{$fclass_attrs}){
333 # $self->{'regulatory_attributes'}{$fclass}{$attr->dbID} = $attr;
334 #}
335 }
336 }
337 else{
338 $self->{'regulatory_attributes'}{$fclass} = [];
339 }
340 }
341
342 return [ map { @{$self->{'regulatory_attributes'}{$_}} } @fclasses ];
343 }
344
345 =head2 has_attribute
346
347 Arg [1] : Attribute Feature dbID
348 Arg [2] : Attribute Feature class e.g. motif or annotated
349 Example : if($regf->has_attribute($af->dbID, 'annotated'){ #do something here }
350 Description: Identifies whether this RegualtoryFeature has a given attribute
351 Returntype : Boolean
352 Exceptions : Throws if args are not defined
353 Caller : General
354 Status : Stable
355
356 =cut
357
358
359 sub has_attribute{
360 my ($self, $dbID, $fclass) = @_;
361
362 throw('Must provide a dbID and a Feature class argument') if ! $dbID && $fclass;
363
364 return exists ${$self->attribute_cache}{$fclass}{$dbID};
365 }
366
367 =head2 get_focus_attributes
368
369 Arg [1] : None
370 Example : my @focus_attrs = @{$regf->get_focus_attributes};
371 Description: Getter for the focus features of this RegualtoryFeature, used to defined the core region
372 Returntype : ARRAYREF
373 Exceptions : None
374 Caller : General
375 Status : Stable
376
377 =cut
378
379 sub get_focus_attributes{
380 my $self = shift;
381
382 if(! exists $self->{'focus_attributes'} ||
383 ! @{$self->{'focus_attributes'}}){
384 $self->_sort_attributes;
385 }
386
387
388 return $self->{'focus_attributes'};
389 }
390
391
392 =head2 get_nonfocus_attributes
393
394 Arg [1] : None
395 Example : my @non_focus_attrs = @{$regf->get_nonfocus_attributes};
396 Description: Getter for the non-focus features of this RegulatoryFeature, used to defined
397 the non core region i.e. the whiskers.
398 Returntype : ARRAYREF
399 Exceptions : None
400 Caller : General
401 Status : Stable
402
403 =cut
404
405 sub get_nonfocus_attributes{
406 my $self = shift;
407
408 #Test focus here as we may not have any nonfocus
409 #But focus will show that we have sorted already
410 if(! exists $self->{'focus_attributes'} ||
411 ! @{$self->{'focus_attributes'}}){
412 $self->_sort_attributes;
413 }
414
415 return $self->{'nonfocus_attributes'};
416 }
417
418 #Add pod here
419
420 sub _sort_attributes{
421 my $self = shift;
422
423 $self->{'focus_attributes'} = [];
424 $self->{'nonfocus_attributes'} = [];
425
426 foreach my $attrf(@{$self->regulatory_attributes}){
427
428 if($attrf->isa('Bio::EnsEMBL::Funcgen::MotifFeature') ||
429 $attrf->feature_set->is_focus_set){
430 push @{$self->{'focus_attributes'}}, $attrf;
431 }
432 else{
433 push @{$self->{'nonfocus_attributes'}}, $attrf;
434 }
435 }
436
437 return;
438 }
439
440
441 =head2 attribute_cache
442
443 Arg [1] : optional - HASHREF of attribute table keys with values as either a list of attribute
444 feature dbIDs or objects. If passing object, any MotifFeature objects should be in position
445 order with respect to the slice.
446 Example : $feature->attribute_cache(\%attribute_feature_info);
447 Description: Setter for the regulatory_attribute cache for this feature. This is a short cut method used by the
448 regulatory build and the webcode to avoid unnecessary fetching and enable enable lazy loading
449 Returntype : HASHREF
450 Exceptions : Throws if trying to overwrite existing cache
451 Caller : RegulatoryFeatureAdaptor.pm and build_regulatory_features.pl
452 Status : At Risk
453
454 =cut
455
456
457 sub attribute_cache{
458 my ($self, $attr_hash) = @_;
459
460 # if(! defined $attr_hash){
461 # $self->regulatory_attributes; #Fetch the attrs?
462 #
463 #
464 # #Do we need to do this now we have separated the caches?
465 #
466 # }
467
468 if(defined $attr_hash){
469
470 foreach my $fclass(keys %{$attr_hash}){
471
472 if(exists $self->{'attribute_cache'}{$fclass}){
473 throw("You are trying to overwrite a pre-existing regulatory attribute cache entry for feature class:\t$fclass");
474 }
475 else{
476 $self->{'attribute_cache'}{$fclass} = $attr_hash->{$fclass};
477 }
478 }
479 }
480
481 return $self->{'attribute_cache'} || {};
482 }
483
484
485 =head2 bound_start
486
487 Example : my $bound_start = $feature->bound_start();
488 Description: Getter for the bound_start attribute for this feature.
489 Gives the 5' most start value of the underlying attribute
490 features.
491 Returntype : string
492 Exceptions : None
493 Caller : General
494 Status : Stable
495
496 =cut
497
498 sub bound_start {
499 my $self = shift;
500 $self->get_underlying_structure if ! defined $self->{'bound_start'};
501
502 return $self->{'bound_start'};
503 }
504
505
506 =head2 bound_end
507
508 Example : my $bound_end = $feature->bound_start();
509 Description: Getter for the bound_end attribute for this feature.
510 Gives the 3' most end value of the underlying attribute
511 features.
512 Returntype : string
513 Exceptions : None
514 Caller : General
515 Status : Stable
516
517 =cut
518
519 sub bound_end {
520 my $self = shift;
521 $self->get_underlying_structure if ! defined $self->{'bound_end'};
522
523 return $self->{'bound_end'};
524 }
525
526
527 =head2 bound_seq_region_start
528
529 Example : my $bound_sr_start = $feature->bound_seq_region_start;
530 Description: Getter for the seq_region bound_start attribute for this feature.
531 Gives the 5' most start value of the underlying attribute
532 features.
533 Returntype : string
534 Exceptions : None
535 Caller : General
536 Status : Stable
537
538 =cut
539
540 sub bound_seq_region_start {
541 my $self = shift;
542
543 if(! defined $self->{bound_seq_region_start}){
544
545 if($self->slice->strand == 1){
546 $self->{bound_seq_region_start} = $self->slice->start + $self->bound_start - 1;
547 }
548 else{ #strand = -1
549 $self->{bound_seq_region_start} = $self->slice->end - $self->bound_end + 1;
550 }
551 }
552
553 return $self->{bound_seq_region_start};
554 }
555
556
557 =head2 bound_seq_region_end
558
559 Example : my $bound_sr_end = $feature->bound_seq_region_end;
560 Description: Getter for the seq_region bound_end attribute for this feature.
561 Gives the 3' most end value of the underlying attribute
562 features.
563 Returntype : string
564 Exceptions : None
565 Caller : General
566 Status : Stable
567
568 =cut
569
570
571 sub bound_seq_region_end {
572 my $self = shift;
573
574 if(! defined $self->{bound_seq_region_end}){
575
576 if($self->slice->strand == 1){
577 $self->{bound_seq_region_end} = $self->slice->start + $self->bound_end - 1;
578 }
579 else{ #strand = -1
580 $self->{bound_seq_region_end} = $self->slice->end - $self->bound_start + 1;
581 }
582 }
583
584 return $self->{bound_seq_region_end};
585 }
586
587
588
589
590
591
592 =head2 is_projected
593
594 Arg [1] : optional - boolean
595 Example : if($regf->is_projected){ #do something different here }
596 Description: Getter/Setter for the projected attribute.
597 Returntype : boolean
598 Exceptions : None
599 Caller : General
600 Status : At risk - remove setter functionality
601
602 =cut
603
604 sub is_projected {
605 my $self = shift;
606
607 if(@_){
608 #added v67
609 warn "RegulatoryFeature::is_projected setter functionality is being removed\n";
610 $self->{'projected'} = shift;
611 }
612
613 return $self->{'projected'};
614 }
615
616
617 =head2 get_underlying_structure
618
619 Example : $self->get_underlying_structure() if(! exists $self->{'bound_end'});
620 Description: Getter for the bound_end attribute for this feature.
621 Gives the 3' most end value of the underlying attribute
622 features.
623 Returntype : string
624 Exceptions : None
625 Caller : General
626 Status : At Risk
627
628 =cut
629
630 #This should really be precomputed and stored in the DB to avoid the MF attr fetch
631 #Need to be aware of projecting here, as these will expire if we project after this method is called
632
633 sub get_underlying_structure{
634 my $self = shift;
635
636 if(! defined $self->{underlying_structure}){
637
638 my @attrs = @{$self->regulatory_attributes()};
639
640 if(! @attrs){
641 throw('No underlying regulatory_attribute features to get_underlying_structure for dbID '.$self->dbID);
642 #This should never happen even with a projection build
643 }
644 else{
645
646
647 #We only need to set the bounds when storing on full slice/seq_region values
648 #else they should be fetched from the DB
649
650 if(! defined $self->{'bound_start'}){
651
652 my (@start_ends);
653
654 foreach my $attr(@attrs){
655 push @start_ends, ($attr->start, $attr->end);
656 }
657
658 #Accounts for core region, where data may be absent on this cell type
659 push @start_ends, ($self->start, $self->end);
660
661 @start_ends = sort { $a <=> $b } @start_ends;
662
663 $self->{'bound_end'} = pop @start_ends;
664 $self->{'bound_start'} = shift @start_ends;
665
666 #Need to account for projection build here
667 #i.e. attr extremeties may not extend past core start/end
668
669 if($self->is_projected){
670 $self->{'bound_end'} = $self->end if $self->end > $self->{'bound_end'};
671 $self->{'bound_start'} = $self->start if $self->start < $self->{'bound_start'};
672 }
673 }
674
675 #Now deal with MotifFeature loci
676 my @mf_loci;
677
678 foreach my $mf(@{$self->regulatory_attributes('motif')}){
679 push @mf_loci, ($mf->start, $mf->end);
680 }
681
682 $self->{underlying_structure} = [$self->{'bound_start'}, $self->start, @mf_loci, $self->end, $self->{'bound_end'}];
683 }
684 }
685
686 return $self->{underlying_structure};
687 }
688
689
690 =head2 is_unique_to_FeatureSets
691
692 Arg[1] : optional - ARRAYREF of regualtory Bio::EnsEMBL::Funcgen::FeatureSet objects
693 Default is FeatureSet of given RegulatoryFeature, else need to be
694 defined explicitly.
695 Arg[2] : optional - HASHREF Params hash:
696 {
697 include_projected => 0|1, # Boolean, include 'projected' features
698 }
699 Example : if($reg_feat->is_unique_to_FeatureSets($fsets)}{
700 #then do some analysis here
701 }
702 Description: Identifies whether this RegualtoryFeature is unique to a set of FeatureSets.
703 Returntype : boolean
704 Exceptions : Throw is arguments not stored or valid.
705 Caller : General
706 Status : At risk
707
708 =cut
709
710 #Probably want to add in an FeatureType constraint here
711 #e.g. so we can compare active vs inactive or poised promoters
712
713 #omit include_multi doesn't make sense here
714
715 sub is_unique_to_FeatureSets{
716 my ($self, $fsets, $params_hash) = @_;
717
718 $fsets ||= [$self->feature_set];
719 my @fset_ids;
720
721
722 #define to avoid deref fails below.
723 $params_hash ||= {};
724 if(ref($params_hash) ne 'HASH'){
725 throw("The params hash argument must be a valid HASHREF:\t".ref($params_hash));
726 }
727
728
729 foreach my $fset(@$fsets){
730 #assume we have an adaptor set
731 $self->adaptor->db->is_stored_and_valid('Bio::EnsEMBL::Funcgen::FeatureSet', $fset);
732
733 if($fset->feature_class ne 'regulatory'){
734 throw('Found non-regulatory FeatureSet');
735 }
736
737 push @fset_ids, $fset->dbID;
738 }
739
740 my $stable_id;
741 ($stable_id = $self->stable_id) =~ s/^[A-Z0]+//;
742
743
744 my @other_rf_ids = @{$self->adaptor->_fetch_other_dbIDs_by_stable_feature_set_ids
745 ($stable_id,
746 \@fset_ids,
747 { include_projected => $params_hash->{include_projected}} )};
748
749 return (@other_rf_ids) ? 0 : 1;
750 }
751
752
753
754 =head2 get_other_RegulatoryFeatures
755
756 Arg[1] : optional - ARRAYREF of regualtory Bio::EnsEMBL::Funcgen::FeatureSet objects
757 Default is FeatureSet of given RegulatoryFeature, else need to be
758 defined explicitly.
759 Arg[2] : optional - HASHREF Params hash:
760 {
761 include_projected => 0|1, # Boolean, include 'projected' features
762 include_multicell => 0|1, # Boolean, include MultiCell features
763 }
764 Example : my @other_fsets = @{$reg_feat->get_other_FeatureSets($fsets)};
765 Description: Gets other RegualtoryFeatures (linked via the stable ID) which are present in the
766 specified list of FeatureSets.
767 Returntype : ARRAYREF of Bio::EnsEMBL::Funcgen::RegulatoryFeature objects
768 Exceptions : Throw is arguments not stored or valid.
769 Caller : General
770 Status : At risk
771
772 =cut
773
774 sub get_other_RegulatoryFeatures{
775 my ($self, $fsets, $params_hash) = @_;
776
777 #define to avoid deref fails below.
778 $params_hash ||= {};
779 if(ref($params_hash) ne 'HASH'){
780 throw("The params hash argument must be a valid HASHREF:\t".ref($params_hash));
781 }
782
783 $fsets ||= [$self->feature_set];
784 my @fset_ids;
785
786 foreach my $fset(@$fsets){
787 #assume we have an adaptor set
788 $self->adaptor->db->is_stored_and_valid('Bio::EnsEMBL::Funcgen::FeatureSet', $fset);
789
790 if($fset->feature_class ne 'regulatory'){
791 throw('Found non-regulatory FeatureSet');
792 }
793
794 push @fset_ids, $fset->dbID;
795 }
796
797 my $stable_id;
798 ($stable_id = $self->stable_id) =~ s/^[A-Z0]+//;
799
800 my @other_fsets_ids = @{$self->adaptor->_fetch_other_dbIDs_by_stable_feature_set_ids
801 ($stable_id, \@fset_ids,
802 {
803 include_projected => $params_hash->{include_projected},
804 include_multicell => $params_hash->{include_multicell},
805 })};
806
807 return $self->adaptor->fetch_all_by_dbID_list(\@other_fsets_ids);
808 }
809
810
811
812 1;
813
814 __END__