on second though, remove post-only restriction on organism tree image cache flushing...
[sgn.git] / cgi-bin / phenome / population.pl
blobcfbe8de11d1db35964fe445153d8f5b61a3ff8a7
1 use strict;
2 use warnings;
4 my $population_detail_page = CXGN::Phenome::PopulationDetailPage->new();
6 package CXGN::Phenome::PopulationDetailPage;
9 use CXGN::Page;
10 use CXGN::Page::FormattingHelpers qw /info_section_html
11 page_title_html
12 columnar_table_html
13 html_optional_show
14 info_table_html
15 tooltipped_text
16 html_alternate_show
19 use CXGN::Phenome::Population;
20 use CXGN::Phenome::PopulationDbxref;
21 use CXGN::People::PageComment;
22 use CXGN::People::Person;
23 use CXGN::Chado::Publication;
24 use CXGN::Chado::Pubauthor;
26 use CXGN::Contact;
27 use CXGN::Map;
30 use base qw / CXGN::Page::Form::SimpleFormPage CXGN::Phenome::Main/;
32 sub new {
33 my $class = shift;
34 my $self = $class->SUPER::new(@_);
35 $self->set_script_name("population.pl");
38 return $self;
41 sub define_object {
42 my $self = shift;
44 # call set_object_id, set_object and set_primary_key here
45 # with the appropriate parameters.
47 $self->set_dbh(CXGN::DB::Connection->new('phenome'));
48 my %args = $self->get_args();
49 my $population_id= $args{population_id};
50 unless (!$population_id || $population_id =~m /^\d+$/) { $self->get_page->message_page("No population exists for identifier $population_id"); }
51 $self->set_object_id($population_id);
52 $self->set_object(CXGN::Phenome::Population->new($self->get_dbh(),$self->get_object_id()));
53 $self->set_primary_key("population_id");
54 $self->set_owners($self->get_object()->get_owners());
60 sub generate_form {
61 my $self = shift;
63 $self->init_form();
65 my %args = $self->get_args();
67 my $population = $self->get_object();
68 my $population_id = $self->get_object_id();
69 my $type_id = $args{type_id};
70 my $type=$args{type};
72 my ($submitter, $submitter_link) = $self->submitter();
74 my $login_user= $self->get_user();
75 my $login_user_id= $login_user->get_sp_person_id();
76 my $form = undef;
78 if ($self->get_action()=~/edit|store/ && ($login_user_id = $submitter || $self->get_user()->get_user_type() eq 'curator') ) {
79 $form = CXGN::Page::Form::Editable->new();
81 else {
82 $form = CXGN::Page::Form::Static->new();
85 $form->add_field(
86 display_name=>"Name:",
87 field_name=>"name",
88 length=>15,
89 object=>$population,
90 getter=>"get_name",
91 setter=>"set_name",
92 validate => 'string',
94 $form->add_textarea(
95 display_name=>"Description: ",
96 field_name=>"description",
97 object=>$population,
98 getter=>"get_description", setter=>"set_description",
99 columns => 40,
100 rows =>4,
104 $form->add_label( display_name=>"Uploaded by: ",
105 field_name=>"submitter",
106 contents=>$submitter_link,
108 $form->add_hidden( field_name=>"population_id", contents=>$args{population_id});
110 $form->add_hidden (
111 field_name => "sp_person_id",
112 contents =>$self->get_user()->get_sp_person_id(),
113 object => $population,
114 setter =>"set_sp_person_id",
117 $form->add_hidden( field_name=>"action", contents=>"store" );
123 $self->set_form($form);
125 if ($self->get_action=~ /view|edit/) {
126 $self->get_form->from_database();
129 }elsif ($self->get_action=~ /store/) {
130 $self->get_form->from_request($self->get_args());
138 sub display_page {
139 my $self = shift;
141 $self->get_page->add_style( text => <<EOS);
143 a.abstract_optional_show {
144 color: blue;
145 cursor: pointer;
146 white-space: nowrap;
148 div.abstract_optional_show {
149 background: #f0f0ff;
150 border: 1px solid #9F9FC7;
151 margin: 0.2em 1em 0.2em 1em;
152 padding: 0.2em 0.5em 0.2em 1em;
158 my %args = $self->get_args();
160 my $population = $self->get_object();
161 my $population_id = $self->get_object_id();
162 my $population_name = $population->get_name();
164 my $action = $args{action};
165 if (!$population_id && $action ne 'new' && $action ne 'store')
166 { $self->get_page->message_page("No population exists for this identifier"); }
168 #used to show certain elements to only the proper users
169 my $login_user= $self->get_user();
170 my $login_user_id= $login_user->get_sp_person_id();
171 my $login_user_type= $login_user->get_user_type();
172 my $page="../phenome/population.pl?population_id=$population_id";
174 $self->get_page()->header("SGN Population name: $population_name");
176 print page_title_html("Population: $population_name \n");
178 $args{calling_page} = $page;
180 my $population_html = $self->get_edit_link_html(). "\t[<a href=/phenome/qtl_form.pl>New QTL Population</a>] <br />";
182 #print all editable form fields
183 $population_html .= $self->get_form()->as_table_string();
186 my ($phenotype, $is_qtl_pop);
187 my @phenotype;
188 my $graph_icon = qq |<img src="../documents/img/pop_graph.png"/> |;
190 my $qtltool = CXGN::Phenome::Qtl::Tools->new();
191 my @pops = $qtltool->has_qtl_data();
193 foreach my $pops (@pops)
195 my $pops_id = $pops->get_population_id();
196 if ($pops_id == $population_id)
198 $is_qtl_pop = 1;
202 if ($population->get_web_uploaded()) {
203 my @traits = $population->get_cvterms();
205 foreach my $trait (@traits) {
206 my $trait_id = $trait->get_user_trait_id();
207 my $trait_name = $trait->get_name();
208 my $definition = $trait->get_definition();
209 my ($min, $max, $avg, $std, $count)= $population->get_pop_data_summary($trait_id);
211 my $cvterm_obj = CXGN::Chado::Cvterm::get_cvterm_by_name( $self->get_dbh(), $trait_name);
212 my $trait_link;
213 my $cvterm_id = $cvterm_obj->get_cvterm_id();
214 if ($cvterm_id)
216 $trait_link = qq |<a href="/chado/cvterm.pl?cvterm_id=$cvterm_id">$trait_name</a>|;
218 } else
220 $trait_link = qq |<a href="/phenome/trait.pl?trait_id=$trait_id">$trait_name</a>|;
223 if ($is_qtl_pop)
225 if ($definition)
227 push @phenotype, [map {$_} ( (tooltipped_text($trait_link, $definition)),
228 $min, $max, $avg,
229 qq | <a href="/phenome/population_indls.pl?population_id=$population_id&amp;cvterm_id=$trait_id">
230 $count</a>
232 qq | <a href="/phenome/population_indls.pl?population_id=$population_id&amp;cvterm_id=$trait_id">
233 $graph_icon</a>
234 | )];
235 } else
237 push @phenotype, [map {$_} ($trait_name, $min, $max, $avg,
238 qq | <a href="/phenome/population_indls.pl?population_id=$population_id&amp;cvterm_id=$trait_id">
239 $count</a>
241 qq | <a href="/phenome/population_indls.pl?population_id=$population_id&amp;cvterm_id=$trait_id">
242 $graph_icon</a>
243 | )];
245 } else
247 if ($definition)
249 push @phenotype, [map {$_} ( (tooltipped_text( $trait_link, $definition )),
250 $min, $max, $avg, $count )];
251 } else
252 { push @phenotype, [map {$_} ( $trait_name, $min, $max, $avg, $count )];
257 else {
258 my @cvterms = $population->get_cvterms();
259 foreach my $cvterm(@cvterms)
261 my ($min, $max, $avg, $std, $count)= $population->get_pop_data_summary($cvterm->get_cvterm_id());
262 my $cvterm_id = $cvterm->get_cvterm_id();
263 my $cvterm_name = $cvterm->get_cvterm_name();
265 if ($is_qtl_pop)
267 if ($cvterm->get_definition())
269 push @phenotype, [map {$_} ( (tooltipped_text( qq|<a href="/chado/cvterm.pl?cvterm_id=$cvterm_id">
270 $cvterm_name</a>
272 $cvterm->get_definition())), $min, $max, $avg, $count,
273 qq | <a href="/phenome/population_indls.pl?population_id=$population_id&amp;cvterm_id=$cvterm_id">
274 $graph_icon</a>
275 | ) ];
276 } else
277 { push @phenotype, [map {$_} (qq | <a href="/chado/cvterm.pl?cvterm_id=$cvterm_id">$cvterm_name</a>|,
278 $min, $max, $avg, $count,
279 qq | <a href="/phenome/population_indls.pl?population_id=$population_id&amp;cvterm_id=$cvterm_id">
280 $graph_icon</a>
281 | ) ];
283 } else
285 if ($cvterm->get_definition())
287 push @phenotype, [map {$_} ( (tooltipped_text( qq|<a href="/chado/cvterm.pl?cvterm_id=$cvterm_id">
288 $cvterm_name</a>
290 $cvterm->get_definition())), $min, $max, $avg, $count) ];
291 } else
293 push @phenotype, [map {$_} (qq | <a href="/chado/cvterm.pl?cvterm_id=$cvterm_id">$cvterm_name</a>|,
294 $min, $max, $avg, $count ) ];
300 my $accessions_link = qq |<a href="../search/phenotype_search.pl?wee9_population_id=$population_id">
301 See all accessions ...</a>
304 my ($phenotype_data, $data_view, $data_download);
306 if (@phenotype)
308 if ($is_qtl_pop) {
309 $phenotype_data = columnar_table_html(headings => [
310 'Trait',
311 'Minimum',
312 'Maximum',
313 'Average',
314 'No. of lines',
315 'QTL(s)...',
317 data =>\@phenotype,
318 __alt_freq =>2,
319 __alt_width =>1,
320 __alt_offset =>3,
321 __align =>'l',
324 $data_download .= qq { <span><br/><br/>Download:<a href="pop_download.pl?population_id=$population_id"><b>\
325 [Phenotype raw data]</b></a> <a href="genotype_download.pl?population_id=$population_id"><b>\
326 [Genotype raw data]</b></a></span>
330 } else
332 $phenotype_data = columnar_table_html(headings => [
333 'Trait',
334 'Minimum',
335 'Maximum',
336 'Average',
337 'No. of lines',
339 data =>\@phenotype,
340 __alt_freq =>2,
341 __alt_width =>1,
342 __alt_offset =>3,
343 __align =>'l',
346 $data_download .= qq { <span><br/><br/>Download:<a href="pop_download.pl?population_id=$population_id"><b>\
347 [Phenotype raw data]</b></a></span>
357 my $pub_subtitle;
358 if ($population_name && ($login_user_type eq 'curator' || $login_user_type eq 'submitter')) {
359 $pub_subtitle .= qq|<a href="../chado/add_publication.pl?type=population&amp;type_id=$population_id&amp;refering_page=$page&amp;action=new">[Associate publication]</a>|;
363 else { $pub_subtitle= qq|<span class=\"ghosted\">[Associate publication]</span>|;
368 my $pubmed;
369 my $url_pubmed = qq | http://www.ncbi.nlm.nih.gov/pubmed/|;
371 my @publications = $population->get_population_publications();
372 my $abstract_view;
373 my $abstract_count = 0;
377 foreach my $pub (@publications) {
378 my ($title, $abstract, $authors, $journal, $pyear,
379 $volume, $issue, $pages, $obsolete, $pub_id, $accession
381 $abstract_count++;
383 my @dbxref_objs = $pub->get_dbxrefs();
384 my $dbxref_obj = shift(@dbxref_objs);
386 $obsolete = $population->get_population_dbxref($dbxref_obj)->get_obsolete();
388 if ($obsolete eq 'f') {
389 $pub_id = $pub->get_pub_id();
390 $title = $pub->get_title();
391 $abstract = $pub->get_abstract();
392 $pyear = $pub->get_pyear();
393 $volume = $pub->get_volume();
394 $journal = $pub->get_series_name();
395 $pages = $pub->get_pages();
396 $issue = $pub->get_issue();
398 $accession = $dbxref_obj->get_accession();
399 my $pub_info = qq|<a href="/chado/publication.pl?pub_id=$pub_id" >PMID:$accession</a>|;
401 my @authors;
402 my $authors;
403 if ($pub_id) {
405 my @pubauthors_ids = $pub->get_pubauthors_ids($pub_id);
407 foreach my $pubauthor_id (@pubauthors_ids) {
408 my $pubauthor_obj = CXGN::Chado::Pubauthor->new($self->get_dbh, $pubauthor_id);
409 my $last_name = $pubauthor_obj->get_surname();
410 my $first_names = $pubauthor_obj->get_givennames();
411 my @first_names = split (/,/, $first_names);
412 $first_names = shift (@first_names);
413 push @authors, ("$first_names" ." ". "$last_name");
414 $authors = join (", ", @authors);
421 $abstract_view = html_optional_show("abstracts$abstract_count",
422 'Show/hide abstract',
423 qq|$abstract <b> <i>$authors.</i> $journal. $pyear. $volume($issue). $pages.</b>|,
424 0, #< do not show by default
425 'abstract_optional_show', #< don't use the default button-like style
429 $pubmed .= qq| <div><a href="$url_pubmed$accession" target="blank">$pub_info</a> $title $abstract_view</div> |;
433 my $is_public = $population->get_privacy_status();
434 my ($submitter_obj, $submitter_link) = $self->submitter();
435 my $map_link = $self->genetic_map();
436 print info_section_html(title => 'Population Details',
437 contents => $population_html,
440 if ($is_public ||
441 $login_user_type eq 'curator' ||
442 $login_user_id ==
443 $population->get_sp_person_id()
444 ) {
445 if ($phenotype_data) {
446 print info_section_html(title => 'Phenotype Data and QTLs',
447 contents => $phenotype_data ." ".$data_download
449 } else {
450 print info_section_html(title => 'Phenotype Data',
451 contents => $accessions_link
455 unless (!$map_link) {
456 print info_section_html( title => 'Genetic Map',
457 contents => $map_link
461 } else {
462 my $message = "The QTL data for this population is not public yet.
463 If you would like to know more about this data,
464 please contact the owner of the data: <b>$submitter_link</b>
465 or email to SGN:
466 <a href=mailto:sgn-feedback\@sgn.cornell.edu>
467 sgn-feedback\@sgn.cornell.edu</a>.\n";
469 print info_section_html(title => 'Phenotype Data and QTLs',
470 contents =>$message,
474 print info_section_html(title => 'Literature Annotation',
475 #subtitle => $pub_subtitle,
476 contents => $pubmed,
479 if ($population_name) {
480 # change sgn_people.forum_topic.page_type and the CHECK constraint!!
481 my $page_comment_obj = CXGN::People::PageComment->new($self->get_dbh(), "population", $population_id, $self->get_page()->{request}->uri()."?".$self->get_page()->{request}->args());
482 print $page_comment_obj->get_html();
485 $self->get_page()->footer();
488 exit();
496 # override store to check if a locus with the submitted symbol/name already exists in the database
498 sub store {
499 my $self = shift;
500 my $population = $self->get_object();
501 my $population_id = $self->get_object_id();
502 my %args = $self->get_args();
504 $self->SUPER::store(0);
506 exit();
510 sub submitter {
511 my $self = shift;
512 my $population = $self->get_object();
513 my $sp_person_id= $population->get_sp_person_id();
514 my $submitter = CXGN::People::Person->new($self->get_dbh(), $population->get_sp_person_id());
515 my $submitter_name = $submitter->get_first_name()." ".$submitter->get_last_name();
516 my $submitter_link = qq |<a href="/solpeople/personal-info.pl?sp_person_id=$sp_person_id">$submitter_name</a> |;
518 return $submitter, $submitter_link;
522 sub genetic_map {
523 my $self = shift;
524 my $mapv_id = $self->get_object()->mapversion_id();
526 if ($mapv_id) {
527 my $map = CXGN::Map->new( $self->get_dbh(), { map_version_id => $mapv_id } );
528 my $map_name = $map->get_long_name();
529 my $map_sh_name = $map->get_short_name();
530 my $genetic_map =
531 qq | <a href=/cview/map.pl?map_version_id=$mapv_id>$map_name ($map_sh_name)</a>|;
533 return $genetic_map;
535 else {
536 return;