5 CXGN::Map - classes to get information on SGN mapping information and to add new map and map version data (new_map, store, & map_version functions).
9 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.
11 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:
15 map_id genetic or fish
16 map_version_id genetic or fish
19 individual_id indivdual_map
21 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.
25 John Binns <zombieite@gmail.com>, Lukas Mueller (lam87@cornell.edu) and Isaak Y Tecle (iyt2@cornell.edu)
31 This class defines the following functions to be implemented by the subclasses, and keeps the old functions for compatibility (see deprecated functions below).
41 use CXGN
::DB
::Connection
;
42 use CXGN
::Map
::Version
;
44 use base
"CXGN::DB::Object";
48 Usage: my $map = CXGN::Map->new($dbh, {map_version_id=>30})
49 Desc: creates a new CXGN::Map object
51 Args: - a database handle, if possible using
52 CXGN::DB::Connection object
53 - a hashref, containing either a key map_id or a key
54 map_version_id, but not both!
62 my($dbh,$map_info)=@_;
63 my $self=$class->SUPER::new
($dbh);
64 unless(CXGN
::DB
::Connection
::is_valid_dbh
($dbh)){die"Invalid DBH";}
65 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";
66 $self->{map_version_id
}=$map_info->{map_version_id
};
67 $self->{map_id
}=$map_info->{map_id
};
69 my $map_id_t = $self->{map_id
};
70 #print STDERR "map id: $map_id_t from map object\n";
73 if($self->{map_version_id
})
75 die"You must only send in a map_id or a map_version_id, not both";
77 my $map_version_id_q=$dbh->prepare("SELECT map_version_id
80 AND current_version='t'"
82 $map_version_id_q->execute($self->{map_id
});
83 if (my @row = $map_version_id_q->fetchrow_array()) {
84 $self->{map_version_id
} = $row[0];
86 print STDERR
"ERROR no map_version_id\n";
89 $self->{map_version_id
} or return undef;
90 my $general_info_q=$dbh->prepare
106 inner join map using (map_id)
110 $general_info_q->execute($self->{map_version_id
});
113 $self->{map_version_id
},
114 $self->{date_loaded
},
115 $self->{current_version
},
120 $self->{population_id
},
122 $self->{has_physical
}
124 )=$general_info_q->fetchrow_array();
125 if(!$self->{map_version_id
}){return undef;}
126 my $linkage_q=$dbh->prepare('SELECT linkage_group.lg_id AS lg_id,linkage_group.map_version_id AS map_version_id,
127 lg_order,lg_name, min(position) AS north_centromere, MAX(position) AS south_centromere
129 LEFT JOIN marker_location ON (north_location_id=location_id
130 OR south_location_id=location_id)
131 WHERE linkage_group.map_version_id=?
132 GROUP BY linkage_group.lg_id, linkage_group.map_version_id,
133 lg_order, lg_name order by lg_order');
134 $linkage_q->execute($self->{map_version_id
});
135 while(my $linkage_group=$linkage_q->fetchrow_hashref())
137 push(@
{$self->{linkage_groups
}},$linkage_group);
145 my $map_id = $self->get_map_id();
146 print STDERR
"map id from store: $map_id\n";
148 my $sth = $self->get_dbh()->prepare("UPDATE sgn.map SET
153 parent1_stock_id = ?,
154 parent2_stock_id = ?,
156 population_stock_id = ?
159 $sth->execute($self->{short_name
},
163 $self->{parent1_stock_id
},
164 $self->{parent2_stock_id
},
166 $self->{population_stock_id
},
170 print STDERR
"Storing map data... \n";
171 print STDERR
"updated map id: $map_id\n";
172 #$dbh->last_insert_id("map", "sgn");
176 print STDERR
"No map id\n";
189 print STDERR
"Short map name: $name\n";
191 $sth = $dbh->prepare("SELECT map_id
193 WHERE short_name ILIKE ?"
195 $sth->execute($name);
196 if (my @row = $sth->fetchrow_array) {
199 print STDERR
"Error: No Map Id for $name\n";
203 print STDERR
"Provide map name, please.\n";
204 die "No map name provided!\n";
208 $sth = $dbh->prepare("INSERT INTO sgn.map (short_name, map_type) VALUES (?, 'genetic') RETURNING map_id");
209 $sth->execute($name) or die "ERROR can not create map\n";;
210 ($map_id) = $sth->fetchrow_array() or die "ERROR inserting map\n";
211 print STDERR
"stored new Map Id: $map_id\n";
214 my ($map, $map_version_id);
216 $map_version_id = CXGN
::Map
::Version
->map_version($dbh, $map_id);
217 #$map_version_id= $self->map_version($dbh, $map_id);
218 print STDERR
"created map version_id: $map_version_id for map_id: $map_id\n";
219 $map = CXGN
::Map
->new($dbh, {map_id
=>$map_id});
220 my $new_map_id = $map->{map_id
};
221 print STDERR
"new_map function with map_id = $new_map_id.\n";
231 =head2 accessors set_short_name, get_short_name
244 return $self->{short_name
};
249 $self->{short_name
}=shift;
252 =head2 accessors set_long_name, get_long_name
265 return $self->{long_name
};
270 $self->{long_name
}=shift;
273 =head2 accessors set_abstract, get_abstract
286 return $self->{abstract
};
291 $self->{abstract
}=shift;
295 =head2 accessors get_parent_1, set_parent_1
308 return $self->{parent_1
};
313 $self->{parent_1
} = shift;
316 =head2 accessors get_parent1_stock_id, set_parent1_stock_id
319 Desc: sets the stock id of parent 1 of this map.
326 sub get_parent1_stock_id
{
328 return $self->{parent1_stock_id
};
331 sub set_parent1_stock_id
{
333 $self->{parent1_stock_id
} = shift;
336 =head2 accessors get_parent2_stock_id, set_parent2_stock_id
339 Desc: sets the stock id of the parent 2 of this map.
346 sub get_parent2_stock_id
{
348 return $self->{parent2_stock_id
};
351 sub set_parent2_stock_id
{
353 $self->{parent2_stock_id
} = shift;
356 =head2 accessors get_population_stock_id, set_population_stock_id
359 Desc: sets the population id of the map, referencing
367 sub get_population_stock_id
{
369 return $self->{population_stock_id
};
372 sub set_population_stock_id
{
374 $self->{population_stock_id
} = shift;
377 =head2 accessors get_population_id, set_population_id
388 sub get_population_id
{
390 return $self->{population_id
};
393 sub set_population_id
{
395 $self->{population_id
} = shift;
412 $self->{map_id
}=shift;
416 return $self->{map_id
};
420 =head2 accessors set_linkage_groups, get_linkage_groups
431 sub get_linkage_groups
{
433 return @
{$self->{linkage_groups
}};
436 sub set_linkage_groups
{
438 @
{$self->{linkage_groups
}}=@_;
441 =head2 function add_linkage_group
451 sub add_linkage_group
{
454 push @
{$self->{linkage_groups
}}, $lg;
458 =head2 accessors set_map_type, get_map_type
471 return $self->{map_type
};
476 $self->{map_type
}=shift;
480 =head2 function get_units
492 if ($self->get_map_type() eq "genetic") {
495 elsif ($self->get_map_type() eq "fish") {
498 elsif ($self->get_map_type() =~ /sequenc/) {
501 elsif ($self->get_map_type() =~ /qtl/i) {
514 =head1 DEPRECATED FUNCTIONS
516 These functions are still working but should not be used in new code.
518 Note that these functions only work as getters and not as setters.
522 =head2 function map_id
535 return $self->{map_id
};
538 =head2 function map_version_id
550 return $self->{map_version_id
};
553 =head2 function short_name
565 return $self->{short_name
};
568 =head2 function long_name
580 return $self->{long_name
};
583 =head2 function abstract
595 return $self->{abstract
};
598 =head2 linkage_groups
602 Ret: a reference to an array of hashrefs with linkage group info.
603 hash keys include lg_name and lg_order
612 if($self->{linkage_groups
})
614 return $self->{linkage_groups
};
626 Ret: the type of the map, either 'fish' for a fish map
627 or 'genetic' for a genetic map.
636 return $self->{map_type
};
652 return $self->{has_IL
};
668 return $self->{has_physical
};
677 Desc: a shortcut function to get at the chromosome names,
679 Ret: a list of chromosome names.
688 my $linkage_groups_ref = $self->linkage_groups();
689 my @names = map $_->{lg_name
}, @
{$linkage_groups_ref};
693 =head2 has_linkage_group
697 Ret: 1 if the string or number represents a linkage group
700 Args: a string or number describing a possible linkage
707 sub has_linkage_group
{
709 my $candidate = shift;
711 $candidate=~ s/\s*(.*)\s*/$1/;
712 foreach my $n (map $_->{lg_name
} , @
{$self->linkage_groups()}) {
713 #print STDERR "comparing $n with $candidate...\n";
714 if ($candidate =~ /^$n$/i) {
715 #print STDERR "Yip!\n";
722 =head2 function get_centromere
724 Synopsis: my ($north, $south, $center) = $map->get_centromere($lg_name)
725 Arguments: a valid linkage group name
726 Returns: a three member list, the first element corresponds
727 to the north boundary of the centromere in cM
728 the second corresponds to the south boundary of
729 the centromere in cM, the third is the arithmetic mean
730 of the two first values.
740 if (! $self->has_linkage_group($lg)) {
741 die "Not a valid linkage group for this map!\n";
744 my $lg_hash = $self->get_linkage_group_hash($lg);
745 # foreach my $k (keys %$lg_hash) {
746 # print " $k, $lg_hash->{$k}\n";
748 my $north = $lg_hash->{north_centromere
} || 0;
749 my $south = $lg_hash->{south_centromere
} || 0;
750 return ($north, $south, int(($north+$south)/2));
753 sub get_linkage_group_hash
{
756 foreach my $lg_hash (@
{$self->linkage_groups()}) {
757 if ($lg_hash->{lg_name
} eq $lg_name) {