1 package CXGN
::Phenome
::Locus
;
12 Access the phenome.locus table, find, add, and delete associated data
13 (images, alleles, dbxrefs, owners, cvterms, publications, etc.)
17 Naama Menda <nm249@cornell.edu>
24 use CXGN
::Phenome
::Allele
;
25 use CXGN
::Phenome
::LocusSynonym
;
26 use CXGN
::Phenome
::LocusMarker
;
27 use CXGN
::Phenome
::Locus
::LocusHistory
;
29 use CXGN
::Phenome
::LocusDbxref
;
30 use CXGN
::Phenome
::Locus
::LocusRanking
;
31 use CXGN
::Transcript
::Unigene
;
32 use CXGN
::Phenome
::Schema
;
33 use CXGN
::Phenome
::LocusGroup
;
35 use CXGN
::Chado
::Dbxref
;
37 use Bio
::Chado
::Schema
;
39 use base qw
/ CXGN::DB::ModifiableI CXGN::Phenome::Locus::LocusRanking /;
43 Usage: my $gene = CXGN::Phenome::Locus->new($dbh,$locus_id);
55 my $id= shift; # the primary key in the databaes of this object
57 unless( $dbh->can('selectall_arrayref') ) {
58 die "First argument to CXGN::Phenome::Locus constructor needs to be a database handle.";
60 my $self=$class->SUPER::new
($dbh);
62 $self->set_locus_id($id);
65 $self->fetch($id); #get the locus details
68 my $locus_marker_query=$self->get_dbh()->prepare(
69 "SELECT distinct locus_marker_id from phenome.locus_marker
70 JOIN sgn.marker_alias USING (marker_id)
71 JOIN sgn.marker_experiment USING (marker_id)
72 JOIN sgn.marker_location USING (location_id)
73 JOIN sgn.map_version USING (map_version_id)
74 WHERE current_version = 't' AND locus_id=?");
76 $locus_marker_query->execute($id);
77 while (my ($lm) = $locus_marker_query->fetchrow_array() ) {
78 push @locus_marker, $lm;
80 for my $lm_id (@locus_marker) {
82 my $locus_marker_obj = CXGN
::Phenome
::LocusMarker
->new($dbh, $lm_id);
83 $self->add_locus_marker($locus_marker_obj);
86 my @dbxrefs= $self->get_dbxrefs();
87 foreach my $d(@dbxrefs) { $self->add_dbxref(); }
92 =head2 new_with_symbol_and_species
94 Usage: CXGN::Phenome::Locus->new_with_symbol_and_species($dbh, $symbol,$species)
95 Desc: instanciate a new locus object using a symbol and a common_name
97 Args: dbh, symbol, and common_name
103 sub new_with_symbol_and_species
{
108 my $query = "SELECT locus_id FROM phenome.locus JOIN sgn.common_name using(common_name_id) WHERE locus_symbol=? AND common_name ilike ?";
109 my $sth = $dbh->prepare($query);
110 $sth->execute($symbol, $species);
111 my ($id) = $sth->fetchrow_array();
112 return $class->new($dbh, $id);
115 =head2 new_with_locusname
117 Usage: CXGN::Phenome::Locus->new_locusname($dbh, $genome_locus_name)
118 Desc: instanciate a new locus object using the locus field
120 Args: dbh, locus genome identifier (e.g. Solyc01g0000010)
125 sub new_with_locusname
{
128 my $locusname = shift;
129 my $query = "SELECT locus_id FROM phenome.locus WHERE locus ilike ? and obsolete = ? ";
130 my $sth = $dbh->prepare($query);
131 $sth->execute($locusname, 'f');
132 my ($id) = $sth->fetchrow_array();
133 return $class->new($dbh, $id);
139 =head2 get_locus_ids_by_editor
141 Usage: my @loci = CXGN::Phenome::Locus::get_loci_by_editor($dbh, 239)
142 Desc: returns a list of locus ids that belong to the given
143 editor. Class function.
144 Args: a database handle and a sp_person_id of the editor
145 Side Effects: accesses the database
150 sub get_locus_ids_by_editor
{
152 my $sp_person_id = shift;
153 my $query = "SELECT locus_id FROM phenome.locus JOIN phenome.locus_owner USING(locus_id)
154 WHERE locus_owner.sp_person_id=? AND locus.obsolete = 'f' ORDER BY locus.modified_date desc, locus.create_date desc";
155 my $sth = $dbh->prepare($query);
156 $sth->execute($sp_person_id);
158 while (my($locus_id) = $sth->fetchrow_array()) {
159 push @loci, $locus_id;
165 =head2 get_locus_ids_by_annotator
167 Usage: my @loci=CXGN::Phenome::Locus::get_loci_by_annotator($dbh, $sp_person_id)
168 Desc: returns a list of locus ids that belong to the given
169 contributing annotator. Class function.
170 Args: a database handle and a sp_person_id of the submitter
171 Side Effects: accesses the database
176 sub get_locus_ids_by_annotator
{
178 my $sp_person_id = shift;
180 my $query= "SELECT distinct locus.locus_id, locus.modified_date FROM phenome.locus
181 LEFT JOIN phenome.locus_dbxref USING (locus_id)
182 LEFT JOIN phenome.locus_unigene using (locus_id)
183 LEFT JOIN phenome.locus_marker using (locus_id)
184 LEFT JOIN phenome.locus_alias using (locus_id)
185 LEFT JOIN phenome.locus2locus ON (phenome.locus.locus_id = locus2locus.subject_id
186 OR phenome.locus.locus_id = locus2locus.subject_id )
187 JOIN phenome.allele USING (locus_id)
188 LEFT JOIN phenome.individual_allele USING (allele_id)
189 LEFT JOIN phenome.individual USING (individual_id)
190 LEFT JOIN phenome.individual_image USING (individual_id)
191 LEFT JOIN metadata.md_image USING (image_id)
193 WHERE locus.updated_by=? OR locus_dbxref.sp_person_id=? OR locus_unigene.sp_person_id=?
194 OR locus_marker.sp_person_id=? OR allele.sp_person_id=? OR locus_alias.sp_person_id=?
195 OR individual_allele.sp_person_id=? OR metadata.md_image.sp_person_id=? OR locus2locus.sp_person_id =?
196 ORDER BY locus.modified_date DESC";
199 my $sth = $dbh->prepare($query);
200 $sth->execute($sp_person_id, $sp_person_id, $sp_person_id, $sp_person_id, $sp_person_id, $sp_person_id, $sp_person_id, $sp_person_id, $sp_person_id);
202 while (my($locus_id, $modified_date) = $sth->fetchrow_array()) {
203 push @loci, $locus_id;
212 my $dbh=$self->get_dbh();
213 my $locus_query = "SELECT locus_id,locus,locus_name, locus_symbol, original_symbol, gene_activity, description, locus.sp_person_id, locus.create_date, locus.modified_date, linkage_group, lg_arm, common_name, common_name_id, updated_by, locus.obsolete
215 JOIN sgn.common_name USING(common_name_id)
217 my $sth=$dbh->prepare($locus_query);
218 $sth->execute($self->get_locus_id());
220 my ($locus_id,$genome_locus, $locus_name,$locus_symbol,$original_symbol, $gene_activity, $description, $sp_person_id, $create_date, $modified_date, $chromosome, $arm, $common_name, $common_name_id, $updated_by, $obsolete)=$sth->fetchrow_array();
221 $self->set_locus_id($locus_id);
222 $self->set_genome_locus($genome_locus);
223 $self->set_locus_name($locus_name);
224 $self->set_locus_symbol($locus_symbol);
225 $self->set_original_symbol($original_symbol);
226 $self->set_gene_activity($gene_activity);
227 $self->set_description($description);
229 $self->set_sp_person_id($sp_person_id);
230 $self->set_create_date($create_date);
231 $self->set_modification_date($modified_date);
232 $self->set_linkage_group($chromosome);
233 $self->set_lg_arm($arm);
234 $self->set_common_name($common_name);
235 $self->set_common_name_id($common_name_id);
236 $self->set_updated_by($updated_by);
237 $self->set_obsolete($obsolete);
240 =head2 exists_in_database
242 Usage: my $existing_locus_id = CXGN::Phenome::Locus::exists_in_database();
243 Desc: check if a locus symbol or name for a given organism exists in the database
244 Ret: an error message for the given symbol, name, and common_name_id
252 sub exists_in_database
{
254 my $locus_name=shift;
255 my $locus_symbol=shift;
257 my $locus_id= $self->get_locus_id();
258 my $common_name_id= $self->get_common_name_id();
259 if (!$locus_name) { $locus_name=$self->get_locus_name(); }
260 if (!$locus_symbol) { $locus_symbol=$self->get_locus_symbol(); }
261 $self->d("Locus.pm: exists_in _database--**$locus_name, $locus_symbol \n");
263 my $name_query = "SELECT locus_id, obsolete
265 WHERE locus_name ILIKE ? and common_name_id = ? ";
266 my $name_sth = $self->get_dbh()->prepare($name_query);
267 $name_sth->execute($locus_name, $common_name_id );
268 my ($name_id, $name_obsolete)= $name_sth->fetchrow_array();
270 my $symbol_query = "SELECT locus_id, obsolete
272 WHERE locus_symbol ILIKE ? and common_name_id = ? ";
273 my $symbol_sth = $self->get_dbh()->prepare($symbol_query);
274 $symbol_sth->execute($locus_symbol, $common_name_id );
275 my ($symbol_id, $symbol_obsolete) = $symbol_sth->fetchrow_array();
277 #loading new locus- $locus_id is undef
278 if (!$locus_id && ($name_id || $symbol_id) ) {
281 $message = "Existing name $name_id";
284 $message = "Existing symbol $symbol_id";
286 $self->d("***$message\n");
287 return ( $message ) ;
289 #trying to update a locus.. if both the name and symbol remain- it's probably an update of
290 #the other fields in the form
291 if ($locus_id && $symbol_id) {
292 if ( ($name_id==$locus_id) && ($symbol_id==$locus_id) ) {
293 $self->d("--locus.pm exists_in_database returned 0.......\n");
295 #trying to update the name and/or the symbol
296 } elsif ( ($name_id!=$locus_id && $name_id) || ($symbol_id!=$locus_id && $symbol_id)) {
297 my $message = " Can't update an existing locus $locus_id name:$name_id symbol:$symbol_id.";
298 $self->d("++++Locus.pm exists_in_database: $message\n");
300 # if the new name or symbol we're trying to update/insert do not exist in the locus table..
302 $self->d("--locus.pm exists_in_database returned 0.......\n");
311 #add another check here with a die/error message for loading scripts
312 my $exists= $self->exists_in_database();
313 die "Locus exists in database! Cannot insert or update! \n $exists \n " if $exists;
314 my $locus_id=$self->get_locus_id();
317 $self->store_history();
319 my $query = "UPDATE phenome.locus SET
329 modified_date = now(),
332 my $sth= $self->get_dbh()->prepare($query);
333 $sth->execute($self->get_genome_locus,$self->get_locus_name, $self->get_locus_symbol, $self->get_original_symbol, $self->get_gene_activity, $self->get_description, $self->get_linkage_group(), $self->get_lg_arm(), $self->get_updated_by(), $self->get_obsolete(), $locus_id );
335 foreach my $dbxref ( @
{$self->{locus_dbxrefs
}} ) {
336 my $locus_dbxref_obj= CXGN
::Phenome
::LocusDbxref
->new($self->get_dbh());
337 #$locus_dbxref_obj->store(); # what do I want to store here?
339 $self->d("Locus.pm store: Updated locus $locus_id ......+\n");
340 #Update locus_alias 'preferred' field
341 $self->update_locus_alias();
345 my $query = "INSERT INTO phenome.locus (locus,locus_name, locus_symbol, original_symbol, gene_activity, description, linkage_group, lg_arm, common_name_id, create_date) VALUES(?,?,?,?,?,?,?,?,?, now()) RETURNING locus_id";
346 my $sth= $self->get_dbh()->prepare($query);
347 $sth->execute($self->get_genome_locus, $self->get_locus_name, $self->get_locus_symbol, $self->get_original_symbol, $self->get_gene_activity, $self->get_description, $self->get_linkage_group(), $self->get_lg_arm(), $self->get_common_name_id);
349 ($locus_id) = $sth->fetchrow_array;
350 $self->set_locus_id($locus_id);
352 my $locus_owner_query="INSERT INTO phenome.locus_owner (locus_id, sp_person_id) VALUES (?,?)";
353 my $locus_owner_sth=$self->get_dbh()->prepare($locus_owner_query);
354 $locus_owner_sth->execute($locus_id, $self->get_sp_person_id());
356 my $alias_query= "INSERT INTO phenome.locus_alias(locus_id, alias, preferred) VALUES (?, ?,'t')";
357 my $alias_sth= $self->get_dbh()->prepare($alias_query);
358 $alias_sth->execute($self->get_locus_id(), $self->get_locus_symbol());
360 #the following query will insert a 'dummy' default allele. Each locus must have a default allele.
361 # This is important for associating individuals with loci. The locus_display code masks the dummy alleles.
362 my $allele= CXGN
::Phenome
::Allele
->new($self->get_dbh());
363 $allele->set_locus_id($locus_id);
364 $allele->set_allele_symbol( uc($self->get_locus_symbol) );
365 $allele->set_is_default('t');
368 $self->d("***#####Locus.pm store: inserting new locus $locus_id....\n");
371 if ($@
) { warn "locus.pm store failed! \n $@ \n" }
377 Usage: $self->delete()
378 Desc: set the locus to obsolete=t
381 Side Effects: sets locus name and symbol to 'ob$locus_id-$locus_name'
382 obsoletes the associated alleles (see Allele.pm: delete() )
389 my $locus_id = $self->get_locus_id();
390 $self->set_locus_symbol("ob". $self->get_locus_id() . "-" .$self->get_locus_symbol() );
391 $self->set_locus_name("ob" . $self->get_locus_id() . "-" . $self->get_locus_name() );
392 my $ob=$self->get_obsolete();
393 if ($ob eq 'f' && $locus_id) {
394 $self->d("Locus.pm is obsoleting locus " . $self->get_locus_id() . "(obsolete=$ob)!!!!\n");
395 $self->set_obsolete('t');
398 $self->d("trying to delete a locus that has not yet been stored to db.\n");
404 Usage: $self->remove_allele($allele_id)
405 Desc: set an allele of this locus to obsolete
408 Side Effects: updates the obsolete field in the allele table to 't'
414 my $allele_id = shift;
415 my $query = "UPDATE phenome.allele
417 WHERE locus_id=? AND allele_id=?";
418 my $sth = $self->get_dbh()->prepare($query);
419 $sth->execute($self->get_locus_id(), $allele_id);
422 =head2 remove_locus_alias
424 Usage: $self->remove_locus_alias($locus_alias_id)
425 Desc: delete a locus alias from the locus_alias table
427 Args: $locus_alias_id
428 Side Effects: deletes a row from the locus_alias table
433 sub remove_locus_alias
{
435 my $locus_synonym_id = shift;
436 my $query = "DELETE FROM phenome.locus_alias WHERE locus_id=? AND locus_alias_id=?";
437 my $sth = $self->get_dbh()->prepare($query);
438 $sth->execute($self->get_locus_id(), $locus_synonym_id);
441 =head2 update_locus_alias
443 Usage: $self->update_locus_alias()
444 Desc: after updating the locus synonym field, we need to make that synonym the
445 'preferred' alias, and set the currently preferred one to 'f'
448 Side Effects: updating rows in the locus_alias table
453 sub update_locus_alias
{
455 my $symbol= $self->get_locus_symbol();
456 my @aliases= $self->get_locus_aliases();
458 foreach my $a ( @aliases) {
459 my $alias=$a->get_locus_alias();
460 if ($alias eq $symbol) {
461 $self->d("alias = $alias , symbol =$symbol, preferred=" . $a->get_preferred() . " Setting prefrred = 't'\n");
462 $a->set_preferred('t');
465 elsif ($a->get_preferred() ==1) {
466 $self->d( "alias = $alias , symbol =$symbol, preferred=" . $a->get_preferred() . " Setting prefrred = 'f'\n");
467 $a->set_preferred('f');
477 Usage: $self->get_unigenes({full=>1, current=>1})
478 Desc: find unigenes associated with the locus
479 Ret: list of (lite) unigene objects (without the sequences- much faster)
480 Args: optional hashref with the following keys:
481 full (1) - get a list of full unigene objects
482 (much slower, but important if you want to access the sequences of the unigens)
483 current(1) - fetch only current unigenes
492 my $full = $opts->{full
};
493 my $current = $opts->{current
};
494 my $query = "SELECT unigene_id FROM phenome.locus_unigene";
495 $query .= " JOIN sgn.unigene USING (unigene_id) JOIN sgn.unigene_build USING (unigene_build_id) ";
496 $query .= " WHERE locus_id=? AND obsolete = 'f' ";
497 $query .= " AND status = 'C' " if $current;
499 my $sth = $self->get_dbh()->prepare($query);
500 $sth->execute($self->get_locus_id());
503 while (my ($unigene_id) = $sth->fetchrow_array()) {
504 if ($full) { $unigene = CXGN
::Transcript
::Unigene
->new($self->get_dbh(), $unigene_id); }
505 else { $unigene = CXGN
::Transcript
::Unigene
->new_lite_unigene($self->get_dbh(), $unigene_id); }
506 push @unigenes, $unigene;
511 =head2 get_locus_unigene_id
513 Usage: my $locus_unigene_id= $locus->get_locus_unigene_id($unigene_id)
514 Desc: find the locus_unigene database id for a given unigene id
515 useful for manipulating locus_unigene table (like obsoleting a locus-unigene association)
516 since we do not have a LocusUnigene object (not sure an object is necessary if all is done from the Locus object)
518 Ret: a database id from the table phenome.locus_unigene
525 sub get_locus_unigene_id
{
527 my $unigene_id=shift;
528 my $query= "SELECT locus_unigene_id FROM phenome.locus_unigene
529 WHERE locus_id=? AND unigene_id=?";
530 my $sth=$self->get_dbh()->prepare($query);
531 $sth->execute($self->get_locus_id(), $unigene_id);
532 my ($locus_unigene_id) = $sth->fetchrow_array();
533 return $locus_unigene_id;
538 Usage: $self->add_unigene($unigene_id, $sp_person_id)
539 Desc: store a unigene-locus association in the database. If the link exists the function will set obsolete=f
541 Args: unigene_id, sp_person_id
542 Side Effects: access the database. Adds a locus_dbxref for SolCyc reactions which are linked to $unigene_id
543 (see table unigene_dbxref)
550 my $unigene_id=shift;
551 my $sp_person_id=shift;
552 my $existing_id= $self->get_locus_unigene_id($unigene_id);
555 $self->d("Locus::add_unigene is updating locus_unigene_id $existing_id!!!!!!");
556 my $u_query="UPDATE phenome.locus_unigene SET obsolete='f' WHERE locus_unigene_id=?";
557 my $u_sth=$self->get_dbh()->prepare($u_query);
558 $u_sth->execute($existing_id);
561 $self->d( "Locus:add_unigene is inserting a new unigene $unigene_id for locus " . $self->get_locus_id() . " (by person $sp_person_id) !!!");
562 my $query="Insert INTO phenome.locus_unigene (locus_id, unigene_id,sp_person_id) VALUES (?,?,?) RETURNING locus_unigene_id " ;
563 my $sth=$self->get_dbh->prepare($query);
564 $sth->execute($self->get_locus_id(), $unigene_id, $sp_person_id);
565 my ($id) = $sth->fetchrow_array;
568 #see if the unigene has solcyc links
570 my $dbh=$self->get_dbh;
571 my $unigene= CXGN
::Transcript
::Unigene
->new($dbh, $unigene_id);
572 my @u_dbxrefs= $unigene->get_dbxrefs();
573 foreach my $d(@u_dbxrefs) {
574 $self->add_locus_dbxref($d, undef, $sp_person_id) if $d->get_db_name() eq 'solcyc_images';
578 =head2 obsolete_unigene
580 Usage: $self->obsolete_unigene
581 Desc: set locus_unigene to obsolete
583 Args: locus_unigene_id
589 sub obsolete_unigene
{
592 my $u_query="UPDATE phenome.locus_unigene SET obsolete='t' WHERE locus_unigene_id=?";
593 my $u_sth=$self->get_dbh()->prepare($u_query);
594 $u_sth->execute($lu_id);
598 =head2 get_associated_loci DEPRECATED. SEE get_locusgroups
601 Usage: my @locus_ids = $locus->get_associated_loci()
602 Desc: return the loci that are associated to this
603 locus from the locus2locus table
604 Ret: a list of locus ids
612 sub get_associated_loci
{
613 warn("DEPRECATED. SEE get_locusgroups() !!!!!!!\n");
616 my $query = "SELECT object_id FROM phenome.locus2locus WHERE obsolete = 'f' AND subject_id=?";
617 my $sth = $self->get_dbh()->prepare($query);
618 $sth->execute($self->get_locus_id());
620 while (my ($associated_locus) = $sth->fetchrow_array()) {
621 push @associated_loci, $associated_locus;
623 return @associated_loci;
628 =head2 get_reciprocal_loci DEPRECATED - SEE get_locusgroups()
629 Usage: my $locus_ids = $locus->get_reciprocal_loci()
630 Desc: returns the loci that this locus is associated to
631 in the locus2locus table
640 sub get_reciprocal_loci
{
641 warn("DEPRECATED. SEE get_locusgroups() !!!!!!!\n");
643 my $query = "SELECT DISTINCT subject_id FROM phenome.locus2locus WHERE obsolete = 'f' AND object_id=?";
644 my $sth = $self->get_dbh()->prepare($query);
645 $sth->execute($self->get_locus_id());
647 while (my ($reciprocal_locus) = $sth->fetchrow_array()) {
648 push @reciprocal_loci, $reciprocal_locus;
650 return @reciprocal_loci;
655 =head2 get_subject_locus2locus_objects DEPRECATED. SEE get_locusgroups()
658 Usage: @l2l = $locus->get_subject_locus2locus_objects()
659 Desc: returns all associated locus2locus objects, including
660 object and subject id based ones.
661 Ret: a list of CXGN::Phenome::Locus2Locus objects
668 sub get_subject_locus2locus_objects
{
669 warn("DEPRECATED. SEE get_locusgroups() !!!!!!!\n");
673 my $q = "SELECT DISTINCT locus2locus_id FROM phenome.locus2locus WHERE (subject_id=?) and obsolete='f'";
674 my $sth = $self->get_dbh()->prepare($q);
675 $sth->execute($self->get_locus_id());
677 while( my ($l2l) = $sth->fetchrow_array()) {
678 push @l2l, CXGN
::Phenome
::Locus2Locus
->new($self->get_dbh(), $l2l);
685 =head2 get_object_locus2locus_objects DEPRECATED. SEE get_locusgroups()
688 Usage: @l2l = $locus->get_object_locus2locus_objects()
689 Desc: returns all associated locus2locus objects, including
691 Ret: a list of CXGN::Phenome::Locus2Locus objects
698 sub get_object_locus2locus_objects
{
699 warn("DEPRECATED. SEE get_locusgroups() !!!!!!!\n");
703 my $q = "SELECT DISTINCT locus2locus_id FROM phenome.locus2locus WHERE object_id=? and obsolete='f'";
704 my $sth = $self->get_dbh()->prepare($q);
705 $sth->execute($self->get_locus_id());
707 while( my ($l2l) = $sth->fetchrow_array()) {
708 push @l2l, CXGN
::Phenome
::Locus2Locus
->new($self->get_dbh(), $l2l);
714 =head2 add_related_locus
716 Usage: $self->add_related_locus($locus_id)
717 Desc: an accessor for building an associated locus list for the locus
725 sub add_related_locus
{
728 push @
{ $self->{related_loci
} }, $locus;
732 =head2 accessors available (get/set)
749 return $self->{locus_id
};
755 $self->{locus_id
}=shift;
761 return $self->{locus_name
};
767 $self->{locus_name
}=shift;
770 sub get_locus_symbol
{
772 return $self->{locus_symbol
};
776 sub set_locus_symbol
{
778 $self->{locus_symbol
}=shift;
782 sub get_original_symbol
{
784 return $self->{original_symbol
};
788 sub set_original_symbol
{
790 $self->{original_symbol
}=shift;
793 sub get_gene_activity
{
795 return $self->{gene_activity
};
799 sub set_gene_activity
{
801 $self->{gene_activity
}=shift;
805 sub get_description
{
807 return $self->{description
};
811 sub set_description
{
813 $self->{description
}=shift;
817 sub get_linkage_group
{
819 return $self->{linkage_group
};
823 sub set_linkage_group
{
825 $self->{linkage_group
}=shift;
831 return $self->{lg_arm
};
837 $self->{lg_arm
}=shift;
841 sub get_common_name
{
843 return $self->{common_name
};
847 sub set_common_name
{
849 $self->{common_name
}=shift;
853 sub get_common_name_id
{
855 return $self->{common_name_id
};
859 sub set_common_name_id
{
861 $self->{common_name_id
}=shift;
864 sub get_genome_locus
{
866 return $self->{genome_locus
};
869 sub set_genome_locus
{
871 $self->{genome_locus
} = shift;
875 =head2 add_locus_alias
877 Usage: $self->add_locus_alias($locus_synonym_object)
878 Desc: add an alias to the locus
879 Ret: a locus_alias id
880 Args: LocusSynonym object
881 Side Effects: accesses the database
886 sub add_locus_alias
{
888 my $locus_alias = shift; #LocusSynonym object!!
889 $locus_alias->set_locus_alias_id(); #set the id to undef in case of the function was called from the merge_locus function
890 $locus_alias->set_locus_id($self->get_locus_id());
891 my $symbol = $self->get_locus_symbol();
892 #if the locus symbol and the alias are the same, then set the new alias to preferred = 't'
893 if ($symbol eq $locus_alias->get_locus_alias()) {
894 $locus_alias->set_preferred('t');
896 my $id=$locus_alias->store();
901 =head2 get_locus_aliases
903 Usage: $self->get_locus_aliases()
904 Desc: find the aliases of a locus
905 Ret: list of LocusSynonym objects
906 Args: optional : preffered and obsolete booleans
912 sub get_locus_aliases
{
914 my ($preferred, $obsolete) = @_;
915 my $query="SELECT locus_alias_id from phenome.locus_alias WHERE locus_id=? ";
916 $query .= " AND preferred = '$preferred' " if $preferred;
917 $query .= " AND obsolete = '$obsolete' " if $obsolete;
918 my $sth=$self->get_dbh()->prepare($query);
920 $sth->execute($self->get_locus_id());
921 while (my ($ls_id) = $sth->fetchrow_array()) {
922 my $lso=CXGN
::Phenome
::LocusSynonym
->new($self->get_dbh(), $ls_id);
923 push @locus_synonyms, $lso;
925 return @locus_synonyms;
930 Usage: $self->add_allele($allele)
931 Desc: add an allele to the locus
932 Ret: the new allele_id
934 Side Effects: accessed the database, Calls Allele->store().
941 my $allele=shift; #allele object
942 $allele->set_locus_id($self->get_locus_id() );
943 my $id = $allele->store();
947 =head2 add_allele_symbol
949 Usage: $self->add_allele_symbol($allele_symbol)
950 Desc: an accessor for building an allele list for the locus
958 sub add_allele_symbol
{
960 my $allele=shift; #allele symbol
961 push @
{ $self->{allele_symbols
} }, $allele;
966 Usage: my @alleles=$self->get_alleles()
967 Desc: find the alleles associated with the locus
968 Ret: a list of allele objects
977 $self->d("Getting alleles.... \n\n");
978 my $allele_query=("SELECT allele_id FROM phenome.allele WHERE locus_id=? AND obsolete='f' AND is_default='f'");
979 my $sth=$self->get_dbh()->prepare($allele_query);
981 $sth->execute($self->get_locus_id());
982 while (my ($a_id) = $sth->fetchrow_array()) {
983 my $allele= CXGN
::Phenome
::Allele
->new($self->get_dbh(), $a_id);
984 push @alleles, $allele;
988 =head2 get_default_allele
990 Usage: $self->get_default_allele()
991 Desc: find the database id from the default allele
999 sub get_default_allele
{
1001 my $query = "SELECT allele_id from phenome.allele
1002 WHERE locus_id = ? AND is_default = 't'";
1003 my $sth=$self->get_dbh()->prepare($query);
1004 $sth->execute($self->get_locus_id());
1005 my ($allele_id) = $sth->fetchrow_array();
1022 my $synonym=shift; #synonym
1023 push @
{ $self->{synonyms
} }, $synonym;
1041 my $dbxref=shift; #dbxref object
1042 push @
{ $self->{dbxrefs
} }, $dbxref;
1047 Usage: $locus->get_dbxrefs();
1048 Desc: get all the dbxrefs associated with a locus
1049 Ret: array of dbxref objects
1051 Side Effects: accesses the database
1058 my $locus_id=$self->get_locus_id();
1060 my $dbxref_query="SELECT locus_dbxref.dbxref_id from phenome.locus_dbxref JOIN public.dbxref USING(dbxref_id) WHERE locus_id=? ORDER BY public.dbxref.accession";
1061 my $sth=$self->get_dbh()->prepare($dbxref_query);
1063 my @dbxrefs=(); #an array for storing dbxref objects
1064 $sth->execute($locus_id);
1065 while (my ($d) = $sth->fetchrow_array() ) {
1066 $dbxref= CXGN
::Chado
::Dbxref
->new($self->get_dbh(), $d);
1067 push @dbxrefs, $dbxref;
1072 =head2 get_dbxrefs_by_type
1074 Usage: $locus->get_dbxrefs_by_type("ontology");
1075 Desc: get all the dbxrefs terms associated with a locus
1076 Ret: array of dbxref objects
1077 Args: type (ontology, literature, genbank)
1078 Side Effects: accesses the database
1083 sub get_dbxrefs_by_type
{
1086 my $locus_id=$self->get_locus_id();
1088 my $dbh = $self->get_dbh();
1090 if ($type eq 'ontology') {
1091 $query="SELECT locus_dbxref.dbxref_id from phenome.locus_dbxref
1092 JOIN public.dbxref USING(dbxref_id)
1093 JOIN public.cvterm USING (dbxref_id)
1094 WHERE locus_id=? ORDER BY public.dbxref.accession";
1095 }elsif ($type eq 'literature') {
1096 $query="SELECT locus_dbxref.dbxref_id from phenome.locus_dbxref
1097 JOIN public.dbxref USING(dbxref_id)
1098 JOIN public.db USING (db_id)
1099 WHERE locus_id=? AND db.name IN ('PMID','SGN_ref') ORDER BY public.dbxref.accession";
1100 }elsif ($type eq 'genbank') {
1101 $query="SELECT locus_dbxref.dbxref_id from phenome.locus_dbxref
1102 JOIN public.dbxref USING(dbxref_id)
1103 JOIN public.db USING (db_id)
1104 WHERE locus_id=? AND db.name IN ('DB:GenBank_GI')
1105 AND locus_dbxref.obsolete= 'f' ORDER BY public.dbxref.accession";
1106 }else { warn "dbxref type '$type' not recognized! \n" ; return undef; }
1107 my $sth=$self->get_dbh()->prepare($query);
1109 my @dbxrefs=(); #an array for storing dbxref objects
1110 $sth->execute($locus_id);
1111 while (my ($d) = $sth->fetchrow_array() ) {
1112 $dbxref= CXGN
::Chado
::Dbxref
->new($self->get_dbh(), $d);
1113 push @dbxrefs, $dbxref;
1118 =head2 get_dbxref_lists
1120 Usage: $locus->get_dbxref_lists();
1121 Desc: get all the dbxrefs terms associated with a locus
1122 Ret: hash of 2D arrays . Keys are the db names values are [dbxref object, locus_dbxref.obsolete]
1129 sub get_dbxref_lists
{
1132 my $query= "SELECT db.name, dbxref.dbxref_id, locus_dbxref.obsolete FROM locus_dbxref
1133 JOIN public.dbxref USING (dbxref_id) JOIN public.db USING (db_id)
1134 WHERE locus_id= ? ORDER BY db.name, dbxref.accession";
1135 my $sth=$self->get_dbh()->prepare($query);
1136 $sth->execute($self->get_locus_id());
1137 while (my ($db_name, $dbxref_id, $obsolete) = $sth->fetchrow_array()) {
1138 push @
{$dbxrefs{$db_name} }, [CXGN
::Chado
::Dbxref
->new($self->get_dbh(), $dbxref_id), $obsolete] ;
1143 =head2 get_all_dbxrefs
1154 sub get_all_dbxrefs
{
1156 my $locus_name = $locus->get_locus_name() ;
1157 my %dbs = $locus->get_dbxref_lists() ; #hash of arrays. keys=dbname values= dbxref objects
1158 my @alleles = $locus->get_alleles();
1159 #add the allele dbxrefs to the locus dbxrefs hash...
1160 #This way the alleles associated publications and sequences are also printed on the locus page
1161 #it might be a good idea to print a link to the allele next to each allele-derived annotation
1163 foreach my $a (@alleles) {
1164 my %a_dbs = $a->get_dbxref_lists();
1166 foreach my $a_db_name ( keys %a_dbs ) {
1167 #add allele_dbxrefs to the locus_dbxrefs list
1168 my %seen = () ; #hash for assisting filtering of duplicated dbxrefs (from allele annotation)
1169 foreach my $xref ( @
{ $dbs{$a_db_name} } ) {
1170 $seen{ $xref->[0]->get_accession() }++;
1171 } #populate with the locus_dbxrefs
1172 foreach my $axref ( @
{ $a_dbs{$a_db_name} } ) { #and filter duplicates
1173 push @
{ $dbs{$a_db_name} }, $axref
1174 unless $seen{ $axref->[0]->get_accession() }++;
1183 =head2 get_locus_dbxrefs
1185 Usage: $self->get_locus_dbxrefs()
1186 Desc: get the LocusDbxref objects associated with this locus
1187 Ret: a hash of arrays. Keys=db_name, values = lists of LocusDbxref objects
1194 sub get_locus_dbxrefs
{
1197 my $query= "SELECT db.name, locus_dbxref.locus_dbxref_id FROM locus_dbxref
1198 JOIN public.dbxref USING (dbxref_id) JOIN public.db USING (db_id)
1199 WHERE locus_id= ? ORDER BY db.name, dbxref.accession";
1200 my $sth=$self->get_dbh()->prepare($query);
1201 $sth->execute($self->get_locus_id());
1202 while (my ($db_name, $ld_id) = $sth->fetchrow_array()) {
1203 push @
{$lds{$db_name} }, CXGN
::Phenome
::LocusDbxref
->new($self->get_dbh(), $ld_id) ;
1209 =head2 add_locus_marker
1220 sub add_locus_marker
{
1222 push @
{ $self->{locus_markers
} }, shift;
1225 =head2 get_locus_markers
1236 sub get_locus_markers
{
1238 return @
{$self->{locus_markers
} || [] };
1242 =head2 get_locus_dbxref
1244 Usage: $locus->get_locus_dbxref($dbxref)
1245 Desc: access locus_dbxref object for a given locus and
1247 Ret: a LocusDbxref object
1249 Side Effects: accesses the database
1254 sub get_locus_dbxref
{
1256 my $dbxref=shift; # my dbxref object..
1257 my $query="SELECT locus_dbxref_id from phenome.locus_dbxref
1258 WHERE locus_id=? AND dbxref_id=? ";
1259 my $sth=$self->get_dbh()->prepare($query);
1260 $sth->execute($self->get_locus_id(), $dbxref->get_dbxref_id() );
1261 my ($locus_dbxref_id) = $sth->fetchrow_array();
1262 my $locus_dbxref= CXGN
::Phenome
::LocusDbxref
->new($self->get_dbh(), $locus_dbxref_id);
1263 return $locus_dbxref;
1266 =head2 add_locus_dbxref
1268 Usage: $locus->add_locus_dbxref($dbxref_object,
1271 Desc: adds a locus_dbxref relationship
1274 Side Effects: calls store function in LocusDbxref
1279 sub add_locus_dbxref
{
1281 my $dbxref=shift; #dbxref object
1282 my $locus_dbxref_id=shift;
1283 my $sp_person_id=shift;
1285 my $locus_dbxref=CXGN
::Phenome
::LocusDbxref
->new($self->get_dbh(), $locus_dbxref_id );
1286 $locus_dbxref->set_locus_id($self->get_locus_id() );
1287 $locus_dbxref->set_dbxref_id($dbxref->get_dbxref_id() );
1288 $locus_dbxref->set_sp_person_id($sp_person_id);
1289 if (!$dbxref->get_dbxref_id()) {return undef };
1291 my $id = $locus_dbxref->store();
1295 =head2 function get_individuals
1297 Synopsis: DEPRECATED. Use get_stock_ids
1298 my @individuals=$locus->get_individuals();
1306 sub get_individuals
{
1308 warn "DEPRECATED. Use get_stocks.";
1312 =head2 get_stock_ids
1314 Usage: my $stock_ids = $self->get_stock_ids
1315 Desc: find stocks associated with the locus
1316 Ret: a list of stock_ids
1325 my $query = "select distinct stock_id FROM phenome.stock_allele
1326 JOIN phenome.allele USING (allele_id)
1327 WHERE locus_id = ? AND allele.obsolete = ? ";
1328 my $ids = $self->get_dbh->selectcol_arrayref
1331 $self->get_locus_id,
1338 =head2 get_locus_registry_symbol
1340 Usage: $locus->get_locus_registry_symbol()
1341 Desc: get the registered symbol of a locus
1342 Ret: a registry object?
1349 sub get_locus_registry_symbol
{
1352 my $query=$self->get_dbh()->prepare("SELECT registry_id from phenome.locus_registry
1353 WHERE locus_id=? ");
1354 $query->execute($self->get_locus_id() );
1355 my ($registry_id) = $query->fetchrow_array();
1357 my $registry= CXGN
::Phenome
::Registry
->new($self->get_dbh(), $registry_id);
1359 }else { return undef; }
1364 =head2 store_history
1366 Usage: $self->store_history()
1367 Desc: Inserts the current fields of a locus object into
1368 the locus_history table before updating the locus details
1379 my $locus=CXGN
::Phenome
::Locus
->new($self->get_dbh(), $self->get_locus_id() );
1380 $self->d( "Locus.pm:*Storing history for locus " . $self->get_locus_id() . "\n");
1381 my $history_query = "INSERT INTO phenome.locus_history (locus_id, locus_name, locus_symbol, original_symbol,gene_activity,locus_description,linkage_group, lg_arm, sp_person_id, updated_by, obsolete, create_date)
1382 VALUES(?,?,?,?,?,?,?,?,?,?,?, now())";
1383 my $history_sth= $self->get_dbh()->prepare($history_query);
1385 $history_sth->execute($locus->get_locus_id(), $locus->get_locus_name(), $locus->get_locus_symbol(), $locus->get_original_symbol(), $locus->get_gene_activity(), $locus->get_description(), $locus->get_linkage_group(), $locus->get_lg_arm(), $locus->get_sp_person_id, $self->get_updated_by(), $locus->get_obsolete() );
1392 Usage: $locus->show_history();
1393 Desc: Selects the data from locus_history table for a locus object
1403 my $locus_id= $self->get_locus_id();
1404 my $history_query=$self->get_dbh()->prepare("SELECT locus_history_id FROM phenome.locus_history WHERE locus_id=?");
1406 $history_query->execute($locus_id);
1407 while (my ($history_id) = $history_query->fetchrow_array()) {
1408 my $history_obj = CXGN
::Phenome
::Locus
::LocusHistory
->new($self->get_dbh(), $history_id);
1409 push @history, $history_obj;
1414 =head2 get_associated_registry
1418 Ret: the Registry symbol
1425 sub get_associated_registry
{
1427 my $locus_id= $self->get_locus_id();
1428 my $registry_query=$self->get_dbh()->prepare("SELECT locus_registry.registry_id, registry.name FROM phenome.locus_registry JOIN phenome.registry USING (registry_id) WHERE locus_id=?");
1429 $registry_query->execute($locus_id);
1430 my ($registry_id, $name) = $registry_query->fetchrow_array();
1434 =head2 associated_publication
1436 Usage: my $associated= $locus->associated_publication($accession)
1437 Desc: checks if a publication is already associated with the locus
1439 Args: publication accession (pubmed ID)
1445 sub associated_publication
{
1448 my $accession=shift;
1449 my $query = $self->get_dbh()->prepare("SELECT dbxref_id FROM phenome.locus_dbxref JOIN dbxref USING (dbxref_id) WHERE locus_id = ? AND dbxref.accession = ? AND obsolete = 'f'");
1450 $query->execute($self->get_locus_id(), $accession);
1451 my ($is_associated) = $query->fetchrow_array();
1452 return $is_associated;
1455 =head2 get_recent_annotated_loci
1457 Usage: my %edits= CXGN::Phenome::Locus::get_recent_annotated_loci($dbh, $date)
1458 Desc: find all the loci annotated after date $date
1459 Ret: hash of arrays of locus objects, aliases, alleles, locus_dbxrefs, unigenes, markers,stocks, and images
1460 Args: database handle and a date
1466 sub get_recent_annotated_loci
{
1473 #get all created and modified loci
1475 my $locus_query="SELECT locus_id FROM phenome.locus WHERE modified_date>? OR create_date>?
1476 ORDER BY modified_date desc";
1477 my $locus_sth=$dbh->prepare($locus_query);
1478 $locus_sth->execute($date,$date);
1479 while (my($locus_id) = $locus_sth->fetchrow_array()) {
1480 my $locus= CXGN
::Phenome
::Locus
->new($dbh, $locus_id);
1481 push @
{ $edits{loci
} }, $locus;
1484 #get all created and modified aliases
1486 my $locus_alias_query="SELECT locus_alias_id FROM phenome.locus_alias
1487 WHERE (modified_date>? OR create_date>?) AND preferred='f'
1488 ORDER BY modified_date desc";
1489 my $locus_alias_sth=$dbh->prepare($locus_alias_query);
1490 $locus_alias_sth->execute($date,$date);
1491 while (my($locus_alias_id) = $locus_alias_sth->fetchrow_array()) {
1492 my $locus_alias= CXGN
::Phenome
::LocusSynonym
->new($dbh, $locus_alias_id);
1493 push @
{ $edits{aliases
} }, $locus_alias;
1495 #get all created and modified alleles
1497 my $allele_query="SELECT allele_id FROM phenome.allele
1498 WHERE (modified_date>? OR create_date>?) and is_default='f'
1499 ORDER BY modified_date desc";
1500 my $allele_sth=$dbh->prepare($allele_query);
1501 $allele_sth->execute($date,$date);
1502 while (my($allele_id) = $allele_sth->fetchrow_array()) {
1503 my $allele= CXGN
::Phenome
::Allele
->new($dbh, $allele_id);
1504 push @
{ $edits{alleles
} }, $allele;
1508 #get all locus_dbxrefs
1510 my $locus_dbxref_query="SELECT locus_dbxref_id FROM phenome.locus_dbxref
1511 WHERE (modified_date>? OR create_date>?)
1512 ORDER BY modified_date desc, create_date desc";
1513 my $locus_dbxref_sth=$dbh->prepare($locus_dbxref_query);
1514 $locus_dbxref_sth->execute($date,$date);
1516 while (my($locus_dbxref_id) = $locus_dbxref_sth->fetchrow_array()) {
1517 my $locus_dbxref= CXGN
::Phenome
::LocusDbxref
->new($dbh, $locus_dbxref_id);
1518 push @
{ $edits{locus_dbxrefs
} }, $locus_dbxref;
1522 #get associated images
1524 my $image_query="SELECT locus_id, image_id , sp_person_id, create_date, modified_date, obsolete
1525 FROM phenome.locus_image
1526 WHERE (modified_date>? OR create_date>?)
1527 ORDER BY modified_date desc, create_date desc";
1528 my $image_sth=$dbh->prepare($image_query);
1529 $image_sth->execute($date,$date);
1531 while (my($locus_id, $image_id, $person_id, $cdate, $mdate, $obsolete) = $image_sth->fetchrow_array()) {
1532 my $image= CXGN
::Image
->new($dbh, $image_id);
1533 my $locus=CXGN
::Phenome
::Locus
->new($dbh, $locus_id);
1534 push @
{ $edits{locus_images
} }, [$locus, $image, $person_id, $cdate, $mdate, $obsolete];
1538 #get associated stocks
1540 my $schema= Bio
::Chado
::Schema
->connect( sub { $dbh->clone } ) ;
1541 my $stock_query = "SELECT * FROM phenome.stock_allele join metadata.md_metadata USING (metadata_id) WHERE create_date>? OR modified_date>? ORDER BY modified_date DESC, create_date DESC";
1542 my $stock_sth = $dbh->prepare($stock_query);
1543 $stock_sth->execute($date, $date);
1544 while ( my $hashref = $stock_sth->fetchrow_hashref() ) {
1545 my $stock = CXGN
::Chado
::Stock
->new($schema, $hashref->{stock_id
} );
1546 my $allele = CXGN
::Phenome
::Allele
->new($dbh, $hashref->{allele_id
} );
1547 push @
{ $edits{stocks
} }, [$stock, $allele, $hashref->{create_person_id
}, $hashref->{create_date
}, $hashref->{modified_date
}, $hashref->{obsolete
}];
1550 #get associated unigenes
1552 my $locus_unigene_query="SELECT locus_id, unigene_id, sp_person_id, create_date, modified_date, obsolete
1553 FROM phenome.locus_unigene
1554 WHERE (modified_date>? OR create_date>?)
1555 ORDER BY modified_date DESC, create_date DESC";
1557 my $locus_unigene_sth=$dbh->prepare($locus_unigene_query);
1558 $locus_unigene_sth->execute($date,$date);
1560 while (my($locus_id, $unigene_id, $person_id, $cdate,$mdate, $obsolete) = $locus_unigene_sth->fetchrow_array()) {
1561 my $unigene= CXGN
::Transcript
::Unigene
->new_lite_unigene($dbh, $unigene_id);
1562 my $locus=CXGN
::Phenome
::Locus
->new($dbh, $locus_id);
1563 push @
{ $edits{locus_unigenes
} }, [$unigene,$locus, $person_id, $cdate, $mdate, $obsolete];
1566 #get associated markers
1567 my $locus_marker_query="SELECT locus_marker_id
1568 FROM phenome.locus_marker
1569 WHERE (modified_date>? OR create_date>?)
1570 ORDER BY modified_date DESC, create_date DESC";
1571 my $locus_marker_sth=$dbh->prepare($locus_marker_query);
1572 $locus_marker_sth->execute($date,$date);
1574 while (my ($locus_marker_id) = $locus_marker_sth->fetchrow_array()) {
1575 my $locus_marker= CXGN
::Phenome
::LocusMaker
->new($dbh, $locus_marker_id);
1576 push @
{ $edits{locus_markers
} }, $locus_marker;
1585 Usage: my %edits= CXGN::Phenome::Locus::get_edits($locus)
1586 Desc: find all annotations by date for this locus
1587 Ret: hash of arrays of aliases, alleles, locus_dbxrefs, unigenes, markers,stocks, and images
1597 my $dbh=$self->get_dbh();
1599 #get all locus edits (LocusHistory objects
1602 push @
{ $edits{loci
} }, $self->show_history();
1605 #get all created and modified aliases
1607 my $locus_alias_query="SELECT locus_alias_id FROM phenome.locus_alias
1609 ORDER BY modified_date desc, create_date desc";
1610 my $locus_alias_sth=$dbh->prepare($locus_alias_query);
1611 $locus_alias_sth->execute($self->get_locus_id());
1612 while (my($locus_alias_id) = $locus_alias_sth->fetchrow_array()) {
1613 my $locus_alias= CXGN
::Phenome
::LocusSynonym
->new($dbh, $locus_alias_id);
1614 push @
{ $edits{aliases
} }, $locus_alias;
1616 #get all created and modified alleles
1618 my $allele_query="SELECT allele_id FROM phenome.allele
1619 WHERE is_default='f' AND locus_id =?
1620 ORDER BY modified_date DESC, create_date DESC";
1621 my $allele_sth=$dbh->prepare($allele_query);
1622 $allele_sth->execute($self->get_locus_id());
1623 while (my($allele_id) = $allele_sth->fetchrow_array()) {
1624 my $allele= CXGN
::Phenome
::Allele
->new($dbh, $allele_id);
1625 push @
{ $edits{alleles
} }, $allele;
1629 #get all locus_dbxrefs
1631 my $locus_dbxref_query="SELECT locus_dbxref_id FROM phenome.locus_dbxref
1633 ORDER BY modified_date desc, create_date desc";
1634 my $locus_dbxref_sth=$dbh->prepare($locus_dbxref_query);
1635 $locus_dbxref_sth->execute($self->get_locus_id());
1637 while (my($locus_dbxref_id) = $locus_dbxref_sth->fetchrow_array()) {
1638 my $locus_dbxref= CXGN
::Phenome
::LocusDbxref
->new($dbh, $locus_dbxref_id);
1639 push @
{ $edits{locus_dbxrefs
} }, $locus_dbxref;
1643 #get associated images
1645 my $image_query="SELECT image_id , sp_person_id, create_date, modified_date, obsolete
1646 FROM phenome.locus_image
1648 ORDER BY modified_date desc, create_date desc";
1649 my $image_sth=$dbh->prepare($image_query);
1650 $image_sth->execute($self->get_locus_id);
1652 while (my($image_id, $person_id, $cdate, $mdate, $obsolete) = $image_sth->fetchrow_array()) {
1653 my $image= CXGN
::Image
->new($dbh, $image_id);
1654 push @
{ $edits{images
} }, [$image, $person_id, $cdate, $mdate, $obsolete];
1658 #get associated stocks
1660 # need to figure out a way for storing stockprops of type 'sgn allele_id' with storage date
1661 #push @{ $edits{individuals} }, $individual;
1665 #get associated unigenes
1667 my $locus_unigene_query="SELECT unigene_id, sp_person_id, create_date, modified_date, obsolete
1668 FROM phenome.locus_unigene
1670 ORDER BY modified_date DESC, create_date DESC";
1672 my $locus_unigene_sth=$dbh->prepare($locus_unigene_query);
1673 $locus_unigene_sth->execute($self->get_locus_id());
1675 while (my($unigene_id, $person_id, $cdate,$mdate, $obsolete) = $locus_unigene_sth->fetchrow_array()) {
1676 my $unigene= CXGN
::Transcript
::Unigene
->new($dbh, $unigene_id);
1677 push @
{ $edits{unigenes
} }, [$unigene, $person_id, $cdate, $mdate, $obsolete];
1680 #get associated markers
1681 my $locus_marker_query="SELECT marker_id FROM phenome.locus_marker
1683 ORDER BY modified_date DESC, create_date DESC";
1684 my $locus_marker_sth=$dbh->prepare($locus_marker_query);
1685 $locus_marker_sth->execute($self-get_locus_id
());
1687 while (my($locus_marker_id) = $locus_marker_sth->fetchrow_array()) {
1688 my $locus_marker= CXGN
::Phenome
::LocusMaker
->new($dbh, $locus_marker_id);
1689 push @
{ $edits{markers
} }, $locus_marker;
1696 =head2 function get_figures
1698 Synopsis: my @figures=$locus->get_figures();
1700 Returns: list of CXGN::image objects
1702 Description: all images are stored in the locus_image linking table
1708 my $query = "SELECT image_id FROM phenome.locus_image
1709 WHERE obsolete = 'f' and locus_id=?";
1710 my $sth = $self->get_dbh()->prepare($query);
1711 $sth->execute($self->get_locus_id());
1714 while (my ($image_id) = $sth->fetchrow_array()) {
1715 $image = CXGN
::Image
->new($self->get_dbh(), $image_id);
1716 push @images, $image;
1721 =head2 get_figure_ids
1723 Usage: $self->get_figure_ids
1724 Desc: get a list of image_ids for figures associated with the locus
1725 Ret: a list of image ids
1732 sub get_figure_ids
{
1734 my $query = "SELECT image_id FROM phenome.locus_image
1735 WHERE obsolete = 'f' and locus_id=?";
1736 my $sth = $self->get_dbh()->prepare($query);
1737 $sth->execute($self->get_locus_id());
1739 while (my ($image_id) = $sth->fetchrow_array()) {
1740 push @image_ids, $image_id;
1749 Usage: $self->add_figure($image_id, $sp_person_id)
1750 Desc: associate an existing image/figure with the locus
1751 Ret: database id (locus_image_id)
1752 Args: image_id, sp_person_id
1753 Side Effects: accesses the database
1761 my $sp_person_id=shift;
1762 my $query="Insert INTO phenome.locus_image (locus_id, image_id,sp_person_id) VALUES (?,?,?)";
1763 my $sth=$self->get_dbh->prepare($query);
1764 $sth->execute($self->get_locus_id(), $image_id, $sp_person_id);
1765 my $id= $self->get_currval("phenome.locus_image_locus_image_id_seq");
1772 Usage: my @owners=$locus->get_owners(1)
1773 Desc: get all the owners of the current locus object
1774 Ret: an array of SGN person ids
1775 Args: [optional] boolean - if passed then return an arrayref of people objects
1783 my $return_obj = shift;
1784 my $query = "SELECT sp_person_id FROM phenome.locus_owner
1785 WHERE locus_id = ? AND obsolete = 'f' ORDER BY create_date";
1786 my $sth=$self->get_dbh()->prepare($query);
1787 $sth->execute($self->get_locus_id());
1791 while (my ($sp_person_id) = $sth->fetchrow_array()) {
1792 $person = CXGN
::People
::Person
->new($self->get_dbh(), $sp_person_id);
1793 push @owners, $sp_person_id;
1794 push @o_objects, $person;
1796 return \
@o_objects if $return_obj;
1802 Usage: $self->add_owner($owner_id,$sp_person_id)
1803 Desc: assign a locus owner
1805 Args: owner_id, user_id
1806 Side Effects: insert a new locus_owner
1814 my $sp_person_id=shift;
1816 if (!$self->owner_exists($owner_id)) {
1818 my $query = "INSERT INTO phenome.locus_owner (sp_person_id, locus_id, granted_by)
1820 my $sth=$self->get_dbh()->prepare($query);
1821 $sth->execute($owner_id, $self->get_locus_id(), $sp_person_id);
1822 my $id= $self->get_currval("phenome.locus_owner_locus_owner_id_seq");
1823 $self->d( "Locus.pm:add_owner: added owner id: $owner_id, granted by: $sp_person_id\n");
1825 }else { return undef; }
1831 Usage: $self->owner_exists($sp_person_id)
1832 Desc: check if the locus already has owner $sp_person_id
1833 Ret: database id (locus_owner_id) or undef
1842 my $sp_person_id=shift;
1843 my $q= "SELECT locus_owner_id, obsolete FROM phenome.locus_owner WHERE locus_id=? AND sp_person_id=? ";
1844 my $sth=$self->get_dbh()->prepare($q);
1845 $sth->execute($self->get_locus_id(), $sp_person_id);
1846 my ($id, $ob)= $sth->fetchrow_array();
1847 return $id || undef;
1852 =head2 get_individual_allele_id
1854 Usage: DEPRECATED. allele_ids are now stored in stock_allele
1855 my $individual_allele_id= $locus->get_individual_allele_id($individual_id)
1856 Desc: find the individual_allele database id for a given individual id
1857 useful for manipulating individual_allele table (like obsoleting an individual-allele association)
1859 Ret: a database id from the table phenome.individual_allele
1860 Args: $individual_id
1866 sub get_individual_allele_id
{
1868 my $individual_id=shift;
1869 my $query= "SELECT individual_allele_id FROM phenome.individual_allele
1870 JOIN phenome.allele USING (allele_id)
1871 WHERE locus_id=? AND individual_id=?";
1872 my $sth=$self->get_dbh()->prepare($query);
1873 $sth->execute($self->get_locus_id(), $individual_id);
1874 my ($individual_allele_id) = $sth->fetchrow_array();
1875 return $individual_allele_id;
1878 =head2 get_associated_locus DEPRECATED. SEE get_locusgroups()
1880 Usage: $locus->get_associated_locus($associated_locus_id)
1881 Desc: get a locus2locus object of the locus (object) associated to the current locus (subject)
1882 Ret: a Locus2Locus object or undef
1883 Args: $associated_locus_id
1889 sub get_associated_locus
{
1890 warn("DEPRECATED. SEE get_locusgroups() !!!!!!!\n");
1893 my $associated_locus_id=shift;
1894 my $query = "SELECT locus2locus_id FROM phenome.locus2locus WHERE object_id=? AND subject_id = ? AND obsolete= 'f'";
1895 my $sth = $self->get_dbh()->prepare($query);
1896 $sth->execute($associated_locus_id, $self->get_locus_id());
1897 my ($l2l_id) = $sth->fetchrow_array();
1900 my $l2l=CXGN
::Phenome
::Locus2Locus
->new($self->get_dbh(), $l2l_id);
1902 } else { return undef };
1905 =head2 get_reciprocal_locus DEPRECATED. SEE get_locusgroups()
1908 Usage: $locus->get_reciprocal_locus($reciprocal_locus_id)
1909 Desc: get a locus2locus object of the reciprocal_locus (subject) associated to the current locus (object).
1910 This is used for printing the reciprocal loci associated with a specific locus.
1911 Ret: Locus2Locus object or undef
1912 Args: $reciprocal_locus_id
1918 sub get_reciprocal_locus
{
1919 warn("DEPRECATED. SEE get_locusgroups() !!!!!!!\n");
1922 my $reciprocal_locus_id=shift;
1923 my $query = "SELECT locus2locus_id FROM phenome.locus2locus WHERE object_id=? AND subject_id = ? AND obsolete='f'";
1924 my $sth = $self->get_dbh()->prepare($query);
1925 $sth->execute( $self->get_locus_id(), $reciprocal_locus_id);
1926 my ($l2l_id) = $sth->fetchrow_array();
1928 my $l2l=CXGN
::Phenome
::Locus2Locus
->new($self->get_dbh(), $l2l_id);
1930 }else {return undef ; }
1934 =head2 get_locus_annotations
1936 Usage: $self->get_locus_annotations($dbh, $cv_name)
1937 Desc: find all cv_name annotations for loci
1938 Ret: list of LocusDbxref objects
1939 Args: database handle and a cv name
1945 sub get_locus_annotations
{
1950 my $query = "SELECT locus_dbxref_id FROM phenome.locus_dbxref
1951 JOIN public.dbxref USING (dbxref_id)
1952 JOIN public.cvterm USING (dbxref_id)
1953 JOIN public.cv USING (cv_id)
1954 WHERE cv.name = ? AND locus_dbxref.obsolete= 'f' ORDER BY locus_id";
1955 my $sth=$dbh->prepare($query);
1956 $sth->execute($cv_name);
1957 while (my ($locus_dbxref_id) = $sth->fetchrow_array()) {
1958 my $locus_dbxref= CXGN
::Phenome
::LocusDbxref
->new($dbh, $locus_dbxref_id);
1959 push @annotations , $locus_dbxref;
1961 return @annotations;
1964 =head2 get_curated_annotations
1966 Usage: $self->get_curated_annotations($dbh, $cv_name)
1967 Desc: find all cv_name non-electronic annotations for loci
1968 Ret: list of LocusDbxref objects
1969 Args: database handle and a cv name
1975 sub get_curated_annotations
{
1980 my $query = "SELECT locus_dbxref_id , locus_dbxref_evidence.evidence_code_id FROM phenome.locus_dbxref
1981 JOIN public.dbxref USING (dbxref_id)
1982 JOIN public.cvterm USING (dbxref_id)
1983 JOIN public.cv USING (cv_id)
1984 JOIN locus_dbxref_evidence USING (locus_dbxref_id)
1985 WHERE cv.name = ? AND locus_dbxref.obsolete= 'f'
1986 AND locus_dbxref_evidence.evidence_code_id !=(SELECT dbxref_id FROM public.cvterm WHERE name = 'inferred from electronic annotation') ORDER BY locus_id";
1987 my $sth=$dbh->prepare($query);
1988 $sth->execute($cv_name);
1989 while (my ($locus_dbxref_id) = $sth->fetchrow_array()) {
1990 my $locus_dbxref= CXGN
::Phenome
::LocusDbxref
->new($dbh, $locus_dbxref_id);
1991 push @annotations , $locus_dbxref;
1993 return @annotations;
1996 =head2 get_annotations_by_db
1998 Usage: $self->get_annotations_by_db('GO')
1999 Desc: find all locus cvterm annotations for a given db
2000 Ret: an array of locus_dbxref objects
2007 sub get_annotations_by_db
{
2012 my $query = "SELECT locus_dbxref_id FROM phenome.locus_dbxref
2013 JOIN phenome.locus_dbxref_evidence USING (locus_dbxref_id)
2014 JOIN public.dbxref USING (dbxref_id)
2015 JOIN public.db USING (db_id)
2016 JOIN public.cvterm USING (dbxref_id)
2017 WHERE db.name = ? AND locus_dbxref_evidence.obsolete= 'f'";
2018 my $sth=$dbh->prepare($query);
2019 $sth->execute($db_name);
2020 while (my ($locus_dbxref_id) = $sth->fetchrow_array()) {
2021 my $locus_dbxref= CXGN
::Phenome
::LocusDbxref
->new($dbh, $locus_dbxref_id);
2022 push @annotations , $locus_dbxref;
2024 return @annotations;
2031 Usage: $self->merge_locus($merged_locus_id, $sp_person_id)
2032 Desc: merge locus X with this locus. The merged locus will be set to obsolete.
2034 Args: the id of the locus to be merged
2035 Side Effects: all data associated with the merged locus will now be associated with the current locus.
2042 my $merged_locus_id=shift;
2043 my $sp_person_id=shift;
2044 my $m_locus=CXGN
::Phenome
::Locus
->new($self->get_dbh(), $merged_locus_id);
2045 $self->d( "*****locus.pm: calling merge_locus...merging locus " . $m_locus->get_locus_id() . " with locus ". $self->get_locus_id() . " \n");
2047 my @m_owners=$m_locus->get_owners();
2048 foreach my $o (@m_owners) {
2049 my $o_id= $self->add_owner($o, $sp_person_id);
2050 $self->d( "merge_locus is adding owner $o to locus " . $self->get_locus_id() . "\n**") if $o_id;
2052 $self->d( "merge_locus checking for aliases ....\n");
2053 my @m_aliases=$m_locus->get_locus_aliases();
2054 foreach my $alias(@m_aliases) {
2055 $self->add_locus_alias($alias);
2056 $self->d( "merge_locus is adding alias " . $alias->get_locus_alias() . " to locus " . $self->get_locus_id() . "\n**");
2058 my @unigenes=$m_locus->get_unigenes();
2059 foreach my $u(@unigenes) {
2060 my $u_id= $u->get_unigene_id();
2061 $self->add_unigene($u_id, $sp_person_id);
2062 $self->d( "merge_locus is adding unigene $u to locus" . $self->get_locus_id() . "\n**");
2064 my @alleles=$m_locus->get_alleles();
2065 foreach my $allele(@alleles) {
2066 $self->d( "adding allele ........\n");
2067 #reset allele id for storing a new one for the current locus
2068 $allele->set_allele_id(undef);
2069 my $allele_id=$self->add_allele($allele);
2070 $self->d( "merge_locus is adding allele $allele_id " . $allele->get_allele_symbol() . "to locus" . $self->get_locus_id() . "\n**");
2072 #find the stocks of the current allele
2073 my $stock_ids = $allele->get_stock_ids;
2074 #associated stocks with the newly inserted allele
2075 foreach my $stock_id(@
$stock_ids) {
2076 $allele->associate_stock($stock_id, $sp_person_id);
2077 $self->d( "merge_locus is adding allele $allele_id to *stock* $stock_id n**");
2081 my @figures=$m_locus->get_figures();
2082 foreach my $image(@figures) {
2083 $self->add_figure($image->get_image_id(), $sp_person_id);
2084 $self->d( "merge_locus is adding figure" . $image->get_image_id() . " to locus " . $self->get_locus_id() . "\n**");
2087 my @dbxrefs=$m_locus->get_dbxrefs();
2088 foreach my $dbxref(@dbxrefs) {
2089 my $ldbxref=$m_locus->get_locus_dbxref($dbxref); #the old locusDbxref object
2090 my @ld_evs=$ldbxref->get_locus_dbxref_evidence(); #some have evidence codes
2091 my $ldbxref_id=$self->add_locus_dbxref($dbxref, undef, $ldbxref->get_sp_person_id()); #store the new locus_dbxref..
2092 $self->d( "merge_locus is adding dbxref " . $dbxref->get_dbxref_id() . "to locus " . $self->get_locus_id() . "\n");
2093 foreach my $ld_ev ( @ld_evs) {
2094 if ($ld_ev->get_object_dbxref_evidence_id() ) {
2095 $ld_ev->set_object_dbxref_evidence_id(undef);
2096 $ld_ev->set_object_dbxref_id($ldbxref_id);
2097 $ld_ev->store(); #store the new locus_dbxref_evidence
2101 #Add this locus to all the groups of the merged locus
2102 my @groups=$m_locus->get_locusgroups();
2106 if ($groups[0]) { $schema = $groups[0]->get_schema(); }
2107 foreach my $group (@groups) {
2108 my $m_lgm = $group->get_object_row()->
2109 find_related
('locusgroup_members', { locus_id
=> $m_locus->get_locus_id() } );
2110 #see if the locus is already a member of the group
2111 my $existing_member= $group->get_object_row()->
2112 find_related
('locusgroup_members', { locus_id
=> $self->get_locus_id() } );
2113 if (!$existing_member) {
2114 my $lgm=CXGN
::Phenome
::LocusgroupMember
->new($schema);
2115 $lgm->set_locusgroup_id($m_lgm->get_column('locusgroup_id') );
2116 $lgm->set_locus_id($self->get_locus_id() );
2117 $lgm->set_evidence_id($m_lgm->get_column('evidence_id'));
2118 $lgm->set_reference_id($m_lgm->get_column('reference_id'));
2119 $lgm->set_sp_person_id($m_lgm->get_column('sp_person_id'));
2120 $lgm->set_direction($m_lgm->get_column('direction'));
2121 $lgm->set_obsolete($m_lgm->get_column('obsolete'));
2122 $lgm->set_create_date($m_lgm->get_column('create_date'));
2123 $lgm->set_modified_date($m_lgm->get_column('modified_date'));
2124 my $lgm_id= $lgm->store();
2126 $self->d( "obsoleting group member... \n");
2127 $m_lgm->set_column(obsolete
=> 't');
2130 #concatenate description
2131 my $self_description = $self->get_description . "\n" if $self->get_description ;
2132 $self->set_description($self_description . $m_locus->get_description) ;
2133 #update chromosome and arm, but only if null in $self locus
2134 $self->set_linkage_group($m_locus->get_linkage_group) if !$self->get_linkage_group;
2135 $self->set_lg_arm($m_locus->get_lg_arm) if !$self->get_lg_arm;
2136 ##update genome locus identifier
2137 $self->set_genome_locus($m_locus->get_genome_locus) if !$self->get_genome_locus;
2138 #update gene activity
2139 $self->set_gene_activity($m_locus->get_gene_activity) if !$self->get_gene_activity;
2142 $self->d( "Obsoleting merged locus... \n");
2143 #last step is to obsolete the old locus. All associated objects (images, alleles, individuals..) should not display obsolete objects on the relevant pages!
2147 my $error = "Merge locus failed! \n $@\n\nCould not merge locus $merged_locus_id with locus " . $self->get_locus_id() . "\n";
2150 $self->d( "merging locus succeded ! \n");
2155 =head2 get_locus_stats
2157 Usage: CXGN::Phenome::Locus->get_locus_stats($dbh)
2158 Desc: class function. Find the status of the locus database by month.
2159 Ret: List of lists [locus_count], [month/year]]
2167 sub get_locus_stats
{
2170 my $query = "select count (locus_id), date_part('month', create_date) as month , date_part('year', create_date) as year from phenome.locus group by month, year order by year, month asc";
2171 my $sth=$dbh->prepare($query);
2175 while (my ($loci, $month, $year) = $sth->fetchrow_array()) {
2176 $year= substr($year, -2);
2178 push @
{ $stats[0] }, "$month/$year";
2179 push @
{ $stats[1] }, $count;
2184 =head2 get_locusgroups
2186 Usage: $self->get_locusgroups()
2187 Desc: Find all the locus groups this locus is a member of
2188 Ret: a list of CXGN::Phenome::LocusGroup objects (DBIx::Class ojects! )
2190 Side Effects: connects to CXGN::Phenome::Schema
2195 sub get_locusgroups
{
2197 my $locus_id = $self->get_locus_id();
2198 my $schema= CXGN
::Phenome
::Schema
->connect(
2199 sub { $self->get_dbh->clone } ,
2200 { on_connect_do
=> ['set search_path to phenome'] },
2202 my @members= $schema->resultset('LocusgroupMember')->search(
2204 locus_id
=> $locus_id ,
2208 foreach my $member (@members) {
2209 my $group_id = $member->get_column('locusgroup_id');
2210 my $lg= CXGN
::Phenome
::LocusGroup
->new($schema, $group_id);
2216 =head2 count_associated_loci
2218 Usage: $self->count_associated_loci()
2219 Desc: count the number of loci associated with this locus
2227 sub count_associated_loci
{
2229 my $locus_id=$self->get_locus_id();
2231 my @locus_groups= $self->get_locusgroups();
2232 foreach my $group(@locus_groups) {
2233 my @members= $group->get_locusgroup_members();
2234 foreach my $member(@members) {
2235 my $member_locus_id= $member->get_column('locus_id');
2236 if (( $member->obsolete() == 0 ) && ($member_locus_id != $locus_id) ) {
2244 =head2 count_ontology_annotations
2246 Usage: $self->count_ontology_annotations()
2247 Desc: count the number of non-obsolete ontology terms with this locus directly or indirectly via alleles
2255 sub count_ontology_annotations
{
2257 my $locus_id=$self->get_locus_id();
2259 my $query = "SELECT count(distinct(cvterm_id)) FROM public.cvterm
2260 JOIN phenome.locus_dbxref USING (dbxref_id) JOIN phenome.locus_dbxref_evidence USING (locus_dbxref_id)
2261 LEFT JOIN phenome.allele_dbxref USING (dbxref_id)
2262 LEFT JOIN phenome.allele USING (allele_id)
2263 WHERE locus_dbxref.locus_id=? AND locus_dbxref.obsolete='f' AND locus_dbxref_evidence.obsolete='f'
2264 OR allele_dbxref.obsolete = 'f'";
2265 my $sth=$self->get_dbh()->prepare($query);
2266 $sth->execute($locus_id);
2267 my ($count)= $sth->fetchrow_array();