4 CXGN::Chado::Cvterm - a class to handle controlled vocabulary terms.
10 Naama Menda <nm249@cornell.edu>
11 Lukas Mueller <lam87@cornell.edu> (added implementation of Bio::Ontology::TermI)
12 (added map_to_slim function [March 3, 2008])
16 package CXGN
::Chado
::Cvterm
;
19 use CXGN
::DB
::Connection
;
20 use CXGN
::Chado
::Dbxref
;
21 use CXGN
::Phenome
::Population
;
22 use CXGN
::Chado
::Cvterm
::CvtermRanking
;
23 use CXGN
::Phenome
::Locus
;
24 use CXGN
::Phenome
::Individual
;
25 use CXGN
::Phenome
::Qtl
::Tools
;
26 use List
::MoreUtils qw
/uniq/;
29 use base qw
/ CXGN::DB::Object CXGN::Chado::Cvterm::CvtermRanking / ;
32 =head1 IMPLEMENTATION OF THE Bio::Ontology::TermI INTERFACE
36 Usage: $t->set_identifier("0000001");
37 Desc: this identifier function maps to the accession.
38 it is a synonym for set_accession and get_accession.
39 For the go accession GO:000222, this would have to
40 be set to 000222, for example.
41 Property: the accession of the term.
49 my $identifier = shift;
50 $self->set_accession($identifier) if $identifier;
51 return $self->get_accession();
57 Usage: $t->name($name);
58 Desc: a synonym for the set_cvterm_name/get_cvterm_name accessors
69 $self->set_cvterm_name($name) if $name;
70 return $self->get_cvterm_name();
75 Usage: $t->definition($definition);
76 Desc: a synonym for the set_definition/get_definition
87 my $definition = shift;
88 $self->set_definition($definition) if defined($definition);
89 return $self->get_definition();
94 Usage: $t->ontology( CXGN::Chado::Ontology->new_with_name($dbh, "gene_ontology");
95 Desc: setter/getter for the ontology object this terms belongs to
96 Property: a CXGN::Chado::Ontology object.
104 my $ontology = shift;
106 $self->set_cv_id($ontology->identifier());
109 return CXGN
::Chado
::Ontology
->new($self->get_dbh(), $self->get_cv_id());
116 Usage: my $v = $t->version($version)
117 Desc: synonym for get/set_version . See L<Bio::Ontology::OntologyI>.
118 Ret: $self->get_version()
128 $self->set_version($version) if defined($version);
129 return $self->get_version();
134 Usage: $cvterm->comment("This is a useful term!");
135 my $comment = $cvterm->comment();
136 Desc: setter/getter for the comment
137 Args/Ret: the comment, a string.
138 Side Effects: accesses the database and retrieves/stores comments
139 on the fly. Thus, the cvterm needs to be stored in the
140 database and have a legal cvterm_id. The function emits
141 a warning and does nothing if that is not the case.
149 my $type_id=CXGN
::Chado
::Cvterm
::get_cvterm_by_name
($self->get_dbh(), "comment")->get_cvterm_id();
151 $self->d("WARNING. Cvterm has not yet been stored. Skipping the comment update.\n");
155 # check if there is already a comment associated with this term.
156 my $query = "SELECT cvtermprop_id from cvtermprop WHERE cvterm_id=? and value=?";
157 my $sth = $self->get_dbh()->prepare($query);
158 $sth->execute($self->get_cvterm_id(), $comment);
159 my %props; #hash of arrays for cvtermprop_id => comment pairs
160 my ($cvtermprop_id) = $sth->fetchrow_array();
162 #while (my ($value) = $sth->fetchrow_array()) { push @comments , $value; }
164 #if ($cvtermprop_id) {
165 # my $update = "UPDATE cvtermprop SET value=? WHERE cvtermprop_id=?";
166 # my $update_h = $self->get_dbh()->prepare($update);
167 # $update_h->execute($comment, $cvtermprop_id);
169 # if does not exist- insert a new one.
170 if (!$cvtermprop_id) {
171 my $insert = "INSERT INTO cvtermprop (cvterm_id, type_id, value, rank)
172 VALUES (?, ?, ?, ?)";
173 my $insert_h = $self->get_dbh()->prepare($insert);
174 $insert_h->execute($self->get_cvterm_id(),
182 # query the comment out of the database
183 my $query = "SELECT value FROM cvtermprop WHERE cvterm_id=?";
184 my $sth = $self->get_dbh()->prepare($query);
185 $sth->execute($self->get_cvterm_id());
186 my ($comment) = $sth->fetchrow_array();
204 return $self->get_dbxref_id();
208 =head1 ORIGINAL CXGN::Chado::Cvterm functions
216 Usage: my @roots = CXGN::Chado::Cvterm::get_roots($dbh, "PO");
217 Desc: a static function that returns a list of root
218 terms for a given namespace such as "GO" or "PO"
220 Ret: a list of cvterm objects that are roots of ontologies
221 Args: $dbh and a namespace
229 my $namespace = shift;
231 my $query = "select cvterm.cvterm_id, cvterm.name from cv join cvterm using (cv_id) join dbxref using(dbxref_id) join db using(db_id) left join cvterm_relationship on (cvterm.cvterm_id=cvterm_relationship.subject_id) where cvterm_relationship.subject_id is null and is_obsolete=0 and is_relationshiptype =0 and db.name=? order by cvterm.name asc";
232 my $sth = $dbh->prepare($query);
233 $sth->execute($namespace);
235 while (my ($cvterm_id) = $sth->fetchrow_array()) {
236 push @roots, CXGN
::Chado
::Cvterm
->new($dbh, $cvterm_id);
243 =head2 get_namespaces
245 Usage: my @namespaces = CXGN::Chado::Cvterm::get_namespaces($dbh)
246 Desc: currently provides a list of supported namespaces that
247 are hardcoded. Needs to be refactored somehow to
248 get the useful namespaces from the database (public.db table).
259 return ("PO", "GO", "SP", "SO", "PATO");
268 Usage: my $cvterm = CXGN::Chado::Cvterm->new($dbh, $cvterm_id);
269 Desc: an object for handling controlled vocabullary term objects
271 Args:$dbh a database handle
272 $cvterm_id = an id of a controlled vocabulary term (from chado cvterm table)
282 my $cvterm_id = shift; #id of the cvterm
284 my $self= $class->SUPER::new
($dbh);
287 $self->set_cvterm_id($cvterm_id);
289 if (!$self->get_cvterm_id()) { # the cvterm supplied was not one that exists
297 =head2 new_with_term_name
299 Usage: my $isa = CXGN::Chado::Cvterm->new_with_term_name($dbh, "isa", $cv_id);
300 Desc: useful for getting the term objects for relationship terms.
301 limited usefulness for any other type of term.
303 Args: a database handle, a term name and a cv_id
309 sub new_with_term_name
{
315 if (!$name && !$cv_id) { die "[Cvterm.pm] new_with_term_name: Need name and cv_id."; }
317 my $query = "SELECT cvterm_id from cvterm where name ilike ? and cv_id=?";
318 my $sth = $dbh->prepare($query);
319 $sth->execute($name, $cv_id);
320 my ($cvterm_id) = $sth->fetchrow_array();
322 my $self = CXGN
::Chado
::Cvterm
->new($dbh, $cvterm_id);
326 =head2 new_with_accession
328 Usage: my $t = CXGN::Chado::Cvterm->new_with_accession($dbh, "InterPro:IPR000001", $cv_id);
329 Desc: an alternate constructor using the accession to define the term.
331 Args: a database handle [CXGN::DB::Connection], an accession [string], cv_id (optional. Can be useful if you think the accession might exist in another other cv)
337 sub new_with_accession
{
340 my $accession = shift;
343 my ($name_space, $id) = split "\:", $accession;
345 if ($accession =~ m/^IPR*/ ) {
346 $name_space = 'InterPro';
350 my $query = "SELECT cvterm_id FROM cvterm join dbxref using(dbxref_id) JOIN db USING (db_id) WHERE db.name=? AND dbxref.accession ilike ?";
351 $query .= " AND cv_id = $cv_id" if $cv_id;
353 my $sth = $dbh->prepare($query);
354 $sth->execute($name_space, $id);
356 my ($cvterm_id) = $sth->fetchrow_array();
358 my $self = $class->new($dbh, $cvterm_id);
366 my $cvterm_query = $self->get_dbh()->prepare("SELECT cvterm.cvterm_id, cv.cv_id, cv.name, cvterm.name, cvterm.definition, cvterm.dbxref_id, cvterm.is_obsolete, cvterm.is_relationshiptype, dbxref.accession, db.name FROM public.cvterm join public.cv using(cv_id) join public.dbxref using(dbxref_id) join public.db using (db_id) WHERE cvterm_id=? ");
368 $cvterm_query->execute( $self->get_cvterm_id() );
371 my ($cvterm_id, $cv_id, $cv_name, $cvterm_name, $definition, $dbxref_id, $obsolete,$is_rel,$accession, $db_name)=$cvterm_query->fetchrow_array();
372 $self->set_cvterm_id($cvterm_id);
373 $self->set_cv_id($cv_id);
374 $self->set_cv_name($cv_name);
375 $self->set_cvterm_name($cvterm_name);
376 $self->set_definition($definition);
377 $self->set_dbxref_id($dbxref_id);
378 $self->set_obsolete($obsolete);
379 $self->set_is_relationshiptype($is_rel);
380 $self->set_accession($accession);
381 $self->set_db_name($db_name);
386 Usage: $self->store()
387 Desc: store a new cvterm. Update if cvterm_id exists
390 Side Effects: store a new dbxref for the cvterm if does not exists already
397 my $cvterm_id=$self->get_cvterm_id();
401 my $existing_cvterm_id=$self->cvterm_exists();
402 if ($existing_cvterm_id) {
403 $self->d( "Cvterm.pm found existing cvterm_id $existing_cvterm_id.. can't update term " .$self->get_cvterm_id() . "! \n");
406 my $query = "UPDATE cvterm set cv_id=?, name=?, dbxref_id=?, definition=?, is_obsolete=? WHERE cvterm_id=?";
407 my $sth = $self->get_dbh()->prepare($query);
408 $sth->execute($self->get_cv_id(), $self->get_cvterm_name(), $self->get_dbxref_id(), $self->get_definition(), $self->get_obsolete(), $self->get_cvterm_id());
411 if (!$self->get_dbxref_id()) {
412 if (!$self->get_accession()) { die "Need an accession for a CV term!"; }
413 my $dbxref = CXGN
::Chado
::Dbxref
->new($self->get_dbh());
414 $dbxref->set_accession($self->get_accession());
415 $dbxref->set_version($self->get_version());
416 $dbxref->set_description($self->definition());
417 my $db_name = $self->get_db_name();
418 if ($db_name) { $dbxref->set_db_name($db_name); }
419 else { die "Need a DB name to store cvterm object.\n"; }
421 my $dbxref_id = $dbxref->store();
422 $self->set_dbxref_id($dbxref_id);
423 $self->d("Inserted new dbxref for accession " . $self->get_db_name() . ":" . $self->get_accession ."\n");
426 my $query = "INSERT INTO cvterm (cv_id, name, dbxref_id, definition, is_obsolete, is_relationshiptype) VALUES (?, ?, ?, ?,?,?)";
428 my $sth = $self->get_dbh()->prepare($query);
429 $sth->execute($self->get_cv_id(), $self->get_cvterm_name(), $self->get_dbxref_id(), $self->get_definition(), $self->get_obsolete(), $self->get_is_relationshiptype());
431 $cvterm_id = $self->get_dbh()->last_insert_id("cvterm", "public");
432 $self->set_cvterm_id($cvterm_id);
440 =head2 Class properties
442 The following class properties have accessors (get_cvterm_id, set_cvterm_id...):
460 return $self->{cvterm_id
};
465 $self->{cvterm_id
}=shift;
470 return $self->{cv_id
};
476 $self->{cv_id
}=shift;
481 return $self->{cv_name
};
487 $self->{cv_name
}=shift;
490 sub get_cvterm_name
{
492 return $self->{cvterm_name
};
496 sub set_cvterm_name
{
498 $self->{cvterm_name
}=shift;
503 return $self->{definition
};
509 $self->{definition
}=shift;
515 return $self->{dbxref_id
};
521 $self->{dbxref_id
}=shift;
526 Usage: my $self->get_dbxref();
527 Desc: get a dbxref object associated with the cvterm
537 return CXGN
::Chado
::Dbxref
->new($self->get_dbh(), $self->get_dbxref_id());
542 return $self->{accession
};
547 $self->{accession
}=shift;
551 return $self->{version
};
556 $self->{version
}=shift;
561 return $self->{db_name
};
567 $self->{db_name
}=shift;
572 return $self->{obsolete
};
577 $self->{obsolete
}=shift;
581 sub get_is_relationshiptype
{
583 return $self->{is_relationshiptype
} || 0;
587 sub set_is_relationshiptype
{
589 $self->{is_relationshiptype
}=shift;
593 =head2 get_full_accession
595 Usage: $self->get_full_accession()
596 Desc: Usse this accessor to find the full accession of your cvterm
597 instead of concatenating db_name and accession (e.g. GO:0001234)
598 Ret: db_name:accession
605 sub get_full_accession
{
607 return $self->get_db_name() . ":" . $self->get_accession();
611 =head2 get_recursive_parents
613 Usage: my @parents = $self->get_recursive_parents()
614 Desc: a method for finding all the parents up to the root of the cvterm, and the cvterm-parent relationship
615 Ret: a list of listrefs containing CXGN::Chado::Cvterm objects and relationship types
623 sub get_recursive_parents
{
627 my $parents_q = "SELECT distinct(cvtermpath.object_id)
629 JOIN cvterm ON (cvtermpath.object_id = cvterm_id)
630 WHERE cvtermpath.subject_id =? AND cvterm.is_obsolete=0 AND pathdistance>0";
632 my $type_q = "SELECT type_id FROM cvterm_relationship
633 WHERE subject_id = ? AND object_id = ?";
634 my $type_sth = $self->get_dbh->prepare($type_q);
635 my $parents_sth = $self->get_dbh()->prepare($parents_q);
637 $parents_sth->execute($self->get_cvterm_id() );
639 while (my ($parent_term_id) = $parents_sth->fetchrow_array()) {
640 my $parent_term = CXGN
::Chado
::Cvterm
->new($self->get_dbh(), $parent_term_id);
641 $type_sth->execute($self->get_cvterm_id, $parent_term_id);
642 my ($type_id) = $type_sth->fetchrow_array();
643 my $relationship_term = CXGN
::Chado
::Cvterm
->new($self->get_dbh(), $type_id);
645 push @parents, [ $parent_term, $relationship_term ];
652 Usage: $self->get_parents
653 Desc: find the direct parents of the cvterm
654 Ret: a list of listrefs containing CXGN::Chado::Cvterm objects and relationship types
663 my $parents_q = "SELECT object_id , type_id
664 FROM cvterm_relationship
665 WHERE subject_id = ? ";
666 my $parents_sth = $self->get_dbh()->prepare($parents_q);
667 $parents_sth->execute($self->get_cvterm_id() );
669 while (my ($parent_term_id, $type_id) = $parents_sth->fetchrow_array()) {
670 my $parent_term = CXGN
::Chado
::Cvterm
->new($self->get_dbh(), $parent_term_id);
671 my $relationship_term = CXGN
::Chado
::Cvterm
->new($self->get_dbh(), $type_id);
673 push @parents, [ $parent_term, $relationship_term ];
680 Usage: my @children = $self->get_children()
681 Desc: a method for finding all the child terms of a cv term and their relationship
682 Ret: a list of lists with two elements: a cvterm object for the child and a
683 cvterm object for the relationship
693 my $children_q = "select subject_id , type_id , name from cvterm_relationship join cvterm on (subject_id = cvterm_id ) where cv_id = ? AND object_id =? ";
695 my $children_sth= $self->get_dbh()->prepare($children_q);
696 $children_sth->execute( $self->get_cv_id, $self->get_cvterm_id() );
697 $self->d( "Parent cvterm id = ".$self->get_cvterm_id()."\n" );
699 while (my ($child_term_id, $type_id, $cvterm_name) = $children_sth->fetchrow_array()) {
700 $self->d( "retrieved child $child_term_id, $type_id\n" );
701 my $child_term = CXGN
::Chado
::Cvterm
->new($self->get_dbh(), $child_term_id);
702 my $relationship_term = CXGN
::Chado
::Cvterm
->new($self->get_dbh(), $type_id);
703 push @children, [ $child_term, $relationship_term ];
709 =head2 get_recursive_children
711 Usage: $self->get_recursive_children
712 Desc: find all recursive child terms of this cvterm
713 Ret: a list of lists with two elements: a cvterm object for the child and a
714 cvterm object for the relationship
721 sub get_recursive_children
{
723 my $q = "SELECT distinct(cvtermpath.subject_id)
725 JOIN cvterm ON (cvtermpath.object_id = cvterm_id)
726 WHERE cvtermpath.object_id =? AND cvterm.is_obsolete=0 AND pathdistance>0 ";
728 my $sth = $self->get_dbh()->prepare($q);
729 $sth->execute($self->get_cvterm_id() );
731 my $type_q = "SELECT type_id FROM cvterm_relationship
732 WHERE subject_id = ? AND object_id = ?";
733 my $type_sth = $self->get_dbh->prepare($type_q);
736 while (my ($child_term_id) = $sth->fetchrow_array()) {
737 my $child_term = CXGN
::Chado
::Cvterm
->new($self->get_dbh(), $child_term_id);
738 $type_sth->execute($child_term_id, $self->get_cvterm_id);
739 my ($type_id) = $type_sth->fetchrow_array();
740 my $relationship_term = CXGN
::Chado
::Cvterm
->new($self->get_dbh(), $type_id);
741 push @children, [ $child_term, $relationship_term ];
747 =head2 count_children
749 Usage: my $childrenNumber = $self->count_children()
750 Desc: a method for fetching the number of children of a cvterm
751 Ret: the number of children for the current db name (this is to avoid counting InterPro children of GO terms)
762 my $child_sth = $self->get_dbh()->prepare("SELECT count( cvterm_relationship.subject_id )FROM cvterm_relationship join cvterm on cvterm.cvterm_id = cvterm_relationship.subject_id JOIN dbxref USING (dbxref_id) WHERE cvterm_relationship.object_id= ? and cvterm.is_obsolete = 0 ");
763 $child_sth->execute($self->get_cvterm_id() );
764 ($childNumber) = $child_sth->fetchrow_array();
772 Usage: my @synonyms = $self->get_synonyms()
773 Desc: a method for fetching all synonyms of a cvterm
774 Ret: an array of synonyms
784 my $cvterm_id= $self->get_cvterm_id();
785 my $query= "SELECT synonym FROM cvtermsynonym WHERE cvterm_id= ?";
787 my $synonym_sth = $self->get_dbh()->prepare($query);
789 $synonym_sth->execute($cvterm_id);
791 while (my ($synonym) = $synonym_sth->fetchrow_array()) {
792 push @synonyms, $synonym;
797 =head2 get_synonym_name
799 Usage: $self->get_synonym_name();
800 Desc: an alias for get_synonyms
801 Ret: an array of synonym names
808 sub get_synonym_name
{
810 my @synonyms=$self->get_synonyms();
817 Usage: $t->add_synonym($new_synonym);
818 Desc: adds the synonym $new_synonym to the term $t.
819 If the synonym $new_synonym already exists,
821 Note that in order to call add_synonym(), the
822 term needs to be stored in the database, otherwise
824 Side Effects: accesses the database. Debug message.
832 if (!$self->has_synonym($synonym)) {
833 my $query = "INSERT INTO cvtermsynonym (cvterm_id, synonym) VALUES (?, ?)";
834 my $sth = $self->get_dbh()->prepare($query);
835 $sth->execute($self->get_cvterm_id(), $synonym);
836 $self->d( "Cvterm.pm: adding synonym '$synonym' to cvterm ". $self->get_cvterm_name() ."\n") ;
839 $self->d("$synonym is already a synonym of term ".($self->get_cvterm_name())."\n");
847 Usage: my $flag = $t->has_synonym("gobbledegook");
848 Desc: returns true if the synonym exists, false otherwise
858 my $putative_synonym = shift;
859 my $synonym_sth = $self->get_dbh()->prepare("SELECT synonym FROM cvtermsynonym WHERE
860 cvterm_id= ? and synonym ilike ?");
861 $synonym_sth->execute($self->get_cvterm_id(), $putative_synonym);
862 my ($synonym) = $synonym_sth->fetchrow_array();
871 =head2 delete_synonym
873 Usage: $cvterm->delete_synonym($synonym)
874 Desc: delete synonym $synonym from cvterm object
877 Side Effects: accesses the database
885 my $query = "DELETE FROM cvtermsynonym WHERE cvterm_id= ? AND synonym = ?";
886 my $sth=$self->get_dbh()->prepare($query);
887 $sth->execute($self->get_cvterm_id(), $synonym);
892 =head2 term_is_obsolete
894 Usage: my $obsolete = $self->term_is_obsolete($cvterm_id);
895 Desc: a method for determining if a term is obsolete
896 Ret: false if not obsolete, true if obsolete
897 Args: $cvterm_id - an id of a controlled vocabulary term
903 sub term_is_obsolete
{
907 my $obsolete_sth = $self->get_dbh()->prepare("SELECT is_obsolete FROM cvterm WHERE cvterm_id= ?");
908 $obsolete_sth->execute($self->get_cvterm_id() );
909 my ($obsolete) = $obsolete_sth->fetchrow_array();
911 if( $obsolete == 1 ) {
918 =head2 associate_feature
920 Usage: $cvterm->associate_feature($feature_id, $pub_id)
921 Desc: associates the feature with $feature_id to the
924 Args: feature_id and a pub_id
925 Side Effects: accesses the database
930 sub associate_feature
{
932 my $feature_id = shift;
934 if (!($pub_id && $feature_id)) {
935 die "[CXGN::Chado::Cvterm] associate_feature(): Need feature_id and pub_id\n";
938 my $query = "INSERT INTO cvterm_feature (cvterm_id, feature_id, pub_id) VALUES (?, ?, ?)";
939 my $sth = $self->get_dbh()->prepare($query);
940 $sth->execute($self->get_cvterm_id(), $feature_id, $pub_id);
945 Usage: my @features = $cvterm->get_features()
946 Desc: returns a list of feature objects that are associated to this
947 cvterm using cvterm_feature table.
948 Ret: a list of CXGN::Chado::Feature objects
950 Side Effects: accesses the database
957 my $query = "SELECT feature_id FROM cvterm_feature WHERE cvterm_id=?";
958 my $sth = $self->get_dbh()->prepare($query);
959 $sth->execute($self->get_cvterm_id());
961 while (my ($feature_id) = $sth->fetchrow_array()) {
962 push @features, CXGN
::Chado
::Feature
->new($self->get_dbh(), $feature_id);
967 =head2 add_secondary_dbxref
969 Usage: $self->add_secondary_dbxref(accession)
970 Desc: add an alternative id to cvterm. Stores in cvterm_dbxref
972 Args: an alternative id (i.e. "GO:0001234")
973 Side Effects: stors a new dbxref if accession is not found in dbxref table
978 sub add_secondary_dbxref
{
981 my ($db_name, $acc) = split (/:/, $accession);
982 my $db=CXGN
::Chado
::Db
->new_with_name($self->get_dbh(), $db_name);
983 if ( !($db->get_db_id()) ) {
984 $db->set_db_name($db_name);
985 $self->d( "Cvterm.pm: Storing a new DB: $db_name\n");
988 #check is $accession exists:
989 my $dbxref_id= CXGN
::Chado
::Dbxref
::get_dbxref_id_by_db_id
($self->get_dbh(), $acc, $db->get_db_id());
991 $self->d("No dbxref_id found for db_name '$db_name' accession '$acc' adding new dbxref...\n");
992 my $dbxref=CXGN
::Chado
::Dbxref
->new($self->get_dbh());
993 $dbxref->set_accession($acc);
994 $dbxref->set_db_name($db->get_db_name());
996 $dbxref_id=$dbxref->get_dbxref_id();
998 if (!$self->has_secondary_dbxref($dbxref_id) ) {
999 my $query = "INSERT INTO cvterm_dbxref (cvterm_id, dbxref_id) VALUES (?,?)";
1000 my $sth=$self->get_dbh()->prepare($query);
1001 $sth->execute($self->get_cvterm_id(), $dbxref_id);
1002 $self->d( "Cvterm.pm: adding secondary id '$accession' to cvterm ". $self->get_cvterm_name() . "\n");
1004 $self->d("Cvterm.pm: $dbxref_id ($accession) is already a secondary id of term '".($self->get_cvterm_name())."'\n");
1008 =head2 has_secondary_dbxref
1010 Usage: $self->has_secondary_dbxref($dbxref_id)
1011 Desc: checks in the database if dbxref_id os already associated with the cvterm
1019 sub has_secondary_dbxref
{
1021 my $dbxref_id=shift;
1022 my $query = "SELECT cvterm_dbxref_id FROM cvterm_dbxref WHERE cvterm_id= ? AND dbxref_id= ?";
1023 my $sth=$self->get_dbh()->prepare($query);
1024 $sth->execute($self->get_cvterm_id(), $dbxref_id);
1025 my ($id) = $sth->fetchrow_array();
1026 if ($id) { return 1; }
1030 =head2 get_secondary_dbxrefs
1032 Usage: $self->get_secondary_dbxrefs()
1033 Desc: find all secondary accessions associated with the cvterm
1034 These are stored in cvterm_dbxref table as dbxref_ids
1035 Ret: an array of accessions (PO:0001234)
1042 sub get_secondary_dbxrefs
{
1044 my $query= "SELECT dbxref_id FROM cvterm_dbxref WHERE cvterm_id=? AND is_for_definition = 0";
1045 my $sth=$self->get_dbh()->prepare($query);
1046 $sth->execute($self->get_cvterm_id() );
1048 while (my ($dbxref_id) = $sth->fetchrow_array() ) {
1049 my $dbxref= CXGN
::Chado
::Dbxref
->new($self->get_dbh(),$dbxref_id);
1050 my $accession = $dbxref->get_db_name() . ":" . $dbxref->get_accession();
1051 push @secondary, $accession;
1056 =head2 delete_secondary_dbxref
1058 Usage: $self->delete_secondary_dbxref()
1059 Desc: delete a cvterm_dbxref from the database
1061 Args: accession (PO:0001234)
1067 sub delete_secondary_dbxref
{
1069 my $accession=shift;
1070 my ($db_name, $acc) = split (/:/, $accession);
1071 my $query= "DELETE FROM cvterm_dbxref where cvterm_id=? AND is_for_definition = 0
1072 AND dbxref_id=(SELECT dbxref_id FROM dbxref WHERE db_id= (SELECT db_id FROM db WHERE name =?)
1073 AND accession = ?)";
1074 my $sth=$self->get_dbh()->prepare($query);
1075 $sth->execute($self->get_cvterm_id(), $db_name, $accession);
1080 =head2 add_def_dbxref
1082 Usage: $self->add_def_dbxref($dbname, $accession)
1083 Desc: add a cvterm definition dbxref to cvterm_dbxref
1085 Args: a db name and a dbxref accession
1086 Side Effects: stores a new db and a new dbxref if $dbname or $accession
1087 do not exist in db and/or dbxref tables
1092 sub add_def_dbxref
{
1095 my $accession=shift;
1096 #check if $dbname exist:
1097 my $db=CXGN
::Chado
::Db
->new_with_name($self->get_dbh(), $dbname);
1098 if ( !($db->get_db_id()) ) {
1099 $db->set_db_name($dbname);
1100 $self->d( "Cvterm.pm: Storing a new DB: $dbname\n");
1103 #check is $accession exists:
1104 my $dbxref_id= CXGN
::Chado
::Dbxref
::get_dbxref_id_by_db_id
($self->get_dbh(), $accession, $db->get_db_id());
1106 my $dbxref=CXGN
::Chado
::Dbxref
->new($self->get_dbh());
1107 $dbxref->set_db_name($db->get_db_name());
1108 $dbxref->set_accession($accession);
1109 $self->d( "Cvterm.pm: Storing a new Dbxref for db $dbname: $accession\n");
1111 $dbxref_id=$dbxref->store();
1113 if (!$self->has_secondary_dbxref($dbxref_id)) {
1114 my $query = "INSERT INTO cvterm_dbxref (cvterm_id, dbxref_id, is_for_definition)
1116 my $sth=$self->get_dbh()->prepare($query);
1117 $sth->execute($self->get_cvterm_id(), $dbxref_id);
1118 $self->d( "Cvterm.pm: Storing a new definition dbxref ($dbname:$accession) for cvterm". $self->get_cvterm_name() . "\n");
1121 my $query = "UPDATE cvterm_dbxref set is_for_definition=1
1122 WHERE cvterm_id=? and dbxref_id=?";
1123 my $sth=$self->get_dbh()->prepare($query);
1124 $sth->execute($self->get_cvterm_id(), $dbxref_id);
1129 =head2 get_def_dbxref
1131 Usage: $self->get_def_dbxref();
1132 Desc: find the definition dbxrefs of the cvterm (stored in cvterm_dbxref)
1133 Ret: an array of dbxref object
1140 sub get_def_dbxref
{
1143 my $query = "SELECT dbxref_id FROM cvterm_dbxref WHERE cvterm_id=? and is_for_definition =1";
1144 my $sth=$self->get_dbh()->prepare($query);
1145 $sth->execute($self->get_cvterm_id());
1147 while (my ($dbxref_id) = $sth->fetchrow_array() ) {
1148 my $dbxref=CXGN
::Chado
::Dbxref
->new($self->get_dbh(), $dbxref_id);
1149 push @dbxrefs, $dbxref;
1155 =head2 delete_def_dbxref
1157 Usage: $self->delete_def_dbxref($dbxref)
1158 Desc: remove from the database a cvterm_dbxref
1161 Side Effects: accesses the database
1166 sub delete_def_dbxref
{
1169 my $query = "DELETE FROM cvterm_dbxref WHERE cvterm_id=? AND dbxref_id=? AND is_for_definition = 1";
1170 my $sth=$self->get_dbh()->prepare($query);
1172 $sth->execute($self->get_cvterm_id(), $dbxref->get_dbxref_id());
1175 =head2 get_cvterm_by_name
1177 Usage: CXGN::Chado::Cvterm::get_cvterm_by_name($dbh, $name)
1178 Desc: get a cvterm object with name $name
1179 Ret: cvterm object. Empty object if name does not exist in cvterm table
1180 Args: database handle and a cvterm name (and '1' if you want to check for an existing relationship type! )
1186 sub get_cvterm_by_name
{
1189 my $is_rel=shift; #optional!
1190 my $query = "SELECT cvterm_id FROM public.cvterm WHERE name ilike ?";
1191 $query .=" AND is_relationshiptype =1 " if $is_rel;
1192 my $sth=$dbh->prepare($query);
1193 $sth->execute($name);
1194 my ($cvterm_id) = $sth->fetchrow_array();
1195 my $cvterm= CXGN
::Chado
::Cvterm
->new($dbh, $cvterm_id);
1199 =head2 cvterm_exists
1201 Usage: $self->cvterm_exists()
1202 Desc: check if another cvterm exists with the same cv_id, name, and is_obsolete value
1204 Ret: cvterm_id or undef if no other cvterm exists
1214 my $cvterm_id= $self->get_cvterm_id();
1215 my $query="SELECT cvterm_id FROM public.cvterm WHERE cv_id=? AND name=? AND is_obsolete=?";
1216 my $sth=$self->get_dbh()->prepare($query);
1217 $sth->execute($self->get_cv_id(), $self->get_cvterm_name(), $self->get_obsolete());
1218 my ($existing_cvterm_id) = $sth->fetchrow_array();
1219 if ($cvterm_id == $existing_cvterm_id) { return undef; }
1220 else { return $existing_cvterm_id ; }
1227 Usage: $self->obsolete()
1228 Desc: set a cvterm is_obsolete = 1
1231 Side Effects: accesses the database
1238 if ($self->get_cvterm_id() ) {
1239 my $query= "UPDATE public.cvterm SET is_obsolete = 1 WHERE cvterm_id=?";
1240 my $sth=$self->get_dbh()->prepare($query);
1241 $sth->execute($self->get_cvterm_id() );
1243 $self->d( "Trying to obsolete a term that hasn't been stored yet! \n");
1249 Usage: $self->get_alt_id();
1250 Desc: find the alternative id of a term. Meant to be used for finding
1251 an alternative cvterm for an obsolete term
1252 Ret: list of dbxref_ids or undef
1261 my $query = "SELECT cvterm.dbxref_id FROM cvterm WHERE cvterm_id IN
1262 (SELECT cvterm_id FROM cvterm_dbxref WHERE dbxref_id= ?)";
1264 my $sth=$self->get_dbh()->prepare($query);
1265 $sth->execute($self->get_dbxref_id() );
1266 while (my ($alt_id) = $sth->fetchrow_array()) {
1267 push @alt_ids, $alt_id ;
1269 return @alt_ids || undef ;
1274 Usage: my @match_list = $cvterm->map_to_slim(@term_list)
1275 Desc: returns a list of terms in the @term_list that
1276 are parents of the term object. This function is
1277 useful for mapping terms to a slim vocabulary.
1278 Ret: a list of term identifiers
1279 Args: a list of term identifiers that are in the slim vocabulary
1280 Side Effects: accesses the database
1281 Note: the db name is stripped off if provided (GO:0003832 is
1291 my %slim_counts = ();
1292 for (my $i=0; $i<@slim; $i++) {
1294 # strip db name off id
1296 $slim[$i]=~s/.*?(\d+).*/$1/;
1298 # make a unique list of slim terms
1300 $slim_counts{$slim[$i]}=0;
1302 $self->get_slim_counts(\
%slim_counts);
1304 print Data
::Dumper
::Dumper
(\
%slim_counts);
1307 foreach my $k (keys %slim_counts) {
1308 if ($slim_counts{$k}>0) { push @matches, $k; }
1313 sub get_slim_counts
{
1315 my $slim_counts = shift;
1317 my $id = $self->identifier();
1319 if (exists($slim_counts->{$id}) && defined($slim_counts->{$id})) {
1320 $slim_counts->{$id}++;
1324 foreach my $p ($self->get_parents()) {
1325 $p->[0]->get_slim_counts($slim_counts);
1330 # sub get_slim_counts {
1332 # my $slim_counts = shift;
1334 # foreach my $p ($self->get_parents()) {
1335 # my $id = $p->[0]->identifier();
1336 # $self->d("Checking $id\n");
1337 # if (exists($slim_counts->{$id}) && defined($slim_counts->{$id})) {
1338 # $slim_counts->{$id}++;
1341 # $p->[0]->get_slim_counts($slim_counts);
1346 # return $slim_counts;
1349 # # sub get_slim_term {
1351 # my $slim_counts = shift;
1354 # foreach my $p ($self->get_parents()) {
1355 # my $id = $p->[0]->identifier();
1356 # if (exists($slim_counts->{$id}) && defined($slim_counts->{$id})) {
1366 =head2 get_all_populations_cvterm
1368 Usage: my @pops = $cvterm->get_all_populations_cvterm();
1369 Desc: returns a list of populations phenotyped for the particular trait (cvterm).
1370 Ret: list of population objects
1372 Side Effects: accesses database
1377 sub get_all_populations_cvterm
{
1379 my $query = "SELECT DISTINCT(phenome.population.population_id) FROM public.phenotype
1381 LEFT JOIN phenome.individual USING (individual_id)
1382 LEFT JOIN phenome.population USING (population_id)
1383 WHERE observable_id = ?";
1384 my $sth=$self->get_dbh->prepare($query);
1385 $sth->execute($self->get_cvterm_id());
1387 while (my ($pop_id) = $sth->fetchrow_array()) {
1388 my $pop = CXGN
::Phenome
::Population
->new($self->get_dbh(), $pop_id);
1389 push @populations, $pop;
1391 return @populations;
1397 =head2 get_individuals
1399 Usage: $self->get_individuals
1400 Desc: find all individuals annotated with this cvterm
1401 Ret: list of Individual objects
1408 sub get_individuals
{
1410 my $query = "SELECT individual_id FROM phenome.individual
1411 JOIN phenome.individual_dbxref USING (individual_id)
1413 my $sth=$self->get_dbh()->prepare($query);;
1414 $sth->execute($self->get_dbxref_id);
1416 while ( my ($individual_id) = $sth->fetchrow_array() ) {
1417 my $ind= CXGN
::Phenome
::Individual
->new($self->get_dbh(), $individual_id);
1418 push @individuals, $ind;
1420 return @individuals;
1425 Usage: $self->get_loci()
1426 Desc: find the loci with annotations of this cvterm
1427 Ret: a list of Locus objects
1436 my $query = "SELECT locus_id FROM phenome.locus
1437 JOIN phenome.locus_dbxref USING (locus_id)
1439 ORDER BY locus.locus_symbol";
1440 my $sth=$self->get_dbh()->prepare($query);;
1441 $sth->execute($self->get_dbxref_id);
1443 while ( my ($locus_id) = $sth->fetchrow_array() ) {
1444 my $locus= CXGN
::Phenome
::Locus
->new($self->get_dbh(), $locus_id);
1450 =head2 get_recursive_loci
1452 Usage: my @loci= $self->get_recursive_loci()
1453 Desc: find all the loci annotated with the cvterm or any of its recursive children
1454 Ret: a list of locus ojects
1461 sub get_recursive_loci
{
1463 my $query = "select distinct locus_id from cvtermpath join cvterm on (cvtermpath.object_id = cvterm.cvterm_id or cvtermpath.subject_id = cvterm.cvterm_id) join phenome.locus_dbxref using (dbxref_id ) join phenome.locus using (locus_id) where (cvtermpath.object_id = ?) and locus_dbxref.obsolete = 'f' and locus.obsolete = 'f' and pathdistance > 0";
1465 my $sth=$self->get_dbh()->prepare($query);
1467 $sth->execute($self->get_cvterm_id() );
1468 while ( my ($locus_id) = $sth->fetchrow_array() ) {
1469 my $locus= CXGN
::Phenome
::Locus
->new($self->get_dbh(), $locus_id);
1476 =head2 get_recursive_individuals
1478 Usage: my @ind= $self->get_recursive_individuals()
1479 Desc: find all the individuals annotated with the cvterm or any of its recursive children
1480 Ret: a list of Individual ojects
1487 sub get_recursive_individuals
{
1490 my $query = "select distinct individual_id from cvtermpath join cvterm on (cvtermpath.object_id = cvterm.cvterm_id or cvtermpath.subject_id = cvterm.cvterm_id) join phenome.individual_dbxref using (dbxref_id ) join phenome.individual using (individual_id) where ( cvtermpath.object_id =?) and individual_dbxref.obsolete = 'f' and individual.obsolete = 'f' and pathdistance > 0 ";
1493 my $sth=$self->get_dbh()->prepare($query);;
1495 $sth->execute($self->get_cvterm_id() );
1496 while ( my ($individual_id) = $sth->fetchrow_array() ) {
1497 my $individual= CXGN
::Phenome
::Individual
->new($self->get_dbh(), $individual_id);
1498 push @ind, $individual;