refactoring the cview/view_maps.pl script - this class was embedded in the script..
[cxgn-corelibs.git] / lib / CXGN / Cview / ViewMaps.pm
blob6894688d24850613deb213e8168cf47bea82f0b6
2 package CXGN::Cview::ViewMaps;
4 use CXGN::Page::FormattingHelpers qw | page_title_html |;
5 use CXGN::Cview::MapFactory;
6 use CXGN::Cview::Chromosome_viewer;
7 use CXGN::Cview::ChrLink;
8 use CXGN::Cview::Utils qw | set_marker_color |;
9 use CXGN::Cview::MapImage;
10 use CXGN::Tools::WebImageCache;
11 use CXGN::Map;
12 use CXGN::VHost;
14 use base qw | CXGN::DB::Object |;
18 =head2 function new()
20 Synopsis:
21 Arguments: none
22 Returns: a handle to a view_maps object
23 Side effects:
24 Description: constructor
26 =cut
28 sub new {
29 my $class = shift;
30 my $dbh = shift;
31 my $page = CXGN::Page->new();
32 my $self = bless {}, $class;
33 $self->set_dbh($dbh);
34 # set some defaults...
36 $self->{page} = $page;
37 $self -> {unzoomedheight} = 20; # how many cM are seen at zoom level 1
39 return $self;
42 sub adjust_parameters {
43 my $self = shift;
45 # adjust input arguments
51 =head2 accessors set_maps(), get_maps()
53 Property:
54 Setter Args:
55 Getter Args:
56 Getter Ret:
57 Side Effects:
58 Description:
60 =cut
62 sub get_maps {
63 my $self=shift;
64 return @{$self->{maps}};
67 sub set_maps {
68 my $self=shift;
69 @{$self->{maps}}=@_;
72 =head2 accessors set_cache(), get_cache()
74 Property: the CXGN::Tools::WebImageCache object
75 Args/Ret: the same
76 Side Effects: this is the object used to generate the
77 cache image.
78 Description:
80 =cut
82 sub get_cache {
83 my $self=shift;
84 return $self->{cache};
87 sub set_cache {
88 my $self=shift;
89 $self->{cache}=shift;
95 =head2 function generate_page()
97 Arguments: none
98 Returns: nothing
99 Side effects: generates the CXGN::Cview::MapImage and stores it
100 to the cache if necessary, or reads just reads
101 the image cache if it is still valid.
103 =cut
105 sub generate_page {
106 my $self = shift;
108 my $vhost = CXGN::VHost->new();
109 my $cache = CXGN::Tools::WebImageCache->new();
111 # define a key for the cache. lets just use the name of the
112 # script and the map_version_ids of the maps being displayed
114 $cache->set_key("view_maps".(join "-", map { $_->get_id() } ($self->get_maps())));
116 $cache->set_basedir($vhost->get_conf("basepath"));
117 $cache->set_temp_dir(File::Spec->catfile($vhost->get_conf("tempfiles_subdir"), "cview"));
118 $cache->set_expiration_time(86400);
120 $self->set_cache($cache);
122 if (! $self->get_cache()->is_valid()) {
123 my $map_width = $self->{map_width} = 720;
124 my $x_distance = $map_width/4; # the number of pixels the different elements are spaced
125 my $row_count = 0;
126 my $row_height = 120; # the height of a row (vertical space for each chromosome image)
127 my $y_distance = $row_height * (1/3);
128 my $chr_height = $row_height * (2/3);
129 my $map_height;
131 # determine the maximum chromosome count among all maps
132 # so that we can accommodate it
134 my $max_chr = 0;
135 foreach my $m ($self->get_maps()) {
136 my $chr_count = 0;
137 if ($m) {
138 $chr_count = $m->get_chromosome_count();
140 if ($chr_count > $max_chr) { $max_chr=$chr_count; }
143 $map_height = $row_height * $max_chr+2*$y_distance;
144 # show the ruler if requested
146 # if ($self->{show_ruler}) {
147 # my $r = ruler->new($x_distance-20, $row_height * $row_count + $y_distance, $chr_height, 0, $self->{c}{$track}[$i]->get_chromosome_length());
148 # $self->{map}->add_ruler($r);
150 $row_count++;
152 $self->{map} = CXGN::Cview::MapImage -> new("", $map_width, $map_height);
154 # get all the chromosomes and add them to the map
156 my $track = 0;
157 foreach my $map ($self->get_maps()) {
158 my @chr_names = $map->get_chromosome_names();
159 for (my $i=0; $i<$map->get_chromosome_count(); $i++) {
161 $self->{c}{$track}[$i] = ($self->get_maps())[$track]->get_chromosome($i+1);
162 $self->{c}{$track}[$i] -> set_vertical_offset($row_height*$i+$y_distance);
163 $self->{c}{$track}[$i] -> set_horizontal_offset($x_distance + $x_distance * ($track));
164 $self->{c}{$track}[$i] -> set_height($chr_height);
165 $self->{c}{$track}[$i] -> set_caption( $chr_names[$i] );
166 $self->{c}{$track}[$i] -> set_width(16);
167 $self->{c}{$track}[$i] -> set_url("/cview/view_chromosome.pl?map_version_id=".($self->get_maps())[$track]->get_id()."&amp;chr_nr=$i");
169 $self->{c}{$track}[$i] -> set_labels_none();
170 $self->{map}->add_chromosome($self->{c}{$track}[$i]);
172 $track++;
176 # get the connections between the chromosomes
178 my %find = ();
180 for (my $track=0; $track<($self->get_maps()); $track++) {
181 for (my $i =0; $i< ($self->get_maps())[$track]->get_chromosome_count(); $i++) {
182 foreach my $m ($self->{c}{$track}[$i]->get_markers()) {
183 $m->hide_label();
184 # make entry into the find hash and store corrsponding chromosomes and offset
185 # (for drawing connections)
186 # if the map is the reference map ($compare_to_map is false).
188 $find{$m->get_id()}->{$track}->{chr}=$i;
189 $find{$m->get_id()}->{$track}->{offset}=$m->get_offset();
191 # set the marker colors
193 set_marker_color($m, "marker_types");
198 foreach my $f (keys(%find)) {
199 foreach my $t (keys %{$find{$f}}) {
200 my $chr = $find{$f}->{$t}->{chr};
201 my $offset = $find{$f}->{$t}->{offset};
203 if (exists($find{$f}->{$t-1}) || defined($find{$f}->{$t-1})) {
204 my $comp_chr = $find{$f}->{$t-1}->{chr};
205 my $comp_offset = $find{$f}->{$t-1}->{offset};
206 #print STDERR "Found on track $t: Chr=$chr offset=$offset, links to track ".($t-1)." Chr=$comp_chr offset $comp_offset\n";
207 if ($comp_chr) {
208 my $link1 = CXGN::Cview::ChrLink->new($self->{c}{$t}[$chr], $offset, $self->{c}{$t-1}[$comp_chr], $comp_offset);
209 $self->{map}->add_chr_link($link1);
212 if (exists($find{$f}->{$t+1})) {
213 my $comp_chr = $find{$f}->{$t+1}->{chr};
214 my $comp_offset = $find{$f}->{$t+1}->{offset};
215 my $link2 = CXGN::Cview::ChrLink->new($self->{c}{$t}[$chr], $offset, $self->{c}{$t+1}[$comp_chr], $comp_offset);
216 $self->{map}->add_chr_link($link2);
223 $self->get_cache()->set_map_name("viewmap");
224 $self->get_cache()->set_image_data($self->{map}->render_png_string());
225 $self->get_cache()->set_image_map_data($self->{map}->get_image_map("viewmap"));
227 # # show the ruler if requested
229 # if ($self->{show_ruler}) {
230 # my $r = ruler->new($x_distance-20, $row_height * $row_count + $y_distance, $chr_height, 0, $self->{c}{$track}[$i]->get_chromosome_length());
231 # $self->{map}->add_ruler($r);
236 # my $filename = "cview".(rand())."_".$$.".png";
238 # $self->{image_path} = $vhost_conf->get_conf('basepath').$vhost_conf->get_conf('tempfiles_subdir')."/cview/$filename";
239 # $self->{image_url} = $vhost_conf->get_conf('tempfiles_subdir')."/cview/$filename";
241 # $self->{map} -> render_png_file($self->{image_path});
243 # $self->{imagemap} = $self->{map}->get_image_map("imagemap");
249 sub get_select_toolbar {
250 my $self = shift;
252 # $left_map = $self->get_left_map() || 0;
253 # $center_map = $self->get_center_map() || 0;
254 # $right_map = $self->get_right_map || 0;
255 my @names = ("left_map_version_id", "center_map_version_id", "right_map_version_id");
256 my @selects = ();
257 for (my $i=0; $i< 3; $i++) {
258 if ( defined(($self->get_maps())[$i])) {
259 push @selects, CXGN::Cview::Utils::get_maps_select($self->get_dbh(), ($self->get_maps())[$i]->get_id(), $names[$i], 1);
261 else {
262 push @selects, CXGN::Cview::Utils::get_maps_select($self->get_dbh(), undef, $names[$i], 1);
265 # my $center_select = CXGN::Cview::Utils::get_maps_select($self, !$center_map || $center_map->get_id(), "center_map_version_id", 1);
266 # my $right_select = CXGN::Cview::Utils::get_maps_select($self, !$right_map || $right_map->get_id(), "right_map_version_id", 1);
269 return qq {
270 <form action="#">
271 <center>
272 <table summary=""><tr><td>$selects[0]</td><td>$selects[1]</td><td>$selects[2]</td></tr></table>
273 <input type="submit" value="set" />
274 </center>
275 </form>
279 =head2 function display()
281 Synopsis:
282 Arguments:
283 Returns:
284 Side effects:
285 Description: composes the page and displays it.
287 =cut
289 sub display {
290 my $self = shift;
293 $self->{page}->header("SGN comparative mapviewer");
294 my $width = int($self->{map_width}/3);
296 my $select = $self->get_select_toolbar();
298 print "$select";
300 if (!$self->get_maps()) {
301 print "<br /><br /><center>Note: No maps are selected. Please select maps from the pull down menus above.</center>\n";
304 print $self->get_cache()->get_image_html();
306 # print "<img src=\"$self->{image_url}\" usemap=\"#chr_comp_map\" border=\"0\" alt=\"\" />\n";
308 # print $self->{map}->get_image_map("chr_comp_map");
310 $self->{page}->footer();
316 =head2 function error_message_page()
318 Synopsis:
319 Arguments:
320 Returns:
321 Side effects:
322 Description:
324 =cut
326 sub error_message_page {
327 my $self = shift;
328 my $page = CXGN::Page->new();
329 $page->header();
331 my $title = page_title_html("Error: No center map defined");
333 print <<HTML;
335 $title
337 A center map needs to be defined for this page to work. Please supply
338 a center_map_version_id as a parameter. If this was the result of a link,
339 please inform SGN about the error.
340 </p>
342 Contact SGN at <a href="mailto:sgn-feedback\@sgn.cornell.edu">sgn-feedback\@sgn.cornell.edu</a>
344 HTML
346 $page->footer();
348 exit();
352 sub clean_up {
353 my $self = shift;