1 package SGN
::Controller
::solGS
::AnalysisQueue
;
4 use namespace
::autoclean
;
5 use File
::Path qw
/ mkpath /;
6 use File
::Spec
::Functions qw
/ catfile catdir/;
7 use File
::Slurp qw
/write_file read_file/;
11 use Storable qw
/ nstore retrieve /;
12 use Carp qw
/ carp confess croak /;
13 use Scalar
::Util
'reftype';
16 BEGIN { extends
'Catalyst::Controller' }
19 sub check_user_login
:Path
('/solgs/check/user/login') Args
(0) {
22 my $user = $c->user();
23 my $ret->{loggedin
} = 0;
27 my $contact = $self->get_user_detail($c);
29 $ret->{contact
} = $contact;
35 $c->res->content_type('application/json');
41 sub save_analysis_profile
:Path
('/solgs/save/analysis/profile') Args
(0) {
44 my $analysis_profile = $c->req->params;
45 $c->stash->{analysis_profile
} = $analysis_profile;
47 my $analysis_page = $analysis_profile->{analysis_page
};
48 $c->stash->{analysis_page
} = $analysis_page;
50 my $ret->{result
} = 0;
52 $self->save_profile($c);
53 my $error_saving = $c->stash->{error
};
62 $c->res->content_type('application/json');
68 sub run_saved_analysis
:Path
('/solgs/run/saved/analysis/') Args
(0) {
71 my $analysis_profile = $c->req->params;
72 $c->stash->{analysis_profile
} = $analysis_profile;
74 $self->parse_arguments($c);
75 $self->structure_output_details($c);
76 $self->run_analysis($c);
78 my $ret->{result
} = $c->stash->{status
};
79 $ret->{arguments
} = $analysis_profile->{arguments
};
83 $c->res->content_type('application/json');
89 sub check_analysis_name
:Path
('/solgs/check/analysis/name') Args
() {
92 my $new_name = $c->req->param('name');
94 my $match = $self->check_analyses_names($c, $new_name);
96 my $ret->{analysis_exists
} = $match;
99 $c->res->content_type('application/json');
105 sub submission_feedback
:Path
('/solgs/submission/feedback/') Args
() {
108 my $job = $c->req->param('job');
109 # $c->controller('solGS::Utils')->stash_json_args($c, $args);
111 my $job_type = $self->get_confirm_msg($c, $job);
112 my $user_id = $c->user()->get_object()->get_sp_person_id();
113 my $referer = $c->req->referer;
115 my $msg = "<p>$job_type</p>"
116 . "<p>You will receive an email when it is completed. "
117 . "You can also check the status of the job on "
118 . "<a href=\"/solpeople/profile/$user_id\">your profile page</a>"
119 . "<p><a href=\"$referer\">[ Go back ]</a></p>";
121 $c->controller('solGS::Utils')->generic_message($c, $msg);
126 sub display_analysis_status
:Path
('/solgs/display/analysis/status') Args
(0) {
129 my $panel_data = $self->get_user_solgs_analyses($c);
131 my $ret->{data
} = $panel_data;
132 my $json = JSON
->new();
133 $ret = $json->encode($ret);
135 $c->res->content_type('application/json');
141 sub check_analyses_names
{
142 my ($self, $c, $new_name) = @_;
144 my $logged_names = $self->check_log_analyses_names($c);
149 $log_match = grep { $_ =~ /$new_name/i } @
$logged_names;
156 my $schema = $c->dbic_schema("Bio::Chado::Schema");
157 $db_match = $schema->resultset("Project::Project")->find({ name
=> $new_name });
160 my $match = $log_match || $db_match ?
1 : 0;
167 sub check_log_analyses_names
{
170 my $log_file = $self->analysis_log_file($c);
171 my $names = qx(cut
-f
2 $log_file);
175 my @names = split(/\n/, $names);
190 $self->analysis_log_file($c);
191 my $log_file = $c->stash->{analysis_log_file
};
193 $self->add_log_headers($c);
195 $self->format_log_entry($c);
196 my $log_entry = $c->stash->{formatted_log_entry
};
198 write_file
($log_file, {binmode => ':utf8', append
=> 1}, $log_entry);
203 sub add_log_headers
{
206 $self->analysis_log_file($c);
207 my $log_file = $c->stash->{analysis_log_file
};
209 my $headers = read_file
($log_file, {binmode => ':utf8'});
213 $headers = 'User_name' .
214 "\t" . 'Analysis_name' .
215 "\t" . "Analysis_page" .
217 "\t" . "Submitted on" .
221 write_file
($log_file, {binmode => ':utf8'}, $headers);
227 sub index_log_file_headers
{
230 no warnings
'uninitialized';
232 $self->analysis_log_file($c);
233 my $log_file = $c->stash->{analysis_log_file
};
235 my @headers = split(/\t/, (read_file
($log_file, {binmode => ':utf8'}))[0]);
237 my $header_index = {};
240 foreach my $header (@headers)
242 $header_index->{$header} = $cnt;
246 $c->stash->{header_index
} = $header_index;
251 sub create_itemized_prediction_log_entries
{
252 my ($self, $c, $analysis_log) = @_;
254 $analysis_log = $self->log_analysis_time($analysis_log);
256 my $json = JSON
->new;
257 my $args = $json->decode($analysis_log->{arguments
});
259 my $trait_ids = $args->{training_traits_ids
};
261 my $analysis_type = $args->{analysis_type
};
264 'training_pop_id' => $args->{training_pop_id
}->[0],
265 'selection_pop_id' => $args->{selection_pop_id
}->[0],
266 'genotyping_protocol_id' => $args->{genotyping_protocol_id
},
267 'data_set_type' => $args->{data_set_type
},
271 foreach my $trait_id (@
$trait_ids)
273 $c->controller('solGS::solGS')->get_trait_details($c, $trait_id);
274 my $trait_abbr = $c->stash->{trait_abbr
};
275 $url_args->{trait_id
} = $trait_id;
278 if ($analysis_type =~ /selection prediction/)
280 $analysis_page = $c->controller('solGS::Path')->selection_page_url($url_args);
284 $analysis_page = $c->controller('solGS::Path')->model_page_url($url_args);
285 $analysis_type = 'single model';
288 my $analysis_name = $analysis_log->{analysis_name
} . ' -- ' . $trait_abbr;
290 $args->{analysis_page
} = $analysis_page;
291 $args->{analysis_name
} = $analysis_name;
292 $args->{trait_id
} = [$trait_id];
293 $args->{training_traits_ids
} = [$trait_id];
294 $args->{analysis_type
} = $analysis_type;
296 $entries .= join("\t", (
297 $analysis_log->{user_name
},
301 $args->{analysis_time
},
302 $json->encode($args),)
314 sub log_analysis_time
{
315 my ($self, $analysis_log ) = @_;
317 my $analysis_time = POSIX
::strftime
("%m/%d/%Y %H:%M", localtime);
319 my $json = JSON
->new;
320 my $args = $json->decode($analysis_log->{arguments
});
322 $args->{analysis_time
} = $analysis_time;
323 $analysis_log->{arguments
} = $json->encode($args);
325 return $analysis_log;
330 sub format_log_entry
{
333 my $profile = $c->stash->{analysis_profile
};
334 $profile= $self->log_analysis_time($profile);
335 my $args = $profile->{arguments
};
337 my $json = JSON
->new;
338 my $time = $json->decode($args)->{analysis_time
};
340 my $traits_args = $json->decode($args);
341 my $traits_ids = $traits_args->{training_traits_ids
} || $traits_args->{trait_id
};
342 my @traits_ids = ref($traits_ids) eq 'ARRAY' ? @
$traits_ids : ($traits_ids);
345 my $analysis_type = $traits_args->{analysis_type
};
347 if (@traits_ids > 1 && $analysis_type =~ /selection/)
349 $analysis_page = $traits_args->{referer
};
353 $analysis_page = $traits_args->{analysis_page
};
356 my $entry = join("\t", (
357 $profile->{user_name
},
358 $profile->{analysis_name
},
367 if (@traits_ids > 1 && $analysis_type =~ /model|selection/ )
369 my $traits_entries = $self->create_itemized_prediction_log_entries($c, $profile);
370 $entry .= $traits_entries;
373 $c->stash->{formatted_log_entry
} = $entry;
378 sub analysis_report_job_args
{
379 my ($self, $c, $status_check_duration) = @_;
381 my $analysis_details = $c->stash->{bg_job_output_details
};
383 my $temp_dir = $c->stash->{analysis_tempfiles_dir
} || $c->stash->{solgs_tempfiles_dir
} ;
385 my $temp_file_template = "analysis-status";
386 my $cluster_files = $c->controller('solGS::AsyncJob')->create_cluster_accessible_tmp_files($c, $temp_file_template);
387 my $out_file = $cluster_files->{out_file_temp
};
388 my $err_file = $cluster_files->{err_file_temp
};
389 my $in_file = $cluster_files->{in_file_temp
};
392 'temp_dir' => $temp_dir,
393 'out_file' => $out_file,
394 'err_file' => $err_file,
395 'cluster_host' => 'localhost'
398 my $report_file = $c->controller('solGS::Files')->create_tempfile($temp_dir, 'analysis-report-args');
399 nstore
$analysis_details, $report_file
400 or croak
"analysis_report_job_args: $! serializing output_details to $report_file";
402 my $job_config = $c->controller('solGS::AsyncJob')->create_cluster_config($c, $config_args);
404 $status_check_duration = ' --status_check_duration ' . $status_check_duration if $status_check_duration;
406 my $cmd = 'mx-run solGS::AnalysisReport'
407 . ' --output_details_file ' . $report_file
408 . $status_check_duration;
413 'config' => $job_config,
414 'background_job'=> $c->stash->{background_job
},
415 'temp_dir' => $temp_dir,
418 $c->stash->{analysis_report_job_args
} = $job_args;
423 sub get_analysis_report_job_args_file
{
424 my ($self, $c, $status_check_duration) = @_;
426 $self->analysis_report_job_args($c, $status_check_duration);
427 my $analysis_job_args = $c->stash->{analysis_report_job_args
};
429 my $temp_dir = $c->stash->{solgs_tempfiles_dir
};
431 my $report_file = $c->controller('solGS::Files')->create_tempfile($temp_dir, 'analysis-report-job-args');
432 nstore
$analysis_job_args, $report_file
433 or croak
"get_analysis_report_job_args_file: $! serializing output_details to $report_file";
435 $c->stash->{analysis_report_job_args_file
} = $report_file;
440 sub email_analysis_report
{
443 $self->analysis_report_job_args($c);
444 my $job_args = $c->stash->{analysis_report_job_args
};
446 my $job = $c->controller('solGS::AsyncJob')->submit_job_cluster($c, $job_args);
450 sub parse_arguments
{
453 my $analysis_data = $c->stash->{analysis_profile
};
454 my $arguments = $analysis_data->{arguments
};
455 my $data_set_type = $analysis_data->{data_set_type
};
459 $c->controller('solGS::Utils')->stash_json_args($c, $arguments);
465 sub structure_output_details
{
468 my $analysis_data = $c->stash->{analysis_profile
};
469 my $analysis_page = $analysis_data->{analysis_page
};
471 my $referer = $c->req->referer;
472 my $base = $c->controller('solGS::Path')->clean_base_name($c);
473 my $output_details = {};
475 my $match_pages = 'solgs\/traits\/all\/population\/'
477 . '|solgs\/model\/combined\/trials\/'
478 . '|solgs\/models\/combined\/trials\/';
480 if ($analysis_page =~ m/$match_pages/)
482 $output_details = $self->structure_training_modeling_output($c);
484 elsif ( $analysis_page =~ m/solgs\/population\
// )
486 $output_details = $self->structure_training_single_pop_data_output($c);
488 elsif ($analysis_page =~ m/solgs\/populations\
/combined\//)
490 $output_details = $self->structure_training_combined_pops_data_output($c);
492 elsif ( $analysis_page =~ m/solgs\/selection\
/(\d+|\w+_\d+)\/model\
/|solgs\/combined\
/model\/\d
+\
/selection\// )
494 $output_details = $self->structure_selection_prediction_output($c);
496 elsif ( $analysis_page =~ m/kinship\/analysis
/ )
498 $output_details = $self->structure_kinship_analysis_output($c);
500 elsif ( $analysis_page =~ m/pca\/analysis
/ )
502 $output_details = $self->structure_pca_analysis_output($c);
504 elsif ( $analysis_page =~ m/cluster\/analysis
/ )
506 $output_details = $self->structure_cluster_analysis_output($c);
509 $self->analysis_log_file($c);
510 my $log_file = $c->stash->{analysis_log_file
};
512 my $mail_list = $self->mailing_list($c);
514 $output_details->{analysis_profile
} = $analysis_data;
515 $output_details->{contact_page
} = $base . '/contact/form';
516 $output_details->{data_set_type
} = $c->stash->{data_set_type
};
517 $output_details->{analysis_log_file
} = $log_file;
518 $output_details->{host
} = qq | $base |;
519 $output_details->{referer
} = qq | $referer |;
520 $output_details->{mailing_list
} = $mail_list;
522 $c->stash->{bg_job_output_details
} = $output_details;
529 my $mail_list = $c->config->{cluster_job_email
};
533 $mail_list = 'cluster-jobs@solgenomics.net';
539 sub structure_kinship_analysis_output
{
542 my $analysis_data = $c->stash->{analysis_profile
};
543 my $analysis_page = $analysis_data->{analysis_page
};
545 my $protocol_id = $c->stash->{genotyping_protocol_id
};
547 $c->controller('solGS::Kinship')->stash_data_str_kinship_pop_id($c);
548 my $pop_id = $c->stash->{kinship_pop_id
};
550 my $base = $c->controller('solGS::Path')->clean_base_name($c);
552 my $kinship_page = $base . $analysis_page;
553 $analysis_data->{analysis_page
} = $kinship_page;
555 my %output_details = ();
557 my $trait_id = $c->stash->{trait_id
};
559 $c->controller('solGS::Files')->genotype_file_name($c, $pop_id, $protocol_id);
560 my $geno_file = $c->stash->{genotype_file_name
};
562 my $coef_files = $c->controller('solGS::Kinship')->get_kinship_coef_files($c, $pop_id, $protocol_id, $trait_id);
563 my $matrix_file = $coef_files->{matrix_file_adj
};
565 $output_details{'kinship_' . $pop_id} = {
566 'output_page' => $kinship_page,
567 'kinship_pop_id' => $pop_id,
568 'genotype_file' => $geno_file,
569 'matrix_file' => $matrix_file,
572 return \
%output_details;
576 sub structure_pca_analysis_output
{
579 my $analysis_data = $c->stash->{analysis_profile
};
580 my $analysis_page = $analysis_data->{analysis_page
};
582 my $pop_id = $c->stash->{pca_pop_id
};
584 my $base = $c->controller('solGS::Path')->clean_base_name($c);
586 my $pca_page = $base . $analysis_page;
587 $analysis_data->{analysis_page
} = $pca_page;
589 my %output_details = ();
590 # $c->controller('solGS::Files')->genotype_file_name($c, $pop_id, $protocol_id);
591 my $geno_file = $c->stash->{genotype_file_name
};
593 $c->stash->{file_id
} = $c->controller('solGS::Files')->create_file_id($c);
594 $c->controller('solGS::pca')->pca_scores_file($c);
595 my $scores_file = $c->stash->{pca_scores_file
};
597 $output_details{'pca_' . $pop_id} = {
598 'output_page' => $pca_page,
599 'pca_pop_id' => $pop_id,
600 'genotype_file' => $geno_file,
601 'scores_file' => $scores_file,
604 return \
%output_details;
609 sub structure_cluster_analysis_output
{
612 my $analysis_data = $c->stash->{analysis_profile
};
613 my $analysis_page = $analysis_data->{analysis_page
};
615 my $pop_id = $c->stash->{cluster_pop_id
};
617 my $base = $c->controller('solGS::Path')->clean_base_name($c);
618 my $cluster_page = $base . $analysis_page;
619 $analysis_data->{analysis_page
} = $cluster_page;
621 my %output_details = ();
622 # $c->controller('solGS::Files')->genotype_file_name($c, $pop_id, $protocol_id);
623 # my $geno_file = $c->stash->{genotype_file_name};
625 $c->stash->{file_id
} = $c->controller('solGS::Files')->create_file_id($c);
626 $c->controller('solGS::Cluster')->kcluster_result_file($c);
627 my $result_file = $c->stash->{'k-means_result_file'};
629 $output_details{'cluster_' . $pop_id} = {
630 'output_page' => $cluster_page,
631 'cluster_pop_id' => $pop_id,
632 'input_file' => $input_file,
633 'result_file' => $result_file,
636 return \
%output_details;
641 sub structure_training_modeling_output
{
644 my $analysis_data = $c->stash->{analysis_profile
};
645 my $analysis_page = $analysis_data->{analysis_page
};
647 my $pop_id = $c->stash->{pop_id
};
648 my $combo_pops_id = $c->stash->{combo_pops_id
};
649 my $protocol_id = $c->stash->{genotyping_protocol_id
};
651 my @traits_ids = @
{$c->stash->{training_traits_ids
}} if $c->stash->{training_traits_ids
};
652 my $referer = $c->req->referer;
654 my $base = $c->controller('solGS::Path')->clean_base_name($c);
656 'training_pop_id' => $pop_id,
657 'genotyping_protocol_id' => $protocol_id,
660 my %output_details = ();
662 foreach my $trait_id (@traits_ids)
664 $url_args->{trait_id
} = $trait_id;
666 $c->stash->{cache_dir
} = $c->stash->{solgs_cache_dir
};
668 $c->controller('solGS::solGS')->get_trait_details($c, $trait_id);
669 $c->controller('solGS::Files')->rrblup_training_gebvs_file($c);
671 my $trait_abbr = $c->stash->{trait_abbr
};
675 if ( $referer =~ m/solgs\/population\
// )
677 $url_args->{data_set_type
} = 'single population';
679 my $model_page = $c->controller('solGS::Path')->model_page_url($url_args);
680 $trait_page = $base . $model_page;
682 if ($analysis_page =~ m/solgs\/traits\
/all\/population\
//)
684 my $traits_selection_id = $c->controller('solGS::Gebvs')->create_traits_selection_id(\
@traits_ids);
685 $analysis_data->{analysis_page
} = $base . "solgs/traits/all/population/" . $pop_id
686 . '/traits/' . $traits_selection_id
687 . '/gp/' . $protocol_id;
689 $c->controller('solGS::Gebvs')->catalogue_traits_selection($c, \
@traits_ids);
693 if ( $referer =~ m/solgs\/search\
/trials\/trait\
// && $analysis_page =~ m/solgs\/trait\
// )
695 $url_args->{data_set_type
} = 'single population';
697 my $model_page = $c->controller('solGS::Path')->model_page_url($url_args);
698 $trait_page = $base . $model_page;
701 if ( $referer =~ m/solgs\/populations\
/combined\// )
703 $url_args->{data_set_type
} = 'combined populations';
705 my $model_page = $c->controller('solGS::Path')->model_page_url($url_args);
706 $trait_page = $base . $model_page;
708 if ($analysis_page =~ m/solgs\/models\
/combined\/trials\
//)
710 my $traits_selection_id = $c->controller('solGS::Gebvs')->create_traits_selection_id(\
@traits_ids);
711 $analysis_data->{analysis_page
} = $base . "solgs/models/combined/trials/"
713 . '/traits/' . $traits_selection_id
714 . '/gp/' . $protocol_id;
716 $c->controller('solGS::Gebvs')->catalogue_traits_selection($c, \
@traits_ids);
720 if ( $analysis_page =~ m/solgs\/model\
/combined\/trials\
// )
722 $url_args->{data_set_type
} = 'combined populations';
724 my $model_page = $c->controller('solGS::Path')->model_page_url($url_args);
726 $trait_page = $base . $model_page;
728 $c->stash->{combo_pops_id
} = $combo_pops_id;
729 $c->controller('solGS::combinedTrials')->cache_combined_pops_data($c);
732 $output_details{'trait_id_' . $trait_abbr} = {
733 'trait_id' => $trait_id,
734 'trait_name' => $c->stash->{trait_name
},
735 'trait_page' => $trait_page,
736 'gebv_file' => $c->stash->{rrblup_training_gebvs_file
},
738 'phenotype_file' => $c->stash->{trait_combined_pheno_file
},
739 'genotype_file' => $c->stash->{trait_combined_geno_file
},
740 'data_set_type' => $c->stash->{data_set_type
},
744 return \
%output_details;
748 sub structure_training_single_pop_data_output
{
751 my $pop_id = $c->stash->{pop_id
};
752 my $protocol_id = $c->stash->{genotyping_protocol_id
};
754 my $base = $c->controller('solGS::Path')->clean_base_name($c);
756 'training_pop_id' => $pop_id,
757 'genotyping_protocol_id' => $protocol_id,
758 'data_set_type' => 'single population'
761 my $training_pop_page = $c->controller('solGS::Path')->training_page_url($args);
762 my $population_page = $base . $training_pop_page;
764 my $data_set_type = $c->stash->{data_set_type
};
769 my %output_details = ();
771 if ($pop_id =~ /list/)
773 my $files = $c->controller('solGS::List')->create_list_pop_data_files($c);
774 $pheno_file = $files->{pheno_file
};
775 $geno_file = $files->{geno_file
};
777 $c->controller('solGS::List')->create_list_population_metadata_file($c, $pop_id);
778 $c->controller('solGS::List')->list_population_summary($c);
779 $pop_name = $c->stash->{project_name
};
781 elsif ($pop_id =~ /dataset/)
783 my $files = $c->controller('solGS::Dataset')->create_dataset_pop_data_files($c,);
784 $pheno_file = $files->{pheno_file
};
785 $geno_file = $files->{geno_file
};
787 $c->controller('solGS::Dataset')->create_dataset_population_metadata_file($c);
788 $c->controller('solGS::Dataset')->dataset_population_summary($c);
789 $pop_name = $c->stash->{project_name
};
793 $c->controller('solGS::Files')->phenotype_file_name($c, $pop_id);
794 $c->controller('solGS::Files')->genotype_file_name($c, $pop_id, $protocol_id);
795 $pheno_file = $c->stash->{phenotype_file_name
};
796 $geno_file = $c->stash->{genotype_file_name
};
798 $c->controller('solGS::Search')->get_project_details($c, $pop_id);
799 $pop_name = $c->stash->{project_name
};
802 $output_details{'population_id_' . $pop_id} = {
803 'population_page' => $population_page,
804 'population_id' => $pop_id,
805 'population_name' => $pop_name,
806 'phenotype_file' => $pheno_file,
807 'genotype_file' => $geno_file,
808 'data_set_type' => $data_set_type,
811 return \
%output_details;
815 sub structure_training_combined_pops_data_output
{
818 my $combo_pops_id = $c->stash->{combo_pops_id
};
819 my $protocol_id = $c->stash->{genotyping_protocol_id
};
821 my $base = $c->controller('solGS::Path')->clean_base_name($c);
823 'training_pop_id' => $combo_pops_id,
824 'genotyping_protocol_id' => $protocol_id,
825 'data_set_type' => 'combined populations'
828 my $training_pop_page = $c->controller('solGS::Path')->training_page_url($args);
830 my $combined_pops_page = $base . $training_pop_page;
831 my @combined_pops_ids = @
{$c->stash->{combo_pops_list
}};
833 $c->controller('solGS::combinedTrials')->multi_pops_pheno_files($c, \
@combined_pops_ids);
834 $c->controller('solGS::combinedTrials')->multi_pops_geno_files($c, \
@combined_pops_ids, $protocol_id);
836 my $multi_ph_files = $c->stash->{multi_pops_pheno_files
};
837 my @pheno_files = split(/\t/, $multi_ph_files);
838 my $multi_gen_files = $c->stash->{multi_pops_geno_files
};
839 my @geno_files = split(/\t/, $multi_gen_files);
840 my $match_status = $c->stash->{pops_with_no_genotype_match
};
842 my %output_details = ();
843 foreach my $pop_id (@combined_pops_ids)
845 $c->controller('solGS::Search')->get_project_details($c, $pop_id);
846 my $population_name = $c->stash->{project_name
};
849 'training_pop_id' => $pop_id,
850 'genotyping_protocol_id' => $protocol_id,
851 'data_set_type' => 'single population'
854 my $training_pop_page = $c->controller('solGS::Path')->training_page_url($args);
856 my $population_page = $base . $training_pop_page;
858 $c->controller('solGS::Files')->phenotype_file_name($c, $pop_id);
859 my $pheno_file = $c->stash->{phenotype_file_name
};
861 $c->controller('solGS::Files')->phenotype_file_name($c, $pop_id, $protocol_id);
862 my $geno_file = $c->stash->{genotype_file_name
};
864 $output_details{'population_id_' . $pop_id} = {
865 'population_page' => $population_page,
866 'population_id' => $pop_id,
867 'population_name' => $population_name,
868 'combo_pops_id' => $combo_pops_id,
869 'phenotype_file' => $pheno_file,
870 'genotype_file' => $geno_file,
871 'data_set_type' => $c->stash->{data_set_type
},
875 $output_details{no_match
} = $match_status;
876 $output_details{combined_pops_page
} = $combined_pops_page;
878 return \
%output_details;
882 sub structure_selection_prediction_output
{
885 my @traits_ids = @
{$c->stash->{training_traits_ids
}} if $c->stash->{training_traits_ids
};
886 my $protocol_id = $c->stash->{genotyping_protocol_id
};
888 my $referer = $c->req->referer;
889 my $base = $c->controller('solGS::Path')->clean_base_name($c);
890 my $data_set_type = $c->stash->{data_set_type
};
891 my %output_details = ();
893 foreach my $trait_id (@traits_ids)
895 $c->controller('solGS::solGS')->get_trait_details($c, $trait_id);
896 my $trait_id = $c->stash->{trait_id
};
897 my $trait_abbr = $c->stash->{trait_abbr
};
898 my $trait_name = $c->stash->{trait_name
};
900 my $tr_pop_id = $c->stash->{training_pop_id
};
901 my $sel_pop_id = $c->stash->{selection_pop_id
};
910 'training_pop_id' => $tr_pop_id,
911 'selection_pop_id' => $sel_pop_id,
912 'trait_id' => $trait_id,
913 'genotyping_protocol_id' => $protocol_id,
914 'data_set_type' => $data_set_type,
917 if ($data_set_type =~ /combined populations/)
919 $tr_pop_page = $c->controller('solGS::Path')->training_page_url($url_args);
921 $tr_pop_page = $base . $tr_pop_page;
922 $tr_pop_name = 'Training population ' . $tr_pop_id;
923 $sel_pop_page = $c->controller('solGS::Path')->selection_page_url($url_args);
924 $sel_pop_page = $base . $sel_pop_page;
926 $model_page = $c->controller('solGS::Path')->model_page_url($url_args);
927 $model_page = $base . $model_page;
931 my $training_pop_page = $c->controller('solGS::Path')->training_page_url($url_args);
933 $tr_pop_page = $base . $training_pop_page;
934 if ($tr_pop_id =~ /list/)
936 $c->stash->{list_id
} = $tr_pop_id =~ s/\w+_//r;
937 $c->controller('solGS::List')->list_population_summary($c);
938 $tr_pop_name = $c->stash->{project_name
};
940 elsif ($tr_pop_id =~ /dataset/)
942 $c->stash->{dataset_id
} = $tr_pop_id =~ s/\w+_//r;
943 $c->controller('solGS::Dataset')->dataset_population_summary($c);
944 $tr_pop_name = $c->stash->{project_name
};
948 $c->controller('solGS::Search')->get_project_details($c, $tr_pop_id);
949 $tr_pop_name = $c->stash->{project_name
};
952 $sel_pop_page = $c->controller('solGS::Path')->selection_page_url($url_args);
953 $sel_pop_page = $base . $sel_pop_page;
955 $model_page = $c->controller('solGS::Path')->model_page_url($url_args);
956 $model_page = $base . $model_page;
959 if ($sel_pop_id =~ /list/)
961 $c->stash->{list_id
} = $sel_pop_id =~ s/\w+_//r;
962 $c->controller('solGS::List')->list_population_summary($c, $sel_pop_id);
963 $c->controller('solGS::List')->create_list_population_metadata_file($c, $sel_pop_id);
965 $sel_pop_name = $c->stash->{selection_pop_name
};
967 elsif ($sel_pop_id =~ /dataset/)
969 $c->stash->{dataset_id
} = $sel_pop_id =~ s/\w+_//r;
970 $c->controller('solGS::Dataset')->create_dataset_population_metadata_file($c);
971 $c->controller('solGS::Dataset')->dataset_population_summary($c);
972 $sel_pop_name = $c->stash->{selection_pop_name
};
976 $c->controller('solGS::Search')->get_project_details($c, $sel_pop_id);
977 $sel_pop_name = $c->stash->{project_name
};
980 $c->controller('solGS::Files')->rrblup_selection_gebvs_file($c, $tr_pop_id, $sel_pop_id, $trait_id);
981 my $gebv_file = $c->stash->{rrblup_selection_gebvs_file
};
983 $c->controller('solGS::Files')->genotype_file_name($c, $sel_pop_id, $protocol_id);
984 my $selection_geno_file = $c->stash->{genotype_file_name
};
986 $output_details{'trait_id_' . $trait_id} = {
987 'training_pop_page' => $tr_pop_page,
988 'training_pop_id' => $tr_pop_id,
989 'training_pop_name' => $tr_pop_name,
990 'selection_pop_name' => $sel_pop_name,
991 'selection_pop_page' => $sel_pop_page,
992 'trait_name' => $trait_name,
993 'trait_id' => $trait_id,
994 'model_page' => $model_page,
995 'gebv_file' => $gebv_file,
996 'selection_geno_file' => $selection_geno_file,
997 'data_set_type' => $data_set_type
1002 return \
%output_details;
1008 my ($self, $c) = @_;
1010 $c->stash->{background_job
} = 1;
1012 my $analysis_profile = $c->stash->{analysis_profile
};
1013 my $analysis_page = $analysis_profile->{analysis_page
};
1014 $c->stash->{analysis_page
} = $analysis_page;
1016 my $base = $c->controller('solGS::Path')->clean_base_name($c);
1017 $analysis_page =~ s/$base//;
1018 my $referer = $c->req->referer;
1020 my @selected_traits = @
{$c->stash->{training_traits_ids
}} if $c->stash->{training_traits_ids
};
1024 my $modeling_pages = 'solgs\/traits\/all\/population\/'
1025 . '|solgs\/models\/combined\/trials\/'
1027 . '|solgs\/model\/combined\/trials\/';
1029 my $selection_pages = '/solgs\/selection\/(\d+|\w+_\d+)\/model\/'
1030 . '|solgs\/combined\/model\/(\d+|\w+_\d+)\/selection\/';
1032 my $training_pages = '/solgs\/population\/'
1033 . '|solgs\/populations\/combined\/';
1035 if ($analysis_page =~ $training_pages)
1037 $self->create_training_data($c);
1039 elsif ($analysis_page =~ /$modeling_pages/)
1041 $self->predict_training_traits($c);
1043 elsif ($analysis_page =~ /$selection_pages/)
1045 $self->predict_selection_traits($c);
1047 elsif ($analysis_page =~ /kinship\/analysis
/)
1049 $self->run_kinship_analysis($c);
1051 elsif ($analysis_page =~ /pca\/analysis
/)
1053 $self->run_pca_analysis($c);
1055 elsif ($analysis_page =~ /cluster\/analysis
/)
1057 $self->run_cluster_analysis($c);
1061 $c->stash->{status
} = 'Error: Unknown job';
1062 print STDERR
"\n Uknown job.\n";
1070 $c->stash->{status
} = "run_analysis failed. Please try re-running the analysis and wait for it to finish. $error[0]";
1074 $c->stash->{status
} = 'Submitted';
1075 $self->update_analysis_progress($c);
1083 sub create_training_data
{
1084 my ($self, $c) = @_;
1086 my $analysis_page = $c->stash->{analysis_page
};
1087 my $protocol_id = $c->stash->{genotyping_protocol_id
};
1089 # if ($analysis_page =~ /solgs\/population\//)
1091 my $pop_id = $c->stash->{model_id
};
1093 if ($analysis_page =~ /solgs\/population\
//)
1095 my $pop_id = $c->stash->{model_id
};
1097 if ($pop_id =~ /list/)
1099 $c->controller('solGS::List')->submit_list_training_data_query($c);
1100 $c->controller('solGS::List')->create_list_population_metadata_file($c, $pop_id);
1102 elsif ($pop_id =~ /dataset/)
1104 $c->controller('solGS::Dataset')->submit_dataset_training_data_query($c);
1105 $c->controller('solGS::Dataset')->create_dataset_population_metadata_file($c);
1109 $c->controller('solGS::AsyncJob')->submit_cluster_training_pop_data_query($c, [$pop_id], $protocol_id);
1112 elsif ($analysis_page =~ /solgs\/populations\
/combined\//)
1114 my $trials = $c->stash->{combo_pops_list
};
1115 $c->controller('solGS::AsyncJob')->submit_cluster_training_pop_data_query($c, $trials, $protocol_id);
1121 sub predict_training_traits
{
1122 my ($self, $c) = @_;
1124 my $analysis_page = $c->stash->{analysis_page
};
1125 my $selected_traits = $c->stash->{training_traits_ids
};
1127 $c->stash->{training_traits_ids
} = [$c->stash->{trait_id
}] if !$c->stash->{training_traits_ids
};
1129 if ($analysis_page =~ /solgs\/traits\
/all\/population\
/|solgs\/trait\
//)
1131 $c->controller('solGS::solGS')->build_multiple_traits_models($c);
1133 elsif ($analysis_page =~ /solgs\/models\
/combined\/trials\
/|solgs\/model\
/combined\/trials\
// )
1135 if ($c->stash->{data_set_type
} =~ /combined populations/)
1137 $c->controller('solGS::combinedTrials')->combine_data_build_multiple_traits_models($c);
1144 sub predict_selection_traits
{
1145 my ($self, $c) = @_;
1147 $c->stash->{prerequisite_type
} = 'selection_pop_download_data';
1148 my $training_pop_id = $c->stash->{training_pop_id
};
1149 my $selection_pop_id = $c->stash->{selection_pop_id
};
1151 if ($selection_pop_id =~ /list/)
1153 $c->stash->{list_id
} = $selection_pop_id =~ s/\w+_//r;
1154 $c->controller('solGS::List')->get_genotypes_list_details($c);
1155 $c->controller('solGS::List')->create_list_population_metadata_file($c, $selection_pop_id);
1157 elsif ($selection_pop_id =~ /dataset/)
1159 $c->stash->{dataset_id
} = $selection_pop_id =~ s/\w+_//r;
1160 $c->controller('solGS::Dataset')->create_dataset_population_metadata_file($c);
1163 my $referer = $c->req->referer;
1164 if ($referer =~ /solgs\/trait\
/|solgs\/traits\
/all\/population\
//)
1166 $c->controller('solGS::solGS')->predict_selection_pop_multi_traits($c);
1168 elsif ($referer =~ /\/combined\
//)
1170 $c->stash->{data_set_type
} = 'combined populations';
1171 $c->controller('solGS::combinedTrials')->predict_selection_pop_combined_pops_model($c);
1177 sub run_kinship_analysis
{
1178 my ($self, $c) = @_;
1180 my $analysis_page = $c->stash->{analysis_page
};
1182 if ($analysis_page = ~/kinship\/analysis
/)
1184 $c->controller('solGS::Kinship')->run_kinship($c);
1190 sub run_pca_analysis
{
1191 my ($self, $c) = @_;
1193 my $analysis_page = $c->stash->{analysis_page
};
1195 if ($analysis_page = ~/pca\/analysis
/)
1197 $c->controller('solGS::pca')->run_pca($c);
1203 sub run_cluster_analysis
{
1204 my ($self, $c) = @_;
1206 my $analysis_page = $c->stash->{analysis_page
};
1208 if ($analysis_page = ~/cluster\/analysis
/)
1210 $c->controller('solGS::Cluster')->run_cluster($c);
1215 sub update_analysis_progress
{
1216 my ($self, $c) = @_;
1218 my $analysis_data = $c->stash->{analysis_profile
};
1219 my $analysis_name= $analysis_data->{analysis_name
};
1220 my $status = $c->stash->{status
};
1222 $self->analysis_log_file($c);
1223 my $log_file = $c->stash->{analysis_log_file
};
1225 my @contents = read_file
($log_file, {binmode => ':utf8'});
1227 map{ $contents[$_] =~ m/\t$analysis_name\t/
1228 ?
$contents[$_] =~ s/error|submitted/$status/ig
1229 : $contents[$_] } 0..$#contents;
1231 write_file
($log_file, {binmode => ':utf8'}, @contents);
1236 sub get_user_detail
{
1237 my ($self, $c) = @_;
1239 my $user = $c->user();
1244 my $private_email = $user->get_private_email();
1245 my $public_email = $user->get_contact_email();
1247 my $email = $public_email
1251 my $salutation = $user->get_salutation();
1252 my $first_name = $user->get_first_name();
1253 my $last_name = $user->get_last_name();
1254 my $user_role = $user->get_object->get_user_type();
1255 my $user_id = $user->get_object()->get_sp_person_id();
1256 my $user_name = $user->id();
1259 'first_name' => $first_name,
1261 'user_role' => $user_role,
1262 'user_id' => $user_id,
1263 'user_name' => $user_name,
1273 sub analysis_log_file
{
1274 my ($self, $c) = @_;
1276 $self->create_analysis_log_dir($c);
1277 my $log_dir = $c->stash->{analysis_log_dir
};
1279 $c->stash->{cache_dir
} = $log_dir;
1282 key
=> 'analysis_log',
1283 file
=> 'analysis_log',
1284 stash_key
=> 'analysis_log_file'
1287 $c->controller('solGS::Files')->cache_file($c, $cache_data);
1292 sub get_confirm_msg
{
1293 my ($self, $c, $job) = @_;
1295 $job =~ s/[_|-]/ /g;
1298 my $msg = "Your $job job is submitted.";
1304 sub get_user_solgs_analyses
{
1305 my ($self, $c) = @_;
1307 $self->analysis_log_file($c);
1308 my $log_file = $c->stash->{analysis_log_file
};
1313 no warnings
'uninitialized';
1317 my @user_analyses = grep{$_ !~ /User_name\s+/i }
1318 read_file
($log_file, {binmode => ':utf8'});
1320 $self->index_log_file_headers($c);
1321 my $header_index = $c->stash->{header_index
};
1323 my $json = JSON
->new();
1324 foreach my $row (@user_analyses)
1326 my @analysis = split(/\t/, $row);
1328 my $arguments = $analysis[5];
1329 $arguments = $json->decode($arguments);
1330 my $analysis_type = $arguments->{analysis_type
};
1331 my $analysis_name = $analysis[$header_index->{'Analysis_name'}];
1332 my $result_page = $analysis[$header_index->{'Analysis_page'}];
1333 my $analysis_status = $analysis[$header_index->{'Status'}];
1334 my $submitted_on = $analysis[$header_index->{'Submitted on'}];
1336 if ($analysis_status =~ /Failed/i)
1338 $result_page = 'N/A';
1340 elsif ($analysis_status =~ /Submitted/i)
1342 $result_page = 'In progress...'
1346 $result_page = qq |<a href
=$result_page>[ View
]</a
>|;
1349 my $row = [$analysis_name, $analysis_type, $submitted_on, $analysis_status, $result_page];
1350 push @panel_data, $row;
1354 return \
@panel_data;
1358 sub create_analysis_log_dir
{
1359 my ($self, $c) = @_;
1361 my $user_id = $c->user->id;
1363 $c->controller('solGS::Files')->get_solgs_dirs($c);
1365 my $log_dir = $c->stash->{analysis_log_dir
};
1367 $log_dir = catdir
($log_dir, $user_id);
1368 mkpath
($log_dir, 0, 0755);
1370 $c->stash->{analysis_log_dir
} = $log_dir;
1375 sub begin
: Private
{
1376 my ($self, $c) = @_;
1378 $c->controller('solGS::Files')->get_solgs_dirs($c);
1385 __PACKAGE__
->meta->make_immutable;