can download plant phenotype data in the same way as plot phenotype data
[sgn.git] / lib / SGN / Controller / solGS / solGS.pm
blobdb97bfe5ebeefa17a096d546789f61bb45cb6244
1 package SGN::Controller::solGS::solGS;
3 use Moose;
4 use namespace::autoclean;
6 use String::CRC;
7 use URI::FromHash 'uri';
8 use File::Path qw / mkpath /;
9 use File::Spec::Functions qw / catfile catdir/;
10 use File::Temp qw / tempfile tempdir /;
11 use File::Slurp qw /write_file read_file :edit prepend_file append_file/;
12 use File::Copy;
13 use File::Basename;
14 use Cache::File;
15 use Try::Tiny;
16 use List::MoreUtils qw /uniq/;
17 use Scalar::Util qw /weaken reftype/;
18 use Statistics::Descriptive;
19 use Math::Round::Var;
20 use Algorithm::Combinatorics qw /combinations/;
21 use Array::Utils qw(:all);
22 use CXGN::Tools::Run;
23 use JSON;
24 use Storable qw/ nstore retrieve /;
25 use Carp qw/ carp confess croak /;
27 BEGIN { extends 'Catalyst::Controller::HTML::FormFu' }
30 # Sets the actions in this controller to be registered with no prefix
31 # so they function identically to actions created in MyApp.pm
34 #__PACKAGE__->config(namespace => '');
36 =head1 NAME
38 solGS::Controller::Root - Root Controller for solGS
40 =head1 DESCRIPTION
42 [enter your description here]
44 =head1 METHODS
46 =head2 index
48 The root page (/)
50 =cut
53 # sub index :Path :Args(0) {
54 # my ($self, $c) = @_;
55 # $c->forward('search');
56 # }
58 sub solgs : Path('/solgs'){
59 my ($self, $c) = @_;
60 $c->forward('search');
64 sub solgs_breeder_search :Path('/solgs/breeder_search') Args(0) {
65 my ($self, $c) = @_;
66 $c->stash->{referer} = $c->req->referer();
67 $c->stash->{template} = '/solgs/breeder_search_solgs.mas';
71 sub submit :Path('/solgs/submit/intro') Args(0) {
72 my ($self, $c) = @_;
74 $c->stash->{template} = $self->template('/submit/intro.mas');
78 sub details_form : Path('/solgs/form/population/details') Args(0) {
79 my ($self, $c) = @_;
81 $self->load_yaml_file($c, 'population/details.yml');
82 my $form = $c->stash->{form};
84 if ($form->submitted_and_valid )
86 $c->res->redirect('/solgs/form/population/phenotype');
88 else
90 $c->stash(template => $self->template('/form/population/details.mas'),
91 form => $form
97 sub phenotype_form : Path('/solgs/form/population/phenotype') Args(0) {
98 my ($self, $c) = @_;
100 $self->load_yaml_file($c, 'population/phenotype.yml');
101 my $form = $c->stash->{form};
103 if ($form->submitted_and_valid)
105 $c->res->redirect('/solgs/form/population/genotype');
107 else
109 $c->stash(template => $self->template('/form/population/phenotype.mas'),
110 form => $form
117 sub genotype_form : Path('/solgs/form/population/genotype') Args(0) {
118 my ($self, $c) = @_;
120 $self->load_yaml_file($c, 'population/genotype.yml');
121 my $form = $c->stash->{form};
123 if ($form->submitted_and_valid)
125 $c->res->redirect('/solgs/population/12');
127 else
129 $c->stash(template => $self->template('/form/population/genotype.mas'),
130 form => $form
137 sub search : Path('/solgs/search') Args() {
138 my ($self, $c) = @_;
140 $self->load_yaml_file($c, 'search/solgs.yml');
141 my $form = $c->stash->{form};
143 $self->gs_traits_index($c);
144 my $gs_traits_index = $c->stash->{gs_traits_index};
146 my $query;
147 if ($form->submitted_and_valid)
149 $query = $form->param_value('search.search_term');
150 $c->res->redirect("/solgs/search/result/traits/$query");
152 else
154 $c->stash(template => $self->template('/search/solgs.mas'),
155 form => $form,
156 message => $query,
157 gs_traits_index => $gs_traits_index,
164 sub search_trials : Path('/solgs/search/trials') Args() {
165 my ($self, $c) = @_;
167 my $page = $c->req->param('page') || 1;
169 my $project_rs = $c->model('solGS::solGS')->all_projects($page, 15);
171 $self->projects_links($c, $project_rs);
172 my $projects = $c->stash->{projects_pages};
174 my $page_links = sub {uri ( query => { page => shift } ) };
176 my $pager = $project_rs->pager;
177 $pager->change_entries_per_page(15);
179 my $pagination;
180 my $url = '/solgs/search/trials/';
182 if ( $pager->previous_page || $pager->next_page )
184 $pagination = '<div style="width:690px; overflow: auto;" class = "paginate_nav">';
186 if( $pager->previous_page )
188 $pagination .= '<a class="paginate_nav" href="' . $url . $page_links->($pager->previous_page) . '">&lt;</a>';
191 for my $c_page ( $pager->first_page .. $pager->last_page )
193 if( $pager->current_page == $c_page )
195 $pagination .= '<span class="paginate_nav_currpage paginate_nav">' . $c_page . '</span>';
197 else
199 $pagination .= '<a class="paginate_nav" href="' . $url. $page_links->($c_page) . '">' . $c_page . '</a>';
202 if( $pager->next_page )
204 $pagination .= '<a class="paginate_nav" href="' . $url . $page_links->($pager->next_page). '">&gt;</a>';
207 $pagination .= '</div>';
210 my $ret->{status} = 'failed';
212 if (@$projects)
214 $ret->{status} = 'success';
215 $ret->{pagination} = $pagination;
216 $ret->{trials} = $projects;
218 else
220 if ($pager->current_page == $pager->last_page)
222 $c->res->redirect("/solgs/search/trials/?page=1");
224 else
226 my $go_next = $pager->current_page + 1;
227 $c->res->redirect("/solgs/search/trials/?page=$go_next");
231 $ret = to_json($ret);
233 $c->res->content_type('application/json');
234 $c->res->body($ret);
239 sub projects_links {
240 my ($self, $c, $pr_rs) = @_;
242 $self->get_projects_details($c, $pr_rs);
243 my $projects = $c->stash->{projects_details};
245 my @projects_pages;
246 my $update_marker_count;
248 foreach my $pr_id (keys %$projects)
250 my $pr_name = $projects->{$pr_id}{project_name};
251 my $pr_desc = $projects->{$pr_id}{project_desc};
252 my $pr_year = $projects->{$pr_id}{project_year};
253 my $pr_location = $projects->{$pr_id}{project_location};
255 my $dummy_name = $pr_name =~ /test\w*/ig;
256 my $dummy_desc = $pr_desc =~ /test\w*/ig;
258 my ($has_genotype, $has_phenotype, $is_gs);
260 unless ($dummy_name || $dummy_desc || !$pr_name )
262 $is_gs = $c->model("solGS::solGS")->get_project_type($pr_id);
264 if ($is_gs =~ /genomic selection|training population/)
266 $has_phenotype = 1;
268 else
270 my $pheno_file = $self->grep_file($c->stash->{solgs_cache_dir}, "phenotype_data_${pr_id}.txt");
271 if (!-e $pheno_file)
273 $has_phenotype = $c->model("solGS::solGS")->has_phenotype($pr_id);
275 if (!$has_phenotype)
277 my $cache_dir = $c->stash->{solgs_cache_dir};
278 my $file_cache = Cache::File->new(cache_root => $cache_dir);
279 $file_cache->purge();
281 my $key = "phenotype_data_" . $pr_id;
282 my $pheno_file = $file_cache->get($key);
284 no warnings 'uninitialized';
286 $pheno_file = catfile($cache_dir, "phenotype_data_${pr_id}.txt");
288 write_file($pheno_file, "");
289 $file_cache->set($key, $pheno_file, '5 days');
295 my $marker_count;
296 if ($has_phenotype)
298 my $trial_compatibility_file = $self->trial_compatibility_file($c);
299 my $size = -s $trial_compatibility_file;
301 if (-s $trial_compatibility_file && !$update_marker_count)
303 my $genotype_prop = $c->model("solGS::solGS")->get_project_genotypeprop($pr_id);
304 $marker_count = $genotype_prop->{'marker_count'};
306 else
308 $update_marker_count = 1;
309 $c->stash->{pop_id} = $pr_id;
310 $self->store_project_marker_count($c);
314 if (!$marker_count && $has_phenotype)
316 my $markers = $c->model("solGS::solGS")->get_project_genotyping_markers($pr_id);
318 unless (!$markers)
320 $c->stash->{pop_id} = $pr_id;
321 $self->store_project_marker_count($c);
325 my $match_code;
326 if ($marker_count)
328 $self->trial_compatibility_table($c, $marker_count);
329 $match_code = $c->stash->{trial_compatibility_code};
332 if ($marker_count && $has_phenotype)
334 unless ($is_gs)
336 my $pr_prop = {'project_id' => $pr_id,
337 'project_type' => 'genomic selection',
340 $c->model("solGS::solGS")->set_project_type($pr_prop);
344 my $pop_prop = {'project_id' => $pr_id,
345 'population type' => 'training population',
348 my $pop_type = $c->model("solGS::solGS")->get_population_type($pr_id);
350 unless ($pop_type)
352 $c->model("solGS::solGS")->set_population_type($pop_prop);
355 my $checkbox = qq |<form> <input type="checkbox" name="project" value="$pr_id" onclick="getPopIds()"/> </form> |;
357 $match_code = qq | <div class=trial_code style="color: $match_code; background-color: $match_code; height: 100%; width:30px">code</div> |;
359 push @projects_pages, [$checkbox, qq|<a href="/solgs/population/$pr_id" onclick="solGS.waitPage(this.href); return false;">$pr_name</a>|,
360 $pr_desc, $pr_location, $pr_year, $match_code
363 elsif ($marker_count && !$has_phenotype)
365 my $pop_type = $c->model("solGS::solGS")->get_population_type($pr_id);
366 unless ($pop_type)
369 my $pop_prop = {'project_id' => $pr_id,
370 'population type' => 'selection population',
373 $c->model("solGS::solGS")->set_population_type($pop_prop);
378 $c->stash->{projects_pages} = \@projects_pages;
382 sub search_trials_trait : Path('/solgs/search/trials/trait') Args(1) {
383 my ($self, $c, $trait_id) = @_;
385 $self->get_trait_details($c, $trait_id);
387 $c->stash->{template} = $self->template('/search/trials/trait.mas');
392 sub show_search_result_pops : Path('/solgs/search/result/populations') Args(1) {
393 my ($self, $c, $trait_id) = @_;
395 my $combine = $c->req->param('combine');
396 my $page = $c->req->param('page') || 1;
398 my $projects_rs = $c->model('solGS::solGS')->search_populations($trait_id, $page);
399 my $trait = $c->model('solGS::solGS')->trait_name($trait_id);
401 $self->get_projects_details($c, $projects_rs);
402 my $projects = $c->stash->{projects_details};
404 my @projects_list;
405 my $marker_count;
406 my $update_marker_count;
408 foreach my $pr_id (keys %$projects)
410 my $trial_compatibility_file = $self->trial_compatibility_file($c);
412 if (-s $trial_compatibility_file && !$update_marker_count)
414 my $genotype_prop = $c->model("solGS::solGS")->get_project_genotypeprop($pr_id);
415 $marker_count = $genotype_prop->{'marker_count'};
417 else
419 $update_marker_count = 1;
420 $c->stash->{pop_id} = $pr_id;
421 $self->store_project_marker_count($c);
424 if ($marker_count)
426 my $is_gs = $c->model("solGS::solGS")->get_project_type($pr_id);
428 unless ($is_gs)
430 my $pr_prop = {'project_id' => $pr_id, 'project_type' => 'genomic selection'};
431 $c->model("solGS::solGS")->set_project_type($pr_prop);
434 $self->trial_compatibility_table($c, $marker_count);
435 my $match_code = $c->stash->{trial_compatibility_code};
437 my $pr_name = $projects->{$pr_id}{project_name};
438 my $pr_desc = $projects->{$pr_id}{project_desc};
439 my $pr_year = $projects->{$pr_id}{project_year};
440 my $pr_location = $projects->{$pr_id}{project_location};
442 my $checkbox = qq |<form> <input type="checkbox" name="project" value="$pr_id" onclick="getPopIds()"/> </form> |;
443 $match_code = qq | <div class=trial_code style="color: $match_code; background-color: $match_code; height: 100%; width:100%">code</div> |;
445 push @projects_list, [ $checkbox, qq|<a href="/solgs/trait/$trait_id/population/$pr_id" onclick="solGS.waitPage(this.href); return false;">$pr_name</a>|, $pr_desc, $pr_location, $pr_year, $match_code
450 my $page_links = sub {uri ( query => { page => shift } ) };
451 my $pager = $projects_rs->pager;
452 $pager->change_entries_per_page(15);
454 my $pagination;
456 my $url = "/solgs/search/result/populations/$trait_id";
458 if ( $pager->previous_page || $pager->next_page )
460 $pagination = '<div style="width:690px; overflow: auto;" class = "paginate_nav">';
462 if( $pager->previous_page )
464 $pagination .= '<a class="paginate_nav" href="' . $url . $page_links->($pager->previous_page) . '">&lt;</a>';
467 for my $c_page ( $pager->first_page .. $pager->last_page )
469 if( $pager->current_page == $c_page )
471 $pagination .= '<span class="paginate_nav_currpage paginate_nav">' . $c_page . '</span>';
473 else
475 $pagination .= '<a class="paginate_nav" href="' . $url. $page_links->($c_page) . '">' . $c_page . '</a>';
478 if( $pager->next_page )
480 $pagination .= '<a class="paginate_nav" href="' . $url . $page_links->($pager->next_page). '">&gt;</a>';
483 $pagination .= '</div>';
486 my $ret->{status} = 'failed';
488 if (@projects_list)
490 $ret->{status} = 'success';
491 $ret->{pagination} = $pagination;
492 $ret->{trials} = \@projects_list;
494 else
496 if ($pager->current_page == $pager->last_page)
498 $c->res->redirect("/solgs/search/result/populations/$trait_id/?page=1&trait=$trait");
500 else
502 my $go_next = $pager->current_page + 1;
503 $c->res->redirect("/solgs/search/result/populations/$trait_id/?page=$go_next&trait=$trait");
507 $ret = to_json($ret);
509 $c->res->content_type('application/json');
510 $c->res->body($ret);
515 sub trial_compatibility_table {
516 my ($self, $c, $markers) = @_;
518 $self->trial_compatibility_file($c);
519 my $compatibility_file = $c->stash->{trial_compatibility_file};
521 my $color;
523 if (-s $compatibility_file)
525 my @line = read_file($compatibility_file);
526 my ($entry) = grep(/$markers/, @line);
527 chomp($entry);
529 if($entry)
531 ($markers, $color) = split(/\t/, $entry);
532 $c->stash->{trial_compatibility_code} = $color;
536 if (!$color)
538 my ($red, $blue, $green) = map { int(rand(255)) } 1..3;
539 $color = 'rgb' . '(' . "$red,$blue,$green" . ')';
541 my $color_code = $markers . "\t" . $color . "\n";
543 $c->stash->{trial_compatibility_code} = $color;
544 write_file($compatibility_file,{append => 1}, $color_code);
549 sub trial_compatibility_file {
550 my ($self, $c) = @_;
552 my $cache_data = {key => 'trial_compatibility',
553 file => 'trial_compatibility_codes',
554 stash_key => 'trial_compatibility_file'
557 $self->cache_file($c, $cache_data);
562 sub get_projects_details {
563 my ($self, $c, $pr_rs) = @_;
565 my ($year, $location, $pr_id, $pr_name, $pr_desc);
566 my %projects_details = ();
568 while (my $pr = $pr_rs->next)
570 $pr_id = $pr->get_column('project_id');
571 $pr_name = $pr->get_column('name');
572 $pr_desc = $pr->get_column('description');
574 my $pr_yr_rs = $c->model('solGS::solGS')->project_year($pr_id);
576 while (my $pr = $pr_yr_rs->next)
578 $year = $pr->value;
581 my $location = $c->model('solGS::solGS')->project_location($pr_id);
583 $projects_details{$pr_id} = {
584 project_name => $pr_name,
585 project_desc => $pr_desc,
586 project_year => $year,
587 project_location => $location,
591 $c->stash->{projects_details} = \%projects_details;
596 sub store_project_marker_count {
597 my ($self, $c) = @_;
599 my $pop_id = $c->stash->{pop_id};
600 my $marker_count = $c->stash->{marker_count};
602 unless ($marker_count)
604 my $markers = $c->model("solGS::solGS")->get_project_genotyping_markers($pop_id);
605 my @markers = split('\t', $markers);
606 $marker_count = scalar(@markers);
609 my $genoprop = {'project_id' => $pop_id, 'marker_count' => $marker_count};
610 $c->model("solGS::solGS")->set_project_genotypeprop($genoprop);
615 sub show_search_result_traits : Path('/solgs/search/result/traits') Args(1) {
616 my ($self, $c, $query) = @_;
618 my $page = $c->req->param('page') || 1;
619 my $gs_traits = $c->model('solGS::solGS')->search_trait($query);
620 my $result = $c->model('solGS::solGS')->trait_details($gs_traits);
622 my @rows;
623 while (my $row = $result->next)
625 my $id = $row->cvterm_id;
626 my $name = $row->name;
627 my $def = $row->definition;
629 my $checkbox;
630 push @rows, [ qq |<a href="/solgs/search/trials/trait/$id" onclick="solGS.waitPage()">$name</a>|, $def];
633 if (@rows)
635 $c->stash(template => $self->template('/search/result/traits.mas'),
636 result => \@rows,
637 query => $query,
640 else
642 $self->gs_traits_index($c);
643 my $gs_traits_index = $c->stash->{gs_traits_index};
645 my $page = $c->req->param('page') || 1;
646 my $project_rs = $c->model('solGS::solGS')->all_projects($page);
647 $self->projects_links($c, $project_rs);
648 my $projects = $c->stash->{projects_pages};
650 $self->load_yaml_file($c, 'search/solgs.yml');
651 my $form = $c->stash->{form};
653 $c->stash(template => $self->template('/search/solgs.mas'),
654 form => $form,
655 message => $query,
656 gs_traits_index => $gs_traits_index,
657 result => $projects,
658 pager => $project_rs->pager,
659 page_links => sub {uri ( query => { page => shift } ) }
666 sub population : Regex('^solgs/population/([\w|\d]+)(?:/([\w+]+))?') {
667 my ($self, $c) = @_;
669 my ($pop_id, $action) = @{$c->req->captures};
671 my $uploaded_reference = $c->req->param('uploaded_reference');
672 $c->stash->{uploaded_reference} = $uploaded_reference;
674 if ($uploaded_reference)
676 $pop_id = $c->req->param('model_id');
678 $c->stash->{model_id} = $c->req->param('model_id'),
679 $c->stash->{list_name} = $c->req->param('list_name'),
683 if ($pop_id )
685 if($pop_id =~ /uploaded/)
687 $c->stash->{uploaded_reference} = 1;
688 $uploaded_reference = 1;
691 $c->stash->{pop_id} = $pop_id;
693 $self->phenotype_file($c);
694 $self->genotype_file($c);
695 $self->get_all_traits($c);
696 $self->project_description($c, $pop_id);
698 $c->stash->{template} = $self->template('/population.mas');
700 if ($action && $action =~ /selecttraits/ ) {
701 $c->stash->{no_traits_selected} = 'none';
703 else {
704 $c->stash->{no_traits_selected} = 'some';
707 $self->select_traits($c);
709 my $acronym = $self->get_acronym_pairs($c);
710 $c->stash->{acronym} = $acronym;
713 my $pheno_data_file = $c->stash->{phenotype_file};
715 if ($uploaded_reference)
717 my $ret->{status} = 'failed';
718 if( !-s $pheno_data_file )
720 $ret->{status} = 'failed';
722 $ret = to_json($ret);
724 $c->res->content_type('application/json');
725 $c->res->body($ret);
731 sub uploaded_population_summary {
732 my ($self, $c) = @_;
734 my $tmp_dir = $c->stash->{solgs_prediction_upload_dir};
736 if (!$c->user)
738 my $page = "/" . $c->req->path;
739 $c->res->redirect("/solgs/list/login/message?page=$page");
740 $c->detach;
742 else
744 my $user_name = $c->user->id;
746 my $model_id = $c->stash->{model_id};
747 my $selection_pop_id = $c->stash->{prediction_pop_id};
749 my $protocol = $c->config->{default_genotyping_protocol};
750 $protocol = 'N/A' if !$protocol;
752 if ($model_id)
754 my $metadata_file_tr = catfile($tmp_dir, "metadata_${user_name}_${model_id}");
756 my @metadata_tr = read_file($metadata_file_tr) if $model_id;
758 my ($key, $list_name, $desc);
760 ($desc) = grep {/description/} @metadata_tr;
761 ($key, $desc) = split(/\t/, $desc);
763 ($list_name) = grep {/list_name/} @metadata_tr;
764 ($key, $list_name) = split(/\t/, $list_name);
766 $c->stash(project_id => $model_id,
767 project_name => $list_name,
768 project_desc => $desc,
769 owner => $user_name,
770 protocol => $protocol,
774 if ($selection_pop_id =~ /uploaded/)
776 my $metadata_file_sl = catfile($tmp_dir, "metadata_${user_name}_${selection_pop_id}");
777 my @metadata_sl = read_file($metadata_file_sl) if $selection_pop_id;
779 my ($list_name_sl) = grep {/list_name/} @metadata_sl;
780 my ($key_sl, $list_name) = split(/\t/, $list_name_sl);
782 $c->stash->{prediction_pop_name} = $list_name;
788 sub get_project_details {
789 my ($self, $c, $pr_id) = @_;
791 my $pr_rs = $c->model('solGS::solGS')->project_details($pr_id);
793 while (my $row = $pr_rs->next)
795 $c->stash(project_id => $row->id,
796 project_name => $row->name,
797 project_desc => $row->description
804 sub project_description {
805 my ($self, $c, $pr_id) = @_;
807 $c->stash->{uploaded_reference} = 1 if ($pr_id =~ /uploaded/);
809 my $protocol = $c->config->{default_genotyping_protocol};
810 $protocol = 'N/A' if !$protocol;
812 if(!$c->stash->{uploaded_reference}) {
813 my $pr_rs = $c->model('solGS::solGS')->project_details($pr_id);
815 while (my $row = $pr_rs->next)
817 $c->stash(project_id => $row->id,
818 project_name => $row->name,
819 project_desc => $row->description
823 $self->get_project_owners($c, $pr_id);
824 $c->stash->{owner} = $c->stash->{project_owners};
827 else
829 $c->stash->{model_id} = $pr_id;
830 $self->uploaded_population_summary($c);
833 $self->genotype_file($c);
834 my $geno_file = $c->stash->{genotype_file};
835 my @geno_lines = read_file($geno_file);
836 my $markers_no = scalar(split ('\t', $geno_lines[0])) - 1;
838 $self->trait_phenodata_file($c);
839 my $trait_pheno_file = $c->stash->{trait_phenodata_file};
840 my @trait_pheno_lines = read_file($trait_pheno_file) if $trait_pheno_file;
842 my $stocks_no = @trait_pheno_lines ? scalar(@trait_pheno_lines) - 1 : scalar(@geno_lines) - 1;
844 $self->phenotype_file($c);
845 my $pheno_file = $c->stash->{phenotype_file};
846 my @phe_lines = read_file($pheno_file);
847 my $traits = $phe_lines[0];
849 $self->filter_phenotype_header($c);
850 my $filter_header = $c->stash->{filter_phenotype_header};
852 $traits =~ s/($filter_header\t)//g;
854 my @traits = split (/\t/, $traits);
855 my $traits_no = scalar(@traits);
857 $c->stash(markers_no => $markers_no,
858 traits_no => $traits_no,
859 stocks_no => $stocks_no,
860 protocol => $protocol,
865 sub select_traits {
866 my ($self, $c) = @_;
868 $self->load_yaml_file($c, 'population/traits.yml');
869 $c->stash->{traits_form} = $c->stash->{form};
873 sub selection_trait :Path('/solgs/selection/') Args(5) {
874 my ($self, $c, $selection_pop_id,
875 $model_key, $model_id,
876 $trait_key, $trait_id) = @_;
878 $c->stash->{pop_id} = $model_id;
879 $c->stash->{trait_id} = $trait_id;
880 $c->stash->{prediction_pop_id} = $selection_pop_id;
881 $c->stash->{template} = $self->template('/population/selection_trait.mas');
883 $self->get_trait_details($c, $trait_id);
885 my $page = $c->req->referer();
887 if ($page =~ /solgs\/model\/combined\/populations/ || $page =~ /solgs\/models\/combined\/trials/ || $model_id =~ /combined/)
889 $model_id =~ s/combined_//g;
891 $c->stash->{pop_id} = $model_id;
892 $self->combined_pops_catalogue_file($c);
893 my $combo_pops_catalogue_file = $c->stash->{combined_pops_catalogue_file};
895 my @combos = read_file($combo_pops_catalogue_file);
897 foreach (@combos)
899 if ($_ =~ m/$model_id/)
901 my ($combo_pops_id, $pops) = split(/\t/, $_);
902 $c->stash->{trait_combo_pops} = $pops;
906 $c->stash->{combo_pops_id} = $model_id;
907 $self->combined_pops_summary($c);
908 $c->stash->{combined_populations} = 1;
911 elsif ($model_id =~ /uploaded/)
913 $c->stash->{prediction_pop_id} = $selection_pop_id;
914 $c->stash->{prediction_pop_name} = $c->stash->{project_name};
916 $c->stash->{model_id} = $model_id;
917 $self->uploaded_population_summary($c);
919 $self->genotype_file($c);
920 my $geno_file = $c->stash->{genotype_file};
921 my @geno_lines = read_file($geno_file);
922 my $markers_no = scalar(split ('\t', $geno_lines[0])) - 1;
924 $self->trait_phenodata_file($c);
925 my $trait_pheno_file = $c->stash->{trait_phenodata_file};
926 my @trait_pheno_lines = read_file($trait_pheno_file) if $trait_pheno_file;
928 my $stocks_no = @trait_pheno_lines ? scalar(@trait_pheno_lines) - 1 : scalar(@geno_lines) - 1;
930 $self->phenotype_file($c);
931 my $pheno_file = $c->stash->{phenotype_file};
932 my @phe_lines = read_file($pheno_file);
933 my $traits = $phe_lines[0];
935 $self->filter_phenotype_header($c);
936 my $filter_header = $c->stash->{filter_phenotype_header};
938 $traits =~ s/($filter_header\t)//g;
940 my @traits = split (/\t/, $traits);
941 my $traits_no = scalar(@traits);
943 $c->stash(markers_no => $markers_no,
944 traits_no => $traits_no,
945 stocks_no => $stocks_no,
948 else
950 $self->project_description($c, $model_id);
951 $self->get_project_owners($c, $model_id);
952 $c->stash->{owner} = $c->stash->{project_owners};
955 if ($selection_pop_id =~ /uploaded/)
957 $c->stash->{prediction_pop_id} = $selection_pop_id;
958 $self->uploaded_population_summary($c);
960 else
962 my $pop_rs = $c->model("solGS::solGS")->project_details($selection_pop_id);
963 while (my $pop_row = $pop_rs->next)
965 $c->stash->{prediction_pop_name} = $pop_row->name;
969 my $identifier = $model_id . '_' . $selection_pop_id;
971 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
972 my $gebvs_file = $c->stash->{prediction_pop_gebvs_file};
974 $self->top_blups($c, $gebvs_file);
976 $c->stash->{blups_download_url} = qq | <a href="/solgs/download/prediction/model/$model_id/prediction/$selection_pop_id/$trait_id">Download all GEBVs</a>|;
981 sub build_single_trait_model {
982 my ($self, $c) = @_;
984 my $trait_id = $c->stash->{trait_id};
985 $self->get_trait_details($c, $trait_id);
987 $self->get_rrblup_output($c);
992 sub trait :Path('/solgs/trait') Args(3) {
993 my ($self, $c, $trait_id, $key, $pop_id) = @_;
995 my $ajaxredirect = $c->req->param('source');
996 $c->stash->{ajax_request} = $ajaxredirect;
998 if ($pop_id && $trait_id)
1000 $c->stash->{pop_id} = $pop_id;
1001 $c->stash->{trait_id} = $trait_id;
1003 $self->build_single_trait_model($c);
1005 $self->gs_files($c);
1007 unless ($ajaxredirect eq 'heritability')
1009 my $script_error = $c->stash->{script_error};
1011 if ($script_error)
1013 my $trait_name = $c->stash->{trait_name};
1014 $c->stash->{message} = "$script_error can't create a prediction model for <b>$trait_name</b>.
1015 There is a problem with the trait dataset.";
1017 $c->stash->{template} = "/generic_message.mas";
1019 else
1021 $self->project_description($c, $pop_id);
1023 $self->trait_phenotype_stat($c);
1025 $self->get_project_owners($c, $pop_id);
1026 $c->stash->{owner} = $c->stash->{project_owners};
1028 $c->stash->{template} = $self->template("/population/trait.mas");
1033 if ($ajaxredirect)
1035 my $trait_abbr = $c->stash->{trait_abbr};
1036 my $cache_dir = $c->stash->{solgs_cache_dir};
1037 my $gebv_file = "gebv_kinship_${trait_abbr}_${pop_id}";
1038 $gebv_file = $self->grep_file($cache_dir, $gebv_file);
1040 my $ret->{status} = 'failed';
1042 if (-s $gebv_file)
1044 $ret->{status} = 'success';
1047 $ret = to_json($ret);
1049 $c->res->content_type('application/json');
1050 $c->res->body($ret);
1057 sub gs_files {
1058 my ($self, $c) = @_;
1060 $self->output_files($c);
1061 #$self->input_files($c);
1062 $self->model_accuracy($c);
1063 $self->blups_file($c);
1064 $self->download_urls($c);
1065 $self->top_markers($c);
1066 $self->model_parameters($c);
1071 sub input_files {
1072 my ($self, $c) = @_;
1074 $self->genotype_file($c);
1075 $self->phenotype_file($c);
1076 $self->formatted_phenotype_file($c);
1078 my $pred_pop_id = $c->stash->{prediction_pop_id};
1079 my $prediction_population_file;
1081 if ($pred_pop_id)
1083 $self->prediction_population_file($c, $pred_pop_id);
1084 $prediction_population_file = $c->stash->{prediction_population_file};
1087 my $formatted_phenotype_file = $c->stash->{formatted_phenotype_file};
1089 my $pheno_file = $c->stash->{phenotype_file};
1090 my $geno_file = $c->stash->{genotype_file};
1091 my $traits_file = $c->stash->{selected_traits_file};
1092 my $trait_file = $c->stash->{trait_file};
1093 my $pop_id = $c->stash->{pop_id};
1095 no warnings 'uninitialized';
1097 my $input_files = join ("\t",
1098 $pheno_file,
1099 $formatted_phenotype_file,
1100 $geno_file,
1101 $traits_file,
1102 $trait_file,
1103 $prediction_population_file
1106 my $name = "input_files_${pop_id}";
1107 my $tempfile = $self->create_tempfile($c, $name);
1108 write_file($tempfile, $input_files);
1109 $c->stash->{input_files} = $tempfile;
1114 sub output_files {
1115 my ($self, $c) = @_;
1117 my $pop_id = $c->stash->{pop_id};
1118 my $trait = $c->stash->{trait_abbr};
1119 my $trait_id = $c->stash->{trait_id};
1121 $self->gebv_marker_file($c);
1122 $self->gebv_kinship_file($c);
1123 $self->validation_file($c);
1124 $self->trait_phenodata_file($c);
1125 $self->variance_components_file($c);
1126 $self->relationship_matrix_file($c);
1128 my $prediction_id = $c->stash->{prediction_pop_id};
1129 if (!$pop_id) {$pop_id = $c->stash->{model_id};}
1131 no warnings 'uninitialized';
1133 $prediction_id = "uploaded_${prediction_id}" if $c->stash->{uploaded_prediction};
1135 my $pred_pop_gebvs_file;
1137 if ($prediction_id)
1139 my $identifier = $pop_id . '_' . $prediction_id;
1140 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
1141 $pred_pop_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
1144 my $file_list = join ("\t",
1145 $c->stash->{gebv_kinship_file},
1146 $c->stash->{gebv_marker_file},
1147 $c->stash->{validation_file},
1148 $c->stash->{trait_phenodata_file},
1149 $c->stash->{selected_traits_gebv_file},
1150 $c->stash->{variance_components_file},
1151 $c->stash->{relationship_matrix_file},
1152 $pred_pop_gebvs_file
1155 my $name = "output_files_${trait}_$pop_id";
1156 my $tempfile = $self->create_tempfile($c, $name);
1157 write_file($tempfile, $file_list);
1159 $c->stash->{output_files} = $tempfile;
1164 sub gebv_marker_file {
1165 my ($self, $c) = @_;
1167 my $pop_id = $c->stash->{pop_id};
1168 my $trait = $c->stash->{trait_abbr};
1170 no warnings 'uninitialized';
1172 my $data_set_type = $c->stash->{data_set_type};
1174 my $cache_data;
1176 if ($data_set_type =~ /combined populations/)
1178 my $combo_identifier = $c->stash->{combo_pops_id};
1180 $cache_data = {key => 'gebv_marker_combined_pops_'. $trait . '_' . $combo_identifier,
1181 file => 'gebv_marker_'. $trait . '_' . $combo_identifier . '_combined_pops',
1182 stash_key => 'gebv_marker_file'
1185 else
1188 $cache_data = {key => 'gebv_marker_' . $pop_id . '_'. $trait,
1189 file => 'gebv_marker_' . $trait . '_' . $pop_id,
1190 stash_key => 'gebv_marker_file'
1194 $self->cache_file($c, $cache_data);
1199 sub variance_components_file {
1200 my ($self, $c) = @_;
1202 my $pop_id = $c->stash->{pop_id};
1203 my $trait = $c->stash->{trait_abbr};
1205 my $data_set_type = $c->stash->{data_set_type};
1207 my $cache_data;
1209 no warnings 'uninitialized';
1211 if ($data_set_type =~ /combined populations/)
1213 my $combo_identifier = $c->stash->{combo_pops_id};
1215 $cache_data = {key => 'variance_components_combined_pops_'. $trait . "_". $combo_identifier,
1216 file => 'variance_components_'. $trait . '_' . $combo_identifier. '_combined_pops',
1217 stash_key => 'variance_components_file'
1220 else
1222 $cache_data = {key => 'variance_components_' . $pop_id . '_'. $trait,
1223 file => 'variance_components_' . $trait . '_' . $pop_id,
1224 stash_key => 'variance_components_file'
1228 $self->cache_file($c, $cache_data);
1232 sub trait_phenodata_file {
1233 my ($self, $c) = @_;
1235 my $pop_id = $c->stash->{pop_id};
1236 my $trait = $c->stash->{trait_abbr};
1237 my $data_set_type = $c->stash->{data_set_type};
1239 my $cache_data;
1241 no warnings 'uninitialized';
1243 if ($data_set_type =~ /combined populations/)
1245 my $combo_identifier = $c->stash->{combo_pops_id};
1246 $cache_data = {key => 'phenotype_trait_combined_pops_'. $trait . "_". $combo_identifier,
1247 file => 'phenotype_trait_'. $trait . '_' . $combo_identifier. '_combined_pops',
1248 stash_key => 'trait_phenodata_file'
1251 else
1253 $cache_data = {key => 'phenotype_' . $pop_id . '_'. $trait,
1254 file => 'phenotype_trait_' . $trait . '_' . $pop_id,
1255 stash_key => 'trait_phenodata_file'
1259 $self->cache_file($c, $cache_data);
1263 sub formatted_phenotype_file {
1264 my ($self, $c) = @_;
1266 my $pop_id = $c->stash->{pop_id};
1267 $pop_id = $c->{stash}->{combo_pops_id} if !$pop_id;
1269 my $cache_data = { key => 'formatted_phenotype_data_' . $pop_id,
1270 file => 'formatted_phenotype_data_' . $pop_id,
1271 stash_key => 'formatted_phenotype_file'
1274 $self->cache_file($c, $cache_data);
1278 sub gebv_kinship_file {
1279 my ($self, $c) = @_;
1281 my $pop_id = $c->stash->{pop_id};
1282 my $trait = $c->stash->{trait_abbr};
1283 my $data_set_type = $c->stash->{data_set_type};
1285 my $cache_data;
1287 no warnings 'uninitialized';
1289 if ($data_set_type =~ /combined populations/)
1291 my $combo_identifier = $c->stash->{combo_pops_id};
1292 $cache_data = {key => 'gebv_kinship_combined_pops_'. $combo_identifier . "_" . $trait,
1293 file => 'gebv_kinship_'. $trait . '_' . $combo_identifier. '_combined_pops',
1294 stash_key => 'gebv_kinship_file'
1298 else
1301 $cache_data = {key => 'gebv_kinship_' . $pop_id . '_'. $trait,
1302 file => 'gebv_kinship_' . $trait . '_' . $pop_id,
1303 stash_key => 'gebv_kinship_file'
1307 $self->cache_file($c, $cache_data);
1312 sub relationship_matrix_file {
1313 my ($self, $c) = @_;
1315 my $pop_id = $c->stash->{pop_id};
1316 my $data_set_type = $c->stash->{data_set_type};
1318 my $cache_data;
1320 no warnings 'uninitialized';
1322 if ($data_set_type =~ /combined populations/)
1324 my $combo_identifier = $c->stash->{combo_pops_id};
1325 $cache_data = {key => 'relationship_matrix_combined_pops_'. $combo_identifier,
1326 file => 'relationship_matrix_combined_pops_' . $combo_identifier,
1327 stash_key => 'relationship_matrix_file'
1331 else
1334 $cache_data = {key => 'relationship_matrix_' . $pop_id,
1335 file => 'relationship_matrix_' . $pop_id,
1336 stash_key => 'relationship_matrix_file'
1340 $self->cache_file($c, $cache_data);
1345 sub blups_file {
1346 my ($self, $c) = @_;
1348 my $blups_file = $c->stash->{gebv_kinship_file};
1349 $self->top_blups($c, $blups_file);
1353 sub download_blups :Path('/solgs/download/blups/pop') Args(3) {
1354 my ($self, $c, $pop_id, $trait, $trait_id) = @_;
1356 $self->get_trait_details($c, $trait_id);
1357 my $trait_abbr = $c->stash->{trait_abbr};
1359 my $dir = $c->stash->{solgs_cache_dir};
1360 my $blup_exp = "gebv_kinship_${trait_abbr}_${pop_id}";
1361 my $blups_file = $self->grep_file($dir, $blup_exp);
1363 unless (!-e $blups_file || -s $blups_file == 0)
1365 my @blups = map { [ split(/\t/) ] } read_file($blups_file);
1367 $c->res->content_type("text/plain");
1368 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @blups);
1374 sub download_marker_effects :Path('/solgs/download/marker/pop') Args(3) {
1375 my ($self, $c, $pop_id, $trait, $trait_id) = @_;
1377 $self->get_trait_details($c, $trait_id);
1378 my $trait_abbr = $c->stash->{trait_abbr};
1380 my $dir = $c->stash->{solgs_cache_dir};
1381 my $marker_exp = "gebv_marker_${trait_abbr}_${pop_id}";
1382 my $markers_file = $self->grep_file($dir, $marker_exp);
1384 unless (!-e $markers_file || -s $markers_file == 0)
1386 my @effects = map { [ split(/\t/) ] } read_file($markers_file);
1388 $c->res->content_type("text/plain");
1389 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @effects);
1395 sub download_urls {
1396 my ($self, $c) = @_;
1397 my $data_set_type = $c->stash->{data_set_type};
1398 my $pop_id;
1400 no warnings 'uninitialized';
1402 if ($data_set_type =~ /combined populations/)
1404 $pop_id = $c->stash->{combo_pops_id};
1406 else
1408 $pop_id = $c->stash->{pop_id};
1411 my $trait_id = $c->stash->{trait_id};
1412 my $ranked_genos_file = $c->stash->{selection_index_file};
1414 if ($ranked_genos_file)
1416 ($ranked_genos_file) = fileparse($ranked_genos_file);
1419 my $blups_url = qq | <a href="/solgs/download/blups/pop/$pop_id/trait/$trait_id">Download all GEBVs</a> |;
1420 my $marker_url = qq | <a href="/solgs/download/marker/pop/$pop_id/trait/$trait_id">Download all marker effects</a> |;
1421 my $validation_url = qq | <a href="/solgs/download/validation/pop/$pop_id/trait/$trait_id">Download model accuracy report</a> |;
1422 my $ranked_genotypes_url = qq | <a href="/solgs/download/ranked/genotypes/pop/$pop_id/$ranked_genos_file">Download selection indices</a> |;
1424 $c->stash(blups_download_url => $blups_url,
1425 marker_effects_download_url => $marker_url,
1426 validation_download_url => $validation_url,
1427 ranked_genotypes_download_url => $ranked_genotypes_url,
1432 sub top_blups {
1433 my ($self, $c, $blups_file) = @_;
1435 my $blups = $self->convert_to_arrayref_of_arrays($c, $blups_file);
1437 my @top_blups = @$blups[0..9];
1439 $c->stash->{top_blups} = \@top_blups;
1443 sub top_markers {
1444 my ($self, $c) = @_;
1446 my $markers_file = $c->stash->{gebv_marker_file};
1448 my $markers = $self->convert_to_arrayref_of_arrays($c, $markers_file);
1450 my @top_markers = @$markers[0..9];
1452 $c->stash->{top_marker_effects} = \@top_markers;
1456 sub validation_file {
1457 my ($self, $c) = @_;
1459 my $pop_id = $c->stash->{pop_id};
1460 my $trait = $c->stash->{trait_abbr};
1462 my $data_set_type = $c->stash->{data_set_type};
1464 my $cache_data;
1466 no warnings 'uninitialized';
1468 if ($data_set_type =~ /combined populations/)
1470 my $combo_identifier = $c->stash->{combo_pops_id};
1471 $cache_data = {key => 'cross_validation_combined_pops_'. $trait . "_${combo_identifier}",
1472 file => 'cross_validation_'. $trait . '_' . $combo_identifier . '_combined_pops' ,
1473 stash_key => 'validation_file'
1476 else
1479 $cache_data = {key => 'cross_validation_' . $pop_id . '_' . $trait,
1480 file => 'cross_validation_' . $trait . '_' . $pop_id,
1481 stash_key => 'validation_file'
1485 $self->cache_file($c, $cache_data);
1489 sub combined_gebvs_file {
1490 my ($self, $c, $identifier) = @_;
1492 my $pop_id = $c->stash->{pop_id};
1494 my $cache_data = {key => 'selected_traits_gebv_' . $pop_id . '_' . $identifier,
1495 file => 'selected_traits_gebv_' . $pop_id . '_' . $identifier,
1496 stash_key => 'selected_traits_gebv_file'
1499 $self->cache_file($c, $cache_data);
1504 sub download_validation :Path('/solgs/download/validation/pop') Args(3) {
1505 my ($self, $c, $pop_id, $trait, $trait_id) = @_;
1507 $self->get_trait_details($c, $trait_id);
1508 my $trait_abbr = $c->stash->{trait_abbr};
1510 my $dir = $c->stash->{solgs_cache_dir};
1511 my $val_exp = "cross_validation_${trait_abbr}_${pop_id}";
1512 my $validation_file = $self->grep_file($dir, $val_exp);
1514 unless (!-e $validation_file || -s $validation_file == 0)
1516 my @validation = map { [ split(/\t/) ] } read_file($validation_file);
1518 $c->res->content_type("text/plain");
1519 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @validation);
1525 sub predict_selection_pop_single_trait {
1526 my ($self, $c) = @_;
1528 if ($c->stash->{data_set_type} =~ /single population/)
1530 $self->predict_selection_pop_single_pop_model($c)
1532 else
1534 $self->predict_selection_pop_combined_pops_model($c);
1541 sub predict_selection_pop_multi_traits {
1542 my ($self, $c) = @_;
1544 my $data_set_type = $c->stash->{data_set_type};
1545 my $training_pop_id = $c->stash->{training_pop_id};
1546 my $selection_pop_id = $c->stash->{selection_pop_id};
1548 $c->stash->{pop_id} = $training_pop_id;
1549 $self->traits_with_valid_models($c);
1550 my @traits_with_valid_models = @{$c->stash->{traits_with_valid_models}};
1552 foreach my $trait_abbr (@traits_with_valid_models)
1554 $c->stash->{trait_abbr} = $trait_abbr;
1555 $self->get_trait_details_of_trait_abbr($c);
1556 $self->predict_selection_pop_single_trait($c);
1562 sub predict_selection_pop_single_pop_model {
1563 my ($self, $c) = @_;
1565 my $trait_id = $c->stash->{trait_id};
1566 my $training_pop_id = $c->stash->{training_pop_id};
1567 my $prediction_pop_id = $c->stash->{prediction_pop_id};
1569 $self->get_trait_details($c, $trait_id);
1570 my $trait_abbr = $c->stash->{trait_abbr};
1572 my $identifier = $training_pop_id . '_' . $prediction_pop_id;
1573 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
1575 my $prediction_pop_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
1577 if (! -s $prediction_pop_gebvs_file)
1579 my $dir = $c->stash->{solgs_cache_dir};
1581 my $exp = "phenotype_data_${training_pop_id}";
1582 my $pheno_file = $self->grep_file($dir, $exp);
1584 $exp = "genotype_data_${training_pop_id}";
1585 my $geno_file = $self->grep_file($dir, $exp);
1587 $c->stash->{pheno_file} = $pheno_file;
1588 $c->stash->{geno_file} = $geno_file;
1589 $self->prediction_population_file($c, $prediction_pop_id);
1591 $self->get_rrblup_output($c);
1597 sub predict_selection_pop_combined_pops_model {
1598 my ($self, $c) = @_;
1600 my $data_set_type = $c->stash->{data_set_type};
1601 my $combo_pops_id = $c->stash->{combo_pops_id};
1602 my $model_id = $c->stash->{model_id};
1603 my $prediction_pop_id = $c->stash->{prediction_pop_id};
1604 my $trait_id = $c->stash->{trait_id};
1606 $self->get_trait_details($c, $trait_id);
1607 my $trait_abbr = $c->stash->{trait_abbr};
1609 my $identifier = $combo_pops_id . '_' . $prediction_pop_id;
1610 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
1612 my $prediction_pop_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
1614 if (! -s $prediction_pop_gebvs_file)
1616 $self->cache_combined_pops_data($c);
1618 $self->prediction_population_file($c, $prediction_pop_id);
1620 $self->get_rrblup_output($c);
1626 sub prediction_population :Path('/solgs/model') Args(3) {
1627 my ($self, $c, $model_id, $pop, $prediction_pop_id) = @_;
1629 my $referer = $c->req->referer;
1630 my $base = $c->req->base;
1631 $referer =~ s/$base//;
1632 my $path = $c->req->path;
1633 $path =~ s/$base//;
1634 my $page = 'solgs/model/combined/populations/';
1636 if ($referer =~ /$page/)
1638 $model_id =~ s/combined_//;
1639 my ($combo_pops_id, $trait_id) = $referer =~ m/(\d+)/g;
1641 $c->stash->{data_set_type} = "combined populations";
1642 $c->stash->{combo_pops_id} = $model_id;
1643 $c->stash->{model_id} = $model_id;
1644 $c->stash->{prediction_pop_id} = $prediction_pop_id;
1645 $c->stash->{trait_id} = $trait_id;
1647 $self->predict_selection_pop_combined_pops_model($c);
1649 $self->combined_pops_summary($c);
1650 $self->trait_phenotype_stat($c);
1651 $self->gs_files($c);
1653 $c->res->redirect("/solgs/model/combined/populations/$model_id/trait/$trait_id");
1654 $c->detach();
1656 elsif ($referer =~ /solgs\/trait\//)
1659 my ($trait_id, $pop_id) = $referer =~ m/(\d+)/g;
1660 if ($model_id =~ /uploaded/) {$pop_id = $model_id;}
1662 $c->stash->{data_set_type} = "single population";
1663 $c->stash->{pop_id} = $pop_id;
1664 $c->stash->{model_id} = $model_id;
1665 $c->stash->{training_pop_id} = $pop_id;
1666 $c->stash->{prediction_pop_id} = $prediction_pop_id;
1667 $c->stash->{trait_id} = $trait_id;
1669 $self->predict_selection_pop_single_pop_model($c);
1671 $self->trait_phenotype_stat($c);
1672 $self->gs_files($c);
1674 $c->res->redirect("/solgs/trait/$trait_id/population/$pop_id");
1675 $c->detach();
1678 elsif ($referer =~ /solgs\/models\/combined\/trials/)
1680 my ($model_id, $prediction_pop_id) = $path =~ m/(\d+)/g;
1682 $c->stash->{data_set_type} = "combined populations";
1683 # $c->stash->{pop_id} = $model_id;
1684 $c->stash->{model_id} = $model_id;
1685 $c->stash->{combo_pops_id} = $model_id;
1686 $c->stash->{prediction_pop_id} = $prediction_pop_id;
1688 $self->analyzed_traits($c);
1689 my @traits_ids = @{ $c->stash->{analyzed_traits_ids} };
1691 foreach my $trait_id (@traits_ids)
1693 $self->get_trait_details($c, $trait_id);
1694 my $trait_abbr = $c->stash->{trait_abbr};
1696 my $identifier = $model_id . '_' . $prediction_pop_id;
1697 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
1699 my $prediction_pop_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
1701 if (! -s $prediction_pop_gebvs_file)
1703 my $dir = $c->stash->{solgs_cache_dir};
1705 $self->cache_combined_pops_data($c);
1707 my $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
1708 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
1710 $c->stash->{pheno_file} = $combined_pops_pheno_file;
1711 $c->stash->{geno_file} = $combined_pops_geno_file;
1713 $c->stash->{prediction_pop_id} = $prediction_pop_id;
1714 $self->prediction_population_file($c, $prediction_pop_id);
1716 $self->get_rrblup_output($c);
1721 $c->res->redirect("/solgs/models/combined/trials/$model_id");
1722 $c->detach();
1724 else
1726 $c->res->redirect("/solgs/analyze/traits/population/$model_id/$prediction_pop_id");
1727 $c->detach();
1733 sub prediction_pop_gebvs_file {
1734 my ($self, $c, $identifier, $trait_id) = @_;
1736 my $cache_data = {key => 'prediction_pop_gebvs_' . $identifier . '_' . $trait_id,
1737 file => 'prediction_pop_gebvs_' . $identifier . '_' . $trait_id,
1738 stash_key => 'prediction_pop_gebvs_file'
1741 $self->cache_file($c, $cache_data);
1746 sub list_predicted_selection_pops {
1747 my ($self, $c, $model_id) = @_;
1749 my $dir = $c->stash->{solgs_cache_dir};
1751 opendir my $dh, $dir or die "can't open $dir: $!\n";
1753 my @files = grep { /prediction_pop_gebvs_${model_id}_/ && -f "$dir/$_" }
1754 readdir($dh);
1756 closedir $dh;
1758 my @pred_pops;
1760 foreach (@files)
1763 unless ($_ =~ /uploaded/) {
1764 my ($model_id2, $pred_pop_id, $trait_id) = $_ =~ m/\d+/g;
1766 push @pred_pops, $pred_pop_id;
1770 @pred_pops = uniq(@pred_pops);
1772 $c->stash->{list_of_predicted_selection_pops} = \@pred_pops;
1777 sub download_prediction_GEBVs :Path('/solgs/download/prediction/model') Args(4) {
1778 my ($self, $c, $pop_id, $prediction, $prediction_id, $trait_id) = @_;
1780 $self->get_trait_details($c, $trait_id);
1781 $c->stash->{pop_id} = $pop_id;
1783 my $identifier = $pop_id . "_" . $prediction_id;
1784 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
1785 my $prediction_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
1787 unless (!-e $prediction_gebvs_file || -s $prediction_gebvs_file == 0)
1789 my @prediction_gebvs = map { [ split(/\t/) ] } read_file($prediction_gebvs_file);
1791 $c->res->content_type("text/plain");
1792 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @prediction_gebvs);
1798 sub prediction_pop_analyzed_traits {
1799 my ($self, $c, $training_pop_id, $prediction_pop_id) = @_;
1801 my $dir = $c->stash->{solgs_cache_dir};
1802 my @pred_files;
1804 opendir my $dh, $dir or die "can't open $dir: $!\n";
1806 no warnings 'uninitialized';
1808 my $prediction_is_uploaded = $c->stash->{uploaded_prediction};
1810 $prediction_pop_id = "uploaded_${prediction_pop_id}" if $prediction_is_uploaded;
1812 if ($training_pop_id != $prediction_pop_id)
1814 my @files = grep { /prediction_pop_gebvs_${training_pop_id}_${prediction_pop_id}/ && -s "$dir/$_" > 0 }
1815 readdir($dh);
1817 closedir $dh;
1819 my @trait_ids;
1821 if ($files[0])
1823 my @copy_files = @files;
1825 @trait_ids = map { s/prediction_pop_gebvs_${training_pop_id}_${prediction_pop_id}_//g ? $_ : 0} @copy_files;
1827 my @traits = ();
1828 if(@trait_ids)
1830 foreach my $trait_id (@trait_ids)
1832 $trait_id =~ s/s+//g;
1833 $self->get_trait_details($c, $trait_id);
1834 push @traits, $c->stash->{trait_abbr};
1838 $c->stash->{prediction_pop_analyzed_traits} = \@traits;
1839 $c->stash->{prediction_pop_analyzed_traits_ids} = \@trait_ids;
1840 $c->stash->{prediction_pop_analyzed_traits_files} = \@files;
1847 sub download_prediction_urls {
1848 my ($self, $c, $training_pop_id, $prediction_pop_id) = @_;
1850 my $selection_traits_ids;
1851 my $selection_traits_files;
1852 my $download_url;# = $c->stash->{download_prediction};
1853 my $model_tr_id = $c->stash->{trait_id};
1856 my $page = $c->req->referer;
1857 my $base = $c->req->base;
1859 my $data_set_type = 'combined populations' if $page =~ /combined/;
1861 if ( $base !~ /localhost/)
1863 $base =~ s/:\d+//;
1864 $base =~ s/http\w?/https/;
1867 $page =~ s/$base//;
1869 no warnings 'uninitialized';
1871 if ($prediction_pop_id)
1873 $self->prediction_pop_analyzed_traits($c, $training_pop_id, $prediction_pop_id);
1875 $selection_traits_ids = $c->stash->{prediction_pop_analyzed_traits_ids};
1876 $selection_traits_files = $c->stash->{prediction_pop_analyzed_traits_files};
1880 if ($page =~ /solgs\/model\/combined\/populations\// )
1882 ($model_tr_id) = $page =~ /(\d+)$/;
1883 $model_tr_id =~ s/s+//g;
1886 if ($page =~ /solgs\/trait\// )
1888 $model_tr_id = (split '/', $page)[2];
1891 if ($page =~ /(\/uploaded\/prediction\/)/ && $page !~ /(\solgs\/traits\/all)/)
1893 ($model_tr_id) = $page =~ /(\d+)$/;
1894 $model_tr_id =~ s/s+//g;
1897 my ($trait_is_predicted) = grep {/$model_tr_id/ } @$selection_traits_ids;
1898 my @selection_traits_ids = uniq(@$selection_traits_ids);
1900 foreach my $trait_id (@selection_traits_ids)
1902 $trait_id =~ s/s+//g;
1903 $self->get_trait_details($c, $trait_id);
1905 my $trait_abbr = $c->stash->{trait_abbr};
1906 my $trait_name = $c->stash->{trait_name};
1908 if ($c->stash->{uploaded_prediction})
1910 unless ($prediction_pop_id =~ /uploaded/)
1912 $prediction_pop_id = 'uploaded_' . $prediction_pop_id;
1915 if ($page =~ /solgs\/traits\/all\/|solgs\/models\/combined\//)
1917 $model_tr_id = $trait_id;
1918 $download_url .= " | " if $download_url;
1921 if ($selection_traits_files->[0] =~ $prediction_pop_id && $trait_id == $model_tr_id)
1923 if ($data_set_type =~ /combined populations/)
1925 $download_url .= qq |<a href="/solgs/selection/$prediction_pop_id/model/combined/$training_pop_id/trait/$trait_id">$trait_abbr</a> |;
1927 else
1929 $download_url .= qq |<a href="/solgs/selection/$prediction_pop_id/model/$training_pop_id/trait/$trait_id">$trait_abbr</a> |;
1934 if ($download_url)
1936 $c->stash->{download_prediction} = $download_url;
1938 else
1940 $c->stash->{download_prediction} = qq | <a href ="/solgs/model/$training_pop_id/prediction/$prediction_pop_id" onclick="solGS.waitPage(this.href); return false;">[ Predict ]</a> |;
1942 $c->stash->{download_prediction} = '' if $c->stash->{uploaded_prediction};
1948 sub model_accuracy {
1949 my ($self, $c) = @_;
1950 my $file = $c->stash->{validation_file};
1951 my @report =();
1953 if ( !-e $file) { @report = (["Validation file doesn't exist.", "None"]);}
1954 if ( -s $file == 0) { @report = (["There is no cross-validation output report.", "None"]);}
1956 if (!@report)
1958 @report = map { [ split(/\t/, $_) ]} read_file($file);
1961 shift(@report); #add condition
1963 $c->stash->{accuracy_report} = \@report;
1968 sub model_parameters {
1969 my ($self, $c) = @_;
1971 $self->variance_components_file($c);
1972 my $file = $c->stash->{variance_components_file};
1974 my @params = map { [ split(/\t/, $_) ]} read_file($file);
1976 shift(@params); #add condition
1978 $c->stash->{model_parameters} = \@params;
1983 sub solgs_details_trait :Path('/solgs/details/trait/') Args(1) {
1984 my ($self, $c, $trait_id) = @_;
1986 $trait_id = $c->req->param('trait_id') if !$trait_id;
1988 my $ret->{status} = undef;
1990 if ($trait_id)
1992 $self->get_trait_details($c, $trait_id);
1993 $ret->{name} = $c->stash->{trait_name};
1994 $ret->{abbr} = $c->stash->{trait_abbr};
1995 $ret->{id} = $c->stash->{trait_id};
1996 $ret->{status} = 1;
1999 $ret = to_json($ret);
2001 $c->res->content_type('application/json');
2002 $c->res->body($ret);
2007 sub get_trait_details {
2008 my ($self, $c, $trait_id) = @_;
2010 $trait_id = $c->stash->{trait_id} if !$trait_id;
2012 my $trait_name = $c->model('solGS::solGS')->trait_name($trait_id);
2013 my $abbr = $self->abbreviate_term($trait_name);
2015 $c->stash->{trait_id} = $trait_id;
2016 $c->stash->{trait_name} = $trait_name;
2017 $c->stash->{trait_abbr} = $abbr;
2021 #creates and writes a list of GEBV files of
2022 #traits selected for ranking genotypes.
2023 sub get_gebv_files_of_traits {
2024 my ($self, $c) = @_;
2026 my $pop_id = $c->stash->{pop_id};
2027 $c->stash->{model_id} = $pop_id;
2028 my $pred_pop_id = $c->stash->{prediction_pop_id};
2030 my $dir = $c->stash->{solgs_cache_dir};
2032 my $gebv_files;
2033 my $valid_gebv_files;
2034 my $pred_gebv_files;
2036 if ($pred_pop_id && $pred_pop_id != $pop_id)
2038 $self->prediction_pop_analyzed_traits($c, $pop_id, $pred_pop_id);
2039 $pred_gebv_files = $c->stash->{prediction_pop_analyzed_traits_files};
2041 foreach (@$pred_gebv_files)
2043 my$gebv_file = catfile($dir, $_);
2044 $gebv_files .= $gebv_file;
2045 $gebv_files .= "\t" unless (@$pred_gebv_files[-1] eq $_);
2048 else
2050 $self->analyzed_traits($c);
2051 my @analyzed_traits_files = @{$c->stash->{analyzed_traits_files}};
2053 foreach my $tr_file (@analyzed_traits_files)
2055 $gebv_files .= $tr_file;
2056 $gebv_files .= "\t" unless ($analyzed_traits_files[-1] eq $tr_file);
2059 my @analyzed_valid_traits_files = @{$c->stash->{analyzed_valid_traits_files}};
2061 foreach my $tr_file (@analyzed_valid_traits_files)
2063 $valid_gebv_files .= $tr_file;
2064 $valid_gebv_files .= "\t" unless ($analyzed_valid_traits_files[-1] eq $tr_file);
2070 my $pred_file_suffix;
2071 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
2073 my $name = "gebv_files_of_traits_${pop_id}${pred_file_suffix}";
2074 my $file = $self->create_tempfile($c, $name);
2076 write_file($file, $gebv_files);
2078 $c->stash->{gebv_files_of_traits} = $file;
2080 my $name2 = "gebv_files_of_valid_traits_${pop_id}${pred_file_suffix}";
2081 my $file2 = $self->create_tempfile($c, $name2);
2083 write_file($file2, $valid_gebv_files);
2085 $c->stash->{gebv_files_of_valid_traits} = $file2;
2090 sub gebv_rel_weights {
2091 my ($self, $c, $params, $pred_pop_id) = @_;
2093 my $pop_id = $c->stash->{pop_id};
2095 my $rel_wts = "trait" . "\t" . 'relative_weight' . "\n";
2096 foreach my $tr (keys %$params)
2098 my $wt = $params->{$tr};
2099 unless ($tr eq 'rank')
2101 $rel_wts .= $tr . "\t" . $wt;
2102 $rel_wts .= "\n";
2106 my $pred_file_suffix;
2107 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
2109 my $name = "rel_weights_${pop_id}${pred_file_suffix}";
2110 my $file = $self->create_tempfile($c, $name);
2111 write_file($file, $rel_wts);
2113 $c->stash->{rel_weights_file} = $file;
2118 sub ranked_genotypes_file {
2119 my ($self, $c, $pred_pop_id) = @_;
2121 my $pop_id = $c->stash->{pop_id};
2123 my $pred_file_suffix;
2124 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
2126 my $name = "ranked_genotypes_${pop_id}${pred_file_suffix}";
2127 my $file = $self->create_tempfile($c, $name);
2128 $c->stash->{ranked_genotypes_file} = $file;
2133 sub selection_index_file {
2134 my ($self, $c, $pred_pop_id) = @_;
2136 my $pop_id = $c->stash->{pop_id};
2138 my $pred_file_suffix;
2139 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
2141 my $name = "selection_index_${pop_id}${pred_file_suffix}";
2142 my $file = $self->create_tempfile($c, $name);
2143 $c->stash->{selection_index_file} = $file;
2148 sub download_ranked_genotypes :Path('/solgs/download/ranked/genotypes/pop') Args(2) {
2149 my ($self, $c, $pop_id, $genotypes_file) = @_;
2151 $c->stash->{pop_id} = $pop_id;
2153 $genotypes_file = catfile($c->stash->{solgs_tempfiles_dir}, $genotypes_file);
2155 unless (!-e $genotypes_file || -s $genotypes_file == 0)
2157 my @ranks = map { [ split(/\t/) ] } read_file($genotypes_file);
2159 $c->res->content_type("text/plain");
2160 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @ranks);
2166 sub rank_genotypes : Private {
2167 my ($self, $c, $pred_pop_id) = @_;
2169 my $pop_id = $c->stash->{pop_id};
2170 $c->stash->{prediction_pop_id} = $pred_pop_id;
2172 my $input_files = join("\t",
2173 $c->stash->{rel_weights_file},
2174 $c->stash->{gebv_files_of_traits}
2177 $self->ranked_genotypes_file($c, $pred_pop_id);
2178 $self->selection_index_file($c, $pred_pop_id);
2180 my $output_files = join("\t",
2181 $c->stash->{ranked_genotypes_file},
2182 $c->stash->{selection_index_file}
2185 my $pred_file_suffix;
2186 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
2188 my $name = "output_rank_genotypes_${pop_id}${pred_file_suffix}";
2189 my $output_file = $self->create_tempfile($c, $name);
2190 write_file($output_file, $output_files);
2193 $name = "input_rank_genotypes_${pop_id}${pred_file_suffix}";
2194 my $input_file = $self->create_tempfile($c, $name);
2195 write_file($input_file, $input_files);
2197 $c->stash->{output_files} = $output_file;
2198 $c->stash->{input_files} = $input_file;
2199 $c->stash->{r_temp_file} = "rank-gebv-genotypes-${pop_id}${pred_file_suffix}";
2200 $c->stash->{r_script} = 'R/selection_index.r';
2202 $self->run_r_script($c);
2203 $self->download_urls($c);
2204 $self->get_top_10_selection_indices($c);
2208 sub get_top_10_selection_indices {
2209 my ($self, $c) = @_;
2211 my $si_file = $c->stash->{selection_index_file};
2213 my $si_data = $self->convert_to_arrayref_of_arrays($c, $si_file);
2214 my @top_genotypes = @$si_data[0..9];
2216 $c->stash->{top_10_selection_indices} = \@top_genotypes;
2220 sub convert_to_arrayref_of_arrays {
2221 my ($self, $c, $file) = @_;
2223 open my $fh, $file or die "couldnot open $file: $!";
2225 my @data;
2226 while (<$fh>)
2228 push @data, map { [ split(/\t/) ] } $_ if $_;
2231 if (@data)
2233 shift(@data);
2234 return \@data;
2235 } else
2237 return;
2242 sub trait_phenotype_file {
2243 my ($self, $c, $pop_id, $trait) = @_;
2245 my $dir = $c->stash->{solgs_cache_dir};
2246 my $exp = "phenotype_trait_${trait}_${pop_id}";
2247 my $file = $self->grep_file($dir, $exp);
2249 $c->stash->{trait_phenotype_file} = $file;
2254 sub check_selection_pops_list :Path('/solgs/check/selection/populations') Args(1) {
2255 my ($self, $c, $tr_pop_id) = @_;
2257 $c->stash->{training_pop_id} = $tr_pop_id;
2259 $self->list_of_prediction_pops_file($c, $tr_pop_id);
2260 my $pred_pops_file = $c->stash->{list_of_prediction_pops_file};
2262 my $ret->{result} = 0;
2264 if (-s $pred_pops_file)
2266 $self->list_of_prediction_pops($c, $tr_pop_id);
2267 $ret->{data} = $c->stash->{list_of_prediction_pops};
2270 $ret = to_json($ret);
2272 $c->res->content_type('application/json');
2273 $c->res->body($ret);
2278 sub check_genotype_data_population :Path('/solgs/check/genotype/data/population/') Args(1) {
2279 my ($self, $c, $pop_id) = @_;
2281 $c->stash->{pop_id} = $pop_id;
2282 $self->check_population_has_genotype($c);
2284 my $ret->{has_genotype} = $c->stash->{population_has_genotype};
2285 $ret = to_json($ret);
2287 $c->res->content_type('application/json');
2288 $c->res->body($ret);
2293 sub check_phenotype_data_population :Path('/solgs/check/phenotype/data/population/') Args(1) {
2294 my ($self, $c, $pop_id) = @_;
2296 $c->stash->{pop_id} = $pop_id;
2297 $self->check_population_has_phenotype($c);
2299 my $ret->{has_phenotype} = $c->stash->{population_has_phenotype};
2300 $ret = to_json($ret);
2302 $c->res->content_type('application/json');
2303 $c->res->body($ret);
2308 sub check_population_exists :Path('/solgs/check/population/exists/') Args(0) {
2309 my ($self, $c) = @_;
2311 my $name = $c->req->param('name');
2313 my $rs = $c->model("solGS::solGS")->project_details_by_name($name);
2315 my $pop_id;
2316 while (my $row = $rs->next) {
2317 $pop_id = $row->id;
2320 my $ret->{population_id} = $pop_id;
2321 $ret = to_json($ret);
2323 $c->res->content_type('application/json');
2324 $c->res->body($ret);
2329 sub check_training_population :Path('/solgs/check/training/population/') Args(1) {
2330 my ($self, $c, $pop_id) = @_;
2332 $c->stash->{pop_id} = $pop_id;
2334 $self->check_population_is_training_population($c);
2335 my $is_training_pop = $c->stash->{is_training_population};
2337 my $training_pop_data;
2338 if ($is_training_pop)
2340 my $pr_rs = $c->model('solGS::solGS')->project_details($pop_id);
2341 $self->projects_links($c, $pr_rs);
2342 $training_pop_data = $c->stash->{projects_pages};
2345 my $ret->{is_training_population} = $is_training_pop;
2346 $ret->{training_pop_data} = $training_pop_data;
2347 $ret = to_json($ret);
2349 $c->res->content_type('application/json');
2350 $c->res->body($ret);
2355 sub check_population_is_training_population {
2356 my ($self, $c) = @_;
2358 my $pr_id = $c->stash->{pop_id};
2359 my $is_gs = $c->model("solGS::solGS")->get_project_type($pr_id);
2361 my $has_phenotype;
2362 my $has_genotype;
2364 if ($is_gs !~ /genomic selection/)
2366 $self->check_population_has_phenotype($c);
2367 $has_phenotype = $c->stash->{population_has_phenotype};
2369 if ($has_phenotype)
2371 $self->check_population_has_genotype($c);
2372 $has_genotype = $c->stash->{population_has_genotype};
2376 if ($is_gs || ($has_phenotype && $has_genotype))
2378 $c->stash->{is_training_population} = 1;
2384 sub check_population_has_phenotype {
2385 my ($self, $c) = @_;
2387 my $pr_id = $c->stash->{pop_id};
2388 my $is_gs = $c->model("solGS::solGS")->get_project_type($pr_id);
2389 my $has_phenotype = 1 if $is_gs;
2391 if ($is_gs !~ /genomic selection/)
2393 my $cache_dir = $c->stash->{solgs_cache_dir};
2394 my $pheno_file = $self->grep_file($cache_dir, "phenotype_data_${pr_id}.txt");
2396 if (!-s $pheno_file)
2398 $has_phenotype = $c->model("solGS::solGS")->has_phenotype($pr_id);
2400 else
2402 $has_phenotype = 1;
2406 $c->stash->{population_has_phenotype} = $has_phenotype;
2411 sub check_population_has_genotype {
2412 my ($self, $c) = @_;
2414 my $pop_id = $c->stash->{pop_id};
2416 my $pop_prop = $c->model("solGS::solGS")->get_project_genotypeprop($pop_id);
2417 my $marker_cnt = $pop_prop->{'marker_count'};
2419 my $has_genotype;
2420 $has_genotype = 1 if $marker_cnt;
2422 unless ($marker_cnt)
2424 my $geno_file;
2425 if ($pop_id =~ /upload/)
2427 my $dir = $c->stash->{solgs_prediction_upload_dir};
2428 my $user_id = $c->user->id;
2429 my $file_name = "genotype_data_${user_id}_${pop_id}";
2430 $geno_file = $self->grep_file($dir, $file_name);
2432 else
2434 my $dir = $c->stash->{solgs_cache_dir};
2435 my $file_name = "genotype_data_${pop_id}";
2436 $geno_file = $self->grep_file($dir, $file_name);
2440 $has_genotype = 1 if -s $geno_file;
2441 unless ($has_genotype)
2443 my $markers = $c->model("solGS::solGS")->get_project_genotyping_markers($pop_id);
2445 if ($markers)
2447 $has_genotype = 1;
2448 $c->stash->{pop_id} = $pop_id;
2450 my @markers = split('\t', $markers);
2451 my $marker_count = scalar(@markers);
2452 $c->stash->{marker_count} = $marker_count;
2454 $self->store_project_marker_count($c);
2459 $c->stash->{population_has_genotype} = $has_genotype;
2464 sub check_selection_population_relevance :Path('/solgs/check/selection/population/relevance') Args() {
2465 my ($self, $c) = @_;
2467 my $data_set_type = $c->req->param('data_set_type');
2468 my $training_pop_id = $c->req->param('training_pop_id');
2469 my $selection_pop_name = $c->req->param('selection_pop_name');
2471 $c->stash->{data_set_type} = $data_set_type;
2473 my $pr_rs = $c->model("solGS::solGS")->project_details_by_exact_name($selection_pop_name);
2475 my $selection_pop_id;
2476 while (my $row = $pr_rs->next) {
2477 $selection_pop_id = $row->project_id;
2480 my $ret = {};
2482 if ($selection_pop_id !~ /$training_pop_id/)
2484 my $has_genotype;
2485 if ($selection_pop_id)
2487 $c->stash->{pop_id} = $selection_pop_id;
2488 $self->check_population_has_genotype($c);
2489 $has_genotype = $c->stash->{population_has_genotype};
2492 my $similarity;
2493 if ($has_genotype)
2495 $c->stash->{pop_id} = $selection_pop_id;
2496 $self->genotype_file($c);
2497 my $selection_pop_geno_file = $c->stash->{genotype_file};
2499 my $training_pop_geno_file;
2501 if ($training_pop_id =~ /upload/)
2503 my $dir = $c->stash->{solgs_prediction_upload_dir};
2504 my $user_id = $c->user->id;
2505 my $tr_geno_file = "genotype_data_${user_id}_${training_pop_id}";
2506 $training_pop_geno_file = $self->grep_file($dir, $tr_geno_file);
2508 else
2510 my $dir = $c->stash->{solgs_cache_dir};
2511 my $tr_geno_file = "genotype_data_${training_pop_id}";
2512 $training_pop_geno_file = $self->grep_file($dir, $tr_geno_file);
2515 $similarity = $self->compare_marker_set_similarity([$selection_pop_geno_file, $training_pop_geno_file]);
2518 my $selection_pop_data;
2519 if ($similarity >= 0.5 )
2521 $c->stash->{training_pop_id} = $training_pop_id;
2522 $self->format_selection_pops($c, [$selection_pop_id]);
2523 $selection_pop_data = $c->stash->{selection_pops_list};
2524 $self->save_selection_pops($c, [$selection_pop_id]);
2527 $ret->{selection_pop_data} = $selection_pop_data;
2528 $ret->{similarity} = $similarity;
2529 $ret->{has_genotype} = $has_genotype;
2530 $ret->{selection_pop_id} = $selection_pop_id;
2532 else
2534 $ret->{selection_pop_id} = $selection_pop_id;
2537 $ret = to_json($ret);
2539 $c->res->content_type('application/json');
2540 $c->res->body($ret);
2545 sub save_selection_pops {
2546 my ($self, $c, $selection_pop_id) = @_;
2548 my $training_pop_id = $c->stash->{training_pop_id};
2550 $self->list_of_prediction_pops_file($c, $training_pop_id);
2551 my $selection_pops_file = $c->stash->{list_of_prediction_pops_file};
2553 my @existing_pops_ids = split(/\n/, read_file($selection_pops_file));
2555 my @uniq_ids = unique(@existing_pops_ids, @$selection_pop_id);
2556 my $formatted_ids = join("\n", @uniq_ids);
2558 write_file($selection_pops_file, $formatted_ids);
2563 sub search_selection_pops :Path('/solgs/search/selection/populations/') {
2564 my ($self, $c, $tr_pop_id) = @_;
2566 $c->stash->{training_pop_id} = $tr_pop_id;
2568 $self->search_all_relevant_selection_pops($c, $tr_pop_id);
2569 my $selection_pops_list = $c->stash->{all_relevant_selection_pops};
2571 my $ret->{selection_pops_list} = 0;
2572 if ($selection_pops_list)
2574 $ret->{data} = $selection_pops_list;
2577 $ret = to_json($ret);
2579 $c->res->content_type('application/json');
2580 $c->res->body($ret);
2585 sub list_of_prediction_pops {
2586 my ($self, $c, $training_pop_id) = @_;
2588 $self->list_of_prediction_pops_file($c, $training_pop_id);
2589 my $pred_pops_file = $c->stash->{list_of_prediction_pops_file};
2591 my @pred_pops_ids = split(/\n/, read_file($pred_pops_file));
2593 $self->format_selection_pops($c, \@pred_pops_ids);
2595 $c->stash->{list_of_prediction_pops} = $c->stash->{selection_pops_list};
2600 sub search_all_relevant_selection_pops {
2601 my ($self, $c, $training_pop_id) = @_;
2603 my @pred_pops_ids = @{$c->model('solGS::solGS')->prediction_pops($training_pop_id)};
2605 $self->save_selection_pops($c, \@pred_pops_ids);
2607 $self->format_selection_pops($c, \@pred_pops_ids);
2609 $c->stash->{all_relevant_selection_pops} = $c->stash->{selection_pops_list};
2614 sub format_selection_pops {
2615 my ($self, $c, $pred_pops_ids) = @_;
2617 my $training_pop_id = $c->stash->{training_pop_id};
2619 my @pred_pops_ids = @{$pred_pops_ids};
2620 my @data;
2622 if (@pred_pops_ids) {
2624 foreach my $prediction_pop_id (@pred_pops_ids)
2626 my $pred_pop_rs = $c->model('solGS::solGS')->project_details($prediction_pop_id);
2627 my $pred_pop_link;
2629 while (my $row = $pred_pop_rs->next)
2631 my $name = $row->name;
2632 my $desc = $row->description;
2634 unless ($name =~ /test/ || $desc =~ /test/)
2636 my $id_pop_name->{id} = $prediction_pop_id;
2637 $id_pop_name->{name} = $name;
2638 $id_pop_name->{pop_type} = 'selection';
2639 $id_pop_name = to_json($id_pop_name);
2641 $pred_pop_link = qq | <a href="/solgs/model/$training_pop_id/prediction/$prediction_pop_id"
2642 onclick="solGS.waitPage(this.href); return false;"><input type="hidden" value=\'$id_pop_name\'>$name</data>
2643 </a>
2646 my $pr_yr_rs = $c->model('solGS::solGS')->project_year($prediction_pop_id);
2647 my $project_yr;
2649 while ( my $yr_r = $pr_yr_rs->next )
2651 $project_yr = $yr_r->value;
2654 $self->download_prediction_urls($c, $training_pop_id, $prediction_pop_id);
2655 my $download_prediction = $c->stash->{download_prediction};
2656 push @data, [$pred_pop_link, $desc, $project_yr, $download_prediction];
2662 $c->stash->{selection_pops_list} = \@data;
2667 sub list_of_prediction_pops_file {
2668 my ($self, $c, $training_pop_id)= @_;
2670 my $cache_data = {key => 'list_of_prediction_pops' . $training_pop_id,
2671 file => 'list_of_prediction_pops_' . $training_pop_id,
2672 stash_key => 'list_of_prediction_pops_file'
2675 $self->cache_file($c, $cache_data);
2680 sub prediction_population_file {
2681 my ($self, $c, $pred_pop_id) = @_;
2683 my $tmp_dir = $c->stash->{solgs_tempfiles_dir};
2685 my ($fh, $tempfile) = tempfile("prediction_population_${pred_pop_id}-XXXXX",
2686 DIR => $tmp_dir
2689 $c->stash->{prediction_pop_id} = $pred_pop_id;
2690 $self->genotype_file($c, $pred_pop_id);
2691 my $pred_pop_file = $c->stash->{pred_genotype_file};
2693 $fh->print($pred_pop_file);
2694 $fh->close;
2696 $c->stash->{prediction_population_file} = $tempfile;
2701 sub combined_pops_catalogue_file {
2702 my ($self, $c) = @_;
2704 my $cache_data = {key => 'combined_pops_catalogue_file',
2705 file => 'combined_pops_catalogue_file',
2706 stash_key => 'combined_pops_catalogue_file'
2709 $self->cache_file($c, $cache_data);
2714 sub catalogue_combined_pops {
2715 my ($self, $c, $entry) = @_;
2717 $self->combined_pops_catalogue_file($c);
2718 my $file = $c->stash->{combined_pops_catalogue_file};
2720 if (! -s $file)
2722 my $header = 'combo_pops_id' . "\t" . 'population_ids';
2723 write_file($file, ($header, $entry));
2725 else
2727 $entry =~ s/\n//;
2728 my @combo = ($entry);
2730 my (@entries) = map{ $_ =~ s/\n// ? $_ : undef } read_file($file);
2731 my @intersect = intersect(@combo, @entries);
2732 unless( @intersect )
2734 write_file($file, {append => 1}, "\n" . "$entry");
2741 sub get_combined_pops_list {
2742 my ($self, $c, $combined_pops_id) = @_;
2744 $self->combined_pops_catalogue_file($c);
2745 my $combo_pops_catalogue_file = $c->stash->{combined_pops_catalogue_file};
2747 my @combos = uniq(read_file($combo_pops_catalogue_file));
2749 foreach my $entry (@combos)
2751 if ($entry =~ m/$combined_pops_id/)
2753 chomp($entry);
2754 my ($combo_pops_id, $pops) = split(/\t/, $entry);
2755 my @pops_list = split(',', $pops);
2756 $c->stash->{combined_pops_list} = \@pops_list;
2757 $c->stash->{trait_combo_pops} = \@pops_list;
2764 sub get_trait_details_of_trait_abbr {
2765 my ($self, $c) = @_;
2767 my $trait_abbr = $c->stash->{trait_abbr};
2769 if (!$c->stash->{pop_id})
2771 $c->stash->{pop_id} = $c->stash->{training_pop_id} || $c->stash->{combo_pops_id};
2774 my $trait_id;
2776 my $acronym_pairs = $self->get_acronym_pairs($c);
2778 if ($acronym_pairs)
2780 foreach my $r (@$acronym_pairs)
2782 if ($r->[0] eq $trait_abbr)
2784 my $trait_name = $r->[1];
2785 $trait_name =~ s/^\s+|\s+$//g;
2787 $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
2788 $self->get_trait_details($c, $trait_id);
2796 sub build_multiple_traits_models {
2797 my ($self, $c) = @_;
2799 my $pop_id = $c->stash->{pop_id};
2800 my $prediction_id = $c->stash->{prediction_pop_id};
2802 my @selected_traits = $c->req->param('trait_id');
2804 if (!@selected_traits && $c->stash->{background_job})
2806 my $params = $c->stash->{analysis_profile};
2807 my $args = $params->{arguments};
2809 my $json = JSON->new();
2810 $args = $json->decode($args);
2812 if (keys %{$args})
2814 foreach my $k ( keys %{$args} )
2816 if ($k eq 'trait_id')
2818 @selected_traits = @{ $args->{$k} };
2821 if (!$pop_id)
2823 if ($k eq 'population_id')
2825 my @pop_ids = @{ $args->{$k} };
2826 $c->stash->{pop_id} = $pop_ids[0];
2830 if ($k eq 'selection_pop_id')
2832 $prediction_id = $args->{$k};
2838 if (!@selected_traits)
2840 if ($prediction_id)
2842 $c->stash->{model_id} = $pop_id;
2844 $self->traits_with_valid_models($c);
2845 @selected_traits = @ {$c->stash->{traits_with_valid_models}};
2847 else
2849 $c->res->redirect("/solgs/population/$pop_id/selecttraits");
2850 $c->detach();
2853 else
2855 my $single_trait_id;
2857 if (scalar(@selected_traits) == 1)
2859 $single_trait_id = $selected_traits[0];
2860 if ($single_trait_id =~ /\D/)
2862 $c->stash->{trait_abbr} = $single_trait_id;
2863 $self->get_trait_details_of_trait_abbr($c);
2864 $single_trait_id = $c->stash->{trait_id};
2867 if (!$prediction_id)
2869 $c->res->redirect("/solgs/trait/$single_trait_id/population/$pop_id");
2870 $c->detach();
2872 else
2874 my $name = "trait_info_${single_trait_id}_pop_${pop_id}";
2875 my $file2 = $self->create_tempfile($c, $name);
2877 $c->stash->{trait_file} = $file2;
2878 $c->stash->{trait_abbr} = $selected_traits[0];
2879 $self->get_trait_details_of_trait_abbr($c);
2881 $self->get_rrblup_output($c);
2884 else
2886 my ($traits, $trait_ids);
2888 for (my $i = 0; $i <= $#selected_traits; $i++)
2890 if ($selected_traits[$i] =~ /\D/)
2892 $c->stash->{trait_abbr} = $selected_traits[$i];
2893 $self->get_trait_details_of_trait_abbr($c);
2894 $traits .= $c->stash->{trait_abbr};
2895 $traits .= "\t" unless ($i == $#selected_traits);
2896 $trait_ids .= $c->stash->{trait_id};
2898 else
2900 my $tr = $c->model('solGS::solGS')->trait_name($selected_traits[$i]);
2901 my $abbr = $self->abbreviate_term($tr);
2902 $traits .= $abbr;
2903 $traits .= "\t" unless ($i == $#selected_traits);
2906 foreach my $tr_id (@selected_traits)
2908 $trait_ids .= $tr_id;
2913 if ($c->stash->{data_set_type} =~ /combined populations/)
2915 my $identifier = crc($trait_ids);
2916 $self->combined_gebvs_file($c, $identifier);
2919 my $name = "selected_traits_pop_${pop_id}";
2920 my $file = $self->create_tempfile($c, $name);
2922 write_file($file, $traits);
2923 $c->stash->{selected_traits_file} = $file;
2925 $name = "trait_info_${single_trait_id}_pop_${pop_id}";
2926 my $file2 = $self->create_tempfile($c, $name);
2928 $c->stash->{trait_file} = $file2;
2929 $self->get_rrblup_output($c);
2936 sub traits_to_analyze :Regex('^solgs/analyze/traits/population/([\w|\d]+)(?:/([\d+]+))?') {
2937 my ($self, $c) = @_;
2939 my ($pop_id, $prediction_id) = @{$c->req->captures};
2941 $c->stash->{pop_id} = $pop_id;
2942 $c->stash->{prediction_pop_id} = $prediction_id;
2944 $self->build_multiple_traits_models($c);
2946 my $referer = $c->req->referer;
2947 my $base = $c->req->base;
2948 $referer =~ s/$base//;
2949 my ($tr_id) = $referer =~ /(\d+)/;
2950 my $trait_page = "solgs/trait/$tr_id/population/$pop_id";
2952 my $error = $c->stash->{script_error};
2954 if ($error)
2956 $c->stash->{message} = "$error can't create prediction models for the selected traits.
2957 There are problems with the datasets of the traits.
2958 <p><a href=\"/solgs/population/$pop_id\">[ Go back ]</a></p>";
2960 $c->stash->{template} = "/generic_message.mas";
2962 else
2964 if ($referer =~ m/$trait_page/)
2966 $c->res->redirect("/solgs/trait/$tr_id/population/$pop_id");
2967 $c->detach();
2969 else
2971 $c->res->redirect("/solgs/traits/all/population/$pop_id/$prediction_id");
2972 $c->detach();
2979 sub all_traits_output :Regex('^solgs/traits/all/population/([\w|\d]+)(?:/([\d+]+))?') {
2980 my ($self, $c) = @_;
2982 my ($pop_id, $pred_pop_id) = @{$c->req->captures};
2984 my @traits = $c->req->param;
2985 @traits = grep {$_ ne 'rank'} @traits;
2986 $c->stash->{training_pop_id} = $pop_id;
2987 $c->stash->{pop_id} = $pop_id;
2989 if ($pred_pop_id)
2991 $c->stash->{prediction_pop_id} = $pred_pop_id;
2992 $c->stash->{population_is} = 'prediction population';
2993 $self->prediction_population_file($c, $pred_pop_id);
2995 my $pr_rs = $c->model('solGS::solGS')->project_details($pred_pop_id);
2997 while (my $row = $pr_rs->next)
2999 $c->stash->{prediction_pop_name} = $row->name;
3002 else
3004 $c->stash->{prediction_pop_id} = undef;
3005 $c->stash->{population_is} = 'training population';
3008 $c->stash->{model_id} = $pop_id;
3009 $self->analyzed_traits($c);
3011 my @analyzed_traits = @{$c->stash->{analyzed_traits}};
3013 if (!@analyzed_traits)
3015 $c->res->redirect("/solgs/population/$pop_id/selecttraits/");
3016 $c->detach();
3019 my @trait_pages;
3020 foreach my $tr (@analyzed_traits)
3022 my $acronym_pairs = $self->get_acronym_pairs($c);
3023 my $trait_name;
3024 if ($acronym_pairs)
3026 foreach my $r (@$acronym_pairs)
3028 if ($r->[0] eq $tr)
3030 $trait_name = $r->[1];
3031 $trait_name =~ s/\n//g;
3032 $c->stash->{trait_name} = $trait_name;
3033 $c->stash->{trait_abbr} = $r->[0];
3038 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
3039 my $trait_abbr = $c->stash->{trait_abbr};
3041 $self->get_model_accuracy_value($c, $pop_id, $trait_abbr);
3042 my $accuracy_value = $c->stash->{accuracy_value};
3044 $c->controller("solGS::Heritability")->get_heritability($c);
3045 my $heritability = $c->stash->{heritability};
3047 push @trait_pages, [ qq | <a href="/solgs/trait/$trait_id/population/$pop_id">$trait_abbr</a>|, $accuracy_value, $heritability];
3051 $self->project_description($c, $pop_id);
3052 my $project_name = $c->stash->{project_name};
3053 my $project_desc = $c->stash->{project_desc};
3055 my @model_desc = ([qq | <a href="/solgs/population/$pop_id">$project_name</a> |, $project_desc, \@trait_pages]);
3057 $c->stash->{template} = $self->template('/population/multiple_traits_output.mas');
3058 $c->stash->{trait_pages} = \@trait_pages;
3059 $c->stash->{model_data} = \@model_desc;
3061 my $acronym = $self->get_acronym_pairs($c);
3062 $c->stash->{acronym} = $acronym;
3067 sub selection_index_form :Path('/solgs/selection/index/form') Args(0) {
3068 my ($self, $c) = @_;
3070 my $pred_pop_id = $c->req->param('pred_pop_id');
3071 my $training_pop_id = $c->req->param('training_pop_id');
3073 $c->stash->{model_id} = $training_pop_id;
3074 $c->stash->{prediction_pop_id} = $pred_pop_id;
3076 my @traits;
3077 if (!$pred_pop_id)
3079 $self->analyzed_traits($c);
3080 @traits = @{ $c->stash->{selection_index_traits} };
3082 else
3084 $self->prediction_pop_analyzed_traits($c, $training_pop_id, $pred_pop_id);
3085 @traits = @{ $c->stash->{prediction_pop_analyzed_traits} };
3088 my $ret->{status} = 'success';
3089 $ret->{traits} = \@traits;
3091 $ret = to_json($ret);
3093 $c->res->content_type('application/json');
3094 $c->res->body($ret);
3099 sub traits_with_valid_models {
3100 my ($self, $c) = @_;
3102 my $pop_id = $c->stash->{pop_id} || $c->stash->{training_pop_id};
3104 $self->analyzed_traits($c);
3106 my @analyzed_traits = @{$c->stash->{analyzed_traits}};
3107 my @filtered_analyzed_traits;
3109 foreach my $analyzed_trait (@analyzed_traits)
3111 $self->get_model_accuracy_value($c, $pop_id, $analyzed_trait);
3112 my $accuracy_value = $c->stash->{accuracy_value};
3113 if ($accuracy_value > 0)
3115 push @filtered_analyzed_traits, $analyzed_trait;
3119 @filtered_analyzed_traits = uniq(@filtered_analyzed_traits);
3120 $c->stash->{traits_with_valid_models} = \@filtered_analyzed_traits;
3125 sub calculate_selection_index :Path('/solgs/calculate/selection/index') Args(2) {
3126 my ($self, $c, $model_id, $pred_pop_id) = @_;
3128 $c->stash->{pop_id} = $model_id;
3130 if ($pred_pop_id =~ /\d+/ && $model_id != $pred_pop_id)
3132 $c->stash->{prediction_pop_id} = $pred_pop_id;
3134 else
3136 $pred_pop_id = undef;
3137 $c->stash->{prediction_pop_id} = $pred_pop_id;
3140 my @traits = $c->req->param;
3141 @traits = grep {$_ ne 'rank'} @traits;
3143 my @values;
3144 foreach (@traits)
3146 push @values, $c->req->param($_);
3149 if (@values)
3151 $self->get_gebv_files_of_traits($c);
3153 my $params = $c->req->params;
3154 $self->gebv_rel_weights($c, $params, $pred_pop_id);
3156 $c->forward('rank_genotypes', [$pred_pop_id]);
3158 my $geno = $self->tohtml_genotypes($c);
3160 my $link = $c->stash->{ranked_genotypes_download_url};
3161 my $ranked_genos = $c->stash->{top_10_selection_indices};
3162 my $index_file = $c->stash->{selection_index_file};
3164 my $ret->{status} = 'No GEBV values to rank.';
3166 if (@$ranked_genos)
3168 $ret->{status} = 'success';
3169 $ret->{genotypes} = $geno;
3170 $ret->{link} = $link;
3171 $ret->{index_file} = $index_file;
3174 $ret = to_json($ret);
3176 $c->res->content_type('application/json');
3177 $c->res->body($ret);
3182 sub combine_populations_confrim :Path('/solgs/combine/populations/trait/confirm') Args(1) {
3183 my ($self, $c, $trait_id) = @_;
3185 my (@pop_ids, $ids);
3187 if ($trait_id =~ /\d+/)
3189 $ids = $c->req->param('confirm_populations');
3190 @pop_ids = split(/,/, $ids);
3191 if (!@pop_ids) {@pop_ids = $ids;}
3193 $c->stash->{trait_id} = $trait_id;
3196 my $pop_links;
3197 my @selected_pops_details;
3199 foreach my $pop_id (@pop_ids)
3201 my $markers = $c->model("solGS::solGS")->get_project_genotyping_markers($pop_id);
3202 my @markers = split(/\t/, $markers);
3203 my $markers_num = scalar(@markers);
3205 $self->trial_compatibility_table($c, $markers_num);
3206 my $match_code = $c->stash->{trial_compatibility_code};
3208 my $pop_rs = $c->model('solGS::solGS')->project_details($pop_id);
3210 $self->get_projects_details($c, $pop_rs);
3211 #my $pop_details = $self->get_projects_details($c, $pop_rs);
3212 my $pop_details = $c->stash->{projects_details};
3213 my $pop_name = $pop_details->{$pop_id}{project_name};
3214 my $pop_desc = $pop_details->{$pop_id}{project_desc};
3215 my $pop_year = $pop_details->{$pop_id}{project_year};
3216 my $pop_location = $pop_details->{$pop_id}{project_location};
3218 my $checkbox = qq |<form> <input style="background-color: $match_code;" type="checkbox" checked="checked" name="project" value="$pop_id" /> </form> |;
3220 $match_code = qq | <div class=trial_code style="color: $match_code; background-color: $match_code; height: 100%; width:100%">code</div> |;
3221 push @selected_pops_details, [$checkbox, qq|<a href="/solgs/trait/$trait_id/population/$pop_id" onclick="solGS.waitPage()">$pop_name</a>|,
3222 $pop_desc, $pop_location, $pop_year, $match_code
3227 $c->stash->{selected_pops_details} = \@selected_pops_details;
3228 $c->stash->{template} = $self->template('/search/result/confirm/populations.mas');
3233 sub combine_populations :Path('/solgs/combine/populations/trait') Args(1) {
3234 my ($self, $c, $trait_id) = @_;
3236 my (@pop_ids, $ids);
3238 if ($trait_id =~ /\d+/)
3240 $ids = $c->req->param($trait_id);
3241 @pop_ids = split(/,/, $ids);
3243 $self->get_trait_details($c, $trait_id);
3246 my $combo_pops_id;
3247 my $ret->{status} = 0;
3249 if (scalar(@pop_ids) > 1 )
3251 $combo_pops_id = crc(join('', @pop_ids));
3252 $c->stash->{combo_pops_id} = $combo_pops_id;
3253 $c->stash->{trait_combo_pops} = $ids;
3255 $c->stash->{trait_combine_populations} = \@pop_ids;
3257 $self->multi_pops_phenotype_data($c, \@pop_ids);
3258 $self->multi_pops_genotype_data($c, \@pop_ids);
3259 $self->multi_pops_geno_files($c, \@pop_ids);
3260 $self->multi_pops_pheno_files($c, \@pop_ids);
3262 my $geno_files = $c->stash->{multi_pops_geno_files};
3263 my @g_files = split(/\t/, $geno_files);
3265 $self->compare_genotyping_platforms($c, \@g_files);
3266 my $not_matching_pops = $c->stash->{pops_with_no_genotype_match};
3268 if (!$not_matching_pops)
3270 $self->cache_combined_pops_data($c);
3272 my $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
3273 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
3275 unless (-s $combined_pops_geno_file && -s $combined_pops_pheno_file )
3277 $self->r_combine_populations($c);
3279 $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
3280 $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
3283 if (-s $combined_pops_pheno_file > 1 && -s $combined_pops_geno_file > 1)
3285 my $tr_abbr = $c->stash->{trait_abbr};
3286 $c->stash->{data_set_type} = 'combined populations';
3287 $self->get_rrblup_output($c);
3288 my $analysis_result = $c->stash->{combo_pops_analysis_result};
3290 $ret->{pop_ids} = $ids;
3291 $ret->{combo_pops_id} = $combo_pops_id;
3292 $ret->{status} = $analysis_result;
3294 my $entry = "\n" . $combo_pops_id . "\t" . $ids;
3295 $self->catalogue_combined_pops($c, $entry);
3298 else
3300 $ret->{not_matching_pops} = $not_matching_pops;
3303 else
3305 my $pop_id = $pop_ids[0];
3306 $ret->{redirect_url} = "/solgs/trait/$trait_id/population/$pop_id";
3309 $ret = to_json($ret);
3311 $c->res->content_type('application/json');
3312 $c->res->body($ret);
3317 sub display_combined_pops_result :Path('/solgs/model/combined/populations/') Args(3){
3318 my ($self, $c, $combo_pops_id, $trait_key, $trait_id,) = @_;
3320 $c->stash->{data_set_type} = 'combined populations';
3321 $c->stash->{combo_pops_id} = $combo_pops_id;
3323 my $pops_cvs = $c->req->param('combined_populations');
3325 if ($pops_cvs)
3327 my @pops = split(',', $pops_cvs);
3328 $c->stash->{trait_combo_pops} = \@pops;
3330 else
3332 $self->get_combined_pops_list($c, $combo_pops_id);
3333 #$pops_ids = $c->stash->{combined_pops_list};
3334 $c->stash->{trait_combo_pops} = $c->stash->{combined_pops_list};
3337 $self->get_trait_details($c, $trait_id);
3338 $self->trait_phenotype_stat($c);
3339 $self->validation_file($c);
3340 $self->model_accuracy($c);
3341 $self->gebv_kinship_file($c);
3342 $self->blups_file($c);
3343 $self->download_urls($c);
3344 $self->gebv_marker_file($c);
3345 $self->top_markers($c);
3346 $self->combined_pops_summary($c);
3347 $self->model_parameters($c);
3349 $c->stash->{template} = $self->template('/model/combined/populations/trait.mas');
3353 sub get_model_accuracy_value {
3354 my ($self, $c, $model_id, $trait_abbr) = @_;
3356 my $dir = $c->stash->{solgs_cache_dir};
3357 opendir my $dh, $dir or die "can't open $dir: $!\n";
3359 my ($validation_file) = grep { /cross_validation_${trait_abbr}_${model_id}/ && -f "$dir/$_" }
3360 readdir($dh);
3362 closedir $dh;
3364 $validation_file = catfile($dir, $validation_file);
3366 my ($row) = grep {/Average/} read_file($validation_file);
3367 my ($text, $accuracy_value) = split(/\t/, $row);
3369 $c->stash->{accuracy_value} = $accuracy_value;
3374 sub get_project_owners {
3375 my ($self, $c, $pr_id) = @_;
3377 my $owners = $c->model("solGS::solGS")->get_stock_owners($pr_id);
3378 my $owners_names;
3380 if ($owners)
3382 for (my $i=0; $i < scalar(@$owners); $i++)
3384 my $owner_name = $owners->[$i]->{'first_name'} . "\t" . $owners->[$i]->{'last_name'} if $owners->[$i];
3386 unless (!$owner_name)
3388 $owners_names .= $owners_names ? ', ' . $owner_name : $owner_name;
3393 $c->stash->{project_owners} = $owners_names;
3397 sub combined_pops_summary {
3398 my ($self, $c) = @_;
3400 my $combo_pops_id = $c->stash->{combo_pops_id};
3402 $self->get_combined_pops_list($c, $combo_pops_id);
3403 my @pops_ids = @{$c->stash->{trait_combo_pops}};
3405 my $desc = 'This training population is a combination of ';
3406 my $projects_owners;
3408 foreach my $pop_id (@pops_ids)
3410 my $pr_rs = $c->model('solGS::solGS')->project_details($pop_id);
3412 while (my $row = $pr_rs->next)
3415 my $pr_id = $row->id;
3416 my $pr_name = $row->name;
3417 $desc .= qq | <a href="/solgs/population/$pr_id">$pr_name </a>|;
3418 $desc .= $pop_id == $pops_ids[-1] ? '.' : ' and ';
3421 $self->get_project_owners($c, $_);
3422 my $project_owners = $c->stash->{project_owners};
3424 unless (!$project_owners)
3426 $projects_owners.= $projects_owners ? ', ' . $project_owners : $project_owners;
3430 my $trait_abbr = $c->stash->{trait_abbr};
3431 my $trait_id = $c->stash->{trait_id};
3433 my $dir = $c->{stash}->{solgs_cache_dir};
3435 my $geno_exp = "genotype_data_${combo_pops_id}_${trait_abbr}_combined";
3436 my $geno_file = $self->grep_file($dir, $geno_exp);
3438 my @geno_lines = read_file($geno_file);
3439 my $markers_no = scalar(split ('\t', $geno_lines[0])) - 1;
3441 my $pheno_exp = "phenotype_trait_${trait_abbr}_${combo_pops_id}_combined";
3442 my $trait_pheno_file = $self->grep_file($dir, $pheno_exp);
3444 my @trait_pheno_lines = read_file($trait_pheno_file);
3445 my $stocks_no = scalar(@trait_pheno_lines) - 1;
3447 my $training_pop = "Training population $combo_pops_id";
3449 my $protocol = $c->config->{default_genotyping_protocol};
3450 $protocol = 'N/A' if !$protocol;
3452 $c->stash(markers_no => $markers_no,
3453 stocks_no => $stocks_no,
3454 project_desc => $desc,
3455 project_name => $training_pop,
3456 owner => $projects_owners,
3457 protocol => $protocol,
3463 sub compare_marker_set_similarity {
3464 my ($self, $marker_file_pair) = @_;
3466 my $first_markers = (read_file($marker_file_pair->[0]))[0];
3467 my $sec_markers = (read_file($marker_file_pair->[1]))[0];
3469 my @first_geno_markers = split(/\t/, $first_markers);
3470 my @sec_geno_markers = split(/\t/, $sec_markers);
3472 if ( @first_geno_markers && @first_geno_markers)
3474 my $common_markers = scalar(intersect(@first_geno_markers, @sec_geno_markers));
3475 my $similarity = $common_markers / scalar(@first_geno_markers);
3477 return $similarity;
3479 else
3481 return 0;
3487 sub compare_genotyping_platforms {
3488 my ($self, $c, $g_files) = @_;
3490 my $combinations = combinations($g_files, 2);
3491 my $combo_cnt = combinations($g_files, 2);
3493 my $not_matching_pops;
3494 my $cnt = 0;
3495 my $cnt_pairs = 0;
3497 while ($combo_cnt->next)
3499 $cnt_pairs++;
3502 while (my $pair = $combinations->next)
3504 $cnt++;
3505 my $similarity = $self->compare_marker_set_similarity($pair);
3507 unless ($similarity > 0.5 )
3509 no warnings 'uninitialized';
3510 my $pop_id_1 = fileparse($pair->[0]);
3511 my $pop_id_2 = fileparse($pair->[1]);
3513 map { s/genotype_data_|\.txt//g } $pop_id_1, $pop_id_2;
3515 my $list_type_pop = $c->stash->{uploaded_prediction};
3517 unless ($list_type_pop)
3519 my @pop_names;
3520 foreach ($pop_id_1, $pop_id_2)
3522 my $pr_rs = $c->model('solGS::solGS')->project_details($_);
3524 while (my $row = $pr_rs->next)
3526 push @pop_names, $row->name;
3530 $not_matching_pops .= '[ ' . $pop_names[0]. ' and ' . $pop_names[1] . ' ]';
3531 $not_matching_pops .= ', ' if $cnt != $cnt_pairs;
3533 # else
3534 # {
3535 # $not_matching_pops = 'not_matching';
3540 $c->stash->{pops_with_no_genotype_match} = $not_matching_pops;
3546 sub submit_cluster_compare_trials_markers {
3547 my ($self, $c, $geno_files) = @_;
3549 $c->stash->{r_temp_file} = 'compare-trials-markers';
3550 $self->create_cluster_acccesible_tmp_files($c);
3551 my $out_temp_file = $c->stash->{out_file_temp};
3552 my $err_temp_file = $c->stash->{err_file_temp};
3554 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
3555 my $background_job = $c->stash->{background_job};
3557 my $status;
3561 # if ($dependency && $background_job)
3563 # my $dependent_job_script = $self->create_tempfile($c, "compare_trials_job", "pl");
3565 # my $cmd = '#!/usr/bin/env perl;' . "\n";
3566 # $cmd .= 'use strict;' . "\n";
3567 # $cmd .= 'use warnings;' . "\n\n\n";
3568 # $cmd .= 'system("Rscript --slave '
3569 # . $in_file_temp
3570 # . ' --args ' . $input_files . ' ' . $output_files
3571 # . ' | qsub -W ' . $dependency . '");';
3573 # write_file($dependent_job_script, $cmd);
3574 # chmod 0755, $dependent_job_script;
3576 # $r_job = CXGN::Tools::Run->run_cluster('perl',
3577 # $dependent_job_script,
3578 # $out_file_temp,
3580 # working_dir => $c->stash->{solgs_tempfiles_dir},
3581 # max_cluster_jobs => 1_000_000_000,
3582 # },
3583 # );
3584 # }
3587 try
3589 my $compare_trials_job = CXGN::Tools::Run->run_cluster_perl({
3591 method => ["SGN::Controller::solGS::solGS" => "compare_genotyping_platforms"],
3592 args => ['SGN::Context', $geno_files],
3593 load_packages => ['SGN::Controller::solGS::solGS', 'SGN::Context'],
3594 run_opts => {
3595 out_file => $out_temp_file,
3596 err_file => $err_temp_file,
3597 working_dir => $temp_dir,
3598 max_cluster_jobs => 1_000_000_000,
3603 $c->stash->{r_job_tempdir} = $compare_trials_job->tempdir();
3604 $c->stash->{r_job_id} = $compare_trials_job->job_id();
3605 $c->stash->{cluster_job} = $compare_trials_job;
3607 unless ($background_job)
3609 $compare_trials_job->wait();
3613 catch
3615 $status = $_;
3616 $status =~ s/\n at .+//s;
3622 sub cache_combined_pops_data {
3623 my ($self, $c) = @_;
3625 my $trait_id = $c->stash->{trait_id};
3626 my $trait_abbr = $c->stash->{trait_abbr};
3627 my $combo_pops_id = $c->stash->{combo_pops_id};
3629 my $cache_pheno_data = {key => "phenotype_data_trait_${trait_id}_${combo_pops_id}_combined",
3630 file => "phenotype_data_${combo_pops_id}_${trait_abbr}_combined",
3631 stash_key => 'trait_combined_pheno_file'
3634 my $cache_geno_data = {key => "genotype_data_trait_${trait_abbr}_${combo_pops_id}_combined",
3635 file => "genotype_data_${combo_pops_id}_${trait_abbr}_combined",
3636 stash_key => 'trait_combined_geno_file'
3640 $self->cache_file($c, $cache_pheno_data);
3641 $self->cache_file($c, $cache_geno_data);
3646 sub multi_pops_pheno_files {
3647 my ($self, $c, $pop_ids) = @_;
3649 my $trait_id = $c->stash->{trait_id};
3650 my $dir = $c->stash->{solgs_cache_dir};
3651 my $files;
3653 if (defined reftype($pop_ids) && reftype($pop_ids) eq 'ARRAY')
3655 foreach my $pop_id (@$pop_ids)
3657 my $exp = 'phenotype_data_' . $pop_id . '.txt';
3658 $files .= catfile($dir, $exp);
3659 $files .= "\t" unless (@$pop_ids[-1] eq $pop_id);
3662 $c->stash->{multi_pops_pheno_files} = $files;
3665 else
3667 my $exp = 'phenotype_data_' . ${pop_ids} . '.txt';
3668 $files = catfile($dir, $exp);
3671 if ($trait_id)
3673 my $name = "trait_${trait_id}_multi_pheno_files";
3674 my $tempfile = $self->create_tempfile($c, $name);
3675 write_file($tempfile, $files);
3681 sub multi_pops_geno_files {
3682 my ($self, $c, $pop_ids) = @_;
3684 my $trait_id = $c->stash->{trait_id};
3685 my $dir = $c->stash->{solgs_cache_dir};
3686 my $files;
3688 if (defined reftype($pop_ids) && reftype($pop_ids) eq 'ARRAY')
3690 foreach my $pop_id (@$pop_ids)
3692 my $exp = 'genotype_data_' . $pop_id . '.txt';
3693 $files .= catfile($dir, $exp);
3694 $files .= "\t" unless (@$pop_ids[-1] eq $pop_id);
3696 $c->stash->{multi_pops_geno_files} = $files;
3698 else
3700 my $exp = 'genotype_data_' . ${pop_ids} . '.txt';
3701 $files = catfile($dir, $exp);
3704 if ($trait_id)
3706 my $name = "trait_${trait_id}_multi_geno_files";
3707 my $tempfile = $self->create_tempfile($c, $name);
3708 write_file($tempfile, $files);
3714 sub create_tempfile {
3715 my ($self, $c, $name, $ext) = @_;
3717 $ext = '.' . $ext if $ext;
3719 my ($fh, $file) = tempfile($name . "-XXXXX",
3720 SUFFIX => $ext,
3721 DIR => $c->stash->{solgs_tempfiles_dir}
3724 $fh->close;
3726 return $file;
3731 sub grep_file {
3732 my ($self, $dir, $exp) = @_;
3734 opendir my $dh, $dir
3735 or die "can't open $dir: $!\n";
3737 my ($file) = grep { /$exp/ && -f "$dir/$_" } readdir($dh);
3738 close $dh;
3740 if ($file)
3742 $file = catfile($dir, $file);
3745 return $file;
3749 sub multi_pops_phenotype_data {
3750 my ($self, $c, $pop_ids) = @_;
3752 no warnings 'uninitialized';
3753 my @job_ids;
3754 if (@$pop_ids)
3756 foreach my $pop_id (@$pop_ids)
3758 $c->stash->{pop_id} = $pop_id;
3759 $self->phenotype_file($c);
3760 push @job_ids, $c->stash->{r_job_id};
3763 if (@job_ids)
3765 @job_ids = uniq(@job_ids);
3766 $c->stash->{multi_pops_pheno_jobs_ids} = \@job_ids;
3771 # $self->multi_pops_pheno_files($c, $pop_ids);
3776 sub multi_pops_genotype_data {
3777 my ($self, $c, $pop_ids) = @_;
3779 no warnings 'uninitialized';
3780 my @job_ids;
3781 if (@$pop_ids)
3783 foreach my $pop_id (@$pop_ids)
3785 $c->stash->{pop_id} = $pop_id;
3786 $self->genotype_file($c);
3787 push @job_ids, $c->stash->{r_job_id};
3790 if (@job_ids)
3792 @job_ids = uniq(@job_ids);
3793 $c->stash->{multi_pops_geno_jobs_ids} = \@job_ids;
3796 # $self->multi_pops_geno_files($c, $pop_ids);
3801 sub phenotype_graph :Path('/solgs/phenotype/graph') Args(0) {
3802 my ($self, $c) = @_;
3804 my $pop_id = $c->req->param('pop_id');
3805 my $trait_id = $c->req->param('trait_id');
3806 my $combo_pops_id = $c->req->param('combo_pops_id');
3808 $self->get_trait_details($c, $trait_id);
3810 $c->stash->{pop_id} = $pop_id;
3811 $c->stash->{combo_pops_id} = $combo_pops_id;
3813 $c->stash->{data_set_type} = 'combined populations' if $combo_pops_id;
3815 $self->trait_phenodata_file($c);
3817 my $trait_pheno_file = $c->{stash}->{trait_phenodata_file};
3818 my $trait_data = $self->convert_to_arrayref_of_arrays($c, $trait_pheno_file);
3820 my $ret->{status} = 'failed';
3822 if (@$trait_data)
3824 $ret->{status} = 'success';
3825 $ret->{trait_data} = $trait_data;
3828 $ret = to_json($ret);
3830 $c->res->content_type('application/json');
3831 $c->res->body($ret);
3836 #generates descriptive stat for a trait phenotype data
3837 sub trait_phenotype_stat {
3838 my ($self, $c) = @_;
3840 $self->trait_phenodata_file($c);
3842 my $trait_pheno_file = $c->{stash}->{trait_phenodata_file};
3844 my $trait_data = $self->convert_to_arrayref_of_arrays($c, $trait_pheno_file);
3846 my @desc_stat;
3847 my $background_job = $c->stash->{background_job};
3849 if ($trait_data && !$background_job)
3851 my @pheno_data;
3852 foreach (@$trait_data)
3854 unless (!$_->[0])
3856 my $d = $_->[1];
3857 chomp($d);
3859 if ($d =~ /\d+/)
3861 push @pheno_data, $d;
3866 my $stat = Statistics::Descriptive::Full->new();
3867 $stat->add_data(@pheno_data);
3869 my $min = $stat->min;
3870 my $max = $stat->max;
3871 my $mean = $stat->mean;
3872 my $med = $stat->median;
3873 my $std = $stat->standard_deviation;
3874 my $cnt = scalar(@$trait_data);
3875 my $cv = ($std / $mean) * 100;
3876 my $na = scalar(@$trait_data) - scalar(@pheno_data);
3878 if ($na == 0) { $na = '--'; }
3880 my $round = Math::Round::Var->new(0.01);
3881 $std = $round->round($std);
3882 $mean = $round->round($mean);
3883 $cv = $round->round($cv);
3884 $cv = $cv . '%';
3886 @desc_stat = ( [ 'Total no. of genotypes', $cnt ],
3887 [ 'Genotypes missing data', $na ],
3888 [ 'Minimum', $min ],
3889 [ 'Maximum', $max ],
3890 [ 'Arithmetic mean', $mean ],
3891 [ 'Median', $med ],
3892 [ 'Standard deviation', $std ],
3893 [ 'Coefficient of variation', $cv ]
3898 else
3900 @desc_stat = ( [ 'Total no. of genotypes', 'None' ],
3901 [ 'Genotypes missing data', 'None' ],
3902 [ 'Minimum', 'None' ],
3903 [ 'Maximum', 'None' ],
3904 [ 'Arithmetic mean', 'None' ],
3905 [ 'Median', 'None'],
3906 [ 'Standard deviation', 'None' ],
3907 [ 'Coefficient of variation', 'None' ]
3912 $c->stash->{descriptive_stat} = \@desc_stat;
3915 #sends an array of trait gebv data to an ajax request
3916 #with a population id and trait id parameters
3917 sub gebv_graph :Path('/solgs/trait/gebv/graph') Args(0) {
3918 my ($self, $c) = @_;
3920 my $pop_id = $c->req->param('pop_id');
3921 my $trait_id = $c->req->param('trait_id');
3922 my $prediction_pop_id = $c->req->param('selection_pop_id');
3923 my $combo_pops_id = $c->req->param('combo_pops_id');
3925 if ($combo_pops_id)
3927 $self->get_combined_pops_list($c, $combo_pops_id);
3928 $c->stash->{data_set_type} = 'combined populations';
3929 $pop_id = $combo_pops_id;
3934 $c->stash->{pop_id} = $pop_id;
3935 $c->stash->{combo_pops_id} = $combo_pops_id;
3936 $c->stash->{prediction_pop_id} = $prediction_pop_id;
3938 $self->get_trait_details($c, $trait_id);
3940 my $page = $c->req->referer();
3941 my $gebv_file;
3943 if ($page =~ /solgs\/selection\//)
3945 my $identifier = $pop_id . '_' . $prediction_pop_id;
3946 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
3948 $gebv_file = $c->stash->{prediction_pop_gebvs_file};
3950 else
3952 $self->gebv_kinship_file($c);
3953 $gebv_file = $c->stash->{gebv_kinship_file};
3957 my $gebv_data = $self->convert_to_arrayref_of_arrays($c, $gebv_file);
3959 my $ret->{status} = 'failed';
3961 if (@$gebv_data)
3963 $ret->{status} = 'success';
3964 $ret->{gebv_data} = $gebv_data;
3967 $ret = to_json($ret);
3969 $c->res->content_type('application/json');
3970 $c->res->body($ret);
3975 sub tohtml_genotypes {
3976 my ($self, $c) = @_;
3978 my $genotypes = $c->stash->{top_10_selection_indices};
3979 my %geno = ();
3981 foreach (@$genotypes)
3983 $geno{$_->[0]} = $_->[1];
3985 return \%geno;
3989 sub get_single_trial_traits {
3990 my ($self, $c) = @_;
3992 my $pop_id = $c->stash->{pop_id};
3994 $self->traits_list_file($c);
3995 my $traits_file = $c->stash->{traits_list_file};
3997 if (!-s $traits_file)
3999 my $traits_rs = $c->model('solGS::solGS')->project_traits($pop_id);
4001 my @traits_list;
4003 while (my $row = $traits_rs->next)
4005 push @traits_list, $row->name;
4008 my $traits = join("\t", @traits_list);
4009 write_file($traits_file, $traits);
4015 sub get_all_traits {
4016 my ($self, $c) = @_;
4018 my $pop_id = $c->stash->{pop_id};
4020 $self->traits_list_file($c);
4021 my $traits_file = $c->stash->{traits_list_file};
4023 if (!-s $traits_file)
4025 my $page = $c->req->path;
4027 if ($page =~ /solgs\/population\//)
4029 $self->get_single_trial_traits($c);
4033 my $traits = read_file($traits_file);
4035 $self->traits_acronym_file($c);
4036 my $acronym_file = $c->stash->{traits_acronym_file};
4038 unless (-s $acronym_file)
4040 my @filtered_traits = split(/\t/, $traits);
4041 my $count = scalar(@filtered_traits);
4043 my $acronymized_traits = $self->acronymize_traits(\@filtered_traits);
4044 my $acronym_table = $acronymized_traits->{acronym_table};
4046 $self->traits_acronym_table($c, $acronym_table);
4049 $self->create_trait_data($c);
4053 sub create_trait_data {
4054 my ($self, $c) = @_;
4056 my $table = 'trait_id' . "\t" . 'trait_name' . "\t" . 'acronym' . "\n";
4058 my $acronym_pairs = $self->get_acronym_pairs($c);
4060 foreach (@$acronym_pairs)
4062 my $trait_name = $_->[1];
4063 $trait_name =~ s/\n//g;
4065 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
4067 if ($trait_id)
4069 $table .= $trait_id . "\t" . $trait_name . "\t" . $_->[0] . "\n";
4073 $self->all_traits_file($c);
4074 my $traits_file = $c->stash->{all_traits_file};
4075 write_file($traits_file, $table);
4079 sub all_traits_file {
4080 my ($self, $c) = @_;
4082 my $pop_id = $c->stash->{pop_id};
4083 #$pop_id = $c->stash->{combo_pops_id} if !$pop_id;
4085 my $cache_data = {key => 'all_traits_pop' . $pop_id,
4086 file => 'all_traits_pop_' . $pop_id,
4087 stash_key => 'all_traits_file'
4090 $self->cache_file($c, $cache_data);
4095 sub traits_list_file {
4096 my ($self, $c) = @_;
4098 my $pop_id = $c->stash->{pop_id};
4099 # $pop_id = $c->stash->{combo_pops_id} if !$pop_id;
4101 my $cache_data = {key => 'traits_list_pop' . $pop_id,
4102 file => 'traits_list_pop_' . $pop_id,
4103 stash_key => 'traits_list_file'
4106 $self->cache_file($c, $cache_data);
4111 sub get_acronym_pairs {
4112 my ($self, $c) = @_;
4114 my $pop_id = $c->stash->{pop_id};
4115 #$pop_id = $c->stash->{combo_pops_id} if !$pop_id;
4117 my $dir = $c->stash->{solgs_cache_dir};
4118 opendir my $dh, $dir
4119 or die "can't open $dir: $!\n";
4121 no warnings 'uninitialized';
4123 my ($file) = grep(/traits_acronym_pop_${pop_id}/, readdir($dh));
4124 $dh->close;
4126 my $acronyms_file = catfile($dir, $file);
4128 my @acronym_pairs;
4129 if (-f $acronyms_file)
4131 @acronym_pairs = map { [ split(/\t/) ] } read_file($acronyms_file);
4132 shift(@acronym_pairs); # remove header;
4135 @acronym_pairs = sort {uc $a->[0] cmp uc $b->[0] } @acronym_pairs;
4137 $c->stash->{acronym} = \@acronym_pairs;
4139 return \@acronym_pairs;
4144 sub traits_acronym_table {
4145 my ($self, $c, $acronym_table) = @_;
4147 my $table = 'Acronym' . "\t" . 'Trait name' . "\n";
4149 foreach (keys %$acronym_table)
4151 $table .= $_ . "\t" . $acronym_table->{$_} . "\n";
4154 $self->traits_acronym_file($c);
4155 my $acronym_file = $c->stash->{traits_acronym_file};
4157 write_file($acronym_file, $table);
4162 sub traits_acronym_file {
4163 my ($self, $c) = @_;
4165 my $pop_id = $c->stash->{pop_id};
4166 #$pop_id = $c->stash->{combo_pops_id} if !$pop_id;
4168 my $cache_data = {key => 'traits_acronym_pop' . $pop_id,
4169 file => 'traits_acronym_pop_' . $pop_id,
4170 stash_key => 'traits_acronym_file'
4173 $self->cache_file($c, $cache_data);
4178 sub analyzed_traits {
4179 my ($self, $c) = @_;
4181 my $training_pop_id = $c->stash->{model_id} || $c->stash->{training_pop_id};
4183 my $dir = $c->stash->{solgs_cache_dir};
4184 opendir my $dh, $dir or die "can't open $dir: $!\n";
4186 my @all_files = grep { /gebv_kinship_[a-zA-Z0-9]/ && -f "$dir/$_" }
4187 readdir($dh);
4189 closedir $dh;
4191 my @traits_files = map { catfile($dir, $_)}
4192 grep {/($training_pop_id)/}
4193 @all_files;
4195 my @traits;
4196 my @traits_ids;
4197 my @si_traits;
4198 my @valid_traits_files;
4200 foreach my $trait_file (@traits_files)
4202 if (-s $trait_file > 1)
4204 my $trait = $trait_file;
4205 $trait =~ s/gebv_kinship_//;
4206 $trait =~ s/$training_pop_id|_|combined_pops//g;
4207 $trait =~ s/$dir|\///g;
4209 my $acronym_pairs = $self->get_acronym_pairs($c);
4210 if ($acronym_pairs)
4212 foreach my $r (@$acronym_pairs)
4214 if ($r->[0] eq $trait)
4216 my $trait_name = $r->[1];
4217 $trait_name =~ s/\n//g;
4218 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
4220 push @traits_ids, $trait_id;
4225 $self->get_model_accuracy_value($c, $training_pop_id, $trait);
4226 my $av = $c->stash->{accuracy_value};
4228 if ($av && $av =~ m/\d+/ && $av > 0)
4230 push @si_traits, $trait;
4231 push @valid_traits_files, $trait_file;
4234 push @traits, $trait;
4236 else
4238 @traits_files = grep { $_ ne $trait_file } @traits_files;
4242 $c->stash->{analyzed_traits} = \@traits;
4243 $c->stash->{analyzed_traits_ids} = \@traits_ids;
4244 $c->stash->{analyzed_traits_files} = \@traits_files;
4245 $c->stash->{selection_index_traits} = \@si_traits;
4246 $c->stash->{analyzed_valid_traits_files} = \@valid_traits_files;
4251 sub filter_phenotype_header {
4252 my ($self, $c) = @_;
4254 my $meta_headers = "uniquename\tobject_name\tobject_id\tstock_id\tstock_name\tdesign\tblock\treplicate";
4256 if ($c)
4258 $c->stash->{filter_phenotype_header} = $meta_headers;
4260 else
4262 return $meta_headers;
4268 sub abbreviate_term {
4269 my ($self, $term) = @_;
4271 my @words = split(/\s/, $term);
4273 my $acronym;
4275 if (scalar(@words) == 1)
4277 $acronym = shift(@words);
4279 else
4281 foreach my $word (@words)
4283 if ($word =~ /^\D/)
4285 my $l = substr($word,0,1,q{});
4286 $acronym .= $l;
4288 else
4290 $acronym .= $word;
4293 $acronym = uc($acronym);
4294 $acronym =~/(\w+)/;
4295 $acronym = $1;
4299 return $acronym;
4304 sub all_gs_traits_list {
4305 my ($self, $c) = @_;
4307 $self->trial_compatibility_file($c);
4308 my $file = $c->stash->{trial_compatibility_file};
4310 my $traits;
4311 my $mv_name = 'all_gs_traits';
4313 my $matview = $c->model('solGS::solGS')->check_matview_exists($mv_name);
4315 if (!$matview)
4317 $c->model('solGS::solGS')->materialized_view_all_gs_traits();
4318 $c->model('solGS::solGS')->insert_matview_public($mv_name);
4320 else
4322 if (!-s $file)
4324 $c->model('solGS::solGS')->refresh_materialized_view_all_gs_traits();
4325 $c->model('solGS::solGS')->update_matview_public($mv_name);
4331 $traits = $c->model('solGS::solGS')->all_gs_traits();
4333 catch
4336 if ($_ =~ /materialized view \"all_gs_traits\" has not been populated/)
4340 $c->model('solGS::solGS')->refresh_materialized_view_all_gs_traits();
4341 $c->model('solGS::solGS')->update_matview_public($mv_name);
4342 $traits = $c->model('solGS::solGS')->all_gs_traits();
4347 $c->stash->{all_gs_traits} = $traits;
4352 sub gs_traits_index {
4353 my ($self, $c) = @_;
4355 $self->all_gs_traits_list($c);
4356 my $all_traits = $c->stash->{all_gs_traits};
4357 my @all_traits = sort{$a cmp $b} @$all_traits;
4359 my @indices = ('A'..'Z');
4360 my %traits_hash;
4361 my @valid_indices;
4363 foreach my $index (@indices)
4365 my @index_traits;
4366 foreach my $trait (@all_traits)
4368 if ($trait =~ /^$index/i)
4370 push @index_traits, $trait;
4373 if (@index_traits)
4375 $traits_hash{$index}=[ @index_traits ];
4379 foreach my $k ( keys(%traits_hash))
4381 push @valid_indices, $k;
4384 @valid_indices = sort( @valid_indices );
4386 my $trait_index;
4387 foreach my $v_i (@valid_indices)
4389 $trait_index .= qq | <a href=/solgs/traits/$v_i>$v_i</a> |;
4390 unless ($v_i eq $valid_indices[-1])
4392 $trait_index .= " | ";
4396 $c->stash->{gs_traits_index} = $trait_index;
4401 sub traits_starting_with {
4402 my ($self, $c, $index) = @_;
4404 $self->all_gs_traits_list($c);
4405 my $all_traits = $c->stash->{all_gs_traits};
4407 my $trait_gr = [
4408 sort { $a cmp $b }
4409 grep { /^$index/i }
4410 uniq @$all_traits
4413 $c->stash->{trait_subgroup} = $trait_gr;
4417 sub hyperlink_traits {
4418 my ($self, $c, $traits) = @_;
4420 my @traits_urls;
4421 foreach my $tr (@$traits)
4423 push @traits_urls, [ qq | <a href="/solgs/search/result/traits/$tr">$tr</a> | ];
4426 $c->stash->{traits_urls} = \@traits_urls;
4431 sub gs_traits : Path('/solgs/traits') Args(1) {
4432 my ($self, $c, $index) = @_;
4434 if ($index =~ /^\w{1}$/)
4436 $self->traits_starting_with($c, $index);
4437 my $traits_gr = $c->stash->{trait_subgroup};
4439 $self->hyperlink_traits($c, $traits_gr);
4440 my $traits_urls = $c->stash->{traits_urls};
4442 $c->stash( template => $self->template('/search/traits/list.mas'),
4443 index => $index,
4444 traits_list => $traits_urls
4447 else
4449 $c->forward('search');
4454 sub submit_cluster_phenotype_query {
4455 my ($self, $c, $args) = @_;
4457 $c->stash->{r_temp_file} = 'phenotype-data-query';
4458 $self->create_cluster_acccesible_tmp_files($c);
4459 my $out_temp_file = $c->stash->{out_file_temp};
4460 my $err_temp_file = $c->stash->{err_file_temp};
4462 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
4463 my $background_job = $c->stash->{background_job};
4465 my $status;
4467 try
4469 my $pheno_job = CXGN::Tools::Run->run_cluster_perl({
4471 method => ["SGN::Controller::solGS::solGS" => "prep_phenotype_file"],
4472 args => [$args],
4473 load_packages => ['SGN::Controller::solGS::solGS', 'SGN::Context', 'SGN::Model::solGS::solGS'],
4474 run_opts => {
4475 out_file => $out_temp_file,
4476 err_file => $err_temp_file,
4477 working_dir => $temp_dir,
4478 max_cluster_jobs => 1_000_000_000,
4483 $c->stash->{r_job_tempdir} = $pheno_job->tempdir();
4484 $c->stash->{r_job_id} = $pheno_job->job_id();
4485 $c->stash->{cluster_job} = $pheno_job;
4487 unless ($background_job)
4489 $pheno_job->wait();
4492 catch
4494 $status = $_;
4495 $status =~ s/\n at .+//s;
4502 sub submit_cluster_genotype_query {
4503 my ($self, $c, $args) = @_;
4505 $c->stash->{r_temp_file} = 'genotype-data-query';
4506 $self->create_cluster_acccesible_tmp_files($c);
4507 my $out_temp_file = $c->stash->{out_file_temp};
4508 my $err_temp_file = $c->stash->{err_file_temp};
4510 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
4511 my $background_job = $c->stash->{background_job};
4513 my $status;
4515 try
4517 my $geno_job = CXGN::Tools::Run->run_cluster_perl({
4519 method => ["SGN::Controller::solGS::solGS" => "prep_genotype_file"],
4520 args => [$args],
4521 load_packages => ['SGN::Controller::solGS::solGS', 'SGN::Context', 'SGN::Model::solGS::solGS'],
4522 run_opts => {
4523 out_file => $out_temp_file,
4524 err_file => $err_temp_file,
4525 working_dir => $temp_dir,
4526 max_cluster_jobs => 1_000_000_000,
4531 $c->stash->{r_job_tempdir} = $geno_job->tempdir();
4532 $c->stash->{r_job_id} = $geno_job->job_id();
4533 $c->stash->{cluster_job} = $geno_job;
4535 unless ($background_job)
4537 $geno_job->wait();
4541 catch
4543 $status = $_;
4544 $status =~ s/\n at .+//s;
4550 sub prep_phenotype_file {
4551 my ($self,$args) = @_;
4553 my $pheno_file = $args->{phenotype_file};
4554 my $pop_id = $args->{population_id};
4555 my $traits_file = $args->{traits_list_file};
4556 my $cache_dir = $args->{cache_dir};
4558 my $model = SGN::Model::solGS::solGS->new({context => 'SGN::Context',
4559 schema => SGN::Context->dbic_schema("Bio::Chado::Schema")});
4561 my $pheno_data = $model->phenotype_data($pop_id);
4563 if ($pheno_data)
4565 $pheno_data = SGN::Controller::solGS::solGS->format_phenotype_dataset($pheno_data, $traits_file);
4566 write_file($pheno_file, $pheno_data);
4569 my $file_cache = Cache::File->new(cache_root => $cache_dir);
4571 $file_cache->set('phenotype_data_' . $pop_id, $pheno_file, '30 days');
4576 sub prep_genotype_file {
4577 my ($self, $args) = @_;
4579 my $geno_file = $args->{genotype_file};
4580 my $cache_dir = $args->{cache_dir};
4581 my $pop_id = ($args->{prediction_id} ? $args->{prediction_id} : $args->{population_id});
4582 my $model = SGN::Model::solGS::solGS->new({context => 'SGN::Context',
4583 schema => SGN::Context->dbic_schema("Bio::Chado::Schema")});
4585 my $geno_data = $model->genotype_data($args);
4587 if ($geno_data)
4589 write_file($geno_file, $geno_data);
4592 my $file_cache = Cache::File->new(cache_root => $cache_dir);
4594 $file_cache->set('genotype_data_' . $pop_id, $geno_file, '30 days');
4599 sub phenotype_file {
4600 my ($self, $c) = @_;
4601 my $pop_id = $c->stash->{pop_id};
4603 die "Population id must be provided to get the phenotype data set." if !$pop_id;
4604 $pop_id =~ s/combined_//;
4606 my $pheno_file;
4608 if ($c->stash->{uploaded_reference} || $pop_id =~ /uploaded/) {
4609 my $tmp_dir = $c->stash->{solgs_prediction_upload_dir};
4611 if (!$c->user) {
4613 my $page = "/" . $c->req->path;
4615 $c->res->redirect("/solgs/list/login/message?page=$page");
4616 $c->detach;
4619 else
4621 my $user_id = $c->user->id;
4622 $pheno_file = catfile ($tmp_dir, "phenotype_data_${user_id}_${pop_id}");
4626 unless ($pheno_file)
4628 my $dir = $c->stash->{solgs_cache_dir};
4629 my $file_cache = Cache::File->new(cache_root => $dir);
4630 $file_cache->purge();
4632 my $key = "phenotype_data_" . $pop_id;
4633 $pheno_file = $file_cache->get($key);
4635 no warnings 'uninitialized';
4637 unless ( -s $pheno_file)
4639 $pheno_file = catfile($dir, 'phenotype_data_' . $pop_id . '.txt');
4641 $self->traits_list_file($c);
4642 my $traits_file = $c->stash->{traits_list_file};
4644 my $args = {
4645 'population_id' => $pop_id,
4646 'phenotype_file' => $pheno_file,
4647 'traits_list_file' => $traits_file,
4648 'cache_dir' => $dir,
4651 if (!$c->stash->{uploaded_reference})
4653 $self->submit_cluster_phenotype_query($c, $args);
4658 $c->stash->{phenotype_file} = $pheno_file;
4663 sub format_phenotype_dataset {
4664 my ($self, $data, $traits_file) = @_;
4666 my @rows = split (/\n/, $data);
4668 my $formatted_headers = $self->format_phenotype_dataset_headers($rows[0], $traits_file);
4669 $rows[0] = $formatted_headers;
4671 my $formatted_dataset = $self->format_phenotype_dataset_rows(\@rows);
4673 return $formatted_dataset;
4677 sub format_phenotype_dataset_rows {
4678 my ($self, $data_rows) = @_;
4680 foreach (@$data_rows)
4682 $_ =~ s/\s+plot//g;
4683 $_ .= "\n";
4686 return $data_rows;
4691 sub format_phenotype_dataset_headers {
4692 my ($self, $raw_headers, $traits_file) = @_;
4694 $raw_headers =~ s/SP:\d+\|//g;
4695 $raw_headers =~ s/\w+:\w+\|//g;
4696 $raw_headers =~ s/\n//g;
4698 my $meta_headers= $self->filter_phenotype_header();
4699 $raw_headers =~ s/($meta_headers\t)//g;
4701 write_file($traits_file, $raw_headers) if $traits_file;
4702 my @filtered_traits = split(/\t/, $raw_headers);
4704 my $acronymized_traits = $self->acronymize_traits(\@filtered_traits);
4705 my $formatted_headers = $acronymized_traits->{formatted_headers};
4707 return $formatted_headers;
4712 sub acronymize_traits {
4713 my ($self, $traits) = @_;
4715 my $formatted_traits;
4716 my $acronym_table = {};
4718 my $cnt = 0;
4719 foreach my $trait_name (@$traits)
4721 $cnt++;
4722 my $abbr = $self->abbreviate_term($trait_name);
4724 $abbr = $abbr . '.2' if $cnt > 1 && $acronym_table->{$abbr};
4726 $formatted_traits .= $abbr;
4727 $formatted_traits .= "\t" unless $cnt == scalar(@$traits);
4729 $acronym_table->{$abbr} = $trait_name if $abbr;
4730 my $tr_h = $acronym_table->{$abbr};
4733 my $meta_headers = $self->filter_phenotype_header();
4734 my $formatted_headers = $meta_headers ."\t". $formatted_traits;
4736 my $acronymized_traits = {
4737 'formatted_headers' => $formatted_headers,
4738 'acronym_table' => $acronym_table
4741 return $acronymized_traits;
4745 sub genotype_file {
4746 my ($self, $c, $pred_pop_id) = @_;
4748 my $pop_id = $c->stash->{pop_id};
4750 my $geno_file;
4752 if ($pred_pop_id)
4754 $pop_id = $c->stash->{prediction_pop_id};
4755 $geno_file = $c->stash->{user_selection_list_genotype_data_file};
4759 die "Population id must be provided to get the genotype data set." if !$pop_id;
4761 if ($c->stash->{uploaded_reference})
4763 my $tmp_dir = $c->stash->{solgs_prediction_upload_dir};
4765 if (!$c->user)
4767 my $path = "/" . $c->req->path;
4768 $c->res->redirect("/solgs/list/login/message?page=$path");
4769 $c->detach;
4771 else
4773 my $user_id = $c->user->id;
4774 $geno_file = catfile ($tmp_dir, "genotype_data_${user_id}_${pop_id}");
4778 if ($pop_id =~ /uploaded/)
4780 my $dir = $c->stash->{solgs_prediction_upload_dir};
4781 my $user_id = $c->user->id;
4783 my $exp = "genotype_data_${user_id}_${pop_id}";
4784 $geno_file = $self->grep_file($dir, $exp);
4788 unless($geno_file)
4790 my $cache_dir = $c->stash->{solgs_cache_dir};
4791 my $file_cache = Cache::File->new(cache_root => $cache_dir);
4792 $file_cache->purge();
4794 my $key = "genotype_data_" . $pop_id;
4795 $geno_file = $file_cache->get($key);
4797 no warnings 'uninitialized';
4799 unless (-s $geno_file)
4801 $geno_file = catfile($c->stash->{solgs_cache_dir}, 'genotype_data_' . $pop_id . '.txt');
4803 my $args = {
4804 'population_id' => $pop_id,
4805 'data_set_type' => $c->stash->{data_set_type},
4806 'cache_dir' => $cache_dir,
4807 'prediction_id' => $pred_pop_id,
4808 'trait_abbr' => $c->stash->{trait_abbr},
4809 'model_id' => $c->stash->{model_id},
4810 'genotype_file' => $geno_file,
4813 $self->submit_cluster_genotype_query($c, $args);
4817 if ($pred_pop_id)
4819 $c->stash->{pred_genotype_file} = $geno_file;
4821 else
4823 $c->stash->{genotype_file} = $geno_file;
4829 sub get_rrblup_output {
4830 my ($self, $c) = @_;
4832 $c->stash->{pop_id} = $c->stash->{combo_pops_id} if $c->stash->{combo_pops_id};
4834 my $pop_id = $c->stash->{pop_id};
4835 my $trait_abbr = $c->stash->{trait_abbr};
4836 my $trait_name = $c->stash->{trait_name};
4837 my $data_set_type = $c->stash->{data_set_type};
4838 my $prediction_id = $c->stash->{prediction_pop_id};
4840 my ($traits_file, @traits, @trait_pages);
4842 if ($trait_abbr)
4844 $self->run_rrblup_trait($c, $trait_abbr);
4846 else
4848 $traits_file = $c->stash->{selected_traits_file};
4849 my $content = read_file($traits_file);
4851 if ($content =~ /\t/)
4853 @traits = split(/\t/, $content);
4855 else
4857 push @traits, $content;
4860 no warnings 'uninitialized';
4862 foreach my $tr (@traits)
4864 my $acronym_pairs = $self->get_acronym_pairs($c);
4865 my $trait_name;
4866 if ($acronym_pairs)
4868 foreach my $r (@$acronym_pairs)
4870 if ($r->[0] eq $tr)
4872 $trait_name = $r->[1];
4873 $trait_name =~ s/\n//g;
4874 $c->stash->{trait_name} = $trait_name;
4875 $c->stash->{trait_abbr} = $r->[0];
4880 $self->run_rrblup_trait($c, $tr);
4882 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
4883 push @trait_pages, [ qq | <a href="/solgs/trait/$trait_id/population/$pop_id" onclick="solGS.waitPage()">$tr</a>| ];
4887 $c->stash->{combo_pops_analysis_result} = 0;
4889 no warnings 'uninitialized';
4891 if ($data_set_type !~ /combined populations/)
4893 if (scalar(@traits) == 1)
4895 $self->gs_files($c);
4896 $c->stash->{template} = $self->template('population/trait.mas');
4899 if (scalar(@traits) > 1)
4901 $c->stash->{model_id} = $pop_id;
4902 $self->analyzed_traits($c);
4903 $c->stash->{template} = $self->template('/population/multiple_traits_output.mas');
4904 $c->stash->{trait_pages} = \@trait_pages;
4907 else
4909 $c->stash->{combo_pops_analysis_result} = 1;
4915 sub run_rrblup_trait {
4916 my ($self, $c, $trait_abbr) = @_;
4918 my $pop_id = $c->stash->{pop_id};
4919 my $trait_name = $c->stash->{trait_name};
4920 my $data_set_type = $c->stash->{data_set_type};
4922 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
4923 $c->stash->{trait_id} = $trait_id;
4925 no warnings 'uninitialized';
4927 if ($data_set_type =~ /combined populations/i)
4929 my $prediction_id = $c->stash->{prediction_pop_id};
4931 $self->output_files($c);
4933 my $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
4934 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
4936 my $trait_info = $trait_id . "\t" . $trait_abbr;
4937 my $trait_file = $self->create_tempfile($c, "trait_info_${trait_id}");
4938 write_file($trait_file, $trait_info);
4940 my $dataset_file = $self->create_tempfile($c, "dataset_info_${trait_id}");
4941 write_file($dataset_file, $data_set_type);
4943 my $prediction_population_file = $c->stash->{prediction_population_file};
4945 my $input_files = join("\t",
4946 $c->stash->{trait_combined_pheno_file},
4947 $c->stash->{trait_combined_geno_file},
4948 $trait_file,
4949 $dataset_file,
4950 $prediction_population_file
4953 my $input_file = $self->create_tempfile($c, "input_files_combo_${trait_abbr}");
4954 write_file($input_file, $input_files);
4956 if ($c->stash->{prediction_pop_id})
4958 $c->stash->{input_files} = $input_file;
4959 # $self->output_files($c);
4960 $self->run_rrblup($c);
4962 else
4964 if (-s $c->stash->{gebv_kinship_file} == 0 ||
4965 -s $c->stash->{gebv_marker_file} == 0 ||
4966 -s $c->stash->{validation_file} == 0
4969 $c->stash->{input_files} = $input_file;
4970 # $self->output_files($c);
4971 $self->run_rrblup($c);
4975 else
4977 my $name = "trait_info_${trait_id}_pop_${pop_id}";
4979 my $trait_info = $trait_id . "\t" . $trait_abbr;
4980 my $file = $self->create_tempfile($c, $name);
4981 $c->stash->{trait_file} = $file;
4982 write_file($file, $trait_info);
4984 my $prediction_id = $c->stash->{prediction_pop_id};
4986 $self->output_files($c);
4988 if ($prediction_id)
4990 $prediction_id = "uploaded_${prediction_id}" if $c->stash->{uploaded_prediction};
4991 my $identifier = $pop_id . '_' . $prediction_id;
4993 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
4994 my $pred_pop_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
4996 unless (-s $pred_pop_gebvs_file != 0)
4998 $self->input_files($c);
4999 $self->run_rrblup($c);
5002 else
5004 if (-s $c->stash->{gebv_kinship_file} == 0 ||
5005 -s $c->stash->{gebv_marker_file} == 0 ||
5006 -s $c->stash->{validation_file} == 0
5009 $self->input_files($c);
5010 $self->run_rrblup($c);
5018 sub run_rrblup {
5019 my ($self, $c) = @_;
5021 #get all input files & arguments for rrblup,
5022 #run rrblup and save output in solgs user dir
5023 my $pop_id = $c->stash->{pop_id};
5024 my $trait_id = $c->stash->{trait_id};
5025 my $input_files = $c->stash->{input_files};
5026 my $output_files = $c->stash->{output_files};
5027 my $data_set_type = $c->stash->{data_set_type};
5029 if ($data_set_type !~ /combined populations/)
5031 die "\nCan't run rrblup without a population id." if !$pop_id;
5035 die "\nCan't run rrblup without a trait id." if !$trait_id;
5037 die "\nCan't run rrblup without input files." if !$input_files;
5038 die "\nCan't run rrblup without output files." if !$output_files;
5040 if ($data_set_type !~ /combined populations/)
5043 $c->stash->{r_temp_file} = "gs-rrblup-${trait_id}-${pop_id}";
5045 else
5047 my $combo_pops = $c->stash->{trait_combo_pops};
5048 $combo_pops = join('', split(/,/, $combo_pops));
5049 my $combo_identifier = crc($combo_pops);
5051 $c->stash->{r_temp_file} = "gs-rrblup-combo-${trait_id}-${combo_identifier}";
5054 $c->stash->{r_script} = 'R/gs.r';
5055 $self->run_r_script($c);
5060 sub r_combine_populations {
5061 my ($self, $c) = @_;
5063 my $combo_pops_id = $c->stash->{combo_pops_id};
5064 my $trait_id = $c->stash->{trait_id};
5065 my $trait_abbr = $c->stash->{trait_abbr};
5067 my $combo_pops_list = $c->stash->{combined_pops_list};
5068 my $pheno_files = $c->stash->{multi_pops_pheno_files};
5069 my $geno_files = $c->stash->{multi_pops_geno_files};
5071 my $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
5072 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
5074 my $trait_info = $trait_id . "\t" . $trait_abbr;
5075 my $trait_file = $self->create_tempfile($c, "trait_info_${trait_id}");
5076 write_file($trait_file, $trait_info);
5078 my $input_files = join ("\t",
5079 $pheno_files,
5080 $geno_files,
5081 $trait_file,
5084 my $output_files = join ("\t",
5085 $combined_pops_pheno_file,
5086 $combined_pops_geno_file,
5090 my $tempfile_input = $self->create_tempfile($c, "input_files_${trait_id}_combine");
5091 write_file($tempfile_input, $input_files);
5093 my $tempfile_output = $self->create_tempfile($c, "output_files_${trait_id}_combine");
5094 write_file($tempfile_output, $output_files);
5096 die "\nCan't call combine populations R script without a trait id." if !$trait_id;
5097 die "\nCan't call combine populations R script without input files." if !$input_files;
5098 die "\nCan't call combine populations R script without output files." if !$output_files;
5100 $c->stash->{input_files} = $tempfile_input;
5101 $c->stash->{output_files} = $tempfile_output;
5102 $c->stash->{r_temp_file} = "combine-pops-${trait_id}";
5103 $c->stash->{r_script} = 'R/combine_populations.r';
5105 $self->run_r_script($c);
5110 sub create_cluster_acccesible_tmp_files {
5111 my ($self, $c) = @_;
5113 my $temp_file_template = $c->stash->{r_temp_file};
5115 CXGN::Tools::Run->temp_base($c->stash->{solgs_tempfiles_dir});
5116 my ( $in_file_temp, $out_file_temp, $err_file_temp) =
5117 map
5119 my ( undef, $filename ) =
5120 tempfile(
5121 catfile(
5122 CXGN::Tools::Run->temp_base(),
5123 "${temp_file_template}-$_-XXXXXX",
5126 $filename
5128 qw / in out err/;
5130 $c->stash(
5131 in_file_temp => $in_file_temp,
5132 out_file_temp => $out_file_temp,
5133 err_file_temp => $err_file_temp,
5139 sub run_async {
5140 my ($self, $c) = @_;
5142 my $dependency = $c->stash->{dependency};
5143 my $dependency_type = $c->stash->{dependency_type};
5144 my $background_job = $c->stash->{background_job};
5145 my $dependent_job = $c->stash->{dependent_job};
5146 my $temp_file_template = $c->stash->{r_temp_file};
5147 my $job_type = $c->stash->{job_type};
5148 my $model_file = $c->stash->{gs_model_args_file};
5149 my $combine_pops_job_id = $c->stash->{combine_pops_job_id};
5150 my $solgs_tmp_dir = "'" . $c->stash->{solgs_tempfiles_dir} . "'";
5152 my $r_script = $c->stash->{r_commands_file};
5153 my $r_script_args = $c->stash->{r_script_args};
5155 if ($combine_pops_job_id)
5157 $dependency = $combine_pops_job_id;
5160 $dependency =~ s/^://;
5162 my $script_args;
5163 foreach my $arg (@$r_script_args)
5165 $script_args .= $arg;
5166 $script_args .= ' --script_args ' unless ($r_script_args->[-1] eq $arg);
5169 my $report_file = $self->create_tempfile($c, 'analysis_report_args');
5170 $c->stash->{report_file} = $report_file;
5172 my $cmd = 'mx-run solGS::DependentJob'
5173 . ' --dependency_jobs ' . $dependency
5174 . ' --dependency_type ' . $dependency_type
5175 . ' --temp_dir ' . $solgs_tmp_dir
5176 . ' --temp_file_template ' . $temp_file_template
5177 . ' --analysis_report_args_file ' . $report_file
5178 . ' --dependent_type ' . $job_type;
5180 if ($r_script)
5182 $cmd .= ' --r_script ' . $r_script
5183 . ' --script_args ' . $script_args
5184 . ' --gs_model_args_file ' . $model_file;
5187 $c->stash->{r_temp_file} = 'run-async';
5188 $self->create_cluster_acccesible_tmp_files($c);
5190 my $err_file_temp = $c->stash->{err_file_temp};
5191 my $out_file_temp = $c->stash->{out_file_temp};
5193 my $async = CXGN::Tools::Run->run_async($cmd,
5195 working_dir => $c->stash->{solgs_tempfiles_dir},
5196 temp_base => $c->stash->{solgs_tempfiles_dir},
5197 max_cluster_jobs => 1_000_000_000,
5198 out_file => $out_file_temp,
5199 err_file => $err_file_temp,
5203 #my $async_pid = $async->pid();
5205 #$c->stash->{async_pid} = $async_pid;
5206 #$c->stash->{r_job_tempdir} = $async->tempdir();
5207 #$c->stash->{r_job_id} = $async->job_id();
5209 # if ($c->stash->{r_script} =~ /combine_populations/)
5211 # $c->stash->{combine_pops_job_id} = $async->job_id();
5212 # #$c->stash->{r_job_tempdir} = $async->tempdir();
5213 # #$c->stash->{r_job_id} = $async->job_id();
5214 # # $c->stash->{cluster_job} = $r_job;
5220 sub run_r_script {
5221 my ($self, $c) = @_;
5223 my $r_script = $c->stash->{r_script};
5224 my $input_files = $c->stash->{input_files};
5225 my $output_files = $c->stash->{output_files};
5227 $self->create_cluster_acccesible_tmp_files($c);
5228 my $in_file_temp = $c->stash->{in_file_temp};
5229 my $out_file_temp = $c->stash->{out_file_temp};
5230 my $err_file_temp = $c->stash->{err_file_temp};
5232 my $dependency = $c->stash->{dependency};
5233 my $dependency_type = $c->stash->{dependency_type};
5234 my $background_job = $c->stash->{background_job};
5237 my $r_cmd_file = $c->path_to($r_script);
5238 copy($r_cmd_file, $in_file_temp)
5239 or die "could not copy '$r_cmd_file' to '$in_file_temp'";
5242 if ($dependency && $background_job)
5244 $c->stash->{r_commands_file} = $in_file_temp;
5245 $c->stash->{r_script_args} = [$input_files, $output_files];
5247 if ($r_script =~ /combine_populations/)
5249 $c->stash->{job_type} = 'combine_populations';
5250 #$c->stash->{combine_pops_job_id} = $dependency;
5251 $c->stash->{gs_model_args_file} = $self->create_tempfile($c, 'gs_model_args');
5252 $self->run_async($c);
5254 elsif ($r_script =~ /gs/)
5256 $c->stash->{job_type} = 'model';
5258 my $model_job = {
5259 'r_command_file' => $in_file_temp,
5260 'input_files' => $input_files,
5261 'output_files' => $output_files,
5262 'r_output_file' => $out_file_temp,
5263 'err_temp_file' => $err_file_temp,
5266 my $model_file = $c->stash->{gs_model_args_file};
5268 nstore $model_job, $model_file
5269 or croak "gs r script: $! serializing model details to '$model_file'";
5271 if ($dependency_type =~ /combine_populations/)
5273 $self->run_async($c);
5277 else
5279 my $r_job = CXGN::Tools::Run->run_cluster('R', 'CMD', 'BATCH',
5280 '--slave',
5281 "--args $input_files $output_files",
5282 $in_file_temp,
5283 $out_file_temp,
5285 working_dir => $c->stash->{solgs_tempfiles_dir},
5286 max_cluster_jobs => 1_000_000_000,
5288 try
5290 $c->stash->{r_job_tempdir} = $r_job->tempdir();
5291 $c->stash->{r_job_id} = $r_job->job_id();
5292 # $c->stash->{cluster_job} = $r_job;
5294 if ($r_script =~ /combine_populations/)
5296 #$c->stash->{job_type} = 'combine_populations';
5297 $c->stash->{combine_pops_job_id} = $r_job->job_id();
5298 $c->stash->{gs_model_args_file} = $self->create_tempfile($c, 'gs_model_args');
5299 #$self->run_async($c);
5302 unless ($background_job)
5304 $r_job->wait();
5307 catch
5309 my $err = $_;
5310 $err =~ s/\n at .+//s;
5314 $err .= "\n=== R output ===\n"
5315 .file($out_file_temp)->slurp
5316 ."\n=== end R output ===\n";
5319 $c->stash->{script_error} = "$r_script";
5326 sub get_solgs_dirs {
5327 my ($self, $c) = @_;
5329 my $tmp_dir = $c->site_cluster_shared_dir;
5330 my $solgs_dir = catdir($tmp_dir, "solgs");
5331 my $solgs_cache = catdir($tmp_dir, 'solgs', 'cache');
5332 my $solgs_tempfiles = catdir($tmp_dir, 'solgs', 'tempfiles');
5333 my $correlation_dir = catdir($tmp_dir, 'correlation', 'cache');
5334 my $solgs_upload = catdir($tmp_dir, 'solgs', 'tempfiles', 'prediction_upload');
5335 my $pca_dir = catdir($tmp_dir, 'pca', 'cache');
5336 my $histogram_dir = catdir($tmp_dir, 'histogram', 'cache');
5337 my $log_dir = catdir($tmp_dir, 'log', 'cache');
5339 mkpath (
5341 $solgs_dir, $solgs_cache, $solgs_tempfiles, $solgs_upload,
5342 $correlation_dir, $pca_dir, $histogram_dir, $log_dir
5344 0, 0755
5347 $c->stash(solgs_dir => $solgs_dir,
5348 solgs_cache_dir => $solgs_cache,
5349 solgs_tempfiles_dir => $solgs_tempfiles,
5350 solgs_prediction_upload_dir => $solgs_upload,
5351 correlation_dir => $correlation_dir,
5352 pca_dir => $pca_dir,
5353 histogram_dir => $histogram_dir,
5354 analysis_log_dir => $log_dir
5360 sub cache_file {
5361 my ($self, $c, $cache_data) = @_;
5363 my $cache_dir = $c->stash->{cache_dir};
5365 unless ($cache_dir)
5367 $cache_dir = $c->stash->{solgs_cache_dir};
5370 my $file_cache = Cache::File->new(cache_root => $cache_dir,
5371 lock_level => Cache::File::LOCK_NFS()
5374 $file_cache->purge();
5376 my $file = $file_cache->get($cache_data->{key});
5378 no warnings 'uninitialized';
5380 unless (-s $file > 1)
5382 $file = catfile($cache_dir, $cache_data->{file});
5383 write_file($file);
5384 $file_cache->set($cache_data->{key}, $file, '30 days');
5387 $c->stash->{$cache_data->{stash_key}} = $file;
5388 $c->stash->{cache_dir} = $c->stash->{solgs_cache_dir};
5392 sub load_yaml_file {
5393 my ($self, $c, $file) = @_;
5395 $file =~ s/\.\w+//;
5396 $file =~ s/(^\/)//;
5398 my $form = $self->form;
5399 my $yaml_dir = '/forms/solgs';
5401 $form->load_config_filestem($c->path_to(catfile($yaml_dir, $file)));
5402 $form->process;
5404 $c->stash->{form} = $form;
5409 sub template {
5410 my ($self, $file) = @_;
5412 $file =~ s/(^\/)//;
5413 my $dir = '/solgs';
5415 return catfile($dir, $file);
5420 # sub default :Path {
5421 # my ( $self, $c ) = @_;
5422 # $c->forward('search');
5427 =head2 end
5429 Attempt to render a view, if needed.
5431 =cut
5433 #sub render : ActionClass('RenderView') {}
5434 sub begin : Private {
5435 my ($self, $c) = @_;
5437 $self->get_solgs_dirs($c);
5442 # sub end : Private {
5443 # my ( $self, $c ) = @_;
5445 # return if @{$c->error};
5447 # # don't try to render a default view if this was handled by a CGI
5448 # $c->forward('render') unless $c->req->path =~ /\.pl$/;
5450 # # enforce a default texest/html content type regardless of whether
5451 # # we tried to render a default view
5452 # $c->res->content_type('text/html') unless $c->res->content_type;
5454 # # insert our javascript packages into the rendered view
5455 # if( $c->res->content_type eq 'text/html' ) {
5456 # $c->forward('/js/insert_js_pack_html');
5457 # $c->res->headers->push_header('Vary', 'Cookie');
5458 # } else {
5459 # $c->log->debug("skipping JS pack insertion for page with content type ".$c->res->content_type)
5460 # if $c->debug;
5465 =head2 auto
5467 Run for every request to the site.
5469 =cut
5471 # sub auto : Private {
5472 # my ($self, $c) = @_;
5473 # CatalystX::GlobalContext->set_context( $c );
5474 # $c->stash->{c} = $c;
5475 # weaken $c->stash->{c};
5477 # $self->get_solgs_dirs($c);
5478 # # gluecode for logins
5480 # # # unless( $c->config->{'disable_login'} ) {
5481 # # my $dbh = $c->dbc->dbh;
5482 # # if ( my $sp_person_id = CXGN::Login->new( $dbh )->has_session ) {
5484 # # my $sp_person = CXGN::People::Person->new( $dbh, $sp_person_id);
5486 # # $c->authenticate({
5487 # # username => $sp_person->get_username(),
5488 # # password => $sp_person->get_password(),
5489 # # });
5490 # # }
5491 # # }
5493 # return 1;
5499 =head1 AUTHOR
5501 Isaak Y Tecle <iyt2@cornell.edu>
5503 =head1 LICENSE
5505 This library is free software. You can redistribute it and/or modify
5506 it under the same terms as Perl itself.
5508 =cut
5510 __PACKAGE__->meta->make_immutable;