our
$VERSION
=
'0.17'
;
sub
create {
my
$self
= {};
my
$dummy
=
shift
;
my
$db
=
shift
;
my
$subset
=
shift
;
my
@seqs
= @{
$subset
->get_all_seqs};
my
$height
= (
$#seqs
+1) * 90 + 40;
my
$width
=
$subset
->get_cluster->get_promo_type + 20;
my
$image
= new GD::Image(
$width
,
$height
);
$self
->{IMAGE} =
$image
;
$self
->{DB} =
$db
;
$self
->{SEQS} = \
@seqs
;
$self
->{WIDTH} =
$width
;
$self
->{HEIGHT} =
$height
;
$self
->{POS} = 0;
$self
->{SUBSET_ID} =
$subset
->get_id;
$self
->{MAP} = {
motif
=> [],
dbtss
=> [],
utr
=> []
};
$self
->{COLOR} = {
background
=> [200,200,200],
label
=> [0,0,0],
strip
=> [220,220,220],
utr
=> [100,100,255],
motif
=> [0,100,0],
tss
=> [0,0,0],
frame
=> [255,0,0],
fuzzres
=> [0,0,255]
};
bless
$self
;
return
(
$self
);
}
sub
add_color {
my
$self
=
shift
;
my
$code
=
shift
;
my
$r
=
shift
;
my
$g
=
shift
;
my
$b
=
shift
;
my
@color
;
@color
= (
$r
,
$g
,
$b
);
$self
->{COLOR}->{
"$code"
} = \
@color
;
}
sub
set_colors {
my
$self
=
shift
;
my
$r
;
my
$g
;
my
$b
;
(
$r
,
$g
,
$b
) = @{
$self
->{COLOR}->{background}};
$self
->{IMAGE}->colorAllocate(
$r
,
$g
,
$b
);
(
$r
,
$g
,
$b
) = @{
$self
->{COLOR}->{label}};
$self
->{LABEL} =
$self
->{IMAGE}->colorAllocate(
$r
,
$g
,
$b
);
(
$r
,
$g
,
$b
) = @{
$self
->{COLOR}->{utr}};
$self
->{UTR} =
$self
->{IMAGE}->colorAllocate(
$r
,
$g
,
$b
);
(
$r
,
$g
,
$b
) = @{
$self
->{COLOR}->{motif}};
$self
->{MOTIFCOLOR} =
$self
->{IMAGE}->colorAllocate(
$r
,
$g
,
$b
);
(
$r
,
$g
,
$b
) = @{
$self
->{COLOR}->{tss}};
$self
->{TSSCOLOR} =
$self
->{IMAGE}->colorAllocate(
$r
,
$g
,
$b
);
(
$r
,
$g
,
$b
) = @{
$self
->{COLOR}->{strip}};
$self
->{STRIP} =
$self
->{IMAGE}->colorAllocate(
$r
,
$g
,
$b
);
(
$r
,
$g
,
$b
) = @{
$self
->{COLOR}->{frame}};
$self
->{FRAME} =
$self
->{IMAGE}->colorAllocate(
$r
,
$g
,
$b
);
(
$r
,
$g
,
$b
) = @{
$self
->{COLOR}->{fuzzres}};
$self
->{FUZZRES} =
$self
->{IMAGE}->colorAllocate(
$r
,
$g
,
$b
);
}
sub
add_scale {
my
$self
=
shift
;
my
$color
=
$self
->{LABEL};
$self
->{IMAGE}->line(10,5,
$self
->{WIDTH}-10,5,
$color
);
my
$i
;
for
(
$i
= 20;
$i
<
$self
->{WIDTH}-10;
$i
+= 10){
if
( (
$i
/ 100) ==
int
(
$i
/ 100) ) {
$self
->{IMAGE}->line(
$i
+10,0,
$i
+10,10,
$color
);
my
$str
= (
$self
->{WIDTH} - 20 -
$i
) * -1;
my
$posx
=
$i
- (
length
(
$str
)/2)*6 + 10;
$self
->{IMAGE}->string(gdSmallFont,
$posx
,10,
$str
,
$color
);
}
else
{
$self
->{IMAGE}->line(
$i
+10,3,
$i
+10,7,
$color
);
}
}
my
$arrow
= new GD::Polygon;
$arrow
->addPt(9,5);
$arrow
->addPt(15,2);
$arrow
->addPt(15,8);
$self
->{IMAGE}->filledPolygon(
$arrow
,
$color
);
}
sub
add_bck_lines {
my
$self
=
shift
;
my
$color
=
$self
->{STRIP};
my
$i
;
for
(
$i
= 20;
$i
<
$self
->{WIDTH}-10;
$i
+= 10){
$self
->{IMAGE}->line(
$i
,0,
$i
,
$self
->{HEIGHT},
$color
);
}
}
sub
add_seq {
my
$self
=
shift
;
my
$index
=
shift
;
my
$seq
=
$self
->{SEQS}->[
$index
];
my
$len
=
$seq
->get_length;
my
$x1
=
$self
->{WIDTH} - 10;
my
$x2
=
$x1
-
$len
;
$self
->{IMAGE}->line(
$x2
,
$index
*90+40,
$x1
,
$index
*90+40,
$self
->{LABEL});
my
$utrlen
=
$seq
->get_utr_length;
if
(
$utrlen
){
my
$utrlen2
=
$x1
-
$utrlen
;
if
(
$utrlen2
< 10){
$utrlen2
= 10}
$self
->{IMAGE}->filledRectangle(
$utrlen2
,
$index
*90+35,
$x1
,
$index
*90+45,
$self
->{UTR});
$self
->{IMAGE}->string(gdTinyFont,
$utrlen2
,
$index
*90+36,
"UTR "
.
$utrlen
.
" bp"
,
$self
->{LABEL});
}
my
$text
=
$seq
->get_taxon_name .
" "
.
$len
.
" bp"
;
$self
->{IMAGE}->string(gdSmallFont,
$x2
,
$index
*90+22,
$text
,
$self
->{LABEL});
my
$features
=
$seq
->get_all_seq_features;
if
(
$features
== -1){
return
}
my
$motif_Y
=
$index
*90 + 60;
my
$shift_factor
= 0;
my
$motif_count
;
my
$min_motif_id
;
for
my
$feat
(
@$features
){
if
( (
$feat
->get_type eq
"con"
) && (
$feat
->get_subsetid eq
$self
->{SUBSET_ID})){
$min_motif_id
=
$feat
->get_motifid;
last
;
}
}
for
my
$feat
(
@$features
){
if
( (
$feat
->get_type eq
"con"
) && (
$feat
->get_subsetid eq
$self
->{SUBSET_ID})){
$motif_count
=
$feat
->get_motifid -
$min_motif_id
+ 1;
my
$label_length
= (
length
(
$motif_count
) + 1) * 6;
my
%motif_element
= (
$feat
->
get_motifid
=> [
$x1
-
$len
+
$feat
->get_start,
$motif_Y
+
$shift_factor
,
$x1
-
$len
+
$feat
->get_end,
$motif_Y
+
$shift_factor
+ 5 ]);
$self
->{IMAGE}->filledRectangle(
$x1
-
$len
+
$feat
->get_start,
$motif_Y
+
$shift_factor
,
$x1
-
$len
+
$feat
->get_end,
$motif_Y
+
$shift_factor
+ 5,
$self
->{MOTIFCOLOR});
$self
->{IMAGE}->string(gdSmallFont,
$x1
-
$len
+
$feat
->get_start,
$motif_Y
+
$shift_factor
+6,
"m$motif_count"
,
$self
->{LABEL});
push
@{
$self
->{MAP}->{
"motif"
}},\
%motif_element
;
if
(
$feat
->
length
>
$label_length
){
$shift_factor
= 0;
}
elsif
( (
$feat
->
length
<
$label_length
) && (
$shift_factor
< 36)){
$shift_factor
+= 18;
}
else
{
$shift_factor
= 0;
}
}
if
( (
$feat
->get_type eq
"tss"
)){
my
$motif_Y
=
$index
*90 + 40;
my
$tssfeat
= new GD::Polygon;
$tssfeat
->addPt(
$x1
-
$len
+
$feat
->get_start,
$motif_Y
);
$tssfeat
->addPt(
$x1
-
$len
+
$feat
->get_start-5,
$motif_Y
+10);
$tssfeat
->addPt(
$x1
-
$len
+
$feat
->get_start+5,
$motif_Y
+10);
$self
->{IMAGE}->filledPolygon(
$tssfeat
,
$self
->{TSSCOLOR});
}
}
}
sub
add_all_seq {
my
$self
=
shift
;
my
@seqs
= @{
$self
->{SEQS}};
my
$i
;
for
(
$i
= 0;
$i
<
$#seqs
+1;
$i
++){
$self
->add_seq(
$i
);
}
}
sub
get_png {
my
$self
=
shift
;
return
(
$self
->{IMAGE}->png);
}
sub
get_image {
my
$self
=
shift
;
return
(
$self
->{IMAGE});
}
sub
get_map {
my
$self
=
shift
;
return
(
$self
->{MAP});
}
sub
get_motif_map {
my
$self
=
shift
;
return
(
$self
->{MAP}->{motif});
}
sub
get_motif_id_by_coord {
my
$self
=
shift
;
my
$x
=
shift
;
my
$y
=
shift
;
for
my
$motif
(@{
$self
->get_motif_map}){
for
my
$motif_id
(
keys
%{
$motif
}){
my
@coords
= @{
$$motif
{
$motif_id
}};
if
((
$x
>
$coords
[0]) && (
$x
<
$coords
[2]) &&
(
$y
>
$coords
[1]) && (
$y
<
$coords
[3])) {
return
(
$motif_id
);
}
}
}
return
(0);
}
sub
draw_motif_frame {
my
$self
=
shift
;
my
$motifid
=
shift
;
my
$actualid
;
my
$have
= 0;
for
my
$motif
(@{
$self
->{MAP}->{motif}}){
(
$actualid
) =
keys
%{
$motif
};
if
(
$actualid
==
$motifid
){
my
@choords
= @{
$$motif
{
$actualid
}};
$have
= 1;
$self
->{IMAGE}->rectangle(
$choords
[0]-3,
$choords
[1]-3,
$choords
[2]+3,
$choords
[3]+3,
$self
->{FRAME});
$self
->{IMAGE}->rectangle(
$choords
[0]-2,
$choords
[1]-2,
$choords
[2]+2,
$choords
[3]+2,
$self
->{FRAME});
}
}
if
(
$have
== 0){
return
(-1)
}
else
{
return
(0)
}
}
sub
draw_fuzz_result {
my
$self
=
shift
;
my
$seqid
=
shift
;
my
$start
=
shift
;
my
$end
=
shift
;
my
$index
= 0;
my
$ori
;
for
my
$i
(@{
$self
->{SEQS}}){
if
(
$i
->get_id eq
$seqid
){
my
$y
=
$index
*90+50;
my
$len
=
$self
->{WIDTH} - 10 -
$i
->get_length;
my
$x1
=
$len
+
$start
;
my
$x2
=
$len
+
$end
;
my
$poly
= new GD::Polygon;
if
((
$end
-
$start
) > 0){
$ori
= -1 }
else
{
$ori
= 1 }
$poly
->addPt(
$start
,
$y
);
$poly
->addPt(
$start
- 5
*$ori
,
$y
- 5);
$poly
->addPt(
$start
- 5
*$ori
,
$y
- 2);
$poly
->addPt(
$end
,
$y
- 2);
$poly
->addPt(
$end
,
$y
+ 3);
$poly
->addPt(
$start
- 5
*$ori
,
$y
+ 3);
$poly
->addPt(
$start
- 5
*$ori
,
$y
+ 5);
$self
->{IMAGE}->filledPolygon(
$poly
,
$self
->{FUZZRES});
return
(0);
}
$index
++;
}
return
(-1);
}
1;