3 Isaak Y Tecle <iyt2@cornell.edu>
7 SGN::Controller::AJAX::Analyze::Anova - a controller for ANOVA. For now, this implements a one-way
8 single trial ANOVA with a possibility for simultanously running anova for multiple traits.
13 package SGN
::Controller
::AJAX
::Analyze
::Anova
;
16 use namespace
::autoclean
;
18 use File
::Slurp qw
/write_file read_file/;
23 use File
::Spec
::Functions
;
24 use File
::Path qw
/ mkpath /;
25 use URI
::FromHash
'uri';
27 BEGIN { extends
'Catalyst::Controller::REST' }
32 default => 'application/json',
34 map => { 'application/json' => 'JSON',
35 'text/html' => 'JSON' },
39 sub anova_check_design
:Path
('/anova/check/design/') Args
(0) {
42 $c->stash->{trial_id
} = $c->req->param('trial_id');
44 $self->check_trial_design($c);
49 sub anova_traits_list
:Path
('/anova/traits/list/') Args
(0) {
52 my $trial_id = $c->req->param('trial_id');
54 $c->stash->{trial_id
} = $trial_id;
56 $self->anova_traits($c);
61 sub anova_phenotype_data
:Path
('/anova/phenotype/data/') Args
(0) {
64 my $trial_id = $c->req->param('trial_id');
65 my @traits_ids = $c->req->param('traits_ids[]');
67 $c->stash->{rest
}{trial_id
} = $trial_id;
69 $c->stash->{trial_id
} = $trial_id;
70 $c->stash->{traits_ids
} = \
@traits_ids;
72 $self->create_anova_phenodata_file($c);
73 $self->get_traits_abbrs($c);
81 my $trial_id = $c->stash->{trial_id
};
83 my $trial = CXGN
::Trial
->new(bcs_schema
=> $self->schema($c),
84 trial_id
=> $trial_id);
86 my $traits = $trial->get_traits_assayed();
87 my $clean_traits = $self->remove_ontology($traits);
89 $c->stash->{rest
}{anova_traits
} = $clean_traits;
95 my ($self, $traits) = @_;
99 foreach my $tr (@
$traits) {
101 $name =~ s/\|CO_\d+:\d+//;
103 my $id_nm = {'trait_id' => $tr->[0], 'trait_name' => $name};
104 push @clean_traits, $id_nm;
107 return \
@clean_traits;
112 sub create_anova_phenodata_file
{
115 $self->anova_pheno_file($c);
116 my $pheno_file = $c->stash->{phenotype_file
};
118 $self->copy_pheno_file_to_anova_dir($c);
120 if (!-s
$pheno_file) {
121 $c->stash->{rest
}{'Error'} = 'There is no phenotype data for this trial.';
123 $c->stash->{rest
}{'success'} = 'Success.';
127 $c->stash->{rest
}{'Error'} = 'There was error querying for the phenotype data.';
133 sub check_trial_design
{
136 my $trial_id = $c->stash->{trial_id
};
138 my $trial = CXGN
::Trial
->new(bcs_schema
=> $self->schema($c),
139 trial_id
=> $trial_id);
141 my $design = $trial->get_design_type();
144 $supported = $self->check_support($design) if $design;
148 $c->stash->{rest
}{'Error'} = 'This trial has no design to apply ANOVA.';
150 elsif ($design && !$supported)
152 $c->stash->{rest
}{'Error'} = $design . ' design is not supported yet. Please report this to the database team. ';
156 $c->stash->{rest
}{'Design'} = $design;
163 my ($self, $design) = @_;
165 my $supported_designs = $self->supported_designs;
167 my ($match) = grep(/$design/, @
$supported_designs);
174 sub supported_designs
{
177 my $supported_designs = [qw(Alpha, Augmented, RCBD, CRD)];
179 return $supported_designs;
183 sub get_traits_abbrs
{
186 my $trial_id = $c->stash->{trial_id
};
187 my $traits_ids = $c->stash->{traits_ids
};
189 $c->stash->{pop_id
} = $trial_id;
190 $c->controller("solGS::solGS")->all_traits_file($c);
191 my $traits_file = $c->stash->{all_traits_file
};
192 my @traits = read_file
($traits_file);
196 foreach my $id (@
$traits_ids) {
197 my ($tr) = grep(/$id/, @traits);
199 my $abbr = (split('\t', $tr))[2] if $tr;
200 my $id_abbr = {'trait_id' => $id, 'trait_abbr' => $abbr};
201 push @traits_abbrs, $id_abbr;
204 $c->stash->{rest
}{traits_abbrs
} = \
@traits_abbrs;
209 sub anova_analyis
:Path
('/anova/analysis/') Args
(0) {
212 my $trial_id = $c->req->param('trial_id');
213 my $traits = $c->req->param('traits[]');
215 $c->stash->{trial_id
} = $trial_id;
217 my $json = JSON
->new();
218 $traits = $json->decode($traits);
220 foreach my $tr (@
$traits)
222 foreach my $k (keys $tr)
224 $c->stash->{$k} = $tr->{$k};
227 unless ($self->check_anova_output($c))
229 $self->run_anova($c);
230 $self->check_anova_output($c);
237 sub check_anova_output
{
240 $self->anova_table_file($c);
241 my $html_file = $c->stash->{anova_table_html_file
};
245 my $html_table = read_file
($html_file);
247 $self->prep_download_files($c);
248 my $anova_table_file = $c->stash->{download_anova
};
249 my $model_file = $c->stash->{download_model
};
250 my $means_file = $c->stash->{download_means
};
251 my $diagnostics_file = $c->stash->{download_diagnostics
};
253 $c->stash->{rest
}{anova_html_table
} = $html_table;
254 $c->stash->{rest
}{anova_table_file
} = $anova_table_file;
255 $c->stash->{rest
}{anova_model_file
} = $model_file;
256 $c->stash->{rest
}{adj_means_file
} = $means_file;
257 $c->stash->{rest
}{anova_diagnostics_file
} = $diagnostics_file;
268 sub prep_download_files
{
271 my $tmp_dir = catfile
($c->config->{tempfiles_subdir
}, 'anova');
272 my $base_tmp_dir = catfile
($c->config->{basepath
}, $tmp_dir);
274 mkpath
([$base_tmp_dir], 0, 0755);
276 $self->anova_table_file($c);
277 my $anova_txt_file = $c->stash->{anova_table_txt_file
};
278 my $anova_html_file = $c->stash->{anova_table_html_file
};
280 $self->anova_model_file($c);
281 my $model_file = $c->stash->{anova_model_file
};
283 $self->adj_means_file($c);
284 my $means_file = $c->stash->{adj_means_file
};
286 $self->anova_diagnostics_file($c);
287 my $diagnostics_file = $c->stash->{anova_diagnostics_file
};
289 copy
($anova_txt_file, $base_tmp_dir)
290 or die "could not copy $anova_txt_file to $base_tmp_dir";
292 copy
($model_file, $base_tmp_dir)
293 or die "could not copy $model_file to $base_tmp_dir";
295 copy
($means_file, $base_tmp_dir)
296 or die "could not copy $means_file to $base_tmp_dir";
298 copy
($diagnostics_file, $base_tmp_dir)
299 or die "could not copy $diagnostics_file to $base_tmp_dir";
301 $anova_txt_file = fileparse
($anova_txt_file);
302 $anova_txt_file = catfile
($tmp_dir, $anova_txt_file);
304 $model_file = fileparse
($model_file);
305 $model_file = catfile
($tmp_dir, $model_file);
307 $means_file = fileparse
($means_file);
308 $means_file = catfile
($tmp_dir, $means_file);
310 $diagnostics_file = fileparse
($diagnostics_file);
311 $diagnostics_file = catfile
($tmp_dir, $diagnostics_file);
313 $c->stash->{download_anova
} = $anova_txt_file;
314 $c->stash->{download_model
} = $model_file;
315 $c->stash->{download_means
} = $means_file;
316 $c->stash->{download_diagnostics
} = $diagnostics_file;
324 my $trial_id = $c->stash->{trial_id
};
325 my $trait_id = $c->stash->{trait_id
};
327 $self->anova_input_files($c);
328 my $input_file = $c->stash->{anova_input_files
};
330 $self->anova_output_files($c);
331 my $output_file = $c->stash->{anova_output_files
};
333 $c->stash->{analysis_tempfiles_dir
} = $c->stash->{anova_temp_dir
};
335 $c->stash->{input_files
} = $input_file;
336 $c->stash->{output_files
} = $output_file;
337 $c->stash->{r_temp_file
} = "anova-${trial_id}-${trait_id}";
338 $c->stash->{r_script
} = 'R/anova.r';
340 $c->controller("solGS::solGS")->run_r_script($c);
345 sub copy_pheno_file_to_anova_dir
{
348 my $trial_id = $c->stash->{trial_id
};
350 $c->controller('solGS::solGS')->phenotype_file_name($c, $trial_id);
351 my $pheno_file = $c->stash->{phenotype_file_name
};
353 my $anova_cache = $c->stash->{anova_cache_dir
};
355 copy
($pheno_file, $anova_cache) or
356 die "could not copy $pheno_file to $anova_cache";
361 sub anova_input_files
{
364 my $trial_id = $c->stash->{trial_id
};
365 my $trait_id = $c->stash->{trait_id
};
367 $self->anova_pheno_file($c);
368 my $pheno_file = $c->stash->{phenotype_file
};
370 $self->anova_traits_file($c);
371 my $traits_file = $c->stash->{anova_traits_file
};
373 my $file_list = join ("\t",
378 my $tmp_dir = $c->stash->{anova_temp_dir
};
379 my $name = "anova_input_files_${trial_id}_${trait_id}";
380 my $tempfile = $c->controller("solGS::solGS")->create_tempfile($tmp_dir, $name);
381 write_file
($tempfile, $file_list);
383 $c->stash->{anova_input_files
} = $tempfile;
388 sub anova_pheno_file
{
391 $c->stash->{pop_id
} = $c->stash->{trial_id
};
393 $c->controller('solGS::solGS')->phenotype_file($c);
398 sub anova_traits_file
{
401 my $trial_id = $c->stash->{trial_id
};
402 my $traits = $c->stash->{trait_abbr
};
404 my $tmp_dir = $c->stash->{anova_temp_dir
};
405 my $name = "anova_traits_file_${trial_id}";
406 my $traits_file = $c->controller("solGS::solGS")->create_tempfile($tmp_dir, $name);
407 write_file
($traits_file, $traits);
409 $c->stash->{anova_traits_file
} = $traits_file;
414 sub anova_output_files
{
417 my $trial_id = $c->stash->{trial_id
};
418 my $trait_id = $c->stash->{trait_id
};
420 $self->anova_table_file($c);
421 $self->anova_model_file($c);
422 $self->adj_means_file($c);
423 $self->anova_diagnostics_file($c);
425 my @files = $c->stash->{anova_table_file
};
427 my $file_list = join ("\t",
428 $c->stash->{anova_model_file
},
429 $c->stash->{anova_table_html_file
},
430 $c->stash->{anova_table_txt_file
},
431 $c->stash->{adj_means_file
},
432 $c->stash->{anova_diagnostics_file
},
435 my $tmp_dir = $c->stash->{anova_temp_dir
};
436 my $name = "anova_output_files_${trial_id}_${trait_id}";
437 my $tempfile = $c->controller("solGS::solGS")->create_tempfile($tmp_dir, $name);
438 write_file
($tempfile, $file_list);
440 $c->stash->{anova_output_files
} = $tempfile;
445 sub anova_table_file
{
448 my $trial_id = $c->stash->{trial_id
};
449 my $trait_id = $c->stash->{trait_id
};
451 $c->stash->{cache_dir
} = $c->stash->{anova_cache_dir
};
453 my $cache_data = {key
=> "anova_table_${trial_id}_${trait_id}_html",
454 file
=> "anova_table_${trial_id}_${trait_id}.html",
455 stash_key
=> "anova_table_html_file"
458 $c->controller("solGS::solGS")->cache_file($c, $cache_data);
460 $c->stash->{cache_dir
} = $c->stash->{anova_cache_dir
};
462 $cache_data = {key
=> "anova_table_${trial_id}_${trait_id}_txt",
463 file
=> "anova_table_${trial_id}_${trait_id}.txt",
464 stash_key
=> "anova_table_txt_file"
467 $c->controller("solGS::solGS")->cache_file($c, $cache_data);
472 sub anova_diagnostics_file
{
475 my $trial_id = $c->stash->{trial_id
};
476 my $trait_id = $c->stash->{trait_id
};
478 $c->stash->{cache_dir
} = $c->stash->{anova_cache_dir
};
480 my $cache_data = {key
=> "anova_diagnosics_${trial_id}_${trait_id}",
481 file
=> "anova_diagnostics_${trial_id}_${trait_id}.png",
482 stash_key
=> "anova_diagnostics_file"
485 $c->controller("solGS::solGS")->cache_file($c, $cache_data);
490 sub anova_model_file
{
493 my $trial_id = $c->stash->{trial_id
};
494 my $trait_id = $c->stash->{trait_id
};
496 $c->stash->{cache_dir
} = $c->stash->{anova_cache_dir
};;
498 my $cache_data = {key
=> "anova_model_${trial_id}_${trait_id}",
499 file
=> "anova_model_${trial_id}_${trait_id}.txt",
500 stash_key
=> "anova_model_file"
503 $c->controller("solGS::solGS")->cache_file($c, $cache_data);
511 my $trial_id = $c->stash->{trial_id
};
512 my $trait_id = $c->stash->{trait_id
};
514 $c->stash->{cache_dir
} = $c->stash->{anova_cache_dir
};;
516 my $cache_data = {key
=> "adj_means_${trial_id}_${trait_id}",
517 file
=> "adj_means_${trial_id}_${trait_id}.txt",
518 stash_key
=> "adj_means_file"
521 $c->controller("solGS::solGS")->cache_file($c, $cache_data);
529 return $c->dbic_schema("Bio::Chado::Schema");
534 sub begin
: Private
{
537 $c->controller("solGS::solGS")->get_solgs_dirs($c);
543 __PACKAGE__
->meta->make_immutable;