Skip to content

Commit

Permalink
refactored to dry out code
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewsparkes committed Jan 29, 2024
1 parent f771d48 commit 220278e
Show file tree
Hide file tree
Showing 22 changed files with 416 additions and 450 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# frozen_string_literal: true

# Part of the Labware creator classes
module LabwareCreators
require_dependency 'labware_creators/pcr_cycles_binned_plate/csv_file_for_duplex_seq'

module PcrCyclesBinnedPlate::CsvFile
#
# This version of the row is for the Duplex Seq pipeline.
#
class DuplexSeq::Row < RowBase
include ActiveModel::Validations

SUB_POOL_NOT_BLANK = 'has a value when Submit for Sequencing is N, it should be empty, in %s'
SUBMIT_FOR_SEQ_INVALID = 'is empty or has an unrecognised value (should be Y or N), in %s'
COVERAGE_MISSING = 'is missing but should be present when Submit for Sequencing is Y, in %s'
COVERAGE_NEGATIVE = 'is negative but should be a positive value, in %s'

attr_reader :submit_for_sequencing, :sub_pool, :coverage

validate :submit_for_sequencing_has_expected_value?
validate :sub_pool_within_expected_range?
validates :coverage,
presence: {
message: ->(object, _data) { COVERAGE_MISSING % object }
},
numericality: {
greater_than: 0,
message: ->(object, _data) { COVERAGE_NEGATIVE % object }
},
unless: -> { empty? || !submit_for_sequencing? }

delegate :submit_for_sequencing_column, :sub_pool_column, :coverage_column, to: :header

def initialize_pipeline_specific_columns
@submit_for_sequencing_as_string = @row_data[submit_for_sequencing_column]&.strip&.upcase
@sub_pool = @row_data[sub_pool_column]&.strip&.to_i
@coverage = @row_data[coverage_column]&.strip&.to_i
end

def submit_for_sequencing?
@submit_for_sequencing ||= (@submit_for_sequencing_as_string == 'Y')
end

def submit_for_sequencing_has_expected_value?
return true if empty?

return true if %w[Y N].include? @submit_for_sequencing_as_string

errors.add('submit_for_sequencing', format(SUBMIT_FOR_SEQ_INVALID, to_s))
end

def sub_pool_within_expected_range?
return true if empty?

# check the value is within range when we do expect a value to be present
if submit_for_sequencing?
return in_range?('sub_pool', sub_pool, @row_config.sub_pool_min, @row_config.sub_pool_max)
end

# expect sub-pool field to be blank, possible mistake by user if not
return true if sub_pool.blank?

# sub-pool is NOT blank and should be
errors.add('sub_pool', format(SUB_POOL_NOT_BLANK, to_s))
false
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

# Part of the Labware creator classes
module LabwareCreators
require_dependency 'labware_creators/pcr_cycles_binned_plate/csv_file_for_duplex_seq'

module PcrCyclesBinnedPlate::CsvFile::DuplexSeq
#
# Class WellDetailsHeader provides a simple wrapper for handling and validating
# the plate barcode header row from the customer csv file
#
class WellDetailsHeader < PcrCyclesBinnedPlate::CsvFile::WellDetailsHeaderBase
# Return the index of the respective column.
attr_reader :submit_for_sequencing_column, :sub_pool_column, :coverage_column

SUBMIT_FOR_SEQUENCING_COLUMN = 'Submit for sequencing (Y/N)?'
SUB_POOL_COLUMN = 'Sub-Pool'
COVERAGE_COLUMN = 'Coverage'

validates :submit_for_sequencing_column,
presence: {
message: ->(object, _data) { "could not be found in: '#{object}'" }
}
validates :sub_pool_column, presence: { message: ->(object, _data) { "could not be found in: '#{object}'" } }
validates :coverage_column, presence: { message: ->(object, _data) { "could not be found in: '#{object}'" } }

private

def initialize_pipeline_specific_columns
@submit_for_sequencing_column = index_of_header(SUBMIT_FOR_SEQUENCING_COLUMN)
@sub_pool_column = index_of_header(SUB_POOL_COLUMN)
@coverage_column = index_of_header(COVERAGE_COLUMN)
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Part of the Labware creator classes
module LabwareCreators
require_dependency 'labware_creators/pcr_cycles_binned_plate/csv_file'
require_dependency 'labware_creators/pcr_cycles_binned_plate/csv_file_base'

#
# Class PlateBarcodeHeader provides a simple wrapper for handling and validating
Expand Down
173 changes: 0 additions & 173 deletions app/models/labware_creators/pcr_cycles_binned_plate/csv_file/row.rb

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@

# Part of the Labware creator classes
module LabwareCreators
require_dependency 'labware_creators/pcr_cycles_binned_plate/csv_file'

#
# This version of the row is for the Targeted NanoSeq pipeline.
# Provides a simple wrapper for handling and validating individual CSV rows.
# Abstract class, extend for uses in specific pipelines.
#
class PcrCyclesBinnedPlate::CsvFile::RowForTNanoSeq
class PcrCyclesBinnedPlate::CsvFile::RowBase
include ActiveModel::Validations

IN_RANGE = 'is empty or contains a value that is out of range (%s to %s), in %s'
WELL_NOT_RECOGNISED = 'contains an invalid well name: %s'
HYB_PANEL_MISSING = 'is empty, in %s'

attr_reader :header,
:well,
Expand All @@ -24,7 +22,6 @@ class PcrCyclesBinnedPlate::CsvFile::RowForTNanoSeq
:sample_volume,
:diluent_volume,
:pcr_cycles,
:hyb_panel,
:index

validates :well,
Expand All @@ -37,7 +34,7 @@ class PcrCyclesBinnedPlate::CsvFile::RowForTNanoSeq
validate :sample_volume_within_expected_range?
validate :diluent_volume_within_expected_range?
validate :pcr_cycles_within_expected_range?
validate :hyb_panel_is_present?

delegate :well_column,
:concentration_column,
:sanger_sample_id_column,
Expand All @@ -47,10 +44,9 @@ class PcrCyclesBinnedPlate::CsvFile::RowForTNanoSeq
:sample_volume_column,
:diluent_volume_column,
:pcr_cycles_column,
:hyb_panel_column,
to: :header

# rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
# rubocop:todo Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
def initialize(row_config, header, index, row_data)
@row_config = row_config
@header = header
Expand All @@ -69,11 +65,16 @@ def initialize(row_config, header, index, row_data)
@sample_volume = @row_data[sample_volume_column]&.strip&.to_f
@diluent_volume = @row_data[diluent_volume_column]&.strip&.to_f
@pcr_cycles = @row_data[pcr_cycles_column]&.strip&.to_i
@hyb_panel = @row_data[hyb_panel_column]&.strip

initialize_pipeline_specific_columns
end

# rubocop:enable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity

def initialize_pipeline_specific_columns
raise '#initialize_pipeline_specific_columns must be implemented on subclasses'
end

def to_s
@well.present? ? "row #{index + 2} [#{@well}]" : "row #{index + 2}"
end
Expand All @@ -99,19 +100,6 @@ def pcr_cycles_within_expected_range?
in_range?('pcr_cycles', pcr_cycles, @row_config.pcr_cycles_min, @row_config.pcr_cycles_max)
end

# Checks whether the Hyb Panel column is filled in
def hyb_panel_is_present?
return true if empty?

# TODO: can we validate the hyb panel value? Does not appear to be tracked in LIMS.
result = hyb_panel.present?
unless result
msg = format(HYB_PANEL_MISSING, to_s)
errors.add('hyb_panel', msg)
end
result
end

# Checks whether a row value it within the specified range using min/max values
# from the row config
#
Expand Down
Loading

0 comments on commit 220278e

Please sign in to comment.