added an accessor for db backend information
[cxgn-corelibs.git] / lib / CXGN / Map.pm
blobd0372d3285de014b91ce2f0c3d8570ee02cf2563
2 =head1 NAME
4 CXGN::Map - classes to get information on SGN mapping information.
6 =head1 DESCRIPTION
8 This class was originally written to retrieve data on genetic maps in the SGN database. However, map types multiplied and this class was re-written as a factory object producing a map object of the appropriate type - genetic, fish, individual, user, etc. These map objects are defined in the CXGN::Map:: namespace. Previous documentation mentioned the existence of a CXGN::Map::Storable class, however, this never seemed to exist and the new map interface and subclasses have been written as read/write objects.
10 The "new" function has been re-cast to act as a factory object and will produce the right type of Map object given the appropriate parameters, which are defined as follows:
12 parameter map type
13 --------- --------
14 map_id genetic or fish
15 map_version_id genetic or fish
16 user_map_id user_map
17 population_id IL map
18 individual_id indivdual_map
20 Note that much of the functionality of this class has been factored out into a CXGN::LinkageGroup object, which also exists in different incarnations for the different map types.
22 =head1 AUTHORS
24 John Binns <zombieite@gmail.com> and Lukas Mueller (lam87@cornell.edu)
28 =head1 FUNCTIONS
30 This class defines the following functions to be implemented by the subclasses, and keeps the old functions for compatibility (see deprecated functions below).
32 =cut
34 use strict;
35 use CXGN::DB::Connection;
37 package CXGN::Map;
39 =head2 new
41 Usage: my $map = CXGN::Map->new($dbh, {map_version_id=>30})
42 Desc: creates a new CXGN::Map object
43 Ret:
44 Args: - a database handle, if possible using
45 CXGN::DB::Connection object
46 - a hashref, containing either a key map_id or a key
47 map_version_id, but not both!
48 Side Effects:
49 Example:
51 =cut
53 sub new {
54 my $class=shift;
55 my($dbh,$map_info)=@_;
56 my $self=bless({},$class);
57 unless(CXGN::DB::Connection::is_valid_dbh($dbh)){die"Invalid DBH";}
58 ref($map_info) eq 'HASH' or die"Must send in a dbh and hash ref with a map_id key or a map_version_id key";
59 $self->{map_version_id}=$map_info->{map_version_id};
60 $self->{map_id}=$map_info->{map_id};
61 if($self->{map_id})
63 if($self->{map_version_id})
65 die"You must only send in a map_id or a map_version_id, not both";
67 my $map_version_id_q=$dbh->prepare("select map_version_id from map_version where map_id=? and current_version='t'");
68 $map_version_id_q->execute($self->{map_id});
69 ($self->{map_version_id})=$map_version_id_q->fetchrow_array();
71 $self->{map_version_id} or return undef;
72 my $general_info_q=$dbh->prepare
74 select
75 map_id,
76 map_version_id,
77 date_loaded,
78 current_version,
79 short_name,
80 long_name,
81 abstract,
82 map_type,
83 has_IL,
84 has_physical
85 from
86 map_version
87 inner join map using (map_id)
88 where
89 map_version_id=?
90 ');
91 $general_info_q->execute($self->{map_version_id});
93 $self->{map_id},
94 $self->{map_version_id},
95 $self->{date_loaded},
96 $self->{current_version},
97 $self->{short_name},
98 $self->{long_name},
99 $self->{abstract},
100 $self->{map_type},
101 $self->{has_IL},
102 $self->{has_physical}
103 )=$general_info_q->fetchrow_array();
104 if(!$self->{map_version_id}){return undef;}
105 my $linkage_q=$dbh->prepare('select linkage_group.lg_id as lg_id,linkage_group.map_version_id as map_version_id,lg_order,lg_name, min(position) as north_centromere, max(position) as south_centromere from linkage_group left join marker_location on (north_location_id=location_id or south_location_id=location_id) where linkage_group.map_version_id=? group by linkage_group.lg_id, linkage_group.map_version_id, lg_order, lg_name order by lg_order');
106 $linkage_q->execute($self->{map_version_id});
107 while(my $linkage_group=$linkage_q->fetchrow_hashref())
109 push(@{$self->{linkage_groups}},$linkage_group);
111 return $self;
115 =head2 accessors set_short_name, get_short_name
117 Property:
118 Setter Args:
119 Getter Args:
120 Getter Ret:
121 Side Effects:
122 Description:
124 =cut
126 sub get_short_name {
127 my $self=shift;
128 return $self->{short_name};
131 sub set_short_name {
132 my $self=shift;
133 $self->{short_name}=shift;
136 =head2 accessors set_long_name, get_long_name
138 Property:
139 Setter Args:
140 Getter Args:
141 Getter Ret:
142 Side Effects:
143 Description:
145 =cut
147 sub get_long_name {
148 my $self=shift;
149 return $self->{long_name};
152 sub set_long_name {
153 my $self=shift;
154 $self->{long_name}=shift;
157 =head2 accessors set_abstract, get_abstract
159 Property:
160 Setter Args:
161 Getter Args:
162 Getter Ret:
163 Side Effects:
164 Description:
166 =cut
168 sub get_abstract {
169 my $self=shift;
170 return $self->{abstract};
173 sub set_abstract {
174 my $self=shift;
175 $self->{abstract}=shift;
178 =head2 accessors set_linkage_groups, get_linkage_groups
180 Property:
181 Setter Args:
182 Getter Args:
183 Getter Ret:
184 Side Effects:
185 Description:
187 =cut
189 sub get_linkage_groups {
190 my $self=shift;
191 return @{$self->{linkage_groups}};
194 sub set_linkage_groups {
195 my $self=shift;
196 @{$self->{linkage_groups}}=@_;
199 =head2 function add_linkage_group
201 Synopsis:
202 Arguments:
203 Returns:
204 Side effects:
205 Description:
207 =cut
209 sub add_linkage_group {
210 my $self = shift;
211 my $lg = shift;
212 push @{$self->{linkage_groups}}, $lg;
216 =head2 accessors set_map_type, get_map_type
218 Property:
219 Setter Args:
220 Getter Args:
221 Getter Ret:
222 Side Effects:
223 Description:
225 =cut
227 sub get_map_type {
228 my $self=shift;
229 return $self->{map_type};
232 sub set_map_type {
233 my $self=shift;
234 $self->{map_type}=shift;
238 =head2 function get_units
240 Synopsis:
241 Arguments:
242 Returns:
243 Side effects:
244 Description:
246 =cut
248 sub get_units {
249 my $self=shift;
250 if ($self->get_map_type() eq "genetic") {
251 return "cM";
253 elsif ($self->get_map_type() eq "fish") {
254 return "%";
256 elsif ($self->get_map_type() =~ /sequenc/) {
257 return "MB";
259 else {
260 return "unknown";
269 =head1 DEPRECATED FUNCTIONS
271 These functions are still working but should not be used in new code.
273 Note that these functions only work as getters and not as setters.
275 =cut
277 =head2 function map_id
279 Synopsis:
280 Arguments:
281 Returns:
282 Side effects:
283 Description:
285 =cut
288 sub map_id {
289 my $self=shift;
290 return $self->{map_id};
293 =head2 function map_version_id
295 Synopsis:
296 Arguments:
297 Returns:
298 Side effects:
299 Description:
301 =cut
303 sub map_version_id {
304 my $self=shift;
305 return $self->{map_version_id};
308 =head2 function short_name
310 Synopsis:
311 Arguments:
312 Returns:
313 Side effects:
314 Description:
316 =cut
318 sub short_name {
319 my $self=shift;
320 return $self->{short_name};
323 =head2 function long_name
325 Synopsis:
326 Arguments:
327 Returns:
328 Side effects:
329 Description:
331 =cut
333 sub long_name {
334 my $self=shift;
335 return $self->{long_name};
338 =head2 function abstract
340 Synopsis:
341 Arguments:
342 Returns:
343 Side effects:
344 Description:
346 =cut
348 sub abstract {
349 my $self=shift;
350 return $self->{abstract};
353 =head2 linkage_groups
355 Usage:
356 Desc:
357 Ret: a reference to an array of hashrefs with linkage group info.
358 hash keys include lg_name and lg_order
359 Args:
360 Side Effects:
361 Example:
363 =cut
365 sub linkage_groups {
366 my $self=shift;
367 if($self->{linkage_groups})
369 return $self->{linkage_groups};
371 else
373 return [];
377 =head2 map_type
379 Usage:
380 Desc:
381 Ret: the type of the map, either 'fish' for a fish map
382 or 'genetic' for a genetic map.
383 Args:
384 Side Effects:
385 Example:
387 =cut
389 sub map_type {
390 my $self = shift;
391 return $self->{map_type};
394 =head2 has_IL
396 Usage:
397 Desc:
398 Ret:
399 Args:
400 Side Effects:
401 Example:
403 =cut
405 sub has_IL {
406 my $self = shift;
407 return $self->{has_IL};
410 =head2 has_physical
412 Usage:
413 Desc:
414 Ret:
415 Args:
416 Side Effects:
417 Example:
419 =cut
421 sub has_physical {
422 my $self = shift;
423 return $self->{has_physical};
429 =head2 get_chr_names
431 Usage:
432 Desc: a shortcut function to get at the chromosome names,
433 sorted by lg_order
434 Ret: a list of chromosome names.
435 Args:
436 Side Effects:
437 Example:
439 =cut
441 sub get_chr_names {
442 my $self = shift;
443 my $linkage_groups_ref = $self->linkage_groups();
444 my @names = map $_->{lg_name}, @{$linkage_groups_ref};
445 return @names;
448 =head2 has_linkage_group
450 Usage:
451 Desc:
452 Ret: 1 if the string or number represents a linkage group
453 of this map
454 0 if it doesn\'t
455 Args: a string or number describing a possible linkage
456 group of this map
457 Side Effects:
458 Example:
460 =cut
462 sub has_linkage_group {
463 my $self = shift;
464 my $candidate = shift;
465 chomp($candidate);
466 $candidate=~ s/\s*(.*)\s*/$1/;
467 foreach my $n (map $_->{lg_name} , @{$self->linkage_groups()}) {
468 #print STDERR "comparing $n with $candidate...\n";
469 if ($candidate =~ /^$n$/i) {
470 #print STDERR "Yip!\n";
471 return 1;
474 return 0;
477 =head2 function get_centromere
479 Synopsis: my ($north, $south, $center) = $map->get_centromere($lg_name)
480 Arguments: a valid linkage group name
481 Returns: a three member list, the first element corresponds
482 to the north boundary of the centromere in cM
483 the second corresponds to the south boundary of
484 the centromere in cM, the third is the arithmetic mean
485 of the two first values.
486 Side effects: none
487 Description:
489 =cut
491 sub get_centromere {
492 my $self=shift;
493 my $lg = shift;
495 if (! $self->has_linkage_group($lg)) {
496 die "Not a valid linkage group for this map!\n";
499 my $lg_hash = $self->get_linkage_group_hash($lg);
500 # foreach my $k (keys %$lg_hash) {
501 # print " $k, $lg_hash->{$k}\n";
503 my $north = $lg_hash->{north_centromere};
504 my $south = $lg_hash->{south_centromere};
505 return ($north, $south, int(($north+$south)/2));
508 sub get_linkage_group_hash {
509 my $self= shift;
510 my $lg_name = shift;
511 foreach my $lg_hash (@{$self->linkage_groups()}) {
512 if ($lg_hash->{lg_name} eq $lg_name) {
513 return $lg_hash;
519 return 1;