fix AGP map and upgrade to new, WGS-based AGPs.
[cview.git] / lib / CXGN / Cview / MapOverviews.pm
blobbd689d59130bf23349d3695f7b19f50de0d068e7
2 =head1 NAME
4 CXGN::Cview::MapOverviews - classes to display different kinds of map overviews.
6 =head1 SYNOPSYS
8 my $overview = CXGN::MapOverview::Generic->new(
9 CXGN::Cview::Map::SGN::Genetic->new($dbh, 9), $args_ref
11 $overview->hilite_markers(@marker_names);
12 $overview->render_map();
13 $overview->get_image_html();
16 =head1 DESCRIPTION
18 CXGN::Cview::MapOverviews contains a number of classes designed to display map
19 overview images (chromosomes aligned horizontally) for a given map. The base
20 class is an abstract class called CXGN::Cview::MapOverviews and it depends on
21 CXGN::Cview classes for drawing the chromosomes. The subclasses derived from
22 this class are
24 =over 5
26 =item *
28 CXGN::Cview::MapOverviews::Generic, which displays a generic overview for maps
29 of type "genetic", "fish" or "physical" - or any other map that has an
30 appropriate CXGN::Cview::Map object implemented.
32 =item *
34 CXGN::Cview::MapOverviews::ProjectStats displays a map showing the progress of
35 the sequencing project. It also uses CXGN::People, to get the BAC statistics
36 associated to the different chromosomes.
38 =back
40 =head2 Caching implementation
42 The caching is implemented using CXGN::Tools::WebImageCache, which implements
43 caching on the file system level. Each subclass of MapOverviews can implement
44 its own get_cache_key() function, which should should be set to a distinct key
45 for each map. MapOverviews::Generic concatenates the map_version_id, the hilited
46 markers, and the package name. For more information, see
47 L<CXGN::Tools::WebImageCache>.
49 =head2 Resetting the cache
51 The cache can be reset by deleting the contents of the caching directory. The
52 default value is set using CXGN::Cview::Config properties basepath,
53 tempfiles_subdir and the string "cview", which resolves to
54 "/data/local/website/sgn/documents/tempfiles/cview/" on the current production
55 systems (as of Dec 2006). The class also takes a $reset_cache parameter in the
56 constructor, which will be passed to the CXGN::Tools::WebImageCache constructor.
57 A true value will cause the cache to be considered as expired.
59 =head1 AUTHORS
61 Lukas Mueller (lam87@cornell.edu)
62 John Binns (zombieite@gmail.com)
64 =cut
66 use strict;
67 use warnings;
69 package CXGN::Cview::MapOverviews;
71 use File::Spec;
72 use CXGN::People;
73 use CXGN::Tools::WebImageCache;
74 use CXGN::Cview;
75 use CXGN::Cview::Chromosome;
76 use CXGN::Cview::Chromosome::PachyteneIdiogram;
77 use CXGN::Cview::Chromosome::Glyph;
78 use CXGN::Cview::MapImage;
79 use CXGN::Cview::Marker;
80 use CXGN::Cview::Marker::RangeMarker;
81 use CXGN::Cview::Ruler;
82 use CXGN::Cview::Chromosome::Physical;
83 use CXGN::Cview::Label;
84 use CXGN::Cview::Map::Tools;
85 use CXGN::Cview::MapOverviews::Generic;
86 use CXGN::Cview::MapOverviews::Physical;
87 use CXGN::Cview::MapOverviews::ProjectStats;
88 use CXGN::Cview::MapOverviews::Individual;
90 =head1 CXGN::Cview::MapOverviews
92 This class implements an abstract interface for drawing map overview images.
94 =cut
97 # an abstract class from which other overviews inherit.
99 =head2 function new()
101 Synopsis: Constructor for MapOverview object
102 Example: my $map_overview = CXGN::Cview::MapOverviews::Generic
103 ->new( $map_object, $args_ref );
104 Arguments: usually a subclass of CXGN::Cview::Map
105 subclasses.
106 the $args_ref can have the following keys (* means required)
107 force forces recalculation of the image
108 basepath* the basepath to use for tempfile storage
109 tempfiles_subdir* the subdir, after the basepath, where
110 the tempfiles are stored
111 dbh* a database handle
113 Returns: a CXGN::Cview::MapOverview object
114 Side effects: none
115 Description:
117 =cut
119 sub new {
120 my $class = shift;
121 my $map = shift;
122 my $args = shift;
124 my $self = bless {}, $class;
126 $self->_set_force($args->{force});
128 # define some default values
130 ####@{$self->{c_len}} = (0, 163, 140, 170, 130, 120, 100, 110, 90, 115, 90, 100, 120);
132 $self->set_horizontal_spacing(50);
133 # $self->set_vhost(CXGN::VHost->new());
135 # set up the cache
137 my $cache = CXGN::Tools::WebImageCache->new();
138 $cache->set_force($args->{force});
139 $cache->set_basedir($args->{basepath});
140 $cache->set_temp_dir($args->{tempfiles_subdir});
141 $self->set_cache($cache);
142 $self->set_image_width(700);
143 $self->set_image_height(200);
144 $self->set_map($map);
145 return $self;
148 =head2 accessors set_map(), get_map()
150 Synopsis: $overview->get_map();
151 Arguments:
152 Returns: gets the map object.
153 Side effects: the corresponding map will be represented
154 on the overview.
155 Description:
157 =cut
159 sub get_map {
160 my $self=shift;
161 return $self->{map};
164 sub set_map {
165 my $self=shift;
166 $self->{map}=shift;
169 # =head2 accessors set_vhost(), get_vhost()
171 # Property: a CXGN::VHost object
172 # Description: This is set to a new CXGN::VHost object
173 # in the constructor. The getter is used
174 # to obtain configuration information, such
175 # as tempfile pathnames and the like.
177 # =cut
179 # sub get_vhost {
180 # my $self=shift;
181 # return $self->{vhost};
184 # sub set_vhost {
185 # my $self=shift;
186 # $self->{vhost}=shift;
189 =head2 function set_horizontal_spacing()
191 Synopsis: $overview->set_horizontal_spacing(60)
192 Arguments: the horizontal spacing in pixels
193 Returns: nothing
194 Side effects: Defines the spacing between the chromosome glyphs
195 in the overview image. If this is not set, the
196 default is 50.
197 Description:
199 =cut
201 sub set_horizontal_spacing {
202 my $self=shift;
203 $self->{horizontal_spacing} = shift;
206 =head2 function get_horizontal_spacing()
208 Synopsis: $my_spacing = $overview->get_horizontal_spacing()
209 Arguments: None (accessor)
210 Returns: the number of pixels between the chromosome glyphs.
211 Side effects: None
212 Description:
214 =cut
216 sub get_horizontal_spacing {
217 my $self=shift;
218 return $self->{horizontal_spacing};
221 =head2 function render_map()
223 Synopsis: $overview->render_map()
224 Arguments:
225 Returns: nothing
226 Side effects: renders the map and sets two properties (see below).
227 Description: this function needs to be implemented in subclasses
228 to draw the desired map. The calculated map should be
229 stored directly using the cache functions
230 (see CXGN::Tools::WebImageCache) (essentially, using the
231 functions set_image_data() and set_image_map_data() ).
233 The subclassed function should call SUPER::render_map(),
234 such that the key can be properly set.
237 =cut
239 sub render_map {
240 my $self = shift;
246 =head2 function get_file_png()
248 Synopsis: $overview->get_file_png($path)
249 Arguments: a fully qualified path of the file
250 Returns:
252 Side effects:
253 Description: saves the image into the specified file
254 Status:
256 =cut
258 sub get_file_png {
259 my $self=shift;
260 my $path = shift;
262 $self->{map_image}->render_png_file($path);
265 =head2 function get_image_map()
267 Synopsis: my $html_image_map = $overview->get_image_map();
268 Arguments: none
269 Returns: an html image map, defining the links on the image
270 Side effects: none
271 Description: none
272 Status: DEPRECATED! USE get_image_html INSTEAD!
274 =cut
276 sub get_image_map {
277 my $self=shift;
278 my $map_name = shift;
280 my $map_file = ($self->get_temp_file())[1].".map";
282 if (!$self->has_cache()) {
283 open (my $FILE, ">", $map_file) ||
284 die "Can't open map file $map_file: $!";
285 print $FILE $self->{image_map};
286 close($FILE);
288 else {
289 open (my $FILE, "<", $map_file) ||
290 die "Can't open map file! $map_file";
291 my @FILE = (<$FILE>);
292 close($FILE);
293 $self->{image_map} = join "\n", @FILE;
295 return $self->{image_map};
299 =head2 function set_image_map()
301 Synopsis: $overview->set_image_map();
302 Arguments: a string representing the html image map for
303 the overview image (essentially, the appropriate
304 <map> tag that goes with the overview image).
305 Returns:
306 Side effects: this will be used directly to print the <map> tag
307 Description:
309 =cut
311 sub set_image_map {
312 my $self = shift;
313 $self->{image_map}=shift;
316 =head2 function get_image_html()
318 Synopsis:
319 Arguments: none
320 Returns: a string representing the image for an html page,
321 including image tag and image map
322 Side effects:
323 Description:
325 =cut
327 sub get_image_html {
328 my $self = shift;
329 return $self->get_cache()->get_image_html();
331 # return '<img src="'.($self->get_file_png())[0].'" usemap="#overview" border="0" />'."<br />\n". $self->get_image_map("overview");
334 =head2 accessors get_marker_count(), set_marker_count()
336 Synopsis: my $count = $map->get_marker_count($chr)
337 Arguments: a chromosome name
338 Returns: the number of markers on that chromosome
339 Side effects:
340 Description: needs to be implemented in a subclass.
342 =cut
345 sub get_marker_count {
348 sub set_marker_count {
351 =head2 accessors set_map_image(), get_map_image()
353 Property: the image object (GD::Image)
354 Side Effects:
355 Description: this image object is used for drawing the image
357 =cut
359 sub get_map_image {
360 my $self=shift;
361 return $self->{map_image};
364 sub set_map_image {
365 my $self=shift;
366 $self->{map_image}=shift;
369 =head2 function hilite_marker()
371 Synopsis: $overview->hilite_marker("TG280");
372 Arguments: a marker name (string)
373 Returns: nothing
374 Side effects: causes the marker to be highlighted on the overview
375 Description:
377 =cut
379 sub hilite_marker {
380 my $self = shift;
381 my $marker_name = shift;
382 if (!exists($self->{hilite_markers})) { @{$self->{hilite_markers}}=(); }
383 push @{$self->{hilite_markers}}, $marker_name;
386 sub get_hilite_markers {
387 my $self = shift;
388 if (!exists($self->{hilite_markers})) { @{$self->{hilite_markers}}=(); }
389 return @{$self->{hilite_markers}};
392 sub add_marker_not_found {
393 my $self = shift;
394 my $marker = shift;
396 # prevent these not initialized errors...
398 if (!exists($self->{markers_not_found})) { %{$self->{markers_not_found}}=(); }
399 ${$self->{markers_not_found}}{$marker}=1;
402 # return the markers that were not found for hiliting on the overview diagram
403 # Note: render_map has to be called before calling this function.
405 sub get_markers_not_found {
406 my $self = shift;
407 if (!$self->{markers_not_found}) { %{$self->{markers_not_found}}=(); }
408 return ( map ($_, (keys(%{$self->{markers_not_found}}))));
411 =head2 add_map_items
413 Usage:
414 Desc:
415 Ret:
416 Args:
417 Side Effects:
418 Example:
420 =cut
422 sub add_map_items {
423 my $self = shift;
424 my @map_items = @_;
426 $self->get_map()->set_map_items(@map_items);
430 =head2 accessors set_chr_height(), get_chr_height()
432 Property: the height of the chromosome in pixels.
433 This is currently only used for the Project
434 Stats overview, in which chromosome don\'t
435 have a 'natural' height.
436 Side Effects:
437 Description:
439 =cut
441 sub get_chr_height {
442 my $self=shift;
443 return $self->{chr_height};
446 sub set_chr_height {
447 my $self=shift;
448 $self->{chr_height}=shift;
451 =head2 accessors set_image_height(), get_image_height()
453 Property: The height of the image in pixels.
454 Setter Args:
455 Side Effects:
456 Description:
458 =cut
460 sub get_image_height {
461 my $self=shift;
462 return $self->{image_height};
465 sub set_image_height {
466 my $self=shift;
467 $self->{image_height}=shift;
470 =head2 accessors set_image_width(), get_image_width()
472 Property: the width of the entire image in pixels.
473 Setter Args:
474 Getter Args:
475 Getter Ret:
476 Side Effects:
477 Description:
479 =cut
481 sub get_image_width {
482 my $self=shift;
483 return $self->{image_width};
486 sub set_image_width {
487 my $self=shift;
488 $self->{image_width}=shift;
493 # accessors _set_force, _get_force
495 # if set to true, forces the re-calculation of the image and stats.
497 sub _get_force {
498 my $self=shift;
499 return $self->{force};
502 sub _set_force {
503 my $self=shift;
504 $self->{force}=shift;
510 # =head2 function has_cache()
512 # Synopsis: $overview->has_cache()
513 # Arguments: none
514 # Returns: true if there is a cached web image for the
515 # given cache key (as returned by get_cache_key()).
516 # Side effects: none
517 # Description:
519 # =cut
521 # sub has_cache {
522 # my $self = shift;
523 # if ($self->_get_force()) { return 0; }
524 # if (-e ($self->get_temp_file())[1] && -e (($self->get_temp_file())[1].".map")) {
525 # return 1;
527 # else {
528 # return 0;
532 =head2 accessors set_cache(), get_cache()
534 Property: a CXGN::Tools::WebImageCache object
535 Args/Ret: the same
536 Side Effects:
537 Description: see CXGN::Tools::WebImageCache
539 =cut
541 sub get_cache {
542 my $self=shift;
543 return $self->{cache};
546 sub set_cache {
547 my $self=shift;
548 $self->{cache}=shift;
551 =head2 get_chromosomes(), set_chromosomes()
553 Usage: my @c = $map->get_chromosomes();
554 Desc: returns (sets) a list of Cview chromosome objects for
555 this map, in the same order as get_chromosome_names().
556 Side Effects:
557 Example:
559 =cut
561 sub get_chromosomes {
562 my $self=shift;
563 return $self->{chromosomes};
567 sub set_chromosomes {
568 my $self=shift;
569 $self->{chromosomes}=shift;
573 =head2 accessors set_chromosome_count, get_chromosome_count
575 Property:
576 Setter Args:
577 Getter Args:
578 Getter Ret:
579 Side Effects:
580 Description:
582 =cut
584 sub get_chromosome_count {
585 my $self=shift;
586 return $self->{chromosome_count};
589 sub set_chromosome_count {
590 my $self=shift;
591 $self->{chromosome_count}=shift;
595 =head2 function get_cache_key()
597 Usage: $map->get_cache_key()
598 Desc: needs to be implemented in subclass and return
599 a cache key for the current map
600 Side Effects:
601 Example:
603 =cut
605 sub get_cache_key {
606 die "get_cache_key is abstract. Please implement in subclass.";