File Coverage

blib/lib/Microarray/GEO/SOFT/GSE.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package Microarray::GEO::SOFT::GSE;
2            
3 1     1   1504 use List::Vectorize qw(!table);
  1         23901  
  1         650  
4             require Microarray::GEO::SOFT::GPL;
5             require Microarray::GEO::SOFT::GSM;
6             require Microarray::GEO::SOFT::GDS;
7 1     1   10 use Carp;
  1         2  
  1         65  
8 1     1   6 use strict;
  1         2  
  1         34  
9            
10 1     1   5 use base "Microarray::GEO::SOFT";
  1         1  
  1         687  
11            
12             our $GDS_MERGE = 0;
13            
14             1;
15            
16             sub new {
17            
18             my $invocant = shift;
19             my $class = ref($invocant) || $invocant;
20             my $self = { "file" => "",
21             "verbose" => 1,
22             "sample_value_column" => 'VALUE',
23             @_ };
24             bless($self, $class);
25            
26             return $self;
27            
28             }
29            
30             sub parse {
31            
32             my $self = shift;
33            
34             my $fh;
35             if(! List::Vectorize::is_glob_ref($self->{file})) {
36            
37             open F, $self->{file} or croak "cannot open $self->{file}.\n";
38             $fh = \*F;
39             }
40             else {
41             $fh = $self->{file};
42             }
43            
44             $self->_parse_series($fh);
45            
46             return $self;
47             }
48            
49             sub _parse_series {
50            
51             my $self = shift;
52            
53             my $fh = shift;
54            
55             Microarray::GEO::SOFT::_set_fh($self->{verbose});
56            
57             my $accession;
58             my $title;
59             my $platform;
60            
61             my $series;
62            
63             my $gpl_list;
64             my $gsm_list;
65            
66             while(my $line = <$fh>) {
67            
68             chomp $line;
69            
70             if($line =~/^\^SERIES = (GSE\d+)$/) {
71             $accession = $1;
72             }
73            
74             if($line =~/^!Series_title = (.*?)$/) {
75             $title = $1;
76             }
77            
78             if($line =~/^!Series_platform_id = (GPL\d+)$/) {
79             push(@$platform, $1);
80             }
81            
82             # platform part in the file
83             elsif($line =~/^\^PLATFORM = (GPL\d+)$/) {
84            
85             $fh = _back_to_last_line($fh, length($line));
86            
87             # it is a GPL object
88             my $gpl = Microarray::GEO::SOFT::GPL->new(file => $fh,
89             verbose => $self->{verbose});
90             $gpl->parse;
91            
92             push(@$gpl_list, $gpl);
93             }
94             # sample part in the file
95             elsif($line =~/^\^SAMPLE = (GSM\d+)$/) {
96            
97             $fh = _back_to_last_line($fh, length($line));
98            
99             # it is a GSM object
100             my $gsm = Microarray::GEO::SOFT::GSM->new(file => $fh,
101             verbose => $self->{verbose},
102             sample_value_column => $self->{sample_value_column});
103             $gsm->parse;
104            
105             push(@$gsm_list, $gsm);
106            
107             }
108             }
109            
110             my $n_platform = len($gpl_list);
111             my $n_sample = len($gsm_list);
112            
113             print "Series info:\n";
114             print " Accession: $accession\n";
115             print " Title:$title\n";
116             print " Platforms: $n_platform\n";
117             print " Samples: $n_sample\n";
118             print "\n";
119            
120             $self->set_meta( accession => $accession,
121             title => $title,
122             platform => $platform );
123             $self->set_list("GPL" => $gpl_list,
124             "GSM" => $gsm_list);
125            
126             Microarray::GEO::SOFT::_set_to_std_fh();
127            
128             return $self;
129             }
130            
131            
132             sub _back_to_last_line {
133            
134             my $fh = shift;
135             my $current_line_length = shift;
136            
137             my $position = tell($fh);
138             seek($fh, $position - $current_line_length - 2, 0);
139            
140             return $fh;
141             }
142            
143             sub set_list {
144            
145             my $self = shift;
146            
147             my $arg = {'GPL' => $self->list('GPL'),
148             'GSM' => $self->list('GSM'),
149             @_};
150            
151             $self->{"GPL_list"} = $arg->{'GPL'};
152             $self->{"GSM_list"} = $arg->{'GSM'};
153            
154             return $self;
155             }
156            
157             sub list {
158            
159             my $self = shift;
160             my $type = shift;
161            
162             if($type ne 'GPL' and $type ne 'GSM') {
163             croak "ERROR $type is not a valid paramter. Permitted argumetns are GPL and GSM.";
164             }
165            
166             return defined($self->{$type.'_list'}) ? $self->{$type.'_list'}
167             : undef ;
168            
169             }
170            
171             # override these method inherited from SUPER class
172             BEGIN {
173            
174             no strict 'refs';
175            
176             for my $accessor (qw(table rownames colnames colnames_explain matrix set_table)) {
177             *{$accessor} = sub {
178             croak "Method '".$accessor."' is not supported by ".__PACKAGE__." because a series can contain more than one platforms\n";
179             }
180             }
181             }
182            
183             # merge samples under same platform as a matrix
184             # this is what is called GDS
185             # since some series contain more than one platforms
186             # thus, this function returns a GDS object array reference
187             sub merge {
188            
189             my $self = shift;
190            
191             my $gpl_list = $self->platform;
192             my $gds_list;
193            
194             for(my $i = 0; $i < len($gpl_list); $i ++) {
195            
196             my $sample_list = $self->list("GSM");
197            
198             # list of GSMs with same platform
199             my $s = subset($sample_list, sub {$_[0]->platform eq $gpl_list->[$i]} );
200            
201             my $g = $self->_merge_gsm($s);
202            
203             push(@$gds_list, $g);
204             }
205            
206             return $gds_list;
207            
208             }
209            
210             sub _merge_gsm {
211            
212             my $self = shift;
213            
214             my $gsm_list = shift;
215            
216             Microarray::GEO::SOFT::_set_fh($self->{verbose});
217            
218             # check whether these samples share same platform
219             my $gpl_list = sapply($gsm_list, sub {$_[0]->platform});
220             if(len(unique($gpl_list)) != 1) {
221             croak "ERROR: Platform should be same\n";
222             }
223            
224             # virtual GDS has a long accession number
225             $GDS_MERGE ++;
226             my $accession = "GDS_merge_$GDS_MERGE"."_from_".$self->accession;
227             my $title = "merged from ".$self->accession." under ".$gpl_list->[0];
228             my $platform = $gpl_list->[0];
229             my $table_colnames;
230             my $table_colnames_explain;
231            
232             for(my $i = 0; $i < len($gsm_list); $i ++) {
233            
234             $table_colnames->[$i] = $gsm_list->[$i]->accession;
235             $table_colnames_explain->[$i] = $gsm_list->[$i]->title;
236            
237             }
238            
239             my $table_rownames = $gsm_list->[0]->rownames;
240            
241             my $table_matrix = [[]];
242             for(my $i = 0; $i < len($gsm_list); $i ++) {
243             for(my $j = 0; $j < len($table_rownames); $j ++) {
244             $table_matrix->[$j]->[$i] = $gsm_list->[$i]->matrix->[$j]->[0];
245             }
246             }
247            
248            
249             my $n_row = len($table_rownames);
250             my $n_col = len($table_colnames);
251            
252             print "Merge GSM into GDS:\n";
253             print " Accession: $accession\n";
254             print " Platform: $platform\n";
255             print " Title: $title\n";
256             print " Rows: $n_row\n";
257             print " Columns: $n_col\n";
258             print "\n";
259            
260             my $gds = Microarray::GEO::SOFT::GDS->new();
261             $gds->set_meta( accession => $accession,
262             title => $title,
263             platform => $platform );
264             $gds->set_table( rownames => $table_rownames,
265             colnames => $table_colnames,
266             colnames_explain => $table_colnames_explain,
267             matrix => $table_matrix );
268            
269             Microarray::GEO::SOFT::_set_to_std_fh();
270            
271             return $gds;
272             }
273            
274            
275             __END__