Merge pull request #5205 from solgenomics/topic/generic_trial_upload
[sgn.git] / lib / CXGN / Cvterm.pm
blob6631fdbd0ca877ce73d7f080e59ba93e5d6bc9e0
1 =head1 NAME
3 CXGN::Cvterm - a second-level object for Cvterm
5 Version: 1.2
7 =head1 DESCRIPTION
9 This object was re-factored from CXGN::Chado::Cvterm and moosified.
10 Use CXGN::Cvterm for new code. CXGN::Chado::Cvterm is deprecated
13 =head1 AUTHOR
15 Naama Menda <nm249@cornell.edu>
16 Lukas Mueller <lam87@cornell.edu>
18 =cut
20 package CXGN::Cvterm ;
22 use Moose;
24 use Carp;
25 use Data::Dumper;
26 use Bio::Chado::Schema;
27 use CXGN::Metadata::Schema;
28 use SGN::Model::Cvterm;
30 use base qw / CXGN::DB::Object / ;
32 use Try::Tiny;
34 =head2 accessor schema
36 =cut
38 has 'schema' => (
39 isa => 'Bio::Chado::Schema',
40 is => 'rw',
41 required => 1
44 =head2 accessor cvterm
46 Returns: Cv::Cvterm DBIx::Class object
48 =cut
50 has 'cvterm' => (
51 isa => 'Bio::Chado::Schema::Result::Cv::Cvterm',
52 is => 'rw',
55 =head2 accessor cvterm_id
57 =cut
59 has 'cvterm_id' => (
60 isa => 'Int',
61 is => 'rw',
64 =head2 accessor cv
66 =cut
68 has 'cv' => (
69 isa => 'Bio::Chado::Schema::Result::Cv::Cv',
70 is => 'rw',
73 =head2 accessor cv_id
75 =cut
77 has 'cv_id' => (
78 isa => 'Int',
79 is => 'rw',
82 =head2 accessor dbxref
84 =cut
86 has 'dbxref' => (
87 isa => 'Bio::Chado::Schema::Result::General::Dbxref',
88 is => 'rw',
91 =head2 accessor db
93 =cut
95 has 'db' => (
96 isa => 'Bio::Chado::Schema::Result::General::Db',
97 is => 'rw',
100 =head2 accessor name
102 =cut
104 has 'name' => (
105 isa => 'Str',
106 is => 'rw',
109 =head2 accessor definition
111 =cut
113 has 'definition' => (
114 isa => 'Str',
115 is => 'rw',
118 =head2 accessor is_obsolete
120 =cut
123 has 'is_obsolete' => (
124 isa => 'Bool',
125 is => 'rw',
126 default => 0,
130 =head2 accessor accession
132 refers to dbxref.accession column
134 =cut
136 has 'accession' => (
137 isa => 'Maybe[Str]',
138 is => 'rw',
141 has 'is_variable' => (
142 isa => 'Bool',
143 is => 'rw',
144 default => sub { return 0; },
147 #########################################
150 sub BUILD {
151 my $self = shift;
153 my $cvterm;
154 if ($self->cvterm_id){
155 $cvterm = $self->schema()->resultset("Cv::Cvterm")->find({ cvterm_id => $self->cvterm_id() });
157 if ($cvterm) {
158 my $cvterm_rel_rs = $self->schema()->resultset("Cv::CvtermRelationship")->search( { subject_id => $self->cvterm_id });
159 # require at least one parent to have a variable_of type
161 while (my $row = $cvterm_rel_rs->next()) {
162 #print STDERR "ROW TYPE: ".$row->type()->name()."\n";
163 if (uc($row->type()->name) eq uc('variable_of')) {
164 $self->is_variable(1);
169 } elsif ($self->accession ) {
170 my ($db_name, $dbxref_accession) = split "\:", $self->accession;
172 #InterPro accessions have a namespace (db.name) that is different from the accession prefic
173 if ($self->accession =~ m/^IPR*/ ) {
174 $db_name = 'InterPro';
175 $dbxref_accession= $self->accession;
177 my $dbxref = $self->schema()->resultset("General::Dbxref")->find(
179 'db.name' => $db_name,
180 'me.accession' => $dbxref_accession,
182 { join => 'db'}
185 if ($dbxref) { $cvterm = $dbxref->cvterm ; }
188 if (defined $cvterm) {
189 $self->cvterm($cvterm);
190 $self->cvterm_id($cvterm->cvterm_id);
191 $self->name($cvterm->name);
192 $self->definition($cvterm->definition || '' );
193 $self->is_obsolete($cvterm->is_obsolete);
195 $self->dbxref( $self->schema()->resultset("General::Dbxref")->find({ dbxref_id=>$cvterm->dbxref_id() }) );
196 $self->cv_id( $cvterm->cv_id);
197 $self->cv( $self->schema()->resultset("Cv::Cv")->find( { cv_id => $cvterm->cv_id() }) );
198 $self->db( $self->dbxref->db );
199 $self->accession( $self->db->name . ':' . $self->dbxref->accession );
202 return $self;
205 =head2 function get_image_ids
207 Synopsis: my @images = $self->get_image_ids()
208 Arguments: none
209 Returns: a list of md_image_ids
210 Side effects: none
211 Description: a method for fetching all images associated with a cvterm
213 =cut
215 sub get_image_ids {
216 my $self = shift;
217 my @ids;
218 my $q = "SELECT image_id FROM metadata.md_image_cvterm WHERE cvterm_id=? AND obsolete = 'f' ";
219 my $h = $self->schema->storage->dbh()->prepare($q);
220 $h->execute($self->cvterm_id);
221 while (my ($image_id) = $h->fetchrow_array()){
222 push @ids, [$image_id, 'cvterm'];
224 return @ids;
229 =head2 function get_is_relationshiptype
231 Usage: my $is_relationshiptype = $self->get_is_relationship_type
232 Desc: find the database value of teh cvterm column is_relationship_type (integer 0,1)
233 Property
234 Side Effects:
235 Example:
237 =cut
239 sub get_is_relationshiptype {
240 my $self = shift;
241 return $self->cvterm->is_relationship_type;
247 =head2 synonyms
249 Usage: my @synonyms = $self->synonyms()
250 Desc: Fetch all synonym names of a cvterm. use BCS cvterm->add_synonym and $cvterm->delete_synonym to manipulate cvtermsynonyms
251 Ret: an array of synonym strings
252 Args: none
253 Side Effects: none
254 Example:
256 =cut
258 sub synonyms {
259 my $self = shift;
260 my $cvterm = $self->cvterm;
261 my $synonym_rs = $cvterm->cvtermsynonyms;
263 my @synonyms =() ;
264 while ( my $s = $synonym_rs->next ) {
265 push (@synonyms, $s->synonym) ;
267 return @synonyms;
270 =head2 get_single_synonym
272 Usage: my $single_synonym = $self->get_single_synonym;
273 Desc: a method for fetching a single synonym, based on the synonym structure. This is ugly and it would be better if we used types and type ids
274 Ret: a single synonym
275 Args: none
276 Side Effects:
277 Example:
279 =cut
281 sub get_single_synonym {
282 my $self=shift;
283 my $cvterm_id= $self->cvterm_id();
285 my $query= "SELECT synonym FROM cvtermsynonym WHERE cvterm_id= ? AND synonym NOT LIKE '% %' AND synonym NOT LIKE '%\\_%' LIMIT 1";
286 my $synonym_sth = $self->schema->storage->dbh->prepare($query);
287 $synonym_sth->execute($cvterm_id);
289 my $single_synonym = $synonym_sth->fetchrow_array();
291 return $single_synonym;
295 =head2 secondary_dbxrefs
297 Usage: $self->secondary_dbxrefs
298 Desc: find all secondary accessions associated with the cvterm
299 These are stored in cvterm_dbxref table
300 Ret: a list of full accession strings (PO:0001234)
301 Args: none
302 Side Effects: none
303 Example:
305 =cut
307 sub secondary_dbxrefs {
308 my $self=shift;
309 my $rs = $self->cvterm->search_related('cvterm_dbxrefs' , { is_for_definition => 0} );
310 my @list;
311 while (my $r = $rs->next) {
312 push @list , $r->dbxref;
314 return @list;
320 =head2 def_dbxrefs
322 Usage: $self->def_dbxrefs
323 Desc: find all definition dbxrefs of the cvterm
324 These are stored in cvterm_dbxref table
325 Ret: an array of dbxref objects
326 Args: none
327 Side Effects: none
328 Example:
330 =cut
332 sub def_dbxrefs {
333 my $self=shift;
334 my $cvterm = $self->cvterm;
335 my @defs = $cvterm->search_related('cvterm_dbxrefs' , { is_for_definition => 1} );
337 return @defs || undef ;
341 =head2 cvtermprops
343 Usage: $self->cvtermprops
344 Desc: find all cvtermprops (names and values) of the cvterm
345 These are stored in cvtermprop table
346 Ret: hashref of arrays - key = cvtermprop type name, value = list of cvtermprop values of that type
347 Args: none
348 Side Effects: none
349 Example:
351 =cut
353 sub cvtermprops {
354 my $self = shift;
355 my $properties;
356 my $cvtermprops = $self->cvterm->cvtermprops;
358 while ( my $prop = $cvtermprops->next ) {
359 push @{ $properties->{$prop->type->name } } , $prop->value ;
361 return $properties;
365 ########################################
366 sub _retrieve_cvtermprop {
367 my $self = shift;
368 my $type = shift;
369 my @results;
371 try {
372 my $cvtermprop_type_id = SGN::Model::Cvterm->get_cvterm_row($self->schema, $type, 'trait_property')->cvterm_id();
373 my $rs = $self->schema()->resultset("Cv::Cvtermprop")->search({ cvterm_id => $self->cvterm_id(), type_id => $cvtermprop_type_id }, { order_by => {-asc => 'cvtermprop_id'} });
375 while (my $r = $rs->next()){
376 push @results, $r->value;
378 } catch {
379 print STDERR "Cvterm $type does not exist in this database\n";
382 my $res = join ',', @results;
383 return $res;
386 sub _remove_cvtermprop {
387 my $self = shift;
388 my $type = shift;
389 my $value = shift;
390 my $type_id = SGN::Model::Cvterm->get_cvterm_row($self->schema, $type, 'trait_property')->cvterm_id();
391 my $rs = $self->schema()->resultset("Cv::Cvtermprop")->search( { type_id=>$type_id, cvterm_id => $self->cvterm_id(), value=>$value } );
393 if ($rs->count() == 1) {
394 $rs->first->delete();
395 return 1;
397 elsif ($rs->count() == 0) {
398 return 0;
400 else {
401 print STDERR "Error removing cvtermprop from cvterm ".$self->cvterm_id().". Please check this manually.\n";
402 return 0;
407 sub _store_cvtermprop {
408 my $self = shift;
409 my $type = shift;
410 my $value = shift;
411 my $cvtermprop = SGN::Model::Cvterm->get_cvterm_row($self->schema, $type, 'trait_property')->name();
412 my $stored_cvtermprop = $self->cvterm->create_cvtermprops({ $cvtermprop => $value});
418 __PACKAGE__->meta->make_immutable;
420 ##########
421 1;########
422 ##########