From b1cddef257d729c1c40786b1fc199cab21ae349e Mon Sep 17 00:00:00 2001 From: "David K. Jackson" Date: Thu, 22 Jun 2023 09:39:17 +0100 Subject: [PATCH 01/18] Rejig run folder tracking function into method --- bin/staging_area_monitor | 148 +-------------------- lib/Monitor/RunFolder/Staging.pm | 147 ++++++++++++++++++++ lib/npg_tracking/illumina/run/long_info.pm | 3 +- 3 files changed, 152 insertions(+), 146 deletions(-) diff --git a/bin/staging_area_monitor b/bin/staging_area_monitor index 635448c3..1ed21c40 100755 --- a/bin/staging_area_monitor +++ b/bin/staging_area_monitor @@ -19,9 +19,6 @@ our $VERSION = '0'; Readonly::Scalar my $SLEEP_INTERVAL => 60 * 15; Readonly::Scalar my $DRY_RUN => $ENV{'dev'} && ($ENV{'dev'} ne 'live'); -Readonly::Array my @UPDATES_FOR_INCOMING_ALLOWED_STATUSES => - ('run pending', 'run in progress', 'run complete'); -Readonly::Scalar my $USERNAME => 'pipeline'; local $OUTPUT_AUTOFLUSH = 1; @@ -39,147 +36,6 @@ _log_noindent($DRY_RUN ? 'DRY RUN, no run folder moves' : 'LIVE RUN'); main(); -sub check_path { ##### Function to deal with one run folder - my ($run_path, $schema, $previous_size_of) = @_; - - my $folder = Monitor::RunFolder::Staging->new( - runfolder_path => $run_path, - npg_tracking_schema => $schema); - $run_path = $folder->runfolder_path; # in case path was transformed - - my $run_status = $folder->tracking_run()->current_run_status_description(); - my $id_run = $folder->tracking_run()->id_run; - - _log("Run $id_run status $run_status"); - if ($folder->platform_NovaSeqX()) { - _log("... run on NovaSeqX instrument"); - } - - my $db_flowcell_barcode = $folder->tracking_run()->flowcell_id; - my $staging_flowcell_barcode = $folder->run_flowcell; # from RunParameters.xml - $staging_flowcell_barcode ||= q[]; - if ($db_flowcell_barcode) { # database flowcell barcode validation - if ($db_flowcell_barcode ne $staging_flowcell_barcode) { - croak 'Flowcell barcode mismatch between database and staging: ' . - join q[ ], $db_flowcell_barcode, $staging_flowcell_barcode; - } - } else { # save flowcell barcode to the tracking database - $staging_flowcell_barcode or croak - "Staging flowcell barcode is not defined for run $id_run"; - _log("Saving staging flowcell barcode $staging_flowcell_barcode to the database."); - $folder->tracking_run()->update({flowcell_id => $staging_flowcell_barcode}); - } - - if ($folder->is_in_analysis) { - _log('Folder is in /analysis/'); - - if( $run_status eq 'qc complete') { - _log('Moving run folder to /outgoing/'); - (not $DRY_RUN) and _log($folder->move_to_outgoing()); - } - return; # Nothing else to do for a folder in /analysis/ - } - - _log('Folder is in /incoming/'); - - # If we don't remember seeing it before, set the folder name and glob; - # set staging tag, if appropriate, set/fix instrument side, workflow side. - # Previously we avoided making changes to the db if status was at or after - # 'run complete'. We might consider reinstating this rule. - if ( not defined $previous_size_of->{$run_path} ) { - $folder->update_run_record(); - $folder->tracking_run()->set_tag( $USERNAME, 'staging' ); - _log('Set staging tag'); - try { - my $iside = $folder->set_instrument_side(); - if ($iside) { - _log("Instrument side is set to $iside"); - } - my $wf_type = $folder->set_workflow_type(); - if ($wf_type) { - _log("Workflow type is set to $wf_type"); - } - $folder->set_run_tags(); - } catch { - _log('Error: ' . $_); - }; - - $previous_size_of->{$run_path} = 0; - } - - # Could delete the directory here. Leave it for now. - return if $run_status eq 'data discarded'; - - if (any { $run_status eq $_ } @UPDATES_FOR_INCOMING_ALLOWED_STATUSES) { - - my $latest_cycle = $folder->get_latest_cycle(); - if ($folder->update_cycle_count($latest_cycle)) { - _log("Cycle count updated to $latest_cycle"); - } - - if ( $run_status eq 'run pending' ) { - - if ($latest_cycle) { - $folder->update_run_status('run in progress'); - _log(q[Run status updated to 'run in progress']); - } - - } elsif ( $run_status eq 'run in progress' ) { - - # The lane count comes from the run folder structure, which - # we should have by now set up. - $folder->delete_superfluous_lanes(); - if ($folder->is_run_complete()) { - $folder->update_run_status('run complete'); - _log(q[Run status updated to 'run complete']); - } - - } else { # run status is 'run complete' - - $folder->update_run_record(); # Inspect and update cycles, - # including expected cycle count! - - if ( $folder->check_tiles($run_path) ) { - - my $previous_size = $previous_size_of->{$run_path}; - my ( $current_size, $latest_mod ) = $folder->monitor_stats(); - _log(sprintf 'Run folder sizes: previous %i, current %i', - $previous_size, $current_size); - $previous_size_of->{$run_path} = $current_size; - - if ( $current_size != $previous_size ) { - _log('Runfolder size is still changing.'); - return; - } - - # Check that no file is 'in the future'. - if ( $latest_mod > time ) { - _log("Files in 'future' $latest_mod are present."); - return; - } - - # Check if we are waiting for the onboard analysis to finish. - if ($folder->is_onboard_analysis_planned() && - !$folder->has_onboard_analysis_finished()) { - return; - } - - # Set status to 'run mirrored' and move run folder - # from /incoming/ to /analysis/ - $folder->update_run_status('run mirrored'); - _log(q[Run status updated to 'run mirrored']); - _log('Moving run folder to analysis'); - (not $DRY_RUN) and _log($folder->move_to_analysis()); - - return 'done'; - } - } - } - - return; - -} ###### End of function to deal with one run folder - ########################################################### ############### Main daemon loop. ###################### ########################################################### @@ -204,7 +60,9 @@ sub main { _log_noindent("Considering $run_path"); my $done; try { - $done = check_path($run_path, $schema, $previous_size_of); + $done = Monitor::RunFolder::Staging->new( + runfolder_path => $run_path, + npg_tracking_schema => $schema)->update_run_from_path($previous_size_of, $DRY_RUN); } finally { if (@_) { _log("ERROR: Execution for $run_path died with: @_\n"); diff --git a/lib/Monitor/RunFolder/Staging.pm b/lib/Monitor/RunFolder/Staging.pm index 1ca23d7c..a749739b 100644 --- a/lib/Monitor/RunFolder/Staging.pm +++ b/lib/Monitor/RunFolder/Staging.pm @@ -34,6 +34,10 @@ Readonly::Scalar my $ONBOARD_ANALYSIS_COMPLETE_FN => q[Secondary_Analysis_Complete.txt]; Readonly::Scalar my $ONBOARD_ANALYSIS_SAMPLESHEET_FN => q[SampleSheet.csv]; +Readonly::Array my @UPDATES_FOR_INCOMING_ALLOWED_STATUSES => + ('run pending', 'run in progress', 'run complete'); +Readonly::Scalar my $USERNAME => 'pipeline'; + has 'status_update' => (isa => 'Bool', is => 'ro', default => 1, @@ -343,6 +347,149 @@ sub _set_sgid { return; } +sub _log { + my @ms = map { "\t$_\n" } @_; + print {*STDOUT} @ms or carp $OS_ERROR; +} + + +sub update_run_from_path { ##### Method to deal with one run folder + my ($folder, $hash_previous_size_of,$DRY_RUN) = @_; # folder is like "self" - code converted from function "check_path" + my $schema = $folder->npg_tracking_schema(); + my $run_path = $folder->runfolder_path; # in case path was transformed + + my $run_status = $folder->tracking_run()->current_run_status_description(); + my $id_run = $folder->tracking_run()->id_run; + + _log("Run $id_run status $run_status"); + if ($folder->platform_NovaSeqX()) { + _log("... run on NovaSeqX instrument"); + } + + my $db_flowcell_barcode = $folder->tracking_run()->flowcell_id; + my $staging_flowcell_barcode = $folder->run_flowcell; # from RunParameters.xml + $staging_flowcell_barcode ||= q[]; + if ($db_flowcell_barcode) { # database flowcell barcode validation + if ($db_flowcell_barcode ne $staging_flowcell_barcode) { + croak 'Flowcell barcode mismatch between database and staging: ' . + join q[ ], $db_flowcell_barcode, $staging_flowcell_barcode; + } + } else { # save flowcell barcode to the tracking database + $staging_flowcell_barcode or croak + "Staging flowcell barcode is not defined for run $id_run"; + _log("Saving staging flowcell barcode $staging_flowcell_barcode to the database."); + $folder->tracking_run()->update({flowcell_id => $staging_flowcell_barcode}); + } + + if ($folder->is_in_analysis) { + _log('Folder is in /analysis/'); + + if( $run_status eq 'qc complete') { + _log('Moving run folder to /outgoing/'); + (not $DRY_RUN) and _log($folder->move_to_outgoing()); + } + return; # Nothing else to do for a folder in /analysis/ + } + + _log('Folder is in /incoming/'); + + # If we don't remember seeing it before, set the folder name and glob; + # set staging tag, if appropriate, set/fix instrument side, workflow side. + # Previously we avoided making changes to the db if status was at or after + # 'run complete'. We might consider reinstating this rule. + if ( not defined $hash_previous_size_of->{$run_path} ) { + $folder->update_run_record(); + $folder->tracking_run()->set_tag( $USERNAME, 'staging' ); + _log('Set staging tag'); + try { + my $iside = $folder->set_instrument_side(); + if ($iside) { + _log("Instrument side is set to $iside"); + } + my $wf_type = $folder->set_workflow_type(); + if ($wf_type) { + _log("Workflow type is set to $wf_type"); + } + $folder->set_run_tags(); + } catch { + _log('Error: ' . $_); + }; + + $hash_previous_size_of->{$run_path} = 0; + } + + # Could delete the directory here. Leave it for now. + return if $run_status eq 'data discarded'; + + if (any { $run_status eq $_ } @UPDATES_FOR_INCOMING_ALLOWED_STATUSES) { + + my $latest_cycle = $folder->get_latest_cycle(); + if ($folder->update_cycle_count($latest_cycle)) { + _log("Cycle count updated to $latest_cycle"); + } + + if ( $run_status eq 'run pending' ) { + + if ($latest_cycle) { + $folder->update_run_status('run in progress'); + _log(q[Run status updated to 'run in progress']); + } + + } elsif ( $run_status eq 'run in progress' ) { + + # The lane count comes from the run folder structure, which + # we should have by now set up. + $folder->delete_superfluous_lanes(); + if ($folder->is_run_complete()) { + $folder->update_run_status('run complete'); + _log(q[Run status updated to 'run complete']); + } + + } else { # run status is 'run complete' + + $folder->update_run_record(); # Inspect and update cycles, + # including expected cycle count! + + if ( $folder->check_tiles($run_path) ) { + + my $previous_size = $hash_previous_size_of->{$run_path}; + my ( $current_size, $latest_mod ) = $folder->monitor_stats(); + _log(sprintf 'Run folder sizes: previous %i, current %i', + $previous_size, $current_size); + $hash_previous_size_of->{$run_path} = $current_size; + + if ( $current_size != $previous_size ) { + _log('Runfolder size is still changing.'); + return; + } + + # Check that no file is 'in the future'. + if ( $latest_mod > time ) { + _log("Files in 'future' $latest_mod are present."); + return; + } + + # Check if we are waiting for the onboard analysis to finish. + if ($folder->is_onboard_analysis_planned() && + !$folder->has_onboard_analysis_finished()) { + return; + } + + # Set status to 'run mirrored' and move run folder + # from /incoming/ to /analysis/ + $folder->update_run_status('run mirrored'); + _log(q[Run status updated to 'run mirrored']); + _log('Moving run folder to analysis'); + (not $DRY_RUN) and _log($folder->move_to_analysis()); + + return 'done'; + } + } + } + + return; + +} ###### End of function to deal with one run folder no Moose; __PACKAGE__->meta->make_immutable(); diff --git a/lib/npg_tracking/illumina/run/long_info.pm b/lib/npg_tracking/illumina/run/long_info.pm index a041669b..65e5eef0 100644 --- a/lib/npg_tracking/illumina/run/long_info.pm +++ b/lib/npg_tracking/illumina/run/long_info.pm @@ -986,7 +986,8 @@ sub _get_xml_document { croak 'Directory path required'; } - my @files = grep { m/\/$reg_expr\Z/xms } io($dir)->all; + my @files = grep { m/\/$reg_expr\Z/xms } io("$dir/")->all; + # "/" suffix of $dir/ to cope with a symlink for a run folder if (@files < 1) { croak qq{File not found for $reg_expr in $dir}; } From 10c5a043e412d8cc2dbf82570805766cc75c3aa9 Mon Sep 17 00:00:00 2001 From: "David K. Jackson" Date: Fri, 23 Jun 2023 09:19:04 +0100 Subject: [PATCH 02/18] change $DRY_RUN to $inhibit_folder_move for update_run_from_path() --- lib/Monitor/RunFolder/Staging.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Monitor/RunFolder/Staging.pm b/lib/Monitor/RunFolder/Staging.pm index a749739b..b9cb175e 100644 --- a/lib/Monitor/RunFolder/Staging.pm +++ b/lib/Monitor/RunFolder/Staging.pm @@ -354,7 +354,7 @@ sub _log { sub update_run_from_path { ##### Method to deal with one run folder - my ($folder, $hash_previous_size_of,$DRY_RUN) = @_; # folder is like "self" - code converted from function "check_path" + my ($folder, $hash_previous_size_of,$inhibit_folder_move) = @_; # folder is like "self" - code converted from function "check_path" my $schema = $folder->npg_tracking_schema(); my $run_path = $folder->runfolder_path; # in case path was transformed @@ -386,7 +386,7 @@ sub update_run_from_path { ##### Method to deal with one run folder if( $run_status eq 'qc complete') { _log('Moving run folder to /outgoing/'); - (not $DRY_RUN) and _log($folder->move_to_outgoing()); + (not $inhibit_folder_move) and _log($folder->move_to_outgoing()); } return; # Nothing else to do for a folder in /analysis/ } @@ -480,7 +480,7 @@ sub update_run_from_path { ##### Method to deal with one run folder $folder->update_run_status('run mirrored'); _log(q[Run status updated to 'run mirrored']); _log('Moving run folder to analysis'); - (not $DRY_RUN) and _log($folder->move_to_analysis()); + (not $inhibit_folder_move) and _log($folder->move_to_analysis()); return 'done'; } From 8b2fe8b74cd5e0cac4ebf6f50f45d34099c58b8f Mon Sep 17 00:00:00 2001 From: "David K. Jackson" Date: Fri, 23 Jun 2023 09:32:40 +0100 Subject: [PATCH 03/18] doc for update_run_from_path() --- lib/Monitor/RunFolder/Staging.pm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/Monitor/RunFolder/Staging.pm b/lib/Monitor/RunFolder/Staging.pm index b9cb175e..f2097cc1 100644 --- a/lib/Monitor/RunFolder/Staging.pm +++ b/lib/Monitor/RunFolder/Staging.pm @@ -567,6 +567,18 @@ false for other instrument types. Returns true if the file that inticates that the onboard analysis has finished is present in the run folder. +=head2 update_run_from_path + + C<<$folder->update_run_from_path($hash_ref_runfolder_size_state_store, + $inhibit_folder_move);>> + +Uses information found in the runfolder, dependent on its location, to update +the tracking database. Your'll need to trace the code for the exact logic... +It will also move the run folder until the flag to inhibit this is passed. +It takes a hash ref contain the (size) state of run folders - this is (in some +logical paths) used to help determine whether certain processes have +completed. + =head1 CONFIGURATION AND ENVIRONMENT =head1 DEPENDENCIES From a8cdea35364b93e1bd626b42290348258fdddaf2 Mon Sep 17 00:00:00 2001 From: Marina Gourtovaia Date: Sat, 9 Jan 2021 00:14:29 +0000 Subject: [PATCH 04/18] samplesheet generator for MiSeq --- bin/npg_samplesheet4MiSeq | 96 +++++++ lib/npg_tracking/daemon/samplesheet/auto.pm | 267 ++++++++++++++++++++ t/30-npg_tracking-daemon-samplesheet-auto.t | 52 ++++ 3 files changed, 415 insertions(+) create mode 100755 bin/npg_samplesheet4MiSeq create mode 100644 lib/npg_tracking/daemon/samplesheet/auto.pm create mode 100644 t/30-npg_tracking-daemon-samplesheet-auto.t diff --git a/bin/npg_samplesheet4MiSeq b/bin/npg_samplesheet4MiSeq new file mode 100755 index 00000000..fee2db35 --- /dev/null +++ b/bin/npg_samplesheet4MiSeq @@ -0,0 +1,96 @@ +#!/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(:easy); + +use npg_tracking::daemon::samplesheet::auto; + +our $VERSION = '0'; + +Log::Log4perl->easy_init($INFO); + +my $log = Log::Log4perl->get_logger('main'); +$log->info('Starting npg samplesheet'); + +npg_tracking::daemon::samplesheet::auto->new()->loop(); + +0; + +__END__ + +=head1 NAME + +npg_samplesheet4MiSeq + +=head1 USAGE + + npg_samplesheet4MiSeq + +=head1 DESCRIPTION + +The script, once started, runs in perpetuity, generating Illumina-style +samplesheets for any MiSeq run with status 'run pending'. + +=head1 REQUIRED ARGUMENTS + +None + +=head1 OPTIONS + +=head1 DIAGNOSTICS + +=head1 CONFIGURATION + +=head1 DEPENDENCIES + +=over + +=item strict + +=item warnings + +=item FindBin + +=item lib + +=item Log::Log4perl + +=item npg_tracking::daemon::samplesheet::auto + +=back + +=head1 EXIT STATUS + + Does not exit unless is sent a signal to terminate. + +=head1 INCOMPATIBILITIES + +=head1 BUGS AND LIMITATIONS + +=head1 AUTHOR + +Jaime Tovar Ejmtc@sanger.ac.ukE + +=head1 LICENSE AND COPYRIGHT + +Copyright (C) 2020,2021 GRL. + +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 . + +=cut diff --git a/lib/npg_tracking/daemon/samplesheet/auto.pm b/lib/npg_tracking/daemon/samplesheet/auto.pm new file mode 100644 index 00000000..915303fb --- /dev/null +++ b/lib/npg_tracking/daemon/samplesheet/auto.pm @@ -0,0 +1,267 @@ +package npg_tracking::daemon::samplesheet::auto; + +use Moose; +use namespace::autoclean; +use Try::Tiny; +use File::Basename; +use Readonly; +use File::Copy; +use File::Spec::Functions; + +use npg::samplesheet; +use npg_tracking::Schema; +use WTSI::DNAP::Warehouse::Schema; +use st::api::lims; +use st::api::lims::samplesheet; + +with q(MooseX::Log::Log4perl); + +our $VERSION = '0'; + +Readonly::Scalar my $DEFAULT_SLEEP => 90; + +=head1 NAME + +npg_tracking::daemon::samplesheet::auto + +=head1 VERSION + +=head1 SYNOPSIS + + use npg_tracking::daemon::samplesheet::auto; + use Log::Log4perl qw(:easy); + BEGIN{ Log::Log4perl->easy_init({level=>$INFO,}); } + npg_tracking::daemon::samplesheet::auto->new()->loop(); + +=head1 DESCRIPTION + +Class for creating Illumina MiSeq samplesheets automatically +for runs which are pending. + +=head1 SUBROUTINES/METHODS + +=head2 npg_tracking_schema + +=cut + +has 'npg_tracking_schema' => ( + 'isa' => 'npg_tracking::Schema', + 'is' => 'ro', + 'lazy_build' => 1, +); +sub _build_npg_tracking_schema { + return npg_tracking::Schema->connect(); +} + +=head2 mlwh_schema + +=cut + +has 'mlwh_schema' => ( + 'isa' => 'WTSI::DNAP::Warehouse::Schema', + 'is' => 'ro', + 'lazy_build' => 1, +); +sub _build_mlwh_schema { + return WTSI::DNAP::Warehouse::Schema->connect(); +} + +=head2 sleep_interval + +=cut + +has 'sleep_interval' => ( + 'is' => 'ro', + 'isa' => 'Int', + 'default' => $DEFAULT_SLEEP, +); + +=head2 loop + +Repeat the process step with the intervening sleep interval. + +=cut + +sub loop { + my $self = shift; + while(1) { $self->process(); sleep $self->sleep_interval;} + return; +}; + +=head2 process + +Find all pending MiSeq runs and create an Illumina samplesheet for each +of them if one does not already exist. + +=cut + +sub process { + my $self = shift; + my $rt = $self->_pending->run_statuses->search({iscurrent=>1}) + ->related_resultset(q(run)); + my $rs = $rt->search( + {q(run.id_instrument_format) => $self->_miseq->id_instrument_format}); + $self->log->debug( $rs->count. q[ ] .($self->_miseq->model). + q[ runs marked as ] .($self->_pending->description)); + while(my$r=$rs->next){ + my $id_run = $r->id_run; + $self->log->info('Considering ' . join q[,],$id_run,$r->instrument->name); + + my $l = st::api::lims->new( + position => 1, + id_run => $id_run, + id_flowcell_lims => $r->batch_id, + driver_type => q(ml_warehouse), + mlwh_schema => $self->mlwh_schema + ); + + my $ss = npg::samplesheet->new(run => $r, lims => [$l]); + + my$o=$ss->output; + my $generate_new = 1; + + if(-e $o) { + my $other_id_run = _id_run_from_samplesheet($o); + if ($other_id_run && $other_id_run == $id_run) { + $self->log->info(qq($o already exists for $id_run)); + $generate_new = 0; + } else { + $self->log->info(qq(Will move existing $o)); + _move_samplesheet($o); + } + } + + if ($generate_new) { + try { + $ss->process; + $self->log->info(qq($o created for run ).($r->id_run)); + } catch { + $self->log->error(qq(Trying to create $o for run ).($r->id_run). + qq( experienced error: $_)); + } + } + } + return; +} + +has '_miseq' => ( + 'is' => 'ro', + 'lazy_build' => 1, +); +sub _build__miseq { + my $self=shift; + return $self->npg_tracking_schema->resultset(q(InstrumentFormat)) + ->find({q(model)=>q(MiSeq)}); +} + +has '_pending' => ( + 'is' => 'ro', + 'lazy_build' => 1, +); +sub _build__pending { + my $self=shift; + return $self->npg_tracking_schema->resultset(q(RunStatusDict)) + ->find({q(description)=>q(run pending)}); +} + +sub _id_run_from_samplesheet { + my $file_path = shift; + my $id_run; + try { + my $sh = st::api::lims::samplesheet->new(path => $file_path); + $sh->data; # force to parse the file + if ($sh->id_run) { + $id_run = int $sh->id_run; + } + }; + return $id_run; +} + +sub _move_samplesheet { + my $file_path = shift; + + my($filename, $dirname) = fileparse($file_path); + $dirname =~ s/\/$//smx; #drop last forward slash if any + my $dirname_dest = $dirname . '_old'; + my $filename_dest = $filename . '_invalid'; + my $moved; + if (-d $dirname_dest) { + $moved = move($file_path, catdir($dirname_dest, $filename_dest)); + } + if (!$moved) { + move($file_path, catdir($dirname, $filename_dest)); + } + return; +} + +__PACKAGE__->meta->make_immutable; + +1; + +__END__ + +=head1 DIAGNOSTICS + +=head1 CONFIGURATION AND ENVIRONMENT + +=head1 DEPENDENCIES + +=over + +=item File::Basename + +=item File::Copy + +=item Moose + +=item namespace::autoclean + +=item MooseX::Log::Log4perl + +=item Readonly + +=item File::Spec::Functions + +=item Try::Tiny + +=item npg_tracking::Schema + +=item npg::samplesheet + +=item st:api::lims + +=item st::api::lims::samplesheet + +=item WTSI::DNAP::Warehouse::Schema + +=back + +=head1 INCOMPATIBILITIES + +=head1 BUGS AND LIMITATIONS + +=head1 AUTHOR + +David K. Jackson Edavid.jackson@sanger.ac.ukE + +=head1 LICENSE AND COPYRIGHT + +Copyright (C) 2012,2013,2014,2019,2021 GRL. + +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 . + +=cut + diff --git a/t/30-npg_tracking-daemon-samplesheet-auto.t b/t/30-npg_tracking-daemon-samplesheet-auto.t new file mode 100644 index 00000000..6bd07c06 --- /dev/null +++ b/t/30-npg_tracking-daemon-samplesheet-auto.t @@ -0,0 +1,52 @@ +use strict; +use warnings; +use Test::More tests => 9; +use Test::Exception; +use File::Temp qw/ tempdir /; +use Moose::Meta::Class; + +use_ok('npg_tracking::daemon::samplesheet::auto'); + +my $util = Moose::Meta::Class->create_anon_class( + roles => [qw/npg_testing::db/])->new_object({}); +my $schema_wh = $util->create_test_db(q[WTSI::DNAP::Warehouse::Schema], + q[t/data/fixtures/wh]); +my $schema = $util->create_test_db(q[npg_tracking::Schema], + q[t/data/fixtures/npg]); + +{ + my $sm; + lives_ok { $sm = npg_tracking::daemon::samplesheet::auto->new( + npg_tracking_schema => $schema, + mlwh_schema => $schema_wh) } 'miseq monitor object'; + isa_ok($sm, 'npg_tracking::daemon::samplesheet::auto'); +} + +{ + is(npg_tracking::daemon::samplesheet::auto::_id_run_from_samplesheet( + 't/data/samplesheet/miseq_default.csv'), 10262, + 'id run retrieved from a samplesheet'); + lives_and { is npg_tracking::daemon::samplesheet::auto::_id_run_from_samplesheet('some_file'), undef} + 'undef reftuned for a non-exisitng samplesheet'; +} + +{ + my $dir = tempdir(UNLINK => 1); + my $file = join q[/], $dir, 'myfile'; + `touch $file`; + npg_tracking::daemon::samplesheet::auto::_move_samplesheet($file); + ok(!-e $file, 'original file does not exist'); + ok(-e $file.'_invalid', 'file has been moved'); + + my $sdir = join q[/], $dir, 'samplesheet'; + mkdir $sdir; + mkdir $sdir . '_old'; + $file = join q[/], $sdir, 'myfile'; + `touch $file`; + my $new_file = join q[/], $sdir . '_old', 'myfile_invalid'; + npg_tracking::daemon::samplesheet::auto::_move_samplesheet($file); + ok(!-e $file, 'original file does not exist'); + ok(-e $new_file, 'moved file is in samplesheet_old directory'); +} + +1; From dc89b2b910b7edadaac88c9a084b2ad1b6028011 Mon Sep 17 00:00:00 2001 From: Marina Gourtovaia Date: Thu, 8 Jun 2023 14:31:38 +0100 Subject: [PATCH 05/18] Renamed imported samplesheet daemon class --- MANIFEST | 3 +++ bin/npg_samplesheet4MiSeq | 8 ++++---- .../daemon => npg}/samplesheet/auto.pm | 10 +++++----- ...sheet-auto.t => 47-npg_samplesheet_auto.t} | 20 +++++++++---------- 4 files changed, 21 insertions(+), 20 deletions(-) rename lib/{npg_tracking/daemon => npg}/samplesheet/auto.pm (95%) rename t/{30-npg_tracking-daemon-samplesheet-auto.t => 47-npg_samplesheet_auto.t} (61%) diff --git a/MANIFEST b/MANIFEST index 75dd884c..7ec082d7 100644 --- a/MANIFEST +++ b/MANIFEST @@ -3,6 +3,7 @@ bin/event_notifications bin/illumina_instruments_uptime bin/npg_daemon_control bin/npg_move_runfolder +bin/npg_samplesheet4MiSeq bin/npg_status_save bin/staging_area_monitor bin/npg_deletable_dr_runs @@ -164,6 +165,7 @@ lib/npg_tracking/report/event2subscribers.pm lib/npg_tracking/report/events.pm lib/npg/samplesheet.pm lib/npg/samplesheet/novaseq_xseries.pm +lib/npg/samplesheet/auto.pm lib/npg/util.pm lib/npg/util/mailer.pm lib/npg/view.pm @@ -417,6 +419,7 @@ t/40-st-study.t t/45-st-api-lims-traversal.t t/47-samplesheet.t t/47-npg_samplesheet_novaseq_xseries.t +t/47-npg_samplesheet_auto.t t/50-controller.t t/50-decorator.t t/60-illumina-runfolder.t diff --git a/bin/npg_samplesheet4MiSeq b/bin/npg_samplesheet4MiSeq index fee2db35..c97cc99f 100755 --- a/bin/npg_samplesheet4MiSeq +++ b/bin/npg_samplesheet4MiSeq @@ -6,7 +6,7 @@ use FindBin qw($Bin); use lib ( -d "$Bin/../lib/perl5" ? "$Bin/../lib/perl5" : "$Bin/../lib" ); use Log::Log4perl qw(:easy); -use npg_tracking::daemon::samplesheet::auto; +use npg::samplesheet::auto; our $VERSION = '0'; @@ -15,7 +15,7 @@ Log::Log4perl->easy_init($INFO); my $log = Log::Log4perl->get_logger('main'); $log->info('Starting npg samplesheet'); -npg_tracking::daemon::samplesheet::auto->new()->loop(); +npg::samplesheet::auto->new()->loop(); 0; @@ -58,7 +58,7 @@ None =item Log::Log4perl -=item npg_tracking::daemon::samplesheet::auto +=item npg::samplesheet::auto =back @@ -76,7 +76,7 @@ Jaime Tovar Ejmtc@sanger.ac.ukE =head1 LICENSE AND COPYRIGHT -Copyright (C) 2020,2021 GRL. +Copyright (C) 2020,2021,2023 GRL. This file is part of NPG. diff --git a/lib/npg_tracking/daemon/samplesheet/auto.pm b/lib/npg/samplesheet/auto.pm similarity index 95% rename from lib/npg_tracking/daemon/samplesheet/auto.pm rename to lib/npg/samplesheet/auto.pm index 915303fb..3a4b479d 100644 --- a/lib/npg_tracking/daemon/samplesheet/auto.pm +++ b/lib/npg/samplesheet/auto.pm @@ -1,4 +1,4 @@ -package npg_tracking::daemon::samplesheet::auto; +package npg::samplesheet::auto; use Moose; use namespace::autoclean; @@ -22,16 +22,16 @@ Readonly::Scalar my $DEFAULT_SLEEP => 90; =head1 NAME -npg_tracking::daemon::samplesheet::auto +npg::samplesheet::auto =head1 VERSION =head1 SYNOPSIS - use npg_tracking::daemon::samplesheet::auto; + use npg::samplesheet::auto; use Log::Log4perl qw(:easy); BEGIN{ Log::Log4perl->easy_init({level=>$INFO,}); } - npg_tracking::daemon::samplesheet::auto->new()->loop(); + npg::samplesheet::auto->new()->loop(); =head1 DESCRIPTION @@ -246,7 +246,7 @@ David K. Jackson Edavid.jackson@sanger.ac.ukE =head1 LICENSE AND COPYRIGHT -Copyright (C) 2012,2013,2014,2019,2021 GRL. +Copyright (C) 2012,2013,2014,2019,2021,2023 GRL. This file is part of NPG. diff --git a/t/30-npg_tracking-daemon-samplesheet-auto.t b/t/47-npg_samplesheet_auto.t similarity index 61% rename from t/30-npg_tracking-daemon-samplesheet-auto.t rename to t/47-npg_samplesheet_auto.t index 6bd07c06..3e0c5e70 100644 --- a/t/30-npg_tracking-daemon-samplesheet-auto.t +++ b/t/47-npg_samplesheet_auto.t @@ -5,28 +5,26 @@ use Test::Exception; use File::Temp qw/ tempdir /; use Moose::Meta::Class; -use_ok('npg_tracking::daemon::samplesheet::auto'); +use_ok('npg::samplesheet::auto'); my $util = Moose::Meta::Class->create_anon_class( roles => [qw/npg_testing::db/])->new_object({}); -my $schema_wh = $util->create_test_db(q[WTSI::DNAP::Warehouse::Schema], - q[t/data/fixtures/wh]); -my $schema = $util->create_test_db(q[npg_tracking::Schema], - q[t/data/fixtures/npg]); +my $schema_wh = $util->create_test_db(q[WTSI::DNAP::Warehouse::Schema]); +my $schema = $util->create_test_db(q[npg_tracking::Schema]); { my $sm; - lives_ok { $sm = npg_tracking::daemon::samplesheet::auto->new( + lives_ok { $sm = npg::samplesheet::auto->new( npg_tracking_schema => $schema, mlwh_schema => $schema_wh) } 'miseq monitor object'; - isa_ok($sm, 'npg_tracking::daemon::samplesheet::auto'); + isa_ok($sm, 'npg::samplesheet::auto'); } { - is(npg_tracking::daemon::samplesheet::auto::_id_run_from_samplesheet( + is(npg::samplesheet::auto::_id_run_from_samplesheet( 't/data/samplesheet/miseq_default.csv'), 10262, 'id run retrieved from a samplesheet'); - lives_and { is npg_tracking::daemon::samplesheet::auto::_id_run_from_samplesheet('some_file'), undef} + lives_and { is npg::samplesheet::auto::_id_run_from_samplesheet('some_file'), undef} 'undef reftuned for a non-exisitng samplesheet'; } @@ -34,7 +32,7 @@ my $schema = $util->create_test_db(q[npg_tracking::Schema], my $dir = tempdir(UNLINK => 1); my $file = join q[/], $dir, 'myfile'; `touch $file`; - npg_tracking::daemon::samplesheet::auto::_move_samplesheet($file); + npg::samplesheet::auto::_move_samplesheet($file); ok(!-e $file, 'original file does not exist'); ok(-e $file.'_invalid', 'file has been moved'); @@ -44,7 +42,7 @@ my $schema = $util->create_test_db(q[npg_tracking::Schema], $file = join q[/], $sdir, 'myfile'; `touch $file`; my $new_file = join q[/], $sdir . '_old', 'myfile_invalid'; - npg_tracking::daemon::samplesheet::auto::_move_samplesheet($file); + npg::samplesheet::auto::_move_samplesheet($file); ok(!-e $file, 'original file does not exist'); ok(-e $new_file, 'moved file is in samplesheet_old directory'); } From 2b6ece337df700ad007cdce64c3a053e2ba13641 Mon Sep 17 00:00:00 2001 From: Marina Gourtovaia Date: Mon, 3 Jul 2023 15:28:39 +0100 Subject: [PATCH 06/18] Fixed a regression in npg_move_runfolder. MooseX::Getopt is no longer used by the underlying class, therefore the arguments have to be processed explicitly. With this change a better control of input arguments is achieved. Documentation is updated and extended. --- bin/npg_move_runfolder | 61 +++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/bin/npg_move_runfolder b/bin/npg_move_runfolder index 8314ea73..f43d5d69 100755 --- a/bin/npg_move_runfolder +++ b/bin/npg_move_runfolder @@ -1,26 +1,36 @@ #!/usr/bin/env perl -######### -# Author: js10 -# Created: 2018-05-30 -# use strict; use warnings; - use FindBin qw($Bin); use lib ( -d "$Bin/../lib/perl5" ? "$Bin/../lib/perl5" : "$Bin/../lib" ); -use Carp; -use autodie qw(:all); +use Getopt::Long; +use Pod::Usage; -use Monitor::Staging; use Monitor::RunFolder::Staging; our $VERSION = '0'; -use Readonly; +my $help; +my $runfolder_path; +my $status_update = 0; + +GetOptions ( + 'help' => \$help, + 'runfolder_path=s' => \$runfolder_path, + 'status_update!' => \$status_update, +); +if ($help) { pod2usage(0); } + +if (!defined $runfolder_path || $runfolder_path == q[]) { + die "ERROR: --runfolder_path argument is required\n"; +} + +my @ms = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + status_update => $status_update +)->move_to_analysis(); -my $mon = Monitor::RunFolder::Staging->new_with_options(status_update => 0); -my @ms = $mon->move_to_analysis(); print join "\n", @ms; 1; @@ -30,23 +40,38 @@ __END__ =head1 NAME -npg_move_runfolder - move 'incoming' to 'analysis' and change group. +npg_move_runfolder - move the run folder given as an argument from +'incoming' to 'analysis' and change group. =head1 VERSION =head1 SYNOPSIS - C + C =head1 DESCRIPTION -This script moves a given run folder from 'incoming' directory to 'analysis' directory -and changes the group name to that found in the staging configuration. -By default it does not change the run status. +This script moves a given run folder from 'incoming' directory to 'analysis' +directory and changes the group name to that found in the staging +configuration. By default it does not change the run status. + +=head1 REQUIRED ARGUMENTS + + C + +=head1 OPTIONS + + C - displays help message and exists + + C - the path of the run folder, required + + C - a boolean option, defaults to false, meaning that + the run status update is not performed =head1 CONFIGURATION AND ENVIRONMENT -Depends on the presence of the npg tracking system. +If the run status update is performed, write access to the tracking +database is required. =head1 INCOMPATIBILITIES @@ -58,7 +83,7 @@ Jennifer Liddle, Ejs10@sanger.ac.ukE =head1 LICENCE AND COPYRIGHT -Copyright (C) 2018 GRL, by Jennifer Liddle +Copyright (C) 2018, 2023 Genome Research Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by From 8f8b1131d1b6dfa8a389c2e72d9db1fb0c609744 Mon Sep 17 00:00:00 2001 From: Marina Gourtovaia Date: Mon, 3 Jul 2023 16:08:26 +0100 Subject: [PATCH 07/18] Updated the Changes file --- Changes | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changes b/Changes index a46e2ca0..aa2e7b13 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,8 @@ LIST OF CHANGES + - Fixed a regression in the npg_move_runfolder script, + which made it unusable. + release 95.0.0 - Remove singularity recipe and related files - Import mlwh drivers From 15e25488cb02de669fc8d3ddccad5f086b38ec51 Mon Sep 17 00:00:00 2001 From: Marina Gourtovaia Date: Tue, 4 Jul 2023 18:37:51 +0100 Subject: [PATCH 08/18] Stop using XML LIMS data in a test. Use mlwarehouse LIMS driver and data for the transcriptoms test. --- MANIFEST | 3 + t/10-transcriptome.t | 287 ++- .../000-Sample.yml | 1703 +++++++++++++++++ .../fixtures_lims_transcriptome/000-Study.yml | 122 ++ .../100-IseqFlowcell.yml | 1163 +++++++++++ 5 files changed, 3110 insertions(+), 168 deletions(-) create mode 100644 t/data/fixtures_lims_transcriptome/000-Sample.yml create mode 100644 t/data/fixtures_lims_transcriptome/000-Study.yml create mode 100644 t/data/fixtures_lims_transcriptome/100-IseqFlowcell.yml diff --git a/MANIFEST b/MANIFEST index 75dd884c..3b0dd416 100644 --- a/MANIFEST +++ b/MANIFEST @@ -481,6 +481,9 @@ t/data/fixtures/400-run_status.yml t/data/fixtures/400-tag_run.yml t/data/fixtures/400-tag_run_lane.yml t/data/fixtures/500-st_cache.yml +t/data/fixtures_lims_transcriptome/000-Sample.yml +t/data/fixtures_lims_transcriptome/000-Study.yml +t/data/fixtures_lims_transcriptome/100-IseqFlowcell.yml t/data/fixtures_lims_wh/00-IseqRunStatusDict.yml t/data/fixtures_lims_wh/000-Sample.yml t/data/fixtures_lims_wh/000-Study.yml diff --git a/t/10-transcriptome.t b/t/10-transcriptome.t index 896cc5bb..2f47293f 100644 --- a/t/10-transcriptome.t +++ b/t/10-transcriptome.t @@ -6,229 +6,180 @@ use File::Spec::Functions qw(catfile); use Test::Exception; use File::Temp qw/ tempdir /; use File::Path qw/make_path/; -use File::chdir; -use File::Copy; -use Cwd; -use Carp; -use IO::File; +use Moose::Meta::Class; use st::api::lims; -my $repos = 't/data/repos1'; - use_ok('npg_tracking::data::transcriptome'); -{ my $tmp_repos = tempdir( CLEANUP => 1); -local $ENV{NPG_WEBSERVICE_CACHE_DIR} = $tmp_repos; +my $dir = join q[/],$tmp_repos,'transcriptomes'; my %builds = (); - $builds{'Homo_sapiens'} = ['1000Genomes_hs37d5','CGP_GRCh37.NCBI.allchr_MT','GRCh37_53']; - $builds{'Mus_musculus'} = ['GRCm38','NCBIm37','std_unmasked_NCBIm37']; - -my $dir = join q[/],$tmp_repos,'transcriptomes'; +$builds{'Homo_sapiens'} = ['1000Genomes_hs37d5','CGP_GRCh37.NCBI.allchr_MT','GRCh37_53']; +$builds{'Mus_musculus'} = ['GRCm38','NCBIm37','std_unmasked_NCBIm37']; foreach my $spp (keys %builds){ - my $rel_dir1 = join q[/],$dir,$spp,'ensembl_75_transcriptome'; - my $rel_dir2 = join q[/],$dir,$spp,'ensembl_74_transcriptome'; - my $rel_dir3 = join q[/],$dir,$spp,'ensembl_84_transcriptome'; - - foreach my $rel_dir ($rel_dir1,$rel_dir2,$rel_dir3){ - - foreach my $build (@{ $builds{$spp} }){ - my $gtf_dir = join q[/],$rel_dir,$build,'gtf'; - my $rnaseq_dir = join q[/],$rel_dir,$build,'RNA-SeQC'; - my $tophat_dir = join q[/],$rel_dir,$build,'tophat2'; - my $salmon_dir = join q[/],$rel_dir,$build,'salmon'; - my $fasta_dir = join q[/],$rel_dir,$build,'fasta'; - my $globin_dir = join q[/],$rel_dir,$build,'globin'; - my $mt_dir = join q[/],$rel_dir,$build,'mt'; - make_path($gtf_dir, - $rnaseq_dir, - $tophat_dir, - $salmon_dir, - $fasta_dir, - $globin_dir, - $mt_dir, - {verbose => 0}); - } - } - - #symlink_default($dir,$spp,'ensembl_75_transcriptome'); - + my $rel_dir1 = join q[/],$dir,$spp,'ensembl_75_transcriptome'; + my $rel_dir2 = join q[/],$dir,$spp,'ensembl_74_transcriptome'; + my $rel_dir3 = join q[/],$dir,$spp,'ensembl_84_transcriptome'; + + foreach my $rel_dir ($rel_dir1,$rel_dir2,$rel_dir3){ + foreach my $build (@{ $builds{$spp} }){ + my $gtf_dir = join q[/],$rel_dir,$build,'gtf'; + my $rnaseq_dir = join q[/],$rel_dir,$build,'RNA-SeQC'; + my $tophat_dir = join q[/],$rel_dir,$build,'tophat2'; + my $salmon_dir = join q[/],$rel_dir,$build,'salmon'; + my $fasta_dir = join q[/],$rel_dir,$build,'fasta'; + my $globin_dir = join q[/],$rel_dir,$build,'globin'; + my $mt_dir = join q[/],$rel_dir,$build,'mt'; + make_path($gtf_dir, + $rnaseq_dir, + $tophat_dir, + $salmon_dir, + $fasta_dir, + $globin_dir, + $mt_dir, + {verbose => 0}); + } + } } -my $batch_dir = join q[/],'st','batches'; -my $samples_dir = join q[/],'st','samples'; -my $study_dir = join q[/],'st','studies'; - -make_path ("$tmp_repos/$batch_dir","$tmp_repos/$samples_dir","$tmp_repos/$study_dir",{verbose => 0}); #to create directory tree - -#Mouse -copy("$repos/$batch_dir/25539.xml","$tmp_repos/$batch_dir/25539.xml") or carp "Copy failed: $!"; -copy("$repos/$samples_dir/1807468.xml","$tmp_repos/$samples_dir/1807468.xml") or carp "Copy failed: $!"; -#Human -copy("$repos/$batch_dir/25715.xml","$tmp_repos/$batch_dir/25715.xml") or carp "Copy failed: $!"; -copy("$repos/$samples_dir/1830658.xml","$tmp_repos/$samples_dir/1830658.xml") or carp "Copy failed: $!"; -copy("$repos/$study_dir/2910.xml","$tmp_repos/$study_dir/2910.xml") or carp "Copy failed: $!"; - -#make directory structure with empty files +# Make directory structure with empty files my @files = (); -$files[0] = join(q[/], $dir, 'Mus_musculus','ensembl_75_transcriptome', 'GRCm38','gtf','ensembl_75_transcriptome-GRCm38.gtf'); +$files[0] = join(q[/], $dir, 'Mus_musculus','ensembl_75_transcriptome', + 'GRCm38','gtf','ensembl_75_transcriptome-GRCm38.gtf'); foreach my $v ('ensembl_74_transcriptome','ensembl_75_transcriptome'){ - my $vdir = join(q[/], $dir, 'Homo_sapiens',$v, '1000Genomes_hs37d5',); - push @files, join(q[/], $vdir,'gtf',$v . '-1000Genomes_hs37d5.gtf'); - push @files, join(q[/], $vdir,'RNA-SeQC',$v . '-1000Genomes_hs37d5.gtf'); - push @files, join(q[/], $vdir,'tophat2','1000Genomes_hs37d5.known.1.bt2'); - push @files, join(q[/], $vdir,'tophat2','1000Genomes_hs37d5.known.ver'); - push @files, join(q[/], $vdir,'salmon','versionInfo.json'); - push @files, join(q[/], $vdir,'salmon','refInfo.json'); - push @files, join(q[/], $vdir,'salmon','header.json'); - push @files, join(q[/], $vdir,'fasta','1000Genomes_hs37d5.fa'); - push @files, join(q[/], $vdir,'globin','globin_genes.csv'); - push @files, join(q[/], $vdir,'mt','mt_genes.csv'); + my $vdir = join(q[/], $dir, 'Homo_sapiens',$v, '1000Genomes_hs37d5',); + push @files, join(q[/], $vdir,'gtf',$v . '-1000Genomes_hs37d5.gtf'); + push @files, join(q[/], $vdir,'RNA-SeQC',$v . '-1000Genomes_hs37d5.gtf'); + push @files, join(q[/], $vdir,'tophat2','1000Genomes_hs37d5.known.1.bt2'); + push @files, join(q[/], $vdir,'tophat2','1000Genomes_hs37d5.known.ver'); + push @files, join(q[/], $vdir,'salmon','versionInfo.json'); + push @files, join(q[/], $vdir,'salmon','refInfo.json'); + push @files, join(q[/], $vdir,'salmon','header.json'); + push @files, join(q[/], $vdir,'fasta','1000Genomes_hs37d5.fa'); + push @files, join(q[/], $vdir,'globin','globin_genes.csv'); + push @files, join(q[/], $vdir,'mt','mt_genes.csv'); } -#make directory structure with empty files and funny business (multiple files, missing files, etc) +# Make directory structure with empty files and funny business +# (multiple files, missing files, etc) foreach my $v ('ensembl_84_transcriptome'){ - my $vdir = join(q[/], $dir, 'Mus_musculus',$v, 'GRCm38',); - #more than 1 gtf present - push @files, join(q[/], $vdir,'gtf',$v . '-GRCm38.gtf'); - push @files, join(q[/], $vdir,'gtf', 'GRCm38_sans_mt.gtf'); - #the rest of the instances are missing + my $vdir = join(q[/], $dir, 'Mus_musculus',$v, 'GRCm38',); + #more than 1 gtf present + push @files, join(q[/], $vdir,'gtf',$v . '-GRCm38.gtf'); + push @files, join(q[/], $vdir,'gtf', 'GRCm38_sans_mt.gtf'); + #the rest of the instances are missing } foreach my $file (@files){ `touch $file`; } -########################################################################################################################### -#Mus_musculus (GRCm38 + ensembl_75_transcriptome) Transcriptome Analysis -my %init = (id_run => 12071, position => 4, tag_index => 2); -my $m_test = npg_tracking::data::transcriptome->new (%init, - lims => st::api::lims->new(%init, batch_id => 25539, driver_type => 'xml'), - repository => $tmp_repos, aligner => 'tophat2'); -isa_ok($m_test, 'npg_tracking::data::transcriptome'); -lives_and { is basename($m_test->gtf_file), 'ensembl_75_transcriptome-GRCm38.gtf' } 'file ensembl_75_transcriptome-GRCm38.gtf found'; +my $class = Moose::Meta::Class->create_anon_class(roles=>[qw/npg_testing::db/]); +my $schema_wh = $class->new_object({})->create_test_db( + q[WTSI::DNAP::Warehouse::Schema], q[t/data/fixtures_lims_transcriptome] +); +my %driver_info = (driver_type => 'ml_warehouse', mlwh_schema => $schema_wh); +############################################################################## -#Homo_sapiens (1000Genomes_hs37d5) -%init = (id_run => 12161, position => 1, tag_index => 1); + +# Homo_sapiens (1000Genomes_hs37d5) +my %init = (id_run => 12161, position => 1, tag_index => 1); my $test = npg_tracking::data::transcriptome->new (%init, - lims => st::api::lims->new(%init, batch_id => 25715, driver_type => 'xml'), + lims => st::api::lims->new(%init, id_flowcell_lims => 25715, %driver_info), repository => $tmp_repos); - -lives_and { is $test->transcriptome_index_path,undef } "ok - returns undef for transcriptome_index_path if no transcriptome version in reference name - Homo_sapiens (1000Genomes_hs37d5)"; - -##update sample xml so that Reference Genome is missing (study 2910.xml already has this field empty) -copy("$tmp_repos/$samples_dir/1830658.xml", "$tmp_repos/$samples_dir/1830658.xml.1") or carp "Copy failed: $!"; -my $fh = IO::File->new("<$tmp_repos/$samples_dir/1830658.xml.1") or carp "cannot open $repos/$samples_dir/1830658.xml.1"; -my $w_fh = IO::File->new(">$tmp_repos/$samples_dir/1830658.xml") or carp "cannot open $repos/$samples_dir/1830658.xml"; -while(<$fh>){ - if (/Homo_sapiens\s+(\S+)/){ - print $w_fh " " x 6 . "\n"; - } - else { print $w_fh $_ } -} -$w_fh->close; -$fh->close; - -%init = (id_run => 12161, position => 1, tag_index => 1); +isa_ok($test, 'npg_tracking::data::transcriptome'); +lives_and { is $test->transcriptome_index_path, undef } + "undef for transcriptome_index_path if no transcriptome version in reference"; + +# Update sample data so that Reference Genome is undefined +# (study 2910 already has this field empty) +my $sample_rs = $schema_wh->resultset('Sample'); +$sample_rs->search({id_sample_lims => 1830658})->next + ->update({reference_genome => undef}); my $test2 = npg_tracking::data::transcriptome->new (%init, - lims => st::api::lims->new(%init, batch_id => 25715, driver_type => 'xml'), + lims => st::api::lims->new(%init, id_flowcell_lims => 25715, %driver_info), repository => $tmp_repos); -lives_and { is $test2->transcriptome_index_path, undef } "no path for bowtie2 indices found (reference genome missing in sample and study xml)"; - - -##update sample xml so that Reference Genome has a transcriptome version : Homo_sapiens (1000Genomes_hs37d5 + ensembl_74_transcriptome) +lives_and { is $test2->transcriptome_index_path, undef } + "no path for bowtie2 indices found (reference genome is undefined)"; -my $ver_fh = IO::File->new("<$tmp_repos/$samples_dir/1830658.xml.1") or carp "cannot open $repos/$samples_dir/1830658.xml.1"; -my $ver_w_fh = IO::File->new(">$tmp_repos/$samples_dir/1830658.xml") or carp "cannot open $repos/$samples_dir/1830658.xml"; -while(<$ver_fh>){ - if (/Homo_sapiens\s+(\S+)/){ - print $ver_w_fh " " x 6 . "Homo_sapiens (1000Genomes_hs37d5 + ensembl_74_transcriptome)\n"; - } - else { print $ver_w_fh $_ } -} -$ver_w_fh->close; -$ver_fh->close; - -%init = (id_run => 12161, position => 1, tag_index => 1); +# Update sample reference genome. +$sample_rs->search({id_sample_lims => 1830658})->next->update({ + reference_genome => q[Homo_sapiens (1000Genomes_hs37d5 + ensembl_74_transcriptome)]}); my $test3 = npg_tracking::data::transcriptome->new (%init, - lims => st::api::lims->new(%init, batch_id => 25715, driver_type => 'xml'), + lims => st::api::lims->new(%init, id_flowcell_lims => 25715, %driver_info), repository => $tmp_repos); -lives_and { is basename($test3->gtf_file), 'ensembl_74_transcriptome-1000Genomes_hs37d5.gtf' } 'file ensembl_74_transcriptome-1000Genomes_hs37d5.gtf found where reference = Homo_sapiens (1000Genomes_hs37d5 + ensembl_74_transcriptome)'; - -lives_and { is basename($test3->rnaseqc_gtf_file), 'ensembl_74_transcriptome-1000Genomes_hs37d5.gtf' } 'RNA-SeQC file ensembl_74_transcriptome-1000Genomes_hs37d5.gtf found where reference = Homo_sapiens (1000Genomes_hs37d5 + ensembl_74_transcriptome)'; - -lives_and { is $test3->transcriptome_index_path, catfile($tmp_repos, q[transcriptomes/Homo_sapiens/ensembl_74_transcriptome/1000Genomes_hs37d5/tophat2]) +lives_and { is basename($test3->gtf_file), + 'ensembl_74_transcriptome-1000Genomes_hs37d5.gtf' } + 'file ensembl_74_transcriptome-1000Genomes_hs37d5.gtf found'; +lives_and { is basename($test3->rnaseqc_gtf_file), + 'ensembl_74_transcriptome-1000Genomes_hs37d5.gtf' } + 'RNA-SeQC file ensembl_74_transcriptome-1000Genomes_hs37d5.gtf found'; +lives_and { is $test3->transcriptome_index_path, + catfile($tmp_repos, + q[transcriptomes/Homo_sapiens/ensembl_74_transcriptome/1000Genomes_hs37d5/tophat2]) } "correct path for bowtie2 indices found"; - -lives_and { is basename($test3->globin_file), 'globin_genes.csv' } 'globin genes csv file found where reference = Homo_sapiens (1000Genomes_hs37d5 + ensembl_74_transcriptome)'; - -lives_and { is basename($test3->mt_file), 'mt_genes.csv' } 'mt genes csv file found where reference = Homo_sapiens (1000Genomes_hs37d5 + ensembl_74_transcriptome)'; - -my $prefix_path_74 = catfile($tmp_repos, q[transcriptomes/Homo_sapiens/ensembl_74_transcriptome/1000Genomes_hs37d5/tophat2/1000Genomes_hs37d5.known]); -lives_and { is $test3->transcriptome_index_name, $prefix_path_74 } "Correctly found transcriptome version index name path and prefix "; +lives_and { is basename($test3->globin_file), 'globin_genes.csv' } + 'globin genes csv file found'; +lives_and { is basename($test3->mt_file), 'mt_genes.csv' } + 'mt genes csv file found'; +my $prefix_path_74 = catfile($tmp_repos, + q[transcriptomes/Homo_sapiens/ensembl_74_transcriptome/1000Genomes_hs37d5/tophat2/1000Genomes_hs37d5.known]); +lives_and { is $test3->transcriptome_index_name, $prefix_path_74 } + "Correctly found transcriptome version index name path and prefix "; my $test4 = npg_tracking::data::transcriptome->new ( %init, repository => $tmp_repos, - lims => st::api::lims->new(%init, batch_id => 25715, driver_type => 'xml'), + lims => st::api::lims->new(%init, id_flowcell_lims => 25715, %driver_info), aligner => 'tophat2', analysis => 'salmon'); -lives_and { is $test4->transcriptome_index_path, catfile($tmp_repos, q[transcriptomes/Homo_sapiens/ensembl_74_transcriptome/1000Genomes_hs37d5/salmon]) +lives_and { is $test4->transcriptome_index_path, catfile($tmp_repos, + q[transcriptomes/Homo_sapiens/ensembl_74_transcriptome/1000Genomes_hs37d5/salmon]) } "correct path for salmon indices found"; - lives_and { is $test4->transcriptome_index_name, undef } "ok - returns undef when looking for index name for salmon"; my $test5 = npg_tracking::data::transcriptome->new ( %init, repository => $tmp_repos, - lims => st::api::lims->new(%init, batch_id => 25715, driver_type => 'xml') + lims => st::api::lims->new(%init, id_flowcell_lims => 25715, %driver_info) ); lives_and { is basename($test5->fasta_file), '1000Genomes_hs37d5.fa' -} "transcriptome fasta file 1000Genomes_hs37d5.fa found where reference = Homo_sapiens (1000Genomes_hs37d5 + ensembl_74_transcriptome)"; +} "transcriptome fasta file 1000Genomes_hs37d5.fa found"; +# Mus_musculus +%init = (id_run => 12071, position => 4, tag_index => 2); -##update sample xml so that Reference Genome has a transcriptome version : Mus_musculus (GRCm38 + ensembl_84_transcriptome) -copy("$tmp_repos/$samples_dir/1807468.xml", "$tmp_repos/$samples_dir/1807468.xml.1") or carp "Copy failed: $!"; -my $cpy_fh = IO::File->new("<$tmp_repos/$samples_dir/1807468.xml.1") or carp "cannot open $repos/$samples_dir/1807468.xml.1"; -my $mm_ver_fh = IO::File->new(">$tmp_repos/$samples_dir/1807468.xml") or carp "cannot open $repos/$samples_dir/1807468.xml"; -while(<$cpy_fh>){ - if (/Mus_musculus\s+(\S+)/){ - print $mm_ver_fh " " x 6 . "Mus_musculus (GRCm38 + ensembl_84_transcriptome)\n"; - } - else { print $mm_ver_fh $_ } -} -$mm_ver_fh->close; -$cpy_fh->close; +# Update sample reference genome +$sample_rs->search({id_sample_lims => 1807468})->next->update({ + reference_genome => q[Mus_musculus (GRCm38 + ensembl_75_transcriptome)]}); +my $test7 = npg_tracking::data::transcriptome->new (%init, + lims => st::api::lims->new(%init, id_flowcell_lims => 25539, %driver_info), + repository => $tmp_repos, aligner => 'tophat2'); +lives_and { is basename($test7->gtf_file), 'ensembl_75_transcriptome-GRCm38.gtf' } + 'file ensembl_75_transcriptome-GRCm38.gtf found'; -%init = (id_run => 12071, position => 4, tag_index => 2); +# Update sample reference genome +$sample_rs->search({id_sample_lims => 1807468})->next->update({ + reference_genome => q[Mus_musculus (GRCm38 + ensembl_84_transcriptome)]}); my $test6 = npg_tracking::data::transcriptome->new ( %init, repository => $tmp_repos, - lims => st::api::lims->new(%init, batch_id => 25539, driver_type => 'xml')); + lims => st::api::lims->new(%init, id_flowcell_lims => 25539, %driver_info)); throws_ok { $test6->gtf_file } qr/More than one gtf file/, -'ok - croaks when more than 1 gtf file found - Mus_musculus (GRCm38 + ensembl_84_transcriptome)'; - -my $prefix_path_84 = catfile($tmp_repos, q[transcriptomes/Mus_musculus/ensembl_84_transcriptome/GRCm38/tophat2/GRCm38.known]); +'ok - error when more than 1 gtf file found'; +my $prefix_path_84 = catfile($tmp_repos, + q[transcriptomes/Mus_musculus/ensembl_84_transcriptome/GRCm38/tophat2/GRCm38.known]); my $re_no_idx_name = qr/^Directory.*exists.*index.*files.*not.*found.*$/msxi; my $empty_idx_name = $test6->transcriptome_index_name; -lives_and { is $empty_idx_name, undef } "ok - returns undef for transcriptome_index_name if index files are not present - Mus_musculus (GRCm38 + ensembl_84_transcriptome)"; +lives_and { is $empty_idx_name, undef } + "returns undef for transcriptome_index_name if index files are not present"; my ($tmsg, $msg); $tmsg = $test6->messages()->mlist; -foreach my $m (@{$tmsg}){ $msg = $m; last if ($msg =~ /$re_no_idx_name/); } -like($msg, $re_no_idx_name, 'ok - message stored when index files not found'); - +foreach my $m (@{$tmsg}){ + $msg = $m; last if ($msg =~ /$re_no_idx_name/); } +like($msg, $re_no_idx_name, 'ok - message stored when index files not found'); -# make default symlink -sub symlink_default { - my($dir,$spp,$release) = @_; - my $orig_dir = getcwd(); - my $rel_dir = join q[/],$dir,$spp; - chdir qq[$rel_dir]; - eval { symlink($release,"default") }; - print "symlink error $@" if $@; - chdir $orig_dir; - return; -} +1; diff --git a/t/data/fixtures_lims_transcriptome/000-Sample.yml b/t/data/fixtures_lims_transcriptome/000-Sample.yml new file mode 100644 index 00000000..b78e7998 --- /dev/null +++ b/t/data/fixtures_lims_transcriptome/000-Sample.yml @@ -0,0 +1,1703 @@ +--- +- accession_number: ~ + age: ~ + cell_type: ~ + cohort: ~ + common_name: ~ + compound: ~ + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2011-08-06 14:24:41 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: ~ + developmental_stage: ~ + disease: ~ + disease_state: ~ + dna_source: Genomic + donor_id: ~ + dose: ~ + ethnicity: ~ + extraction_method: ~ + father: ~ + gc_content: Neutral + gender: ~ + genotype: ~ + geographical_region: ~ + growth_condition: ~ + id_lims: SQSCP + id_sample_lims: 1255141 + id_sample_tmp: 1237247 + immunoprecipitate: ~ + is_resubmitted: ~ + last_updated: 2021-04-12 19:48:50 + marked_as_consent_withdrawn_by: ~ + mother: ~ + name: phiX_for_spiked_buffers + organism: ~ + organism_part: ~ + phenotype: ~ + public_name: ~ + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 20:28:54 + reference_genome: PhiX (Sanger-SNPs) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: ~ + subject: ~ + supplier_name: ~ + taxon_id: 10847 + time_point: ~ + treatment: ~ + uuid_sample_lims: d3a59c4c-c037-11e0-834c-00144f01a414 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:37 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of S-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807467 + id_sample_tmp: 1785733 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S1_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-1-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 333275f0-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:37 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of S-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807468 + id_sample_tmp: 1785734 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S2_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-2-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 3366f370-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:37 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of S-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807469 + id_sample_tmp: 1785735 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S3_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-3-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 3386b070-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:37 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of S-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807470 + id_sample_tmp: 1785736 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S4_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-4-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 339cf790-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:37 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of S-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807471 + id_sample_tmp: 1785737 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S5_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-5-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 33acaf00-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:38 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: 'RNA from OB of the brain of S- cross' + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807472 + id_sample_tmp: 1785738 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S1_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-1-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 33ba1c80-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:38 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: 'RNA from OB of the brain of S- cross' + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807473 + id_sample_tmp: 1785739 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S2_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-2-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 33c7b110-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:38 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: 'RNA from OB of the brain of S- cross' + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807474 + id_sample_tmp: 1785740 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S3_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-3-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 33d63000-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:38 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: 'RNA from OB of the brain of S- cross' + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807475 + id_sample_tmp: 1785741 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S4_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-4-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 33e6aac0-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:38 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: 'RNA from OB of the brain of S- cross' + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: CAST/EiJ + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807476 + id_sample_tmp: 1785742 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: C57BL/6J + name: ZSL_S5_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mBLpCAST-5-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 33f72580-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:38 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807477 + id_sample_tmp: 1785743 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M1_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-1-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:46 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 34147180-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:38 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807478 + id_sample_tmp: 1785744 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M2_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-2-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:47 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 34249e20-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:38 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807479 + id_sample_tmp: 1785745 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M3_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-3-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:47 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 343b8180-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:39 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807480 + id_sample_tmp: 1785746 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M4_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-4-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:47 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 344fa5c0-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:39 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from MOE of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807481 + id_sample_tmp: 1785747 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M5_MOE + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-5-MOE + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:47 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 34646640-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:39 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from OB of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807482 + id_sample_tmp: 1785748 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M1_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-1-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:47 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 347974e0-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:39 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from OB of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807483 + id_sample_tmp: 1785749 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M2_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-2-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:47 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 349142a0-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:39 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from OB of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807484 + id_sample_tmp: 1785750 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M3_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-3-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:47 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 34a518c0-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:39 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from OB of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807485 + id_sample_tmp: 1785751 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M4_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-4-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:47 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 34b915f0-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: 14 weeks + cell_type: N/A + cohort: ~ + common_name: Mus musculus + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-06 09:30:39 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: RNA from OB of the brain of M-cross + developmental_stage: Adult + disease: N/A + disease_state: N/A + dna_source: Brain + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: C57BL/6J + gc_content: Neutral + gender: Female + genotype: F1 hybred + geographical_region: ~ + growth_condition: Normal + id_lims: SQSCP + id_sample_lims: 1807486 + id_sample_tmp: 1785752 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:39:58 + marked_as_consent_withdrawn_by: ~ + mother: CAST/EiJ + name: ZSL_M5_BULB + organism: Mouse + organism_part: Brain + phenotype: N/A + public_name: mCASTpBL-5-OB + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:46:47 + reference_genome: Mus_musculus (GRCm38) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: F1 hybred + subject: N/A + supplier_name: ~ + taxon_id: 10090 + time_point: N/A + treatment: N/A + uuid_sample_lims: 34cbdaa0-76b5-11e3-9714-68b59976a382 +- accession_number: ~ + age: N/A + cell_type: iPS-derived macrophage + cohort: ~ + common_name: Homo sapiens + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-28 11:23:55 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: Total RNA from iPS-derived macrophages using mirVana + developmental_stage: N/A + disease: N/A + disease_state: N/A + dna_source: Genomic + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: ~ + gc_content: Neutral + gender: Not Applicable + genotype: N/A + geographical_region: ~ + growth_condition: N/A + id_lims: SQSCP + id_sample_lims: 1830658 + id_sample_tmp: 1808338 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:41:26 + marked_as_consent_withdrawn_by: ~ + mother: ~ + name: abc + organism: Human + organism_part: N/A + phenotype: Normal + public_name: abc + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:49:44 + reference_genome: Homo_sapiens (1000Genomes_hs37d5) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: ~ + subject: ~ + supplier_name: ~ + taxon_id: 9606 + time_point: N/A + treatment: control + uuid_sample_lims: ac43efe0-880e-11e3-a7f3-68b59976a382 +- accession_number: ~ + age: N/A + cell_type: iPS-derived macrophage + cohort: ~ + common_name: Homo sapiens + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-28 11:23:55 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: Total RNA from iPS-derived macrophages using mirVana + developmental_stage: N/A + disease: N/A + disease_state: N/A + dna_source: Genomic + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: ~ + gc_content: Neutral + gender: Not Applicable + genotype: N/A + geographical_region: ~ + growth_condition: N/A + id_lims: SQSCP + id_sample_lims: 1830659 + id_sample_tmp: 1808339 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:41:26 + marked_as_consent_withdrawn_by: ~ + mother: ~ + name: abc + organism: Human + organism_part: N/A + phenotype: Normal + public_name: abc + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:49:44 + reference_genome: Homo_sapiens (1000Genomes_hs37d5) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: ~ + subject: ~ + supplier_name: ~ + taxon_id: 9606 + time_point: N/A + treatment: LPS + uuid_sample_lims: ac816e10-880e-11e3-a7f3-68b59976a382 +- accession_number: ~ + age: N/A + cell_type: iPS-derived macrophage + cohort: ~ + common_name: Homo sapiens + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-28 11:23:55 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: Total RNA from iPS-derived macrophages using mirVana + developmental_stage: N/A + disease: N/A + disease_state: N/A + dna_source: Genomic + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: ~ + gc_content: Neutral + gender: Not Applicable + genotype: N/A + geographical_region: ~ + growth_condition: N/A + id_lims: SQSCP + id_sample_lims: 1830660 + id_sample_tmp: 1808340 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:41:26 + marked_as_consent_withdrawn_by: ~ + mother: ~ + name: abc + organism: Human + organism_part: N/A + phenotype: Normal + public_name: abc + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:49:44 + reference_genome: Homo_sapiens (1000Genomes_hs37d5) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: ~ + subject: ~ + supplier_name: ~ + taxon_id: 9606 + time_point: N/A + treatment: control + uuid_sample_lims: ac9bfaf0-880e-11e3-a7f3-68b59976a382 +- accession_number: ~ + age: N/A + cell_type: iPS-derived macrophage + cohort: ~ + common_name: Homo sapiens + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-01-28 11:23:55 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: Total RNA from iPS-derived macrophages using mirVana + developmental_stage: N/A + disease: N/A + disease_state: N/A + dna_source: Genomic + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: ~ + gc_content: Neutral + gender: Not Applicable + genotype: N/A + geographical_region: ~ + growth_condition: N/A + id_lims: SQSCP + id_sample_lims: 1830661 + id_sample_tmp: 1808341 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:41:26 + marked_as_consent_withdrawn_by: ~ + mother: ~ + name: abc + organism: Human + organism_part: N/A + phenotype: Normal + public_name: abc + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:49:44 + reference_genome: Homo_sapiens (1000Genomes_hs37d5) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: ~ + subject: ~ + supplier_name: ~ + taxon_id: 9606 + time_point: N/A + treatment: LPS + uuid_sample_lims: acb6aee0-880e-11e3-a7f3-68b59976a382 +- accession_number: ~ + age: N/A + cell_type: iPS-derived macrophage + cohort: ~ + common_name: Homo sapiens + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-02-05 12:29:16 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: Total RNA from iPS-derived macrophages using mirVana + developmental_stage: N/A + disease: N/A + disease_state: N/A + dna_source: Genomic + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: ~ + gc_content: Neutral + gender: Not Applicable + genotype: N/A + geographical_region: ~ + growth_condition: N/A + id_lims: SQSCP + id_sample_lims: 1846288 + id_sample_tmp: 1823966 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:42:25 + marked_as_consent_withdrawn_by: ~ + mother: ~ + name: abc + organism: Human + organism_part: N/A + phenotype: Normal + public_name: abc + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:51:39 + reference_genome: Homo_sapiens (1000Genomes_hs37d5) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: ~ + subject: ~ + supplier_name: ~ + taxon_id: 9606 + time_point: N/A + treatment: control + uuid_sample_lims: 21000c30-8e61-11e3-b3b8-68b59976a382 +- accession_number: ~ + age: N/A + cell_type: iPS-derived macrophage + cohort: ~ + common_name: Homo sapiens + compound: N/A + concentration_determined_by: ~ + consent_withdrawn: 0 + control: ~ + control_type: ~ + country_of_origin: ~ + created: 2014-02-05 12:29:16 + customer_measured_concentration: ~ + customer_measured_volume: ~ + date_of_consent_withdrawn: ~ + date_of_sample_collection: ~ + date_of_sample_extraction: ~ + deleted_at: ~ + description: Total RNA from iPS-derived macrophages using mirVana + developmental_stage: N/A + disease: N/A + disease_state: N/A + dna_source: Genomic + donor_id: ~ + dose: N/A + ethnicity: ~ + extraction_method: ~ + father: ~ + gc_content: Neutral + gender: Not Applicable + genotype: N/A + geographical_region: ~ + growth_condition: N/A + id_lims: SQSCP + id_sample_lims: 1846289 + id_sample_tmp: 1823967 + immunoprecipitate: N/A + is_resubmitted: ~ + last_updated: 2021-04-12 20:42:25 + marked_as_consent_withdrawn_by: ~ + mother: ~ + name: abc + organism: Human + organism_part: N/A + phenotype: Normal + public_name: abc + purification_method: ~ + purified: ~ + recorded_at: 2021-04-12 21:51:39 + reference_genome: Homo_sapiens (1000Genomes_hs37d5) + replicate: ~ + sample_type: ~ + sample_visibility: Hold + sanger_sample_id: ~ + sibling: ~ + storage_conditions: ~ + strain: ~ + subject: ~ + supplier_name: ~ + taxon_id: 9606 + time_point: N/A + treatment: LPS + uuid_sample_lims: 2119fcd0-8e61-11e3-b3b8-68b59976a382 + diff --git a/t/data/fixtures_lims_transcriptome/000-Study.yml b/t/data/fixtures_lims_transcriptome/000-Study.yml new file mode 100644 index 00000000..fa4c0d0c --- /dev/null +++ b/t/data/fixtures_lims_transcriptome/000-Study.yml @@ -0,0 +1,122 @@ +--- +- abbreviation: 198STDY + abstract: ~ + accession_number: ~ + aligned: 1 + array_express_accession_number: ~ + contains_human_dna: 0 + contaminated_human_dna: 0 + created: 2008-11-13 13:27:48 + data_access_group: ~ + data_deletion_period: ~ + data_destination: ~ + data_release_delay_period: ~ + data_release_delay_reason: ~ + data_release_sort_of_study: genotyping or cytogenetics + data_release_strategy: open + data_release_timing: standard + deleted_at: ~ + description: None + ega_dac_accession_number: ~ + ega_policy_accession_number: ~ + ena_project_id: ~ + ethically_approved: ~ + faculty_sponsor: None + hmdmc_number: ~ + id_lims: SQSCP + id_study_lims: 198 + id_study_tmp: 177 + last_updated: 2021-10-15 08:54:34 + name: Illumina Controls + prelim_id: ~ + recorded_at: 2021-10-15 08:54:35 + reference_genome: ' ' + remove_x_and_autosomes: 0 + s3_email_list: ~ + separate_y_chromosome_data: 0 + state: active + study_title: ~ + study_type: Resequencing + study_visibility: Hold + uuid_study_lims: 2aa1cd2e-a557-11df-8092-00144f01a414 +- abbreviation: 2899STDY + abstract: ~ + accession_number: ~ + aligned: 1 + array_express_accession_number: ~ + contains_human_dna: 0 + contaminated_human_dna: 0 + created: 2014-01-06 09:24:16 + data_access_group: ~ + data_deletion_period: ~ + data_destination: ~ + data_release_delay_period: ~ + data_release_delay_reason: ~ + data_release_sort_of_study: transcriptomics + data_release_strategy: open + data_release_timing: standard + deleted_at: ~ + description: ~ + ega_dac_accession_number: ~ + ega_policy_accession_number: ~ + ena_project_id: ~ + ethically_approved: ~ + faculty_sponsor: ~ + hmdmc_number: ~ + id_lims: SQSCP + id_study_lims: 2899 + id_study_tmp: 2866 + last_updated: 2021-10-15 08:55:26 + name: Parent-of-origin allelic expression bias in mouse olfaction system + prelim_id: ~ + recorded_at: 2021-10-15 08:55:40 + reference_genome: Mus_musculus (GRCm38) + remove_x_and_autosomes: 0 + s3_email_list: ~ + separate_y_chromosome_data: 0 + state: active + study_title: Detecting parent-of-origin allelic expression bias in mouse olfaction system + study_type: Transcriptome Analysis + study_visibility: Hold + uuid_study_lims: 5060f850-76b4-11e3-9e87-68b59976a382 +- abbreviation: macrophage_miRNA + abstract: ~ + accession_number: ~ + aligned: 1 + array_express_accession_number: ~ + contains_human_dna: 1 + contaminated_human_dna: 0 + created: 2014-01-14 10:49:48 + data_access_group: ~ + data_deletion_period: ~ + data_destination: ~ + data_release_delay_period: ~ + data_release_delay_reason: ~ + data_release_sort_of_study: transcriptomics + data_release_strategy: managed + data_release_timing: standard + deleted_at: ~ + description: ~ + ega_dac_accession_number: ~ + ega_policy_accession_number: ~ + ena_project_id: ~ + ethically_approved: 1 + faculty_sponsor: ~ + hmdmc_number: ~ + id_lims: SQSCP + id_study_lims: 2910 + id_study_tmp: 2877 + last_updated: 2021-10-15 08:55:27 + name: 'I1548 - miRNA expression in response to LPS stimulus in macrophages' + prelim_id: ~ + recorded_at: 2021-10-15 08:55:40 + reference_genome: ~ + remove_x_and_autosomes: 0 + s3_email_list: ~ + separate_y_chromosome_data: 0 + state: active + study_title: miRNA expression in response to LPS stimulus in macrophages + study_type: Transcriptome Analysis + study_visibility: Hold + uuid_study_lims: 9699b400-7d09-11e3-b3de-68b59976a382 + diff --git a/t/data/fixtures_lims_transcriptome/100-IseqFlowcell.yml b/t/data/fixtures_lims_transcriptome/100-IseqFlowcell.yml new file mode 100644 index 00000000..38a8c845 --- /dev/null +++ b/t/data/fixtures_lims_transcriptome/100-IseqFlowcell.yml @@ -0,0 +1,1163 @@ +--- +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889563 + id_library_lims: NT356545P + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785733 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155523 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 1 + tag_index: 1 + tag_sequence: ATCACG + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889564 + id_library_lims: NT356546Q + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785734 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155524 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 2 + tag_index: 2 + tag_sequence: CGATGT + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889565 + id_library_lims: NT356547R + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785735 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155525 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 3 + tag_index: 3 + tag_sequence: TTAGGC + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889566 + id_library_lims: NT356548S + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785736 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155526 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 4 + tag_index: 4 + tag_sequence: TGACCA + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889567 + id_library_lims: NT356549T + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785737 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155527 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 5 + tag_index: 5 + tag_sequence: ACAGTG + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889568 + id_library_lims: NT356550M + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785738 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155528 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 6 + tag_index: 6 + tag_sequence: GCCAAT + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889569 + id_library_lims: NT356551N + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785739 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155529 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 7 + tag_index: 7 + tag_sequence: CAGATC + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889570 + id_library_lims: NT356552O + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785740 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155530 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 8 + tag_index: 8 + tag_sequence: ACTTGA + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889571 + id_library_lims: NT356553P + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785741 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155531 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 9 + tag_index: 9 + tag_sequence: GATCAG + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889572 + id_library_lims: NT356554Q + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785742 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155532 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 10 + tag_index: 10 + tag_sequence: TAGCTT + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889573 + id_library_lims: NT356555R + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785743 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155533 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 11 + tag_index: 11 + tag_sequence: GGCTAC + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889574 + id_library_lims: NT356556S + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785744 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155534 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 12 + tag_index: 12 + tag_sequence: CTTGTA + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889575 + id_library_lims: NT356557T + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785745 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155535 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 13 + tag_index: 13 + tag_sequence: AGTCAA + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889576 + id_library_lims: NT356558U + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785746 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155536 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 14 + tag_index: 14 + tag_sequence: AGTTCC + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889577 + id_library_lims: NT356559V + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785747 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155537 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 15 + tag_index: 15 + tag_sequence: ATGTCA + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889578 + id_library_lims: NT356560O + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785748 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155538 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 16 + tag_index: 16 + tag_sequence: CCGTCC + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889579 + id_library_lims: NT356561P + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785749 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155539 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:22 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 17 + tag_index: 17 + tag_sequence: GTCCGC + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889580 + id_library_lims: NT356562Q + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785750 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155540 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:22 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 18 + tag_index: 18 + tag_sequence: GTGAAA + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889581 + id_library_lims: NT356563R + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785751 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155541 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:22 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 19 + tag_index: 19 + tag_sequence: GTGGCC + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9327018 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889582 + id_library_lims: NT356564S + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1785752 + id_study_tmp: 2866 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 9155542 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Illumina cDNA protocol + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:22 + requested_insert_size_from: 200 + requested_insert_size_to: 500 + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 20 + tag_index: 20 + tag_sequence: GTTTCG + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: ~ + entity_id_lims: 9327018 + entity_type: library_indexed_spike + external_release: 1 + flowcell_barcode: C2N5GACXX + forward_read_length: 100 + id_flowcell_lims: 25539 + id_iseq_flowcell_tmp: 2889562 + id_library_lims: NT310838E + id_lims: SQSCP + id_pool_lims: NT357120V + id_sample_tmp: 1237247 + id_study_tmp: 177 + is_r_and_d: 0 + is_spiked: 1 + last_updated: 2016-02-09 11:31:19 + legacy_library_id: 6200285 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: ~ + position: 4 + primer_panel: ~ + priority: 0 + purpose: standard + recorded_at: 2016-02-09 11:31:21 + requested_insert_size_from: ~ + requested_insert_size_to: ~ + reverse_read_length: 100 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 168 + tag_index: 168 + tag_sequence: ACAACGCAAT + tag_set_id_lims: 6 + tag_set_name: 'Sanger_168tags - 10 mer tags' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9416272 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: ~ + forward_read_length: 25 + id_flowcell_lims: 25715 + id_iseq_flowcell_tmp: 3046395 + id_library_lims: NT364634M + id_lims: SQSCP + id_pool_lims: NT365034V + id_sample_tmp: 1808338 + id_study_tmp: 2877 + is_r_and_d: 0 + is_spiked: 0 + last_updated: 2015-06-08 15:20:09 + legacy_library_id: 9376962 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Small RNA + position: 1 + primer_panel: ~ + priority: 0 + purpose: ~ + recorded_at: 2015-06-08 15:20:21 + requested_insert_size_from: 17 + requested_insert_size_to: 30 + reverse_read_length: 25 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 1 + tag_index: 1 + tag_sequence: ATCACG + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9416272 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: ~ + forward_read_length: 25 + id_flowcell_lims: 25715 + id_iseq_flowcell_tmp: 3046396 + id_library_lims: NT364635N + id_lims: SQSCP + id_pool_lims: NT365034V + id_sample_tmp: 1808339 + id_study_tmp: 2877 + is_r_and_d: 0 + is_spiked: 0 + last_updated: 2015-06-08 15:20:09 + legacy_library_id: 9376963 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Small RNA + position: 1 + primer_panel: ~ + priority: 0 + purpose: ~ + recorded_at: 2015-06-08 15:20:21 + requested_insert_size_from: 17 + requested_insert_size_to: 30 + reverse_read_length: 25 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 2 + tag_index: 2 + tag_sequence: CGATGT + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9416272 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: ~ + forward_read_length: 25 + id_flowcell_lims: 25715 + id_iseq_flowcell_tmp: 3046397 + id_library_lims: NT364636O + id_lims: SQSCP + id_pool_lims: NT365034V + id_sample_tmp: 1808340 + id_study_tmp: 2877 + is_r_and_d: 0 + is_spiked: 0 + last_updated: 2015-06-08 15:20:09 + legacy_library_id: 9376964 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Small RNA + position: 1 + primer_panel: ~ + priority: 0 + purpose: ~ + recorded_at: 2015-06-08 15:20:21 + requested_insert_size_from: 17 + requested_insert_size_to: 30 + reverse_read_length: 25 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 3 + tag_index: 3 + tag_sequence: TTAGGC + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9416272 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: ~ + forward_read_length: 25 + id_flowcell_lims: 25715 + id_iseq_flowcell_tmp: 3046398 + id_library_lims: NT364637P + id_lims: SQSCP + id_pool_lims: NT365034V + id_sample_tmp: 1808341 + id_study_tmp: 2877 + is_r_and_d: 0 + is_spiked: 0 + last_updated: 2015-06-08 15:20:09 + legacy_library_id: 9376965 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Small RNA + position: 1 + primer_panel: ~ + priority: 0 + purpose: ~ + recorded_at: 2015-06-08 15:20:21 + requested_insert_size_from: 17 + requested_insert_size_to: 30 + reverse_read_length: 25 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 4 + tag_index: 4 + tag_sequence: TGACCA + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9416272 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: ~ + forward_read_length: 25 + id_flowcell_lims: 25715 + id_iseq_flowcell_tmp: 3046399 + id_library_lims: NT364638Q + id_lims: SQSCP + id_pool_lims: NT365034V + id_sample_tmp: 1823966 + id_study_tmp: 2877 + is_r_and_d: 0 + is_spiked: 0 + last_updated: 2015-06-08 15:20:09 + legacy_library_id: 9376966 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Small RNA + position: 1 + primer_panel: ~ + priority: 0 + purpose: ~ + recorded_at: 2015-06-08 15:20:21 + requested_insert_size_from: 17 + requested_insert_size_to: 30 + reverse_read_length: 25 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 5 + tag_index: 5 + tag_sequence: ACAGTG + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ +- bait_name: ~ + cost_code: S0755 + entity_id_lims: 9416272 + entity_type: library_indexed + external_release: 1 + flowcell_barcode: ~ + forward_read_length: 25 + id_flowcell_lims: 25715 + id_iseq_flowcell_tmp: 3046400 + id_library_lims: NT364639R + id_lims: SQSCP + id_pool_lims: NT365034V + id_sample_tmp: 1823967 + id_study_tmp: 2877 + is_r_and_d: 0 + is_spiked: 0 + last_updated: 2015-06-08 15:20:09 + legacy_library_id: 9376967 + loading_concentration: ~ + manual_qc: 1 + pipeline_id_lims: Small RNA + position: 1 + primer_panel: ~ + priority: 0 + purpose: ~ + recorded_at: 2015-06-08 15:20:21 + requested_insert_size_from: 17 + requested_insert_size_to: 30 + reverse_read_length: 25 + spiked_phix_barcode: ~ + spiked_phix_percentage: ~ + suboptimal: ~ + tag2_identifier: ~ + tag2_sequence: ~ + tag2_set_id_lims: ~ + tag2_set_name: ~ + tag_identifier: 6 + tag_index: 6 + tag_sequence: GCCAAT + tag_set_id_lims: 27 + tag_set_name: 'TruSeq mRNA Adapter and NEB Small RNA Index Sequences - 6mer' + team: Illumina-C + workflow: ~ + From 7ffa12cd7333973fa4466a6e777bbf2ebf8bdb04 Mon Sep 17 00:00:00 2001 From: Marina Gourtovaia Date: Thu, 6 Jul 2023 15:08:03 +0100 Subject: [PATCH 09/18] Flagged planned onboard analysis. The flag is implemented in the long_info role, which makes it available to any class that inherits from this role, i.e. to most of the code that deals with the run folders. The implementation examines the content of RunParameters.xml The new flag replaces the previous implementation of a similar flag in the staging monitor. --- MANIFEST | 1 + lib/Monitor/RunFolder/Staging.pm | 30 +------ lib/npg_tracking/illumina/run/long_info.pm | 16 ++++ t/34-monitor-runfolder-staging.t | 48 ++--------- t/60-illumina-run-long_info.t | 25 +++++- .../RunParameters.novaseqx.onboard.xml | 79 +++++++++++++++++++ 6 files changed, 128 insertions(+), 71 deletions(-) create mode 100644 t/data/run_params/RunParameters.novaseqx.onboard.xml diff --git a/MANIFEST b/MANIFEST index 3b0dd416..9ec534c1 100644 --- a/MANIFEST +++ b/MANIFEST @@ -726,6 +726,7 @@ t/data/run_params/RunParameters.novaseq.xml t/data/run_params/RunParameters.novaseq.xp.xml t/data/run_params/RunParameters.novaseq.xp.v1.5.xml t/data/run_params/RunParameters.novaseqx.xml +t/data/run_params/RunParameters.novaseqx.onboard.xml t/data/run_params/runParameters.hiseq.rr.single.xml t/data/run_params/runParameters.hiseq.rr.twoind.xml t/data/run_params/runParameters.hiseq.rr.xml diff --git a/lib/Monitor/RunFolder/Staging.pm b/lib/Monitor/RunFolder/Staging.pm index d0c441b0..3b6802b1 100644 --- a/lib/Monitor/RunFolder/Staging.pm +++ b/lib/Monitor/RunFolder/Staging.pm @@ -39,7 +39,6 @@ Readonly::Scalar my $DEFAULT_ONBOARD_ANALYSIS_DN => q[1]; # used at the moment. Readonly::Scalar my $ONBOARD_ANALYSIS_COMPLETE_FN => q[Secondary_Analysis_Complete.txt]; -Readonly::Scalar my $ONBOARD_ANALYSIS_SAMPLESHEET_FN => q[SampleSheet.csv]; Readonly::Array my @UPDATES_FOR_INCOMING_ALLOWED_STATUSES => ('run pending', 'run in progress', 'run complete'); @@ -97,27 +96,6 @@ sub is_run_complete { return $is_run_complete; } - - -sub is_onboard_analysis_planned { - my $self = shift; - - my $planned = 0; - if ($self->platform_NovaSeqX()) { - my $ss = join q[/], - $self->runfolder_path(), $ONBOARD_ANALYSIS_SAMPLESHEET_FN; - my $have_ss = -f $ss; - carp sprintf 'Samplesheet %s for the onboard analysis%sfound', - $ss, $have_ss ? q[ ] : q[ not ]; - if ($have_ss) { - $planned = any { $_ =~ /^\[BCLConvert/smx } read_file($ss); - carp sprintf 'Samplesheet %s %s the BCLConvert section', - $ss, $planned ? q[has] : q[doesn't have]; - } - } - return $planned; -} - sub is_onboard_analysis_output_copied { my $self = shift; @@ -478,7 +456,7 @@ sub update_run_from_path { ##### Method to deal with one run folder } # Check if we are waiting for the onboard analysis to finish. - if ($folder->is_onboard_analysis_planned() && + if ($folder->onboard_analysis_planned() && !$folder->is_onboard_analysis_output_copied()) { return; } @@ -564,12 +542,6 @@ false otherwise. Move the run folder from 'analysis' to 'outgoing'. -=head2 is_onboard_analysis_planned - -Returns true if the run folder for the NovaSeq SeriesX run contains a -samplesheet with a section for the bcl on board data conversion. Always returns -false for other instrument types. - =head2 is_onboard_analysis_output_copied Returns true if the file that flags the end of the transfer of the onboard diff --git a/lib/npg_tracking/illumina/run/long_info.pm b/lib/npg_tracking/illumina/run/long_info.pm index 65e5eef0..abe2e2ab 100644 --- a/lib/npg_tracking/illumina/run/long_info.pm +++ b/lib/npg_tracking/illumina/run/long_info.pm @@ -814,6 +814,22 @@ sub instrument_side { _get_single_element_text($self->_run_params(), 'FCPosition'); } +=head2 onboard_analysis_planned + +Returns true if the RunParameter.xml file contains a section indicating +that DRAGEN analysis is planned, returns false otherwise. Of all locally +available sequencing instruments, ony NovaSeqX instruments are expected +to have this section. + +=cut + +sub onboard_analysis_planned { + my $self = shift; + my $workflows = _get_single_element_text( + $self->_run_params(), 'SecondaryAnalysisWorkflow'); + return $workflows && ($workflows =~ /DRAGEN/xms); +} + ######################################################### # Private attributes # ######################################################### diff --git a/t/34-monitor-runfolder-staging.t b/t/34-monitor-runfolder-staging.t index 971c741b..b60dab4a 100644 --- a/t/34-monitor-runfolder-staging.t +++ b/t/34-monitor-runfolder-staging.t @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 51; +use Test::More tests => 50; use Test::Exception; use Test::Warn; use File::Copy; @@ -465,7 +465,7 @@ subtest 'run completion for NovaSeqX' => sub { }; subtest 'onboard analysis completion for NovaSeqX' => sub { - plan tests => 8; + plan tests => 6; my $tmpdir = tempdir( CLEANUP => 1 ); copy('t/data/run_params/RunParameters.novaseqx.xml',"$tmpdir/RunParameters.xml") @@ -475,30 +475,20 @@ subtest 'onboard analysis completion for NovaSeqX' => sub { my $monitor = Monitor::RunFolder::Staging->new(runfolder_path => $tmpdir); - ok (!$monitor->is_onboard_analysis_planned(), + ok (!$monitor->onboard_analysis_planned(), 'onboard analysis is not planned'); ok (!$monitor->is_onboard_analysis_output_copied(), 'onboard analysis has not been copied'); - my $ss_file = "$tmpdir/SampleSheet.csv"; - open my $fh, '>', $ss_file or die 'Cannot open a file for writing'; - print $fh "[Header]\n[Cloud_BCLConvert_Settings]\n" or die 'Cannot print'; - close $fh or die 'Cannot close the file handle'; - ok (!$monitor->is_onboard_analysis_planned(), - 'onboard analysis is not planned'); - + copy('t/data/run_params/RunParameters.novaseqx.onboard.xml', + "$tmpdir/RunParameters.xml") or die "Copy failed: $!"; my $adir = "$tmpdir/Analysis"; mkdir $adir; + $monitor = Monitor::RunFolder::Staging->new(runfolder_path => $tmpdir); + ok ($monitor->onboard_analysis_planned(), 'onboard analysis is planned'); ok (!$monitor->is_onboard_analysis_output_copied(), 'onboard analysis has not been copied'); - - open $fh, '>>', $ss_file or die 'Cannot open a file for appending'; - print $fh "[BCLConvert_Settings]\n" or die 'Cannot print'; - close $fh or die 'Cannot close the file handle'; - ok ($monitor->is_onboard_analysis_planned(), 'onboard analysis is planned'); - ok (!$monitor->is_onboard_analysis_output_copied(), - 'onboard analysis has not been copied'); - + mkdir "$adir/2"; `touch $adir/2/CopyComplete.txt`; ok (!$monitor->is_onboard_analysis_output_copied(), @@ -510,26 +500,4 @@ subtest 'onboard analysis completion for NovaSeqX' => sub { 'onboard analysis has been copied'); }; -subtest 'no onboard analysis planned for NovaSeq' => sub { - plan tests => 2; - - my $tmpdir = tempdir( CLEANUP => 1 ); - copy('t/data/run_params/RunParameters.novaseq.xml',"$tmpdir/RunParameters.xml") - or die "Copy failed: $!"; - copy('t/data/run_info/runInfo.novaseq.xml',"$tmpdir/RunInfo.xml") - or die "Copy failed: $!"; - my $monitor = Monitor::RunFolder::Staging->new(runfolder_path => $tmpdir); - - ok (!$monitor->is_onboard_analysis_planned(), - 'onboard analysis is not planned'); - - my $ss_file = "$tmpdir/SampleSheet.csv"; - open my $fh, '>', $ss_file or die 'Cannot open a file for writing'; - print $fh "[Header]\n[BCLConvert_Settings]\n" or die 'Cannot print'; - close $fh or die 'Cannot close the file handle'; - ok (!$monitor->is_onboard_analysis_planned(), - 'onboard analysis is not planned'); -}; - - 1; diff --git a/t/60-illumina-run-long_info.t b/t/60-illumina-run-long_info.t index e92058a1..ab44defe 100644 --- a/t/60-illumina-run-long_info.t +++ b/t/60-illumina-run-long_info.t @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 67; +use Test::More tests => 68; use Test::Exception; use Test::Deep; use File::Temp qw(tempdir); @@ -29,7 +29,7 @@ package main; my $basedir = tempdir( CLEANUP => 1 ); subtest 'retrieving information from runParameters.xml' => sub { - plan tests => 153; + plan tests => 167; my $rf = join q[/], $basedir, 'runfolder'; mkdir $rf; @@ -118,10 +118,31 @@ subtest 'retrieving information from runParameters.xml' => sub { ok (!$li->uses_patterned_flowcell, 'not patterned flowcell'); } + ok (!$li->onboard_analysis_planned(), 'onboard analysis is not planned'); + unlink $name; } }; +subtest 'detecting onboard analysis' => sub { + plan tests => 1; + + my $rf = join q[/], $basedir, 'runfolder_onboard'; + mkdir $rf; + copy('t/data/run_params/RunParameters.novaseqx.onboard.xml', + "$rf/RunParameters.xml"); + + my $class = Moose::Meta::Class->create_anon_class( + methods => {"runfolder_path" => sub {$rf}}, + roles => [qw/npg_tracking::illumina::run::long_info/] + ); + my $li = $class->new_object(); + ok ($li->onboard_analysis_planned(), 'onboard analysis is planned'); + + my $o = $li->onboard_analysis_planned(); + diag $o; +}; + subtest 'getting i5opposite for run' => sub { plan tests => 19; diff --git a/t/data/run_params/RunParameters.novaseqx.onboard.xml b/t/data/run_params/RunParameters.novaseqx.onboard.xml new file mode 100644 index 00000000..959a5ed3 --- /dev/null +++ b/t/data/run_params/RunParameters.novaseqx.onboard.xml @@ -0,0 +1,79 @@ + + + B + control-software + 1.1.0.18335 + //nx1-esa.dnapipelines.sanger.ac.uk/staging/IL_seq_data/incoming/20230628_LH00210_0008_B225TGJLT3 + InstrumentPerformance + LocalOrchestrated + LocalAnalysis + NovaSeqXPlus + LH00210 + 20230628_LH00210_0008_B225TGJLT3 + 8 + 10B Sequencing + 10B-01.01.00 + 47539 + NovaSeqXSeries B3 + NovaSeqXSeriesB3 + 1.2345678 + + + 225TGJLT3 + 20750642 + 20080370 + 2024-04-09T00:00:00+01:00 + FlowCell + 10B + + + LC4009058-LC3 + 20740727 + 20066614 + 2024-03-27T00:00:00Z + Reagent + 10B + + + LC2304140485-1 + 23041301 + 20089853 + 2024-07-13T00:00:00+01:00 + Buffer + 10B + + + LC1009924-LC1 + 1000017597 + 20072271 + 2024-04-08T00:00:00+01:00 + SampleTube + 10B + + + LC2007014-LC1 + 17847282 + 20081650 + 2024-02-13T00:00:00Z + Lyo + 10B + + + + + + + + + + + 4.1.7 + + DRAGEN BCL Convert + DRAGEN Germline + DRAGEN Germline + DRAGEN RNA + + + + \ No newline at end of file From 25dd4fa45083850e2353d4597e77736027fd0f3b Mon Sep 17 00:00:00 2001 From: Marina Gourtovaia Date: Mon, 10 Jul 2023 20:02:11 +0100 Subject: [PATCH 10/18] Ensure we have a loader to generate ORM classes --- Build.PL | 1 + 1 file changed, 1 insertion(+) diff --git a/Build.PL b/Build.PL index 942085ca..f9da0065 100644 --- a/Build.PL +++ b/Build.PL @@ -140,6 +140,7 @@ my $builder = $class->new( 'DBIx::Class' => '0.08119', 'DBIx::Class::Core' => 0, 'DBIx::Class::Schema' => 0, + 'DBIx::Class::Schema::Loader' => 0, 'DBIx::Class::InflateColumn::DateTime' => 0, 'Digest::MD5' => 0, 'Digest::SHA' => 0, From 9e1f826632da8713cca9bb998bc5acfa8d8567bf Mon Sep 17 00:00:00 2001 From: "David K. Jackson" Date: Tue, 11 Jul 2023 10:45:17 +0100 Subject: [PATCH 11/18] minimal change to support {} pre-* in glob --- cgi-bin/locate_runfolder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgi-bin/locate_runfolder b/cgi-bin/locate_runfolder index f020510c..e163a40f 100755 --- a/cgi-bin/locate_runfolder +++ b/cgi-bin/locate_runfolder @@ -46,7 +46,7 @@ sub main { # optionally prepended by some url, # neither of which we need to capture. /? # An occasional extra slash - ((?:/\S+?/\*)?) # Run folder path glob. + ((?:/\S+?/\S*?\*)?) # Run folder path glob. / ([^/?]+) # Run folder name. (.*) }smx; From bf6b34bbb62485bc3825f0172af3ff53bb879476 Mon Sep 17 00:00:00 2001 From: "David K. Jackson" Date: Tue, 11 Jul 2023 12:13:46 +0100 Subject: [PATCH 12/18] simplify, add link page for multiple glob results --- cgi-bin/locate_runfolder | 46 +++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/cgi-bin/locate_runfolder b/cgi-bin/locate_runfolder index e163a40f..668e526f 100755 --- a/cgi-bin/locate_runfolder +++ b/cgi-bin/locate_runfolder @@ -25,6 +25,19 @@ sub _error { return; } +sub _list_folders { + my @list = @_; + print "Content-type: text/html\n\n", + "\n", + "

NPG Tracking Server

\n", + "

multiple folders found

\n
    \n", + (map{"
  • $_
  • \n"}@list), + "
\n\n" + or croak "Error printing: $ERRNO"; + return; +} + + sub _script_name { my $name = $PROGRAM_NAME; ($name) = $name =~ m{([^/?]+)\Z}smx; @@ -40,41 +53,36 @@ sub main { # Apache httpd server, this depends on whether mod-rewrite is enabled # in the server, the version of the server and the history of its updates. my $script_name = _script_name(); - my ($pathglob, $runfolder, $suffix) = $path_info =~ + my ($pathglob) = $path_info =~ m{ \A(?:(?:.+/)?$script_name)? # Optionally, the name of this script, # optionally prepended by some url, # neither of which we need to capture. /? # An occasional extra slash - ((?:/\S+?/\S*?\*)?) # Run folder path glob. - / - ([^/?]+) # Run folder name. - (.*) }smx; + (/[\/a-zA-Z0-9_*{},-]+?) # path glob. + \z + }smx; - if (!($pathglob && $runfolder)) { - _error('Failed to get pathglob or run folder or both', $path_info); + if (!($pathglob )) { + _error('Failed to get pathglob', $path_info); return; } - my @folders = sort { -M $a <=> -M $b } glob "$pathglob/$runfolder"; + my @folders = grep {length} # remove empty entries post-detaint + map { /([\/a-z0-9_-]+)/imsx; $1 } # detaint + sort { -M $a <=> -M $b } + glob $pathglob; if (!@folders) { - _error('Run folder not found', $path_info); + _error('Folder not found', $pathglob); return; } - my ($uri) = $folders[0]=~/([\/a-z0-9_-]+)/imsx; # detaint - if (!$uri) { - _error('Detainting has not left anything', $path_info); + if (@folders > 1) { + _list_folders(@folders); return; } - my $rellink = readlink "$uri/Latest_Summary"; - if (defined $rellink) { - $suffix =~ s{^/Latest_Summary}{/$rellink}smx; - } - - my $UNSAFE = q[#]; - $uri .= q(/) . uri_escape($suffix,$UNSAFE); + my $uri = $folders[0]; print "Content-type: text/html\n\n", qq(\n) From b52b042b828b3dded9baa045297a6bca042799c4 Mon Sep 17 00:00:00 2001 From: "David K. Jackson" Date: Tue, 11 Jul 2023 12:33:32 +0100 Subject: [PATCH 13/18] perlcritic --- cgi-bin/locate_runfolder | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cgi-bin/locate_runfolder b/cgi-bin/locate_runfolder index 668e526f..f9de38c0 100755 --- a/cgi-bin/locate_runfolder +++ b/cgi-bin/locate_runfolder @@ -69,9 +69,9 @@ sub main { } my @folders = grep {length} # remove empty entries post-detaint - map { /([\/a-z0-9_-]+)/imsx; $1 } # detaint + map { /([\/a-z0-9_-]+)/imsx ? $1 : q() } #detaint sort { -M $a <=> -M $b } - glob $pathglob; + glob $pathglob; if (!@folders) { _error('Folder not found', $pathglob); return; From 8e1ce417b4572120efac342e08eaf81200a8996e Mon Sep 17 00:00:00 2001 From: Kieron Taylor Date: Tue, 18 Jul 2023 16:42:09 +0100 Subject: [PATCH 14/18] Allow NovaSeqX samplesheets to embed instrument and slot, and not contaminate anything else --- lib/npg/samplesheet/novaseq_xseries.pm | 43 ++++++++++++++------- lib/npg_tracking/illumina/run/short_info.pm | 15 ++++++- t/47-npg_samplesheet_novaseq_xseries.t | 28 +++++++------- t/60-illumina-run-short_info.t | 34 +++++++++++++--- t/data/dbic_fixtures/300-Run.yml | 2 +- 5 files changed, 88 insertions(+), 34 deletions(-) diff --git a/lib/npg/samplesheet/novaseq_xseries.pm b/lib/npg/samplesheet/novaseq_xseries.pm index 5981d6c9..b6379c6a 100755 --- a/lib/npg/samplesheet/novaseq_xseries.pm +++ b/lib/npg/samplesheet/novaseq_xseries.pm @@ -66,7 +66,7 @@ on this instrument model. The DRAGEN analysis can process a limited number of distinct analysis configurations. The germline and RNA alignment sections of the generated -samplesheet will contain as many samples as possible within the limit set by +samplesheet will contain as many samples as possible within the limit set by the C attribute. The default value for this attribute is 4, which is the number of distinct configurations that the on-board DRAGEN analysis can handle. @@ -74,10 +74,10 @@ on-board DRAGEN analysis can handle. In the BCLConvert section, each combination of index lengths counts as a unique configuration. If the number of these configurations exceeds the value of the the C attribute, no DRAGEN analysis -sections are added to the samplesheet. +sections are added to the samplesheet. See specification in -L +L A full listing of analysis options is available in L @@ -171,7 +171,7 @@ has 'keep_fastq' => ( Variant calling mode, defaults to C, other valid options are C and C - + =cut has 'varcall' => ( @@ -308,13 +308,15 @@ sub _build_run_name { if ($self->has_id_run()) { $run_name = $self->id_run; } else { + # Run is not tracked, generate a placeholder ID my $ug = Data::UUID->new(); my @a = split /-/xms, $ug->to_string($ug->create()); # Add a random string at the end so that the batch can be reused. - $run_name = sprintf 'ssbatch%s_%s', $self->batch_id(), $a[0]; + return sprintf 'ssbatch%s_%s', $self->batch_id(), $a[0]; } - return $run_name; + # Embed instrument's Sanger network name and slot + return sprintf '%s_%s_%s', $run_name, $self->run->instrument->name, $self->get_instrument_side; } =head2 file_name @@ -333,21 +335,16 @@ sub _build_file_name { my $file_name; if ($self->has_id_run) { - my $side = $self->run->is_tag_set('fc_slotA') ? 'A' : - ($self->run->is_tag_set('fc_slotB') ? 'B' : q[]); - if (!$side) { - croak 'Slot is not set for run ' . $self->id_run; - } $file_name = join q[_], $self->run->instrument->name, $self->id_run, - $side, + $self->get_instrument_side, q[ssbatch] . $self->batch_id; } else { $file_name = $self->run_name; } - my $date = DateTime->now()->strftime('%y%m%d'); # 230602 for 2 June 2023 + my $date = DateTime->now()->strftime('%y%m%d'); # 230602 for 2 June 2023 $file_name = sprintf '%s_%s.csv', $date, $file_name; return $file_name; @@ -642,7 +639,7 @@ sub add_common_headers { $self->_add_line(qw(InstrumentType NovaSeqXPlus)); $self->_add_line(); - # Reads section + # Reads section $self->_add_line('[Reads]'); $self->_add_line(q[Read1Cycles], $READ1_LENGTH); $self->_add_line(q[Read2Cycles], $READ2_LENGTH); @@ -695,6 +692,24 @@ sub do_libtype_tenx_test { return any { $lt =~ /$_/xmsi } @TENX_ANALYSES_LIB_TYPES; } +=head2 get_instrument_side + +Consult run tags to determine which slot/side of the instrument this run is +intended to be inserted into. Croaks when no value has been set. + +=cut + +sub get_instrument_side { + my $self = shift; + my $side = $self->run->is_tag_set('fc_slotA') ? 'A' : + ($self->run->is_tag_set('fc_slotB') ? 'B' : q[]); + if (! $side) { + croak 'Slot is not set for run ' . $self->id_run; + } + return $side; +} + + sub _add_samples { my ($self, @samples) = @_; diff --git a/lib/npg_tracking/illumina/run/short_info.pm b/lib/npg_tracking/illumina/run/short_info.pm index 25353cc6..87e34853 100644 --- a/lib/npg_tracking/illumina/run/short_info.pm +++ b/lib/npg_tracking/illumina/run/short_info.pm @@ -95,8 +95,10 @@ sub _build_id_run { $self->run_folder(); } + # Try to read id_run from the folder name ($inst_t, $inst_i, $id_run) = $self->run_folder() =~ /$NAME_PATTERN/gmsx; + # Failing that try the tracking DB. if ( !$id_run ) { if ($self->can(q(npg_tracking_schema)) and $self->npg_tracking_schema()) { my $rs = $self->npg_tracking_schema()->resultset('Run') @@ -107,8 +109,19 @@ sub _build_id_run { } } + # When no id_run is set (as in pick-up runs) attempt to parse an id_run from + # the experiment name recorded in the Illumina XML file. + # We embed additional information in NovaSeqX samplesheets which have no + # meaning here. See L if ( !$id_run && $self->can('experiment_name') && $self->experiment_name() ) { - ($id_run) = $self->experiment_name() =~ /\A[\s]*([\d]+)[\s]*\Z/xms; + ($id_run, undef) = $self->experiment_name() =~ m{ + \A + [\s]* + ([\d]+) # id_run + (_[\w\d]*)? # instrument name or other embedded info + [\s]* + \Z + }xms; } if( !$id_run ) { diff --git a/t/47-npg_samplesheet_novaseq_xseries.t b/t/47-npg_samplesheet_novaseq_xseries.t index e122b820..d63405b0 100644 --- a/t/47-npg_samplesheet_novaseq_xseries.t +++ b/t/47-npg_samplesheet_novaseq_xseries.t @@ -12,7 +12,7 @@ use_ok('npg::samplesheet::novaseq_xseries'); my $class = Moose::Meta::Class->create_anon_class(roles=>[qw/npg_testing::db/]); my $schema_tracking = $class->new_object({})->create_test_db( - q[npg_tracking::Schema], q[t/data/dbic_fixtures] + q[npg_tracking::Schema], q[t/data/dbic_fixtures] ); my $schema_wh = $class->new_object({})->create_test_db( @@ -22,7 +22,7 @@ my $schema_wh = $class->new_object({})->create_test_db( my $date = DateTime->now()->strftime('%y%m%d'); subtest 'create the generator object, test simple attributes' => sub { - plan tests => 13; + plan tests => 14; my $g = npg::samplesheet::novaseq_xseries->new( npg_tracking_schema => $schema_tracking, @@ -51,21 +51,21 @@ subtest 'create the generator object, test simple attributes' => sub { like($g->run_name, qr/\Assbatch97071_[\w]+\Z/, 'run name when id_run is not given'); like($g->file_name, qr/\A${date}_ssbatch97071_[\w]+\.csv\Z/, - 'samplesheet file name when id_run is not given'); - - $g = npg::samplesheet::novaseq_xseries->new( - npg_tracking_schema => $schema_tracking, - mlwh_schema => $schema_wh, - id_run => 47446, - batch_id => 97071, - ); - is($g->run_name, '47446', 'run name is run ID when the latter is known'); + 'samplesheet file name when id_run is not given'); + my $run_row = $schema_tracking->resultset('Run')->create({ id_run => 47446, id_instrument_format => 12, id_instrument => 69, team => 'A' }); + + $g = npg::samplesheet::novaseq_xseries->new( + npg_tracking_schema => $schema_tracking, + mlwh_schema => $schema_wh, + id_run => 47446, + batch_id => 97071, + ); throws_ok { $g->file_name } qr/Slot is not set for run 47446/, 'error when the slot is unknown'; @@ -80,11 +80,13 @@ subtest 'create the generator object, test simple attributes' => sub { ); is ($g->file_name, "${date}_NVX1_47446_${slot}_ssbatch97071.csv", 'correct file name is generated'); + is($g->run_name, "47446_NVX1_${slot}", + 'run name is constructed from run ID when possible'); if ($slot eq 'A') { $run_row->unset_tag($tag); } } - + $g = npg::samplesheet::novaseq_xseries->new( npg_tracking_schema => $schema_tracking, mlwh_schema => $schema_wh, @@ -111,7 +113,7 @@ subtest 'create the generator object, test simple attributes' => sub { ); throws_ok { $g->file_name } qr/Instrument model is not NovaSeq X Series/, - 'error when the run is registered on the wrong instrument model'; + 'error when the run is registered on the wrong instrument model'; }; 1; diff --git a/t/60-illumina-run-short_info.t b/t/60-illumina-run-short_info.t index 4fadfd48..3a0d22e2 100644 --- a/t/60-illumina-run-short_info.t +++ b/t/60-illumina-run-short_info.t @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 45; +use Test::More tests => 46; use Test::Exception; use File::Temp qw/ tempdir /; use Moose::Meta::Class; @@ -30,7 +30,7 @@ sub _build_run_folder { my $path = $self->_short_path(); return first {$_ ne q()} reverse splitdir($path); - + } @@ -39,7 +39,7 @@ has q{_short_path} => ( isa => q{Str}, is => q{ro}, lazy_build => sub _build__short_path { my ($self) = @_; my @dir = $self->has_run_folder() ? glob $self->_folder_path_glob_pattern() . $self->run_folder() - : $self->has_id_run() ? glob $self->_folder_path_glob_pattern() . q(*_{r,}) . $self->id_run() . q{*} + : $self->has_id_run() ? glob $self->_folder_path_glob_pattern() . q(*_{r,}) . $self->id_run() . q{*} : $self->has_name() ? glob $self->_folder_path_glob_pattern() . q{*} . $self->name() : croak q{No run_folder, name or id_run provided} ; @@ -71,6 +71,12 @@ sub _folder_path_glob_pattern { } +package test::nvx_short_info; +use Moose; +with 'npg_tracking::illumina::run::short_info'; + +has experiment_name => (is => 'rw'); + package main; sub create_staging { @@ -187,7 +193,7 @@ my $run_folder = q{123456_IL2_1234}; }); is($short_info->short_reference(), $id_run, q{HS short_reference returns id_run}); is($short_info->name(),q{HS2_1234}, q{HS name worked out correctly}); - is($short_info->short_reference(), q{123456_HS2_1234_B_205NNABXX}, q{HS short_reference returns run_folder}); + is($short_info->short_reference(), q{123456_HS2_1234_B_205NNABXX}, q{HS short_reference returns run_folder}); } #### test where name is give in the constructor @@ -243,7 +249,7 @@ my $run_folder = q{123456_IL2_1234}; my $name; my $flowcell_id; - lives_ok { + lives_ok { $name = $short_info->name(); $flowcell_id= $short_info->flowcell_id(); } q{MiSeq runfolder - kit id in place of flowcell}; @@ -265,4 +271,22 @@ subtest 'process run_folder when no id_run present' => sub { } qr[Unable to identify id_run], q[Throws when it obtain id_run]; }; +subtest 'Test id_run extraction from within experiment_name' => sub { + plan tests => 5; + my $short_info = test::nvx_short_info->new(experiment_name => '45678_NVX1_A', run_folder => 'not_a_folder'); + is($short_info->id_run, '45678', 'id_run parsed from experiment name'); + + $short_info = test::nvx_short_info->new(experiment_name => ' 45678_NVX1_A ', run_folder => 'not_a_folder'); + is($short_info->id_run, '45678', 'id_run parsed from loosely formatted experiment name'); + + $short_info = test::nvx_short_info->new(experiment_name => '45678', run_folder => 'not_a_folder'); + is($short_info->id_run, '45678', 'Bare id_run as experiment name is fine'); + + $short_info = test::nvx_short_info->new(experiment_name => 'NovaSeqX_WHGS_TruSeqPF_NA12878', run_folder => 'not_a_folder'); + throws_ok { $short_info->id_run } qr{Unable to identify id_run with data provided}, 'Custom run name cannot be parsed'; + + $short_info = test::nvx_short_info->new(id_run => '45678', experiment_name => '56789_NVX1_A', run_folder => 'not_a_folder'); + is($short_info->id_run, '45678', 'Set id_run wins over experiment_name'); +}; + 1; diff --git a/t/data/dbic_fixtures/300-Run.yml b/t/data/dbic_fixtures/300-Run.yml index 36bbfc2f..eb0798bd 100644 --- a/t/data/dbic_fixtures/300-Run.yml +++ b/t/data/dbic_fixtures/300-Run.yml @@ -9,7 +9,7 @@ team: 'RAD' is_paired: 0 priority: 1 - flowcell_id: + flowcell_id: - actual_cycle_count: 64 batch_id: 4861 expected_cycle_count: 64 From 5cfc861ed172bb61ec1c4a1f72e59f95be514ccf Mon Sep 17 00:00:00 2001 From: Kieron Taylor Date: Thu, 20 Jul 2023 17:02:04 +0100 Subject: [PATCH 15/18] Tidy up run_name builder and reduce code duplication. Changes file_name. --- lib/npg/samplesheet/novaseq_xseries.pm | 12 +++++------- t/47-npg_samplesheet_novaseq_xseries.t | 4 ++-- t/60-illumina-run-short_info.t | 8 +++++++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/npg/samplesheet/novaseq_xseries.pm b/lib/npg/samplesheet/novaseq_xseries.pm index b6379c6a..bbdabd79 100755 --- a/lib/npg/samplesheet/novaseq_xseries.pm +++ b/lib/npg/samplesheet/novaseq_xseries.pm @@ -306,17 +306,17 @@ sub _build_run_name { my $run_name; if ($self->has_id_run()) { - $run_name = $self->id_run; + # Embed instrument's Sanger network name and slot + $run_name = sprintf '%s_%s_%s', $self->id_run, $self->run->instrument->name, $self->get_instrument_side; } else { # Run is not tracked, generate a placeholder ID my $ug = Data::UUID->new(); my @a = split /-/xms, $ug->to_string($ug->create()); # Add a random string at the end so that the batch can be reused. - return sprintf 'ssbatch%s_%s', $self->batch_id(), $a[0]; + $run_name = sprintf 'ssbatch%s_%s', $self->batch_id(), $a[0]; } - # Embed instrument's Sanger network name and slot - return sprintf '%s_%s_%s', $run_name, $self->run->instrument->name, $self->get_instrument_side; + return $run_name; } =head2 file_name @@ -336,9 +336,7 @@ sub _build_file_name { my $file_name; if ($self->has_id_run) { $file_name = join q[_], - $self->run->instrument->name, - $self->id_run, - $self->get_instrument_side, + $self->run_name, q[ssbatch] . $self->batch_id; } else { $file_name = $self->run_name; diff --git a/t/47-npg_samplesheet_novaseq_xseries.t b/t/47-npg_samplesheet_novaseq_xseries.t index d63405b0..15f5cedb 100644 --- a/t/47-npg_samplesheet_novaseq_xseries.t +++ b/t/47-npg_samplesheet_novaseq_xseries.t @@ -78,7 +78,7 @@ subtest 'create the generator object, test simple attributes' => sub { id_run => 47446, batch_id => 97071, ); - is ($g->file_name, "${date}_NVX1_47446_${slot}_ssbatch97071.csv", + is ($g->file_name, "${date}_47446_NVX1_${slot}_ssbatch97071.csv", 'correct file name is generated'); is($g->run_name, "47446_NVX1_${slot}", 'run name is constructed from run ID when possible'); @@ -102,7 +102,7 @@ subtest 'create the generator object, test simple attributes' => sub { mlwh_schema => $schema_wh, id_run => 47446, ); - is ($g->file_name, "${date}_NVX1_47446_B_ssbatch99888.csv", + is ($g->file_name, "${date}_47446_NVX1_B_ssbatch99888.csv", 'correct file name is generated'); $run_row->update({id_instrument_format => 10, id_instrument => 68}); diff --git a/t/60-illumina-run-short_info.t b/t/60-illumina-run-short_info.t index 3a0d22e2..9777e889 100644 --- a/t/60-illumina-run-short_info.t +++ b/t/60-illumina-run-short_info.t @@ -272,13 +272,19 @@ subtest 'process run_folder when no id_run present' => sub { }; subtest 'Test id_run extraction from within experiment_name' => sub { - plan tests => 5; + plan tests => 7; my $short_info = test::nvx_short_info->new(experiment_name => '45678_NVX1_A', run_folder => 'not_a_folder'); is($short_info->id_run, '45678', 'id_run parsed from experiment name'); $short_info = test::nvx_short_info->new(experiment_name => ' 45678_NVX1_A ', run_folder => 'not_a_folder'); is($short_info->id_run, '45678', 'id_run parsed from loosely formatted experiment name'); + $short_info = test::nvx_short_info->new(experiment_name => '45678_NVX1_A ', run_folder => 'not_a_folder'); + is($short_info->id_run, '45678', 'id_run parsed from experiment name with postfix spaces'); + + $short_info = test::nvx_short_info->new(experiment_name => ' 45678_NVX1_A', run_folder => 'not_a_folder'); + is($short_info->id_run, '45678', 'id_run parsed from experiment name with prefixed spaces'); + $short_info = test::nvx_short_info->new(experiment_name => '45678', run_folder => 'not_a_folder'); is($short_info->id_run, '45678', 'Bare id_run as experiment name is fine'); From db0b91b38538653fe12fb490630df43c1011e2cd Mon Sep 17 00:00:00 2001 From: Kieron Taylor Date: Thu, 20 Jul 2023 17:48:33 +0100 Subject: [PATCH 16/18] Simplify regex for parsing NovaSeqX experiment names --- lib/npg_tracking/illumina/run/short_info.pm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/npg_tracking/illumina/run/short_info.pm b/lib/npg_tracking/illumina/run/short_info.pm index 87e34853..5e08a2a4 100644 --- a/lib/npg_tracking/illumina/run/short_info.pm +++ b/lib/npg_tracking/illumina/run/short_info.pm @@ -117,9 +117,8 @@ sub _build_id_run { ($id_run, undef) = $self->experiment_name() =~ m{ \A [\s]* - ([\d]+) # id_run - (_[\w\d]*)? # instrument name or other embedded info - [\s]* + ([\d]+) # id_run + ([\w\d\s]*) # instrument name or other embedded info \Z }xms; } From 1e6ddf60be14597f50251736e0bd9757602b30ca Mon Sep 17 00:00:00 2001 From: Marina Gourtovaia Date: Thu, 20 Jul 2023 17:22:11 +0100 Subject: [PATCH 17/18] Added tests for top level staging monitor. --- MANIFEST | 3 + t/35-monitor_one_runfolder.t | 280 ++ t/data/dbic_fixtures/100-InstrumentFormat.yml | 6 + t/data/dbic_fixtures/200-Instrument.yml | 15 +- .../RunParameters.novaseqx.onboard.xml | 12 +- .../novaseqxplus/RunInfo.xml | 3162 +++++++++++++++++ .../novaseqxplus/RunParameters.xml | 68 + 7 files changed, 3539 insertions(+), 7 deletions(-) create mode 100644 t/35-monitor_one_runfolder.t create mode 100644 t/data/test_staging_daemon/novaseqxplus/RunInfo.xml create mode 100644 t/data/test_staging_daemon/novaseqxplus/RunParameters.xml diff --git a/MANIFEST b/MANIFEST index 69fce4b4..e67a01cf 100644 --- a/MANIFEST +++ b/MANIFEST @@ -406,6 +406,7 @@ t/30-api-util.t t/34-monitor-runfolder-staging.t t/34-monitor-runfolder.t t/34-monitor-staging.t +t/35-monitor_one_runfolder.t t/40-st-base.t t/40-st-batch.t t/40-st-lims-insert_size.t @@ -1346,6 +1347,8 @@ t/data/test45/st/studies/297.xml t/data/test45/st/studies/333.xml t/data/test45/st/studies/365.xml t/data/test45/st/studies/700.xml +t/data/test_staging_daemon/novaseqxplus/RunInfo.xml +t/data/test_staging_daemon/novaseqxplus/RunParameters.xml t/data/gaii/staging/IL12/incoming/100721_IL12_05222/Data/Intensities/L001/.gitignore t/data/gaii/staging/IL3/incoming/100622_IL3_01234/Data/Intensities/L001/C1.1/.gitignore t/data/gaii/staging/IL3/incoming/100622_IL3_01234/Data/Intensities/L001/C10.1/.gitignore diff --git a/t/35-monitor_one_runfolder.t b/t/35-monitor_one_runfolder.t new file mode 100644 index 00000000..b572d6a9 --- /dev/null +++ b/t/35-monitor_one_runfolder.t @@ -0,0 +1,280 @@ +use strict; +use warnings; +use Test::More tests => 7; +use Test::Exception; +use File::Path qw/make_path/; +use File::Copy; +use File::Temp qw/ tempdir /; + +use t::dbic_util; + +use_ok('Monitor::RunFolder::Staging'); + +######### +# Tests for high-level functionality, ie the update_run_from_path method +# of the Monitor::RunFolder::Staging class. In these tests the class +# instances are created the same way as in the staging_area_monitor script, +# i.e. by supplying the runfolder_path and npg_tracking_schema attributes. +# +# Tests are arranged roughly in the way the code flows. Each subtest +# corresponds to one loop of the staging monitor. +# + +my $schema = t::dbic_util->new->test_schema(); # t/data/dbic_fixtures +my $dir = tempdir( CLEANUP => 1 ); + +my $idir = "$dir/incoming"; +my $adir = "$dir/analysis"; +my $odir = "$dir/outgoing"; +make_path($idir, $adir, $odir); + +# Create bare-bones NovaSeqXPlus run. +my $id_run = 47539; +my $run = $schema ->resultset('Run')->create({ + id_run => $id_run, + expected_cycle_count => 8, + actual_cycle_count => 0, + id_instrument => 70, + id_instrument_format => 13, + team => 'A' +}); +$run->update_run_status('run pending'); + +my $runfolder_name = q[20230628_LH00210_0008_B225TGJLT3]; +# The runfolder is originally in 'incoming' +my $runfolder_path = join q[/], $idir, $runfolder_name; +make_path($runfolder_path); +my $basecalls_path = "$runfolder_path/Data/Intensities/BaseCalls"; + +copy 't/data/test_staging_daemon/novaseqxplus/RunInfo.xml', + "$runfolder_path/RunInfo.xml"; +copy 't/data/test_staging_daemon/novaseqxplus/RunParameters.xml', + "$runfolder_path/RunParameters.xml"; + +subtest 'a new run in incoming' => sub { + plan tests => 15; + + my $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + my $size_hash = {}; + my $done; + lives_ok { $done = $monitor->update_run_from_path($size_hash) } 'run the monitor'; + ok (!$done, 'correct return value'); + ok (defined $monitor->tracking_run(), 'run row is cached'); + my $tracking_run = $monitor->tracking_run(); + is ($tracking_run->id_run, $id_run, 'correct db record is cached'); + is ($tracking_run->folder_name(), $runfolder_name, + 'tracking database - run folder name is set'); + is ($tracking_run->folder_path_glob(), "$dir/*/", + 'tracking database - run folder glob is set'); + is ($tracking_run->actual_cycle_count(), 0, 'cycle count is zero'); + is ($tracking_run->current_run_status_description(), 'run pending', + 'the run is still pending'); + is ($tracking_run->flowcell_id(), '225TGJLT3', + 'flowcell barcode is recorded'); + ok ($tracking_run->is_tag_set('staging'), 'staging tag is set'); + ok ($tracking_run->is_tag_set('fc_slotB'), 'instrument side B is set'); + ok ($tracking_run->is_tag_set('paired_read'), 'run is tagged as paired'); + ok ($tracking_run->is_tag_set('multiplex'), 'run is tagged as multiplex'); + ok (exists $size_hash->{$runfolder_path}, 'runfolder size is cached'); + is ($size_hash->{$runfolder_path}, 0, 'runfolder size is set to zero'); +}; + +subtest 'run in progress' => sub { + plan tests => 10; + + # Now the run is half way through to completion. + for my $i ((1 .. 8)) { + for my $j ((1 .. 4)) { + make_path("$basecalls_path/L00${i}/C${j}.1"); + } + } + my $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + my $size_hash = {$runfolder_path => 0}; + my $done; + lives_ok { $done = $monitor->update_run_from_path($size_hash) } 'run the monitor'; + ok (!$done, 'correct return value'); + is ($monitor->tracking_run->actual_cycle_count(), 4, 'cycle count is 4'); + is ($monitor->tracking_run->current_run_status_description(), 'run in progress', + 'the run is in progress'); + is ($size_hash->{$runfolder_path}, 0, 'runfolder size is zero'); + + # Now the run is close to completion. + for my $i ((1 .. 8)) { + for my $j ((5 .. 8)) { + make_path("$basecalls_path/L00${i}/C${j}.1"); + } + } + $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + lives_ok { $done = $monitor->update_run_from_path($size_hash) } 'run the monitor'; + ok (!$done, 'correct return value'); + is ($monitor->tracking_run->actual_cycle_count(), 8, 'cycle count is 8'); + is ($monitor->tracking_run->current_run_status_description(), 'run in progress', + 'the run is in progress'); + is ($size_hash->{$runfolder_path}, 0, 'runfolder size is zero'); +}; + +subtest 'run is completed' => sub { + plan tests => 5; + + for my $f (qw(RTAComplete.txt CopyComplete.txt)) { + `touch $runfolder_path/$f`; + } + + my $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + my $size_hash = {$runfolder_path => 0}; + my $done; + lives_ok { $done = $monitor->update_run_from_path($size_hash) } 'run the monitor'; + ok (!$done, 'correct return value'); + is ($monitor->tracking_run->actual_cycle_count(), 8, 'cycle count is 8'); + is ($monitor->tracking_run->current_run_status_description(), 'run complete', + 'the run has completed'); + is ($size_hash->{$runfolder_path}, 0, 'runfolder size is zero'); +}; + +subtest 'run is mirrored' => sub { + plan tests => 10; + + for my $i ((1 .. 8)) { + for my $j ((1 .. 8)) { + for my $s ((1 .. 2)) { + `touch $basecalls_path/L00${i}/C${j}.1/L00${i}_${s}.cbcl`; + } + } + } + my $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + my $size_hash = {$runfolder_path => 0}; + my $done; + lives_ok { $done = $monitor->update_run_from_path($size_hash) } 'run the monitor'; + ok (!$done, 'correct return value'); + my $size = $size_hash->{$runfolder_path}; + ok ($size > 0, 'runfolder size is not zero'); + is ($monitor->tracking_run->current_run_status_description(), 'run complete', + 'the run is still marked as completed'); + + $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + lives_ok { $done = $monitor->update_run_from_path($size_hash) } 'run the monitor'; + ok ($done, 'correct return value'); + is ($size_hash->{$runfolder_path}, $size, 'runfolder size does not change'); + is ($monitor->tracking_run->current_run_status_description(), 'analysis pending', + 'the run is marked as mirrored and automatically moved to pending analysis'); + ok (!-e $runfolder_path, 'the old run folder path is invalid'); + $runfolder_path = join q[/], $adir, $runfolder_name; + ok (-e $runfolder_path, q[the folder has been moved to 'analysis']); +}; + +subtest q[move to 'outgoing'] => sub { + plan tests => 10; + + # Run is now in the 'analysis' directory' + $run->update_run_status('secondary analysis in progress'); + my $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + my $done; + lives_ok { $done = $monitor->update_run_from_path({}) } 'run the monitor'; + ok (!$done, 'correct return value'); + ok (-e $runfolder_path, q[run folder is still in 'analysis']); + + $run->update_run_status('qc complete'); + $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + my $inhibit_folder_move = 1; + lives_ok { $done = $monitor->update_run_from_path({}, $inhibit_folder_move ) } + 'run the monitor'; + ok (!$done, 'correct return value'); + ok (-e $runfolder_path, q[run folder is still in 'analysis']); + + lives_ok { $done = $monitor->update_run_from_path({}) } 'run the monitor'; + ok (!$done, 'correct return value'); + ok (!-e $runfolder_path, 'the old run folder path is invalid'); + $runfolder_path = join q[/], $odir, $runfolder_name; + ok (-e $runfolder_path, q[the folder has been moved to 'outgoing']); +}; + +subtest q[wait for DRAGEN analysis to finish] => sub { + plan tests => 13; + + # Change the run status. + sleep 1; # Ensure a different timestamp for the new status. + $run->update_run_status('run complete'); + + my $new_path = join q[/], $idir, $runfolder_name; + `mv $runfolder_path $new_path`; # Move the run folder back to 'incoming'. + $runfolder_path = $new_path; + # Copy the file with the DRAGEN analysis section. + copy('t/data/run_params/RunParameters.novaseqx.onboard.xml', + "$runfolder_path/RunParameters.xml"); + my $dpath = "$runfolder_path/Analysis/1"; + make_path($dpath); # Create DRAGEN analysis directory. + + my $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + my $size_hash = {$runfolder_path => 0}; + my $done; + lives_ok { $done = $monitor->update_run_from_path($size_hash) } + 'run the monitor'; + ok (!$done, 'correct return value'); + ok ($monitor->onboard_analysis_planned(), 'onboard analysis is planned'); + ok (!$monitor->is_onboard_analysis_output_copied(), + 'onboard analysis data is not copied across yet'); + ok (-e $runfolder_path, q[run folder is in 'incoming']); + my $size = $size_hash->{$runfolder_path}; + + $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + lives_ok { $done = $monitor->update_run_from_path($size_hash) } 'run the monitor'; + ok (!$done, 'correct return value'); + ok (-e $runfolder_path, q[run folder is still in 'incoming']); + ok ($size_hash->{$runfolder_path} == $size, 'the run folder size is stable'); + ok (!$monitor->is_onboard_analysis_output_copied(), + 'onboard analysis data is not copied across yet'); + + # Mark DRAGEN analysis as copied across. + open my $fh, q[>], "$dpath/CopyComplete.txt" or die 'Cannot open the file'; + print $fh 'Mark DRAGEN analysis as copied' or die 'Cannot write'; + close $fh or die 'Cannot close the filehandle'; + + $monitor = Monitor::RunFolder::Staging->new( + runfolder_path => $runfolder_path, + npg_tracking_schema => $schema + ); + lives_ok { $done = $monitor->update_run_from_path($size_hash) } 'run the monitor'; + # Sometimes the runfolder size comes out differently at this point, + # and and extra round is needed. + if (!$done) { + $monitor->update_run_from_path($size_hash); + } + ok (!-e $runfolder_path, 'the old run folder path is invalid'); + $runfolder_path = join q[/], $adir, $runfolder_name; + ok (-e $runfolder_path, q[the folder has been moved to 'analysis']); +}; + +1; + + + diff --git a/t/data/dbic_fixtures/100-InstrumentFormat.yml b/t/data/dbic_fixtures/100-InstrumentFormat.yml index bd97d3cb..12010813 100644 --- a/t/data/dbic_fixtures/100-InstrumentFormat.yml +++ b/t/data/dbic_fixtures/100-InstrumentFormat.yml @@ -49,3 +49,9 @@ iscurrent: 1 default_tiles: 0 default_columns: 0 +- id_instrument_format: 14 + id_manufacturer: 10 + model: NovaSeqXPlus + iscurrent: 1 + default_tiles: 0 + default_columns: 0 diff --git a/t/data/dbic_fixtures/200-Instrument.yml b/t/data/dbic_fixtures/200-Instrument.yml index 92ce84a4..28b4927c 100644 --- a/t/data/dbic_fixtures/200-Instrument.yml +++ b/t/data/dbic_fixtures/200-Instrument.yml @@ -126,5 +126,18 @@ staging_dir: latest_contact: percent_complete: - lab: Ogilvie + lab: Ogilvie +- id_instrument: 70 + name: NVX2 + id_instrument_format: 14 + external_name: 'LH00210' + serial: '' + iscurrent: 1 + ipaddr: + instrument_comp: + mirroring_host: + staging_dir: + latest_contact: + percent_complete: + lab: Ogilvie diff --git a/t/data/run_params/RunParameters.novaseqx.onboard.xml b/t/data/run_params/RunParameters.novaseqx.onboard.xml index 959a5ed3..0a072c63 100644 --- a/t/data/run_params/RunParameters.novaseqx.onboard.xml +++ b/t/data/run_params/RunParameters.novaseqx.onboard.xml @@ -13,7 +13,7 @@ 8 10B Sequencing 10B-01.01.00 - 47539 + 47539_NX1_B NovaSeqXSeries B3 NovaSeqXSeriesB3 1.2345678 @@ -60,10 +60,10 @@ - - - - + + + + @@ -76,4 +76,4 @@ - \ No newline at end of file + diff --git a/t/data/test_staging_daemon/novaseqxplus/RunInfo.xml b/t/data/test_staging_daemon/novaseqxplus/RunInfo.xml new file mode 100644 index 00000000..0877d020 --- /dev/null +++ b/t/data/test_staging_daemon/novaseqxplus/RunInfo.xml @@ -0,0 +1,3162 @@ + + + + 225TGJLT3 + LH00210 + 2023-06-28T16:55:32Z + + + + + + + + + + 1_1101 + 1_1102 + 1_1103 + 1_1104 + 1_1105 + 1_1106 + 1_1107 + 1_1108 + 1_1109 + 1_1110 + 1_1111 + 1_1112 + 1_1113 + 1_1114 + 1_1115 + 1_1116 + 1_1117 + 1_1118 + 1_1119 + 1_1120 + 1_1121 + 1_1122 + 1_1123 + 1_1124 + 1_1125 + 1_1126 + 1_1127 + 1_1128 + 1_1129 + 1_1130 + 1_1131 + 1_1132 + 1_1133 + 1_1134 + 1_1135 + 1_1136 + 1_1137 + 1_1138 + 1_1139 + 1_1140 + 1_1141 + 1_1142 + 1_1143 + 1_1144 + 1_1145 + 1_1146 + 1_1147 + 1_1148 + 1_1149 + 1_1150 + 1_1151 + 1_1152 + 1_1153 + 1_1154 + 1_1155 + 1_1156 + 1_1157 + 1_1158 + 1_1159 + 1_1160 + 1_1161 + 1_1162 + 1_1163 + 1_1164 + 1_1165 + 1_1166 + 1_1167 + 1_1168 + 1_1169 + 1_1170 + 1_1171 + 1_1172 + 1_1173 + 1_1174 + 1_1175 + 1_1176 + 1_1177 + 1_1178 + 1_1179 + 1_1180 + 1_1181 + 1_1182 + 1_1183 + 1_1184 + 1_1185 + 1_1186 + 1_1187 + 1_1188 + 1_1189 + 1_1190 + 1_1191 + 1_1192 + 1_1193 + 1_1194 + 1_1195 + 1_1196 + 1_1197 + 1_1198 + 1_1201 + 1_1202 + 1_1203 + 1_1204 + 1_1205 + 1_1206 + 1_1207 + 1_1208 + 1_1209 + 1_1210 + 1_1211 + 1_1212 + 1_1213 + 1_1214 + 1_1215 + 1_1216 + 1_1217 + 1_1218 + 1_1219 + 1_1220 + 1_1221 + 1_1222 + 1_1223 + 1_1224 + 1_1225 + 1_1226 + 1_1227 + 1_1228 + 1_1229 + 1_1230 + 1_1231 + 1_1232 + 1_1233 + 1_1234 + 1_1235 + 1_1236 + 1_1237 + 1_1238 + 1_1239 + 1_1240 + 1_1241 + 1_1242 + 1_1243 + 1_1244 + 1_1245 + 1_1246 + 1_1247 + 1_1248 + 1_1249 + 1_1250 + 1_1251 + 1_1252 + 1_1253 + 1_1254 + 1_1255 + 1_1256 + 1_1257 + 1_1258 + 1_1259 + 1_1260 + 1_1261 + 1_1262 + 1_1263 + 1_1264 + 1_1265 + 1_1266 + 1_1267 + 1_1268 + 1_1269 + 1_1270 + 1_1271 + 1_1272 + 1_1273 + 1_1274 + 1_1275 + 1_1276 + 1_1277 + 1_1278 + 1_1279 + 1_1280 + 1_1281 + 1_1282 + 1_1283 + 1_1284 + 1_1285 + 1_1286 + 1_1287 + 1_1288 + 1_1289 + 1_1290 + 1_1291 + 1_1292 + 1_1293 + 1_1294 + 1_1295 + 1_1296 + 1_1297 + 1_1298 + 2_1101 + 2_1102 + 2_1103 + 2_1104 + 2_1105 + 2_1106 + 2_1107 + 2_1108 + 2_1109 + 2_1110 + 2_1111 + 2_1112 + 2_1113 + 2_1114 + 2_1115 + 2_1116 + 2_1117 + 2_1118 + 2_1119 + 2_1120 + 2_1121 + 2_1122 + 2_1123 + 2_1124 + 2_1125 + 2_1126 + 2_1127 + 2_1128 + 2_1129 + 2_1130 + 2_1131 + 2_1132 + 2_1133 + 2_1134 + 2_1135 + 2_1136 + 2_1137 + 2_1138 + 2_1139 + 2_1140 + 2_1141 + 2_1142 + 2_1143 + 2_1144 + 2_1145 + 2_1146 + 2_1147 + 2_1148 + 2_1149 + 2_1150 + 2_1151 + 2_1152 + 2_1153 + 2_1154 + 2_1155 + 2_1156 + 2_1157 + 2_1158 + 2_1159 + 2_1160 + 2_1161 + 2_1162 + 2_1163 + 2_1164 + 2_1165 + 2_1166 + 2_1167 + 2_1168 + 2_1169 + 2_1170 + 2_1171 + 2_1172 + 2_1173 + 2_1174 + 2_1175 + 2_1176 + 2_1177 + 2_1178 + 2_1179 + 2_1180 + 2_1181 + 2_1182 + 2_1183 + 2_1184 + 2_1185 + 2_1186 + 2_1187 + 2_1188 + 2_1189 + 2_1190 + 2_1191 + 2_1192 + 2_1193 + 2_1194 + 2_1195 + 2_1196 + 2_1197 + 2_1198 + 2_1201 + 2_1202 + 2_1203 + 2_1204 + 2_1205 + 2_1206 + 2_1207 + 2_1208 + 2_1209 + 2_1210 + 2_1211 + 2_1212 + 2_1213 + 2_1214 + 2_1215 + 2_1216 + 2_1217 + 2_1218 + 2_1219 + 2_1220 + 2_1221 + 2_1222 + 2_1223 + 2_1224 + 2_1225 + 2_1226 + 2_1227 + 2_1228 + 2_1229 + 2_1230 + 2_1231 + 2_1232 + 2_1233 + 2_1234 + 2_1235 + 2_1236 + 2_1237 + 2_1238 + 2_1239 + 2_1240 + 2_1241 + 2_1242 + 2_1243 + 2_1244 + 2_1245 + 2_1246 + 2_1247 + 2_1248 + 2_1249 + 2_1250 + 2_1251 + 2_1252 + 2_1253 + 2_1254 + 2_1255 + 2_1256 + 2_1257 + 2_1258 + 2_1259 + 2_1260 + 2_1261 + 2_1262 + 2_1263 + 2_1264 + 2_1265 + 2_1266 + 2_1267 + 2_1268 + 2_1269 + 2_1270 + 2_1271 + 2_1272 + 2_1273 + 2_1274 + 2_1275 + 2_1276 + 2_1277 + 2_1278 + 2_1279 + 2_1280 + 2_1281 + 2_1282 + 2_1283 + 2_1284 + 2_1285 + 2_1286 + 2_1287 + 2_1288 + 2_1289 + 2_1290 + 2_1291 + 2_1292 + 2_1293 + 2_1294 + 2_1295 + 2_1296 + 2_1297 + 2_1298 + 3_1101 + 3_1102 + 3_1103 + 3_1104 + 3_1105 + 3_1106 + 3_1107 + 3_1108 + 3_1109 + 3_1110 + 3_1111 + 3_1112 + 3_1113 + 3_1114 + 3_1115 + 3_1116 + 3_1117 + 3_1118 + 3_1119 + 3_1120 + 3_1121 + 3_1122 + 3_1123 + 3_1124 + 3_1125 + 3_1126 + 3_1127 + 3_1128 + 3_1129 + 3_1130 + 3_1131 + 3_1132 + 3_1133 + 3_1134 + 3_1135 + 3_1136 + 3_1137 + 3_1138 + 3_1139 + 3_1140 + 3_1141 + 3_1142 + 3_1143 + 3_1144 + 3_1145 + 3_1146 + 3_1147 + 3_1148 + 3_1149 + 3_1150 + 3_1151 + 3_1152 + 3_1153 + 3_1154 + 3_1155 + 3_1156 + 3_1157 + 3_1158 + 3_1159 + 3_1160 + 3_1161 + 3_1162 + 3_1163 + 3_1164 + 3_1165 + 3_1166 + 3_1167 + 3_1168 + 3_1169 + 3_1170 + 3_1171 + 3_1172 + 3_1173 + 3_1174 + 3_1175 + 3_1176 + 3_1177 + 3_1178 + 3_1179 + 3_1180 + 3_1181 + 3_1182 + 3_1183 + 3_1184 + 3_1185 + 3_1186 + 3_1187 + 3_1188 + 3_1189 + 3_1190 + 3_1191 + 3_1192 + 3_1193 + 3_1194 + 3_1195 + 3_1196 + 3_1197 + 3_1198 + 3_1201 + 3_1202 + 3_1203 + 3_1204 + 3_1205 + 3_1206 + 3_1207 + 3_1208 + 3_1209 + 3_1210 + 3_1211 + 3_1212 + 3_1213 + 3_1214 + 3_1215 + 3_1216 + 3_1217 + 3_1218 + 3_1219 + 3_1220 + 3_1221 + 3_1222 + 3_1223 + 3_1224 + 3_1225 + 3_1226 + 3_1227 + 3_1228 + 3_1229 + 3_1230 + 3_1231 + 3_1232 + 3_1233 + 3_1234 + 3_1235 + 3_1236 + 3_1237 + 3_1238 + 3_1239 + 3_1240 + 3_1241 + 3_1242 + 3_1243 + 3_1244 + 3_1245 + 3_1246 + 3_1247 + 3_1248 + 3_1249 + 3_1250 + 3_1251 + 3_1252 + 3_1253 + 3_1254 + 3_1255 + 3_1256 + 3_1257 + 3_1258 + 3_1259 + 3_1260 + 3_1261 + 3_1262 + 3_1263 + 3_1264 + 3_1265 + 3_1266 + 3_1267 + 3_1268 + 3_1269 + 3_1270 + 3_1271 + 3_1272 + 3_1273 + 3_1274 + 3_1275 + 3_1276 + 3_1277 + 3_1278 + 3_1279 + 3_1280 + 3_1281 + 3_1282 + 3_1283 + 3_1284 + 3_1285 + 3_1286 + 3_1287 + 3_1288 + 3_1289 + 3_1290 + 3_1291 + 3_1292 + 3_1293 + 3_1294 + 3_1295 + 3_1296 + 3_1297 + 3_1298 + 4_1101 + 4_1102 + 4_1103 + 4_1104 + 4_1105 + 4_1106 + 4_1107 + 4_1108 + 4_1109 + 4_1110 + 4_1111 + 4_1112 + 4_1113 + 4_1114 + 4_1115 + 4_1116 + 4_1117 + 4_1118 + 4_1119 + 4_1120 + 4_1121 + 4_1122 + 4_1123 + 4_1124 + 4_1125 + 4_1126 + 4_1127 + 4_1128 + 4_1129 + 4_1130 + 4_1131 + 4_1132 + 4_1133 + 4_1134 + 4_1135 + 4_1136 + 4_1137 + 4_1138 + 4_1139 + 4_1140 + 4_1141 + 4_1142 + 4_1143 + 4_1144 + 4_1145 + 4_1146 + 4_1147 + 4_1148 + 4_1149 + 4_1150 + 4_1151 + 4_1152 + 4_1153 + 4_1154 + 4_1155 + 4_1156 + 4_1157 + 4_1158 + 4_1159 + 4_1160 + 4_1161 + 4_1162 + 4_1163 + 4_1164 + 4_1165 + 4_1166 + 4_1167 + 4_1168 + 4_1169 + 4_1170 + 4_1171 + 4_1172 + 4_1173 + 4_1174 + 4_1175 + 4_1176 + 4_1177 + 4_1178 + 4_1179 + 4_1180 + 4_1181 + 4_1182 + 4_1183 + 4_1184 + 4_1185 + 4_1186 + 4_1187 + 4_1188 + 4_1189 + 4_1190 + 4_1191 + 4_1192 + 4_1193 + 4_1194 + 4_1195 + 4_1196 + 4_1197 + 4_1198 + 4_1201 + 4_1202 + 4_1203 + 4_1204 + 4_1205 + 4_1206 + 4_1207 + 4_1208 + 4_1209 + 4_1210 + 4_1211 + 4_1212 + 4_1213 + 4_1214 + 4_1215 + 4_1216 + 4_1217 + 4_1218 + 4_1219 + 4_1220 + 4_1221 + 4_1222 + 4_1223 + 4_1224 + 4_1225 + 4_1226 + 4_1227 + 4_1228 + 4_1229 + 4_1230 + 4_1231 + 4_1232 + 4_1233 + 4_1234 + 4_1235 + 4_1236 + 4_1237 + 4_1238 + 4_1239 + 4_1240 + 4_1241 + 4_1242 + 4_1243 + 4_1244 + 4_1245 + 4_1246 + 4_1247 + 4_1248 + 4_1249 + 4_1250 + 4_1251 + 4_1252 + 4_1253 + 4_1254 + 4_1255 + 4_1256 + 4_1257 + 4_1258 + 4_1259 + 4_1260 + 4_1261 + 4_1262 + 4_1263 + 4_1264 + 4_1265 + 4_1266 + 4_1267 + 4_1268 + 4_1269 + 4_1270 + 4_1271 + 4_1272 + 4_1273 + 4_1274 + 4_1275 + 4_1276 + 4_1277 + 4_1278 + 4_1279 + 4_1280 + 4_1281 + 4_1282 + 4_1283 + 4_1284 + 4_1285 + 4_1286 + 4_1287 + 4_1288 + 4_1289 + 4_1290 + 4_1291 + 4_1292 + 4_1293 + 4_1294 + 4_1295 + 4_1296 + 4_1297 + 4_1298 + 5_1101 + 5_1102 + 5_1103 + 5_1104 + 5_1105 + 5_1106 + 5_1107 + 5_1108 + 5_1109 + 5_1110 + 5_1111 + 5_1112 + 5_1113 + 5_1114 + 5_1115 + 5_1116 + 5_1117 + 5_1118 + 5_1119 + 5_1120 + 5_1121 + 5_1122 + 5_1123 + 5_1124 + 5_1125 + 5_1126 + 5_1127 + 5_1128 + 5_1129 + 5_1130 + 5_1131 + 5_1132 + 5_1133 + 5_1134 + 5_1135 + 5_1136 + 5_1137 + 5_1138 + 5_1139 + 5_1140 + 5_1141 + 5_1142 + 5_1143 + 5_1144 + 5_1145 + 5_1146 + 5_1147 + 5_1148 + 5_1149 + 5_1150 + 5_1151 + 5_1152 + 5_1153 + 5_1154 + 5_1155 + 5_1156 + 5_1157 + 5_1158 + 5_1159 + 5_1160 + 5_1161 + 5_1162 + 5_1163 + 5_1164 + 5_1165 + 5_1166 + 5_1167 + 5_1168 + 5_1169 + 5_1170 + 5_1171 + 5_1172 + 5_1173 + 5_1174 + 5_1175 + 5_1176 + 5_1177 + 5_1178 + 5_1179 + 5_1180 + 5_1181 + 5_1182 + 5_1183 + 5_1184 + 5_1185 + 5_1186 + 5_1187 + 5_1188 + 5_1189 + 5_1190 + 5_1191 + 5_1192 + 5_1193 + 5_1194 + 5_1195 + 5_1196 + 5_1197 + 5_1198 + 5_1201 + 5_1202 + 5_1203 + 5_1204 + 5_1205 + 5_1206 + 5_1207 + 5_1208 + 5_1209 + 5_1210 + 5_1211 + 5_1212 + 5_1213 + 5_1214 + 5_1215 + 5_1216 + 5_1217 + 5_1218 + 5_1219 + 5_1220 + 5_1221 + 5_1222 + 5_1223 + 5_1224 + 5_1225 + 5_1226 + 5_1227 + 5_1228 + 5_1229 + 5_1230 + 5_1231 + 5_1232 + 5_1233 + 5_1234 + 5_1235 + 5_1236 + 5_1237 + 5_1238 + 5_1239 + 5_1240 + 5_1241 + 5_1242 + 5_1243 + 5_1244 + 5_1245 + 5_1246 + 5_1247 + 5_1248 + 5_1249 + 5_1250 + 5_1251 + 5_1252 + 5_1253 + 5_1254 + 5_1255 + 5_1256 + 5_1257 + 5_1258 + 5_1259 + 5_1260 + 5_1261 + 5_1262 + 5_1263 + 5_1264 + 5_1265 + 5_1266 + 5_1267 + 5_1268 + 5_1269 + 5_1270 + 5_1271 + 5_1272 + 5_1273 + 5_1274 + 5_1275 + 5_1276 + 5_1277 + 5_1278 + 5_1279 + 5_1280 + 5_1281 + 5_1282 + 5_1283 + 5_1284 + 5_1285 + 5_1286 + 5_1287 + 5_1288 + 5_1289 + 5_1290 + 5_1291 + 5_1292 + 5_1293 + 5_1294 + 5_1295 + 5_1296 + 5_1297 + 5_1298 + 6_1101 + 6_1102 + 6_1103 + 6_1104 + 6_1105 + 6_1106 + 6_1107 + 6_1108 + 6_1109 + 6_1110 + 6_1111 + 6_1112 + 6_1113 + 6_1114 + 6_1115 + 6_1116 + 6_1117 + 6_1118 + 6_1119 + 6_1120 + 6_1121 + 6_1122 + 6_1123 + 6_1124 + 6_1125 + 6_1126 + 6_1127 + 6_1128 + 6_1129 + 6_1130 + 6_1131 + 6_1132 + 6_1133 + 6_1134 + 6_1135 + 6_1136 + 6_1137 + 6_1138 + 6_1139 + 6_1140 + 6_1141 + 6_1142 + 6_1143 + 6_1144 + 6_1145 + 6_1146 + 6_1147 + 6_1148 + 6_1149 + 6_1150 + 6_1151 + 6_1152 + 6_1153 + 6_1154 + 6_1155 + 6_1156 + 6_1157 + 6_1158 + 6_1159 + 6_1160 + 6_1161 + 6_1162 + 6_1163 + 6_1164 + 6_1165 + 6_1166 + 6_1167 + 6_1168 + 6_1169 + 6_1170 + 6_1171 + 6_1172 + 6_1173 + 6_1174 + 6_1175 + 6_1176 + 6_1177 + 6_1178 + 6_1179 + 6_1180 + 6_1181 + 6_1182 + 6_1183 + 6_1184 + 6_1185 + 6_1186 + 6_1187 + 6_1188 + 6_1189 + 6_1190 + 6_1191 + 6_1192 + 6_1193 + 6_1194 + 6_1195 + 6_1196 + 6_1197 + 6_1198 + 6_1201 + 6_1202 + 6_1203 + 6_1204 + 6_1205 + 6_1206 + 6_1207 + 6_1208 + 6_1209 + 6_1210 + 6_1211 + 6_1212 + 6_1213 + 6_1214 + 6_1215 + 6_1216 + 6_1217 + 6_1218 + 6_1219 + 6_1220 + 6_1221 + 6_1222 + 6_1223 + 6_1224 + 6_1225 + 6_1226 + 6_1227 + 6_1228 + 6_1229 + 6_1230 + 6_1231 + 6_1232 + 6_1233 + 6_1234 + 6_1235 + 6_1236 + 6_1237 + 6_1238 + 6_1239 + 6_1240 + 6_1241 + 6_1242 + 6_1243 + 6_1244 + 6_1245 + 6_1246 + 6_1247 + 6_1248 + 6_1249 + 6_1250 + 6_1251 + 6_1252 + 6_1253 + 6_1254 + 6_1255 + 6_1256 + 6_1257 + 6_1258 + 6_1259 + 6_1260 + 6_1261 + 6_1262 + 6_1263 + 6_1264 + 6_1265 + 6_1266 + 6_1267 + 6_1268 + 6_1269 + 6_1270 + 6_1271 + 6_1272 + 6_1273 + 6_1274 + 6_1275 + 6_1276 + 6_1277 + 6_1278 + 6_1279 + 6_1280 + 6_1281 + 6_1282 + 6_1283 + 6_1284 + 6_1285 + 6_1286 + 6_1287 + 6_1288 + 6_1289 + 6_1290 + 6_1291 + 6_1292 + 6_1293 + 6_1294 + 6_1295 + 6_1296 + 6_1297 + 6_1298 + 7_1101 + 7_1102 + 7_1103 + 7_1104 + 7_1105 + 7_1106 + 7_1107 + 7_1108 + 7_1109 + 7_1110 + 7_1111 + 7_1112 + 7_1113 + 7_1114 + 7_1115 + 7_1116 + 7_1117 + 7_1118 + 7_1119 + 7_1120 + 7_1121 + 7_1122 + 7_1123 + 7_1124 + 7_1125 + 7_1126 + 7_1127 + 7_1128 + 7_1129 + 7_1130 + 7_1131 + 7_1132 + 7_1133 + 7_1134 + 7_1135 + 7_1136 + 7_1137 + 7_1138 + 7_1139 + 7_1140 + 7_1141 + 7_1142 + 7_1143 + 7_1144 + 7_1145 + 7_1146 + 7_1147 + 7_1148 + 7_1149 + 7_1150 + 7_1151 + 7_1152 + 7_1153 + 7_1154 + 7_1155 + 7_1156 + 7_1157 + 7_1158 + 7_1159 + 7_1160 + 7_1161 + 7_1162 + 7_1163 + 7_1164 + 7_1165 + 7_1166 + 7_1167 + 7_1168 + 7_1169 + 7_1170 + 7_1171 + 7_1172 + 7_1173 + 7_1174 + 7_1175 + 7_1176 + 7_1177 + 7_1178 + 7_1179 + 7_1180 + 7_1181 + 7_1182 + 7_1183 + 7_1184 + 7_1185 + 7_1186 + 7_1187 + 7_1188 + 7_1189 + 7_1190 + 7_1191 + 7_1192 + 7_1193 + 7_1194 + 7_1195 + 7_1196 + 7_1197 + 7_1198 + 7_1201 + 7_1202 + 7_1203 + 7_1204 + 7_1205 + 7_1206 + 7_1207 + 7_1208 + 7_1209 + 7_1210 + 7_1211 + 7_1212 + 7_1213 + 7_1214 + 7_1215 + 7_1216 + 7_1217 + 7_1218 + 7_1219 + 7_1220 + 7_1221 + 7_1222 + 7_1223 + 7_1224 + 7_1225 + 7_1226 + 7_1227 + 7_1228 + 7_1229 + 7_1230 + 7_1231 + 7_1232 + 7_1233 + 7_1234 + 7_1235 + 7_1236 + 7_1237 + 7_1238 + 7_1239 + 7_1240 + 7_1241 + 7_1242 + 7_1243 + 7_1244 + 7_1245 + 7_1246 + 7_1247 + 7_1248 + 7_1249 + 7_1250 + 7_1251 + 7_1252 + 7_1253 + 7_1254 + 7_1255 + 7_1256 + 7_1257 + 7_1258 + 7_1259 + 7_1260 + 7_1261 + 7_1262 + 7_1263 + 7_1264 + 7_1265 + 7_1266 + 7_1267 + 7_1268 + 7_1269 + 7_1270 + 7_1271 + 7_1272 + 7_1273 + 7_1274 + 7_1275 + 7_1276 + 7_1277 + 7_1278 + 7_1279 + 7_1280 + 7_1281 + 7_1282 + 7_1283 + 7_1284 + 7_1285 + 7_1286 + 7_1287 + 7_1288 + 7_1289 + 7_1290 + 7_1291 + 7_1292 + 7_1293 + 7_1294 + 7_1295 + 7_1296 + 7_1297 + 7_1298 + 8_1101 + 8_1102 + 8_1103 + 8_1104 + 8_1105 + 8_1106 + 8_1107 + 8_1108 + 8_1109 + 8_1110 + 8_1111 + 8_1112 + 8_1113 + 8_1114 + 8_1115 + 8_1116 + 8_1117 + 8_1118 + 8_1119 + 8_1120 + 8_1121 + 8_1122 + 8_1123 + 8_1124 + 8_1125 + 8_1126 + 8_1127 + 8_1128 + 8_1129 + 8_1130 + 8_1131 + 8_1132 + 8_1133 + 8_1134 + 8_1135 + 8_1136 + 8_1137 + 8_1138 + 8_1139 + 8_1140 + 8_1141 + 8_1142 + 8_1143 + 8_1144 + 8_1145 + 8_1146 + 8_1147 + 8_1148 + 8_1149 + 8_1150 + 8_1151 + 8_1152 + 8_1153 + 8_1154 + 8_1155 + 8_1156 + 8_1157 + 8_1158 + 8_1159 + 8_1160 + 8_1161 + 8_1162 + 8_1163 + 8_1164 + 8_1165 + 8_1166 + 8_1167 + 8_1168 + 8_1169 + 8_1170 + 8_1171 + 8_1172 + 8_1173 + 8_1174 + 8_1175 + 8_1176 + 8_1177 + 8_1178 + 8_1179 + 8_1180 + 8_1181 + 8_1182 + 8_1183 + 8_1184 + 8_1185 + 8_1186 + 8_1187 + 8_1188 + 8_1189 + 8_1190 + 8_1191 + 8_1192 + 8_1193 + 8_1194 + 8_1195 + 8_1196 + 8_1197 + 8_1198 + 8_1201 + 8_1202 + 8_1203 + 8_1204 + 8_1205 + 8_1206 + 8_1207 + 8_1208 + 8_1209 + 8_1210 + 8_1211 + 8_1212 + 8_1213 + 8_1214 + 8_1215 + 8_1216 + 8_1217 + 8_1218 + 8_1219 + 8_1220 + 8_1221 + 8_1222 + 8_1223 + 8_1224 + 8_1225 + 8_1226 + 8_1227 + 8_1228 + 8_1229 + 8_1230 + 8_1231 + 8_1232 + 8_1233 + 8_1234 + 8_1235 + 8_1236 + 8_1237 + 8_1238 + 8_1239 + 8_1240 + 8_1241 + 8_1242 + 8_1243 + 8_1244 + 8_1245 + 8_1246 + 8_1247 + 8_1248 + 8_1249 + 8_1250 + 8_1251 + 8_1252 + 8_1253 + 8_1254 + 8_1255 + 8_1256 + 8_1257 + 8_1258 + 8_1259 + 8_1260 + 8_1261 + 8_1262 + 8_1263 + 8_1264 + 8_1265 + 8_1266 + 8_1267 + 8_1268 + 8_1269 + 8_1270 + 8_1271 + 8_1272 + 8_1273 + 8_1274 + 8_1275 + 8_1276 + 8_1277 + 8_1278 + 8_1279 + 8_1280 + 8_1281 + 8_1282 + 8_1283 + 8_1284 + 8_1285 + 8_1286 + 8_1287 + 8_1288 + 8_1289 + 8_1290 + 8_1291 + 8_1292 + 8_1293 + 8_1294 + 8_1295 + 8_1296 + 8_1297 + 8_1298 + 1_2101 + 1_2102 + 1_2103 + 1_2104 + 1_2105 + 1_2106 + 1_2107 + 1_2108 + 1_2109 + 1_2110 + 1_2111 + 1_2112 + 1_2113 + 1_2114 + 1_2115 + 1_2116 + 1_2117 + 1_2118 + 1_2119 + 1_2120 + 1_2121 + 1_2122 + 1_2123 + 1_2124 + 1_2125 + 1_2126 + 1_2127 + 1_2128 + 1_2129 + 1_2130 + 1_2131 + 1_2132 + 1_2133 + 1_2134 + 1_2135 + 1_2136 + 1_2137 + 1_2138 + 1_2139 + 1_2140 + 1_2141 + 1_2142 + 1_2143 + 1_2144 + 1_2145 + 1_2146 + 1_2147 + 1_2148 + 1_2149 + 1_2150 + 1_2151 + 1_2152 + 1_2153 + 1_2154 + 1_2155 + 1_2156 + 1_2157 + 1_2158 + 1_2159 + 1_2160 + 1_2161 + 1_2162 + 1_2163 + 1_2164 + 1_2165 + 1_2166 + 1_2167 + 1_2168 + 1_2169 + 1_2170 + 1_2171 + 1_2172 + 1_2173 + 1_2174 + 1_2175 + 1_2176 + 1_2177 + 1_2178 + 1_2179 + 1_2180 + 1_2181 + 1_2182 + 1_2183 + 1_2184 + 1_2185 + 1_2186 + 1_2187 + 1_2188 + 1_2189 + 1_2190 + 1_2191 + 1_2192 + 1_2193 + 1_2194 + 1_2195 + 1_2196 + 1_2197 + 1_2198 + 1_2201 + 1_2202 + 1_2203 + 1_2204 + 1_2205 + 1_2206 + 1_2207 + 1_2208 + 1_2209 + 1_2210 + 1_2211 + 1_2212 + 1_2213 + 1_2214 + 1_2215 + 1_2216 + 1_2217 + 1_2218 + 1_2219 + 1_2220 + 1_2221 + 1_2222 + 1_2223 + 1_2224 + 1_2225 + 1_2226 + 1_2227 + 1_2228 + 1_2229 + 1_2230 + 1_2231 + 1_2232 + 1_2233 + 1_2234 + 1_2235 + 1_2236 + 1_2237 + 1_2238 + 1_2239 + 1_2240 + 1_2241 + 1_2242 + 1_2243 + 1_2244 + 1_2245 + 1_2246 + 1_2247 + 1_2248 + 1_2249 + 1_2250 + 1_2251 + 1_2252 + 1_2253 + 1_2254 + 1_2255 + 1_2256 + 1_2257 + 1_2258 + 1_2259 + 1_2260 + 1_2261 + 1_2262 + 1_2263 + 1_2264 + 1_2265 + 1_2266 + 1_2267 + 1_2268 + 1_2269 + 1_2270 + 1_2271 + 1_2272 + 1_2273 + 1_2274 + 1_2275 + 1_2276 + 1_2277 + 1_2278 + 1_2279 + 1_2280 + 1_2281 + 1_2282 + 1_2283 + 1_2284 + 1_2285 + 1_2286 + 1_2287 + 1_2288 + 1_2289 + 1_2290 + 1_2291 + 1_2292 + 1_2293 + 1_2294 + 1_2295 + 1_2296 + 1_2297 + 1_2298 + 2_2101 + 2_2102 + 2_2103 + 2_2104 + 2_2105 + 2_2106 + 2_2107 + 2_2108 + 2_2109 + 2_2110 + 2_2111 + 2_2112 + 2_2113 + 2_2114 + 2_2115 + 2_2116 + 2_2117 + 2_2118 + 2_2119 + 2_2120 + 2_2121 + 2_2122 + 2_2123 + 2_2124 + 2_2125 + 2_2126 + 2_2127 + 2_2128 + 2_2129 + 2_2130 + 2_2131 + 2_2132 + 2_2133 + 2_2134 + 2_2135 + 2_2136 + 2_2137 + 2_2138 + 2_2139 + 2_2140 + 2_2141 + 2_2142 + 2_2143 + 2_2144 + 2_2145 + 2_2146 + 2_2147 + 2_2148 + 2_2149 + 2_2150 + 2_2151 + 2_2152 + 2_2153 + 2_2154 + 2_2155 + 2_2156 + 2_2157 + 2_2158 + 2_2159 + 2_2160 + 2_2161 + 2_2162 + 2_2163 + 2_2164 + 2_2165 + 2_2166 + 2_2167 + 2_2168 + 2_2169 + 2_2170 + 2_2171 + 2_2172 + 2_2173 + 2_2174 + 2_2175 + 2_2176 + 2_2177 + 2_2178 + 2_2179 + 2_2180 + 2_2181 + 2_2182 + 2_2183 + 2_2184 + 2_2185 + 2_2186 + 2_2187 + 2_2188 + 2_2189 + 2_2190 + 2_2191 + 2_2192 + 2_2193 + 2_2194 + 2_2195 + 2_2196 + 2_2197 + 2_2198 + 2_2201 + 2_2202 + 2_2203 + 2_2204 + 2_2205 + 2_2206 + 2_2207 + 2_2208 + 2_2209 + 2_2210 + 2_2211 + 2_2212 + 2_2213 + 2_2214 + 2_2215 + 2_2216 + 2_2217 + 2_2218 + 2_2219 + 2_2220 + 2_2221 + 2_2222 + 2_2223 + 2_2224 + 2_2225 + 2_2226 + 2_2227 + 2_2228 + 2_2229 + 2_2230 + 2_2231 + 2_2232 + 2_2233 + 2_2234 + 2_2235 + 2_2236 + 2_2237 + 2_2238 + 2_2239 + 2_2240 + 2_2241 + 2_2242 + 2_2243 + 2_2244 + 2_2245 + 2_2246 + 2_2247 + 2_2248 + 2_2249 + 2_2250 + 2_2251 + 2_2252 + 2_2253 + 2_2254 + 2_2255 + 2_2256 + 2_2257 + 2_2258 + 2_2259 + 2_2260 + 2_2261 + 2_2262 + 2_2263 + 2_2264 + 2_2265 + 2_2266 + 2_2267 + 2_2268 + 2_2269 + 2_2270 + 2_2271 + 2_2272 + 2_2273 + 2_2274 + 2_2275 + 2_2276 + 2_2277 + 2_2278 + 2_2279 + 2_2280 + 2_2281 + 2_2282 + 2_2283 + 2_2284 + 2_2285 + 2_2286 + 2_2287 + 2_2288 + 2_2289 + 2_2290 + 2_2291 + 2_2292 + 2_2293 + 2_2294 + 2_2295 + 2_2296 + 2_2297 + 2_2298 + 3_2101 + 3_2102 + 3_2103 + 3_2104 + 3_2105 + 3_2106 + 3_2107 + 3_2108 + 3_2109 + 3_2110 + 3_2111 + 3_2112 + 3_2113 + 3_2114 + 3_2115 + 3_2116 + 3_2117 + 3_2118 + 3_2119 + 3_2120 + 3_2121 + 3_2122 + 3_2123 + 3_2124 + 3_2125 + 3_2126 + 3_2127 + 3_2128 + 3_2129 + 3_2130 + 3_2131 + 3_2132 + 3_2133 + 3_2134 + 3_2135 + 3_2136 + 3_2137 + 3_2138 + 3_2139 + 3_2140 + 3_2141 + 3_2142 + 3_2143 + 3_2144 + 3_2145 + 3_2146 + 3_2147 + 3_2148 + 3_2149 + 3_2150 + 3_2151 + 3_2152 + 3_2153 + 3_2154 + 3_2155 + 3_2156 + 3_2157 + 3_2158 + 3_2159 + 3_2160 + 3_2161 + 3_2162 + 3_2163 + 3_2164 + 3_2165 + 3_2166 + 3_2167 + 3_2168 + 3_2169 + 3_2170 + 3_2171 + 3_2172 + 3_2173 + 3_2174 + 3_2175 + 3_2176 + 3_2177 + 3_2178 + 3_2179 + 3_2180 + 3_2181 + 3_2182 + 3_2183 + 3_2184 + 3_2185 + 3_2186 + 3_2187 + 3_2188 + 3_2189 + 3_2190 + 3_2191 + 3_2192 + 3_2193 + 3_2194 + 3_2195 + 3_2196 + 3_2197 + 3_2198 + 3_2201 + 3_2202 + 3_2203 + 3_2204 + 3_2205 + 3_2206 + 3_2207 + 3_2208 + 3_2209 + 3_2210 + 3_2211 + 3_2212 + 3_2213 + 3_2214 + 3_2215 + 3_2216 + 3_2217 + 3_2218 + 3_2219 + 3_2220 + 3_2221 + 3_2222 + 3_2223 + 3_2224 + 3_2225 + 3_2226 + 3_2227 + 3_2228 + 3_2229 + 3_2230 + 3_2231 + 3_2232 + 3_2233 + 3_2234 + 3_2235 + 3_2236 + 3_2237 + 3_2238 + 3_2239 + 3_2240 + 3_2241 + 3_2242 + 3_2243 + 3_2244 + 3_2245 + 3_2246 + 3_2247 + 3_2248 + 3_2249 + 3_2250 + 3_2251 + 3_2252 + 3_2253 + 3_2254 + 3_2255 + 3_2256 + 3_2257 + 3_2258 + 3_2259 + 3_2260 + 3_2261 + 3_2262 + 3_2263 + 3_2264 + 3_2265 + 3_2266 + 3_2267 + 3_2268 + 3_2269 + 3_2270 + 3_2271 + 3_2272 + 3_2273 + 3_2274 + 3_2275 + 3_2276 + 3_2277 + 3_2278 + 3_2279 + 3_2280 + 3_2281 + 3_2282 + 3_2283 + 3_2284 + 3_2285 + 3_2286 + 3_2287 + 3_2288 + 3_2289 + 3_2290 + 3_2291 + 3_2292 + 3_2293 + 3_2294 + 3_2295 + 3_2296 + 3_2297 + 3_2298 + 4_2101 + 4_2102 + 4_2103 + 4_2104 + 4_2105 + 4_2106 + 4_2107 + 4_2108 + 4_2109 + 4_2110 + 4_2111 + 4_2112 + 4_2113 + 4_2114 + 4_2115 + 4_2116 + 4_2117 + 4_2118 + 4_2119 + 4_2120 + 4_2121 + 4_2122 + 4_2123 + 4_2124 + 4_2125 + 4_2126 + 4_2127 + 4_2128 + 4_2129 + 4_2130 + 4_2131 + 4_2132 + 4_2133 + 4_2134 + 4_2135 + 4_2136 + 4_2137 + 4_2138 + 4_2139 + 4_2140 + 4_2141 + 4_2142 + 4_2143 + 4_2144 + 4_2145 + 4_2146 + 4_2147 + 4_2148 + 4_2149 + 4_2150 + 4_2151 + 4_2152 + 4_2153 + 4_2154 + 4_2155 + 4_2156 + 4_2157 + 4_2158 + 4_2159 + 4_2160 + 4_2161 + 4_2162 + 4_2163 + 4_2164 + 4_2165 + 4_2166 + 4_2167 + 4_2168 + 4_2169 + 4_2170 + 4_2171 + 4_2172 + 4_2173 + 4_2174 + 4_2175 + 4_2176 + 4_2177 + 4_2178 + 4_2179 + 4_2180 + 4_2181 + 4_2182 + 4_2183 + 4_2184 + 4_2185 + 4_2186 + 4_2187 + 4_2188 + 4_2189 + 4_2190 + 4_2191 + 4_2192 + 4_2193 + 4_2194 + 4_2195 + 4_2196 + 4_2197 + 4_2198 + 4_2201 + 4_2202 + 4_2203 + 4_2204 + 4_2205 + 4_2206 + 4_2207 + 4_2208 + 4_2209 + 4_2210 + 4_2211 + 4_2212 + 4_2213 + 4_2214 + 4_2215 + 4_2216 + 4_2217 + 4_2218 + 4_2219 + 4_2220 + 4_2221 + 4_2222 + 4_2223 + 4_2224 + 4_2225 + 4_2226 + 4_2227 + 4_2228 + 4_2229 + 4_2230 + 4_2231 + 4_2232 + 4_2233 + 4_2234 + 4_2235 + 4_2236 + 4_2237 + 4_2238 + 4_2239 + 4_2240 + 4_2241 + 4_2242 + 4_2243 + 4_2244 + 4_2245 + 4_2246 + 4_2247 + 4_2248 + 4_2249 + 4_2250 + 4_2251 + 4_2252 + 4_2253 + 4_2254 + 4_2255 + 4_2256 + 4_2257 + 4_2258 + 4_2259 + 4_2260 + 4_2261 + 4_2262 + 4_2263 + 4_2264 + 4_2265 + 4_2266 + 4_2267 + 4_2268 + 4_2269 + 4_2270 + 4_2271 + 4_2272 + 4_2273 + 4_2274 + 4_2275 + 4_2276 + 4_2277 + 4_2278 + 4_2279 + 4_2280 + 4_2281 + 4_2282 + 4_2283 + 4_2284 + 4_2285 + 4_2286 + 4_2287 + 4_2288 + 4_2289 + 4_2290 + 4_2291 + 4_2292 + 4_2293 + 4_2294 + 4_2295 + 4_2296 + 4_2297 + 4_2298 + 5_2101 + 5_2102 + 5_2103 + 5_2104 + 5_2105 + 5_2106 + 5_2107 + 5_2108 + 5_2109 + 5_2110 + 5_2111 + 5_2112 + 5_2113 + 5_2114 + 5_2115 + 5_2116 + 5_2117 + 5_2118 + 5_2119 + 5_2120 + 5_2121 + 5_2122 + 5_2123 + 5_2124 + 5_2125 + 5_2126 + 5_2127 + 5_2128 + 5_2129 + 5_2130 + 5_2131 + 5_2132 + 5_2133 + 5_2134 + 5_2135 + 5_2136 + 5_2137 + 5_2138 + 5_2139 + 5_2140 + 5_2141 + 5_2142 + 5_2143 + 5_2144 + 5_2145 + 5_2146 + 5_2147 + 5_2148 + 5_2149 + 5_2150 + 5_2151 + 5_2152 + 5_2153 + 5_2154 + 5_2155 + 5_2156 + 5_2157 + 5_2158 + 5_2159 + 5_2160 + 5_2161 + 5_2162 + 5_2163 + 5_2164 + 5_2165 + 5_2166 + 5_2167 + 5_2168 + 5_2169 + 5_2170 + 5_2171 + 5_2172 + 5_2173 + 5_2174 + 5_2175 + 5_2176 + 5_2177 + 5_2178 + 5_2179 + 5_2180 + 5_2181 + 5_2182 + 5_2183 + 5_2184 + 5_2185 + 5_2186 + 5_2187 + 5_2188 + 5_2189 + 5_2190 + 5_2191 + 5_2192 + 5_2193 + 5_2194 + 5_2195 + 5_2196 + 5_2197 + 5_2198 + 5_2201 + 5_2202 + 5_2203 + 5_2204 + 5_2205 + 5_2206 + 5_2207 + 5_2208 + 5_2209 + 5_2210 + 5_2211 + 5_2212 + 5_2213 + 5_2214 + 5_2215 + 5_2216 + 5_2217 + 5_2218 + 5_2219 + 5_2220 + 5_2221 + 5_2222 + 5_2223 + 5_2224 + 5_2225 + 5_2226 + 5_2227 + 5_2228 + 5_2229 + 5_2230 + 5_2231 + 5_2232 + 5_2233 + 5_2234 + 5_2235 + 5_2236 + 5_2237 + 5_2238 + 5_2239 + 5_2240 + 5_2241 + 5_2242 + 5_2243 + 5_2244 + 5_2245 + 5_2246 + 5_2247 + 5_2248 + 5_2249 + 5_2250 + 5_2251 + 5_2252 + 5_2253 + 5_2254 + 5_2255 + 5_2256 + 5_2257 + 5_2258 + 5_2259 + 5_2260 + 5_2261 + 5_2262 + 5_2263 + 5_2264 + 5_2265 + 5_2266 + 5_2267 + 5_2268 + 5_2269 + 5_2270 + 5_2271 + 5_2272 + 5_2273 + 5_2274 + 5_2275 + 5_2276 + 5_2277 + 5_2278 + 5_2279 + 5_2280 + 5_2281 + 5_2282 + 5_2283 + 5_2284 + 5_2285 + 5_2286 + 5_2287 + 5_2288 + 5_2289 + 5_2290 + 5_2291 + 5_2292 + 5_2293 + 5_2294 + 5_2295 + 5_2296 + 5_2297 + 5_2298 + 6_2101 + 6_2102 + 6_2103 + 6_2104 + 6_2105 + 6_2106 + 6_2107 + 6_2108 + 6_2109 + 6_2110 + 6_2111 + 6_2112 + 6_2113 + 6_2114 + 6_2115 + 6_2116 + 6_2117 + 6_2118 + 6_2119 + 6_2120 + 6_2121 + 6_2122 + 6_2123 + 6_2124 + 6_2125 + 6_2126 + 6_2127 + 6_2128 + 6_2129 + 6_2130 + 6_2131 + 6_2132 + 6_2133 + 6_2134 + 6_2135 + 6_2136 + 6_2137 + 6_2138 + 6_2139 + 6_2140 + 6_2141 + 6_2142 + 6_2143 + 6_2144 + 6_2145 + 6_2146 + 6_2147 + 6_2148 + 6_2149 + 6_2150 + 6_2151 + 6_2152 + 6_2153 + 6_2154 + 6_2155 + 6_2156 + 6_2157 + 6_2158 + 6_2159 + 6_2160 + 6_2161 + 6_2162 + 6_2163 + 6_2164 + 6_2165 + 6_2166 + 6_2167 + 6_2168 + 6_2169 + 6_2170 + 6_2171 + 6_2172 + 6_2173 + 6_2174 + 6_2175 + 6_2176 + 6_2177 + 6_2178 + 6_2179 + 6_2180 + 6_2181 + 6_2182 + 6_2183 + 6_2184 + 6_2185 + 6_2186 + 6_2187 + 6_2188 + 6_2189 + 6_2190 + 6_2191 + 6_2192 + 6_2193 + 6_2194 + 6_2195 + 6_2196 + 6_2197 + 6_2198 + 6_2201 + 6_2202 + 6_2203 + 6_2204 + 6_2205 + 6_2206 + 6_2207 + 6_2208 + 6_2209 + 6_2210 + 6_2211 + 6_2212 + 6_2213 + 6_2214 + 6_2215 + 6_2216 + 6_2217 + 6_2218 + 6_2219 + 6_2220 + 6_2221 + 6_2222 + 6_2223 + 6_2224 + 6_2225 + 6_2226 + 6_2227 + 6_2228 + 6_2229 + 6_2230 + 6_2231 + 6_2232 + 6_2233 + 6_2234 + 6_2235 + 6_2236 + 6_2237 + 6_2238 + 6_2239 + 6_2240 + 6_2241 + 6_2242 + 6_2243 + 6_2244 + 6_2245 + 6_2246 + 6_2247 + 6_2248 + 6_2249 + 6_2250 + 6_2251 + 6_2252 + 6_2253 + 6_2254 + 6_2255 + 6_2256 + 6_2257 + 6_2258 + 6_2259 + 6_2260 + 6_2261 + 6_2262 + 6_2263 + 6_2264 + 6_2265 + 6_2266 + 6_2267 + 6_2268 + 6_2269 + 6_2270 + 6_2271 + 6_2272 + 6_2273 + 6_2274 + 6_2275 + 6_2276 + 6_2277 + 6_2278 + 6_2279 + 6_2280 + 6_2281 + 6_2282 + 6_2283 + 6_2284 + 6_2285 + 6_2286 + 6_2287 + 6_2288 + 6_2289 + 6_2290 + 6_2291 + 6_2292 + 6_2293 + 6_2294 + 6_2295 + 6_2296 + 6_2297 + 6_2298 + 7_2101 + 7_2102 + 7_2103 + 7_2104 + 7_2105 + 7_2106 + 7_2107 + 7_2108 + 7_2109 + 7_2110 + 7_2111 + 7_2112 + 7_2113 + 7_2114 + 7_2115 + 7_2116 + 7_2117 + 7_2118 + 7_2119 + 7_2120 + 7_2121 + 7_2122 + 7_2123 + 7_2124 + 7_2125 + 7_2126 + 7_2127 + 7_2128 + 7_2129 + 7_2130 + 7_2131 + 7_2132 + 7_2133 + 7_2134 + 7_2135 + 7_2136 + 7_2137 + 7_2138 + 7_2139 + 7_2140 + 7_2141 + 7_2142 + 7_2143 + 7_2144 + 7_2145 + 7_2146 + 7_2147 + 7_2148 + 7_2149 + 7_2150 + 7_2151 + 7_2152 + 7_2153 + 7_2154 + 7_2155 + 7_2156 + 7_2157 + 7_2158 + 7_2159 + 7_2160 + 7_2161 + 7_2162 + 7_2163 + 7_2164 + 7_2165 + 7_2166 + 7_2167 + 7_2168 + 7_2169 + 7_2170 + 7_2171 + 7_2172 + 7_2173 + 7_2174 + 7_2175 + 7_2176 + 7_2177 + 7_2178 + 7_2179 + 7_2180 + 7_2181 + 7_2182 + 7_2183 + 7_2184 + 7_2185 + 7_2186 + 7_2187 + 7_2188 + 7_2189 + 7_2190 + 7_2191 + 7_2192 + 7_2193 + 7_2194 + 7_2195 + 7_2196 + 7_2197 + 7_2198 + 7_2201 + 7_2202 + 7_2203 + 7_2204 + 7_2205 + 7_2206 + 7_2207 + 7_2208 + 7_2209 + 7_2210 + 7_2211 + 7_2212 + 7_2213 + 7_2214 + 7_2215 + 7_2216 + 7_2217 + 7_2218 + 7_2219 + 7_2220 + 7_2221 + 7_2222 + 7_2223 + 7_2224 + 7_2225 + 7_2226 + 7_2227 + 7_2228 + 7_2229 + 7_2230 + 7_2231 + 7_2232 + 7_2233 + 7_2234 + 7_2235 + 7_2236 + 7_2237 + 7_2238 + 7_2239 + 7_2240 + 7_2241 + 7_2242 + 7_2243 + 7_2244 + 7_2245 + 7_2246 + 7_2247 + 7_2248 + 7_2249 + 7_2250 + 7_2251 + 7_2252 + 7_2253 + 7_2254 + 7_2255 + 7_2256 + 7_2257 + 7_2258 + 7_2259 + 7_2260 + 7_2261 + 7_2262 + 7_2263 + 7_2264 + 7_2265 + 7_2266 + 7_2267 + 7_2268 + 7_2269 + 7_2270 + 7_2271 + 7_2272 + 7_2273 + 7_2274 + 7_2275 + 7_2276 + 7_2277 + 7_2278 + 7_2279 + 7_2280 + 7_2281 + 7_2282 + 7_2283 + 7_2284 + 7_2285 + 7_2286 + 7_2287 + 7_2288 + 7_2289 + 7_2290 + 7_2291 + 7_2292 + 7_2293 + 7_2294 + 7_2295 + 7_2296 + 7_2297 + 7_2298 + 8_2101 + 8_2102 + 8_2103 + 8_2104 + 8_2105 + 8_2106 + 8_2107 + 8_2108 + 8_2109 + 8_2110 + 8_2111 + 8_2112 + 8_2113 + 8_2114 + 8_2115 + 8_2116 + 8_2117 + 8_2118 + 8_2119 + 8_2120 + 8_2121 + 8_2122 + 8_2123 + 8_2124 + 8_2125 + 8_2126 + 8_2127 + 8_2128 + 8_2129 + 8_2130 + 8_2131 + 8_2132 + 8_2133 + 8_2134 + 8_2135 + 8_2136 + 8_2137 + 8_2138 + 8_2139 + 8_2140 + 8_2141 + 8_2142 + 8_2143 + 8_2144 + 8_2145 + 8_2146 + 8_2147 + 8_2148 + 8_2149 + 8_2150 + 8_2151 + 8_2152 + 8_2153 + 8_2154 + 8_2155 + 8_2156 + 8_2157 + 8_2158 + 8_2159 + 8_2160 + 8_2161 + 8_2162 + 8_2163 + 8_2164 + 8_2165 + 8_2166 + 8_2167 + 8_2168 + 8_2169 + 8_2170 + 8_2171 + 8_2172 + 8_2173 + 8_2174 + 8_2175 + 8_2176 + 8_2177 + 8_2178 + 8_2179 + 8_2180 + 8_2181 + 8_2182 + 8_2183 + 8_2184 + 8_2185 + 8_2186 + 8_2187 + 8_2188 + 8_2189 + 8_2190 + 8_2191 + 8_2192 + 8_2193 + 8_2194 + 8_2195 + 8_2196 + 8_2197 + 8_2198 + 8_2201 + 8_2202 + 8_2203 + 8_2204 + 8_2205 + 8_2206 + 8_2207 + 8_2208 + 8_2209 + 8_2210 + 8_2211 + 8_2212 + 8_2213 + 8_2214 + 8_2215 + 8_2216 + 8_2217 + 8_2218 + 8_2219 + 8_2220 + 8_2221 + 8_2222 + 8_2223 + 8_2224 + 8_2225 + 8_2226 + 8_2227 + 8_2228 + 8_2229 + 8_2230 + 8_2231 + 8_2232 + 8_2233 + 8_2234 + 8_2235 + 8_2236 + 8_2237 + 8_2238 + 8_2239 + 8_2240 + 8_2241 + 8_2242 + 8_2243 + 8_2244 + 8_2245 + 8_2246 + 8_2247 + 8_2248 + 8_2249 + 8_2250 + 8_2251 + 8_2252 + 8_2253 + 8_2254 + 8_2255 + 8_2256 + 8_2257 + 8_2258 + 8_2259 + 8_2260 + 8_2261 + 8_2262 + 8_2263 + 8_2264 + 8_2265 + 8_2266 + 8_2267 + 8_2268 + 8_2269 + 8_2270 + 8_2271 + 8_2272 + 8_2273 + 8_2274 + 8_2275 + 8_2276 + 8_2277 + 8_2278 + 8_2279 + 8_2280 + 8_2281 + 8_2282 + 8_2283 + 8_2284 + 8_2285 + 8_2286 + 8_2287 + 8_2288 + 8_2289 + 8_2290 + 8_2291 + 8_2292 + 8_2293 + 8_2294 + 8_2295 + 8_2296 + 8_2297 + 8_2298 + + + + + + blue + green + + + + diff --git a/t/data/test_staging_daemon/novaseqxplus/RunParameters.xml b/t/data/test_staging_daemon/novaseqxplus/RunParameters.xml new file mode 100644 index 00000000..356aed39 --- /dev/null +++ b/t/data/test_staging_daemon/novaseqxplus/RunParameters.xml @@ -0,0 +1,68 @@ + + + B + control-software + 1.1.0.18335 + //nx1-esa.dnapipelines.sanger.ac.uk/staging/IL_seq_data/incoming/20230628_LH00210_0008_B225TGJLT3 + InstrumentPerformance + LocalOrchestrated + LocalAnalysis + NovaSeqXPlus + LH00210 + 20230628_LH00210_0008_B225TGJLT3 + 8 + 10B Sequencing + 10B-01.01.00 + 47539 + NovaSeqXSeries B3 + NovaSeqXSeriesB3 + 1.2345678 + + + 225TGJLT3 + 20750642 + 20080370 + 2024-04-09T00:00:00+01:00 + FlowCell + 10B + + + LC4009058-LC3 + 20740727 + 20066614 + 2024-03-27T00:00:00Z + Reagent + 10B + + + LC2304140485-1 + 23041301 + 20089853 + 2024-07-13T00:00:00+01:00 + Buffer + 10B + + + LC1009924-LC1 + 1000017597 + 20072271 + 2024-04-08T00:00:00+01:00 + SampleTube + 10B + + + LC2007014-LC1 + 17847282 + 20081650 + 2024-02-13T00:00:00Z + Lyo + 10B + + + + + + + + + From 1f77a63338dabcca7e2dc8e9d0275186e2dd4a49 Mon Sep 17 00:00:00 2001 From: jmtcsngr Date: Wed, 26 Jul 2023 13:04:04 +0100 Subject: [PATCH 18/18] prep release 96.0.0 --- Changes | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Changes b/Changes index aa2e7b13..319702e2 100644 --- a/Changes +++ b/Changes @@ -1,7 +1,16 @@ LIST OF CHANGES +release 96.0.0 - Fixed a regression in the npg_move_runfolder script, which made it unusable. + - Rejig run folder tracking function into method + - Stop using XML LIMS data in a test + - Import samplesheet daemon + - Ensure we have a loader to generate ORM classes + - Flagged planned onboard analysis + - locate_runfolder: simplify, cope with complex globs, link page for multiple + locations + - Allow NovaSeqX samplesheets to embed instrument and slot release 95.0.0 - Remove singularity recipe and related files