Skip to content

Commit

Permalink
Merge pull request #681 from wtsi-npg/devel
Browse files Browse the repository at this point in the history
merge from devel to master to create release 68.2.0
  • Loading branch information
mgcam authored Apr 28, 2020
2 parents b24b60d + 010db50 commit 40fc5f5
Show file tree
Hide file tree
Showing 11 changed files with 286 additions and 40 deletions.
10 changes: 10 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
LIST OF CHANGES FOR NPG-QC PACKAGE

release 68.2.0
- tweak for genome coverage figure in qc summary - fall back to target
if no default autosomes only number available.
- a new script - npg_simple_robo4artic - to generate autoqc review
results from third party QC data
- skip ref_match autoqc checks only for true GBS samples
- SeqQC viewer: make visual cues for utility (user) QC outcomes always
visible regardless of whether they concur with the manual QC outcome
or not

release 68.1.0
- criteria_md5 attribute is added to the review autoqc result object;
previously it was computed at a point of loading to the database
Expand Down
1 change: 1 addition & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ bin/mqc_outcome_reporter
bin/npg_mqc_skipper
bin/npg_qc_autoqc_data.pl
bin/npg_qc_tag_sniff.pl
bin/npg_simple_robo4artic
bin/call_gtck_composite_rpt.pl
bin/genotype_call_results_reporter
Build.PL
Expand Down
208 changes: 208 additions & 0 deletions bin/npg_simple_robo4artic
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
#!/usr/bin/env perl

use strict;
use warnings;
use FindBin qw($Bin);
use lib ( -d "$Bin/../lib/perl5" ? "$Bin/../lib/perl5" : "$Bin/../lib" );
use Log::Log4perl qw(:levels);
use Try::Tiny;
use Carp;

use npg_tracking::glossary::rpt;
use npg_tracking::glossary::composition::factory::rpt_list;
use npg_tracking::glossary::moniker;
use npg_qc::autoqc::checks::review;

our $VERSION = '0';

Log::Log4perl->easy_init({layout => '%d %-5p %c - %m%n',
level => $INFO});
my $logger = Log::Log4perl->get_logger();

my $dir_out = $ARGV[0];
if (defined $dir_out) {
if (($dir_out ne q[]) and (-d $dir_out) and (-w $dir_out)) {
$logger->info("Using output directory $dir_out");
} else {
$logger->error(
"Output directory $dir_out does not exists or is not writable");
exit 2;
}
} else {
$logger->info('Using current directory as an output directory');
}

my $line_number = 0;
##no critic (InputOutput::ProhibitExplicitStdin)
while (my $line = <STDIN>) {
##use critic
$line_number++;

if ($line =~ /\Asample_name,/smx) { # header, skip
next;
}
my $l = "Line $line_number:";
my $outcome;
my $file_name_root;
my $r;
my $sname;
my $lib_type;

try {
my @columns = split /,/xms, $line;
(@columns >= 2) or croak 'at least two columns are expected';
$file_name_root = shift @columns;
$file_name_root or croak 'no file name in the first column';
$outcome = pop @columns;
defined $outcome or croak 'no outcome in the last column';
$outcome =~ s/\s+\Z//xms;
$outcome =~ /\A(TRUE|FALSE)\Z/xms or croak
"unexpected outcome value '$outcome'";

my $h = npg_tracking::glossary::moniker->parse_file_name($file_name_root);
my $rpt = npg_tracking::glossary::rpt->deflate_rpt($h);
$r = npg_qc::autoqc::checks::review->new(rpt_list => $rpt);
$sname = $r->lims->sample_supplier_name();
$lib_type = $r->lims->library_type();
} catch {
$logger->error("$l $_");
exit 1;
};

if (!$sname) {
$logger->warn(
"$l skipping $file_name_root, sample supplier name is not set");
next;
}

my ($name_prefix) = $sname =~ /\A([[:upper:]]{4})-/xms;
if (!$name_prefix || ($name_prefix =~ /\ACGAP\Z/ixms)) {
$logger->warn(
"$l skipping $file_name_root, sample '${sname}' does not belong to Heron");
next;
}

if (!$lib_type) {
$logger->warn(
"$l skipping $file_name_root, library type is not set");
next;
}

$r->result->pass(int($outcome eq 'TRUE' ? 1 : 0));
$r->result->qc_outcome($r->generate_qc_outcome('uqc', 'artic-qc'));
$r->result->library_type($lib_type);
my $condition = 'Passed ncov2019-artic-nf QC';
$r->result->evaluation_results({$condition => $r->result->pass});
$r->result->criteria({'and' => [$condition]});
try {
$r->result->store($dir_out);
} catch {
$logger->error("$l $_");
exit 2;
};
}

exit 0;

__END__
=head1 NAME
npg_simple_robo4artic
=head1 USAGE
=head1 CONFIGURATION
=head1 SYNOPSIS
echo '34014_1#104,TRUE' | npg_simple_robo4artic
echo '34014_1#104,FALSE' | npg_simple_robo4artic 'my_dir'
=head1 DESCRIPTION
This script creates autoqc review result JSON files for
entities and outcomes piped from STDIN. One line of input
produces one file, unless this input is considered irrelevant.
The JSON files are created in the working directory unless an
alternative directory is specified as teh only argument. The
qc outcomes are recorded as user QC.
Example of input:
34014_1#104,1.21,98.61,19221,34014_1#104.primertrimmed.consensus.fa,34014_1#104.mapped.primertrimmed.sorted.bam,TRUE
34014_1#105,87.85,9.91,376,34014_1#105.primertrimmed.consensus.fa,34014_1#105.mapped.primertrimmed.sorted.bam,FALSE
Only the first and the last column of the input is considered.
=head1 REQUIRED ARGUMENTS
None
=head1 OPTIONS
=head1 SUBROUTINES/METHODS
=head1 DIAGNOSTICS
=head1 CONFIGURATION AND ENVIRONMENT
=head1 DEPENDENCIES
=over
=item strict
=item warnings
=item FindBin
=item lib
=item Carp
=item Try::Tiny
=item Log::Log4perl
=item npg_tracking::glossary::rpt
=item npg_tracking::glossary::composition::factory::rpt_list
=item npg_tracking::glossary::moniker
=item npg_qc::autoqc::checks::review
=back
=head1 INCOMPATIBILITIES
=head1 EXIT STATUS
=head1 BUGS AND LIMITATIONS
=head1 AUTHOR
Marina Gourtovaia
=head1 LICENSE AND COPYRIGHT
Copyright (C) 2020 Genome Research Ltd.
This file is part of NPG.
NPG is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
=cut
2 changes: 1 addition & 1 deletion lib/npg_qc/Schema/Mqc/OutcomeEntity.pm
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ sub sanitize_value {
$value =~ s/\A\s+//smx;
$value =~ s/\s+\Z//smx;
$value or croak q[Only white space characters in input];
($value =~ /\A[[:word:][:space:]#-]+\Z/smx) or croak 'Illegal characters';
($value =~ /\A[[:word:][:space:]#-]+\Z/smx) or croak qq[Illegal characters in $value];
return $value;
}

Expand Down
3 changes: 2 additions & 1 deletion lib/npg_qc/autoqc/checks/ref_match.pm
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ sub _scan_repository {
override 'can_run' => sub {
my $self = shift;

if($self->lims->gbs_plex_name){
if ($self->lims->gbs_plex_name &&
($self->lims->library_type && $self->lims->library_type =~ /^GbS|GnT\sMDA/ismx)) {
$self->result->add_comment('Ref match skipped for gbs plex libraries.');
return 0;
}
Expand Down
73 changes: 45 additions & 28 deletions lib/npg_qc/autoqc/checks/review.pm
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ sub execute {
$self->final_qc_outcome && croak $err;
$self->result->add_comment($err);
};
$self->result->qc_outcome($self->_generate_qc_outcome($md5));
$self->result->qc_outcome(
$self->generate_qc_outcome($self->_outcome_type(), $md5));

return;
}
Expand Down Expand Up @@ -270,6 +271,42 @@ sub evaluate {
return $self->_apply_operator([values %{$emap}], $CONJUNCTION_OP);
}

=head2 generate_qc_outcome
Returns a hash reference representing the QC outcome.
my $u_outcome = $r->generate_qc_outcome('uqc', $md5);
my $m_outcome = $r->generate_qc_outcome('mqc');
=cut

sub generate_qc_outcome {
my ($self, $outcome_type, $md5) = @_;

$outcome_type or croak 'outcome type should be defined';

my $package_name = 'npg_qc::Schema::Mqc::OutcomeDict';
my $pass = $self->result->pass;
#####
# Any of Accepted, Rejected, Undecided outcomes can be returned here
my $outcome = ($outcome_type eq $QC_TYPE_DEFAULT)
? $package_name->generate_short_description(
$self->final_qc_outcome ? 1 : 0, $pass)
: $package_name->generate_short_description_prefix($pass);

$outcome_type .= '_outcome';
my $outcome_info = { $outcome_type => $outcome,
timestamp => create_current_timestamp(),
username => $ROBO_KEY};
if ($outcome_type =~ /\Auqc/xms) {
my @r = ($ROBO_KEY, $VERSION);
$md5 and push @r, $md5;
$outcome_info->{'rationale'} = join q[ ], @r;
}

return $outcome_info;
}

=head2 lims
st::api::lims object corresponding ti this object's rpt_list
Expand All @@ -278,13 +315,12 @@ private attribute.
=cut

has '_lims' => (
has 'lims' => (
isa => 'st::api::lims',
is => 'ro',
init_arg => 'lims',
lazy_build => 1,
);
sub _build__lims {
sub _build_lims {
my $self = shift;
return st::api::lims->new(rpt_list => $self->rpt_list);
}
Expand All @@ -299,7 +335,7 @@ sub _build__robo_config{

my $message;
my $strict = 1; # Parse study section only, ignore the default section.
my $config = $self->study_config($self->_lims(), $strict);
my $config = $self->study_config($self->lims(), $strict);

if (keys %{$config}) {
$config = $config->{$ROBO_KEY};
Expand Down Expand Up @@ -332,7 +368,7 @@ sub _build__criteria {

(keys %{$self->_robo_config}) or return $rewritten;

my $lib_type = $self->_lims->library_type;
my $lib_type = $self->lims->library_type;
$lib_type or croak 'Library type is not defined for ' . $self->composition->freeze;
# We are going to compare library type strings in lower case
# because the case for this type of LIMs data might be inconsistent.
Expand Down Expand Up @@ -569,8 +605,8 @@ sub _evaluate_expression {
return $evaluator->($obj);
}

sub _generate_qc_outcome {
my ($self, $md5) = @_;
sub _outcome_type {
my $self = shift;

my $outcome_type = $self->_robo_config()->{$QC_TYPE_KEY};
if ($outcome_type) {
Expand All @@ -581,26 +617,7 @@ sub _generate_qc_outcome {
$outcome_type = $QC_TYPE_DEFAULT;
}

my $package_name = 'npg_qc::Schema::Mqc::OutcomeDict';
my $pass = $self->result->pass;
#####
# Any of Accepted, Rejected, Undecided outcomes can be returned here
my $outcome = ($outcome_type eq $QC_TYPE_DEFAULT)
? $package_name->generate_short_description(
$self->final_qc_outcome ? 1 : 0, $pass)
: $package_name->generate_short_description_prefix($pass);

$outcome_type .= '_outcome';
my $outcome_info = { $outcome_type => $outcome,
timestamp => create_current_timestamp(),
username => $ROBO_KEY};
if ($outcome_type eq 'uqc') {
my @r = ($ROBO_KEY, $VERSION);
$md5 and push @r, $md5;
$outcome_info->{'rationale'} = join q[:], @r;
}

return $outcome_info;
return $outcome_type;
}

__PACKAGE__->meta->make_immutable();
Expand Down
2 changes: 1 addition & 1 deletion npg_qc_viewer/root/src/about_qc_checks.tt2
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ target metrics separated by a pipe delimiter ;<br/><br/>
<tr><th>Field</th><th>Description</th></tr>
<tr><td>PP%</td><td>% mapped reads which are mapped in proper pairs - from Target region stats</td></tr>
<tr><td>Gb</td><td>yield within target (bp) - from Target region stats</td></tr>
<tr><td>Cov</td><td>% regions above coverage threshold - from Autosomes only target region stats</td></tr>
<tr><td>Cov</td><td>% regions above coverage threshold - Autosomes only target region stats is the default value but if Autosomes only (denoted by small a) stats aren't available it will fall back to Target regions stats (denoted by a small t).</td></tr>
</table>
<br/><br/>
<a name="verify bam id_check"></a>
Expand Down
Loading

0 comments on commit 40fc5f5

Please sign in to comment.