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';
17 BEGIN { extends
'Catalyst::Controller::REST' }
20 default => 'application/json',
22 map => { 'application/json' => 'JSON' },
26 sub check_user_login
: Path
('/solgs/check/user/login') Args
(0) {
27 my ( $self, $c ) = @_;
29 my $user = $c->user();
30 $c->stash->{rest
}{loggedin
} = 0;
34 contact
=> $self->get_user_detail($c),
41 sub save_analysis_profile
: Path
('/solgs/save/analysis/profile') Args
(0) {
42 my ( $self, $c ) = @_;
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 $c->stash->{rest
}{result
} = 0;
51 $self->save_profile($c);
52 my $error_saving = $c->stash->{error
};
54 if ( !$error_saving ) {
55 $c->stash->{rest
}{result
} = 1;
61 sub run_saved_analysis
: Path
('/solgs/run/saved/analysis/') Args
(0) {
62 my ( $self, $c ) = @_;
64 my $analysis_profile = $c->req->params;
65 $c->stash->{analysis_profile
} = $analysis_profile;
66 $self->parse_arguments($c);
67 $self->structure_output_details($c);
68 $self->run_analysis($c);
71 result
=> $c->stash->{status
},
72 arguments
=> $analysis_profile->{arguments
}
77 sub check_analysis_name
: Path
('/solgs/check/analysis/name') Args
() {
78 my ( $self, $c ) = @_;
80 my $new_name = $c->req->param('name');
81 my $match = $self->check_analyses_names( $c, $new_name );
83 $c->stash->{rest
}{analysis_exists
} = $match;
87 sub display_analysis_status
: Path
('/solgs/display/analysis/status') Args
(0) {
88 my ( $self, $c ) = @_;
90 $c->stash->{rest
}{data
} = $self->get_user_solgs_analyses($c);
93 sub check_analyses_names
{
94 my ( $self, $c, $new_name ) = @_;
96 my $logged_names = $self->check_log_analyses_names($c);
100 $log_match = grep { $_ =~ /$new_name/i } @
$logged_names;
105 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
107 my $schema = $c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id);
109 $schema->resultset("Project::Project")->find( { name
=> $new_name } );
112 my $match = $log_match || $db_match ?
1 : undef;
118 sub check_log_analyses_names
{
119 my ( $self, $c ) = @_;
121 my $log_file = $self->analysis_log_file($c);
122 my $names = qx(cut
-f
2 $log_file);
125 my @names = split( /\n/, $names );
136 my ( $self, $c ) = @_;
138 $self->analysis_log_file($c);
139 my $log_file = $c->stash->{analysis_log_file
};
141 $self->add_log_headers($c);
143 $self->format_log_entry($c);
144 my $log_entry = $c->stash->{formatted_log_entry
};
146 write_file
( $log_file, { binmode => ':utf8', append
=> 1 }, $log_entry );
150 sub add_log_headers
{
151 my ( $self, $c ) = @_;
153 $self->analysis_log_file($c);
154 my $log_file = $c->stash->{analysis_log_file
};
156 my $headers = read_file
( $log_file, { binmode => ':utf8' } );
161 . 'Analysis_name' . "\t"
162 . "Analysis_page" . "\t"
164 . "Submitted on" . "\t"
165 . "Arguments" . "\n";
167 write_file
( $log_file, { binmode => ':utf8' }, $headers );
172 sub index_log_file_headers
{
173 my ( $self, $c ) = @_;
175 no warnings
'uninitialized';
177 $self->analysis_log_file($c);
178 my $log_file = $c->stash->{analysis_log_file
};
181 split( /\t/, ( read_file
( $log_file, { binmode => ':utf8' } ) )[0] );
183 my $header_index = {};
186 foreach my $header (@headers) {
187 $header_index->{$header} = $cnt;
191 $c->stash->{header_index
} = $header_index;
195 sub create_itemized_prediction_log_entries
{
196 my ( $self, $c, $analysis_log ) = @_;
198 $analysis_log = $self->log_analysis_time($analysis_log);
200 my $json = JSON
->new;
201 my $args = $json->decode( $analysis_log->{arguments
} );
203 my $trait_ids = $args->{training_traits_ids
};
205 my $analysis_type = $args->{analysis_type
};
208 'training_pop_id' => $args->{training_pop_id
}->[0],
209 'selection_pop_id' => $args->{selection_pop_id
}->[0],
210 'genotyping_protocol_id' => $args->{genotyping_protocol_id
},
211 'data_set_type' => $args->{data_set_type
},
215 foreach my $trait_id (@
$trait_ids) {
216 $c->controller('solGS::Trait')->get_trait_details( $c, $trait_id );
217 my $trait_abbr = $c->stash->{trait_abbr
};
218 $url_args->{trait_id
} = $trait_id;
221 if ( $analysis_type =~ /selection_prediction/ ) {
223 $c->controller('solGS::Path')->selection_page_url($url_args);
227 $c->controller('solGS::Path')->model_page_url($url_args);
229 $c->controller('solGS::Path')->page_type( $c, $analysis_page );
233 $analysis_log->{analysis_name
} . ' -- ' . $trait_abbr;
235 $args->{analysis_page
} = $analysis_page;
236 $args->{analysis_name
} = $analysis_name;
237 $args->{trait_id
} = [$trait_id];
238 $args->{training_traits_ids
} = [$trait_id];
239 $args->{analysis_type
} = $analysis_type;
244 $analysis_log->{user_name
}, $analysis_name,
245 $analysis_page, 'Submitted',
246 $args->{analysis_time
}, $json->encode($args),
258 sub log_analysis_time
{
259 my ( $self, $analysis_log ) = @_;
261 my $analysis_time = POSIX
::strftime
( "%m/%d/%Y %H:%M", localtime );
263 my $json = JSON
->new;
264 my $args = $json->decode( $analysis_log->{arguments
} );
266 $args->{analysis_time
} = $analysis_time;
267 $analysis_log->{arguments
} = $json->encode($args);
269 return $analysis_log;
273 sub format_log_entry
{
274 my ( $self, $c ) = @_;
276 my $profile = $c->stash->{analysis_profile
};
277 $profile = $self->log_analysis_time($profile);
278 my $args = $profile->{arguments
};
280 my $json = JSON
->new;
281 my $time = $json->decode($args)->{analysis_time
};
283 my $traits_args = $json->decode($args);
285 $traits_args->{training_traits_ids
} || $traits_args->{trait_id
};
286 my @traits_ids = ref($traits_ids) eq 'ARRAY' ? @
$traits_ids : ($traits_ids);
289 my $analysis_type = $traits_args->{analysis_type
};
291 if ( @traits_ids > 1 && $analysis_type =~ /selection/ ) {
292 $analysis_page = $traits_args->{referer
};
295 $analysis_page = $traits_args->{analysis_page
};
301 $profile->{user_name
}, $profile->{analysis_name
},
302 $analysis_page, 'Submitted',
309 if ( @traits_ids > 1 && $analysis_type =~ /model|selection/ ) {
311 $self->create_itemized_prediction_log_entries( $c, $profile );
312 $entry .= $traits_entries;
315 $c->stash->{formatted_log_entry
} = $entry;
319 sub analysis_report_job_args
{
320 my ( $self, $c, $status_check_duration ) = @_;
322 my $analysis_details = $c->stash->{bg_job_output_details
};
325 $c->stash->{analysis_tempfiles_dir
} || $c->stash->{solgs_tempfiles_dir
};
327 my $temp_file_template = "analysis-status";
328 my $cluster_files = $c->controller('solGS::AsyncJob')
329 ->create_cluster_accessible_tmp_files( $c, $temp_file_template );
330 my $out_file = $cluster_files->{out_file_temp
};
331 my $err_file = $cluster_files->{err_file_temp
};
332 my $in_file = $cluster_files->{in_file_temp
};
335 'temp_dir' => $temp_dir,
336 'out_file' => $out_file,
337 'err_file' => $err_file,
338 'cluster_host' => 'localhost'
341 my $report_file = $c->controller('solGS::Files')
342 ->create_tempfile( $temp_dir, 'analysis-report-args' );
343 nstore
$analysis_details, $report_file
345 "analysis_report_job_args: $! serializing output_details to $report_file";
347 my $job_config = $c->controller('solGS::AsyncJob')
348 ->create_cluster_config( $c, $config_args );
350 $status_check_duration =
351 ' --status_check_duration ' . $status_check_duration
352 if $status_check_duration;
355 'mx-run solGS::AnalysisReport'
356 . ' --output_details_file '
358 . $status_check_duration;
362 'config' => $job_config,
363 'background_job' => $c->stash->{background_job
},
364 'temp_dir' => $temp_dir,
367 $c->stash->{analysis_report_job_args
} = $job_args;
371 sub get_analysis_report_job_args_file
{
372 my ( $self, $c, $status_check_duration ) = @_;
374 $self->analysis_report_job_args( $c, $status_check_duration );
375 my $analysis_job_args = $c->stash->{analysis_report_job_args
};
377 my $temp_dir = $c->stash->{solgs_tempfiles_dir
};
379 my $report_file = $c->controller('solGS::Files')
380 ->create_tempfile( $temp_dir, 'analysis-report-job-args' );
381 nstore
$analysis_job_args, $report_file
383 "get_analysis_report_job_args_file: $! serializing output_details to $report_file";
385 $c->stash->{analysis_report_job_args_file
} = $report_file;
389 sub email_analysis_report
{
390 my ( $self, $c ) = @_;
392 $self->analysis_report_job_args($c);
393 my $job_args = $c->stash->{analysis_report_job_args
};
396 $c->controller('solGS::AsyncJob')->submit_job_cluster( $c, $job_args );
400 sub parse_arguments
{
401 my ( $self, $c ) = @_;
403 my $analysis_data = $c->stash->{analysis_profile
};
404 my $arguments = $analysis_data->{arguments
};
407 $c->controller('solGS::Utils')->stash_json_args( $c, $arguments );
412 sub structure_output_details
{
413 my ( $self, $c ) = @_;
415 my $analysis_data = $c->stash->{analysis_profile
};
416 my $analysis_page = $analysis_data->{analysis_page
};
418 my $uri_base = $c->req->base;
419 my $referer = $c->req->referer || $analysis_page;
420 $referer =~ s/$uri_base//;
422 my $base = $c->stash->{hostname
};
423 $referer = $base . "/" . $referer;
425 my $output_details = {};
428 'solgs\/traits\/all\/population\/'
430 . '|solgs\/model\/combined\/trials\/'
431 . '|solgs\/models\/combined\/trials\/';
433 if ( $analysis_page =~ m/$match_pages/ ) {
434 $output_details = $self->structure_training_modeling_output($c);
436 elsif ( $analysis_page =~ m/solgs\/population\
// ) {
437 $output_details = $self->structure_training_single_pop_data_output($c);
439 elsif ( $analysis_page =~ m/solgs\/populations\
/combined\// ) {
441 $self->structure_training_combined_pops_data_output($c);
443 elsif ( $analysis_page =~
444 m/solgs\/selection\
/(\d+|\w+_\d+)\/model\
/|solgs\/combined\
/model\/\d
+\
/selection\//
447 $output_details = $self->structure_selection_prediction_output($c);
449 elsif ( $analysis_page =~ m/kinship\/analysis
/ ) {
450 $output_details = $self->structure_kinship_analysis_output($c);
452 elsif ( $analysis_page =~ m/pca\/analysis
/ ) {
453 $output_details = $self->structure_pca_analysis_output($c);
455 elsif ( $analysis_page =~ m/cluster\/analysis
/ ) {
456 $output_details = $self->structure_cluster_analysis_output($c);
459 $self->analysis_log_file($c);
460 my $log_file = $c->stash->{analysis_log_file
};
462 my $mail_list = $self->mailing_list($c);
464 $output_details->{analysis_profile
} = $analysis_data;
465 $output_details->{contact_page
} = $base . '/contact/form';
466 $output_details->{data_set_type
} = $c->stash->{data_set_type
};
467 $output_details->{analysis_log_file
} = $log_file;
468 $output_details->{host
} = qq | $base |;
469 $output_details->{referer
} = qq | $referer |;
470 $output_details->{mailing_list
} = $mail_list;
472 $c->stash->{bg_job_output_details
} = $output_details;
477 my ( $self, $c ) = @_;
479 my $mail_list = $c->config->{cluster_job_email
};
482 $mail_list = 'cluster-jobs@solgenomics.net';
488 sub structure_kinship_analysis_output
{
489 my ( $self, $c ) = @_;
491 my $analysis_data = $c->stash->{analysis_profile
};
492 my $analysis_page = $analysis_data->{analysis_page
};
494 my $protocol_id = $c->stash->{genotyping_protocol_id
};
496 $c->controller('solGS::Kinship')->stash_kinship_pop_id($c);
497 my $pop_id = $c->stash->{kinship_pop_id
};
499 my $base = $c->stash->{hostname
};
501 my $kinship_page = $base . $analysis_page;
502 $analysis_data->{analysis_page
} = $kinship_page;
504 my %output_details = ();
506 my $trait_id = $c->stash->{trait_id
};
508 $c->controller('solGS::Files')
509 ->genotype_file_name( $c, $pop_id, $protocol_id );
510 my $geno_file = $c->stash->{genotype_file_name
};
512 my $coef_files = $c->controller('solGS::Kinship')
513 ->get_kinship_coef_files( $c, $pop_id, $protocol_id, $trait_id );
514 my $matrix_file = $coef_files->{matrix_file_adj
};
516 $output_details{ 'kinship_' . $pop_id } = {
517 'output_page' => $kinship_page,
518 'kinship_pop_id' => $pop_id,
519 'genotype_file' => $geno_file,
520 'matrix_file' => $matrix_file,
523 return \
%output_details;
526 sub structure_pca_analysis_output
{
527 my ( $self, $c ) = @_;
529 my $analysis_data = $c->stash->{analysis_profile
};
530 my $analysis_page = $analysis_data->{analysis_page
};
532 my $base = $c->stash->{hostname
};
534 my $pca_page = $base . $analysis_page;
535 $analysis_data->{analysis_page
} = $pca_page;
536 my $pop_id = $c->stash->{pca_pop_id
};
538 $c->stash->{file_id
} = $c->controller('solGS::Files')->create_file_id($c);
539 my $input_file = $c->controller('solGS::pca')->pca_data_input_files($c);
541 $c->controller('solGS::pca')->pca_scores_file($c);
542 my $scores_file = $c->stash->{pca_scores_file
};
544 my %output_details = (
547 'output_page' => $pca_page,
548 'pca_pop_id' => $pop_id,
549 'input_file' => $input_file,
550 'scores_file' => $scores_file,
554 return \
%output_details;
558 sub structure_cluster_analysis_output
{
559 my ( $self, $c ) = @_;
561 my $analysis_data = $c->stash->{analysis_profile
};
562 my $analysis_page = $analysis_data->{analysis_page
};
564 my $pop_id = $c->stash->{cluster_pop_id
};
566 my $base = $c->stash->{hostname
};
567 my $cluster_page = $base . $analysis_page;
568 $analysis_data->{analysis_page
} = $cluster_page;
569 my $cluster_type = $c->stash->{cluster_type
};
572 $c->controller('solGS::Cluster')->cluster_data_input_files($c);
574 $c->stash->{file_id
} = $c->controller('solGS::Files')->create_file_id($c);
575 $c->controller('solGS::Cluster')->cluster_result_file($c);
578 if ( $cluster_type =~ /k-means/i ) {
579 $result_file = $c->stash->{"${cluster_type}_result_file"};
582 $result_file = $c->stash->{"${cluster_type}_result_newick_file"};
585 my %output_details = (
588 'output_page' => $cluster_page,
589 'cluster_pop_id' => $pop_id,
590 'input_file' => $input_file,
591 'result_file' => $result_file,
595 return \
%output_details;
599 sub structure_training_modeling_output
{
600 my ( $self, $c ) = @_;
602 my $analysis_data = $c->stash->{analysis_profile
};
603 my $analysis_page = $analysis_data->{analysis_page
};
605 my $training_pop_id = $c->stash->{training_pop_id
};
606 my $protocol_id = $c->stash->{genotyping_protocol_id
};
608 my @traits_ids = @
{ $c->stash->{training_traits_ids
} }
609 if $c->stash->{training_traits_ids
};
611 my $referer = $c->req->referer;
612 my $base = $c->stash->{hostname
};
615 'training_pop_id' => $training_pop_id,
616 'genotyping_protocol_id' => $protocol_id,
620 $referer =~ /solgs\/population\
//
621 || ( $referer =~ /solgs\/search\
/trials\/trait\
//
622 && $analysis_page =~ m/solgs\/trait\
// )
625 $url_args->{data_set_type
} = 'single_population';
627 elsif ($referer =~ /solgs\/populations\
/combined\//
628 || $analysis_page =~ /solgs\/model\
/combined\/trials\
// )
630 $url_args->{data_set_type
} = 'combined_populations';
632 $c->stash->{combo_pops_id
} = $training_pop_id;
633 $c->controller('solGS::combinedTrials')->cache_combined_pops_data($c);
636 my $multi_models_url;
637 if ( scalar(@traits_ids) > 1 ) {
638 my $traits_selection_id = $c->controller('solGS::Gebvs')
639 ->create_traits_selection_id( \
@traits_ids );
641 $c->controller('solGS::Gebvs')
642 ->catalogue_traits_selection( $c, \
@traits_ids );
644 $url_args->{'traits_selection_id'} = $traits_selection_id;
647 $c->controller("solGS::Path")->multi_models_page_url($url_args);
648 $multi_models_url = $base . $multi_models_url;
652 my %output_details = ();
654 foreach my $trait_id (@traits_ids) {
655 $url_args->{trait_id
} = $trait_id;
657 $c->stash->{cache_dir
} = $c->stash->{solgs_cache_dir
};
659 $c->controller('solGS::Trait')->get_trait_details( $c, $trait_id );
660 $c->controller('solGS::Files')->rrblup_training_gebvs_file($c);
662 my $trait_abbr = $c->stash->{trait_abbr
};
665 $c->controller('solGS::Path')->model_page_url($url_args);
666 $model_page = $base . $model_page;
668 $c->controller('solGS::Files')->model_phenodata_file($c);
669 my $model_pheno_file = $c->stash->{model_phenodata_file
};
671 $c->controller('solGS::Files')->model_genodata_file($c);
672 my $model_geno_file = $c->stash->{model_genodata_file
};
674 $output_details{ 'trait_id_' . $trait_abbr } = {
675 'trait_id' => $trait_id,
676 'trait_name' => $c->stash->{trait_name
},
677 'trait_page' => $model_page,
678 'gebv_file' => $c->stash->{rrblup_training_gebvs_file
},
679 'pop_id' => $training_pop_id,
680 'phenotype_file' => $model_pheno_file,
681 'genotype_file' => $model_geno_file,
682 'data_set_type' => $c->stash->{data_set_type
},
687 $output_details{'multi_models_url'} = $multi_models_url;
689 return \
%output_details;
692 sub structure_training_single_pop_data_output
{
693 my ( $self, $c ) = @_;
695 my $pop_id = $c->stash->{pop_id
};
696 my $protocol_id = $c->stash->{genotyping_protocol_id
};
698 my $base = $c->stash->{hostname
};
700 'training_pop_id' => $pop_id,
701 'genotyping_protocol_id' => $protocol_id,
702 'data_set_type' => 'single_population'
705 my $training_pop_page =
706 $c->controller('solGS::Path')->training_page_url($args);
707 my $population_page = $base . $training_pop_page;
709 my $data_set_type = $c->stash->{data_set_type
};
714 my %output_details = ();
716 if ( $pop_id =~ /list/ ) {
718 $c->controller('solGS::List')->create_list_pop_data_files($c);
719 $pheno_file = $files->{pheno_file
};
720 $geno_file = $files->{geno_file
};
722 $c->controller('solGS::List')
723 ->create_list_population_metadata_file( $c, $pop_id );
724 $c->controller('solGS::List')->list_population_summary($c);
725 $pop_name = $c->stash->{project_name
};
727 elsif ( $pop_id =~ /dataset/ ) {
728 my $files = $c->controller('solGS::Dataset')
729 ->create_dataset_pop_data_files( $c, );
730 $pheno_file = $files->{pheno_file
};
731 $geno_file = $files->{geno_file
};
733 $c->controller('solGS::Dataset')
734 ->create_dataset_population_metadata_file($c);
735 $c->controller('solGS::Dataset')->dataset_population_summary($c);
736 $pop_name = $c->stash->{project_name
};
739 $c->controller('solGS::Files')->phenotype_file_name( $c, $pop_id );
740 $c->controller('solGS::Files')
741 ->genotype_file_name( $c, $pop_id, $protocol_id );
742 $pheno_file = $c->stash->{phenotype_file_name
};
743 $geno_file = $c->stash->{genotype_file_name
};
745 $c->controller('solGS::Search')->get_project_details( $c, $pop_id );
746 $pop_name = $c->stash->{project_name
};
749 $output_details{ 'population_id_' . $pop_id } = {
750 'population_page' => $population_page,
751 'population_id' => $pop_id,
752 'population_name' => $pop_name,
753 'phenotype_file' => $pheno_file,
754 'genotype_file' => $geno_file,
755 'data_set_type' => $data_set_type,
758 return \
%output_details;
761 sub structure_training_combined_pops_data_output
{
762 my ( $self, $c ) = @_;
764 my $combo_pops_id = $c->stash->{combo_pops_id
};
765 my $protocol_id = $c->stash->{genotyping_protocol_id
};
767 my $base = $c->stash->{hostname
};
769 'training_pop_id' => $combo_pops_id,
770 'genotyping_protocol_id' => $protocol_id,
771 'data_set_type' => 'combined_populations'
774 my $training_pop_page =
775 $c->controller('solGS::Path')->training_page_url($args);
777 my $combined_pops_page = $base . $training_pop_page;
778 my @combined_pops_ids = @
{ $c->stash->{combo_pops_list
} };
780 $c->controller('solGS::combinedTrials')
781 ->multi_pops_pheno_files( $c, \
@combined_pops_ids );
782 $c->controller('solGS::combinedTrials')
783 ->multi_pops_geno_files( $c, \
@combined_pops_ids, $protocol_id );
785 my $multi_ph_files = $c->stash->{multi_pops_pheno_files
};
786 my @pheno_files = split( /\t/, $multi_ph_files );
787 my $multi_gen_files = $c->stash->{multi_pops_geno_files
};
788 my @geno_files = split( /\t/, $multi_gen_files );
789 my $match_status = $c->stash->{pops_with_no_genotype_match
};
791 my %output_details = ();
792 foreach my $pop_id (@combined_pops_ids) {
793 $c->controller('solGS::Search')->get_project_details( $c, $pop_id );
794 my $population_name = $c->stash->{project_name
};
797 'training_pop_id' => $pop_id,
798 'genotyping_protocol_id' => $protocol_id,
799 'data_set_type' => 'single_population'
802 my $training_pop_page =
803 $c->controller('solGS::Path')->training_page_url($args);
805 my $population_page = $base . $training_pop_page;
807 $c->controller('solGS::Files')->phenotype_file_name( $c, $pop_id );
808 my $pheno_file = $c->stash->{phenotype_file_name
};
810 $c->controller('solGS::Files')
811 ->phenotype_file_name( $c, $pop_id, $protocol_id );
812 my $geno_file = $c->stash->{genotype_file_name
};
814 $output_details{ 'population_id_' . $pop_id } = {
815 'population_page' => $population_page,
816 'population_id' => $pop_id,
817 'population_name' => $population_name,
818 'combo_pops_id' => $combo_pops_id,
819 'phenotype_file' => $pheno_file,
820 'genotype_file' => $geno_file,
821 'data_set_type' => $c->stash->{data_set_type
},
825 $output_details{no_match
} = $match_status;
826 $output_details{combined_pops_page
} = $combined_pops_page;
828 return \
%output_details;
831 sub structure_selection_prediction_output
{
832 my ( $self, $c ) = @_;
834 my @traits_ids = @
{ $c->stash->{training_traits_ids
} }
835 if $c->stash->{training_traits_ids
};
836 my $protocol_id = $c->stash->{genotyping_protocol_id
};
838 my $referer = $c->req->referer;
839 my $base = $c->stash->{hostname
};
841 my $data_set_type = $c->stash->{data_set_type
};
842 my %output_details = ();
844 foreach my $trait_id (@traits_ids) {
845 $c->controller('solGS::Trait')->get_trait_details( $c, $trait_id );
846 my $trait_id = $c->stash->{trait_id
};
847 my $trait_abbr = $c->stash->{trait_abbr
};
848 my $trait_name = $c->stash->{trait_name
};
850 my $tr_pop_id = $c->stash->{training_pop_id
};
851 my $sel_pop_id = $c->stash->{selection_pop_id
};
860 'training_pop_id' => $tr_pop_id,
861 'selection_pop_id' => $sel_pop_id,
862 'trait_id' => $trait_id,
863 'genotyping_protocol_id' => $protocol_id,
864 'data_set_type' => $data_set_type,
867 if ( $data_set_type =~ /combined_populations/ ) {
869 $c->controller('solGS::Path')->training_page_url($url_args);
871 $tr_pop_page = $base . $tr_pop_page;
872 $tr_pop_name = 'Training population ' . $tr_pop_id;
874 $c->controller('solGS::Path')->selection_page_url($url_args);
875 $sel_pop_page = $base . $sel_pop_page;
878 $c->controller('solGS::Path')->model_page_url($url_args);
879 $model_page = $base . $model_page;
882 my $training_pop_page =
883 $c->controller('solGS::Path')->training_page_url($url_args);
885 $tr_pop_page = $base . $training_pop_page;
886 if ( $tr_pop_id =~ /list/ ) {
887 $c->stash->{list_id
} = $tr_pop_id =~ s/\w+_//r;
888 $c->controller('solGS::List')->list_population_summary($c);
889 $tr_pop_name = $c->stash->{project_name
};
891 elsif ( $tr_pop_id =~ /dataset/ ) {
892 $c->stash->{dataset_id
} = $tr_pop_id =~ s/\w+_//r;
893 $c->controller('solGS::Dataset')
894 ->dataset_population_summary($c);
895 $tr_pop_name = $c->stash->{project_name
};
898 $c->controller('solGS::Search')
899 ->get_project_details( $c, $tr_pop_id );
900 $tr_pop_name = $c->stash->{project_name
};
904 $c->controller('solGS::Path')->selection_page_url($url_args);
905 $sel_pop_page = $base . $sel_pop_page;
908 $c->controller('solGS::Path')->model_page_url($url_args);
909 $model_page = $base . $model_page;
912 if ( $sel_pop_id =~ /list/ ) {
913 $c->stash->{list_id
} = $sel_pop_id =~ s/\w+_//r;
914 $c->controller('solGS::List')
915 ->list_population_summary( $c, $sel_pop_id );
916 $c->controller('solGS::List')
917 ->create_list_population_metadata_file( $c, $sel_pop_id );
919 $sel_pop_name = $c->stash->{selection_pop_name
};
921 elsif ( $sel_pop_id =~ /dataset/ ) {
922 $c->stash->{dataset_id
} = $sel_pop_id =~ s/\w+_//r;
923 $c->controller('solGS::Dataset')
924 ->create_dataset_population_metadata_file($c);
925 $c->controller('solGS::Dataset')->dataset_population_summary($c);
926 $sel_pop_name = $c->stash->{selection_pop_name
};
929 $c->controller('solGS::Search')
930 ->get_project_details( $c, $sel_pop_id );
931 $sel_pop_name = $c->stash->{project_name
};
934 $c->controller('solGS::Files')
935 ->rrblup_selection_gebvs_file( $c, $tr_pop_id, $sel_pop_id,
937 my $gebv_file = $c->stash->{rrblup_selection_gebvs_file
};
939 $c->controller('solGS::Files')
940 ->genotype_file_name( $c, $sel_pop_id, $protocol_id );
941 my $selection_geno_file = $c->stash->{genotype_file_name
};
943 $output_details{ 'trait_id_' . $trait_id } = {
944 'training_pop_page' => $tr_pop_page,
945 'training_pop_id' => $tr_pop_id,
946 'training_pop_name' => $tr_pop_name,
947 'selection_pop_name' => $sel_pop_name,
948 'selection_pop_page' => $sel_pop_page,
949 'trait_name' => $trait_name,
950 'trait_id' => $trait_id,
951 'model_page' => $model_page,
952 'gebv_file' => $gebv_file,
953 'selection_geno_file' => $selection_geno_file,
954 'data_set_type' => $data_set_type
959 if ( scalar(@traits_ids) > 1 ) {
960 my $uri_base = $c->req->base;
961 my $referer = $c->req->referer;
962 $referer =~ s/$uri_base//;
963 my $base = $c->stash->{hostname
};
965 $output_details{'multi_models_url'} = $base . "/" . $referer;
968 return \
%output_details;
973 my ( $self, $c ) = @_;
975 $c->stash->{background_job
} = 1;
977 my $analysis_profile = $c->stash->{analysis_profile
};
978 my $analysis_page = $analysis_profile->{analysis_page
};
979 $c->stash->{analysis_page
} = $analysis_page;
981 my $base = $c->stash->{hostname
};
982 $analysis_page =~ s/$base//;
983 my $referer = $c->req->referer;
985 my @selected_traits = @
{ $c->stash->{training_traits_ids
} }
986 if $c->stash->{training_traits_ids
};
990 'solgs\/traits\/all\/population\/'
991 . '|solgs\/models\/combined\/trials\/'
993 . '|solgs\/model\/combined\/trials\/';
995 my $selection_pages = '/solgs\/selection\/(\d+|\w+_\d+)\/model\/'
996 . '|solgs\/combined\/model\/(\d+|\w+_\d+)\/selection\/';
999 '/solgs\/population\/' . '|solgs\/populations\/combined\/';
1001 if ( $analysis_page =~ $training_pages ) {
1002 $self->create_training_data($c);
1004 elsif ( $analysis_page =~ /$modeling_pages/ ) {
1005 $self->predict_training_traits($c);
1007 elsif ( $analysis_page =~ /$selection_pages/ ) {
1008 $self->predict_selection_traits($c);
1010 elsif ( $analysis_page =~ /kinship\/analysis
/ ) {
1011 $self->run_kinship_analysis($c);
1013 elsif ( $analysis_page =~ /pca\/analysis
/ ) {
1014 $self->run_pca_analysis($c);
1016 elsif ( $analysis_page =~ /cluster\/analysis
/ ) {
1017 $self->run_cluster_analysis($c);
1020 $c->stash->{status
} = 'Error: Unknown job';
1021 print STDERR
"\n Unknown job.\n";
1028 $c->stash->{status
} =
1029 "run_analysis failed. Please try re-running the analysis and wait for it to finish. $error[0]";
1032 $c->stash->{status
} = 'Submitted';
1033 $self->update_analysis_progress($c);
1038 sub create_training_data
{
1039 my ( $self, $c ) = @_;
1041 my $analysis_page = $c->stash->{analysis_page
};
1042 my $protocol_id = $c->stash->{genotyping_protocol_id
};
1044 # if ($analysis_page =~ /solgs\/population\//)
1046 my $pop_id = $c->stash->{model_id
};
1048 if ( $analysis_page =~ /solgs\/population\
// ) {
1049 my $pop_id = $c->stash->{model_id
};
1051 if ( $pop_id =~ /list/ ) {
1052 $c->controller('solGS::List')->submit_list_training_data_query($c);
1053 $c->controller('solGS::List')
1054 ->create_list_population_metadata_file( $c, $pop_id );
1056 elsif ( $pop_id =~ /dataset/ ) {
1057 $c->controller('solGS::Dataset')
1058 ->submit_dataset_training_data_query($c);
1059 $c->controller('solGS::Dataset')
1060 ->create_dataset_population_metadata_file($c);
1063 $c->controller('solGS::AsyncJob')
1064 ->submit_cluster_training_pop_data_query( $c, [$pop_id],
1068 elsif ( $analysis_page =~ /solgs\/populations\
/combined\// ) {
1069 my $trials = $c->stash->{combo_pops_list
};
1070 $c->controller('solGS::AsyncJob')
1071 ->submit_cluster_training_pop_data_query( $c, $trials, $protocol_id );
1077 sub predict_training_traits
{
1078 my ( $self, $c ) = @_;
1080 my $analysis_page = $c->stash->{analysis_page
};
1081 my $selected_traits = $c->stash->{training_traits_ids
};
1083 $c->stash->{training_traits_ids
} = [ $c->stash->{trait_id
} ]
1084 if !$c->stash->{training_traits_ids
};
1086 if ( $analysis_page =~ /solgs\/traits\
/all\/population\
/|solgs\/trait\
// ) {
1087 $c->controller('solGS::solGS')->build_multiple_traits_models($c);
1089 elsif ( $analysis_page =~
1090 /solgs\/models\
/combined\/trials\
/|solgs\/model\
/combined\/trials\
// )
1092 if ( $c->stash->{data_set_type
} =~ /combined_populations/ ) {
1093 $c->controller('solGS::combinedTrials')
1094 ->combine_data_build_multiple_traits_models($c);
1100 sub predict_selection_traits
{
1101 my ( $self, $c ) = @_;
1103 $c->stash->{prerequisite_type
} = 'selection_pop_download_data';
1104 my $training_pop_id = $c->stash->{training_pop_id
};
1105 my $selection_pop_id = $c->stash->{selection_pop_id
};
1107 if ( $selection_pop_id =~ /list/ ) {
1108 $c->stash->{list_id
} = $selection_pop_id =~ s/\w+_//r;
1109 $c->controller('solGS::List')->get_genotypes_list_details($c);
1110 $c->controller('solGS::List')
1111 ->create_list_population_metadata_file( $c, $selection_pop_id );
1113 elsif ( $selection_pop_id =~ /dataset/ ) {
1114 $c->stash->{dataset_id
} = $selection_pop_id =~ s/\w+_//r;
1115 $c->controller('solGS::Dataset')
1116 ->create_dataset_population_metadata_file($c);
1119 my $referer = $c->req->referer;
1120 if ( $referer =~ /solgs\/trait\
/|solgs\/traits\
/all\/population\
// ) {
1121 $c->controller('solGS::solGS')->predict_selection_pop_multi_traits($c);
1123 elsif ( $referer =~ /\/combined\
// ) {
1124 $c->stash->{data_set_type
} = 'combined_populations';
1125 $c->controller('solGS::combinedTrials')
1126 ->predict_selection_pop_combined_pops_model($c);
1131 sub run_kinship_analysis
{
1132 my ( $self, $c ) = @_;
1134 my $analysis_page = $c->stash->{analysis_page
};
1136 if ( $analysis_page = ~/kinship\/analysis
/ ) {
1137 $c->controller('solGS::Kinship')->run_kinship($c);
1142 sub run_pca_analysis
{
1143 my ( $self, $c ) = @_;
1145 my $analysis_page = $c->stash->{analysis_page
};
1147 if ( $analysis_page = ~/pca\/analysis
/ ) {
1148 $c->controller('solGS::pca')->run_pca($c);
1153 sub run_cluster_analysis
{
1154 my ( $self, $c ) = @_;
1156 my $analysis_page = $c->stash->{analysis_page
};
1158 if ( $analysis_page = ~/cluster\/analysis
/ ) {
1159 $c->controller('solGS::Cluster')->run_cluster($c);
1164 sub update_analysis_progress
{
1165 my ( $self, $c ) = @_;
1167 my $analysis_data = $c->stash->{analysis_profile
};
1168 my $analysis_name = $analysis_data->{analysis_name
};
1169 my $status = $c->stash->{status
};
1171 $self->analysis_log_file($c);
1172 my $log_file = $c->stash->{analysis_log_file
};
1174 my @contents = read_file
( $log_file, { binmode => ':utf8' } );
1177 $contents[$_] =~ m/\t$analysis_name\t/
1178 ?
$contents[$_] =~ s/error|submitted/$status/ig
1182 write_file
( $log_file, { binmode => ':utf8' }, @contents );
1186 sub get_user_detail
{
1187 my ( $self, $c ) = @_;
1189 my $user = $c->user();
1193 my $private_email = $user->get_private_email();
1194 my $public_email = $user->get_contact_email();
1201 my $salutation = $user->get_salutation();
1202 my $first_name = $user->get_first_name();
1203 my $last_name = $user->get_last_name();
1204 my $user_role = $user->get_object->get_user_type();
1205 my $user_id = $user->get_object()->get_sp_person_id();
1206 my $user_name = $user->id();
1209 'first_name' => $first_name,
1211 'user_role' => $user_role,
1212 'user_id' => $user_id,
1213 'user_name' => $user_name,
1222 sub analysis_log_file
{
1223 my ( $self, $c ) = @_;
1225 $self->create_analysis_log_dir($c);
1226 my $log_dir = $c->stash->{analysis_log_dir
};
1228 $c->stash->{cache_dir
} = $log_dir;
1231 key
=> 'analysis_log',
1232 file
=> 'analysis_log',
1233 stash_key
=> 'analysis_log_file'
1236 $c->controller('solGS::Files')->cache_file( $c, $cache_data );
1240 sub get_user_solgs_analyses
{
1241 my ( $self, $c ) = @_;
1243 $self->analysis_log_file($c);
1244 my $log_file = $c->stash->{analysis_log_file
};
1249 no warnings
'uninitialized';
1252 my @user_analyses = grep { $_ !~ /User_name\s+/i }
1253 read_file
( $log_file, { binmode => ':utf8' } );
1255 $self->index_log_file_headers($c);
1256 my $header_index = $c->stash->{header_index
};
1258 my $json = JSON
->new();
1259 foreach my $row (@user_analyses) {
1260 my @analysis = split( /\t/, $row );
1262 my $arguments = $analysis[5];
1263 $arguments = $json->decode($arguments);
1264 my $analysis_type = $arguments->{analysis_type
};
1265 my $analysis_name = $analysis[ $header_index->{'Analysis_name'} ];
1266 my $result_page = $analysis[ $header_index->{'Analysis_page'} ];
1267 my $analysis_status = $analysis[ $header_index->{'Status'} ];
1268 my $submitted_on = $analysis[ $header_index->{'Submitted on'} ];
1270 if ( $analysis_status =~ /Failed/i ) {
1271 $result_page = 'N/A';
1273 elsif ( $analysis_status =~ /Submitted/i ) {
1274 $result_page = 'In progress...';
1277 $result_page = qq |<a href
=$result_page>[ View
]</a
>|;
1281 $analysis_name, $analysis_type, $submitted_on,
1282 $analysis_status, $result_page
1284 push @panel_data, $row;
1288 return \
@panel_data;
1291 sub create_analysis_log_dir
{
1292 my ( $self, $c ) = @_;
1294 my $user_id = $c->user->id;
1296 $c->controller('solGS::Files')->get_solgs_dirs($c);
1298 my $log_dir = $c->stash->{analysis_log_dir
};
1300 $log_dir = catdir
( $log_dir, $user_id );
1301 mkpath
( $log_dir, 0, 0755 );
1303 $c->stash->{analysis_log_dir
} = $log_dir;
1307 sub begin
: Private
{
1308 my ( $self, $c ) = @_;
1310 $c->controller('solGS::Files')->get_solgs_dirs($c);
1314 __PACKAGE__
->meta->make_immutable;