line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Bio::DOOP::Graphics::Feature; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
7
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
44
|
|
4
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
34
|
|
5
|
1
|
|
|
1
|
|
545
|
use GD; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 NAME |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
Bio::DOOP::Graphics::Feature - Graphical representation of the features |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 VERSION |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
Version 0.18 |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=cut |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our $VERSION = '0.18'; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 SYNOPSIS |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 DESCRIPTION |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
This object represents a picture that contains all the sequences and sequence features of a subset. |
24
|
|
|
|
|
|
|
The module is fast enough to use it in your CGI scripts. You can also use it to visualize |
25
|
|
|
|
|
|
|
the subset. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 AUTHOR |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
Tibor Nagy, Godollo, Hungary |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=head1 METHODS |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head2 create |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Creates a new picture. Later you can add your own graphical elements to it. |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
Arguments: Bio::DOOP::DBSQL object and subset primary id. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
Return type: Bio::DOOP::Graphics::Feature object |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
$picture = Bio::DOOP::Graphics::Feature->create($db,"1234"); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=cut |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub create { |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
my $self = {}; |
48
|
|
|
|
|
|
|
my $dummy = shift; |
49
|
|
|
|
|
|
|
my $db = shift; |
50
|
|
|
|
|
|
|
my $subset = shift; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
my @seqs = @{$subset->get_all_seqs}; |
53
|
|
|
|
|
|
|
my $height = ($#seqs+1) * 90 + 40; |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
my $width = $subset->get_cluster->get_promo_type + 20; |
56
|
|
|
|
|
|
|
my $image = new GD::Image($width,$height); # Create the image |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
$self->{IMAGE} = $image; |
59
|
|
|
|
|
|
|
$self->{DB} = $db; |
60
|
|
|
|
|
|
|
$self->{SEQS} = \@seqs; |
61
|
|
|
|
|
|
|
$self->{WIDTH} = $width; |
62
|
|
|
|
|
|
|
$self->{HEIGHT} = $height; |
63
|
|
|
|
|
|
|
$self->{POS} = 0; |
64
|
|
|
|
|
|
|
$self->{SUBSET_ID} = $subset->get_id; |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# This is the map of the image. It is useful for HTML image maps. |
67
|
|
|
|
|
|
|
# TODO : Add more types to this hash. |
68
|
|
|
|
|
|
|
$self->{MAP} = { |
69
|
|
|
|
|
|
|
motif => [], |
70
|
|
|
|
|
|
|
dbtss => [], |
71
|
|
|
|
|
|
|
utr => [] |
72
|
|
|
|
|
|
|
}; |
73
|
|
|
|
|
|
|
# The colormap of the object. |
74
|
|
|
|
|
|
|
$self->{COLOR} = { |
75
|
|
|
|
|
|
|
background => [200,200,200], |
76
|
|
|
|
|
|
|
label => [0,0,0], |
77
|
|
|
|
|
|
|
strip => [220,220,220], |
78
|
|
|
|
|
|
|
utr => [100,100,255], |
79
|
|
|
|
|
|
|
motif => [0,100,0], |
80
|
|
|
|
|
|
|
tss => [0,0,0], |
81
|
|
|
|
|
|
|
frame => [255,0,0], |
82
|
|
|
|
|
|
|
fuzzres => [0,0,255] |
83
|
|
|
|
|
|
|
}; |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
bless $self; |
86
|
|
|
|
|
|
|
return($self); |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=head2 add_color |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Add an RGB color to the specified element. |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
The available elements are the following : background, label, strip, utr, motif, tss, frame, fuzzres. |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
$image->add_color("background",200,200,200); |
96
|
|
|
|
|
|
|
$image->set_colors; |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=cut |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub add_color { |
101
|
|
|
|
|
|
|
my $self = shift; |
102
|
|
|
|
|
|
|
my $code = shift; |
103
|
|
|
|
|
|
|
my $r = shift; |
104
|
|
|
|
|
|
|
my $g = shift; |
105
|
|
|
|
|
|
|
my $b = shift; |
106
|
|
|
|
|
|
|
my @color; |
107
|
|
|
|
|
|
|
@color = ($r,$g,$b); |
108
|
|
|
|
|
|
|
$self->{COLOR}->{"$code"} = \@color; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=head2 set_colors |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Sets all colors. Allocate colors previously with add_color. Use this method only ONCE after you set |
114
|
|
|
|
|
|
|
all the colors. If you use it more than once, the results will be strange. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=cut |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub set_colors { |
119
|
|
|
|
|
|
|
my $self = shift; |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
my $r; |
122
|
|
|
|
|
|
|
my $g; |
123
|
|
|
|
|
|
|
my $b; |
124
|
|
|
|
|
|
|
($r,$g,$b) = @{$self->{COLOR}->{background}}; |
125
|
|
|
|
|
|
|
$self->{IMAGE}->colorAllocate($r,$g,$b); # Set the background color. |
126
|
|
|
|
|
|
|
($r,$g,$b) = @{$self->{COLOR}->{label}}; |
127
|
|
|
|
|
|
|
$self->{LABEL} = $self->{IMAGE}->colorAllocate($r,$g,$b); # Set the label color. |
128
|
|
|
|
|
|
|
($r,$g,$b) = @{$self->{COLOR}->{utr}}; |
129
|
|
|
|
|
|
|
$self->{UTR} = $self->{IMAGE}->colorAllocate($r,$g,$b); # Set the UTR color. |
130
|
|
|
|
|
|
|
($r,$g,$b) = @{$self->{COLOR}->{motif}}; |
131
|
|
|
|
|
|
|
$self->{MOTIFCOLOR} = $self->{IMAGE}->colorAllocate($r,$g,$b); # Set the motif color. |
132
|
|
|
|
|
|
|
($r,$g,$b) = @{$self->{COLOR}->{tss}}; |
133
|
|
|
|
|
|
|
$self->{TSSCOLOR} = $self->{IMAGE}->colorAllocate($r,$g,$b); # Set the tss color. |
134
|
|
|
|
|
|
|
($r,$g,$b) = @{$self->{COLOR}->{strip}}; |
135
|
|
|
|
|
|
|
$self->{STRIP} = $self->{IMAGE}->colorAllocate($r,$g,$b); # Set the strip color. |
136
|
|
|
|
|
|
|
($r,$g,$b) = @{$self->{COLOR}->{frame}}; |
137
|
|
|
|
|
|
|
$self->{FRAME} = $self->{IMAGE}->colorAllocate($r,$g,$b); # Set the frame color. |
138
|
|
|
|
|
|
|
($r,$g,$b) = @{$self->{COLOR}->{fuzzres}}; |
139
|
|
|
|
|
|
|
$self->{FUZZRES} = $self->{IMAGE}->colorAllocate($r,$g,$b); # Set the fuzznuc result color. |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=head2 add_scale |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
Draws the scale on the picture. |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=cut |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
sub add_scale { |
149
|
|
|
|
|
|
|
my $self = shift; |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
my $color = $self->{LABEL}; |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# Draw the main axis. |
154
|
|
|
|
|
|
|
$self->{IMAGE}->line(10,5,$self->{WIDTH}-10,5,$color); |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
# Draw the scales. |
157
|
|
|
|
|
|
|
my $i; |
158
|
|
|
|
|
|
|
for ($i = 20; $i < $self->{WIDTH}-10; $i += 10){ |
159
|
|
|
|
|
|
|
if( ($i / 100) == int($i / 100) ) { |
160
|
|
|
|
|
|
|
$self->{IMAGE}->line($i+10,0,$i+10,10,$color); # Large scale. |
161
|
|
|
|
|
|
|
my $str = ($self->{WIDTH} - 20 - $i) * -1; # The scale label. |
162
|
|
|
|
|
|
|
my $posx = $i - (length($str)/2)*6 + 10; # Nice label positioning. |
163
|
|
|
|
|
|
|
$self->{IMAGE}->string(gdSmallFont,$posx,10,$str,$color); |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
else { |
166
|
|
|
|
|
|
|
$self->{IMAGE}->line($i+10,3,$i+10,7,$color); # Small scale. |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# Draw the arrow. |
171
|
|
|
|
|
|
|
my $arrow = new GD::Polygon; |
172
|
|
|
|
|
|
|
$arrow->addPt(9,5); |
173
|
|
|
|
|
|
|
$arrow->addPt(15,2); |
174
|
|
|
|
|
|
|
$arrow->addPt(15,8); |
175
|
|
|
|
|
|
|
$self->{IMAGE}->filledPolygon($arrow,$color); |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=head2 add_bck_lines |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Draws scale lines through the whole image background. |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=cut |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub add_bck_lines { |
185
|
|
|
|
|
|
|
my $self = shift; |
186
|
|
|
|
|
|
|
my $color = $self->{STRIP}; |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
my $i; |
189
|
|
|
|
|
|
|
for ($i = 20; $i < $self->{WIDTH}-10; $i += 10){ |
190
|
|
|
|
|
|
|
$self->{IMAGE}->line($i,0,$i,$self->{HEIGHT},$color); |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=head2 add_seq |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
Draws a specified sequence on the picture. This is internal code, do not use it directly. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=cut |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub add_seq { |
202
|
|
|
|
|
|
|
my $self = shift; |
203
|
|
|
|
|
|
|
my $index = shift; |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
my $seq = $self->{SEQS}->[$index]; |
206
|
|
|
|
|
|
|
my $len = $seq->get_length; |
207
|
|
|
|
|
|
|
my $x1 = $self->{WIDTH} - 10; |
208
|
|
|
|
|
|
|
my $x2 = $x1-$len; |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# Draw the seq line. |
211
|
|
|
|
|
|
|
$self->{IMAGE}->line($x2, $index*90+40, $x1, $index*90+40, $self->{LABEL}); |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# Draw UTR. |
214
|
|
|
|
|
|
|
my $utrlen = $seq->get_utr_length; |
215
|
|
|
|
|
|
|
if ($utrlen){ |
216
|
|
|
|
|
|
|
my $utrlen2 = $x1 - $utrlen; |
217
|
|
|
|
|
|
|
if ($utrlen2 < 10){$utrlen2 = 10} |
218
|
|
|
|
|
|
|
$self->{IMAGE}->filledRectangle($utrlen2, $index*90+35, $x1, $index*90+45, $self->{UTR}); |
219
|
|
|
|
|
|
|
$self->{IMAGE}->string(gdTinyFont, $utrlen2, $index*90+36, "UTR ".$utrlen." bp", $self->{LABEL}); |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# Print the sequence name and length. |
223
|
|
|
|
|
|
|
my $text = $seq->get_taxon_name . " " . $len . " bp"; |
224
|
|
|
|
|
|
|
$self->{IMAGE}->string(gdSmallFont, $x2, $index*90+22, $text, $self->{LABEL}); |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# Draw features. |
227
|
|
|
|
|
|
|
my $features = $seq->get_all_seq_features; |
228
|
|
|
|
|
|
|
if ($features == -1){ return } |
229
|
|
|
|
|
|
|
my $motif_Y = $index*90 + 60; |
230
|
|
|
|
|
|
|
my $shift_factor = 0; |
231
|
|
|
|
|
|
|
my $motif_count; |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
my $min_motif_id; |
234
|
|
|
|
|
|
|
for my $feat (@$features){ |
235
|
|
|
|
|
|
|
if( ($feat->get_type eq "con") && ($feat->get_subsetid eq $self->{SUBSET_ID})){ |
236
|
|
|
|
|
|
|
$min_motif_id = $feat->get_motifid; |
237
|
|
|
|
|
|
|
last; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
for my $feat (@$features){ |
241
|
|
|
|
|
|
|
# Draw motifs. |
242
|
|
|
|
|
|
|
if( ($feat->get_type eq "con") && ($feat->get_subsetid eq $self->{SUBSET_ID})){ |
243
|
|
|
|
|
|
|
$motif_count = $feat->get_motifid - $min_motif_id + 1; |
244
|
|
|
|
|
|
|
# This code helps to make three rows for the motifs. |
245
|
|
|
|
|
|
|
my $label_length = (length($motif_count) + 1) * 6; # Label width with gdSmallFont |
246
|
|
|
|
|
|
|
my %motif_element = ($feat->get_motifid => [ $x1 - $len + $feat->get_start, |
247
|
|
|
|
|
|
|
$motif_Y + $shift_factor, |
248
|
|
|
|
|
|
|
$x1 - $len + $feat->get_end, |
249
|
|
|
|
|
|
|
$motif_Y + $shift_factor + 5 ]); |
250
|
|
|
|
|
|
|
$self->{IMAGE}->filledRectangle($x1 - $len + $feat->get_start, |
251
|
|
|
|
|
|
|
$motif_Y + $shift_factor, |
252
|
|
|
|
|
|
|
$x1 - $len + $feat->get_end, |
253
|
|
|
|
|
|
|
$motif_Y + $shift_factor + 5, |
254
|
|
|
|
|
|
|
$self->{MOTIFCOLOR}); |
255
|
|
|
|
|
|
|
$self->{IMAGE}->string(gdSmallFont, $x1 - $len + $feat->get_start, $motif_Y+$shift_factor+6, "m$motif_count", $self->{LABEL}); |
256
|
|
|
|
|
|
|
push @{$self->{MAP}->{"motif"}},\%motif_element; |
257
|
|
|
|
|
|
|
if ($feat->length > $label_length){ |
258
|
|
|
|
|
|
|
$shift_factor = 0; |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
elsif( ($feat->length < $label_length) && ($shift_factor < 36)){ |
261
|
|
|
|
|
|
|
$shift_factor += 18; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
else { |
264
|
|
|
|
|
|
|
$shift_factor = 0; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
# Draw tss. |
269
|
|
|
|
|
|
|
if( ($feat->get_type eq "tss")){ |
270
|
|
|
|
|
|
|
my $motif_Y = $index*90 + 40; |
271
|
|
|
|
|
|
|
my $tssfeat = new GD::Polygon; |
272
|
|
|
|
|
|
|
$tssfeat->addPt($x1-$len+$feat->get_start,$motif_Y); |
273
|
|
|
|
|
|
|
$tssfeat->addPt($x1-$len+$feat->get_start-5,$motif_Y+10); |
274
|
|
|
|
|
|
|
$tssfeat->addPt($x1-$len+$feat->get_start+5,$motif_Y+10); |
275
|
|
|
|
|
|
|
$self->{IMAGE}->filledPolygon($tssfeat,$self->{TSSCOLOR}); |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=head2 add_all_seq |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
Draws all sequences of the subset. The first one is the reference species. |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=cut |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
sub add_all_seq { |
289
|
|
|
|
|
|
|
my $self = shift; |
290
|
|
|
|
|
|
|
my @seqs = @{$self->{SEQS}}; |
291
|
|
|
|
|
|
|
my $i; |
292
|
|
|
|
|
|
|
for($i = 0; $i < $#seqs+1; $i++){ |
293
|
|
|
|
|
|
|
$self->add_seq($i); |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=head2 get_png |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
Returns the png image. Use this when you finish the work and would like to see the result. |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
open IMAGE,">picture.png"; |
302
|
|
|
|
|
|
|
binmode IMAGE; |
303
|
|
|
|
|
|
|
print IMAGE $image->get_png; |
304
|
|
|
|
|
|
|
close IMAGE; |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=cut |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub get_png { |
309
|
|
|
|
|
|
|
my $self = shift; |
310
|
|
|
|
|
|
|
return($self->{IMAGE}->png); |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=head2 get_image |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
Returns the drawn image pointer. Useful for adding your own GD methods for unique picture manipulation. |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=cut |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
sub get_image { |
321
|
|
|
|
|
|
|
my $self = shift; |
322
|
|
|
|
|
|
|
return($self->{IMAGE}); |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=head2 get_map |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
Returns a hash of arrays of hash of arrays reference that contains the image map information. |
328
|
|
|
|
|
|
|
Here is a real world example of how to handle this method : |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
use Bio::DOOP::DOOP; |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
$db = Bio::DOOP::DBSQL->connect($user,$passwd,"doop-plant-1_5","localhost"); |
333
|
|
|
|
|
|
|
$cluster = Bio::DOOP::Cluster->new($db,'81001110','500'); |
334
|
|
|
|
|
|
|
$image = Bio::DOOP::Graphics::Feature->create($db,$cluster); |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
for $motif (@{$image->get_map->{motif}}){ |
337
|
|
|
|
|
|
|
for $motif_id (keys %{$motif}){ |
338
|
|
|
|
|
|
|
@coords = @{$$motif{$motif_id}}; |
339
|
|
|
|
|
|
|
# Print out the motif primary id and the four coordinates in the picture |
340
|
|
|
|
|
|
|
# id x1 y1 x2 y2 |
341
|
|
|
|
|
|
|
print "$motif_id $coords[0] $coords[1] $coords[2] $coords[3]\n"; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
It is somewhat difficult, but if you are familiar with references and nested data structures, you |
346
|
|
|
|
|
|
|
will understand it. |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=cut |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
sub get_map { |
351
|
|
|
|
|
|
|
my $self = shift; |
352
|
|
|
|
|
|
|
return($self->{MAP}); |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
=head2 get_motif_map |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
Returns only the arrayref of motif hashes. |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=cut |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
sub get_motif_map { |
362
|
|
|
|
|
|
|
my $self = shift; |
363
|
|
|
|
|
|
|
return($self->{MAP}->{motif}); |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
=head2 get_motif_id_by_coord |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
With this, you can get a motif id, if you specify the coordinates of a pixel. |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
$motif_id = $image->get_motif_id_by_coord(100,200); |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=cut |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
sub get_motif_id_by_coord { |
375
|
|
|
|
|
|
|
my $self = shift; |
376
|
|
|
|
|
|
|
my $x = shift; |
377
|
|
|
|
|
|
|
my $y = shift; |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
for my $motif (@{$self->get_motif_map}){ |
380
|
|
|
|
|
|
|
for my $motif_id (keys %{$motif}){ |
381
|
|
|
|
|
|
|
my @coords = @{$$motif{$motif_id}}; |
382
|
|
|
|
|
|
|
if(($x > $coords[0]) && ($x < $coords[2]) && |
383
|
|
|
|
|
|
|
($y > $coords[1]) && ($y < $coords[3])) { |
384
|
|
|
|
|
|
|
return($motif_id); |
385
|
|
|
|
|
|
|
} |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
return(0); |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
=head2 draw_motif_frame |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
This method draws a frame around a given motif. |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
Arguments: motif primary id |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
Return type: 0 if success, -1 if the given motif id is not in the picture. |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
$image->draw_motif_frame($motifid); |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=cut |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
sub draw_motif_frame { |
404
|
|
|
|
|
|
|
my $self = shift; |
405
|
|
|
|
|
|
|
my $motifid = shift; |
406
|
|
|
|
|
|
|
my $actualid; |
407
|
|
|
|
|
|
|
my $have = 0; |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
for my $motif (@{$self->{MAP}->{motif}}){ |
410
|
|
|
|
|
|
|
($actualid) = keys %{$motif}; |
411
|
|
|
|
|
|
|
if ($actualid == $motifid){ |
412
|
|
|
|
|
|
|
my @choords = @{$$motif{$actualid}}; |
413
|
|
|
|
|
|
|
$have = 1; |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
# Draw the frame |
416
|
|
|
|
|
|
|
$self->{IMAGE}->rectangle($choords[0]-3,$choords[1]-3,$choords[2]+3,$choords[3]+3,$self->{FRAME}); |
417
|
|
|
|
|
|
|
$self->{IMAGE}->rectangle($choords[0]-2,$choords[1]-2,$choords[2]+2,$choords[3]+2,$self->{FRAME}); |
418
|
|
|
|
|
|
|
} |
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
if ($have == 0){ |
422
|
|
|
|
|
|
|
return(-1) |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
else{ |
425
|
|
|
|
|
|
|
return(0) |
426
|
|
|
|
|
|
|
} |
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=head2 draw_fuzz_result |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
You can draw the fuzznuc result on the picture with this method. |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
Arguments : sequence primary id, start position, end position |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
To set drawing color, you can use the setcolor("fuzzres",$r,$g,$b) method. |
436
|
|
|
|
|
|
|
The method shows the orientation. The arrow always points to the start position. |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
Return value : 0 if success, -1 if the given sequence id can't be found. |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
$image->draw_fuzz_result(357,20,70); |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=cut |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
sub draw_fuzz_result { |
445
|
|
|
|
|
|
|
my $self = shift; |
446
|
|
|
|
|
|
|
my $seqid = shift; |
447
|
|
|
|
|
|
|
my $start = shift; |
448
|
|
|
|
|
|
|
my $end = shift; |
449
|
|
|
|
|
|
|
my $index = 0; |
450
|
|
|
|
|
|
|
my $ori; |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
for my $i (@{$self->{SEQS}}){ |
453
|
|
|
|
|
|
|
if ($i->get_id eq $seqid){ |
454
|
|
|
|
|
|
|
my $y = $index*90+50; |
455
|
|
|
|
|
|
|
my $len = $self->{WIDTH} - 10 - $i->get_length; |
456
|
|
|
|
|
|
|
my $x1 = $len + $start; |
457
|
|
|
|
|
|
|
my $x2 = $len + $end; |
458
|
|
|
|
|
|
|
my $poly = new GD::Polygon; |
459
|
|
|
|
|
|
|
if(($end - $start) > 0){ $ori = -1 }else{ $ori = 1 } |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
$poly->addPt($start, $y); |
462
|
|
|
|
|
|
|
$poly->addPt($start - 5*$ori, $y - 5); |
463
|
|
|
|
|
|
|
$poly->addPt($start - 5*$ori, $y - 2); |
464
|
|
|
|
|
|
|
$poly->addPt($end, $y - 2); |
465
|
|
|
|
|
|
|
$poly->addPt($end, $y + 3); |
466
|
|
|
|
|
|
|
$poly->addPt($start - 5*$ori, $y + 3); |
467
|
|
|
|
|
|
|
$poly->addPt($start - 5*$ori, $y + 5); |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
$self->{IMAGE}->filledPolygon($poly,$self->{FUZZRES}); |
470
|
|
|
|
|
|
|
return(0); |
471
|
|
|
|
|
|
|
} |
472
|
|
|
|
|
|
|
$index++; |
473
|
|
|
|
|
|
|
} |
474
|
|
|
|
|
|
|
return(-1); |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
1; |