1 package solGS
::AnalysisReport
;
4 use namespace
::autoclean
;
6 use Email
::Sender
::Simple qw
/sendmail/;
8 use Email
::Simple
::Creator
;
9 use File
::Spec
::Functions qw
/catfile catdir/;
10 use File
::Slurp qw
/write_file read_file/;
11 use Storable qw
/ nstore retrieve /;
14 with
'MooseX::Getopt';
15 with
'MooseX::Runnable';
17 has
'output_details_file' => (
28 my $output_details = retrieve
($self->output_details_file);
29 $self->check_analysis_status($output_details);
34 sub check_analysis_status
{
35 my ($self, $output_details) = @_;
37 $output_details = $self->check_success($output_details);
39 $self->log_analysis_status($output_details);
40 $self->report_status($output_details);
46 my ($self, $output_details) = @_;
48 my $analysis_profile = $output_details->{analysis_profile
};
50 if ( $analysis_profile->{analysis_type
} =~ /population download/ )
52 $output_details = $self->check_population_download($output_details);
54 elsif ( $analysis_profile->{analysis_type
} =~ /(single|multiple) model/ )
56 if ($output_details->{data_set_type
} =~ /combined populations/)
58 $output_details = $self->check_combined_pops_trait_modeling($output_details);
60 elsif ($output_details->{data_set_type
} =~ /single population/)
62 $output_details = $self->check_trait_modeling($output_details);
65 elsif ( $analysis_profile->{analysis_type
} =~ /combine populations/ )
67 $output_details = $self->check_multi_pops_data_download($output_details);
69 elsif ( $analysis_profile->{analysis_type
} =~ /selection prediction/ )
71 if ($output_details->{data_set_type
} =~ /combined populations/)
73 # $output_details = $self->check_combined_pops_trait_modeling($output_details);
74 $output_details = $self->check_selection_prediction($output_details);
76 elsif ($output_details->{data_set_type
} =~ /single population/)
78 $output_details = $self->check_selection_prediction($output_details);
83 return $output_details;
87 sub check_combined_pops_trait_modeling
{
88 my ($self, $output_details) = @_;
90 $output_details = $self->check_pops_trait_data_combination($output_details);
91 $output_details = $self->check_trait_modeling($output_details);
93 return $output_details;
97 sub check_pops_trait_data_combination
{
98 my ($self, $output_details) = @_;
100 my $job_tempdir = $output_details->{r_job_tempdir
};
102 foreach my $k (keys %{$output_details})
104 if ($k =~ /population_id/)
109 if (ref $output_details->{$k} eq 'HASH')
111 $pheno_file = $output_details->{$k}->{phenotype_file
};
112 $geno_file = $output_details->{$k}->{genotype_file
};
115 if ($geno_file || $pheno_file)
124 $pheno_size = -s
$pheno_file;
125 $geno_size = -s
$geno_file;
129 $output_details->{$k}->{pheno_success
} = 'pheno success';
134 $output_details->{$k}->{geno_success
} = 'geno success';
137 if ($pheno_size && $geno_size)
139 $output_details->{$k}->{success
} = 1;
140 $output_details->{status
} = 'Done';
147 $died_file = $self->get_file($job_tempdir, 'died');
150 $output_details->{$k}->{pheno_success
} = 0;
151 $output_details->{$k}->{geno_success
} = 0;
152 $output_details->{$k}->{success
} = 0;
153 $output_details->{status
} = 'Failed';
162 if (ref $output_details->{$k} eq 'HASH')
164 $output_details->{$k}->{pheno_success
} = 0;
165 $output_details->{$k}->{geno_success
} = 0;
166 $output_details->{$k}->{success
} = 0;
167 $output_details->{status
} = 'Failed';
173 return $output_details;
178 sub check_multi_pops_data_download
{
179 my ($self, $output_details) = @_;
181 my $job_tempdir = $output_details->{r_job_tempdir
};
183 my $no_match = $output_details->{no_match
};
185 foreach my $k (keys %{$output_details})
189 if ($k =~ /population_id/)
191 if (ref $output_details->{$k} eq 'HASH')
193 $pheno_file = $output_details->{$k}->{phenotype_file
};
194 $geno_file = $output_details->{$k}->{genotype_file
};
195 print STDERR
"\n $k - pheno_file: $pheno_file -- geno_file: $geno_file\n";
198 if ($geno_file && $pheno_file)
207 $pheno_size = -s
$pheno_file;
208 $geno_size = -s
$geno_file;
212 $output_details->{$k}->{pheno_success
} = 'pheno success';
217 $output_details->{$k}->{geno_success
} = 'geno success';
220 if ($pheno_size && $geno_size)
222 $output_details->{$k}->{success
} = 1;
223 $output_details->{status
} = 'Done';
230 print STDERR
"\n job_tempdir: $job_tempdir\n";
231 $died_file = $self->get_file($job_tempdir, 'died');
234 $output_details->{$k}->{pheno_success
} = 0;
235 $output_details->{$k}->{geno_success
} = 0;
236 $output_details->{$k}->{success
} = 0;
237 $output_details->{status
} = 'Failed';
246 if (ref $output_details->{$k} eq 'HASH')
248 $output_details->{$k}->{pheno_success
} = 0;
249 $output_details->{$k}->{geno_success
} = 0;
250 $output_details->{$k}->{success
} = 0;
251 $output_details->{status
} = 'Failed';
257 return $output_details;
261 sub check_selection_prediction
{
262 my ($self, $output_details) = @_;
264 my $job_tempdir = $output_details->{r_job_tempdir
};
266 foreach my $k (keys %{$output_details})
268 if ($k =~ /trait_id/)
271 if (ref $output_details->{$k} eq 'HASH')
273 if ($output_details->{$k}->{trait_id
})
275 $gebv_file = $output_details->{$k}->{gebv_file
};
286 $gebv_size = -s
$gebv_file;
290 $output_details->{$k}->{success
} = 1;
291 $output_details->{status
} = 'Done';
298 $died_file = $self->get_file($job_tempdir, 'died');
301 $output_details->{$k}->{success
} = 0;
302 $output_details->{status
} = 'Failed';
312 if (ref $output_details->{$k} eq 'HASH')
314 $output_details->{$k}->{success
} = 0;
315 $output_details->{status
} = 'Failed';
321 return $output_details;
326 sub check_trait_modeling
{
327 my ($self, $output_details) = @_;
329 my $job_tempdir = $output_details->{r_job_tempdir
};
331 foreach my $k (keys %{$output_details})
333 if ($k =~ /trait_id/)
336 if (ref $output_details->{$k} eq 'HASH')
338 if ($output_details->{$k}->{trait_id
})
340 $gebv_file = $output_details->{$k}->{gebv_file
};
351 $gebv_size = -s
$gebv_file;
355 $output_details->{$k}->{success
} = 1;
356 $output_details->{status
} = 'Done';
363 $died_file = $self->get_file($job_tempdir, 'died');
366 $output_details->{$k}->{success
} = 0;
367 $output_details->{status
} = 'Failed';
377 if (ref $output_details->{$k} eq 'HASH')
379 $output_details->{$k}->{success
} = 0;
380 $output_details->{status
} = 'Failed';
386 return $output_details;
390 sub check_population_download
{
391 my ($self, $output_details) = @_;
393 my $job_tempdir = $output_details->{r_job_tempdir
};
395 foreach my $k (keys %{$output_details})
397 if ($k =~ /population_id/)
402 if (ref $output_details->{$k} eq 'HASH')
404 if ($output_details->{$k}->{population_id
})
406 $pheno_file = $output_details->{$k}->{phenotype_file
};
407 $geno_file = $output_details->{$k}->{genotype_file
};
409 if ($pheno_file && $geno_file)
418 $pheno_size = -s
$pheno_file;
419 $geno_size = -s
$geno_file;
421 unless (!$pheno_size)
423 $output_details->{$k}->{pheno_success
} = 1;
428 $output_details->{$k}->{geno_success
} = 1;
431 if ($pheno_size && $geno_size)
433 $output_details->{$k}->{success
} = 1;
434 $output_details->{status
} = 'Done';
441 $died_file = $self->get_file($job_tempdir, 'died');
444 $output_details->{$k}->{pheno_success
} = 0;
445 $output_details->{$k}->{geno_success
} = 0;
446 $output_details->{$k}->{success
} = 0;
447 $output_details->{status
} = 'Failed';
456 if (ref $output_details->{$k} eq 'HASH')
458 $output_details->{$k}->{pheno_success
} = 0;
459 $output_details->{$k}->{geno_success
} = 0;
460 $output_details->{$k}->{success
} = 0;
461 $output_details->{status
} = 'Failed';
469 return $output_details;
475 my ($self, $dir, $exp) = @_;
478 or die "can't open $dir: $!\n";
480 my ($file) = grep { /$exp/ && -f
"$dir/$_" } readdir($dh);
485 $file = catfile
($dir, $file);
493 my ($self, $output_details) = @_;
495 my $analysis_profile = $output_details->{analysis_profile
};
496 my $user_email = $analysis_profile->{user_email
};
497 my $user_name = $analysis_profile->{user_name
};
499 my $analysis_page = $analysis_profile->{analysis_page
};
500 my $analysis_name = $analysis_profile->{analysis_name
};
501 my $analysis_type = $analysis_profile->{analysis_type
};
505 if ($analysis_type =~ /multiple models/)
507 $analysis_result = $self->multi_modeling_message($output_details);
509 elsif ($analysis_type =~ /single model/)
511 $analysis_result = $self->single_modeling_message($output_details);
513 elsif ($analysis_type =~ /population download/ )
515 $analysis_result = $self->population_download_message($output_details);
517 elsif ($analysis_type =~ /combine populations/ )
519 $analysis_result = $self->combine_populations_message($output_details);
521 elsif ($analysis_type =~ /selection prediction/ )
523 $analysis_result = $self->selection_prediction_message($output_details);
526 my $closing = "If you have any remarks, please contact us:\n"
527 . $output_details->{contact_page
}
528 ."\n\nThanks and regards,\nsolGS M Tool";
530 my $body = "Dear $user_name,\n"
531 . "\n$analysis_result"
538 if ($output_details->{host
} =~ /localhost/)
540 my $uid = getpwuid($<);
541 $email_from = '"' . $uid .'" <' . $uid . '@localhost.localdomain>';
542 $email_to = '"' . $uid .'" <' . $uid . '@localhost.localdomain>';
546 $email_from = '"solGS M Tool" <cluster-jobs@solgenomics.net>';
547 $email_to = "$user_name <$user_email>";
548 $email_cc = 'solGS Job <cluster-jobs@solgenomics.net>';
551 my $email = Email
::Simple
->create(
556 Subject
=> "Analysis result of $analysis_name",
566 sub multi_modeling_message
{
567 my ($self, $output_details) = @_;
572 foreach my $k (keys %{$output_details})
574 if ($k =~ /trait_id/)
578 if (ref $output_details->{$k} eq 'HASH')
580 if ($output_details->{$k}->{trait_id
})
582 if ($output_details->{$k}->{success
})
586 my $trait_name = uc($output_details->{$k}->{trait_name
});
587 my $trait_page = $output_details->{$k}->{trait_page
};
588 $message .= "The analysis for $trait_name is done."
589 ." You can view the model output here:"
590 ."\n\n$trait_page\n\n";
595 my $trait_name = uc($output_details->{$k}->{trait_name
});
596 $message .= "The analysis for $trait_name failed.\n\n";
604 $message .= "You can also view the summary of all the analyses in the page below."
605 ."\nAdditionally, you may find the analytical features in the page useful.\n"
606 . $output_details->{analysis_profile
}->{analysis_page
} ."\n\n";
613 sub single_modeling_message
{
614 my ($self, $output_details) = @_;
617 foreach my $k (keys %{$output_details})
620 if ($k =~ /trait_id/)
623 if (ref $output_details->{$k} eq 'HASH')
625 if ($output_details->{$k}->{trait_id
})
627 my $trait_name = uc($output_details->{$k}->{trait_name
});
628 my $trait_page = $output_details->{$k}->{trait_page
};
629 $gebv_file = $output_details->{$k}->{gebv_file
};
631 if ($output_details->{$k}->{success
})
633 $message = "The analysis for $trait_name is done."
634 ."\nYou can view the model output here:"
635 ."\n\n$trait_page\n\n";
639 $message = "The analysis for $trait_name failed."
640 ."\n\nWe are troubleshooting the cause. "
641 . "We will contact you when we find out more.";
652 sub selection_prediction_message
{
653 my ($self, $output_details) = @_;
657 foreach my $k (keys %{$output_details})
659 if ($k =~ /trait_id/)
662 if (ref $output_details->{$k} eq 'HASH')
664 if ($output_details->{$k}->{trait_id
})
666 my $trait_name = uc($output_details->{$k}->{trait_name
});
667 my $training_pop_page = $output_details->{$k}->{training_pop_page
};
668 my $model_page = $output_details->{$k}->{model_page
};
669 my $prediction_pop_name = $output_details->{$k}->{prediction_pop_name
};
671 if ($output_details->{$k}->{success
})
676 $message .= "The prediction of selection population $prediction_pop_name is done."
677 . "\nYou can view the prediction output by clicking the trait name "
678 . "\nat the bottom of the model page(s):\n\n";
681 $message .= "$model_page\n\n";
685 $message .= "The analysis for $trait_name failed."
686 ."\n\nWe are troubleshooting the cause. "
687 . "We will contact you when we find out more.";
692 $message .= "You can also view the summary of all the analyses in the page below."
693 ."\nAdditionally, you may find the analytical features in the page useful.\n"
694 . $output_details->{referer
} . "\n\n";
705 sub population_download_message
{
706 my ($self, $output_details) = @_;
710 foreach my $k (keys %{$output_details})
712 if ($k =~ /population_id/)
714 if (ref $output_details->{$k} eq 'HASH')
716 if ($output_details->{$k}->{population_id
})
718 my $pop_name = uc($output_details->{$k}->{population_name
});
719 my $pop_page = $output_details->{$k}->{population_page
};
721 if ($output_details->{$k}->{success
})
723 $message = "The phenotype and genotype data for $pop_name is ready for analysis."
724 ."\nYou can view the training population page here:\n"
729 $message = "Downloading phenotype and genotype data for $pop_name failed."
730 ."\nWe are troubleshooting the cause. "
731 . "We will contact you when we find out more.";
742 sub combine_populations_message
{
743 my ($self, $output_details) = @_;
745 my $no_match = $output_details->{no_match
};
752 . " can not be combined.\n"
753 . "Possibly the the populations were genotyped\n"
754 . "with different marker sets or querying the data for one or more of the\n"
755 . "populations failed. See details below:\n\n";
757 my $troost_mededeling;
759 foreach my $k (keys %{$output_details})
761 if ($k =~ /population_id/)
763 if (ref $output_details->{$k} eq 'HASH')
765 if ($output_details->{$k}->{population_id
})
767 my $pop_name = uc($output_details->{$k}->{population_name
});
768 my $pop_page = $output_details->{$k}->{population_page
};
770 if ($output_details->{$k}->{success
})
772 $message .= "The phenotype and genotype data for $pop_name is succesfuly downloaded."
773 ."\nYou can view the population here:"
778 $message .= "Downloading phenotype and genotype data for $pop_name failed.";
779 $troost_mededeling = "\n\nWe are troubleshooting the cause. "
780 . "We will contact you when we find out more.";
787 $message .= $troost_mededeling;
791 my $combined_pops_page = $output_details->{combined_pops_page
};
792 $message .= "Your combined training population is ready for analysis."
793 ."You can view it here:\n\n$combined_pops_page\n\n";
800 sub log_analysis_status
{
801 my ($self, $output_details) = @_;
803 my $log_file = $output_details->{analysis_log_file
};
805 my $analysis_profile = $output_details->{analysis_profile
};
806 my $analysis_name = $analysis_profile->{analysis_name
};
808 my $status = $output_details->{status
};
810 my @contents = read_file
($log_file);
812 map{ $contents[$_] =~ m/\t$analysis_name\t/
813 ?
$contents[$_] =~ s/error|submitted/$status/ig
814 : $contents[$_] } 0..$#contents;
816 write_file
($log_file, @contents);
824 __PACKAGE__
->meta->make_immutable;