Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pull from devel to master to create release 72.0.1 #857

Merged
merged 7 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
LIST OF CHANGES FOR NPG-QC PACKAGE

release 72.0.1
- Ensured that retrieving values from a partially defined pulldown_metrics
result does not trigger an error. Added a test to demonstrate that such
result can be loaded to the database without problems.
- Updated the SeqQC summary display for pulldown_metrics incomplete results
so that just 'n/a' is displayed.
- autoqc rna seqqc max memory hardcoded limit increased to 8000MB

release 72.0.0

- QC View sorting order to put merged lanes before unmerged.
Expand Down
1 change: 1 addition & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ t/data/autoqc/pulldown_metrics/pdm.out
t/data/autoqc/pulldown_metrics/samplesheet_pulldown.csv
t/data/autoqc/pulldown_metrics/39193_3_14.pulldown_metrics.json
t/data/autoqc/pulldown_metrics/40739_2_29.pulldown_metrics.json
t/data/autoqc/pulldown_metrics/48367_2_2.pulldown_metrics.json
t/data/autoqc/qc/1937_3.map
t/data/autoqc/qX_yield/npg/instrument/15.xml
t/data/autoqc/qX_yield/npg/run/2549.xml
Expand Down
2 changes: 1 addition & 1 deletion lib/npg_qc/autoqc/checks/rna_seqc.pm
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ sub _command {
if($self->ref_rrna){
$ref_rrna_option = q[-bwa ] . $self->bwa_rrna . q[ -BWArRNA ]. $self->ref_rrna;
}
my $command = $self->java_cmd. sprintf q[ -Xmx4000m -XX:+UseSerialGC -XX:-UsePerfData -jar %s -s %s -o %s -r %s -t %s -ttype %d %s %s],
my $command = $self->java_cmd. sprintf q[ -Xmx8000m -XX:+UseSerialGC -XX:-UsePerfData -jar %s -s %s -o %s -r %s -t %s -ttype %d %s %s],
$self->_java_jar_path,
$self->_input_str,
$self->rna_seqc_report_path,
Expand Down
105 changes: 58 additions & 47 deletions lib/npg_qc/autoqc/role/pulldown_metrics.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use Readonly;
our $VERSION = '0';
## no critic (Documentation::RequirePodAtEnd)

Readonly::Scalar our $HUNDRED => 100;
Readonly::Scalar our $HUNDRED => 100;

=head1 NAME

Expand All @@ -27,28 +27,27 @@ npg_qc::autoqc::role::pulldown_metrics
=cut

sub criterion {
my $self = shift;

return q[Fail if on bait bases less than 20%];
}

=head2 bait_design_efficiency

Target territory / bait territory. 1 == perfectly efficient, 0.5 = half of baited bases are not target. BAIT_DESIGN_EFFICIENCY in Picard metrics.
Picard metrics BAIT_DESIGN_EFFICIENCY: target territory / bait territory.
1 == perfectly efficient, 0.5 = half of baited bases are not target.

=cut

sub bait_design_efficiency {
my $self = shift;
if ($self->bait_territory && defined $self->target_territory) {
return $self->target_territory/$self->bait_territory;
return $self->target_territory / $self->bait_territory;
}
return;
}

=head2 unique_reads_percent

unique_reads_num / total_reads_num, PCT_PF_UQ_READS in Picard metrics.
Picard metrics PCT_PF_UQ_READS: unique_reads_num / total_reads_num

=cut

Expand All @@ -69,106 +68,120 @@ sub unique_reads_percent {
sub unique_reads_aligned_percent {
my $self = shift;
if ($self->total_reads_num && defined $self->unique_reads_aligned_num) {
return ($self->unique_reads_aligned_num / $self->total_reads_num) * $HUNDRED;
return ($self->unique_reads_aligned_num /
$self->total_reads_num) * $HUNDRED;
}
return;
}

=head2 on_bait_reads_percent

Picard metrics:
PF_UQ_READS_ALIGNED_BAIT : The number of PF unique reads that are aligned overlapping a bait by >= 1bp
Picard metrics PF_UQ_READS_ALIGNED_BAIT:
The number of PF unique reads that are aligned overlapping a bait by >= 1bp

=cut

sub on_bait_reads_percent {
my $self = shift;

if ($self->total_reads_num && defined $self->other_metrics->{PF_UQ_READS_ALIGNED_BAIT}) {
return ($self->other_metrics->{PF_UQ_READS_ALIGNED_BAIT} / $self->total_reads_num) * $HUNDRED;
}
if (defined $self->other_metrics && $self->total_reads_num &&
defined $self->other_metrics->{PF_UQ_READS_ALIGNED_BAIT}) {
return ($self->other_metrics->{PF_UQ_READS_ALIGNED_BAIT} /
$self->total_reads_num) * $HUNDRED;
}
return;
}

=head2 near_bait_reads_percent


Picard metrics :
PF_UQ_READS_ALIGNED_NEAR_BAIT: The number of PF unique reads that dont overlap a bait but align within 250bp
of a bait.
Picard metrics PF_UQ_READS_ALIGNED_NEAR_BAIT:
The number of PF unique reads that dont overlap a bait but align within 250bp
of a bait.

=cut

sub near_bait_reads_percent {
my $self = shift;

if ($self->total_reads_num && defined $self->other_metrics->{PF_UQ_READS_ALIGNED_NEAR_BAIT}) {
return ($self->other_metrics->{PF_UQ_READS_ALIGNED_NEAR_BAIT} / $self->total_reads_num) * $HUNDRED;
if (defined $self->other_metrics && $self->total_reads_num &&
defined $self->other_metrics->{PF_UQ_READS_ALIGNED_NEAR_BAIT}) {
return ($self->other_metrics->{PF_UQ_READS_ALIGNED_NEAR_BAIT} /
$self->total_reads_num) * $HUNDRED;
}
return;
}

=head2 on_target_reads_percent

Picard metrics:
PF_UQ_READS_ALIGNED_TARGET: The number of PF unique reads that are aligned overlapping a target by >= 1bp
Picard metrics PF_UQ_READS_ALIGNED_TARGET:
The number of PF unique reads that are aligned overlapping a target by >= 1bp

=cut

sub on_target_reads_percent {
my $self = shift;

if ($self->total_reads_num && defined $self->other_metrics->{PF_UQ_READS_ALIGNED_TARGET}) {
return ($self->other_metrics->{PF_UQ_READS_ALIGNED_TARGET} / $self->total_reads_num) * $HUNDRED;
if (defined $self->other_metrics && $self->total_reads_num &&
defined $self->other_metrics->{PF_UQ_READS_ALIGNED_TARGET}) {
return ($self->other_metrics->{PF_UQ_READS_ALIGNED_TARGET} /
$self->total_reads_num) * $HUNDRED;
}
return;
}

=head2 selected_bases_percent

(on_bait_bases_num + near_bait_bases_num) / [PF_BASES, PCT_SELECTED_BASES] in Picard metrics.
(on_bait_bases_num + near_bait_bases_num) / [PF_BASES, PCT_SELECTED_BASES]
in Picard metrics.

=cut

sub selected_bases_percent {
my $self= shift;
if ($self->picard_version_base_count && defined $self->on_bait_bases_num && defined $self->near_bait_bases_num) {
return (($self->on_bait_bases_num + $self->near_bait_bases_num) / $self->picard_version_base_count) * $HUNDRED;
if ($self->picard_version_base_count && defined $self->on_bait_bases_num &&
defined $self->near_bait_bases_num) {
return (($self->on_bait_bases_num + $self->near_bait_bases_num) /
$self->picard_version_base_count) * $HUNDRED;
}
return;
}

=head2 on_bait_bases_percent

The percentage of aligned, de-duped, on-bait bases out of the PF bases available. PCT_USABLE_BASES_ON_BAIT in Picard metrics
The percentage of aligned, de-duped, on-bait bases out of the PF bases
available. PCT_USABLE_BASES_ON_BAIT in Picard metrics

=cut

sub on_bait_bases_percent {
my $self = shift;
if($self->picard_version_base_count && defined $self->on_bait_bases_num) {
return ($self->on_bait_bases_num / $self->picard_version_base_count) * $HUNDRED;
return ($self->on_bait_bases_num /
$self->picard_version_base_count) * $HUNDRED;
}
return;
}

=head2 near_bait_bases_percent

The percentage of aligned, de-duped, on-bait bases out of the PF bases available.
The percentage of aligned, de-duped, on-bait bases out of the PF bases
available.

=cut

sub near_bait_bases_percent {
my $self = shift;
if($self->picard_version_base_count && defined $self->near_bait_bases_num) {
return ($self->near_bait_bases_num / $self->picard_version_base_count) * $HUNDRED;
return ($self->near_bait_bases_num /
$self->picard_version_base_count) * $HUNDRED;
}
return;
}

=head2 off_bait_bases_percent

The percentage of aligned PF bases that mapped neither on or near a bait. PCT_OFF_BAIT in Picard metrics
The percentage of aligned PF bases that mapped neither on or near a bait.
PCT_OFF_BAIT in Picard metrics

=cut

Expand All @@ -182,7 +195,7 @@ sub off_bait_bases_percent {

=head2 on_bait_vs_selected_percent

ON_BAIT_VS_SELECTED in Picard metrics
ON_BAIT_VS_SELECTED in Picard metrics

=cut

Expand All @@ -199,14 +212,16 @@ sub on_bait_vs_selected_percent {

=head2 on_target_bases_percent

The percentage of aligned, de-duped, on-target bases out of the PF bases available. PCT_USABLE_BASES_ON_TARGET in Picard metrics
The percentage of aligned, de-duped, on-target bases out of the PF bases
available. PCT_USABLE_BASES_ON_TARGET in Picard metrics

=cut

sub on_target_bases_percent {
my $self = shift;
if ($self->picard_version_base_count && defined $self->on_target_bases_num) {
return ($self->on_target_bases_num / $self->picard_version_base_count) * $HUNDRED;
return ($self->on_target_bases_num /
$self->picard_version_base_count) * $HUNDRED;
}
return;
}
Expand All @@ -232,11 +247,10 @@ sub zero_coverage_targets_percent {
sub target_bases_coverage_percent {
my $self = shift;
my $tbc = {};
if ($self->other_metrics) {
my @keys = keys %{$self->other_metrics};
@keys = grep {/^PCT_TARGET_BASES/smx} @keys;
if (defined $self->other_metrics) {
my @keys = grep {/^PCT_TARGET_BASES/smx} keys %{$self->other_metrics};
foreach my $key (@keys) {
my ($coverage) = $key =~ /_(\d+)X/smx;
my ($coverage) = $key =~ /_(\d+)X/smx;
$tbc->{$coverage} = $self->other_metrics->{$key} * $HUNDRED;
}
}
Expand All @@ -246,8 +260,6 @@ sub target_bases_coverage_percent {
=head2 bait_bases_coverage_percent

Various increments between PCT_BAIT_BASES_1X and PCT_BAIT_BASES_1000X
to be stored in npgqc pulldown_metrics.other_metrics

Represents the fraction of bait bases with a depth of >= Nx

PCT_BAIT_BASES_2X
Expand All @@ -260,9 +272,8 @@ PCT_BAIT_BASES_30X
sub bait_bases_coverage_percent {
my $self = shift;
my $bbc = {};
if ($self->other_metrics) {
my @keys = keys %{$self->other_metrics};
@keys = grep {/^PCT_BAIT_BASES/smx} @keys;
if (defined $self->other_metrics) {
my @keys = grep {/^PCT_BAIT_BASES/smx} keys %{$self->other_metrics};
foreach my $key (@keys) {
# e.g. PCT_BAIT_BASES_30X
# multiply by a 100 as is not already a percentage, despite the name
Expand All @@ -271,7 +282,6 @@ sub bait_bases_coverage_percent {
}
}


return $bbc;
}

Expand All @@ -283,9 +293,8 @@ sub bait_bases_coverage_percent {
sub hs_penalty {
my $self = shift;
my $penalty = {};
if ($self->other_metrics) {
my @keys = keys %{$self->other_metrics};
@keys = grep {/^HS_PENALTY/smx} @keys;
if (defined $self->other_metrics) {
my @keys = grep {/^HS_PENALTY/smx} keys %{$self->other_metrics};
foreach my $key (@keys) {
my ($coverage) = $key =~ /_(\d+)X/smx;
$penalty->{$coverage} = $self->other_metrics->{$key};
Expand All @@ -309,7 +318,9 @@ PF_BASES instead.

sub picard_version_base_count {
my $self = shift;
return (exists $self->other_metrics->{PF_BASES}) ? $self->other_metrics->{PF_BASES} : $self->unique_bases_aligned_num;
return
(defined $self->other_metrics && exists $self->other_metrics->{PF_BASES})
? $self->other_metrics->{PF_BASES} : $self->unique_bases_aligned_num;
}


Expand Down
6 changes: 5 additions & 1 deletion npg_qc_viewer/root/src/ui_lanes/lane.tt2
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ END
[% href='#pdmc_' _ result.id_run _ ':' _ result.position _ ':' _ result.tag_index %]

[%-
mcoverage = 0;
mcoverage;
IF result.unique_bases_aligned_num.defined && result.unique_bases_aligned_num != 0;
mcoverage = result.mean_target_coverage / (result.unique_bases_aligned_num / 1000000000);
END;
Expand All @@ -439,6 +439,7 @@ END
END;
coverage = result.target_bases_coverage_percent.20 ? result.target_bases_coverage_percent.20 : 0;
-%]
[% IF mcoverage.defined %]
[% IF result.interval_files_identical.defined && result.interval_files_identical == 1 %]
<span class="pdmc_na" title="Bait and target intervals identical"><a href="[% href %]">NA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NA<br/></a></span>
<span class="dark_blue" title="On-bait bases %age"><a href="[% href %]">[% FILTER format('%2.2f');on_bait;END %]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a></span>
Expand All @@ -448,6 +449,9 @@ END
<span class="dark_blue" title="On-bait bases %age"><a href="[% href %]">[% FILTER format('%2.2f');on_bait;END %]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</a></span>
<span class="dark_blue" title="On-target bases %age"><a href="[% href %]">[% FILTER format('%2.2f');on_target;END %]</a></span>
[% END %]
[% ELSE %]
n/a
[% END %]
[%- END -%]

[% BLOCK substitution_metrics -%]
Expand Down
21 changes: 17 additions & 4 deletions t/60-autoqc-db_loader.t
Original file line number Diff line number Diff line change
Expand Up @@ -875,17 +875,30 @@ subtest 'loading review and other results from path' => sub {
};

subtest 'loading partially defined results' => sub {
plan tests => 2;
plan tests => 4;

my $db = $db_helper->create_test_db(q[npg_qc::Schema], 't/data/fixtures');
my $db = $db_helper->create_test_db(q[npg_qc::Schema]);
my $db_loader = npg_qc::autoqc::db_loader->new(
path => ['t/data/autoqc/dbix_loader/short_results'],
schema => $db,
verbose => 0,
verbose => 0
);
lives_ok { $db_loader->load() } 'no error loading an incomplete result';
lives_ok { $db_loader->load() }
'no error loading an incomplete genotype result';
is ($db->resultset('Genotype')->search({})->count(), 1,
'one genotype record is created');

$db_loader = npg_qc::autoqc::db_loader->new(
json_file =>
['t/data/autoqc/pulldown_metrics/48367_2_2.pulldown_metrics.json'],
schema => $db,
verbose => 0
);
lives_ok { $db_loader->load() }
'no error loading an incomplete pulldown_metrics result';
is ($db->resultset('PulldownMetrics')->search({})->count(), 1,
'one genotype record is created');

};

1;
Loading
Loading