Added to perldoc instructions about the use of the environment variables.
[cxgn-corelibs.git] / lib / CXGN / Cview / Chromosome / PachyteneIdiogram.pm
blob1eea10b0fa0d7897f7fe1113b792573cbb75bebe
5 =head1 NAME
7 CXGN::Cview::PachyteneIdiogram - a class for drawing a schematic representation of chromosomes in the pachytene phase.
9 =head1 DESCRIPTION
11 This object renders a pachytene idiogram, which are currently only defined for each of the 12 tomato chromosomes. It inherits from CXGN::Cview::chromosome. Inherits from L<CXGN::Cview::Chromosome>. The description of the tomato pachytene chromosomes is available in a flat file version, and there is a function in L<CXGN::Cview::Cview_data_adatper> to load it.
13 =head1 SEE ALSO
15 See also the documentation in L<CXGN::Cview>.
17 =head1 AUTHOR(S)
19 Lukas Mueller (lam87@cornell.edu)
21 =head1 FUNCTIONS
24 =cut
26 use strict;
28 use CXGN::Cview::Chromosome;
29 use CXGN::Cview::Ruler::PachyteneRuler;
31 package CXGN::Cview::Chromosome::PachyteneIdiogram;
33 use base qw( CXGN::Cview::Chromosome );
35 =head2 function new()
37 Constructor. Takes the same parameters as CXGN::Cview::Chromosome::new().
39 =cut
41 sub new {
42 my $class = shift;
43 my $self = $class->SUPER::new(@_);
44 $self->set_outline_color(0,0,0);
45 $self->set_color(255, 255, 255);
46 $self->set_hilite_color(50, 255, 50);
47 $self->set_width(10);
48 $self->set_vertical_offset_top_edge();
49 $self->{curved_height} = 8;
51 $self->{feature_color} = {
52 short_arm => "100 ,100,250",
53 long_arm => "100,100,250",
54 heterochromatin => "75,75,250",
55 telomere => "25,75,200",
56 satellite => "75,75,250",
58 $self->{feature_width} = {
59 short_arm => 6,
60 long_arm => 6,
61 heterochromatin => 10,
62 telomere => 8,
63 satellite => 8,
66 @{$self->{render_order}} = (
67 "short_arm",
68 "long_arm",
69 "heterochromatin",
70 "telomere",
71 "satellite"
74 my $r = CXGN::Cview::Ruler::PachyteneRuler->new();
75 $self->set_ruler($r);
76 return $self;
79 =head2 function add_feature()
81 Add a feature to the pachytene idiogram. Allowed feature types are restricted to:
82 telomere, satellite, long_arm, short_arm etc. This is used to construct the
83 image representation of the idiogram.
85 Note: feature types are rendered in a specific order. See new().
87 =cut
89 sub add_feature {
90 my $self = shift;
91 my $type = shift;
92 my $start_coord = shift;
93 my $end_coord = shift;
95 #print STDERR "Cview::pchytene::add_feature: Adding feature $type, $start_coord, $end_coord\n";
97 if (!exists($self->{feature_color}->{$type})) {
98 print STDERR "Cview.pm [pachytene_idiogram]: Unknown feature type: $type\n";
100 if ($type eq "short_arm") {
101 $self->set_short_arm_length(abs($end_coord-$start_coord));
102 #print STDERR "short arm length: $self->{short_arm_length}\n";
104 if ($type eq "long_arm") {
105 $self->set_long_arm_length(abs($end_coord-$start_coord));
108 my %h = ( type => $type,
109 start_coord => $start_coord,
110 end_coord => $end_coord,
113 push @{$self->{features}}, \%h;
117 # Note: _calculate_scaling_factor is overridden to account for the differences in the representation
118 # of a pachytene chromosome.
120 sub _calculate_scaling_factor {
121 my $self = shift;
122 $self->{scaling_factor} = ($self->get_height()/($self->get_short_arm_length()+$self->get_long_arm_length()));
123 #print STDERR "pachytene_idiogram: _calculate_scaling_factor::scaling factor: $self->{scaling_factor}\n";
126 =head2 function mapunits2pixels()
128 Override the chromosome mapunits2pixels to reflect the different unit and representation of this map.
130 =cut
132 sub mapunits2pixels {
133 my $self = shift;
134 my $percent = shift;
135 my $pixels = 0;
136 # note: give the pixels from the vertical_offset (centromere) to the percent marker positioin
137 my $shortarmratio = $self->get_short_arm_length()/($self->get_short_arm_length()+$self->get_long_arm_length());
138 my $longarmratio = 1-$shortarmratio;
139 if ($percent < 0) {
140 $pixels = $self->get_height() * $shortarmratio * $percent / 100;
141 # the result is a negative number, always measured from the centromere
143 else {
144 $pixels = $self->get_height()* $longarmratio * $percent / 100;
146 return $pixels;
149 =head2 function get_short_arm_length()
151 Synopsis:
152 Arguments: None
153 Returns: the length of the short arm in arbitrary units.
154 Side effects:
155 Description:
157 =cut
159 sub get_short_arm_length {
160 my $self=shift;
161 return $self->{short_arm_length};
164 =head2 function set_short_arm_length()
166 Synopsis:
167 Arguments:
168 Returns:
169 Side effects:
170 Description:
172 =cut
174 sub set_short_arm_length {
175 my $self=shift;
176 $self->{short_arm_length}=shift;
179 =head2 function get_long_arm_length()
181 Synopsis:
182 Arguments:
183 Returns: The short arm length in arbitrary units.
184 Side effects:
185 Description:
187 =cut
189 sub get_long_arm_length {
190 my $self=shift;
191 return $self->{long_arm_length};
194 =head2 function set_long_arm_length()
196 Synopsis:
197 Arguments:
198 Returns:
199 Side effects:
200 Description:
202 =cut
204 sub set_long_arm_length {
205 my $self=shift;
206 $self->{long_arm_length}=shift;
211 sub draw_chromosome {
212 my $self =shift;
213 #print STDERR "Rendering the PACHYTENE business...\n";
214 my $image = shift;
215 $self->_calculate_scaling_factor();
217 # calculate ruler properties...
219 $self->get_ruler()->set_height($self->get_height());
220 $self->get_ruler()->set_short_arm_ruler_pixels($self->get_short_arm_length()*$self->get_scaling_factor());
221 $self->get_ruler()->set_long_arm_ruler_pixels($self->get_long_arm_length()*$self->get_scaling_factor());
223 #$image -> line(0, $self->get_vertical_offset(), 100, $self->get_vertical_offset(), $image->colorResolve(0, 0, 0));
226 # features have to be rendered in the correct order -- first the arms and then the rest.
227 foreach my $type (@{$self->{render_order}}) {
228 foreach my $f (@{$self->{features}}) {
229 if ($f->{type} eq $type) {
230 #print STDERR "Rendering feature $f->{type}, $f->{start_coord}, $f->{end_coord} | Color: $self->{feature_color}->{$f->{type}}\n";
231 if (!exists($self->{feature_color}->{$f->{type}})) { print STDERR "$f->{type} HAS NO ASSOCIATED FEATURE COLOR!\n";}
232 my ($red, $green, $blue) = split /\,/, $self->{feature_color}->{$f->{type}};
233 my $color = $image-> colorResolve($red, $green,$blue);
235 my $x = $self->get_horizontal_offset() - $self->{feature_width}->{$f->{type}}/2;
236 my $y = $self->get_vertical_offset()+$f->{start_coord}*$self->get_scaling_factor();
237 my $lx = $self->get_horizontal_offset()+ $self->{feature_width}->{$f->{type}}/2;
238 my $ly = $self->get_vertical_offset()+$f->{end_coord}*$self->get_scaling_factor();
240 #print STDERR "Featurescreencoords: $f->{type}, $x, $y, $lx, $ly, $color\n";
241 # gd can't draw a filled rectangle with $y > $ly, so swap if that's the case.
242 if ($y > $ly) { my $z=$y; $y=$ly; $ly=$z; }
243 $image -> filledRectangle(
244 $x,
245 $y,
246 $lx,
247 $ly,
248 $color);
253 $self->draw_centromere($image);
255 $self->draw_caption($image);
258 sub render_markers {
259 my $self = shift;
260 my $image = shift;
262 my @m = $self->get_markers();
263 foreach my $m (@m) {
264 #print STDERR "Drawing marker ".$self->get_name()."\n";
265 $m -> render($image);
270 =head2 draw_centromere
272 Usage:
273 Desc:
274 Ret:
275 Args:
276 Side Effects:
277 Example:
279 =cut
281 sub draw_centromere {
282 my $self = shift;
283 my $image = shift;
284 my $centromere_color = $image->colorResolve(80, 80, 150);
285 $image->filledArc($self->get_X(),$self->get_Y(),10,10,0,360, $centromere_color);
290 =head2 function set_vertical_offset_centromere()
292 This function sets the vertical offset to the centromere (default).
294 =cut
296 sub set_vertical_offset_centromere {
297 my $self = shift;
298 $self->{vertical_offset_type} = "centromere";
301 sub set_vertical_offset_top_edge {
302 my $self = shift;
303 $self->{vertical_offset_type} = "top_edge";
307 # sub get_vertical_offset {
308 # my $self = shift;
309 # if ($self->{vertical_offset_type} eq "top_edge") {
310 # return $self->SUPER::get_vertical_offset()+100;
314 # The following method is overridden because the caption is rendered
315 # at a slightly different location (the vertical offset defines the
316 # centromere and not the top edge)
318 sub draw_caption {
319 my $self = shift;
320 my $image = shift;
322 my $outline_color = $image -> colorResolve(
323 $self->{outline_color}[0],
324 $self->{outline_color}[1],
325 $self->{outline_color}[2]
327 my $bigfont = GD::Font->Large();
328 $image -> string(
329 $bigfont,
330 $self->get_horizontal_offset()- $bigfont->width() * length($self->get_caption())/2,
331 $self->get_vertical_offset()-$self->{scaling_factor}*$self->{short_arm_length}-$bigfont->height(),
332 $self->get_caption(), $outline_color );
334 #$image->string($bigfont, 50, 50, "HELLO", $outline_color);
337 sub layout {
338 my $self=shift;
340 print STDERR "EXECUTING layout() in PachyteneIdiogram...\n";
341 # determine the offset type
342 if ($self->{vertical_offset_type} eq "top_edge") {
343 my $new_offset = $self->get_vertical_offset()-$self->mapunits2pixels(-100);
344 #print STDERR "Setting the vertical offset to $new_offset..\n";
345 $self->set_vertical_offset($new_offset);
348 $self->_calculate_scaling_factor();
349 $self->distribute_labels();
354 sub get_enclosing_rect {
355 my $self = shift;
356 if ($self->{vertical_offset_type} eq "top_edge") {
357 $self->set_vertical_offset($self->get_vertical_offset()-$self->mapunits2pixels(-100));
359 return ($self->get_horizontal_offset()-int($self->get_width()/2),
360 $self->get_vertical_offset()+$self->mapunits2pixels(-100),
361 $self->get_horizontal_offset()+int($self->get_width()/2),
362 $self->get_vertical_offset()+$self->mapunits2pixels(100)
367 return 1;