seedlot upload with accession synonyms. seedlot upload works to update existing seedlots
[sgn.git] / lib / SGN / Controller / solGS / solGS.pm
blob138970747869c8549d828b4f1ade4e63e7fce45f
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' }
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 search : Path('/solgs/search') Args() {
79 my ($self, $c) = @_;
81 #$self->gs_traits_index($c);
82 #my $gs_traits_index = $c->stash->{gs_traits_index};
84 $c->stash(template => $self->template('/search/solgs.mas'),
85 # gs_traits_index => $gs_traits_index,
91 sub search_trials : Path('/solgs/search/trials') Args() {
92 my ($self, $c) = @_;
94 my $show_result = $c->req->param('show_result');
95 my $limit = $show_result =~ /all/ ? undef : 10;
97 my $projects_ids = $c->model('solGS::solGS')->all_gs_projects($limit);
99 my $ret->{status} = 'failed';
101 my $formatted_trials = [];
103 if (@$projects_ids)
105 my $projects_rs = $c->model('solGS::solGS')->project_details($projects_ids);
107 $self->get_projects_details($c, $projects_rs);
108 my $projects = $c->stash->{projects_details};
110 $self->format_gs_projects($c, $projects);
111 $formatted_trials = $c->stash->{formatted_gs_projects};
113 $ret->{status} = 'success';
116 $ret->{trials} = $formatted_trials;
117 $ret = to_json($ret);
119 $c->res->content_type('application/json');
120 $c->res->body($ret);
125 sub projects_links {
126 my ($self, $c, $pr_rs) = @_;
128 $self->get_projects_details($c, $pr_rs);
129 my $projects = $c->stash->{projects_details};
131 my @projects_pages;
132 my $update_marker_count;
134 foreach my $pr_id (keys %$projects)
136 my $pr_name = $projects->{$pr_id}{project_name};
137 my $pr_desc = $projects->{$pr_id}{project_desc};
138 my $pr_year = $projects->{$pr_id}{project_year};
139 my $pr_location = $projects->{$pr_id}{project_location};
141 my $dummy_name = $pr_name =~ /test\w*/ig;
142 #my $dummy_desc = $pr_desc =~ /test\w*/ig;
144 $self->check_population_has_genotype($c);
145 my $has_genotype = $c->stash->{population_has_genotype};
147 no warnings 'uninitialized';
149 unless ($dummy_name || !$pr_name )
151 #$self->trial_compatibility_table($c, $has_genotype);
152 #my $match_code = $c->stash->{trial_compatibility_code};
154 my $checkbox = qq |<form> <input type="checkbox" name="project" value="$pr_id" onclick="getPopIds()"/> </form> |;
156 #$match_code = qq | <div class=trial_code style="color: $match_code; background-color: $match_code; height: 100%; width:30px">code</div> |;
158 push @projects_pages, [$checkbox, qq|<a href="/solgs/population/$pr_id" onclick="solGS.waitPage(this.href); return false;">$pr_name</a>|,
159 $pr_desc, $pr_location, $pr_year
167 $c->stash->{projects_pages} = \@projects_pages;
171 sub search_trials_trait : Path('/solgs/search/trials/trait') Args(1) {
172 my ($self, $c, $trait_id) = @_;
174 $self->get_trait_details($c, $trait_id);
176 $c->stash->{template} = $self->template('/search/trials/trait.mas');
181 sub show_search_result_pops : Path('/solgs/search/result/populations') Args(1) {
182 my ($self, $c, $trait_id) = @_;
184 my $combine = $c->req->param('combine');
185 my $page = $c->req->param('page') || 1;
187 my $projects_ids = $c->model('solGS::solGS')->search_trait_trials($trait_id);
189 my $ret->{status} = 'failed';
190 my $formatted_projects = [];
192 if (@$projects_ids)
194 my $projects_rs = $c->model('solGS::solGS')->project_details($projects_ids);
195 my $trait = $c->model('solGS::solGS')->trait_name($trait_id);
197 $self->get_projects_details($c, $projects_rs);
198 my $projects = $c->stash->{projects_details};
200 $self->format_trait_gs_projects($c, $trait_id, $projects);
201 $formatted_projects = $c->stash->{formatted_gs_projects};
203 $ret->{status} = 'success';
206 $ret->{trials} = $formatted_projects;
208 $ret = to_json($ret);
210 $c->res->content_type('application/json');
211 $c->res->body($ret);
216 sub format_trait_gs_projects {
217 my ($self, $c, $trait_id, $projects) = @_;
219 my @formatted_projects;
221 foreach my $pr_id (keys %$projects)
223 my $pr_name = $projects->{$pr_id}{project_name};
224 my $pr_desc = $projects->{$pr_id}{project_desc};
225 my $pr_year = $projects->{$pr_id}{project_year};
226 my $pr_location = $projects->{$pr_id}{project_location};
228 $c->stash->{pop_id} = $pr_id;
229 $self->check_population_has_genotype($c);
230 my $has_genotype = $c->stash->{population_has_genotype};
232 if ($has_genotype)
234 my $trial_compatibility_file = $self->trial_compatibility_file($c);
236 $self->trial_compatibility_table($c, $has_genotype);
237 my $match_code = $c->stash->{trial_compatibility_code};
239 my $checkbox = qq |<form> <input type="checkbox" name="project" value="$pr_id" onclick="getPopIds()"/> </form> |;
240 $match_code = qq | <div class=trial_code style="color: $match_code; background-color: $match_code; height: 100%; width:100%">code</div> |;
242 push @formatted_projects, [ $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];
246 $c->stash->{formatted_gs_projects} = \@formatted_projects;
251 sub format_gs_projects {
252 my ($self, $c, $projects) = @_;
254 my @formatted_projects;
256 foreach my $pr_id (keys %$projects)
258 my $pr_name = $projects->{$pr_id}{project_name};
259 my $pr_desc = $projects->{$pr_id}{project_desc};
260 my $pr_year = $projects->{$pr_id}{project_year};
261 my $pr_location = $projects->{$pr_id}{project_location};
263 # $c->stash->{pop_id} = $pr_id;
264 # $self->check_population_has_genotype($c);
265 # my $has_genotype = $c->stash->{population_has_genotype};
266 my $has_genotype = $c->config->{default_genotyping_protocol};
268 if ($has_genotype)
270 my $trial_compatibility_file = $self->trial_compatibility_file($c);
272 $self->trial_compatibility_table($c, $has_genotype);
273 my $match_code = $c->stash->{trial_compatibility_code};
275 my $checkbox = qq |<form> <input type="checkbox" name="project" value="$pr_id" onclick="getPopIds()"/> </form> |;
276 $match_code = qq | <div class=trial_code style="color: $match_code; background-color: $match_code; height: 100%; width:100%">code</div> |;
278 push @formatted_projects, [ $checkbox, qq|<a href="/solgs/population/$pr_id" onclick="solGS.waitPage(this.href); return false;">$pr_name</a>|, $pr_desc, $pr_location, $pr_year, $match_code];
282 $c->stash->{formatted_gs_projects} = \@formatted_projects;
287 sub trial_compatibility_table {
288 my ($self, $c, $markers) = @_;
290 $self->trial_compatibility_file($c);
291 my $compatibility_file = $c->stash->{trial_compatibility_file};
293 my $color;
295 if (-s $compatibility_file)
297 my @line = read_file($compatibility_file);
298 my ($entry) = grep(/$markers/, @line);
299 chomp($entry);
301 if($entry)
303 ($markers, $color) = split(/\t/, $entry);
304 $c->stash->{trial_compatibility_code} = $color;
308 if (!$color)
310 my ($red, $blue, $green) = map { int(rand(255)) } 1..3;
311 $color = 'rgb' . '(' . "$red,$blue,$green" . ')';
313 my $color_code = $markers . "\t" . $color . "\n";
315 $c->stash->{trial_compatibility_code} = $color;
316 write_file($compatibility_file,{append => 1}, $color_code);
321 sub trial_compatibility_file {
322 my ($self, $c) = @_;
324 my $cache_data = {key => 'trial_compatibility',
325 file => 'trial_compatibility_codes',
326 stash_key => 'trial_compatibility_file'
329 $self->cache_file($c, $cache_data);
334 sub get_projects_details {
335 my ($self, $c, $pr_rs) = @_;
337 my ($year, $location, $pr_id, $pr_name, $pr_desc);
338 my %projects_details = ();
340 while (my $pr = $pr_rs->next)
342 $pr_id = $pr->get_column('project_id');
343 $pr_name = $pr->get_column('name');
344 $pr_desc = $pr->get_column('description');
346 my $pr_yr_rs = $c->model('solGS::solGS')->project_year($pr_id);
348 while (my $pr = $pr_yr_rs->next)
350 $year = $pr->value;
353 my $location = $c->model('solGS::solGS')->project_location($pr_id);
355 $projects_details{$pr_id} = {
356 project_name => $pr_name,
357 project_desc => $pr_desc,
358 project_year => $year,
359 project_location => $location,
363 $c->stash->{projects_details} = \%projects_details;
368 sub store_project_marker_count {
369 my ($self, $c) = @_;
371 my $pop_id = $c->stash->{pop_id};
372 my $marker_count = $c->stash->{marker_count};
374 unless ($marker_count)
376 my $markers = $c->model("solGS::solGS")->get_project_genotyping_markers($pop_id);
377 my @markers = split('\t', $markers);
378 $marker_count = scalar(@markers);
381 my $genoprop = {'project_id' => $pop_id, 'marker_count' => $marker_count};
382 $c->model("solGS::solGS")->set_project_genotypeprop($genoprop);
387 sub search_traits : Path('/solgs/search/traits/') Args(1) {
388 my ($self, $c, $query) = @_;
390 my $traits = $c->model('solGS::solGS')->search_trait($query);
391 my $result = $c->model('solGS::solGS')->trait_details($traits);
393 my $ret->{status} = 0;
394 if ($result->first)
396 $ret->{status} = 1;
399 $ret = to_json($ret);
401 $c->res->content_type('application/json');
402 $c->res->body($ret);
407 sub show_search_result_traits : Path('/solgs/search/result/traits') Args(1) {
408 my ($self, $c, $query) = @_;
410 my $traits = $c->model('solGS::solGS')->search_trait($query);
411 my $result = $c->model('solGS::solGS')->trait_details($traits);
413 my @rows;
414 while (my $row = $result->next)
416 my $id = $row->cvterm_id;
417 my $name = $row->name;
418 my $def = $row->definition;
420 push @rows, [ qq |<a href="/solgs/search/trials/trait/$id" onclick="solGS.waitPage()">$name</a>|, $def];
423 if (@rows)
425 $c->stash(template => $self->template('/search/result/traits.mas'),
426 result => \@rows,
427 query => $query,
434 sub population : Regex('^solgs/population/([\w|\d]+)(?:/([\w+]+))?') {
435 my ($self, $c) = @_;
437 my ($pop_id, $action) = @{$c->req->captures};
439 my $uploaded_reference = $c->req->param('uploaded_reference');
440 $c->stash->{uploaded_reference} = $uploaded_reference;
442 if ($uploaded_reference)
444 $pop_id = $c->req->param('model_id');
446 $c->stash->{model_id} = $c->req->param('model_id'),
447 $c->stash->{list_name} = $c->req->param('list_name'),
451 if ($pop_id )
453 if($pop_id =~ /uploaded/)
455 $c->stash->{uploaded_reference} = 1;
456 $uploaded_reference = 1;
459 $c->stash->{pop_id} = $pop_id;
461 $self->phenotype_file($c);
462 $self->genotype_file($c);
463 $self->get_all_traits($c);
464 $self->project_description($c, $pop_id);
466 $c->stash->{template} = $self->template('/population.mas');
468 if ($action && $action =~ /selecttraits/ ) {
469 $c->stash->{no_traits_selected} = 'none';
471 else {
472 $c->stash->{no_traits_selected} = 'some';
475 my $acronym = $self->get_acronym_pairs($c);
476 $c->stash->{acronym} = $acronym;
479 my $pheno_data_file = $c->stash->{phenotype_file};
481 if ($uploaded_reference)
483 my $ret->{status} = 'failed';
484 if ( !-s $pheno_data_file )
486 $ret->{status} = 'failed';
488 $ret = to_json($ret);
490 $c->res->content_type('application/json');
491 $c->res->body($ret);
497 sub uploaded_population_summary {
498 my ($self, $c, $list_pop_id) = @_;
500 my $tmp_dir = $c->stash->{solgs_prediction_upload_dir};
502 if (!$c->user)
504 my $page = "/" . $c->req->path;
505 $c->res->redirect("/solgs/list/login/message?page=$page");
506 $c->detach;
508 else
510 my $user_name = $c->user->id;
512 #my $model_id = $c->stash->{model_id};
513 #my $selection_pop_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id};
515 my $protocol = $c->config->{default_genotyping_protocol};
516 $protocol = 'N/A' if !$protocol;
518 if ($list_pop_id)
520 my $metadata_file_tr = catfile($tmp_dir, "metadata_${user_name}_${list_pop_id}");
522 my @metadata_tr = read_file($metadata_file_tr) if $list_pop_id;
524 my ($key, $list_name, $desc);
526 ($desc) = grep {/description/} @metadata_tr;
527 ($key, $desc) = split(/\t/, $desc);
529 ($list_name) = grep {/list_name/} @metadata_tr;
530 ($key, $list_name) = split(/\t/, $list_name);
532 $c->stash(project_id => $list_pop_id,
533 project_name => $list_name,
534 prediction_pop_name => $list_name,
535 project_desc => $desc,
536 owner => $user_name,
537 protocol => $protocol,
541 # if ($selection_pop_id =~ /uploaded/)
543 # my $metadata_file_sl = catfile($tmp_dir, "metadata_${user_name}_${selection_pop_id}");
544 # my @metadata_sl = read_file($metadata_file_sl) if $selection_pop_id;
546 # my ($list_name_sl) = grep {/list_name/} @metadata_sl;
547 # my ($key_sl, $list_name) = split(/\t/, $list_name_sl);
549 # $c->stash->{prediction_pop_name} = $list_name;
555 sub get_project_details {
556 my ($self, $c, $pr_id) = @_;
558 my $pr_rs = $c->model('solGS::solGS')->project_details($pr_id);
560 while (my $row = $pr_rs->next)
562 $c->stash(project_id => $row->id,
563 project_name => $row->name,
564 project_desc => $row->description
571 sub get_markers_count {
572 my ($self, $c, $pop_hash) = @_;
574 my $filtered_geno_file;
575 my $markers_cnt;
577 if ($pop_hash->{training_pop})
579 my $training_pop_id = $pop_hash->{training_pop_id};
580 $c->stash->{pop_id} = $training_pop_id;
581 $self->filtered_training_genotype_file($c);
582 $filtered_geno_file = $c->stash->{filtered_training_genotype_file};
584 if (-s $filtered_geno_file) {
585 my @geno_lines = read_file($filtered_geno_file);
586 $markers_cnt = scalar(split('\t', $geno_lines[0])) - 1;
588 else
590 $self->genotype_file_name($c, $training_pop_id);
591 my $geno_file = $c->stash->{genotype_file_name};
592 my @geno_lines = read_file($geno_file);
593 $markers_cnt= scalar(split ('\t', $geno_lines[0])) - 1;
597 elsif ($pop_hash->{selection_pop})
599 my $selection_pop_id = $pop_hash->{selection_pop_id};
600 $c->stash->{pop_id} = $selection_pop_id;
601 $self->filtered_selection_genotype_file($c);
602 $filtered_geno_file = $c->stash->{filtered_selection_genotype_file};
604 if (-s $filtered_geno_file) {
605 my @geno_lines = read_file($filtered_geno_file);
606 $markers_cnt = scalar(split('\t', $geno_lines[0])) - 1;
608 else
610 $self->genotype_file_name($c, $selection_pop_id);
611 my $geno_file = $c->stash->{genotype_file_name};
612 my @geno_lines = read_file($geno_file);
613 $markers_cnt= scalar(split ('\t', $geno_lines[0])) - 1;
617 return $markers_cnt;
622 sub project_description {
623 my ($self, $c, $pr_id) = @_;
625 $c->stash->{pop_id} = $pr_id;
626 $c->stash->{uploaded_reference} = 1 if ($pr_id =~ /uploaded/);
628 my $protocol = $c->config->{default_genotyping_protocol};
629 $protocol = 'N/A' if !$protocol;
631 if(!$c->stash->{uploaded_reference}) {
632 my $pr_rs = $c->model('solGS::solGS')->project_details($pr_id);
634 while (my $row = $pr_rs->next)
636 $c->stash(project_id => $row->id,
637 project_name => $row->name,
638 project_desc => $row->description
642 $self->get_project_owners($c, $pr_id);
643 $c->stash->{owner} = $c->stash->{project_owners};
646 else
648 $c->stash->{model_id} = $pr_id;
649 $self->uploaded_population_summary($c, $pr_id);
652 $self->filtered_training_genotype_file($c);
653 my $filtered_geno_file = $c->stash->{filtered_training_genotype_file};
655 my $markers_no;
656 my @geno_lines;
658 if (-s $filtered_geno_file) {
659 @geno_lines = read_file($filtered_geno_file);
660 $markers_no = scalar(split('\t', $geno_lines[0])) - 1;
662 else
664 $self->genotype_file($c);
665 my $geno_file = $c->stash->{genotype_file};
666 @geno_lines = read_file($geno_file);
667 $markers_no = scalar(split ('\t', $geno_lines[0])) - 1;
670 $self->trait_phenodata_file($c);
671 my $trait_pheno_file = $c->stash->{trait_phenodata_file};
672 my @trait_pheno_lines = read_file($trait_pheno_file) if $trait_pheno_file;
674 my $stocks_no = @trait_pheno_lines ? scalar(@trait_pheno_lines) - 1 : scalar(@geno_lines) - 1;
676 $self->traits_acronym_file($c);
677 my $traits_file = $c->stash->{traits_acronym_file};
678 my @lines = read_file($traits_file);
679 my $traits_no = scalar(@lines) - 1;
681 $c->stash(markers_no => $markers_no,
682 traits_no => $traits_no,
683 stocks_no => $stocks_no,
684 protocol => $protocol,
690 sub selection_trait :Path('/solgs/selection/') Args(5) {
691 my ($self, $c, $selection_pop_id,
692 $model_key, $training_pop_id,
693 $trait_key, $trait_id) = @_;
695 $self->get_trait_details($c, $trait_id);
696 $c->stash->{training_pop_id} = $training_pop_id;
697 $c->stash->{selection_pop_id} = $selection_pop_id;
698 $c->stash->{data_set_type} = 'single population';
700 if ($training_pop_id =~ /uploaded/)
702 $self->uploaded_population_summary($c, $training_pop_id);
703 $c->stash->{training_pop_id} = $c->stash->{project_id};
704 $c->stash->{training_pop_name} = $c->stash->{project_name};
705 $c->stash->{training_pop_desc} = $c->stash->{project_desc};
706 $c->stash->{training_pop_owner} = $c->stash->{owner};
708 else
710 $self->get_project_details($c, $training_pop_id);
711 $c->stash->{training_pop_id} = $c->stash->{project_id};
712 $c->stash->{training_pop_name} = $c->stash->{project_name};
713 $c->stash->{training_pop_desc} = $c->stash->{project_desc};
715 $self->get_project_owners($c, $training_pop_id);
716 $c->stash->{training_pop_owner} = $c->stash->{project_owners};
719 if ($selection_pop_id =~ /uploaded/)
721 $self->uploaded_population_summary($c, $selection_pop_id);
722 $c->stash->{selection_pop_id} = $c->stash->{project_id};
723 $c->stash->{selection_pop_name} = $c->stash->{project_name};
724 $c->stash->{selection_pop_desc} = $c->stash->{project_desc};
725 $c->stash->{selection_pop_owner} = $c->stash->{owner};
727 else
729 $self->get_project_details($c, $selection_pop_id);
730 $c->stash->{selection_pop_id} = $c->stash->{project_id};
731 $c->stash->{selection_pop_name} = $c->stash->{project_name};
732 $c->stash->{selection_pop_desc} = $c->stash->{project_desc};
734 $self->get_project_owners($c, $selection_pop_id);
735 $c->stash->{selection_pop_owner} = $c->stash->{project_owners};
738 my $tr_pop_mr_cnt = $self->get_markers_count($c, {'training_pop' => 1, 'training_pop_id' => $training_pop_id});
739 my $sel_pop_mr_cnt = $self->get_markers_count($c, {'selection_pop' => 1, 'selection_pop_id' => $selection_pop_id});
741 $c->stash->{training_markers_cnt} = $tr_pop_mr_cnt;
742 $c->stash->{selection_markers_cnt} = $sel_pop_mr_cnt;
744 my $protocol = $c->config->{default_genotyping_protocol};
745 $protocol = 'N/A' if !$protocol;
746 $c->stash->{protocol} = $protocol;
748 my $identifier = $training_pop_id . '_' . $selection_pop_id;
749 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
750 my $gebvs_file = $c->stash->{prediction_pop_gebvs_file};
752 my @stock_rows = read_file($gebvs_file);
753 $c->stash->{selection_stocks_cnt} = scalar(@stock_rows) - 1;
755 $self->top_blups($c, $gebvs_file);
757 $c->stash->{blups_download_url} = qq | <a href="/solgs/download/prediction/model/$training_pop_id/prediction/$selection_pop_id/$trait_id">Download all GEBVs</a>|;
759 $c->stash->{template} = $self->template('/population/selection_trait.mas');
764 sub build_single_trait_model {
765 my ($self, $c) = @_;
767 my $trait_id = $c->stash->{trait_id};
768 $self->get_trait_details($c, $trait_id);
770 $self->get_rrblup_output($c);
775 sub trait :Path('/solgs/trait') Args(3) {
776 my ($self, $c, $trait_id, $key, $pop_id) = @_;
778 my $ajaxredirect = $c->req->param('source');
779 $c->stash->{ajax_request} = $ajaxredirect;
781 if ($pop_id && $trait_id)
783 $c->stash->{pop_id} = $pop_id;
784 $c->stash->{trait_id} = $trait_id;
786 $self->build_single_trait_model($c);
788 $self->gs_files($c);
790 unless ($ajaxredirect eq 'heritability')
792 my $script_error = $c->stash->{script_error};
794 if ($script_error)
796 my $trait_name = $c->stash->{trait_name};
797 $c->stash->{message} = "$script_error can't create a prediction model for <b>$trait_name</b>.
798 There is a problem with the trait dataset.";
800 $c->stash->{template} = "/generic_message.mas";
802 else
804 $self->traits_acronym_file($c);
805 my $acronym_file = $c->stash->{traits_acronym_file};
807 if (!-e $acronym_file || !-s $acronym_file)
809 $self->get_all_traits($c);
812 $self->project_description($c, $pop_id);
814 $self->trait_phenotype_stat($c);
816 $self->get_project_owners($c, $pop_id);
817 $c->stash->{owner} = $c->stash->{project_owners};
819 $c->stash->{template} = $self->template("/population/trait.mas");
824 if ($ajaxredirect)
826 my $trait_abbr = $c->stash->{trait_abbr};
827 my $cache_dir = $c->stash->{solgs_cache_dir};
828 my $gebv_file = "gebv_kinship_${trait_abbr}_${pop_id}";
829 $gebv_file = $self->grep_file($cache_dir, $gebv_file);
831 my $ret->{status} = 'failed';
833 if (-s $gebv_file)
835 $ret->{status} = 'success';
838 $ret = to_json($ret);
840 $c->res->content_type('application/json');
841 $c->res->body($ret);
848 sub gs_files {
849 my ($self, $c) = @_;
851 $self->output_files($c);
852 #$self->input_files($c);
853 $self->model_accuracy($c);
854 $self->blups_file($c);
855 $self->download_urls($c);
856 $self->top_markers($c);
857 $self->model_parameters($c);
862 sub input_files {
863 my ($self, $c) = @_;
865 $self->genotype_file($c);
866 $self->phenotype_file($c);
867 $self->formatted_phenotype_file($c);
869 my $pred_pop_id = $c->stash->{prediction_pop_id} ||$c->stash->{selection_pop_id} ;
870 my ($prediction_population_file, $filtered_pred_geno_file);
872 if ($pred_pop_id)
874 $prediction_population_file = $c->stash->{prediction_population_file};
877 my $formatted_phenotype_file = $c->stash->{formatted_phenotype_file};
879 my $pheno_file = $c->stash->{phenotype_file};
880 my $geno_file = $c->stash->{genotype_file};
881 my $traits_file = $c->stash->{selected_traits_file};
882 my $trait_file = $c->stash->{trait_file};
883 my $pop_id = $c->stash->{pop_id};
885 no warnings 'uninitialized';
887 my $input_files = join ("\t",
888 $pheno_file,
889 $formatted_phenotype_file,
890 $geno_file,
891 $traits_file,
892 $trait_file,
893 $prediction_population_file,
896 my $name = "input_files_${pop_id}";
897 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
898 my $tempfile = $self->create_tempfile($temp_dir, $name);
899 write_file($tempfile, $input_files);
900 $c->stash->{input_files} = $tempfile;
905 sub output_files {
906 my ($self, $c) = @_;
908 my $pop_id = $c->stash->{pop_id};
909 my $trait = $c->stash->{trait_abbr};
910 my $trait_id = $c->stash->{trait_id};
912 $self->gebv_marker_file($c);
913 $self->gebv_kinship_file($c);
914 $self->validation_file($c);
915 $self->trait_phenodata_file($c);
916 $self->variance_components_file($c);
917 $self->relationship_matrix_file($c);
918 $self->filtered_training_genotype_file($c);
920 $self->filtered_training_genotype_file($c);
922 my $prediction_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id};
923 if (!$pop_id) {$pop_id = $c->stash->{model_id};}
925 no warnings 'uninitialized';
927 #$prediction_id = "uploaded_${prediction_id" if $c->stash->{uploaded_prediction};
929 my $pred_pop_gebvs_file;
931 if ($prediction_id)
933 my $identifier = $pop_id . '_' . $prediction_id;
934 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
935 $pred_pop_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
938 my $file_list = join ("\t",
939 $c->stash->{gebv_kinship_file},
940 $c->stash->{gebv_marker_file},
941 $c->stash->{validation_file},
942 $c->stash->{trait_phenodata_file},
943 $c->stash->{selected_traits_gebv_file},
944 $c->stash->{variance_components_file},
945 $c->stash->{relationship_matrix_file},
946 $c->stash->{filtered_training_genotype_file},
947 $pred_pop_gebvs_file
950 my $name = "output_files_${trait}_$pop_id";
951 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
952 my $tempfile = $self->create_tempfile($temp_dir, $name);
953 write_file($tempfile, $file_list);
955 $c->stash->{output_files} = $tempfile;
960 sub gebv_marker_file {
961 my ($self, $c) = @_;
963 my $pop_id = $c->stash->{pop_id};
964 my $trait = $c->stash->{trait_abbr};
966 no warnings 'uninitialized';
968 my $data_set_type = $c->stash->{data_set_type};
970 my $cache_data;
972 if ($data_set_type =~ /combined populations/)
974 my $combo_identifier = $c->stash->{combo_pops_id};
976 $cache_data = {key => 'gebv_marker_combined_pops_'. $trait . '_' . $combo_identifier,
977 file => 'gebv_marker_'. $trait . '_' . $combo_identifier . '_combined_pops',
978 stash_key => 'gebv_marker_file'
981 else
984 $cache_data = {key => 'gebv_marker_' . $pop_id . '_'. $trait,
985 file => 'gebv_marker_' . $trait . '_' . $pop_id,
986 stash_key => 'gebv_marker_file'
990 $self->cache_file($c, $cache_data);
995 sub variance_components_file {
996 my ($self, $c) = @_;
998 my $pop_id = $c->stash->{pop_id};
999 my $trait = $c->stash->{trait_abbr};
1001 my $data_set_type = $c->stash->{data_set_type};
1003 my $cache_data;
1005 no warnings 'uninitialized';
1007 if ($data_set_type =~ /combined populations/)
1009 my $combo_identifier = $c->stash->{combo_pops_id};
1011 $cache_data = {key => 'variance_components_combined_pops_'. $trait . "_". $combo_identifier,
1012 file => 'variance_components_'. $trait . '_' . $combo_identifier. '_combined_pops',
1013 stash_key => 'variance_components_file'
1016 else
1018 $cache_data = {key => 'variance_components_' . $pop_id . '_'. $trait,
1019 file => 'variance_components_' . $trait . '_' . $pop_id,
1020 stash_key => 'variance_components_file'
1024 $self->cache_file($c, $cache_data);
1028 sub trait_phenodata_file {
1029 my ($self, $c) = @_;
1031 my $pop_id = $c->stash->{pop_id};
1032 my $trait = $c->stash->{trait_abbr};
1033 my $data_set_type = $c->stash->{data_set_type};
1035 my $cache_data;
1037 no warnings 'uninitialized';
1039 if ($data_set_type =~ /combined populations/)
1041 my $combo_identifier = $c->stash->{combo_pops_id};
1042 $cache_data = {key => 'phenotype_trait_combined_pops_'. $trait . "_". $combo_identifier,
1043 file => 'phenotype_trait_'. $trait . '_' . $combo_identifier. '_combined_pops',
1044 stash_key => 'trait_phenodata_file'
1047 else
1049 $cache_data = {key => 'phenotype_' . $pop_id . '_'. $trait,
1050 file => 'phenotype_trait_' . $trait . '_' . $pop_id,
1051 stash_key => 'trait_phenodata_file'
1055 $self->cache_file($c, $cache_data);
1059 sub filtered_training_genotype_file {
1060 my ($self, $c) = @_;
1062 my $pop_id = $c->stash->{pop_id};
1063 $pop_id = $c->{stash}->{combo_pops_id} if !$pop_id;
1065 my $cache_data = { key => 'filtered_genotype_data_' . $pop_id,
1066 file => 'filtered_genotype_data_' . $pop_id . '.txt',
1067 stash_key => 'filtered_training_genotype_file'
1070 $self->cache_file($c, $cache_data);
1074 sub filtered_selection_genotype_file {
1075 my ($self, $c) = @_;
1077 my $pop_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id};
1079 my $cache_data = { key => 'filtered_genotype_data_' . $pop_id,
1080 file => 'filtered_genotype_data_' . $pop_id . '.txt',
1081 stash_key => 'filtered_selection_genotype_file'
1084 $self->cache_file($c, $cache_data);
1088 sub formatted_phenotype_file {
1089 my ($self, $c) = @_;
1091 my $pop_id = $c->stash->{pop_id};
1092 $pop_id = $c->{stash}->{combo_pops_id} if !$pop_id;
1094 my $cache_data = { key => 'formatted_phenotype_data_' . $pop_id,
1095 file => 'formatted_phenotype_data_' . $pop_id,
1096 stash_key => 'formatted_phenotype_file'
1099 $self->cache_file($c, $cache_data);
1103 sub phenotype_file_name {
1104 my ($self, $c, $pop_id) = @_;
1106 #my $pop_id = $c->stash->{pop_id};
1107 #$pop_id = $c->{stash}->{combo_pops_id} if !$pop_id;
1109 if ($pop_id =~ /uploaded/)
1111 my $tmp_dir = $c->stash->{solgs_prediction_upload_dir};
1112 my $file = catfile($tmp_dir, 'phenotype_data_' . $pop_id . '.txt');
1113 $c->stash->{phenotype_file_name} = $file;
1115 else
1118 my $cache_data = { key => 'phenotype_data_' . $pop_id,
1119 file => 'phenotype_data_' . $pop_id . '.txt',
1120 stash_key => 'phenotype_file_name'
1123 $self->cache_file($c, $cache_data);
1128 sub genotype_file_name {
1129 my ($self, $c, $pop_id) = @_;
1131 # my $pop_id = $c->stash->{pop_id};
1132 # $pop_id = $c->stash->{combo_pops_id} if !$pop_id;
1133 # my $pred_pop_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id} ;
1135 if ($pop_id =~ /uploaded/)
1137 my $tmp_dir = $c->stash->{solgs_prediction_upload_dir};
1138 my $file = catfile($tmp_dir, 'genotype_data_' . $pop_id . '.txt');
1139 $c->stash->{genotype_file_name} = $file;
1141 else
1143 my $cache_data = { key => 'genotype_data_' . $pop_id,
1144 file => 'genotype_data_' . $pop_id . '.txt',
1145 stash_key => 'genotype_file_name'
1148 $self->cache_file($c, $cache_data);
1153 sub gebv_kinship_file {
1154 my ($self, $c) = @_;
1156 my $pop_id = $c->stash->{pop_id};
1157 my $trait = $c->stash->{trait_abbr};
1158 my $data_set_type = $c->stash->{data_set_type};
1160 my $cache_data;
1162 no warnings 'uninitialized';
1164 if ($data_set_type =~ /combined populations/)
1166 my $combo_identifier = $c->stash->{combo_pops_id};
1167 $cache_data = {key => 'gebv_kinship_combined_pops_'. $combo_identifier . "_" . $trait,
1168 file => 'gebv_kinship_'. $trait . '_' . $combo_identifier. '_combined_pops',
1169 stash_key => 'gebv_kinship_file'
1173 else
1176 $cache_data = {key => 'gebv_kinship_' . $pop_id . '_'. $trait,
1177 file => 'gebv_kinship_' . $trait . '_' . $pop_id,
1178 stash_key => 'gebv_kinship_file'
1182 $self->cache_file($c, $cache_data);
1187 sub relationship_matrix_file {
1188 my ($self, $c) = @_;
1190 my $pop_id = $c->stash->{pop_id};
1191 my $data_set_type = $c->stash->{data_set_type};
1193 my $cache_data;
1195 no warnings 'uninitialized';
1197 if ($data_set_type =~ /combined populations/)
1199 my $combo_identifier = $c->stash->{combo_pops_id};
1200 $cache_data = {key => 'relationship_matrix_combined_pops_'. $combo_identifier,
1201 file => 'relationship_matrix_combined_pops_' . $combo_identifier,
1202 stash_key => 'relationship_matrix_file'
1206 else
1209 $cache_data = {key => 'relationship_matrix_' . $pop_id,
1210 file => 'relationship_matrix_' . $pop_id,
1211 stash_key => 'relationship_matrix_file'
1215 $self->cache_file($c, $cache_data);
1220 sub blups_file {
1221 my ($self, $c) = @_;
1223 my $blups_file = $c->stash->{gebv_kinship_file};
1224 $self->top_blups($c, $blups_file);
1228 sub download_blups :Path('/solgs/download/blups/pop') Args(3) {
1229 my ($self, $c, $pop_id, $trait, $trait_id) = @_;
1231 $self->get_trait_details($c, $trait_id);
1232 my $trait_abbr = $c->stash->{trait_abbr};
1234 my $dir = $c->stash->{solgs_cache_dir};
1235 my $blup_exp = "gebv_kinship_${trait_abbr}_${pop_id}";
1236 my $blups_file = $self->grep_file($dir, $blup_exp);
1238 unless (!-e $blups_file || -s $blups_file == 0)
1240 my @blups = map { [ split(/\t/) ] } read_file($blups_file);
1242 $c->res->content_type("text/plain");
1243 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @blups);
1249 sub download_marker_effects :Path('/solgs/download/marker/pop') Args(3) {
1250 my ($self, $c, $pop_id, $trait, $trait_id) = @_;
1252 $self->get_trait_details($c, $trait_id);
1253 my $trait_abbr = $c->stash->{trait_abbr};
1255 my $dir = $c->stash->{solgs_cache_dir};
1256 my $marker_exp = "gebv_marker_${trait_abbr}_${pop_id}";
1257 my $markers_file = $self->grep_file($dir, $marker_exp);
1259 unless (!-e $markers_file || -s $markers_file == 0)
1261 my @effects = map { [ split(/\t/) ] } read_file($markers_file);
1263 $c->res->content_type("text/plain");
1264 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @effects);
1270 sub download_urls {
1271 my ($self, $c) = @_;
1272 my $data_set_type = $c->stash->{data_set_type};
1273 my $pop_id;
1275 no warnings 'uninitialized';
1277 if ($data_set_type =~ /combined populations/)
1279 $pop_id = $c->stash->{combo_pops_id};
1281 else
1283 $pop_id = $c->stash->{pop_id};
1286 my $trait_id = $c->stash->{trait_id};
1287 my $ranked_genos_file = $c->stash->{selection_index_file};
1289 if ($ranked_genos_file)
1291 ($ranked_genos_file) = fileparse($ranked_genos_file);
1294 my $blups_url = qq | <a href="/solgs/download/blups/pop/$pop_id/trait/$trait_id">Download all GEBVs</a> |;
1295 my $marker_url = qq | <a href="/solgs/download/marker/pop/$pop_id/trait/$trait_id">Download all marker effects</a> |;
1296 my $validation_url = qq | <a href="/solgs/download/validation/pop/$pop_id/trait/$trait_id">Download model accuracy report</a> |;
1297 my $ranked_genotypes_url = qq | <a href="/solgs/download/ranked/genotypes/pop/$pop_id/$ranked_genos_file">Download selection indices</a> |;
1299 $c->stash(blups_download_url => $blups_url,
1300 marker_effects_download_url => $marker_url,
1301 validation_download_url => $validation_url,
1302 ranked_genotypes_download_url => $ranked_genotypes_url,
1307 sub top_blups {
1308 my ($self, $c, $blups_file) = @_;
1310 my $blups = $self->convert_to_arrayref_of_arrays($c, $blups_file);
1312 my @top_blups = @$blups[0..9];
1314 $c->stash->{top_blups} = \@top_blups;
1318 sub top_markers {
1319 my ($self, $c) = @_;
1321 my $markers_file = $c->stash->{gebv_marker_file};
1323 my $markers = $self->convert_to_arrayref_of_arrays($c, $markers_file);
1325 my @top_markers = @$markers[0..9];
1327 $c->stash->{top_marker_effects} = \@top_markers;
1331 sub validation_file {
1332 my ($self, $c) = @_;
1334 my $pop_id = $c->stash->{pop_id};
1335 my $trait = $c->stash->{trait_abbr};
1337 my $data_set_type = $c->stash->{data_set_type};
1339 my $cache_data;
1341 no warnings 'uninitialized';
1343 if ($data_set_type =~ /combined populations/)
1345 my $combo_identifier = $c->stash->{combo_pops_id};
1346 $cache_data = {key => 'cross_validation_combined_pops_'. $trait . "_${combo_identifier}",
1347 file => 'cross_validation_'. $trait . '_' . $combo_identifier . '_combined_pops' ,
1348 stash_key => 'validation_file'
1351 else
1354 $cache_data = {key => 'cross_validation_' . $pop_id . '_' . $trait,
1355 file => 'cross_validation_' . $trait . '_' . $pop_id,
1356 stash_key => 'validation_file'
1360 $self->cache_file($c, $cache_data);
1364 sub combined_gebvs_file {
1365 my ($self, $c, $identifier) = @_;
1367 my $pop_id = $c->stash->{pop_id};
1369 my $cache_data = {key => 'selected_traits_gebv_' . $pop_id . '_' . $identifier,
1370 file => 'selected_traits_gebv_' . $pop_id . '_' . $identifier,
1371 stash_key => 'selected_traits_gebv_file'
1374 $self->cache_file($c, $cache_data);
1379 sub download_validation :Path('/solgs/download/validation/pop') Args(3) {
1380 my ($self, $c, $pop_id, $trait, $trait_id) = @_;
1382 $self->get_trait_details($c, $trait_id);
1383 my $trait_abbr = $c->stash->{trait_abbr};
1385 my $dir = $c->stash->{solgs_cache_dir};
1386 my $val_exp = "cross_validation_${trait_abbr}_${pop_id}";
1387 my $validation_file = $self->grep_file($dir, $val_exp);
1389 unless (!-e $validation_file || -s $validation_file == 0)
1391 my @validation = map { [ split(/\t/) ] } read_file($validation_file);
1393 $c->res->content_type("text/plain");
1394 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @validation);
1400 sub predict_selection_pop_single_trait {
1401 my ($self, $c) = @_;
1403 if ($c->stash->{data_set_type} =~ /single population/)
1405 $self->predict_selection_pop_single_pop_model($c)
1407 else
1409 $self->predict_selection_pop_combined_pops_model($c);
1416 sub predict_selection_pop_multi_traits {
1417 my ($self, $c) = @_;
1419 my $data_set_type = $c->stash->{data_set_type};
1420 my $training_pop_id = $c->stash->{training_pop_id};
1421 my $selection_pop_id = $c->stash->{selection_pop_id};
1423 $c->stash->{pop_id} = $training_pop_id;
1424 $self->traits_with_valid_models($c);
1425 my @traits_with_valid_models = @{$c->stash->{traits_with_valid_models}};
1427 foreach my $trait_abbr (@traits_with_valid_models)
1429 $c->stash->{trait_abbr} = $trait_abbr;
1430 $self->get_trait_details_of_trait_abbr($c);
1431 $self->predict_selection_pop_single_trait($c);
1437 sub predict_selection_pop_single_pop_model {
1438 my ($self, $c) = @_;
1440 my $trait_id = $c->stash->{trait_id};
1441 my $training_pop_id = $c->stash->{training_pop_id};
1442 my $prediction_pop_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id};
1444 $self->get_trait_details($c, $trait_id);
1445 my $trait_abbr = $c->stash->{trait_abbr};
1447 my $identifier = $training_pop_id . '_' . $prediction_pop_id;
1448 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
1450 my $prediction_pop_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
1452 if (!-s $prediction_pop_gebvs_file)
1454 my $dir = $c->stash->{solgs_cache_dir};
1456 my $exp = "phenotype_data_${training_pop_id}";
1457 my $pheno_file = $self->grep_file($dir, $exp);
1459 $exp = "genotype_data_${training_pop_id}";
1460 my $geno_file = $self->grep_file($dir, $exp);
1462 $c->stash->{pheno_file} = $pheno_file;
1463 $c->stash->{geno_file} = $geno_file;
1465 $self->prediction_population_file($c, $prediction_pop_id);
1466 $self->get_rrblup_output($c);
1472 sub predict_selection_pop_combined_pops_model {
1473 my ($self, $c) = @_;
1475 my $data_set_type = $c->stash->{data_set_type};
1476 my $combo_pops_id = $c->stash->{combo_pops_id};
1477 my $model_id = $c->stash->{model_id};
1478 my $prediction_pop_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id};
1479 my $trait_id = $c->stash->{trait_id};
1481 $self->get_trait_details($c, $trait_id);
1482 my $trait_abbr = $c->stash->{trait_abbr};
1484 my $identifier = $combo_pops_id . '_' . $prediction_pop_id;
1485 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
1487 my $prediction_pop_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
1489 if (!-s $prediction_pop_gebvs_file)
1491 $self->cache_combined_pops_data($c);
1493 $self->prediction_population_file($c, $prediction_pop_id);
1495 $self->get_rrblup_output($c);
1501 sub selection_prediction :Path('/solgs/model') Args(3) {
1502 my ($self, $c, $training_pop_id, $pop, $selection_pop_id) = @_;
1504 my $referer = $c->req->referer;
1505 my $path = $c->req->path;
1506 my $base = $c->req->base;
1507 $referer =~ s/$base//;
1509 $c->stash->{training_pop_id} = $training_pop_id;
1510 $c->stash->{model_id} = $training_pop_id;
1511 $c->stash->{pop_id} = $training_pop_id;
1512 $c->stash->{prediction_pop_id} = $selection_pop_id;
1513 $c->stash->{selection_pop_id} = $selection_pop_id;
1515 if ($referer =~ /solgs\/model\/combined\/populations\//)
1517 my ($combo_pops_id, $trait_id) = $referer =~ m/(\d+)/g;
1519 $c->stash->{data_set_type} = "combined populations";
1520 $c->stash->{combo_pops_id} = $combo_pops_id;
1521 $c->stash->{trait_id} = $trait_id;
1523 $self->predict_selection_pop_combined_pops_model($c);
1525 $self->combined_pops_summary($c);
1526 $self->trait_phenotype_stat($c);
1527 $self->gs_files($c);
1529 $c->res->redirect("/solgs/model/combined/populations/$combo_pops_id/trait/$trait_id");
1530 $c->detach();
1532 elsif ($referer =~ /solgs\/trait\//)
1534 my ($trait_id, $pop_id) = $referer =~ m/(\d+)/g;
1536 $c->stash->{data_set_type} = "single population";
1537 $c->stash->{trait_id} = $trait_id;
1539 $self->predict_selection_pop_single_pop_model($c);
1541 $self->trait_phenotype_stat($c);
1542 $self->gs_files($c);
1544 $c->res->redirect("/solgs/trait/$trait_id/population/$training_pop_id");
1545 $c->detach();
1547 elsif ($referer =~ /solgs\/models\/combined\/trials/)
1549 $c->stash->{data_set_type} = "combined populations";
1550 $c->stash->{combo_pops_id} = $training_pop_id;
1552 $self->traits_with_valid_models($c);
1553 my @traits_abbrs = @ {$c->stash->{traits_with_valid_models}};
1555 foreach my $trait_abbr (@traits_abbrs)
1557 $c->stash->{trait_abbr} = $trait_abbr;
1558 $self->get_trait_details_of_trait_abbr($c);
1559 $self->predict_selection_pop_combined_pops_model($c);
1562 $c->res->redirect("/solgs/models/combined/trials/$training_pop_id");
1563 $c->detach();
1565 elsif ($referer =~ /solgs\/traits\/all\/population\//)
1567 $c->stash->{data_set_type} = "single population";
1569 $self->predict_selection_pop_multi_traits($c);
1571 $c->res->redirect("/solgs/traits/all/population/$training_pop_id");
1572 $c->detach();
1578 sub prediction_pop_gebvs_file {
1579 my ($self, $c, $identifier, $trait_id) = @_;
1581 my $cache_data = {key => 'prediction_pop_gebvs_' . $identifier . '_' . $trait_id,
1582 file => 'prediction_pop_gebvs_' . $identifier . '_' . $trait_id,
1583 stash_key => 'prediction_pop_gebvs_file'
1586 $self->cache_file($c, $cache_data);
1591 sub list_predicted_selection_pops {
1592 my ($self, $c, $model_id) = @_;
1594 my $dir = $c->stash->{solgs_cache_dir};
1596 opendir my $dh, $dir or die "can't open $dir: $!\n";
1598 my @files = grep { /prediction_pop_gebvs_${model_id}_/ && -f "$dir/$_" }
1599 readdir($dh);
1601 closedir $dh;
1603 my @pred_pops;
1605 foreach (@files)
1608 unless ($_ =~ /uploaded/) {
1609 my ($model_id2, $pred_pop_id, $trait_id) = $_ =~ m/\d+/g;
1611 push @pred_pops, $pred_pop_id;
1615 @pred_pops = uniq(@pred_pops);
1617 $c->stash->{list_of_predicted_selection_pops} = \@pred_pops;
1622 sub download_prediction_GEBVs :Path('/solgs/download/prediction/model') Args(4) {
1623 my ($self, $c, $pop_id, $prediction, $prediction_id, $trait_id) = @_;
1625 $self->get_trait_details($c, $trait_id);
1626 $c->stash->{pop_id} = $pop_id;
1628 my $identifier = $pop_id . "_" . $prediction_id;
1629 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
1630 my $prediction_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
1632 unless (!-e $prediction_gebvs_file || -s $prediction_gebvs_file == 0)
1634 my @prediction_gebvs = map { [ split(/\t/) ] } read_file($prediction_gebvs_file);
1636 $c->res->content_type("text/plain");
1637 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @prediction_gebvs);
1643 sub prediction_pop_analyzed_traits {
1644 my ($self, $c, $training_pop_id, $prediction_pop_id) = @_;
1646 my $dir = $c->stash->{solgs_cache_dir};
1647 my @pred_files;
1649 opendir my $dh, $dir or die "can't open $dir: $!\n";
1651 no warnings 'uninitialized';
1653 my $prediction_is_uploaded = $c->stash->{uploaded_prediction};
1655 #$prediction_pop_id = "uploaded_${prediction_pop_id}" if $prediction_is_uploaded;
1657 if ($training_pop_id !~ /$prediction_pop_id/)
1659 my @files = grep { /prediction_pop_gebvs_${training_pop_id}_${prediction_pop_id}/ && -s "$dir/$_" > 0 }
1660 readdir($dh);
1662 closedir $dh;
1664 my @trait_ids;
1666 if ($files[0])
1668 my @copy_files = @files;
1670 @trait_ids = map { s/prediction_pop_gebvs_${training_pop_id}_${prediction_pop_id}_//g ? $_ : 0} @copy_files;
1672 my @traits = ();
1673 if(@trait_ids)
1675 foreach my $trait_id (@trait_ids)
1677 $trait_id =~ s/s+//g;
1678 $self->get_trait_details($c, $trait_id);
1679 push @traits, $c->stash->{trait_abbr};
1683 $c->stash->{prediction_pop_analyzed_traits} = \@traits;
1684 $c->stash->{prediction_pop_analyzed_traits_ids} = \@trait_ids;
1685 $c->stash->{prediction_pop_analyzed_traits_files} = \@files;
1692 sub download_prediction_urls {
1693 my ($self, $c, $training_pop_id, $prediction_pop_id) = @_;
1695 my $selection_traits_ids;
1696 my $selection_traits_files;
1697 my $download_url;# = $c->stash->{download_prediction};
1698 my $model_tr_id = $c->stash->{trait_id};
1700 my $page = $c->req->referer;
1701 my $base = $c->req->base;
1703 my $data_set_type = 'combined populations' if $page =~ /combined/;
1705 if ( $base !~ /localhost/)
1707 $base =~ s/:\d+//;
1708 $base =~ s/http\w?/https/;
1711 $page =~ s/$base//;
1713 no warnings 'uninitialized';
1715 if ($prediction_pop_id)
1717 $self->prediction_pop_analyzed_traits($c, $training_pop_id, $prediction_pop_id);
1718 $selection_traits_ids = $c->stash->{prediction_pop_analyzed_traits_ids};
1719 $selection_traits_files = $c->stash->{prediction_pop_analyzed_traits_files};
1722 if ($page =~ /solgs\/model\/combined\/populations\// )
1724 ($model_tr_id) = $page =~ /(\d+)$/;
1725 $model_tr_id =~ s/s+//g;
1728 if ($page =~ /solgs\/trait\// )
1730 $model_tr_id = (split '/', $page)[2];
1733 if ($page =~ /(\/uploaded\/prediction\/)/ && $page !~ /(\solgs\/traits\/all)/)
1735 ($model_tr_id) = $page =~ /(\d+)$/;
1736 $model_tr_id =~ s/s+//g;
1739 my ($trait_is_predicted) = grep {/$model_tr_id/ } @$selection_traits_ids;
1740 my @selection_traits_ids = uniq(@$selection_traits_ids);
1742 foreach my $trait_id (@selection_traits_ids)
1744 $trait_id =~ s/s+//g;
1745 $self->get_trait_details($c, $trait_id);
1747 my $trait_abbr = $c->stash->{trait_abbr};
1748 my $trait_name = $c->stash->{trait_name};
1751 if ($page =~ /solgs\/traits\/all\/|solgs\/models\/combined\//)
1753 $model_tr_id = $trait_id;
1754 $download_url .= " | " if $download_url;
1757 if ($selection_traits_files->[0] =~ $prediction_pop_id && $trait_id == $model_tr_id)
1759 if ($data_set_type =~ /combined populations/)
1761 $download_url .= qq |<a href="/solgs/selection/$prediction_pop_id/model/combined/$training_pop_id/trait/$trait_id">$trait_abbr</a> |;
1763 else
1765 $download_url .= qq |<a href="/solgs/selection/$prediction_pop_id/model/$training_pop_id/trait/$trait_id">$trait_abbr</a> |;
1770 if ($download_url)
1772 $c->stash->{download_prediction} = $download_url;
1774 else
1776 $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> |;
1778 $c->stash->{download_prediction} = undef if $c->stash->{uploaded_prediction};
1784 sub model_accuracy {
1785 my ($self, $c) = @_;
1786 my $file = $c->stash->{validation_file};
1787 my @report =();
1789 if ( !-e $file) { @report = (["Validation file doesn't exist.", "None"]);}
1790 if ( -s $file == 0) { @report = (["There is no cross-validation output report.", "None"]);}
1792 if (!@report)
1794 @report = map { [ split(/\t/, $_) ]} read_file($file);
1797 shift(@report); #add condition
1799 $c->stash->{accuracy_report} = \@report;
1804 sub model_parameters {
1805 my ($self, $c) = @_;
1807 $self->variance_components_file($c);
1808 my $file = $c->stash->{variance_components_file};
1810 my @params = map { [ split(/\t/, $_) ]} read_file($file);
1812 shift(@params); #add condition
1814 $c->stash->{model_parameters} = \@params;
1819 sub solgs_details_trait :Path('/solgs/details/trait/') Args(1) {
1820 my ($self, $c, $trait_id) = @_;
1822 $trait_id = $c->req->param('trait_id') if !$trait_id;
1824 my $ret->{status} = undef;
1826 if ($trait_id)
1828 $self->get_trait_details($c, $trait_id);
1829 $ret->{name} = $c->stash->{trait_name};
1830 $ret->{def} = $c->stash->{trait_def};
1831 $ret->{abbr} = $c->stash->{trait_abbr};
1832 $ret->{id} = $c->stash->{trait_id};
1833 $ret->{status} = 1;
1836 $ret = to_json($ret);
1838 $c->res->content_type('application/json');
1839 $c->res->body($ret);
1844 sub get_trait_details {
1845 my ($self, $c, $trait) = @_;
1847 $trait = $c->stash->{trait_id} if !$trait;
1849 die "Can't get trait details with out trait id or name: $!\n" if !$trait;
1851 my ($trait_name, $trait_def, $trait_id, $trait_abbr);
1853 if ($trait =~ /^\d+$/)
1855 $trait = $c->model('solGS::solGS')->trait_name($trait);
1858 if ($trait)
1860 my $rs = $c->model('solGS::solGS')->trait_details($trait);
1862 while (my $row = $rs->next)
1864 $trait_id = $row->id;
1865 $trait_name = $row->name;
1866 $trait_def = $row->definition;
1867 $trait_abbr = $self->abbreviate_term($trait_name);
1871 my $abbr = $self->abbreviate_term($trait_name);
1873 $c->stash->{trait_id} = $trait_id;
1874 $c->stash->{trait_name} = $trait_name;
1875 $c->stash->{trait_def} = $trait_def;
1876 $c->stash->{trait_abbr} = $abbr;
1880 #creates and writes a list of GEBV files of
1881 #traits selected for ranking genotypes.
1882 sub get_gebv_files_of_traits {
1883 my ($self, $c) = @_;
1885 my $pop_id = $c->stash->{pop_id};
1886 $c->stash->{model_id} = $pop_id;
1887 my $pred_pop_id = $c->stash->{prediction_pop_id};
1889 my $dir = $c->stash->{solgs_cache_dir};
1891 my $gebv_files;
1892 my $valid_gebv_files;
1893 my $pred_gebv_files;
1895 if ($pred_pop_id && $pred_pop_id != $pop_id)
1897 $self->prediction_pop_analyzed_traits($c, $pop_id, $pred_pop_id);
1898 $pred_gebv_files = $c->stash->{prediction_pop_analyzed_traits_files};
1900 foreach (@$pred_gebv_files)
1902 my$gebv_file = catfile($dir, $_);
1903 $gebv_files .= $gebv_file;
1904 $gebv_files .= "\t" unless (@$pred_gebv_files[-1] eq $_);
1907 else
1909 $self->analyzed_traits($c);
1910 my @analyzed_traits_files = @{$c->stash->{analyzed_traits_files}};
1912 foreach my $tr_file (@analyzed_traits_files)
1914 $gebv_files .= $tr_file;
1915 $gebv_files .= "\t" unless ($analyzed_traits_files[-1] eq $tr_file);
1918 my @analyzed_valid_traits_files = @{$c->stash->{analyzed_valid_traits_files}};
1920 foreach my $tr_file (@analyzed_valid_traits_files)
1922 $valid_gebv_files .= $tr_file;
1923 $valid_gebv_files .= "\t" unless ($analyzed_valid_traits_files[-1] eq $tr_file);
1929 my $pred_file_suffix;
1930 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
1932 my $name = "gebv_files_of_traits_${pop_id}${pred_file_suffix}";
1933 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
1934 my $file = $self->create_tempfile($temp_dir, $name);
1936 write_file($file, $gebv_files);
1938 $c->stash->{gebv_files_of_traits} = $file;
1940 my $name2 = "gebv_files_of_valid_traits_${pop_id}${pred_file_suffix}";
1941 my $file2 = $self->create_tempfile($temp_dir, $name2);
1943 write_file($file2, $valid_gebv_files);
1945 $c->stash->{gebv_files_of_valid_traits} = $file2;
1950 sub gebv_rel_weights {
1951 my ($self, $c, $params, $pred_pop_id) = @_;
1953 my $pop_id = $c->stash->{pop_id};
1955 my $rel_wts = "trait" . "\t" . 'relative_weight' . "\n";
1956 foreach my $tr (keys %$params)
1958 my $wt = $params->{$tr};
1959 unless ($tr eq 'rank')
1961 $rel_wts .= $tr . "\t" . $wt;
1962 $rel_wts .= "\n";
1966 my $pred_file_suffix;
1967 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
1969 my $name = "rel_weights_${pop_id}${pred_file_suffix}";
1970 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
1971 my $file = $self->create_tempfile($temp_dir, $name);
1972 write_file($file, $rel_wts);
1974 $c->stash->{rel_weights_file} = $file;
1979 sub ranked_genotypes_file {
1980 my ($self, $c, $pred_pop_id) = @_;
1982 my $pop_id = $c->stash->{pop_id};
1984 my $pred_file_suffix;
1985 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
1987 my $name = "ranked_genotypes_${pop_id}${pred_file_suffix}";
1988 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
1989 my $file = $self->create_tempfile($temp_dir, $name);
1990 $c->stash->{ranked_genotypes_file} = $file;
1995 sub selection_index_file {
1996 my ($self, $c, $pred_pop_id) = @_;
1998 my $pop_id = $c->stash->{pop_id};
2000 my $pred_file_suffix;
2001 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
2003 my $name = "selection_index_${pop_id}${pred_file_suffix}";
2004 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
2005 my $file = $self->create_tempfile($temp_dir, $name);
2006 $c->stash->{selection_index_file} = $file;
2011 sub download_ranked_genotypes :Path('/solgs/download/ranked/genotypes/pop') Args(2) {
2012 my ($self, $c, $pop_id, $genotypes_file) = @_;
2014 $c->stash->{pop_id} = $pop_id;
2016 $genotypes_file = catfile($c->stash->{solgs_tempfiles_dir}, $genotypes_file);
2018 unless (!-e $genotypes_file || -s $genotypes_file == 0)
2020 my @ranks = map { [ split(/\t/) ] } read_file($genotypes_file);
2022 $c->res->content_type("text/plain");
2023 $c->res->body(join "", map { $_->[0] . "\t" . $_->[1] } @ranks);
2029 sub rank_genotypes : Private {
2030 my ($self, $c, $pred_pop_id) = @_;
2032 my $pop_id = $c->stash->{pop_id};
2033 $c->stash->{prediction_pop_id} = $pred_pop_id;
2035 my $input_files = join("\t",
2036 $c->stash->{rel_weights_file},
2037 $c->stash->{gebv_files_of_traits}
2040 $self->ranked_genotypes_file($c, $pred_pop_id);
2041 $self->selection_index_file($c, $pred_pop_id);
2043 my $output_files = join("\t",
2044 $c->stash->{ranked_genotypes_file},
2045 $c->stash->{selection_index_file}
2048 my $pred_file_suffix;
2049 $pred_file_suffix = '_' . $pred_pop_id if $pred_pop_id;
2051 my $name = "output_rank_genotypes_${pop_id}${pred_file_suffix}";
2052 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
2053 my $output_file = $self->create_tempfile($temp_dir, $name);
2054 write_file($output_file, $output_files);
2056 $name = "input_rank_genotypes_${pop_id}${pred_file_suffix}";
2057 my $input_file = $self->create_tempfile($temp_dir, $name);
2058 write_file($input_file, $input_files);
2060 $c->stash->{output_files} = $output_file;
2061 $c->stash->{input_files} = $input_file;
2062 $c->stash->{r_temp_file} = "rank-gebv-genotypes-${pop_id}${pred_file_suffix}";
2063 $c->stash->{r_script} = 'R/solGS/selection_index.r';
2065 $self->run_r_script($c);
2066 $self->download_urls($c);
2067 $self->get_top_10_selection_indices($c);
2071 sub get_top_10_selection_indices {
2072 my ($self, $c) = @_;
2074 my $si_file = $c->stash->{selection_index_file};
2076 my $si_data = $self->convert_to_arrayref_of_arrays($c, $si_file);
2077 my @top_genotypes = @$si_data[0..9];
2079 $c->stash->{top_10_selection_indices} = \@top_genotypes;
2083 sub convert_to_arrayref_of_arrays {
2084 my ($self, $c, $file) = @_;
2086 open my $fh, $file or die "couldnot open $file: $!";
2088 my @data;
2089 while (<$fh>)
2091 push @data, map { [ split(/\t/) ] } $_ if $_;
2094 if (@data)
2096 shift(@data);
2097 return \@data;
2098 } else
2100 return;
2105 sub trait_phenotype_file {
2106 my ($self, $c, $pop_id, $trait) = @_;
2108 my $dir = $c->stash->{solgs_cache_dir};
2109 my $exp = "phenotype_trait_${trait}_${pop_id}";
2110 my $file = $self->grep_file($dir, $exp);
2112 $c->stash->{trait_phenotype_file} = $file;
2117 sub check_selection_pops_list :Path('/solgs/check/selection/populations') Args(1) {
2118 my ($self, $c, $tr_pop_id) = @_;
2120 $c->stash->{training_pop_id} = $tr_pop_id;
2122 $self->list_of_prediction_pops_file($c, $tr_pop_id);
2123 my $pred_pops_file = $c->stash->{list_of_prediction_pops_file};
2125 my $ret->{result} = 0;
2127 if (-s $pred_pops_file)
2129 $self->list_of_prediction_pops($c, $tr_pop_id);
2130 $ret->{data} = $c->stash->{list_of_prediction_pops};
2133 $ret = to_json($ret);
2135 $c->res->content_type('application/json');
2136 $c->res->body($ret);
2141 sub check_genotype_data_population :Path('/solgs/check/genotype/data/population/') Args(1) {
2142 my ($self, $c, $pop_id) = @_;
2144 $c->stash->{pop_id} = $pop_id;
2145 $self->check_population_has_genotype($c);
2147 my $ret->{has_genotype} = $c->stash->{population_has_genotype};
2148 $ret = to_json($ret);
2150 $c->res->content_type('application/json');
2151 $c->res->body($ret);
2156 sub check_phenotype_data_population :Path('/solgs/check/phenotype/data/population/') Args(1) {
2157 my ($self, $c, $pop_id) = @_;
2159 $c->stash->{pop_id} = $pop_id;
2160 $self->check_population_has_phenotype($c);
2162 my $ret->{has_phenotype} = $c->stash->{population_has_phenotype};
2163 $ret = to_json($ret);
2165 $c->res->content_type('application/json');
2166 $c->res->body($ret);
2171 sub check_population_exists :Path('/solgs/check/population/exists/') Args(0) {
2172 my ($self, $c) = @_;
2174 my $name = $c->req->param('name');
2176 my $rs = $c->model("solGS::solGS")->project_details_by_name($name);
2178 my $pop_id;
2179 while (my $row = $rs->next) {
2180 $pop_id = $row->id;
2183 my $ret->{population_id} = $pop_id;
2184 $ret = to_json($ret);
2186 $c->res->content_type('application/json');
2187 $c->res->body($ret);
2192 sub check_training_population :Path('/solgs/check/training/population/') Args(1) {
2193 my ($self, $c, $pop_id) = @_;
2195 $c->stash->{pop_id} = $pop_id;
2197 $self->check_population_is_training_population($c);
2198 my $is_training_pop = $c->stash->{is_training_population};
2200 my $training_pop_data;
2201 if ($is_training_pop)
2203 my $pr_rs = $c->model('solGS::solGS')->project_details($pop_id);
2204 $self->projects_links($c, $pr_rs);
2205 $training_pop_data = $c->stash->{projects_pages};
2208 my $ret->{is_training_population} = $is_training_pop;
2209 $ret->{training_pop_data} = $training_pop_data;
2210 $ret = to_json($ret);
2212 $c->res->content_type('application/json');
2213 $c->res->body($ret);
2218 sub check_population_is_training_population {
2219 my ($self, $c) = @_;
2221 my $pr_id = $c->stash->{pop_id};
2222 my $is_gs = $c->model("solGS::solGS")->get_project_type($pr_id);
2224 my $has_phenotype;
2225 my $has_genotype;
2227 if ($is_gs !~ /genomic selection/)
2229 $self->check_population_has_phenotype($c);
2230 $has_phenotype = $c->stash->{population_has_phenotype};
2232 if ($has_phenotype)
2234 $self->check_population_has_genotype($c);
2235 $has_genotype = $c->stash->{population_has_genotype};
2239 if ($is_gs || ($has_phenotype && $has_genotype))
2241 $c->stash->{is_training_population} = 1;
2247 sub check_population_has_phenotype {
2248 my ($self, $c) = @_;
2250 my $pr_id = $c->stash->{pop_id};
2251 my $is_gs = $c->model("solGS::solGS")->get_project_type($pr_id);
2252 my $has_phenotype = 1 if $is_gs;
2254 if ($is_gs !~ /genomic selection/)
2256 my $cache_dir = $c->stash->{solgs_cache_dir};
2257 my $pheno_file = $self->grep_file($cache_dir, "phenotype_data_${pr_id}.txt");
2259 if (!-s $pheno_file)
2261 $has_phenotype = $c->model("solGS::solGS")->has_phenotype($pr_id);
2263 else
2265 $has_phenotype = 1;
2269 $c->stash->{population_has_phenotype} = $has_phenotype;
2274 sub check_population_has_genotype {
2275 my ($self, $c) = @_;
2277 my $pop_id = $c->stash->{pop_id};
2279 my $has_genotype;
2281 my $geno_file;
2282 if ($pop_id =~ /upload/)
2284 my $dir = $c->stash->{solgs_prediction_upload_dir};
2285 my $user_id = $c->user->id;
2286 my $file_name = "genotype_data_${pop_id}";
2287 $geno_file = $self->grep_file($dir, $file_name);
2288 $has_genotype = 1 if -s $geno_file;
2291 unless ($has_genotype)
2293 $has_genotype = $c->model('solGS::solGS')->has_genotype($pop_id);
2296 $c->stash->{population_has_genotype} = $has_genotype;
2301 sub check_selection_population_relevance :Path('/solgs/check/selection/population/relevance') Args() {
2302 my ($self, $c) = @_;
2304 my $data_set_type = $c->req->param('data_set_type');
2305 my $training_pop_id = $c->req->param('training_pop_id');
2306 my $selection_pop_name = $c->req->param('selection_pop_name');
2307 my $trait_id = $c->req->param('trait_id');
2309 $c->stash->{data_set_type} = $data_set_type;
2311 my $pr_rs = $c->model("solGS::solGS")->project_details_by_exact_name($selection_pop_name);
2313 my $selection_pop_id;
2314 while (my $row = $pr_rs->next) {
2315 $selection_pop_id = $row->project_id;
2318 my $ret = {};
2320 if ($selection_pop_id !~ /$training_pop_id/)
2322 my $has_genotype;
2323 if ($selection_pop_id)
2325 $c->stash->{pop_id} = $selection_pop_id;
2326 $self->check_population_has_genotype($c);
2327 $has_genotype = $c->stash->{population_has_genotype};
2330 my $similarity;
2331 if ($has_genotype)
2333 $c->stash->{pop_id} = $selection_pop_id;
2335 $self->first_stock_genotype_data($c, $selection_pop_id);
2336 my $selection_pop_geno_file = $c->stash->{first_stock_genotype_file};
2338 my $training_pop_geno_file;
2340 if ($training_pop_id =~ /upload/)
2342 my $dir = $c->stash->{solgs_prediction_upload_dir};
2343 my $user_id = $c->user->id;
2344 my $tr_geno_file = "genotype_data_${training_pop_id}";
2345 $training_pop_geno_file = $self->grep_file($dir, $tr_geno_file);
2347 else
2349 my $dir = $c->stash->{solgs_cache_dir};
2350 my $tr_geno_file;
2352 if ($data_set_type =~ /combined populations/)
2354 $self->get_trait_details($c, $trait_id);
2355 my $trait_abbr = $c->stash->{trait_abbr};
2356 $tr_geno_file = "genotype_data_${training_pop_id}_${trait_abbr}";
2358 else
2360 $tr_geno_file = "genotype_data_${training_pop_id}";
2363 $training_pop_geno_file = $self->grep_file($dir, $tr_geno_file);
2366 $similarity = $self->compare_marker_set_similarity([$selection_pop_geno_file, $training_pop_geno_file]);
2369 my $selection_pop_data;
2370 if ($similarity >= 0.5 )
2372 $c->stash->{training_pop_id} = $training_pop_id;
2373 $self->format_selection_pops($c, [$selection_pop_id]);
2374 $selection_pop_data = $c->stash->{selection_pops_list};
2375 $self->save_selection_pops($c, [$selection_pop_id]);
2378 $ret->{selection_pop_data} = $selection_pop_data;
2379 $ret->{similarity} = $similarity;
2380 $ret->{has_genotype} = $has_genotype;
2381 $ret->{selection_pop_id} = $selection_pop_id;
2383 else
2385 $ret->{selection_pop_id} = $selection_pop_id;
2388 $ret = to_json($ret);
2390 $c->res->content_type('application/json');
2391 $c->res->body($ret);
2396 sub save_selection_pops {
2397 my ($self, $c, $selection_pop_id) = @_;
2399 my $training_pop_id = $c->stash->{training_pop_id};
2401 $self->list_of_prediction_pops_file($c, $training_pop_id);
2402 my $selection_pops_file = $c->stash->{list_of_prediction_pops_file};
2404 my @existing_pops_ids = split(/\n/, read_file($selection_pops_file));
2406 my @uniq_ids = unique(@existing_pops_ids, @$selection_pop_id);
2407 my $formatted_ids = join("\n", @uniq_ids);
2409 write_file($selection_pops_file, $formatted_ids);
2414 sub search_selection_pops :Path('/solgs/search/selection/populations/') {
2415 my ($self, $c, $tr_pop_id) = @_;
2417 $c->stash->{training_pop_id} = $tr_pop_id;
2419 $self->search_all_relevant_selection_pops($c, $tr_pop_id);
2420 my $selection_pops_list = $c->stash->{all_relevant_selection_pops};
2422 my $ret->{selection_pops_list} = 0;
2423 if ($selection_pops_list)
2425 $ret->{data} = $selection_pops_list;
2428 $ret = to_json($ret);
2430 $c->res->content_type('application/json');
2431 $c->res->body($ret);
2436 sub list_of_prediction_pops {
2437 my ($self, $c, $training_pop_id) = @_;
2439 $self->list_of_prediction_pops_file($c, $training_pop_id);
2440 my $pred_pops_file = $c->stash->{list_of_prediction_pops_file};
2442 my @pred_pops_ids = split(/\n/, read_file($pred_pops_file));
2444 $self->format_selection_pops($c, \@pred_pops_ids);
2446 $c->stash->{list_of_prediction_pops} = $c->stash->{selection_pops_list};
2451 sub search_all_relevant_selection_pops {
2452 my ($self, $c, $training_pop_id) = @_;
2454 my @pred_pops_ids = @{$c->model('solGS::solGS')->prediction_pops($training_pop_id)};
2456 $self->save_selection_pops($c, \@pred_pops_ids);
2458 $self->format_selection_pops($c, \@pred_pops_ids);
2460 $c->stash->{all_relevant_selection_pops} = $c->stash->{selection_pops_list};
2465 sub format_selection_pops {
2466 my ($self, $c, $pred_pops_ids) = @_;
2468 my $training_pop_id = $c->stash->{training_pop_id};
2470 my @pred_pops_ids = @{$pred_pops_ids};
2471 my @data;
2473 if (@pred_pops_ids) {
2475 foreach my $prediction_pop_id (@pred_pops_ids)
2477 my $pred_pop_rs = $c->model('solGS::solGS')->project_details($prediction_pop_id);
2478 my $pred_pop_link;
2480 while (my $row = $pred_pop_rs->next)
2482 my $name = $row->name;
2483 my $desc = $row->description;
2485 # unless ($name =~ /test/ || $desc =~ /test/)
2487 my $id_pop_name->{id} = $prediction_pop_id;
2488 $id_pop_name->{name} = $name;
2489 $id_pop_name->{pop_type} = 'selection';
2490 $id_pop_name = to_json($id_pop_name);
2492 $pred_pop_link = qq | <a href="/solgs/model/$training_pop_id/prediction/$prediction_pop_id"
2493 onclick="solGS.waitPage(this.href); return false;"><input type="hidden" value=\'$id_pop_name\'>$name</data>
2494 </a>
2497 my $pr_yr_rs = $c->model('solGS::solGS')->project_year($prediction_pop_id);
2498 my $project_yr;
2500 while ( my $yr_r = $pr_yr_rs->next )
2502 $project_yr = $yr_r->value;
2505 $self->download_prediction_urls($c, $training_pop_id, $prediction_pop_id);
2506 my $download_prediction = $c->stash->{download_prediction};
2508 push @data, [$pred_pop_link, $desc, $project_yr, $download_prediction];
2514 $c->stash->{selection_pops_list} = \@data;
2519 sub list_of_prediction_pops_file {
2520 my ($self, $c, $training_pop_id)= @_;
2522 my $cache_data = {key => 'list_of_prediction_pops' . $training_pop_id,
2523 file => 'list_of_prediction_pops_' . $training_pop_id,
2524 stash_key => 'list_of_prediction_pops_file'
2527 $self->cache_file($c, $cache_data);
2532 sub first_stock_genotype_file {
2533 my ($self, $c, $pop_id) = @_;
2535 my $cache_data = {key => 'first_stock_genotype_file'. $pop_id,
2536 file => 'first_stock_genotype_file_' . $pop_id . '.txt',
2537 stash_key => 'first_stock_genotype_file'
2540 $self->cache_file($c, $cache_data);
2545 sub prediction_population_file {
2546 my ($self, $c, $pred_pop_id) = @_;
2548 my $tmp_dir = $c->stash->{solgs_tempfiles_dir};
2550 my ($fh, $tempfile) = tempfile("prediction_population_${pred_pop_id}-XXXXX",
2551 DIR => $tmp_dir
2554 $c->stash->{prediction_pop_id} = $pred_pop_id;
2556 $self->filtered_selection_genotype_file($c);
2557 my $filtered_geno_file = $c->stash->{filtered_selection_genotype_file};
2559 my $geno_files = $filtered_geno_file;
2561 $self->genotype_file($c, $pred_pop_id);
2562 $geno_files .= "\t" . $c->stash->{pred_genotype_file};
2564 $fh->print($geno_files);
2565 $fh->close;
2567 $c->stash->{prediction_population_file} = $tempfile;
2572 sub combined_pops_catalogue_file {
2573 my ($self, $c) = @_;
2575 my $cache_data = {key => 'combined_pops_catalogue_file',
2576 file => 'combined_pops_catalogue_file',
2577 stash_key => 'combined_pops_catalogue_file'
2580 $self->cache_file($c, $cache_data);
2585 sub catalogue_combined_pops {
2586 my ($self, $c, $entry) = @_;
2588 $self->combined_pops_catalogue_file($c);
2589 my $file = $c->stash->{combined_pops_catalogue_file};
2591 if (! -s $file)
2593 my $header = 'combo_pops_id' . "\t" . 'population_ids';
2594 write_file($file, ($header, $entry));
2596 else
2598 $entry =~ s/\n//;
2599 my @combo = ($entry);
2601 my (@entries) = map{ $_ =~ s/\n// ? $_ : undef } read_file($file);
2602 my @intersect = intersect(@combo, @entries);
2603 unless( @intersect )
2605 write_file($file, {append => 1}, "\n" . "$entry");
2612 sub get_combined_pops_list {
2613 my ($self, $c, $combined_pops_id) = @_;
2615 $self->combined_pops_catalogue_file($c);
2616 my $combo_pops_catalogue_file = $c->stash->{combined_pops_catalogue_file};
2618 my @combos = uniq(read_file($combo_pops_catalogue_file));
2620 foreach my $entry (@combos)
2622 if ($entry =~ m/$combined_pops_id/)
2624 chomp($entry);
2625 my ($combo_pops_id, $pops) = split(/\t/, $entry);
2626 my @pops_list = split(',', $pops);
2627 $c->stash->{combined_pops_list} = \@pops_list;
2628 $c->stash->{trait_combo_pops} = \@pops_list;
2635 sub get_trait_details_of_trait_abbr {
2636 my ($self, $c) = @_;
2638 my $trait_abbr = $c->stash->{trait_abbr};
2640 if (!$c->stash->{pop_id})
2642 $c->stash->{pop_id} = $c->stash->{training_pop_id} || $c->stash->{combo_pops_id};
2645 my $trait_id;
2647 my $acronym_pairs = $self->get_acronym_pairs($c);
2649 if ($acronym_pairs)
2651 foreach my $r (@$acronym_pairs)
2653 if ($r->[0] eq $trait_abbr)
2655 my $trait_name = $r->[1];
2656 $trait_name =~ s/^\s+|\s+$//g;
2658 $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
2659 $self->get_trait_details($c, $trait_id);
2667 sub build_multiple_traits_models {
2668 my ($self, $c) = @_;
2670 my $pop_id = $c->stash->{pop_id} || $c->stash->{training_pop_id};
2671 my $prediction_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id};
2673 my @selected_traits = $c->req->param('trait_id[]');
2675 if (!@selected_traits && $c->stash->{background_job})
2677 @selected_traits = @{$c->stash->{selected_traits}};
2679 #$pop_id = $c->stash->{training_pop_id};
2681 # my $params = $c->stash->{analysis_profile};
2682 # my $args = $params->{arguments};
2684 # my $json = JSON->new();
2685 # $args = $json->decode($args);
2687 # if (keys %{$args})
2688 # {
2689 # foreach my $k ( keys %{$args} )
2691 # if ($k eq 'trait_id')
2693 # @selected_traits = @{ $args->{$k} };
2694 # }
2696 # if (!$pop_id)
2698 # if ($k eq 'population_id')
2700 # my @pop_ids = @{ $args->{$k} };
2701 # $c->stash->{pop_id} = $pop_ids[0];
2705 # if ($k eq 'selection_pop_id')
2707 # $prediction_id = $args->{$k};
2709 # }
2710 # }
2711 # }
2713 if (!@selected_traits)
2715 if ($prediction_id)
2717 $c->stash->{model_id} = $pop_id;
2719 $self->traits_with_valid_models($c);
2720 @selected_traits = @ {$c->stash->{traits_with_valid_models}};
2722 else
2724 $c->res->redirect("/solgs/population/$pop_id/selecttraits");
2725 $c->detach();
2728 else
2730 my $single_trait_id;
2732 if (scalar(@selected_traits) == 1)
2734 $single_trait_id = $selected_traits[0];
2735 if ($single_trait_id =~ /\D/)
2737 $c->stash->{trait_abbr} = $single_trait_id;
2738 $self->get_trait_details_of_trait_abbr($c);
2739 $single_trait_id = $c->stash->{trait_id};
2742 if (!$prediction_id)
2744 $c->res->redirect("/solgs/trait/$single_trait_id/population/$pop_id");
2745 $c->detach();
2747 else
2749 my $name = "trait_info_${single_trait_id}_pop_${pop_id}";
2750 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
2751 my $file2 = $self->create_tempfile($temp_dir, $name);
2753 $c->stash->{trait_file} = $file2;
2754 $c->stash->{trait_abbr} = $selected_traits[0];
2755 $self->get_trait_details_of_trait_abbr($c);
2757 $self->get_rrblup_output($c);
2760 else
2762 my ($traits, $trait_ids);
2764 for (my $i = 0; $i <= $#selected_traits; $i++)
2766 if ($selected_traits[$i] =~ /\D/)
2768 $c->stash->{trait_abbr} = $selected_traits[$i];
2769 $self->get_trait_details_of_trait_abbr($c);
2770 $traits .= $c->stash->{trait_abbr};
2771 $traits .= "\t" unless ($i == $#selected_traits);
2772 $trait_ids .= $c->stash->{trait_id};
2774 else
2776 my $tr = $c->model('solGS::solGS')->trait_name($selected_traits[$i]);
2777 my $abbr = $self->abbreviate_term($tr);
2778 $traits .= $abbr;
2779 $traits .= "\t" unless ($i == $#selected_traits);
2781 foreach my $tr_id (@selected_traits)
2783 $trait_ids .= $tr_id;
2788 if ($c->stash->{data_set_type} =~ /combined populations/)
2790 my $identifier = crc($trait_ids);
2791 $self->combined_gebvs_file($c, $identifier);
2794 my $name = "selected_traits_pop_${pop_id}";
2795 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
2796 my $file = $self->create_tempfile($temp_dir, $name);
2798 write_file($file, $traits);
2799 $c->stash->{selected_traits_file} = $file;
2801 $name = "trait_info_${single_trait_id}_pop_${pop_id}";
2802 my $file2 = $self->create_tempfile($temp_dir, $name);
2804 $c->stash->{trait_file} = $file2;
2805 $self->get_rrblup_output($c);
2812 sub traits_to_analyze :Regex('^solgs/analyze/traits/population/([\w|\d]+)(?:/([\d+]+))?') {
2813 my ($self, $c) = @_;
2815 my ($pop_id, $prediction_id) = @{$c->req->captures};
2817 my $req = $c->req->param('source');
2819 $c->stash->{pop_id} = $pop_id;
2820 $c->stash->{prediction_pop_id} = $prediction_id;
2822 $self->build_multiple_traits_models($c);
2824 my $referer = $c->req->referer;
2825 my $base = $c->req->base;
2826 $referer =~ s/$base//;
2827 my ($tr_id) = $referer =~ /(\d+)/;
2828 my $trait_page = "solgs/trait/$tr_id/population/$pop_id";
2830 my $error = $c->stash->{script_error};
2832 if ($error)
2834 $c->stash->{message} = "$error can't create prediction models for the selected traits.
2835 There are problems with the datasets of the traits.
2836 <p><a href=\"/solgs/population/$pop_id\">[ Go back ]</a></p>";
2838 $c->stash->{template} = "/generic_message.mas";
2840 elsif ($req =~ /AJAX/)
2842 my $ret->{status} = 'success';
2844 $ret = to_json($ret);
2846 $c->res->content_type('application/json');
2847 $c->res->body($ret);
2849 else
2851 if ($referer =~ m/$trait_page/)
2853 $c->res->redirect("/solgs/trait/$tr_id/population/$pop_id");
2854 $c->detach();
2856 else
2858 $c->res->redirect("/solgs/traits/all/population/$pop_id/$prediction_id");
2859 $c->detach();
2866 sub all_traits_output :Regex('^solgs/traits/all/population/([\w|\d]+)(?:/([\d+]+))?') {
2867 my ($self, $c) = @_;
2869 my ($pop_id, $pred_pop_id) = @{$c->req->captures};
2871 my @traits = $c->req->param;
2872 @traits = grep {$_ ne 'rank'} @traits;
2873 $c->stash->{training_pop_id} = $pop_id;
2874 $c->stash->{pop_id} = $pop_id;
2876 if ($pred_pop_id)
2878 $c->stash->{prediction_pop_id} = $pred_pop_id;
2879 $c->stash->{population_is} = 'prediction population';
2880 $self->prediction_population_file($c, $pred_pop_id);
2882 my $pr_rs = $c->model('solGS::solGS')->project_details($pred_pop_id);
2884 while (my $row = $pr_rs->next)
2886 $c->stash->{prediction_pop_name} = $row->name;
2889 else
2891 $c->stash->{prediction_pop_id} = undef;
2892 $c->stash->{population_is} = 'training population';
2895 $c->stash->{model_id} = $pop_id;
2896 $self->analyzed_traits($c);
2898 my @analyzed_traits = @{$c->stash->{analyzed_traits}};
2900 if (!@analyzed_traits)
2902 $c->res->redirect("/solgs/population/$pop_id/selecttraits/");
2903 $c->detach();
2906 my @trait_pages;
2907 foreach my $tr (@analyzed_traits)
2909 my $acronym_pairs = $self->get_acronym_pairs($c);
2910 my $trait_name;
2911 if ($acronym_pairs)
2913 foreach my $r (@$acronym_pairs)
2915 if ($r->[0] eq $tr)
2917 $trait_name = $r->[1];
2918 $trait_name =~ s/\n//g;
2919 $c->stash->{trait_name} = $trait_name;
2920 $c->stash->{trait_abbr} = $r->[0];
2925 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
2926 my $trait_abbr = $c->stash->{trait_abbr};
2928 $self->get_model_accuracy_value($c, $pop_id, $trait_abbr);
2929 my $accuracy_value = $c->stash->{accuracy_value};
2931 $c->controller("solGS::Heritability")->get_heritability($c);
2932 my $heritability = $c->stash->{heritability};
2934 push @trait_pages, [ qq | <a href="/solgs/trait/$trait_id/population/$pop_id">$trait_abbr</a>|, $accuracy_value, $heritability];
2938 $self->project_description($c, $pop_id);
2939 my $project_name = $c->stash->{project_name};
2940 my $project_desc = $c->stash->{project_desc};
2942 my @model_desc = ([qq | <a href="/solgs/population/$pop_id">$project_name</a> |, $project_desc, \@trait_pages]);
2944 $c->stash->{template} = $self->template('/population/multiple_traits_output.mas');
2945 $c->stash->{trait_pages} = \@trait_pages;
2946 $c->stash->{model_data} = \@model_desc;
2948 my $acronym = $self->get_acronym_pairs($c);
2949 $c->stash->{acronym} = $acronym;
2954 sub selection_index_form :Path('/solgs/selection/index/form') Args(0) {
2955 my ($self, $c) = @_;
2957 my $pred_pop_id = $c->req->param('pred_pop_id');
2958 my $training_pop_id = $c->req->param('training_pop_id');
2960 $c->stash->{model_id} = $training_pop_id;
2961 $c->stash->{prediction_pop_id} = $pred_pop_id;
2963 my @traits;
2964 if (!$pred_pop_id)
2966 $self->analyzed_traits($c);
2967 @traits = @{ $c->stash->{selection_index_traits} };
2969 else
2971 $self->prediction_pop_analyzed_traits($c, $training_pop_id, $pred_pop_id);
2972 @traits = @{ $c->stash->{prediction_pop_analyzed_traits} };
2975 my $ret->{status} = 'success';
2976 $ret->{traits} = \@traits;
2978 $ret = to_json($ret);
2980 $c->res->content_type('application/json');
2981 $c->res->body($ret);
2986 sub traits_with_valid_models {
2987 my ($self, $c) = @_;
2989 my $pop_id = $c->stash->{pop_id} || $c->stash->{training_pop_id};
2991 $self->analyzed_traits($c);
2993 my @analyzed_traits = @{$c->stash->{analyzed_traits}};
2994 my @filtered_analyzed_traits;
2995 my @valid_traits_ids;
2997 foreach my $analyzed_trait (@analyzed_traits)
2999 $self->get_model_accuracy_value($c, $pop_id, $analyzed_trait);
3000 my $av = $c->stash->{accuracy_value};
3001 if ($av && $av =~ m/\d+/ && $av > 0)
3003 push @filtered_analyzed_traits, $analyzed_trait;
3006 $c->stash->{trait_abbr} = $analyzed_trait;
3007 $self->get_trait_details_of_trait_abbr($c);
3008 push @valid_traits_ids, $c->stash->{trait_id};
3012 @filtered_analyzed_traits = uniq(@filtered_analyzed_traits);
3013 @valid_traits_ids = uniq(@valid_traits_ids);
3015 $c->stash->{traits_with_valid_models} = \@filtered_analyzed_traits;
3016 $c->stash->{traits_ids_with_valid_models} = \@valid_traits_ids;
3021 sub calculate_selection_index :Path('/solgs/calculate/selection/index') Args(2) {
3022 my ($self, $c, $model_id, $pred_pop_id) = @_;
3024 $c->stash->{pop_id} = $model_id;
3026 if ($pred_pop_id =~ /\d+/ && $model_id != $pred_pop_id)
3028 $c->stash->{prediction_pop_id} = $pred_pop_id;
3030 else
3032 $pred_pop_id = undef;
3033 $c->stash->{prediction_pop_id} = $pred_pop_id;
3036 my @traits = $c->req->param;
3037 @traits = grep {$_ ne 'rank'} @traits;
3039 my @values;
3040 foreach (@traits)
3042 push @values, $c->req->param($_);
3045 if (@values)
3047 $self->get_gebv_files_of_traits($c);
3049 my $params = $c->req->params;
3050 $self->gebv_rel_weights($c, $params, $pred_pop_id);
3052 $c->forward('rank_genotypes', [$pred_pop_id]);
3054 my $geno = $self->tohtml_genotypes($c);
3056 my $link = $c->stash->{ranked_genotypes_download_url};
3057 my $ranked_genos = $c->stash->{top_10_selection_indices};
3058 my $index_file = $c->stash->{selection_index_file};
3060 my $ret->{status} = 'No GEBV values to rank.';
3062 if (@$ranked_genos)
3064 $ret->{status} = 'success';
3065 $ret->{genotypes} = $geno;
3066 $ret->{link} = $link;
3067 $ret->{index_file} = $index_file;
3070 $ret = to_json($ret);
3072 $c->res->content_type('application/json');
3073 $c->res->body($ret);
3078 sub combine_populations_confrim :Path('/solgs/combine/populations/trait/confirm') Args(1) {
3079 my ($self, $c, $trait_id) = @_;
3081 my (@pop_ids, $ids);
3083 if ($trait_id =~ /\d+/)
3085 $ids = $c->req->param('confirm_populations');
3086 @pop_ids = split(/,/, $ids);
3087 if (!@pop_ids) {@pop_ids = $ids;}
3089 $c->stash->{trait_id} = $trait_id;
3092 my $pop_links;
3093 my @selected_pops_details;
3095 foreach my $pop_id (@pop_ids)
3097 my $markers = $c->model("solGS::solGS")->get_project_genotyping_markers($pop_id);
3098 my @markers = split(/\t/, $markers);
3099 my $markers_num = scalar(@markers);
3101 $self->trial_compatibility_table($c, $markers_num);
3102 my $match_code = $c->stash->{trial_compatibility_code};
3104 my $pop_rs = $c->model('solGS::solGS')->project_details($pop_id);
3106 $self->get_projects_details($c, $pop_rs);
3107 #my $pop_details = $self->get_projects_details($c, $pop_rs);
3108 my $pop_details = $c->stash->{projects_details};
3109 my $pop_name = $pop_details->{$pop_id}{project_name};
3110 my $pop_desc = $pop_details->{$pop_id}{project_desc};
3111 my $pop_year = $pop_details->{$pop_id}{project_year};
3112 my $pop_location = $pop_details->{$pop_id}{project_location};
3114 my $checkbox = qq |<form> <input style="background-color: $match_code;" type="checkbox" checked="checked" name="project" value="$pop_id" /> </form> |;
3116 $match_code = qq | <div class=trial_code style="color: $match_code; background-color: $match_code; height: 100%; width:100%">code</div> |;
3117 push @selected_pops_details, [$checkbox, qq|<a href="/solgs/trait/$trait_id/population/$pop_id" onclick="solGS.waitPage()">$pop_name</a>|,
3118 $pop_desc, $pop_location, $pop_year, $match_code
3123 $c->stash->{selected_pops_details} = \@selected_pops_details;
3124 $c->stash->{template} = $self->template('/search/result/confirm/populations.mas');
3129 sub combine_populations :Path('/solgs/combine/populations/trait') Args(1) {
3130 my ($self, $c, $trait_id) = @_;
3132 my (@pop_ids, $ids);
3134 if ($trait_id =~ /\d+/)
3136 $ids = $c->req->param($trait_id);
3137 @pop_ids = split(/,/, $ids);
3139 $self->get_trait_details($c, $trait_id);
3142 my $combo_pops_id;
3143 my $ret->{status} = 0;
3145 if (scalar(@pop_ids) > 1 )
3147 $combo_pops_id = crc(join('', @pop_ids));
3148 $c->stash->{combo_pops_id} = $combo_pops_id;
3149 $c->stash->{trait_combo_pops} = $ids;
3151 $c->stash->{trait_combine_populations} = \@pop_ids;
3153 $self->multi_pops_phenotype_data($c, \@pop_ids);
3154 $self->multi_pops_genotype_data($c, \@pop_ids);
3155 $self->multi_pops_geno_files($c, \@pop_ids);
3156 $self->multi_pops_pheno_files($c, \@pop_ids);
3158 my $geno_files = $c->stash->{multi_pops_geno_files};
3159 my @g_files = split(/\t/, $geno_files);
3161 $self->compare_genotyping_platforms($c, \@g_files);
3162 my $not_matching_pops = $c->stash->{pops_with_no_genotype_match};
3164 if (!$not_matching_pops)
3166 $self->cache_combined_pops_data($c);
3168 my $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
3169 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
3171 unless (-s $combined_pops_geno_file && -s $combined_pops_pheno_file )
3173 $self->r_combine_populations($c);
3175 $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
3176 $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
3179 if (-s $combined_pops_pheno_file > 1 && -s $combined_pops_geno_file > 1)
3181 my $tr_abbr = $c->stash->{trait_abbr};
3182 $c->stash->{data_set_type} = 'combined populations';
3183 $self->get_rrblup_output($c);
3184 my $analysis_result = $c->stash->{combo_pops_analysis_result};
3186 $ret->{pop_ids} = $ids;
3187 $ret->{combo_pops_id} = $combo_pops_id;
3188 $ret->{status} = $analysis_result;
3190 my $entry = "\n" . $combo_pops_id . "\t" . $ids;
3191 $self->catalogue_combined_pops($c, $entry);
3194 else
3196 $ret->{not_matching_pops} = $not_matching_pops;
3199 else
3201 my $pop_id = $pop_ids[0];
3202 $ret->{redirect_url} = "/solgs/trait/$trait_id/population/$pop_id";
3205 $ret = to_json($ret);
3207 $c->res->content_type('application/json');
3208 $c->res->body($ret);
3213 sub get_model_accuracy_value {
3214 my ($self, $c, $model_id, $trait_abbr) = @_;
3216 my $dir = $c->stash->{solgs_cache_dir};
3217 opendir my $dh, $dir or die "can't open $dir: $!\n";
3219 my ($validation_file) = grep { /cross_validation_${trait_abbr}_${model_id}/ && -f "$dir/$_" }
3220 readdir($dh);
3222 closedir $dh;
3224 $validation_file = catfile($dir, $validation_file);
3226 my ($row) = grep {/Average/} read_file($validation_file);
3227 my ($text, $accuracy_value) = split(/\t/, $row);
3229 $c->stash->{accuracy_value} = $accuracy_value;
3234 sub get_project_owners {
3235 my ($self, $c, $pr_id) = @_;
3237 my $owners = $c->model("solGS::solGS")->get_stock_owners($pr_id);
3238 my $owners_names;
3240 if ($owners)
3242 for (my $i=0; $i < scalar(@$owners); $i++)
3244 my $owner_name = $owners->[$i]->{'first_name'} . "\t" . $owners->[$i]->{'last_name'} if $owners->[$i];
3246 unless (!$owner_name)
3248 $owners_names .= $owners_names ? ', ' . $owner_name : $owner_name;
3253 $c->stash->{project_owners} = $owners_names;
3257 sub combined_pops_summary {
3258 my ($self, $c) = @_;
3260 my $combo_pops_id = $c->stash->{combo_pops_id};
3262 $self->get_combined_pops_list($c, $combo_pops_id);
3263 my @pops_ids = @{$c->stash->{trait_combo_pops}};
3265 my $desc = 'This training population is a combination of ';
3266 my $projects_owners;
3268 foreach my $pop_id (@pops_ids)
3270 my $pr_rs = $c->model('solGS::solGS')->project_details($pop_id);
3272 while (my $row = $pr_rs->next)
3275 my $pr_id = $row->id;
3276 my $pr_name = $row->name;
3277 $desc .= qq | <a href="/solgs/population/$pr_id">$pr_name </a>|;
3278 $desc .= $pop_id == $pops_ids[-1] ? '.' : ' and ';
3281 $self->get_project_owners($c, $_);
3282 my $project_owners = $c->stash->{project_owners};
3284 unless (!$project_owners)
3286 $projects_owners.= $projects_owners ? ', ' . $project_owners : $project_owners;
3290 my $trait_abbr = $c->stash->{trait_abbr};
3291 my $trait_id = $c->stash->{trait_id};
3293 $self->filtered_training_genotype_file($c);
3294 my $filtered_geno_file = $c->stash->{filtered_training_genotype_file};
3296 $self->cache_combined_pops_data($c);
3297 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
3298 my @unfiltered_geno_rows = read_file($combined_pops_geno_file);
3300 my $markers_no;
3301 my @geno_lines;
3303 if (-s $filtered_geno_file) {
3304 my @rows = read_file($filtered_geno_file);
3305 $markers_no = scalar(split('\t', $rows[0])) - 1;
3307 else
3309 $markers_no = scalar(split ('\t', $unfiltered_geno_rows[0])) - 1;
3312 my $stocks_no = scalar(@unfiltered_geno_rows) - 1;
3313 my $training_pop = "Training population $combo_pops_id";
3315 my $protocol = $c->config->{default_genotyping_protocol};
3316 $protocol = 'N/A' if !$protocol;
3318 $c->stash(markers_no => $markers_no,
3319 stocks_no => $stocks_no,
3320 project_desc => $desc,
3321 project_name => $training_pop,
3322 owner => $projects_owners,
3323 protocol => $protocol,
3329 sub compare_marker_set_similarity {
3330 my ($self, $marker_file_pair) = @_;
3332 my $file_1 = $marker_file_pair->[0];
3333 my $file_2 = $marker_file_pair->[1];
3335 my $first_markers = (read_file($marker_file_pair->[0]))[0];
3336 my $sec_markers = (read_file($marker_file_pair->[1]))[0];
3338 my @first_geno_markers = split(/\t/, $first_markers);
3339 my @sec_geno_markers = split(/\t/, $sec_markers);
3341 if ( @first_geno_markers && @first_geno_markers)
3343 my $common_markers = scalar(intersect(@first_geno_markers, @sec_geno_markers));
3344 my $similarity = $common_markers / scalar(@first_geno_markers);
3346 return $similarity;
3348 else
3350 return 0;
3356 sub compare_genotyping_platforms {
3357 my ($self, $c, $g_files) = @_;
3359 my $combinations = combinations($g_files, 2);
3360 my $combo_cnt = combinations($g_files, 2);
3362 my $not_matching_pops;
3363 my $cnt = 0;
3364 my $cnt_pairs = 0;
3366 while ($combo_cnt->next)
3368 $cnt_pairs++;
3371 while (my $pair = $combinations->next)
3373 $cnt++;
3374 my $similarity = $self->compare_marker_set_similarity($pair);
3376 unless ($similarity > 0.5 )
3378 no warnings 'uninitialized';
3379 my $pop_id_1 = fileparse($pair->[0]);
3380 my $pop_id_2 = fileparse($pair->[1]);
3382 map { s/genotype_data_|\.txt//g } $pop_id_1, $pop_id_2;
3384 my $list_type_pop = $c->stash->{uploaded_prediction};
3386 unless ($list_type_pop)
3388 my @pop_names;
3389 foreach ($pop_id_1, $pop_id_2)
3391 my $pr_rs = $c->model('solGS::solGS')->project_details($_);
3393 while (my $row = $pr_rs->next)
3395 push @pop_names, $row->name;
3399 $not_matching_pops .= '[ ' . $pop_names[0]. ' and ' . $pop_names[1] . ' ]';
3400 $not_matching_pops .= ', ' if $cnt != $cnt_pairs;
3402 # else
3403 # {
3404 # $not_matching_pops = 'not_matching';
3409 $c->stash->{pops_with_no_genotype_match} = $not_matching_pops;
3415 sub submit_cluster_compare_trials_markers {
3416 my ($self, $c, $geno_files) = @_;
3418 $c->stash->{r_temp_file} = 'compare-trials-markers';
3419 $self->create_cluster_acccesible_tmp_files($c);
3420 my $out_temp_file = $c->stash->{out_file_temp};
3421 my $err_temp_file = $c->stash->{err_file_temp};
3423 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
3424 my $background_job = $c->stash->{background_job};
3426 my $status;
3430 # if ($dependency && $background_job)
3432 # my $dependent_job_script = $self->create_tempfile($c, "compare_trials_job", "pl");
3434 # my $cmd = '#!/usr/bin/env perl;' . "\n";
3435 # $cmd .= 'use strict;' . "\n";
3436 # $cmd .= 'use warnings;' . "\n\n\n";
3437 # $cmd .= 'system("Rscript --slave '
3438 # . $in_file_temp
3439 # . ' --args ' . $input_files . ' ' . $output_files
3440 # . ' | qsub -W ' . $dependency . '");';
3442 # write_file($dependent_job_script, $cmd);
3443 # chmod 0755, $dependent_job_script;
3445 # $r_job = CXGN::Tools::Run->run_cluster('perl',
3446 # $dependent_job_script,
3447 # $out_file_temp,
3449 # working_dir => $c->stash->{solgs_tempfiles_dir},
3450 # max_cluster_jobs => 1_000_000_000,
3451 # },
3452 # );
3453 # }
3456 try
3458 my $compare_trials_job = CXGN::Tools::Run->run_cluster_perl({
3460 method => ["SGN::Controller::solGS::solGS" => "compare_genotyping_platforms"],
3461 args => ['SGN::Context', $geno_files],
3462 load_packages => ['SGN::Controller::solGS::solGS', 'SGN::Context'],
3463 run_opts => {
3464 out_file => $out_temp_file,
3465 err_file => $err_temp_file,
3466 working_dir => $temp_dir,
3467 max_cluster_jobs => 1_000_000_000,
3472 $c->stash->{r_job_tempdir} = $compare_trials_job->tempdir();
3473 $c->stash->{r_job_id} = $compare_trials_job->job_id();
3474 $c->stash->{cluster_job} = $compare_trials_job;
3476 unless ($background_job)
3478 $compare_trials_job->wait();
3482 catch
3484 $status = $_;
3485 $status =~ s/\n at .+//s;
3491 sub cache_combined_pops_data {
3492 my ($self, $c) = @_;
3494 my $trait_id = $c->stash->{trait_id};
3495 my $trait_abbr = $c->stash->{trait_abbr};
3496 my $combo_pops_id = $c->stash->{combo_pops_id};
3498 my $cache_pheno_data = {key => "phenotype_data_${trait_id}_${combo_pops_id}_combined",
3499 file => "phenotype_data_${combo_pops_id}_${trait_abbr}_combined",
3500 stash_key => 'trait_combined_pheno_file'
3503 my $cache_geno_data = {key => "genotype_data_${trait_id}_${combo_pops_id}_combined",
3504 file => "genotype_data_${combo_pops_id}_${trait_abbr}_combined",
3505 stash_key => 'trait_combined_geno_file'
3509 $self->cache_file($c, $cache_pheno_data);
3510 $self->cache_file($c, $cache_geno_data);
3515 sub multi_pops_pheno_files {
3516 my ($self, $c, $pop_ids) = @_;
3518 my $trait_id = $c->stash->{trait_id};
3519 my $dir = $c->stash->{solgs_cache_dir};
3520 my $files;
3522 if (defined reftype($pop_ids) && reftype($pop_ids) eq 'ARRAY')
3524 foreach my $pop_id (@$pop_ids)
3526 my $exp = 'phenotype_data_' . $pop_id . '.txt';
3527 $files .= catfile($dir, $exp);
3528 $files .= "\t" unless (@$pop_ids[-1] eq $pop_id);
3531 $c->stash->{multi_pops_pheno_files} = $files;
3534 else
3536 my $exp = 'phenotype_data_' . ${pop_ids} . '.txt';
3537 $files = catfile($dir, $exp);
3540 if ($trait_id)
3542 my $name = "trait_${trait_id}_multi_pheno_files";
3543 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
3544 my $tempfile = $self->create_tempfile($temp_dir, $name);
3545 write_file($tempfile, $files);
3551 sub multi_pops_geno_files {
3552 my ($self, $c, $pop_ids) = @_;
3554 my $trait_id = $c->stash->{trait_id};
3555 my $dir = $c->stash->{solgs_cache_dir};
3556 my $files;
3558 if (defined reftype($pop_ids) && reftype($pop_ids) eq 'ARRAY')
3560 foreach my $pop_id (@$pop_ids)
3562 my $exp = 'genotype_data_' . $pop_id . '.txt';
3563 $files .= catfile($dir, $exp);
3564 $files .= "\t" unless (@$pop_ids[-1] eq $pop_id);
3566 $c->stash->{multi_pops_geno_files} = $files;
3568 else
3570 my $exp = 'genotype_data_' . ${pop_ids} . '.txt';
3571 $files = catfile($dir, $exp);
3574 if ($trait_id)
3576 my $name = "trait_${trait_id}_multi_geno_files";
3577 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
3578 my $tempfile = $self->create_tempfile($temp_dir, $name);
3579 write_file($tempfile, $files);
3585 sub create_tempfile {
3586 my ($self, $dir, $name, $ext) = @_;
3588 $ext = '.' . $ext if $ext;
3590 my ($fh, $file) = tempfile($name . "-XXXXX",
3591 SUFFIX => $ext,
3592 DIR => $dir,
3595 $fh->close;
3597 return $file;
3602 sub grep_file {
3603 my ($self, $dir, $exp) = @_;
3605 opendir my $dh, $dir
3606 or die "can't open $dir: $!\n";
3608 my ($file) = grep { /^$exp/ && -f "$dir/$_" } readdir($dh);
3609 close $dh;
3611 if ($file)
3613 $file = catfile($dir, $file);
3616 return $file;
3620 sub multi_pops_phenotype_data {
3621 my ($self, $c, $pop_ids) = @_;
3623 no warnings 'uninitialized';
3624 my @job_ids;
3625 if (@$pop_ids)
3627 foreach my $pop_id (@$pop_ids)
3629 $c->stash->{pop_id} = $pop_id;
3630 $self->phenotype_file($c);
3631 push @job_ids, $c->stash->{r_job_id};
3634 if (@job_ids)
3636 @job_ids = uniq(@job_ids);
3637 $c->stash->{multi_pops_pheno_jobs_ids} = \@job_ids;
3642 # $self->multi_pops_pheno_files($c, $pop_ids);
3647 sub multi_pops_genotype_data {
3648 my ($self, $c, $pop_ids) = @_;
3650 no warnings 'uninitialized';
3651 my @job_ids;
3652 if (@$pop_ids)
3654 foreach my $pop_id (@$pop_ids)
3656 $c->stash->{pop_id} = $pop_id;
3657 $self->genotype_file($c);
3658 push @job_ids, $c->stash->{r_job_id};
3661 if (@job_ids)
3663 @job_ids = uniq(@job_ids);
3664 $c->stash->{multi_pops_geno_jobs_ids} = \@job_ids;
3667 # $self->multi_pops_geno_files($c, $pop_ids);
3672 sub phenotype_graph :Path('/solgs/phenotype/graph') Args(0) {
3673 my ($self, $c) = @_;
3675 my $pop_id = $c->req->param('pop_id');
3676 my $trait_id = $c->req->param('trait_id');
3677 my $combo_pops_id = $c->req->param('combo_pops_id');
3679 $self->get_trait_details($c, $trait_id);
3681 $c->stash->{pop_id} = $pop_id;
3682 $c->stash->{combo_pops_id} = $combo_pops_id;
3684 $c->stash->{data_set_type} = 'combined populations' if $combo_pops_id;
3686 $self->trait_phenodata_file($c);
3688 my $trait_pheno_file = $c->{stash}->{trait_phenodata_file};
3689 my $trait_data = $self->convert_to_arrayref_of_arrays($c, $trait_pheno_file);
3691 my $ret->{status} = 'failed';
3693 if (@$trait_data)
3695 $ret->{status} = 'success';
3696 $ret->{trait_data} = $trait_data;
3699 $ret = to_json($ret);
3701 $c->res->content_type('application/json');
3702 $c->res->body($ret);
3707 #generates descriptive stat for a trait phenotype data
3708 sub trait_phenotype_stat {
3709 my ($self, $c) = @_;
3711 $self->trait_phenodata_file($c);
3713 my $trait_pheno_file = $c->{stash}->{trait_phenodata_file};
3715 my $trait_data = $self->convert_to_arrayref_of_arrays($c, $trait_pheno_file);
3717 my @desc_stat;
3718 my $background_job = $c->stash->{background_job};
3720 if ($trait_data && !$background_job)
3722 my @pheno_data;
3723 foreach (@$trait_data)
3725 unless (!$_->[0])
3727 my $d = $_->[1];
3728 chomp($d);
3730 if ($d =~ /\d+/)
3732 push @pheno_data, $d;
3737 my $stat = Statistics::Descriptive::Full->new();
3738 $stat->add_data(@pheno_data);
3740 my $min = $stat->min;
3741 my $max = $stat->max;
3742 my $mean = $stat->mean;
3743 my $med = $stat->median;
3744 my $std = $stat->standard_deviation;
3745 my $cnt = scalar(@$trait_data);
3746 my $cv = ($std / $mean) * 100;
3747 my $na = scalar(@$trait_data) - scalar(@pheno_data);
3749 if ($na == 0) { $na = '--'; }
3751 my $round = Math::Round::Var->new(0.01);
3752 $std = $round->round($std);
3753 $mean = $round->round($mean);
3754 $cv = $round->round($cv);
3755 $cv = $cv . '%';
3757 @desc_stat = ( [ 'Total no. of genotypes', $cnt ],
3758 [ 'Genotypes missing data', $na ],
3759 [ 'Minimum', $min ],
3760 [ 'Maximum', $max ],
3761 [ 'Arithmetic mean', $mean ],
3762 [ 'Median', $med ],
3763 [ 'Standard deviation', $std ],
3764 [ 'Coefficient of variation', $cv ]
3769 else
3771 @desc_stat = ( [ 'Total no. of genotypes', 'None' ],
3772 [ 'Genotypes missing data', 'None' ],
3773 [ 'Minimum', 'None' ],
3774 [ 'Maximum', 'None' ],
3775 [ 'Arithmetic mean', 'None' ],
3776 [ 'Median', 'None'],
3777 [ 'Standard deviation', 'None' ],
3778 [ 'Coefficient of variation', 'None' ]
3783 $c->stash->{descriptive_stat} = \@desc_stat;
3786 #sends an array of trait gebv data to an ajax request
3787 #with a population id and trait id parameters
3788 sub gebv_graph :Path('/solgs/trait/gebv/graph') Args(0) {
3789 my ($self, $c) = @_;
3791 my $pop_id = $c->req->param('pop_id');
3792 my $trait_id = $c->req->param('trait_id');
3793 my $prediction_pop_id = $c->req->param('selection_pop_id');
3794 my $combo_pops_id = $c->req->param('combo_pops_id');
3796 if ($combo_pops_id)
3798 $self->get_combined_pops_list($c, $combo_pops_id);
3799 $c->stash->{data_set_type} = 'combined populations';
3800 $pop_id = $combo_pops_id;
3805 $c->stash->{pop_id} = $pop_id;
3806 $c->stash->{combo_pops_id} = $combo_pops_id;
3807 $c->stash->{prediction_pop_id} = $prediction_pop_id;
3809 $self->get_trait_details($c, $trait_id);
3811 my $page = $c->req->referer();
3812 my $gebv_file;
3814 if ($page =~ /solgs\/selection\//)
3816 my $identifier = $pop_id . '_' . $prediction_pop_id;
3817 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
3819 $gebv_file = $c->stash->{prediction_pop_gebvs_file};
3821 else
3823 $self->gebv_kinship_file($c);
3824 $gebv_file = $c->stash->{gebv_kinship_file};
3828 my $gebv_data = $self->convert_to_arrayref_of_arrays($c, $gebv_file);
3830 my $ret->{status} = 'failed';
3832 if (@$gebv_data)
3834 $ret->{status} = 'success';
3835 $ret->{gebv_data} = $gebv_data;
3838 $ret = to_json($ret);
3840 $c->res->content_type('application/json');
3841 $c->res->body($ret);
3846 sub tohtml_genotypes {
3847 my ($self, $c) = @_;
3849 my $genotypes = $c->stash->{top_10_selection_indices};
3850 my %geno = ();
3852 foreach (@$genotypes)
3854 $geno{$_->[0]} = $_->[1];
3856 return \%geno;
3860 sub get_single_trial_traits {
3861 my ($self, $c) = @_;
3863 my $pop_id = $c->stash->{pop_id};
3865 $self->traits_list_file($c);
3866 my $traits_file = $c->stash->{traits_list_file};
3868 if (!-s $traits_file)
3870 my $traits_rs = $c->model('solGS::solGS')->project_traits($pop_id);
3872 my @traits_list;
3874 while (my $row = $traits_rs->next)
3876 push @traits_list, $row->name;
3879 my $traits = join("\t", @traits_list);
3880 write_file($traits_file, $traits);
3886 sub get_all_traits {
3887 my ($self, $c) = @_;
3889 my $pop_id = $c->stash->{pop_id};
3891 $self->traits_list_file($c);
3892 my $traits_file = $c->stash->{traits_list_file};
3894 if (!-s $traits_file)
3896 my $page = $c->req->path;
3898 if ($page =~ /solgs\/population\//)
3900 $self->get_single_trial_traits($c);
3904 my $traits = read_file($traits_file);
3906 $self->traits_acronym_file($c);
3907 my $acronym_file = $c->stash->{traits_acronym_file};
3909 unless (-s $acronym_file)
3911 my @filtered_traits = split(/\t/, $traits);
3912 my $count = scalar(@filtered_traits);
3914 my $acronymized_traits = $self->acronymize_traits(\@filtered_traits);
3915 my $acronym_table = $acronymized_traits->{acronym_table};
3917 $self->traits_acronym_table($c, $acronym_table);
3920 $self->create_trait_data($c);
3924 sub create_trait_data {
3925 my ($self, $c) = @_;
3929 my $acronym_pairs = $self->get_acronym_pairs($c);
3931 if (@$acronym_pairs)
3933 my $table = 'trait_id' . "\t" . 'trait_name' . "\t" . 'acronym' . "\n";
3934 foreach (@$acronym_pairs)
3936 my $trait_name = $_->[1];
3937 $trait_name =~ s/\n//g;
3939 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
3941 if ($trait_id)
3943 $table .= $trait_id . "\t" . $trait_name . "\t" . $_->[0] . "\n";
3947 $self->all_traits_file($c);
3948 my $traits_file = $c->stash->{all_traits_file};
3949 write_file($traits_file, $table);
3954 sub all_traits_file {
3955 my ($self, $c) = @_;
3957 my $pop_id = $c->stash->{pop_id};
3958 #$pop_id = $c->stash->{combo_pops_id} if !$pop_id;
3960 my $cache_data = {key => 'all_traits_pop' . $pop_id,
3961 file => 'all_traits_pop_' . $pop_id,
3962 stash_key => 'all_traits_file'
3965 $self->cache_file($c, $cache_data);
3970 sub traits_list_file {
3971 my ($self, $c) = @_;
3973 my $pop_id = $c->stash->{pop_id};
3974 # $pop_id = $c->stash->{combo_pops_id} if !$pop_id;
3976 my $cache_data = {key => 'traits_list_pop' . $pop_id,
3977 file => 'traits_list_pop_' . $pop_id,
3978 stash_key => 'traits_list_file'
3981 $self->cache_file($c, $cache_data);
3986 sub get_acronym_pairs {
3987 my ($self, $c) = @_;
3989 my $pop_id = $c->stash->{pop_id};
3990 #$pop_id = $c->stash->{combo_pops_id} if !$pop_id;
3992 my $dir = $c->stash->{solgs_cache_dir};
3993 opendir my $dh, $dir
3994 or die "can't open $dir: $!\n";
3996 no warnings 'uninitialized';
3998 my ($file) = grep(/traits_acronym_pop_${pop_id}/, readdir($dh));
3999 $dh->close;
4001 my $acronyms_file = catfile($dir, $file);
4003 my @acronym_pairs;
4004 if (-f $acronyms_file)
4006 @acronym_pairs = map { [ split(/\t/) ] } read_file($acronyms_file);
4007 shift(@acronym_pairs); # remove header;
4010 @acronym_pairs = sort {uc $a->[0] cmp uc $b->[0] } @acronym_pairs;
4012 $c->stash->{acronym} = \@acronym_pairs;
4014 return \@acronym_pairs;
4019 sub traits_acronym_table {
4020 my ($self, $c, $acronym_table) = @_;
4022 if (keys %$acronym_table)
4024 my $table = 'Acronym' . "\t" . 'Trait name' . "\n";
4026 foreach (keys %$acronym_table)
4028 $table .= $_ . "\t" . $acronym_table->{$_} . "\n";
4031 $self->traits_acronym_file($c);
4032 my $acronym_file = $c->stash->{traits_acronym_file};
4034 write_file($acronym_file, $table);
4040 sub traits_acronym_file {
4041 my ($self, $c) = @_;
4043 my $pop_id = $c->stash->{pop_id};
4044 #$pop_id = $c->stash->{combo_pops_id} if !$pop_id;
4046 my $cache_data = {key => 'traits_acronym_pop' . $pop_id,
4047 file => 'traits_acronym_pop_' . $pop_id,
4048 stash_key => 'traits_acronym_file'
4051 $self->cache_file($c, $cache_data);
4056 sub analyzed_traits {
4057 my ($self, $c) = @_;
4059 my $training_pop_id = $c->stash->{model_id} || $c->stash->{training_pop_id};
4061 my $dir = $c->stash->{solgs_cache_dir};
4062 opendir my $dh, $dir or die "can't open $dir: $!\n";
4064 my @all_files = grep { /gebv_kinship_[a-zA-Z0-9]/ && -f "$dir/$_" }
4065 readdir($dh);
4067 closedir $dh;
4069 my @traits_files = map { catfile($dir, $_)}
4070 grep {/($training_pop_id)/}
4071 @all_files;
4073 my @traits;
4074 my @traits_ids;
4075 my @si_traits;
4076 my @valid_traits_files;
4078 foreach my $trait_file (@traits_files)
4080 if (-s $trait_file > 1)
4082 my $trait = basename($trait_file);
4083 $trait =~ s/gebv_kinship_//;
4084 $trait =~ s/$training_pop_id|_|combined_pops//g;
4085 $trait =~ s/$dir|\///g;
4087 my $trait_id;
4089 my $acronym_pairs = $self->get_acronym_pairs($c);
4090 if ($acronym_pairs)
4092 foreach my $r (@$acronym_pairs)
4094 if ($r->[0] eq $trait)
4096 my $trait_name = $r->[1];
4097 $trait_name =~ s/\n//g;
4098 $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
4100 push @traits_ids, $trait_id;
4105 $self->get_model_accuracy_value($c, $training_pop_id, $trait);
4106 my $av = $c->stash->{accuracy_value};
4108 if ($av && $av =~ m/\d+/ && $av > 0)
4110 push @si_traits, $trait;
4111 push @valid_traits_files, $trait_file;
4114 push @traits, $trait;
4116 else
4118 @traits_files = grep { $_ ne $trait_file } @traits_files;
4122 $c->stash->{analyzed_traits} = \@traits;
4123 $c->stash->{analyzed_traits_ids} = \@traits_ids;
4124 $c->stash->{analyzed_traits_files} = \@traits_files;
4125 $c->stash->{selection_index_traits} = \@si_traits;
4126 $c->stash->{analyzed_valid_traits_files} = \@valid_traits_files;
4130 sub filter_phenotype_header {
4131 my ($self, $c) = @_;
4133 my @headers = ( 'studyYear', 'studyDbId', 'studyName', 'studyDesign', 'locationDbId', 'locationName', 'germplasmDbId', 'germplasmName', 'germplasmSynonyms', 'observationLevel', 'observationUnitDbId', 'observationUnitName', 'replicate', 'blockNumber', 'plotNumber' );
4135 my $meta_headers = join("\t", @headers);
4136 if ($c)
4138 $c->stash->{filter_phenotype_header} = $meta_headers;
4140 else
4142 return $meta_headers;
4148 sub abbreviate_term {
4149 my ($self, $term) = @_;
4151 my @words = split(/\s/, $term);
4153 my $acronym;
4155 if (scalar(@words) == 1)
4157 $acronym = shift(@words);
4159 else
4161 foreach my $word (@words)
4163 if ($word =~ /^\D/)
4165 my $l = substr($word,0,1,q{});
4166 $acronym .= $l;
4168 else
4170 $acronym .= $word;
4173 $acronym = uc($acronym);
4174 $acronym =~/(\w+)/;
4175 $acronym = $1;
4179 return $acronym;
4184 sub all_gs_traits_list {
4185 my ($self, $c) = @_;
4187 $self->trial_compatibility_file($c);
4188 my $file = $c->stash->{trial_compatibility_file};
4190 my $traits;
4191 my $mv_name = 'all_gs_traits';
4193 my $matview = $c->model('solGS::solGS')->check_matview_exists($mv_name);
4195 if (!$matview)
4197 $c->model('solGS::solGS')->materialized_view_all_gs_traits();
4198 $c->model('solGS::solGS')->insert_matview_public($mv_name);
4200 else
4202 if (!-s $file)
4204 $c->model('solGS::solGS')->refresh_materialized_view_all_gs_traits();
4205 $c->model('solGS::solGS')->update_matview_public($mv_name);
4211 $traits = $c->model('solGS::solGS')->all_gs_traits();
4213 catch
4216 if ($_ =~ /materialized view \"all_gs_traits\" has not been populated/)
4220 $c->model('solGS::solGS')->refresh_materialized_view_all_gs_traits();
4221 $c->model('solGS::solGS')->update_matview_public($mv_name);
4222 $traits = $c->model('solGS::solGS')->all_gs_traits();
4227 $c->stash->{all_gs_traits} = $traits;
4232 sub gs_traits_index {
4233 my ($self, $c) = @_;
4235 $self->all_gs_traits_list($c);
4236 my $all_traits = $c->stash->{all_gs_traits};
4237 my @all_traits = sort{$a cmp $b} @$all_traits;
4239 my @indices = ('A'..'Z');
4240 my %traits_hash;
4241 my @valid_indices;
4243 foreach my $index (@indices)
4245 my @index_traits;
4246 foreach my $trait (@all_traits)
4248 if ($trait =~ /^$index/i)
4250 push @index_traits, $trait;
4253 if (@index_traits)
4255 $traits_hash{$index}=[ @index_traits ];
4259 foreach my $k ( keys(%traits_hash))
4261 push @valid_indices, $k;
4264 @valid_indices = sort( @valid_indices );
4266 my $trait_index;
4267 foreach my $v_i (@valid_indices)
4269 $trait_index .= qq | <a href=/solgs/traits/$v_i>$v_i</a> |;
4270 unless ($v_i eq $valid_indices[-1])
4272 $trait_index .= " | ";
4276 $c->stash->{gs_traits_index} = $trait_index;
4281 sub traits_starting_with {
4282 my ($self, $c, $index) = @_;
4284 $self->all_gs_traits_list($c);
4285 my $all_traits = $c->stash->{all_gs_traits};
4287 my $trait_gr = [
4288 sort { $a cmp $b }
4289 grep { /^$index/i }
4290 uniq @$all_traits
4293 $c->stash->{trait_subgroup} = $trait_gr;
4297 sub hyperlink_traits {
4298 my ($self, $c, $traits) = @_;
4300 if (ref($traits) eq 'ARRAY')
4302 my @traits_urls;
4303 foreach my $tr (@$traits)
4305 push @traits_urls, [ qq | <a href="/solgs/search/result/traits/$tr">$tr</a> | ];
4308 $c->stash->{traits_urls} = \@traits_urls;
4310 else
4312 $c->stash->{traits_urls} = qq | <a href="/solgs/search/result/traits/$traits">$traits</a> |;
4317 sub gs_traits : Path('/solgs/traits') Args(1) {
4318 my ($self, $c, $index) = @_;
4320 my @traits_list;
4322 if ($index =~ /^\w{1}$/)
4324 $self->traits_starting_with($c, $index);
4325 my $traits_gr = $c->stash->{trait_subgroup};
4327 foreach my $trait (@$traits_gr)
4329 $self->hyperlink_traits($c, $trait);
4330 my $trait_url = $c->stash->{traits_urls};
4332 $self->get_trait_details($c, $trait);
4333 push @traits_list, [$trait_url, $c->stash->{trait_def}];
4336 $c->stash( template => $self->template('/search/traits/list.mas'),
4337 index => $index,
4338 traits_list => \@traits_list
4341 else
4343 $c->forward('search');
4348 sub submit_cluster_phenotype_query {
4349 my ($self, $c, $args) = @_;
4351 $c->stash->{r_temp_file} = 'phenotype-data-query';
4352 $self->create_cluster_acccesible_tmp_files($c);
4353 my $out_temp_file = $c->stash->{out_file_temp};
4354 my $err_temp_file = $c->stash->{err_file_temp};
4356 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
4357 my $background_job = $c->stash->{background_job};
4359 my $status;
4361 try
4363 my $pheno_job = CXGN::Tools::Run->run_cluster_perl({
4365 method => ["SGN::Controller::solGS::solGS" => "prep_phenotype_file"],
4366 args => [$args],
4367 load_packages => ['SGN::Controller::solGS::solGS', 'SGN::Context', 'SGN::Model::solGS::solGS'],
4368 run_opts => {
4369 out_file => $out_temp_file,
4370 err_file => $err_temp_file,
4371 working_dir => $temp_dir,
4372 max_cluster_jobs => 1_000_000_000,
4377 $c->stash->{r_job_tempdir} = $pheno_job->tempdir();
4378 $c->stash->{r_job_id} = $pheno_job->job_id();
4379 $c->stash->{cluster_job} = $pheno_job;
4381 unless ($background_job)
4383 $pheno_job->wait();
4386 catch
4388 $status = $_;
4389 $status =~ s/\n at .+//s;
4396 sub submit_cluster_genotype_query {
4397 my ($self, $c, $args) = @_;
4399 $c->stash->{r_temp_file} = 'genotype-data-query';
4400 $self->create_cluster_acccesible_tmp_files($c);
4401 my $out_temp_file = $c->stash->{out_file_temp};
4402 my $err_temp_file = $c->stash->{err_file_temp};
4404 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
4405 my $background_job = $c->stash->{background_job};
4407 my $status;
4409 try
4411 my $geno_job = CXGN::Tools::Run->run_cluster_perl({
4413 method => ["SGN::Controller::solGS::solGS" => "prep_genotype_file"],
4414 args => [$args],
4415 load_packages => ['SGN::Controller::solGS::solGS', 'SGN::Context', 'SGN::Model::solGS::solGS'],
4416 run_opts => {
4417 out_file => $out_temp_file,
4418 err_file => $err_temp_file,
4419 working_dir => $temp_dir,
4420 max_cluster_jobs => 1_000_000_000,
4425 $c->stash->{r_job_tempdir} = $geno_job->tempdir();
4426 $c->stash->{r_job_id} = $geno_job->job_id();
4427 $c->stash->{cluster_job} = $geno_job;
4429 unless ($background_job)
4431 $geno_job->wait();
4435 catch
4437 $status = $_;
4438 $status =~ s/\n at .+//s;
4444 sub prep_phenotype_file {
4445 my ($self,$args) = @_;
4447 my $pheno_file = $args->{phenotype_file};
4448 my $pop_id = $args->{population_id};
4449 my $traits_file = $args->{traits_list_file};
4451 my $model = SGN::Model::solGS::solGS->new({context => 'SGN::Context',
4452 schema => SGN::Context->dbic_schema("Bio::Chado::Schema")});
4454 my $pheno_data = $model->phenotype_data($pop_id);
4456 if ($pheno_data)
4458 my $pheno_data = SGN::Controller::solGS::solGS->format_phenotype_dataset($pheno_data, $traits_file);
4459 write_file($pheno_file, $pheno_data);
4465 sub first_stock_genotype_data {
4466 my ($self, $c, $pr_id) = @_;
4468 $self->first_stock_genotype_file($c, $pr_id);
4469 my $geno_file = $c->stash->{first_stock_genotype_file};
4471 my $geno_data = $c->model('solGS::solGS')->first_stock_genotype_data($pr_id);
4473 if ($geno_data)
4475 write_file($geno_file, $geno_data);
4480 sub prep_genotype_file {
4481 my ($self, $args) = @_;
4483 my $geno_file = $args->{genotype_file};
4484 my $pop_id = ($args->{prediction_id} ? $args->{prediction_id} : $args->{population_id});
4486 my $model = SGN::Model::solGS::solGS->new({context => 'SGN::Context',
4487 schema => SGN::Context->dbic_schema("Bio::Chado::Schema")});
4489 my $geno_data = $model->genotype_data($args);
4491 if ($geno_data)
4493 write_file($geno_file, $geno_data);
4499 sub phenotype_file {
4500 my ($self, $c, $pop_id) = @_;
4502 if (!$pop_id) {
4503 $pop_id = $c->stash->{pop_id}
4504 || $c->stash->{training_pop_id}
4505 || $c->stash->{trial_id};
4508 die "Population id must be provided to get the phenotype data set." if !$pop_id;
4509 $pop_id =~ s/combined_//;
4511 if ($c->stash->{uploaded_reference} || $pop_id =~ /uploaded/) {
4512 if (!$c->user) {
4514 my $page = "/" . $c->req->path;
4516 $c->res->redirect("/solgs/list/login/message?page=$page");
4517 $c->detach;
4522 $self->phenotype_file_name($c, $pop_id);
4523 my $pheno_file = $c->stash->{phenotype_file_name};
4525 no warnings 'uninitialized';
4527 unless ( -s $pheno_file)
4529 $self->traits_list_file($c);
4530 my $traits_file = $c->stash->{traits_list_file};
4532 my $args = {
4533 'population_id' => $pop_id,
4534 'phenotype_file' => $pheno_file,
4535 'traits_list_file' => $traits_file,
4538 if (!$c->stash->{uploaded_reference})
4540 $self->submit_cluster_phenotype_query($c, $args);
4544 $self->get_all_traits($c);
4546 $c->stash->{phenotype_file} = $pheno_file;
4551 sub format_phenotype_dataset {
4552 my ($self, $data_ref, $traits_file) = @_;
4554 my $data = $$data_ref;
4555 my @rows = split (/\n/, $data);
4557 my $formatted_headers = $self->format_phenotype_dataset_headers($rows[0], $traits_file);
4558 $rows[0] = $formatted_headers;
4560 my $formatted_dataset = $self->format_phenotype_dataset_rows(\@rows);
4562 return $formatted_dataset;
4566 sub format_phenotype_dataset_rows {
4567 my ($self, $data_rows) = @_;
4569 my $data = join("\n", @$data_rows);
4571 return $data;
4576 sub format_phenotype_dataset_headers {
4577 my ($self, $raw_headers, $traits_file) = @_;
4579 $raw_headers =~ s/\|\w+:\d+//g;
4580 $raw_headers =~ s/\n//g;
4582 my $traits = $raw_headers;
4584 my $meta_headers= $self->filter_phenotype_header();
4585 my @mh = split("\t", $meta_headers);
4586 foreach my $mh (@mh) {
4587 $traits =~ s/($mh)//g;
4590 $traits =~ s/^\s+|\s+$//g;
4592 write_file($traits_file, $traits) if $traits_file;
4593 my @filtered_traits = split(/\t/, $traits);
4595 $raw_headers =~ s/$traits//g;
4596 my $acronymized_traits = $self->acronymize_traits(\@filtered_traits);
4597 my $formatted_headers = $raw_headers . $acronymized_traits->{acronymized_traits};
4599 return $formatted_headers;
4604 sub acronymize_traits {
4605 my ($self, $traits) = @_;
4607 my $acronym_table = {};
4608 my $cnt = 0;
4609 my $acronymized_traits;
4611 foreach my $trait_name (@$traits)
4613 $cnt++;
4614 my $abbr = $self->abbreviate_term($trait_name);
4616 $abbr = $abbr . '.2' if $cnt > 1 && $acronym_table->{$abbr};
4618 $acronymized_traits .= $abbr;
4619 $acronymized_traits .= "\t" unless $cnt == scalar(@$traits);
4621 $acronym_table->{$abbr} = $trait_name if $abbr;
4622 my $tr_h = $acronym_table->{$abbr};
4625 my $acronym_data = {
4626 'acronymized_traits' => $acronymized_traits,
4627 'acronym_table' => $acronym_table
4630 return $acronym_data;
4634 sub genotype_file {
4635 my ($self, $c, $pred_pop_id) = @_;
4637 my $pop_id = $c->stash->{pop_id};
4638 my $geno_file;
4640 if ($pred_pop_id)
4642 $pop_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id};
4643 $geno_file = $c->stash->{user_selection_list_genotype_data_file};
4646 die "Population id must be provided to get the genotype data set." if !$pop_id;
4648 if ($c->stash->{uploaded_reference} || $pop_id =~ /uploaded/)
4650 if (!$c->user)
4652 my $path = "/" . $c->req->path;
4653 $c->res->redirect("/solgs/list/login/message?page=$path");
4654 $c->detach;
4658 unless ($geno_file)
4660 $self->genotype_file_name($c, $pop_id);
4661 $geno_file = $c->stash->{genotype_file_name};
4664 no warnings 'uninitialized';
4666 unless (-s $geno_file)
4668 my $model_id = $c->stash->{model_id};
4670 my $dir = ($model_id =~ /uploaded/)
4671 ? $c->stash->{solgs_prediction_upload_dir}
4672 : $c->stash->{solgs_cache_dir};
4674 my $trait_abbr = $c->stash->{trait_abbr};
4676 my $tr_file = ($c->stash->{data_set_type} =~ /combined/)
4677 ? "genotype_data_${model_id}_${trait_abbr}_combined"
4678 : "genotype_data_${model_id}.txt";
4680 my $tr_geno_file = catfile($dir, $tr_file);
4682 my $args = {
4683 'population_id' => $pop_id,
4684 'prediction_id' => $pred_pop_id,
4685 'model_id' => $model_id,
4686 'tr_geno_file' => $tr_geno_file,
4687 'genotype_file' => $geno_file,
4688 'cache_dir' => $c->stash->{solgs_cache_dir},
4691 $self->submit_cluster_genotype_query($c, $args);
4694 if ($pred_pop_id)
4696 $c->stash->{pred_genotype_file} = $geno_file;
4698 else
4700 $c->stash->{genotype_file} = $geno_file;
4706 sub get_rrblup_output {
4707 my ($self, $c) = @_;
4709 $c->stash->{pop_id} = $c->stash->{combo_pops_id} if $c->stash->{combo_pops_id};
4711 my $pop_id = $c->stash->{pop_id} || $c->stash->{training_pop_id};
4712 my $trait_abbr = $c->stash->{trait_abbr};
4713 my $trait_name = $c->stash->{trait_name};
4714 my $data_set_type = $c->stash->{data_set_type};
4715 my $prediction_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id};
4717 my ($traits_file, @traits, @trait_pages);
4719 if ($trait_abbr)
4721 $self->run_rrblup_trait($c, $trait_abbr);
4723 else
4725 $traits_file = $c->stash->{selected_traits_file};
4726 my $content = read_file($traits_file);
4728 if ($content =~ /\t/)
4730 @traits = split(/\t/, $content);
4732 else
4734 push @traits, $content;
4737 no warnings 'uninitialized';
4739 foreach my $tr (@traits)
4741 my $acronym_pairs = $self->get_acronym_pairs($c);
4742 my $trait_name;
4743 if ($acronym_pairs)
4745 foreach my $r (@$acronym_pairs)
4747 if ($r->[0] eq $tr)
4749 $trait_name = $r->[1];
4750 $trait_name =~ s/\n//g;
4751 $c->stash->{trait_name} = $trait_name;
4752 $c->stash->{trait_abbr} = $r->[0];
4757 $self->run_rrblup_trait($c, $tr);
4759 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
4760 push @trait_pages, [ qq | <a href="/solgs/trait/$trait_id/population/$pop_id" onclick="solGS.waitPage()">$tr</a>| ];
4764 $c->stash->{combo_pops_analysis_result} = 0;
4766 no warnings 'uninitialized';
4768 if ($data_set_type !~ /combined populations/)
4770 if (scalar(@traits) == 1)
4772 $self->gs_files($c);
4773 $c->stash->{template} = $self->template('population/trait.mas');
4776 if (scalar(@traits) > 1)
4778 $c->stash->{model_id} = $pop_id;
4779 $self->analyzed_traits($c);
4780 $c->stash->{template} = $self->template('/population/multiple_traits_output.mas');
4781 $c->stash->{trait_pages} = \@trait_pages;
4784 else
4786 $c->stash->{combo_pops_analysis_result} = 1;
4792 sub run_rrblup_trait {
4793 my ($self, $c, $trait_abbr) = @_;
4795 my $pop_id = $c->stash->{pop_id};
4796 my $trait_name = $c->stash->{trait_name};
4797 my $data_set_type = $c->stash->{data_set_type};
4799 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
4800 $c->stash->{trait_id} = $trait_id;
4802 no warnings 'uninitialized';
4804 if ($data_set_type =~ /combined populations/i)
4806 my $prediction_id = $c->stash->{prediction_pop_id};
4808 $self->output_files($c);
4810 my $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
4811 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
4813 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
4814 my $trait_info = $trait_id . "\t" . $trait_abbr;
4815 my $trait_file = $self->create_tempfile($temp_dir, "trait_info_${trait_id}");
4816 write_file($trait_file, $trait_info);
4818 my $dataset_file = $self->create_tempfile($temp_dir, "dataset_info_${trait_id}");
4819 write_file($dataset_file, $data_set_type);
4821 my $prediction_population_file = $c->stash->{prediction_population_file};
4823 my $input_files = join("\t",
4824 $c->stash->{trait_combined_pheno_file},
4825 $c->stash->{trait_combined_geno_file},
4826 $trait_file,
4827 $dataset_file,
4828 $prediction_population_file,
4831 my $input_file = $self->create_tempfile($temp_dir, "input_files_combo_${trait_abbr}");
4832 write_file($input_file, $input_files);
4834 if ($c->stash->{prediction_pop_id})
4836 $c->stash->{input_files} = $input_file;
4837 $self->run_rrblup($c);
4839 else
4841 if (-s $c->stash->{gebv_kinship_file} == 0 ||
4842 -s $c->stash->{gebv_marker_file} == 0 ||
4843 -s $c->stash->{validation_file} == 0
4846 $c->stash->{input_files} = $input_file;
4847 # $self->output_files($c);
4848 $self->run_rrblup($c);
4852 else
4854 my $name = "trait_info_${trait_id}_pop_${pop_id}";
4855 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
4856 my $trait_info = $trait_id . "\t" . $trait_abbr;
4857 my $file = $self->create_tempfile($temp_dir, $name);
4858 $c->stash->{trait_file} = $file;
4859 write_file($file, $trait_info);
4861 my $prediction_id = $c->stash->{prediction_pop_id} || $c->stash->{selection_pop_id};
4862 $self->output_files($c);
4864 if ($prediction_id)
4866 #$prediction_id = "prediction_id} if $c->stash->{uploaded_prediction};
4867 my $identifier = $pop_id . '_' . $prediction_id;
4869 $self->prediction_pop_gebvs_file($c, $identifier, $trait_id);
4870 my $pred_pop_gebvs_file = $c->stash->{prediction_pop_gebvs_file};
4872 unless (-s $pred_pop_gebvs_file != 0)
4874 $self->input_files($c);
4875 $self->run_rrblup($c);
4878 else
4880 if (-s $c->stash->{gebv_kinship_file} == 0 ||
4881 -s $c->stash->{gebv_marker_file} == 0 ||
4882 -s $c->stash->{validation_file} == 0
4885 $self->input_files($c);
4886 $self->run_rrblup($c);
4894 sub run_rrblup {
4895 my ($self, $c) = @_;
4897 #get all input files & arguments for rrblup,
4898 #run rrblup and save output in solgs user dir
4899 my $pop_id = $c->stash->{pop_id};
4900 my $trait_id = $c->stash->{trait_id};
4901 my $input_files = $c->stash->{input_files};
4902 my $output_files = $c->stash->{output_files};
4903 my $data_set_type = $c->stash->{data_set_type};
4905 if ($data_set_type !~ /combined populations/)
4907 die "\nCan't run rrblup without a population id." if !$pop_id;
4911 die "\nCan't run rrblup without a trait id." if !$trait_id;
4913 die "\nCan't run rrblup without input files." if !$input_files;
4914 die "\nCan't run rrblup without output files." if !$output_files;
4916 if ($data_set_type !~ /combined populations/)
4919 $c->stash->{r_temp_file} = "gs-rrblup-${trait_id}-${pop_id}";
4921 else
4923 my $combo_pops = $c->stash->{trait_combo_pops};
4924 $combo_pops = join('', split(/,/, $combo_pops));
4925 my $combo_identifier = crc($combo_pops);
4927 $c->stash->{r_temp_file} = "gs-rrblup-combo-${trait_id}-${combo_identifier}";
4930 $c->stash->{r_script} = 'R/solGS/gs.r';
4931 $self->run_r_script($c);
4936 sub r_combine_populations {
4937 my ($self, $c) = @_;
4939 my $combo_pops_id = $c->stash->{combo_pops_id};
4940 my $trait_id = $c->stash->{trait_id};
4941 my $trait_abbr = $c->stash->{trait_abbr};
4943 my $combo_pops_list = $c->stash->{combined_pops_list};
4944 my $pheno_files = $c->stash->{multi_pops_pheno_files};
4945 my $geno_files = $c->stash->{multi_pops_geno_files};
4947 my $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
4948 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
4950 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
4951 my $trait_info = $trait_id . "\t" . $trait_abbr;
4952 my $trait_file = $self->create_tempfile($temp_dir, "trait_info_${trait_id}");
4953 write_file($trait_file, $trait_info);
4955 my $input_files = join ("\t",
4956 $pheno_files,
4957 $geno_files,
4958 $trait_file,
4961 my $output_files = join ("\t",
4962 $combined_pops_pheno_file,
4963 $combined_pops_geno_file,
4966 my $tempfile_input = $self->create_tempfile($temp_dir, "input_files_${trait_id}_combine");
4967 write_file($tempfile_input, $input_files);
4969 my $tempfile_output = $self->create_tempfile($temp_dir, "output_files_${trait_id}_combine");
4970 write_file($tempfile_output, $output_files);
4972 die "\nCan't call combine populations R script without a trait id." if !$trait_id;
4973 die "\nCan't call combine populations R script without input files." if !$input_files;
4974 die "\nCan't call combine populations R script without output files." if !$output_files;
4976 $c->stash->{input_files} = $tempfile_input;
4977 $c->stash->{output_files} = $tempfile_output;
4978 $c->stash->{r_temp_file} = "combine-pops-${trait_id}";
4979 $c->stash->{r_script} = 'R/solGS/combine_populations.r';
4981 $self->run_r_script($c);
4986 sub create_cluster_acccesible_tmp_files {
4987 my ($self, $c) = @_;
4989 my $temp_file_template = $c->stash->{r_temp_file};
4991 my $temp_dir = $c->stash->{analysis_tempfiles_dir} || $c->stash->{solgs_tempfiles_dir};
4993 CXGN::Tools::Run->temp_base($temp_dir);
4994 my ( $in_file_temp, $out_file_temp, $err_file_temp) =
4995 map
4997 my ( undef, $filename ) =
4998 tempfile(
4999 catfile(
5000 CXGN::Tools::Run->temp_base(),
5001 "${temp_file_template}-$_-XXXXXX",
5004 $filename
5006 qw / in out err/;
5008 $c->stash(
5009 in_file_temp => $in_file_temp,
5010 out_file_temp => $out_file_temp,
5011 err_file_temp => $err_file_temp,
5017 sub run_async {
5018 my ($self, $c) = @_;
5020 my $dependency = $c->stash->{dependency};
5021 my $dependency_type = $c->stash->{dependency_type};
5022 my $background_job = $c->stash->{background_job};
5023 my $dependent_job = $c->stash->{dependent_job};
5024 my $temp_file_template = $c->stash->{r_temp_file};
5025 my $job_type = $c->stash->{job_type};
5026 my $model_file = $c->stash->{gs_model_args_file};
5027 my $combine_pops_job_id = $c->stash->{combine_pops_job_id};
5028 my $solgs_tmp_dir = "'" . $c->stash->{solgs_tempfiles_dir} . "'";
5030 my $r_script = $c->stash->{r_commands_file};
5031 my $r_script_args = $c->stash->{r_script_args};
5033 if ($combine_pops_job_id)
5035 $dependency = $combine_pops_job_id;
5038 $dependency =~ s/^://;
5040 my $script_args;
5041 foreach my $arg (@$r_script_args)
5043 $script_args .= $arg;
5044 $script_args .= ' --script_args ' unless ($r_script_args->[-1] eq $arg);
5047 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
5048 my $report_file = $self->create_tempfile($temp_dir, 'analysis_report_args');
5049 $c->stash->{report_file} = $report_file;
5051 my $cmd = 'mx-run solGS::DependentJob'
5052 . ' --dependency_jobs ' . $dependency
5053 . ' --dependency_type ' . $dependency_type
5054 . ' --temp_dir ' . $solgs_tmp_dir
5055 . ' --temp_file_template ' . $temp_file_template
5056 . ' --analysis_report_args_file ' . $report_file
5057 . ' --dependent_type ' . $job_type;
5059 if ($r_script)
5061 $cmd .= ' --r_script ' . $r_script
5062 . ' --script_args ' . $script_args
5063 . ' --gs_model_args_file ' . $model_file;
5066 $c->stash->{r_temp_file} = 'run-async';
5067 $self->create_cluster_acccesible_tmp_files($c);
5069 my $err_file_temp = $c->stash->{err_file_temp};
5070 my $out_file_temp = $c->stash->{out_file_temp};
5072 my $async = CXGN::Tools::Run->run_async($cmd,
5074 working_dir => $c->stash->{solgs_tempfiles_dir},
5075 temp_base => $c->stash->{solgs_tempfiles_dir},
5076 max_cluster_jobs => 1_000_000_000,
5077 out_file => $out_file_temp,
5078 err_file => $err_file_temp,
5082 #my $async_pid = $async->pid();
5084 #$c->stash->{async_pid} = $async_pid;
5085 #$c->stash->{r_job_tempdir} = $async->tempdir();
5086 #$c->stash->{r_job_id} = $async->job_id();
5088 # if ($c->stash->{r_script} =~ /combine_populations/)
5090 # $c->stash->{combine_pops_job_id} = $async->job_id();
5091 # #$c->stash->{r_job_tempdir} = $async->tempdir();
5092 # #$c->stash->{r_job_id} = $async->job_id();
5093 # # $c->stash->{cluster_job} = $r_job;
5099 sub run_r_script {
5100 my ($self, $c) = @_;
5102 my $r_script = $c->stash->{r_script};
5103 my $input_files = $c->stash->{input_files};
5104 my $output_files = $c->stash->{output_files};
5106 $self->create_cluster_acccesible_tmp_files($c);
5107 my $in_file_temp = $c->stash->{in_file_temp};
5108 my $out_file_temp = $c->stash->{out_file_temp};
5109 my $err_file_temp = $c->stash->{err_file_temp};
5111 my $dependency = $c->stash->{dependency};
5112 my $dependency_type = $c->stash->{dependency_type};
5113 my $background_job = $c->stash->{background_job};
5115 my $temp_dir = $c->stash->{analysis_tempfiles_dir} || $c->stash->{solgs_tempfiles_dir};
5118 my $r_cmd_file = $c->path_to($r_script);
5119 copy($r_cmd_file, $in_file_temp)
5120 or die "could not copy '$r_cmd_file' to '$in_file_temp'";
5123 if ($dependency && $background_job)
5125 $c->stash->{r_commands_file} = $in_file_temp;
5126 $c->stash->{r_script_args} = [$input_files, $output_files];
5128 $c->stash->{gs_model_args_file} = $self->create_tempfile($temp_dir, 'gs_model_args');
5130 if ($r_script =~ /combine_populations/)
5132 $c->stash->{job_type} = 'combine_populations';
5133 $self->run_async($c);
5135 elsif ($r_script =~ /gs/)
5137 $c->stash->{job_type} = 'model';
5139 my $model_job = {
5140 'r_command_file' => $in_file_temp,
5141 'input_files' => $input_files,
5142 'output_files' => $output_files,
5143 'r_output_file' => $out_file_temp,
5144 'err_temp_file' => $err_file_temp,
5147 my $model_file = $c->stash->{gs_model_args_file};
5149 nstore $model_job, $model_file
5150 or croak "gs r script: $! serializing model details to '$model_file'";
5152 if ($dependency_type =~ /combine_populations|download_data/)
5154 $self->run_async($c);
5158 else
5160 my $r_job = CXGN::Tools::Run->run_cluster('R', 'CMD', 'BATCH',
5161 '--slave',
5162 "--args $input_files $output_files",
5163 $in_file_temp,
5164 $out_file_temp,
5166 working_dir => $temp_dir,
5167 max_cluster_jobs => 1_000_000_000,
5169 try
5171 $c->stash->{r_job_tempdir} = $r_job->tempdir();
5172 $c->stash->{r_job_id} = $r_job->job_id();
5173 # $c->stash->{cluster_job} = $r_job;
5175 if ($r_script =~ /combine_populations/)
5177 #$c->stash->{job_type} = 'combine_populations';
5178 $c->stash->{combine_pops_job_id} = $r_job->job_id();
5180 my $temp_dir = $c->stash->{solgs_tempfiles_dir};
5181 $c->stash->{gs_model_args_file} = $self->create_tempfile($temp_dir, 'gs_model_args');
5182 #$self->run_async($c);
5185 unless ($background_job)
5187 $r_job->wait();
5190 catch
5192 my $err = $_;
5193 $err =~ s/\n at .+//s;
5197 $err .= "\n=== R output ===\n"
5198 .file($out_file_temp)->slurp
5199 ."\n=== end R output ===\n";
5202 $c->stash->{script_error} = "$r_script";
5209 sub get_solgs_dirs {
5210 my ($self, $c) = @_;
5212 my $geno_version = $c->config->{default_genotyping_protocol};
5213 $geno_version = 'analysis-data' if ($geno_version =~ /undefined/) || !$geno_version;
5214 $geno_version =~ s/\s+//g;
5215 my $tmp_dir = $c->site_cluster_shared_dir;
5216 $tmp_dir = catdir($tmp_dir, $geno_version);
5217 my $solgs_dir = catdir($tmp_dir, "solgs");
5218 my $solgs_cache = catdir($tmp_dir, 'solgs', 'cache');
5219 my $solgs_tempfiles = catdir($tmp_dir, 'solgs', 'tempfiles');
5220 my $correlation_dir = catdir($tmp_dir, 'correlation', 'cache');
5221 my $solgs_upload = catdir($tmp_dir, 'solgs', 'tempfiles', 'prediction_upload');
5222 my $pca_dir = catdir($tmp_dir, 'pca', 'cache');
5223 my $histogram_dir = catdir($tmp_dir, 'histogram', 'cache');
5224 my $log_dir = catdir($tmp_dir, 'log', 'cache');
5225 my $anova_cache = catdir($tmp_dir, 'anova', 'cache');
5226 my $anova_temp = catdir($tmp_dir, 'anova', 'tempfiles');
5228 mkpath (
5230 $solgs_dir, $solgs_cache, $solgs_tempfiles, $solgs_upload,
5231 $correlation_dir, $pca_dir, $histogram_dir, $log_dir, $anova_cache,
5232 $anova_temp,
5234 0, 0755
5237 $c->stash(solgs_dir => $solgs_dir,
5238 solgs_cache_dir => $solgs_cache,
5239 solgs_tempfiles_dir => $solgs_tempfiles,
5240 solgs_prediction_upload_dir => $solgs_upload,
5241 correlation_dir => $correlation_dir,
5242 pca_dir => $pca_dir,
5243 histogram_dir => $histogram_dir,
5244 analysis_log_dir => $log_dir,
5245 anova_cache_dir => $anova_cache,
5246 anova_temp_dir => $anova_temp,
5252 sub cache_file {
5253 my ($self, $c, $cache_data) = @_;
5255 my $cache_dir = $c->stash->{cache_dir};
5257 unless ($cache_dir)
5259 $cache_dir = $c->stash->{solgs_cache_dir};
5262 my $file_cache = Cache::File->new(cache_root => $cache_dir,
5263 lock_level => Cache::File::LOCK_NFS()
5266 $file_cache->purge();
5268 my $file = $file_cache->get($cache_data->{key});
5270 no warnings 'uninitialized';
5272 unless (-s $file > 1)
5274 $file = catfile($cache_dir, $cache_data->{file});
5275 write_file($file);
5276 $file_cache->set($cache_data->{key}, $file, '30 days');
5279 $c->stash->{$cache_data->{stash_key}} = $file;
5280 $c->stash->{cache_dir} = $c->stash->{solgs_cache_dir};
5284 sub template {
5285 my ($self, $file) = @_;
5287 $file =~ s/(^\/)//;
5288 my $dir = '/solgs';
5290 return catfile($dir, $file);
5295 # sub default :Path {
5296 # my ( $self, $c ) = @_;
5297 # $c->forward('search');
5302 =head2 end
5304 Attempt to render a view, if needed.
5306 =cut
5308 #sub render : ActionClass('RenderView') {}
5309 sub begin : Private {
5310 my ($self, $c) = @_;
5312 $self->get_solgs_dirs($c);
5317 # sub end : Private {
5318 # my ( $self, $c ) = @_;
5320 # return if @{$c->error};
5322 # # don't try to render a default view if this was handled by a CGI
5323 # $c->forward('render') unless $c->req->path =~ /\.pl$/;
5325 # # enforce a default texest/html content type regardless of whether
5326 # # we tried to render a default view
5327 # $c->res->content_type('text/html') unless $c->res->content_type;
5329 # # insert our javascript packages into the rendered view
5330 # if( $c->res->content_type eq 'text/html' ) {
5331 # $c->forward('/js/insert_js_pack_html');
5332 # $c->res->headers->push_header('Vary', 'Cookie');
5333 # } else {
5334 # $c->log->debug("skipping JS pack insertion for page with content type ".$c->res->content_type)
5335 # if $c->debug;
5340 =head2 auto
5342 Run for every request to the site.
5344 =cut
5346 # sub auto : Private {
5347 # my ($self, $c) = @_;
5348 # CatalystX::GlobalContext->set_context( $c );
5349 # $c->stash->{c} = $c;
5350 # weaken $c->stash->{c};
5352 # $self->get_solgs_dirs($c);
5353 # # gluecode for logins
5355 # # # unless( $c->config->{'disable_login'} ) {
5356 # # my $dbh = $c->dbc->dbh;
5357 # # if ( my $sp_person_id = CXGN::Login->new( $dbh )->has_session ) {
5359 # # my $sp_person = CXGN::People::Person->new( $dbh, $sp_person_id);
5361 # # $c->authenticate({
5362 # # username => $sp_person->get_username(),
5363 # # password => $sp_person->get_password(),
5364 # # });
5365 # # }
5366 # # }
5368 # return 1;
5374 =head1 AUTHOR
5376 Isaak Y Tecle <iyt2@cornell.edu>
5378 =head1 LICENSE
5380 This library is free software. You can redistribute it and/or modify
5381 it under the same terms as Perl itself.
5383 =cut
5385 __PACKAGE__->meta->make_immutable;