0
|
1 #
|
|
2 # Ensembl module for Bio::EnsEMBL::Funcgen::Array
|
|
3 #
|
|
4 # You may distribute this module under the same terms as Perl itself
|
|
5
|
|
6
|
|
7 =head1 LICENSE
|
|
8
|
|
9 Copyright (c) 1999-2011 The European Bioinformatics Institute and
|
|
10 Genome Research Limited. All rights reserved.
|
|
11
|
|
12 This software is distributed under a modified Apache license.
|
|
13 For license details, please see
|
|
14
|
|
15 http://www.ensembl.org/info/about/code_licence.html
|
|
16
|
|
17 =head1 CONTACT
|
|
18
|
|
19 Please email comments or questions to the public Ensembl
|
|
20 developers list at <ensembl-dev@ebi.ac.uk>.
|
|
21
|
|
22 Questions may also be sent to the Ensembl help desk at
|
|
23 <helpdesk@ensembl.org>.
|
|
24
|
|
25
|
|
26 =head1 NAME
|
|
27
|
|
28 Bio::EnsEMBL::Funcgen::Array - A module to represent a nucleotide microarray.
|
|
29
|
|
30 =head1 SYNOPSIS
|
|
31
|
|
32 use Bio::EnsEMBL::Funcgen::Array;
|
|
33
|
|
34 my $array = Bio::EnsEMBL::Funcgen::Array->new(
|
|
35 -NAME => 'Array-1',
|
|
36 -FORMAT => 'Tiled',
|
|
37 -SIZE => '1',
|
|
38 -VENDOR => 'Nimblegen',
|
|
39 -DESCRIPTION => $desc,
|
|
40 -TYPE => 'OLIGO',
|
|
41 -CLASS => 'VENDOR_FORMAT'
|
|
42 );
|
|
43
|
|
44 my $db_adaptor = Bio::EnsEMBL::Funcgen::DBSQL::DBAdaptor->new(...);
|
|
45 my $array_adaptor = $db_adaptor->get_ArrayAdaptor();
|
|
46 my $array = $array_adaptor->fetch_by_name($array_name)
|
|
47
|
|
48 =head1 DESCRIPTION
|
|
49
|
|
50 An Array object represents a nucleotide (OLIGO, PCR etc.) microarray. The data
|
|
51 (currently the name, format, size, species, vendor and description) are stored
|
|
52 in the array table.
|
|
53
|
|
54 =cut
|
|
55
|
|
56
|
|
57 use strict;
|
|
58 use warnings;
|
|
59
|
|
60
|
|
61 package Bio::EnsEMBL::Funcgen::Array;
|
|
62
|
|
63
|
|
64 use Bio::EnsEMBL::Utils::Argument qw( rearrange );
|
|
65 use Bio::EnsEMBL::Utils::Exception qw( throw warning );
|
|
66 use Bio::EnsEMBL::Funcgen::Storable;
|
|
67
|
|
68 use vars qw(@ISA);# %VALID_TYPE);
|
|
69 @ISA = qw(Bio::EnsEMBL::Funcgen::Storable);
|
|
70
|
|
71
|
|
72 # Possible types for OligoArray objects
|
|
73 #This should match the vendor enum values?
|
|
74 #%VALID_TYPE = (
|
|
75 # 'AFFY' => 1,
|
|
76 # 'OLIGO' => 1,
|
|
77 #);
|
|
78
|
|
79
|
|
80 =head2 new
|
|
81
|
|
82 Arg [-NAME] : string - the name of this array
|
|
83 Arg [-VENDOR] : string - the vendor of this array (AFFY, NIMBLEGEN etc)
|
|
84 Arg [-TYPE] : string - type of array e.g. OLIGO, PCR
|
|
85 Arg [-FORMAT] : string - the format of this array (TILED, TARGETTED, GENE etc)
|
|
86 Arg [-DESCRIPTION] : strin - description of the array
|
|
87
|
|
88 #array_chips is array of hashes or design_id and name, dbID will be populated on store, this should be a simple object!
|
|
89
|
|
90 Example : my $array = Bio::EnsEMBL::Funcgen::Array->new(
|
|
91 -NAME => 'Array-1',
|
|
92 -FORMAT => 'Tiled',
|
|
93 -SIZE => '1',
|
|
94 -VENDOR => 'Nimblegen',
|
|
95 -TYPE => 'OLIGO',
|
|
96 -DESCRIPTION => $desc,
|
|
97 -CLASS => 'VENDOR_FORMAT',#e.g. AFFY_UTR, ILLUMINA_WG
|
|
98 );
|
|
99 Description: Creates a new Bio::EnsEMBL::Funcgen::Array object.
|
|
100 Returntype : Bio::EnsEMBL::Funcgen::Array
|
|
101 Exceptions : None ? should throw if mandatort params not set/valid
|
|
102 Caller : General
|
|
103 Status : At risk
|
|
104
|
|
105 =cut
|
|
106
|
|
107 sub new {
|
|
108 my $caller = shift;
|
|
109
|
|
110 my $class = ref($caller) || $caller;
|
|
111 my $self = $class->SUPER::new(@_);
|
|
112
|
|
113 my ($name, $format, $size, $vendor, $type, $desc, $aclass)
|
|
114 = rearrange( ['NAME', 'FORMAT', 'SIZE', 'VENDOR', 'TYPE', 'DESCRIPTION', 'CLASS'], @_ );
|
|
115
|
|
116 #mandatory params?
|
|
117 #name, format, vendor
|
|
118 #enum on format?
|
|
119
|
|
120 my @stack = caller();
|
|
121
|
|
122 if($self->dbID() && $stack[0] ne "Bio::EnsEMBL::Funcgen::DBSQL::ArrayAdaptor"){
|
|
123 throw("You must use the ArrayAdaptor($stack[0]) to generate Arrays with a dbID i.e. from the DB, as this module accomodates updating which may cause incorrect data if the object is not generated form the DB");
|
|
124 }
|
|
125
|
|
126
|
|
127 throw("Must provide a vendor parameter") if ! $vendor;
|
|
128 throw("Must provide a name parameter") if ! $name;
|
|
129 #any others?
|
|
130
|
|
131
|
|
132 $self->name($name);
|
|
133 $self->format($format) if defined $format;
|
|
134
|
|
135 if(defined $format && $format eq 'EXPRESSION' && ! defined $class){
|
|
136 throw('You must defined a class if you are importing and array with an EXPRESSION format');
|
|
137 }
|
|
138
|
|
139 $self->class(uc($aclass)) if defined $aclass;
|
|
140 $self->size($size) if defined $size;
|
|
141 $self->vendor($vendor);
|
|
142 $self->description($desc) if defined $desc;
|
|
143 $self->type($type) if defined $type;
|
|
144
|
|
145 return $self;
|
|
146 }
|
|
147
|
|
148 =head2 get_all_Probes
|
|
149
|
|
150 Args : None
|
|
151 Example : my $probes = $array->get_all_Probes();
|
|
152 Description: Returns all probes on an array. Needs a database connection.
|
|
153 Returntype : Listref of Bio::EnsEMBL::Funcgen::Probe objects
|
|
154 Exceptions : None
|
|
155 Caller : General
|
|
156 Status : At Risk
|
|
157
|
|
158 =cut
|
|
159
|
|
160 sub get_all_Probes {
|
|
161 my $self = shift;
|
|
162
|
|
163 if ( $self->dbID() && $self->adaptor() ) {
|
|
164 my $opa = $self->adaptor()->db()->get_ProbeAdaptor();
|
|
165 my $probes = $opa->fetch_all_by_Array($self);
|
|
166 return $probes;
|
|
167 } else {
|
|
168 warning('Need database connection to retrieve Probes');
|
|
169 return [];
|
|
170 }
|
|
171 }
|
|
172
|
|
173 =head2 get_all_Probe_dbIDs
|
|
174
|
|
175 Args : None
|
|
176 Example : my @dbids = @{$array->get_all_Probe_dbIDs};
|
|
177 Description: Returns an array ref of all the Probe database IDs for this array
|
|
178 Returntype : arrayref of ints
|
|
179 Exceptions : None
|
|
180 Caller : General
|
|
181 Status : At Risk
|
|
182
|
|
183 =cut
|
|
184
|
|
185 sub get_all_Probe_dbIDs {
|
|
186 my $self = shift;
|
|
187
|
|
188 if(! $self->{probe_dbids}){
|
|
189 #check for adaptor here?
|
|
190
|
|
191 if(! $self->adaptor){
|
|
192 throw('Must have set an adaptor to get_all_Probe_dbIDs');
|
|
193 }
|
|
194
|
|
195 $self->{probe_dbids} = $self->adaptor->fetch_Probe_dbIDs_by_Array($self);
|
|
196 }
|
|
197
|
|
198 return $self->{probe_dbids};
|
|
199 }
|
|
200
|
|
201
|
|
202
|
|
203
|
|
204 #Nath new get methods
|
|
205
|
|
206 =head2 get_all_ProbeSets
|
|
207
|
|
208 Args : None
|
|
209 Example : my $probesets = $array->get_all_ProbeSets();
|
|
210 Description: Returns all probesets on an array. Needs a database connection.
|
|
211 Returntype : Listref of Bio::EnsEMBL::Funcgen::ProbeSets objects
|
|
212 Exceptions : None
|
|
213 Caller : General
|
|
214 Status : Medium Risk
|
|
215
|
|
216 =cut
|
|
217
|
|
218 sub get_all_ProbeSets {
|
|
219 my $self = shift;
|
|
220
|
|
221 if ( $self->dbID() && $self->adaptor() ) {
|
|
222 my $opsa = $self->adaptor()->db()->get_ProbeSetAdaptor();
|
|
223 my $probesets = $opsa->fetch_all_by_Array($self);
|
|
224 return $probesets;
|
|
225 } else {
|
|
226 warning('Need database connection to retrieve ProbeSets');
|
|
227 return [];
|
|
228 }
|
|
229 }
|
|
230
|
|
231
|
|
232 #All the array_chip methods will be migrated to ArrayChip.pm
|
|
233
|
|
234 =head2 get_array_chip_ids
|
|
235
|
|
236 Example : my @ac_ids = @{$array->get_array_chip_ids()};
|
|
237 Description: Returns all array_chip_ids for this array.
|
|
238 Returntype : Listref of array_chip ids
|
|
239 Exceptions : Throws if none retrieved
|
|
240 Caller : General
|
|
241 Status : At Risk
|
|
242
|
|
243 =cut
|
|
244
|
|
245 sub get_array_chip_ids {
|
|
246 my $self = shift;
|
|
247
|
|
248 my @ac_ids;
|
|
249
|
|
250
|
|
251 $self->get_ArrayChips();
|
|
252
|
|
253 #should we get_ArrayChips is we have none cached?
|
|
254 #this may cause problem
|
|
255
|
|
256
|
|
257 foreach my $achip(values %{$self->{'array_chips'}}){
|
|
258 push @ac_ids, $achip->dbID();
|
|
259 }
|
|
260
|
|
261 if(! @ac_ids){
|
|
262 throw("No array_chip_ids available"); # should this be warn?
|
|
263 }
|
|
264
|
|
265 return \@ac_ids;
|
|
266 }
|
|
267
|
|
268 =head2 get_design_ids
|
|
269
|
|
270 Example : my @design_ids = @{$array->get_design_ids()};
|
|
271 Description: Returns a the design_ids for each array_chip contained within this array
|
|
272 Returntype : list
|
|
273 Exceptions : None
|
|
274 Caller : General
|
|
275 Status : Medium Risk
|
|
276
|
|
277 =cut
|
|
278
|
|
279
|
|
280
|
|
281 sub get_design_ids{
|
|
282 my $self = shift;
|
|
283 return [keys %{$self->{'array_chips'}}];
|
|
284 }
|
|
285
|
|
286
|
|
287
|
|
288 =head2 name
|
|
289
|
|
290 Arg [1] : (optional) string - the name of this array
|
|
291 Example : my $name = $array->name();
|
|
292 Description: Getter, setter of the name attribute for Array
|
|
293 objects.
|
|
294 Returntype : string
|
|
295 Exceptions : None
|
|
296 Caller : General
|
|
297 Status : Medium Risk
|
|
298
|
|
299 =cut
|
|
300
|
|
301 sub name{
|
|
302 my $self = shift;
|
|
303
|
|
304 $self->{'name'} = shift if @_;
|
|
305
|
|
306 #do we need this?
|
|
307 #if ( !exists $self->{'name'} && $self->dbID() && $self->adaptor() ) {
|
|
308 # $self->adaptor->fetch_attributes($self);
|
|
309 #}
|
|
310
|
|
311 return $self->{'name'};
|
|
312 }
|
|
313
|
|
314
|
|
315 =head2 type
|
|
316
|
|
317 Arg [1] : (optional) string - the type of this array
|
|
318 Example : $array->type('OLIGO');
|
|
319 Description: Getter, setter of the type attribute for Array
|
|
320 objects.
|
|
321 Returntype : string
|
|
322 Exceptions : None
|
|
323 Caller : General
|
|
324 Status : Medium Risk
|
|
325
|
|
326 =cut
|
|
327
|
|
328 sub type{
|
|
329 my $self = shift;
|
|
330
|
|
331 $self->{'type'} = shift if @_;
|
|
332
|
|
333 return $self->{'type'};
|
|
334 }
|
|
335
|
|
336
|
|
337 =head2 format
|
|
338
|
|
339 Arg [1] : (optional) string - the format of the array
|
|
340 Example : my $format = $array->format();
|
|
341 Description: Getter, setter of format attribute for
|
|
342 Array objects e.g. Tiled, Targetted etc...
|
|
343 Returntype : string
|
|
344 Exceptions : None
|
|
345 Caller : General
|
|
346 Status : Medium Risk
|
|
347
|
|
348 =cut
|
|
349
|
|
350 sub format {
|
|
351 my $self = shift;
|
|
352
|
|
353 $self->{'format'} = shift if @_;
|
|
354
|
|
355 #do we need this?
|
|
356 #if ( !exists $self->{'format'} && $self->dbID() && $self->adaptor() ) {
|
|
357 # $self->adaptor->fetch_attributes($self);
|
|
358 #}
|
|
359
|
|
360 return $self->{'format'};
|
|
361 }
|
|
362
|
|
363 =head2 class
|
|
364
|
|
365 Arg [1] : (optional) string - the class of the array
|
|
366 Example : my $class = $array->class('AFFY_UTR');
|
|
367 Description: Getter, setter of class attribute for
|
|
368 Array objects e.g. AFFY_UTR, AFFY_ST
|
|
369 Returntype : string
|
|
370 Exceptions : None
|
|
371 Caller : General
|
|
372 Status : Medium Risk
|
|
373
|
|
374 =cut
|
|
375
|
|
376 sub class {
|
|
377 my $self = shift;
|
|
378
|
|
379 $self->{'class'} = shift if @_;
|
|
380
|
|
381 return $self->{'class'};
|
|
382 }
|
|
383
|
|
384
|
|
385 =head2 size
|
|
386
|
|
387 Arg [1] : (optional) int - the number of ? in the array
|
|
388 Example : my $size = $array->size();
|
|
389 Description: Getter of size attribute for Array objects. This
|
|
390 simply counts the constituent ArrayChips
|
|
391 Returntype : int
|
|
392 Exceptions : None
|
|
393 Caller : General
|
|
394 Status : Medium Risk
|
|
395
|
|
396 =cut
|
|
397
|
|
398 sub size {
|
|
399 my $self = shift;
|
|
400
|
|
401 return scalar(keys %{$self->{'array_chips'}});
|
|
402 }
|
|
403
|
|
404
|
|
405 =head2 vendor
|
|
406
|
|
407 Arg [1] : (optional) string - the name of the array vendor
|
|
408 Example : my $vendor = $array->vendor();
|
|
409 Description: Getter, setter of vendor attribute for
|
|
410 Array objects.
|
|
411 Returntype : string
|
|
412 Exceptions : None
|
|
413 Caller : General
|
|
414 Status : Medium Risk
|
|
415
|
|
416 =cut
|
|
417
|
|
418 sub vendor {
|
|
419 my $self = shift;
|
|
420 $self->{'vendor'} = shift if @_;
|
|
421
|
|
422 #do we need this?
|
|
423 #if ( !exists $self->{'vendor'} && $self->dbID() && $self->adaptor() ) {
|
|
424 # $self->adaptor->fetch_attributes($self);
|
|
425 #}
|
|
426
|
|
427 return $self->{'vendor'};
|
|
428 }
|
|
429
|
|
430 =head2 description
|
|
431
|
|
432 Arg [1] : (optional) string - the description of the array
|
|
433 Example : my $size = $array->description();
|
|
434 Description: Getter, setter of description attribute for
|
|
435 Array objects.
|
|
436 Returntype : string
|
|
437 Exceptions : None
|
|
438 Caller : General
|
|
439 Status : Medium Risk
|
|
440
|
|
441 =cut
|
|
442
|
|
443 sub description {
|
|
444 my $self = shift;
|
|
445 $self->{'description'} = shift if @_;
|
|
446
|
|
447 #do we need this?
|
|
448 #if ( !exists $self->{'description'} && $self->dbID() && $self->adaptor() ) {
|
|
449 # $self->adaptor->fetch_attributes($self);
|
|
450 #}
|
|
451
|
|
452 return $self->{'description'};
|
|
453 }
|
|
454
|
|
455 =head2 probe_count
|
|
456
|
|
457 Example : my $num_probes = $array->probe_count();
|
|
458 Description: Return number of probes on array
|
|
459 Returntype : string
|
|
460 Exceptions : None
|
|
461 Caller : General
|
|
462 Status : At Risk
|
|
463
|
|
464 =cut
|
|
465
|
|
466 sub probe_count {
|
|
467 my ($self) = @_;
|
|
468 #Do we want a distinct flag here?
|
|
469
|
|
470 if(! defined $self->{'probe_count'}){
|
|
471 $self->{'probe_count'} = $self->adaptor->fetch_probe_count_by_Array($self);
|
|
472 }
|
|
473
|
|
474 return $self->{'probe_count'};
|
|
475 }
|
|
476
|
|
477
|
|
478
|
|
479 =head2 get_ArrayChips
|
|
480
|
|
481 Example : my @achips = @{$array->get_ArrayChips()};
|
|
482 Description: Getter, setter and lazy loader of array_chip hashes
|
|
483 Returntype : Arrays of ArrayChip objects
|
|
484 Exceptions : Throws exception if none found for array_id
|
|
485 Caller : General
|
|
486 Status : High Risk - migrate to ArrayChip.pm
|
|
487
|
|
488 =cut
|
|
489
|
|
490 sub get_ArrayChips {
|
|
491 my $self = shift;
|
|
492
|
|
493 #lazy loaded as we won't want this for light DB
|
|
494 #should do meta check and want here
|
|
495
|
|
496 if ( ! exists $self->{'array_chips'}){
|
|
497
|
|
498 if( $self->dbID() && $self->adaptor() ) {
|
|
499 #$self->adaptor->fetch_attributes($self);
|
|
500 #need to do this differently as we're accessing a different table
|
|
501 $self->{'array_chips'} = {};
|
|
502
|
|
503 foreach my $achip(@{$self->adaptor->db->get_ArrayChipAdaptor->fetch_all_by_array_id($self->dbID())}){
|
|
504 $self->{'array_chips'}{$achip->design_id} = $achip;
|
|
505 #%{$self->{'array_chips'}} = %{$self->adaptor->db->get_ArrayAdaptor->_fetch_array_chips_by_array_dbID($self->dbID())};
|
|
506 }
|
|
507 }
|
|
508 else{
|
|
509 throw("Need array dbID and DB connection to retrieve array_chips");
|
|
510 }
|
|
511 }
|
|
512
|
|
513 return [ values %{$self->{'array_chips'}} ];
|
|
514 }
|
|
515
|
|
516 =head2 get_ArrayChip_by_design_id
|
|
517
|
|
518 Arg [1] : (mandatory) int - design_id
|
|
519 Example : my %ac = %{$array->get_ArrayChip_by_design_id('1234')};
|
|
520 Description: Getter for array_chip hashes
|
|
521 Returntype : Hashref
|
|
522 Exceptions : Throws exception if no design_id defined, warns if not part of array
|
|
523 Caller : General
|
|
524 Status : At risk
|
|
525
|
|
526 =cut
|
|
527
|
|
528 sub get_ArrayChip_by_design_id{
|
|
529 my ($self, $design_id) = @_;
|
|
530
|
|
531
|
|
532 #warn "This needs to get the array chip if not defined?? but we're using it to test whether is has been stored same problem as probe_design?";
|
|
533
|
|
534 my ($achip);
|
|
535 throw("Must supply a valid array chip design_id") if (! defined $design_id);
|
|
536
|
|
537 if(defined $self->{'array_chips'}{$design_id}){
|
|
538 $achip = $self->{'array_chips'}{$design_id};
|
|
539 }else{
|
|
540 #No we use this to check whether it has been stored with the array
|
|
541 #warn("should this throw? Array does not contain ArrayChip:$design_id\n");
|
|
542 }
|
|
543
|
|
544 return $achip;
|
|
545 }
|
|
546
|
|
547 =head2 add_ArrayChip
|
|
548
|
|
549 Arg [1] : mandatory - Bio::EnsEMBL::Funcgen::ArrayChip
|
|
550 Example : $array->add_ArrayChip($array_chip);
|
|
551 Description: Setter for array chips
|
|
552 Returntype : None
|
|
553 Exceptions : Throws if arg not a Bio::EnsEMBL::Funcgen::ArrayChip, or Array not stored
|
|
554 Caller : General
|
|
555 Status : Ar risk
|
|
556
|
|
557 =cut
|
|
558
|
|
559 #This uses previosuly stored array_chips withotu warning
|
|
560 #Need to implement fetch_store method?
|
|
561
|
|
562 sub add_ArrayChip{
|
|
563 my ($self, $array_chip) = @_;
|
|
564
|
|
565 throw("You must supply a stored Bio::EnsEMBL::Funcgen::ArrayChip") if(! ($array_chip &&
|
|
566 $array_chip->isa("Bio::EnsEMBL::Funcgen::ArrayChip") &&
|
|
567 $array_chip->dbID()));
|
|
568
|
|
569 if ($self->dbID() && $self->adaptor()){
|
|
570 $self->get_ArrayChips() if (! $self->{'array_chips'});
|
|
571
|
|
572 if(exists $self->{'array_chips'}{$array_chip->design_id}){
|
|
573 $array_chip = $self->{'array_chips'}{$array_chip->design_id};
|
|
574 #warn("Array chip for ".$array_chip->design_id()." already exists, using previous stored array chip\n");
|
|
575 }else{
|
|
576 $self->{'array_chips'}{$array_chip->design_id} = $array_chip;
|
|
577 }
|
|
578
|
|
579 }else{
|
|
580 throw("Array must be stored before adding an array_chip");
|
|
581 }
|
|
582
|
|
583 return;
|
|
584 }
|
|
585
|
|
586
|
|
587 1;
|
|
588
|