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

Switched default LIMS driver in samplesheet generation #750

Merged
merged 4 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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

- Switched the default LIMS driver in samplesheet generation from 'xml'
to 'ml_warehouse'.
- Added 'lims_driver_type' attribute to npg::samplesheet.
- Updated the tests for samplesheet generation, which are using the xml
LIMS driver, to set the driver type explicitly.
- In samplesheet generation, dropped a special case of MiSeq instruments
without a batch; last use in production was over 5 years ago.

release 96.0.0
- Fixed a regression in the npg_move_runfolder script,
which made it unusable.
Expand Down
59 changes: 46 additions & 13 deletions lib/npg/samplesheet.pm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use st::api::lims;
use st::api::lims::samplesheet;
use npg_tracking::util::config qw(get_config_staging_areas);
use npg_tracking::util::abs_path qw(abs_path);
use WTSI::DNAP::Warehouse::Schema;

with 'npg_tracking::glossary::run';

Expand Down Expand Up @@ -62,12 +63,25 @@ still retained in the relevant custom fields.
my$config=get_config_staging_areas();
Readonly::Scalar my $SAMPLESHEET_PATH => $config->{'samplesheets'}||q(samplesheets/);
Readonly::Scalar my $MIN_COLUMN_NUM => 3;
Readonly::Scalar my $DEFAULT_LIMS_DRIVER_TYPE => 'xml';
Readonly::Scalar my $DEFAULT_LIMS_DRIVER_TYPE => 'ml_warehouse';

##################################################################
####################### Public attributes ########################
##################################################################

=head2 lims_driver_type

LIMs driver type to use, defaults to ml_warehouse.

=cut

has 'lims_driver_type' => (
'isa' => 'Str',
'required' => 0,
'is' => 'ro',
'default' => $DEFAULT_LIMS_DRIVER_TYPE,
);

=head2 id_run

An optional attribute
Expand Down Expand Up @@ -157,6 +171,21 @@ sub _build_npg_tracking_schema {
return $s
}

=head2 mlwh_schema

DBIx schema class for ml_warehouse access.

=cut

has 'mlwh_schema' => (
isa => 'WTSI::DNAP::Warehouse::Schema',
jmtcsngr marked this conversation as resolved.
Show resolved Hide resolved
is => 'ro',
required => 0,
lazy_build => 1,);
sub _build_mlwh_schema {
return WTSI::DNAP::Warehouse::Schema->connect();
}

=head2 run

An attribute, DBIx object for a row in the run table of the tracking database.
Expand All @@ -180,7 +209,6 @@ An attribute, an array of st::api::lims type objects.

This attribute should normally be provided by the caller via the
constuctor. If the attribute is not provided, it it built automatically.
XML st::api::lims driver is used to access LIMS data.

=cut

Expand All @@ -191,17 +219,20 @@ has 'lims' => (
);
sub _build_lims {
my $self=shift;
my $id = $self->run->batch_id;
if ($id=~/\A\d{13}\z/smx) {
load_class 'st::api::lims::warehouse';
return [st::api::lims->new(
position => 1,
driver => st::api::lims::warehouse->new(position=>1, tube_ean13_barcode=>$id)
)];

my $ref = {driver_type => $self->lims_driver_type};
my $batch_id = $self->run->batch_id;
if ($self->lims_driver_type eq $DEFAULT_LIMS_DRIVER_TYPE) {
$ref->{'id_flowcell_lims'} = $batch_id;
$ref->{'mlwh_schema'} = $self->mlwh_schema;
} elsif ($self->lims_driver_type eq 'xml') {
$ref->{'batch_id'} = $batch_id;
} else {
croak sprintf 'Lazy-build for driver type %s is not inplemented',
$self->lims_driver_type;
}
return [st::api::lims->new(
batch_id => $id,
driver_type => $DEFAULT_LIMS_DRIVER_TYPE)->children];

return [st::api::lims->new($ref)->children];
};

=head2 output
Expand Down Expand Up @@ -592,6 +623,8 @@ __END__

=item open

=item WTSI::DNAP::Warehouse::Schema

=back

=head1 INCOMPATIBILITIES
Expand All @@ -604,7 +637,7 @@ David K. Jackson E<lt>[email protected]<gt>

=head1 LICENSE AND COPYRIGHT

Copyright (C) 2019,2020 Genome Research Ltd.
Copyright (C) 2019,2020, 2023 Genome Research Ltd.

This file is part of NPG.

Expand Down
74 changes: 57 additions & 17 deletions t/47-samplesheet.t
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use strict;
use warnings;
use Test::More tests => 11;
use Test::More tests => 13;
use Test::LongString;
use Test::Exception;
use File::Slurp;
use File::Temp qw/tempdir/;
use File::Path qw/make_path/;
use Moose::Meta::Class;

use t::dbic_util;
local $ENV{'dev'} = q(wibble); # ensure we're not going live anywhere
Expand All @@ -15,6 +16,12 @@ use_ok('npg::samplesheet');
use_ok('st::api::lims');

my $schema = t::dbic_util->new->test_schema();

my $class = Moose::Meta::Class->create_anon_class(roles=>[qw/npg_testing::db/]);
my $mlwh_schema = $class->new_object({})->create_test_db(
q[WTSI::DNAP::Warehouse::Schema], q[t/data/fixtures_lims_wh]
);

local $ENV{NPG_WEBSERVICE_CACHE_DIR} = q(t/data/samplesheet);

my $dir = tempdir( CLEANUP => 1 );
Expand All @@ -23,23 +30,56 @@ subtest 'object creation' => sub {
plan tests => 8;

my $result = q();
dies_ok { npg::samplesheet->new( repository=>$dir, output=>\$result)->process }
dies_ok { npg::samplesheet->new( lims_driver_type=>'xml', repository=>$dir, output=>\$result)->process }
'sample sheet process fails when neither run object nor id_run given';

my $ss;
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>7007); } 'sample sheet object - no output provided';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>7007); } 'sample sheet object - no output provided';
cmp_ok($ss->output, 'eq', '/nfs/sf49/ILorHSorMS_sf49/samplesheets/wibble/MS0001309-300.csv', 'default output location (with zeroes trimmed appropriately)');
is($ss->lims->[0]->driver_type, 'xml', 'xml driver is used');

lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946); } 'sample sheet object - no output provided';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946); } 'sample sheet object - no output provided';
cmp_ok($ss->output, 'eq', '/nfs/sf49/ILorHSorMS_sf49/samplesheets/wibble/000000000-A0616.csv', 'default output location');

lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>7007); } 'sample sheet object - no output provided';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>7007); } 'sample sheet object - no output provided';
my $orig_flowcell_id = $ss->run->flowcell_id;
$ss->run->flowcell_id(q(MS2000132-500V2));
cmp_ok($ss->output, 'eq', '/nfs/sf49/ILorHSorMS_sf49/samplesheets/wibble/MS2000132-500V2.csv', 'default output location copes with V2 MiSeq cartirdges/reagent kits');
};

subtest 'error on an unknown driver types' => sub {
plan tests => 1;

throws_ok {
npg::samplesheet->new(
lims_driver_type => 'foo',
repository => $dir,
npg_tracking_schema => $schema,
id_run => 7007)->lims()
} qr/Lazy-build for driver type foo is not inplemented/,
'error with the driver type for which LIMS objects cannot be built';
};

subtest 'simple tests for the default driver' => sub {
plan tests => 2;

my $run_row = $schema->resultset('Run')->find(7007);
my $current_batch_id = $run_row->batch_id;
$run_row->update({batch_id => 57543});

my $ss = npg::samplesheet->new(
repository => $dir,
npg_tracking_schema => $schema,
mlwh_schema => $mlwh_schema,
id_run => 7007
);
is ($ss->lims_driver_type, 'ml_warehouse', 'correct default driver type');
my $lims = $ss->lims();
is (@{$lims}, 1, 'LIMS data for 1 lane is built');

$run_row->update({batch_id => $current_batch_id});
};

subtest 'values conversion' => sub {
plan tests => 12;

Expand Down Expand Up @@ -91,13 +131,13 @@ RESULT_7007

my $ss;
my $result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>7007, output=>\$result); } 'sample sheet object for unplexed paired run';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>7007, output=>\$result); } 'sample sheet object for unplexed paired run';
lives_ok { $ss->process(); } ' sample sheet generated';
is_string($result, $expected_result_7007);

my $run = $schema->resultset(q(Run))->find(7007);
$result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, run=>$run, output=>\$result); } 'sample sheet object from run object - no id_run given';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, run=>$run, output=>\$result); } 'sample sheet object from run object - no id_run given';
lives_ok { $ss->process(); } ' sample sheet generated';
is_string($result, $expected_result_7007);
};
Expand All @@ -107,7 +147,7 @@ subtest 'default samplesheet for a plexed paired run' => sub {

my $ss;
my $result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, output=>\$result); } 'samplesheet object for plexed paired run';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, output=>\$result); } 'samplesheet object for plexed paired run';
my $expected_result = << 'RESULT_6946';
[Header],,,,
Investigator Name,mq1,,,
Expand Down Expand Up @@ -150,7 +190,7 @@ subtest 'default samplesheet for a plexed paired run with reference fallback' =>

my $ss;
my $result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>7825, output=>\$result); } 'sample sheet object for plexed paired run';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>7825, output=>\$result); } 'sample sheet object for plexed paired run';
my $expected_result = << 'RESULT_7825';
[Header],,,,
Investigator Name,nh4,,,
Expand Down Expand Up @@ -187,7 +227,7 @@ subtest 'default samplesheet, mkfastq option enabled' => sub {
# with the mkfastq option we get an extra leading column, Lane
my $ss;
my $result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>7826, mkfastq => 1, output=>\$result); }
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>7826, mkfastq => 1, output=>\$result); }
'sample sheet object mkfastq';
my $expected_result = << 'RESULT_mkfastq';
[Header],,,,,
Expand Down Expand Up @@ -224,7 +264,7 @@ subtest 'default samplesheet for dual index' => sub {

my $ss;
my $result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>7826, output=>\$result); } 'sample sheet object for dual index';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>7826, output=>\$result); } 'sample sheet object for dual index';
my $expected_result = << 'RESULT_7826';
[Header],,,,
Investigator Name,nh4,,,
Expand Down Expand Up @@ -260,13 +300,13 @@ subtest 'extended samplesheets' => sub {

my $ss;
my $result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, extend => 1, id_run=>7007, output=>\$result); } 'extended sample sheet object for unplexed paired run';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, extend => 1, id_run=>7007, output=>\$result); } 'extended sample sheet object for unplexed paired run';
ok(!$ss->_dual_index, 'no dual index');
lives_ok { $ss->process(); } ' sample sheet generated';
is_string($result, read_file('t/data/samplesheet/7007_extended.csv'));

$result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); } 'extended sample sheet object for plexed paired run';
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); } 'extended sample sheet object for plexed paired run';
ok(!$ss->_dual_index, 'no dual index');
lives_ok { $ss->process(); } ' sample sheet generated';
is_string($result, read_file('t/data/samplesheet/6946_extended.csv'));
Expand All @@ -276,7 +316,7 @@ subtest 'extended samplesheets' => sub {
$schema->resultset('Run')->find(6946)->update({batch_id => 4775});

$result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); }
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); }
'extended sample sheet object for unplexed paired 8 lane run with a control lane';
lives_ok { $ss->process(); } 'sample sheet generated';
is_string($result, read_file('t/data/samplesheet/1control7libs_extended.csv'));
Expand All @@ -286,7 +326,7 @@ subtest 'extended samplesheets' => sub {
$schema->resultset('Run')->find(6946)->update({batch_id => 16249});

$result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); }
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); }
'extended sample sheet object for plexed paired 8 lane run';
ok(!$ss->_dual_index, 'no dual index');
lives_ok { $ss->process(); } 'sample sheet generated';
Expand All @@ -297,7 +337,7 @@ subtest 'extended samplesheets' => sub {
$schema->resultset('Run')->find(6946)->update({batch_id => 23798});

$result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); }
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); }
'extended sample sheet object for plexed paired run with both pool and library lanes';
ok($ss->_dual_index, 'dual index from a 16 char first index');
lives_ok { $ss->process(); } 'sample sheet generated';
Expand All @@ -307,7 +347,7 @@ subtest 'extended samplesheets' => sub {
$schema->resultset('Run')->find(6946)->update({batch_id => 1,});

$result = q();
lives_ok { $ss = npg::samplesheet->new(repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); }
lives_ok { $ss = npg::samplesheet->new(lims_driver_type=>'xml', repository=>$dir, npg_tracking_schema=>$schema, id_run=>6946, extend => 1, output=>\$result); }
'extended sample sheet object for plexed paired run with both pool and library lanes';
ok($ss->_dual_index, 'dual index from two indexes in LIMs');
lives_ok { $ss->process(); } 'sample sheet generated';
Expand Down