Skip to content

Commit

Permalink
added validations in csv file for duplicate well coordinates and tube…
Browse files Browse the repository at this point in the history
… barcodes, and for multiple rack barcodes
  • Loading branch information
andrewsparkes committed Nov 6, 2023
1 parent 6012511 commit b54ffed
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 0 deletions.
30 changes: 30 additions & 0 deletions app/models/labware_creators/plate_split_to_tube_racks/csv_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class PlateSplitToTubeRacks::CsvFile

validate :correctly_parsed?
validates_nested :tube_rack_scan, if: :correctly_formatted?
validate :check_for_rack_barcodes_the_same, if: :correctly_formatted?
validate :check_no_duplicate_well_coordinates, if: :correctly_formatted?
validate :check_no_duplicate_tube_barcodes, if: :correctly_formatted?

NO_TUBE_TEXTS = ['NO READ', 'NOSCAN'].freeze

Expand Down Expand Up @@ -97,6 +100,33 @@ def correctly_formatted?
correctly_parsed?
end

def check_for_rack_barcodes_the_same
tube_rack_barcodes = tube_rack_scan.group_by(&:tube_rack_barcode).keys

return unless tube_rack_barcodes.size > 1

barcodes_str = tube_rack_barcodes.join(',')
errors.add(:base, "Should not contain different rack barcodes (#{barcodes_str})")
end

def check_no_duplicate_well_coordinates
duplicated_well_coordinates =
tube_rack_scan.group_by(&:tube_position).select { |_position, tubes| tubes.size > 1 }.keys.join(',')

return if duplicated_well_coordinates.empty?

errors.add(:base, "Contains duplicate well coordinates (#{duplicated_well_coordinates})")
end

def check_no_duplicate_tube_barcodes
duplicated_tube_barcodes =
tube_rack_scan.group_by(&:tube_barcode).select { |_tube_barcode, tubes| tubes.size > 1 }.keys.join(',')

return if duplicated_tube_barcodes.empty?

errors.add(:base, "Contains duplicate tube barcodes (#{duplicated_tube_barcodes})")
end

# Generates a hash of position details based on the tube rack scan data in the CSV file.
#
# @return [Hash] A hash of position details, where the keys are positions and the values
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FX12345678, A1, AB10000001
FX12345678, B1, AB10000002
FX12345678, C1, AB10000003
FX12345678, D1, AB10000004
FX12345678, E1, AB10000005
FX12345678, F1, AB10000006
FX12345678, G1, AB10000007
FX12345678, H1, AB10000008
FX23838838, A2, AB10000009
FX12345678, B2, AB10000010
FX12345678, C2, AB10000011
FX12345678, D2, AB10000012
FX12345678, E2, AB10000013
FX12345678, F2, AB10000014
FX12345678, G2, AB10000015
FX12345678, H2, AB10000016
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FX12345678, A1, AB10000001
FX12345678, B1, AB10000002
FX12345678, C1, AB10000003
FX12345678, D1, AB10000004
FX12345678, E1, AB10000005
FX12345678, F1, AB10000006
FX12345678, G1, AB10000007
FX12345678, H1, AB10000008
FX12345678, A2, AB10000009
FX12345678, B2, AB10000009
FX12345678, C2, AB10000011
FX12345678, D2, AB10000011
FX12345678, E2, AB10000013
FX12345678, F2, AB10000014
FX12345678, G2, AB10000015
FX12345678, H2, AB10000016
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FX12345678, A1, AB10000001
FX12345678, B1, AB10000002
FX12345678, C1, AB10000003
FX12345678, D1, AB10000004
FX12345678, E1, AB10000005
FX12345678, F1, AB10000006
FX12345678, G1, AB10000007
FX12345678, H1, AB10000008
FX12345678, A2, AB10000009
FX12345678, A2, AB10000010
FX12345678, C2, AB10000011
FX12345678, D2, AB10000012
FX12345678, E2, AB10000013
FX12345678, E2, AB10000014
FX12345678, G2, AB10000015
FX12345678, H2, AB10000016
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,69 @@
end
end
end

# there should be only one rack barcode in the file and it should be the same for all rows
context 'A file with inconsistant rack barcodes' do
let(:file) do
fixture_file_upload(
'spec/fixtures/files/plate_split_to_tube_racks/tube_rack_scan_with_different_rack_barcodes.csv',
'sequencescape/qc_file'
)
end

describe '#valid?' do
it 'should be invalid' do
expect(subject.valid?).to be false
end

it 'reports the errors' do
subject.valid?
expect(subject.errors.full_messages).to include(
'Should not contain different rack barcodes (FX12345678,FX23838838)'
)
end
end
end

# the same well position should not appear more than once in the file
context 'A file with duplicated well positions' do
let(:file) do
fixture_file_upload(
'spec/fixtures/files/plate_split_to_tube_racks/tube_rack_scan_with_duplicate_well_positions.csv',
'sequencescape/qc_file'
)
end

describe '#valid?' do
it 'should be invalid' do
expect(subject.valid?).to be false
end

it 'reports the errors' do
subject.valid?
expect(subject.errors.full_messages).to include('Contains duplicate well coordinates (A2,E2)')
end
end
end

# the same tube barcode should not appear more than once in the file
context 'A file with duplicated tube barcodes' do
let(:file) do
fixture_file_upload(
'spec/fixtures/files/plate_split_to_tube_racks/tube_rack_scan_with_duplicate_tubes.csv',
'sequencescape/qc_file'
)
end

describe '#valid?' do
it 'should be invalid' do
expect(subject.valid?).to be false
end

it 'reports the errors' do
subject.valid?
expect(subject.errors.full_messages).to include('Contains duplicate tube barcodes (AB10000009,AB10000011)')
end
end
end
end

0 comments on commit b54ffed

Please sign in to comment.