seedlot upload with accession synonyms. seedlot upload works to update existing seedlots
[sgn.git] / lib / SGN / Controller / solGS / combinedTrials.pm
blobcb1f285241077f7af7aa7d02a815c528afa99b9c
1 package SGN::Controller::solGS::combinedTrials;
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/;
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 Array::Utils qw(:all);
19 use CXGN::Tools::Run;
20 use JSON;
23 BEGIN { extends 'Catalyst::Controller' }
26 sub get_combined_pops_id :Path('/solgs/get/combined/populations/id') Args() {
27 my ($self, $c) = @_;
29 my @pops_ids = $c->req->param('trials[]');
31 my $combo_pops_id;
32 my $ret->{status} = 0;
34 if (@pops_ids > 1)
36 $c->stash->{pops_ids_list} = \@pops_ids;
37 $self->create_combined_pops_id($c);
38 my $combo_pops_id = $c->stash->{combo_pops_id};
40 my $ids = join(',', @pops_ids);
41 my $entry = "\n" . $combo_pops_id . "\t" . $ids;
42 $c->controller("solGS::solGS")->catalogue_combined_pops($c, $entry);
44 $ret->{combo_pops_id} = $combo_pops_id;
45 $ret->{status} = 1;
48 $ret = to_json($ret);
50 $c->res->content_type('application/json');
51 $c->res->body($ret);
56 sub prepare_data_for_trials :Path('/solgs/retrieve/populations/data') Args() {
57 my ($self, $c) = @_;
59 my @pops_ids = $c->req->param('trials[]');
61 my $combo_pops_id;
62 my $ret->{status} = 0;
64 my $solgs_controller = $c->controller('solGS::solGS');
65 my $not_matching_pops;
66 my @g_files;
68 if (scalar(@pops_ids) > 1)
70 $c->stash->{pops_ids_list} = \@pops_ids;
71 $self->create_combined_pops_id($c);
72 my $combo_pops_id = $c->stash->{combo_pops_id};
74 my $ids = join(',', @pops_ids);
75 my $entry = "\n" . $combo_pops_id . "\t" . $ids;
76 $solgs_controller->catalogue_combined_pops($c, $entry);
78 $self->prepare_multi_pops_data($c);
80 my $geno_files = $c->stash->{multi_pops_geno_files};
81 @g_files = split(/\t/, $geno_files);
83 $solgs_controller->compare_genotyping_platforms($c, \@g_files);
84 $not_matching_pops = $c->stash->{pops_with_no_genotype_match};
86 if (!$not_matching_pops)
88 $self->save_common_traits_acronyms($c);
90 else
92 $ret->{not_matching_pops} = $not_matching_pops;
95 $ret->{combined_pops_id} = $combo_pops_id;
97 else
99 my $pop_id = $pops_ids[0];
101 $c->stash->{pop_id} = $pop_id;
102 $solgs_controller->phenotype_file($c);
103 $solgs_controller->genotype_file($c);
105 $ret->{redirect_url} = "/solgs/population/$pop_id";
108 $ret = to_json($ret);
110 $c->res->content_type('application/json');
111 $c->res->body($ret);
116 sub combined_trials_page :Path('/solgs/populations/combined') Args(1) {
117 my ($self, $c, $combo_pops_id) = @_;
119 $c->stash->{pop_id} = $combo_pops_id;
120 $c->stash->{combo_pops_id} = $combo_pops_id;
122 $self->save_common_traits_acronyms($c);
124 my $solgs_controller = $c->controller('solGS::solGS');
126 $solgs_controller->get_all_traits($c);
127 #$solgs_controller->select_traits($c);
128 $solgs_controller->get_acronym_pairs($c);
130 $self->combined_trials_desc($c);
132 $c->stash->{template} = $solgs_controller->template('/population/combined/combined.mas');
137 sub model_combined_trials_trait :Path('/solgs/model/combined/trials') Args(3) {
138 my ($self, $c, $combo_pops_id, $trait_txt, $trait_id) = @_;
140 $c->stash->{combo_pops_id} = $combo_pops_id;
141 $c->stash->{trait_id} = $trait_id;
143 $self->combine_trait_data($c);
144 $self->build_model_combined_trials_trait($c);
146 $c->controller('solGS::solGS')->gebv_kinship_file($c);
147 my $gebv_file = $c->stash->{gebv_kinship_file};
149 if ( -s $gebv_file )
151 $c->res->redirect("/solgs/model/combined/populations/$combo_pops_id/trait/$trait_id");
152 $c->detach();
158 sub models_combined_trials :Path('/solgs/models/combined/trials') Args(1) {
159 my ($self, $c, $combo_pops_id) = @_;
161 $c->stash->{combo_pops_id} = $combo_pops_id;
162 $c->stash->{model_id} = $combo_pops_id;
163 $c->stash->{pop_id} = $combo_pops_id;
164 $c->stash->{data_set_type} = 'combined populations';
166 my @traits_ids = $c->req->param('trait_id[]');
167 my $req = $c->req->param('source');
168 my @traits_pages;
170 my $solgs_controller = $c->controller('solGS::solGS');
172 if (!@traits_ids) {
174 $solgs_controller->analyzed_traits($c);
175 my @analyzed_traits = @{ $c->stash->{analyzed_traits} };
177 foreach my $tr (@analyzed_traits)
179 my $acronym_pairs = $solgs_controller->get_acronym_pairs($c);
180 my $trait_name;
181 if ($acronym_pairs)
183 foreach my $r (@$acronym_pairs)
185 if ($r->[0] eq $tr)
187 $trait_name = $r->[1];
188 $trait_name =~ s/\n//g;
189 $c->stash->{trait_name} = $trait_name;
190 $c->stash->{trait_abbr} = $r->[0];
195 my $trait_id = $c->model('solGS::solGS')->get_trait_id($trait_name);
196 my $trait_abbr = $c->stash->{trait_abbr};
198 $solgs_controller->get_model_accuracy_value($c, $combo_pops_id, $trait_abbr);
199 my $accuracy_value = $c->stash->{accuracy_value};
201 $c->controller("solGS::Heritability")->get_heritability($c);
202 my $heritability = $c->stash->{heritability};
204 push @traits_pages,
205 [ qq | <a href="/solgs/model/combined/populations/$combo_pops_id/trait/$trait_id" onclick="solGS.waitPage()">$trait_abbr</a>|, $accuracy_value, $heritability];
208 elsif (scalar(@traits_ids) == 1)
210 my $trait_id = $traits_ids[0];
211 $c->res->redirect("/solgs/model/combined/trials/$combo_pops_id/trait/$trait_id");
212 $c->detach();
214 elsif (scalar(@traits_ids) > 1)
216 foreach my $trait_id (@traits_ids)
218 $c->stash->{trait_id} = $trait_id;
219 $solgs_controller->get_trait_details($c, $trait_id);
220 my $tr_abbr = $c->stash->{trait_abbr};
222 $self->combine_trait_data($c);
223 $self->build_model_combined_trials_trait($c);
225 $solgs_controller->get_model_accuracy_value($c, $combo_pops_id, $tr_abbr);
226 my $accuracy_value = $c->stash->{accuracy_value};
228 $c->controller("solGS::Heritability")->get_heritability($c);
229 my $heritability = $c->stash->{heritability};
231 push @traits_pages,
232 [ qq | <a href="/solgs/model/combined/populations/$combo_pops_id/trait/$trait_id" onclick="solGS.waitPage()">$tr_abbr</a>|, $accuracy_value, $heritability];
237 if ($req =~ /AJAX/)
239 my $ret->{status} = 'success';
240 $ret = to_json($ret);
242 $c->res->content_type('application/json');
243 $c->res->body($ret);
245 else
247 $solgs_controller->analyzed_traits($c);
248 my $analyzed_traits = $c->stash->{analyzed_traits};
250 $c->stash->{trait_pages} = \@traits_pages;
251 $c->stash->{template} = $solgs_controller->template('/population/combined/multiple_traits_output.mas');
253 $self->combined_trials_desc($c);
255 my $project_name = $c->stash->{project_name};
256 my $project_desc = $c->stash->{project_desc};
258 my @model_desc = ([qq | <a href="/solgs/populations/combined/$combo_pops_id">$project_name</a> |, $project_desc, \@traits_pages]);
259 $c->stash->{model_data} = \@model_desc;
260 $c->stash->{pop_id} = $combo_pops_id;
261 $solgs_controller->get_acronym_pairs($c);
266 sub display_combined_pops_result :Path('/solgs/model/combined/populations/') Args(3){
267 my ($self, $c, $combo_pops_id, $trait_key, $trait_id,) = @_;
269 $c->stash->{data_set_type} = 'combined populations';
270 $c->stash->{combo_pops_id} = $combo_pops_id;
272 my $pops_cvs = $c->req->param('combined_populations');
273 my $solgs_controller = $c->controller('solGS::solGS');
275 if ($pops_cvs)
277 my @pops = split(',', $pops_cvs);
278 $c->stash->{trait_combo_pops} = \@pops;
280 else
282 $solgs_controller->get_combined_pops_list($c, $combo_pops_id);
283 $c->stash->{trait_combo_pops} = $c->stash->{combined_pops_list};
286 $solgs_controller->get_trait_details($c, $trait_id);
287 $solgs_controller->trait_phenotype_stat($c);
288 $solgs_controller->validation_file($c);
289 $solgs_controller->model_accuracy($c);
290 $solgs_controller->gebv_kinship_file($c);
291 $solgs_controller->blups_file($c);
292 $solgs_controller->download_urls($c);
293 $solgs_controller->gebv_marker_file($c);
294 $solgs_controller->top_markers($c);
295 $solgs_controller->combined_pops_summary($c);
296 $solgs_controller->model_parameters($c);
298 $c->stash->{template} = $solgs_controller->template('/model/combined/populations/trait.mas');
302 sub selection_combined_pops_trait :Path('/solgs/selection/') Args(6) {
303 my ($self, $c, $selection_pop_id,
304 $model_key, $combined_key, $model_id,
305 $trait_key, $trait_id) = @_;
307 $c->stash->{combo_pops_id} = $model_id;
308 $c->stash->{trait_id} = $trait_id;
309 $c->stash->{prediction_pop_id} = $selection_pop_id;
310 $c->stash->{data_set_type} = 'combined populations';
311 $c->stash->{combined_populations} = 1;
313 $c->controller('solGS::solGS')->get_trait_details($c, $trait_id);
315 if ($selection_pop_id =~ /uploaded/)
317 $c->controller('solGS::solGS')->uploaded_population_summary($c, $selection_pop_id);
318 $c->stash->{selection_pop_id} = $c->stash->{project_id};
319 $c->stash->{selection_pop_name} = $c->stash->{project_name};
320 $c->stash->{selection_pop_desc} = $c->stash->{project_desc};
321 $c->stash->{selection_pop_owner} = $c->stash->{owner};
323 else
325 $c->controller('solGS::solGS')->get_project_details($c, $selection_pop_id);
326 $c->stash->{selection_pop_id} = $c->stash->{project_id};
327 $c->stash->{selection_pop_name} = $c->stash->{project_name};
328 $c->stash->{selection_pop_desc} = $c->stash->{project_desc};
330 $c->controller('solGS::solGS')->get_project_owners($c, $selection_pop_id);
331 $c->stash->{selection_pop_owner} = $c->stash->{project_owners};
334 my $mr_cnt_args = {'selection_pop' => 1, 'selection_pop_id' => $selection_pop_id};
335 my $sel_pop_mr_cnt = $c->controller('solGS::solGS')->get_markers_count($c, $mr_cnt_args);
336 $c->stash->{selection_markers_cnt} = $sel_pop_mr_cnt;
338 my $protocol = $c->config->{default_genotyping_protocol};
339 $protocol = 'N/A' if !$protocol;
340 $c->stash->{protocol} = $protocol;
342 my $identifier = $model_id . '_' . $selection_pop_id;
343 $c->controller('solGS::solGS')->prediction_pop_gebvs_file($c, $identifier, $trait_id);
344 my $gebvs_file = $c->stash->{prediction_pop_gebvs_file};
346 my @stock_rows = read_file($gebvs_file);
347 $c->stash->{selection_stocks_cnt} = scalar(@stock_rows) - 1;
349 $c->controller('solGS::solGS')->top_blups($c, $gebvs_file);
351 $c->stash->{blups_download_url} = qq | <a href="/solgs/download/prediction/model/$model_id/prediction/$selection_pop_id/$trait_id">Download all GEBVs</a>|;
353 $c->stash->{template} = $c->controller('solGS::solGS')->template('/selection/combined/selection_trait.mas');
357 sub build_model_combined_trials_trait {
358 my ($self, $c) = @_;
360 my $solgs_controller = $c->controller('solGS::solGS');
361 $c->stash->{data_set_type} = 'combined populations';
363 $solgs_controller->gebv_kinship_file($c);
364 my $gebv_file = $c->stash->{gebv_kinship_file};
366 unless ( -s $gebv_file )
368 my $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
369 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
371 $c->stash->{pop_id} = $c->stash->{combo_pops_id};
372 $solgs_controller->get_rrblup_output($c);
377 sub combine_trait_data {
378 my ($self, $c) = @_;
380 my $combo_pops_id = $c->stash->{combo_pops_id};
381 my $trait_id = $c->stash->{trait_id};
383 my $solgs_controller = $c->controller('solGS::solGS');
384 $solgs_controller->get_trait_details($c, $trait_id);
386 $solgs_controller->cache_combined_pops_data($c);
388 my $combined_pops_pheno_file = $c->stash->{trait_combined_pheno_file};
389 my $combined_pops_geno_file = $c->stash->{trait_combined_geno_file};
391 my $geno_cnt = (split(/\s+/, qx / wc -l $combined_pops_geno_file /))[0];
392 my $pheno_cnt = (split(/\s+/, qx / wc -l $combined_pops_pheno_file /))[0];
394 unless ( $geno_cnt > 10 && $pheno_cnt > 10 )
396 $self->get_combined_pops_arrayref($c);
397 my $combined_pops_list = $c->stash->{arrayref_combined_pops_ids};
398 $c->stash->{trait_combine_populations} = $combined_pops_list;
400 $self->prepare_multi_pops_data($c);
402 my $background_job = $c->stash->{background_job};
403 my $prerequisite_jobs = $c->stash->{prerequisite_jobs};
405 if ($background_job)
407 if ($prerequisite_jobs =~ /^:+$/)
409 $prerequisite_jobs = undef;
412 if ($prerequisite_jobs)
414 $c->stash->{dependency} = $prerequisite_jobs;
415 $c->stash->{dependency_type} = 'download_data';
419 $solgs_controller->r_combine_populations($c);
425 sub combine_data_build_model {
426 my ($self, $c) = @_;
428 my $trait_id = $c->stash->{trait_id};
429 $c->controller('solGS::solGS')->get_trait_details($c, $trait_id);
431 $self->combine_trait_data($c);
433 my $combine_job_id = $c->stash->{combine_pops_job_id};
435 if ($combine_job_id)
437 $c->stash->{dependency} = "'" . $combine_job_id . "'";
439 if (!$c->stash->{dependency_type})
441 $c->stash->{dependency_type} = 'combine_populations';
445 $self->build_model_combined_trials_trait($c);
450 sub combined_trials_desc {
451 my ($self, $c) = @_;
453 my $combo_pops_id = $c->stash->{combo_pops_id};
455 $self->get_combined_pops_arrayref($c);
456 my $combined_pops_list = $c->stash->{arrayref_combined_pops_ids};
458 my $solgs_controller = $c->controller('solGS::solGS');
460 my $desc = 'This training population is a combination of ';
462 my $projects_owners;
463 my $s_pop_id;
465 foreach my $pop_id (@$combined_pops_list)
467 my $pr_rs = $c->model('solGS::solGS')->project_details($pop_id);
469 while (my $row = $pr_rs->next)
471 my $pr_id = $row->id;
472 my $pr_name = $row->name;
473 $desc .= qq | <a href="/solgs/population/$pr_id">$pr_name</a>|;
474 $desc .= $pop_id == $combined_pops_list->[-1] ? '.' : ' and ';
477 $solgs_controller->get_project_owners($c, $_);
478 my $project_owners = $c->stash->{project_owners};
480 unless (!$project_owners)
482 $projects_owners.= $projects_owners ? ', ' . $project_owners : $project_owners;
485 $s_pop_id = $pop_id;
486 $s_pop_id =~ s/\s+//;
489 $c->stash->{pop_id} = $s_pop_id;
490 $solgs_controller->filtered_training_genotype_file($c);
491 my $filtered_geno_file = $c->stash->{filtered_training_genotype_file};
493 my $markers_no;
494 my @geno_lines;
495 my $dir = $c->{stash}->{solgs_cache_dir};
497 if (-s $filtered_geno_file)
499 @geno_lines = read_file($filtered_geno_file);
500 $markers_no = scalar(split('\t', $geno_lines[0])) - 1;
502 else
504 my $geno_exp = "genotype_data_${s_pop_id}.txt";
505 my $geno_file = $solgs_controller->grep_file($dir, $geno_exp);
506 @geno_lines = read_file($geno_file);
507 $markers_no = scalar(split ('\t', $geno_lines[0])) - 1;
510 my $trait_exp = "traits_acronym_pop_${combo_pops_id}";
511 my $traits_list_file = $solgs_controller->grep_file($dir, $trait_exp);
513 my @traits_list = read_file($traits_list_file);
514 my $traits_no = scalar(@traits_list) - 1;
516 my $stock_no = scalar(@geno_lines) - 1;
518 my $training_pop = "Training population $combo_pops_id";
520 my $protocol = $c->config->{default_genotyping_protocol};
521 $protocol = 'N/A' if !$protocol;
523 $c->stash(stocks_no => $stock_no,
524 markers_no => $markers_no,
525 traits_no => $traits_no,
526 project_desc => $desc,
527 project_name => $training_pop,
528 owner => $projects_owners,
529 protocol => $protocol,
534 sub find_common_traits {
535 my ($self, $c) = @_;
537 my $combo_pops_id = $c->stash->{combo_pops_id};
539 $self->get_combined_pops_arrayref($c);
540 my $combined_pops_list = $c->stash->{arrayref_combined_pops_ids};
542 my $solgs_controller = $c->controller('solGS::solGS');
544 my @common_traits;
545 foreach my $pop_id (@$combined_pops_list)
547 $c->stash->{pop_id} = $pop_id;
549 $solgs_controller->get_single_trial_traits($c);
550 $solgs_controller->traits_list_file($c);
551 my $traits_list_file = $c->stash->{traits_list_file};
553 my $traits = read_file($traits_list_file);
554 my @trial_traits = split(/\t/, $traits);
556 if (@common_traits)
558 @common_traits = intersect(@common_traits, @trial_traits);
560 else
562 @common_traits = @trial_traits;
566 $c->stash->{common_traits} = \@common_traits;
570 sub save_common_traits_acronyms {
571 my ($self, $c) = @_;
573 my $combo_pops_id = $c->stash->{combo_pops_id};
575 $self->find_common_traits($c);
576 my $common_traits = $c->stash->{common_traits};
578 $c->stash->{pop_id} = $combo_pops_id;
579 $c->controller('solGS::solGS')->traits_list_file($c);
580 my $traits_file = $c->stash->{traits_list_file};
581 write_file($traits_file, join("\t", @$common_traits)) if $traits_file;
586 sub get_combined_pops_arrayref {
587 my ($self, $c) = @_;
589 my $combo_pops_id = $c->stash->{combo_pops_id};
591 $c->controller('solGS::solGS')->get_combined_pops_list($c, $combo_pops_id);
592 my $pops_list = $c->stash->{combined_pops_list};
594 $c->stash->{arrayref_combined_pops_ids} = $pops_list;
599 sub prepare_multi_pops_data {
600 my ($self, $c) = @_;
602 $self->get_combined_pops_arrayref($c);
603 my $combined_pops_list = $c->stash->{arrayref_combined_pops_ids};
605 my $solgs_controller = $c->controller('solGS::solGS');
607 $solgs_controller->multi_pops_phenotype_data($c, $combined_pops_list);
608 $solgs_controller->multi_pops_genotype_data($c, $combined_pops_list);
609 $solgs_controller->multi_pops_geno_files($c, $combined_pops_list);
610 $solgs_controller->multi_pops_pheno_files($c, $combined_pops_list);
612 my @all_jobs = (@{$c->stash->{multi_pops_pheno_jobs_ids}},
613 @{$c->stash->{multi_pops_geno_jobs_ids}});
615 my $prerequisite_jobs;
617 if (@all_jobs && scalar(@all_jobs) > 1)
619 $prerequisite_jobs = join(':', @all_jobs);
622 else
624 if (@all_jobs && scalar(@all_jobs) == 1) { $prerequisite_jobs = $all_jobs[0];}
627 if ($prerequisite_jobs =~ /^:+$/) {$prerequisite_jobs = undef;}
629 $c->stash->{prerequisite_jobs} = $prerequisite_jobs;
634 sub create_combined_pops_id {
635 my ($self, $c) = @_;
637 $c->stash->{combo_pops_id} = crc(join('', @{$c->stash->{pops_ids_list}}));
642 sub begin : Private {
643 my ($self, $c) = @_;
645 $c->controller("solGS::solGS")->get_solgs_dirs($c);
650 #####
652 #####