Class: SampleManifestExcel::Upload::Processor::TubeRack
- Inherits:
-
Base
- Object
- Base
- SampleManifestExcel::Upload::Processor::TubeRack
show all
- Includes:
- ActiveModel::Validations, CsvParserClient
- Defined in:
- app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb
Overview
Used for processing the upload of sample manifests. Contains behaviour specific to processing ‘Tube Rack’ manifests. Had to explicitly specify the namespace for Base here otherwise it picks up Upload::Base
Constant Summary
Constants inherited
from Base
Base::MANDATORY_FIELDS
Instance Attribute Summary collapse
Attributes inherited from Base
#upload
Instance Method Summary
collapse
get_tube_rack_scan_results, no_read?, remove_no_read_results
Methods inherited from Base
#aliquots_updated?, #create_samples_if_not_present, #downstream_aliquots_updated?, #sample_manifest_updated?, #samples_updated?, #samples_valid?, #substitutions, #type, #update_sample_manifest, #update_samples_and_aliquots
Constructor Details
#initialize(upload) ⇒ TubeRack
Returns a new instance of TubeRack.
19
20
21
22
23
24
25
26
27
28
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 19
def initialize(upload)
super(upload)
@tube_rack_information_processed = false
@tube_rack_barcodes_from_manifest = retrieve_tube_rack_barcodes_from_manifest
return if @tube_rack_barcodes_from_manifest.nil?
@tube_barcodes_from_manifest = upload.data.column(1).compact
@tube_rack_information_previously_processed = check_if_tube_racks_present
end
|
Instance Attribute Details
#tube_rack_barcodes_from_manifest ⇒ Object
Returns the value of attribute tube_rack_barcodes_from_manifest.
17
18
19
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 17
def tube_rack_barcodes_from_manifest
@tube_rack_barcodes_from_manifest
end
|
Instance Method Details
#check_foreign_barcode_unique(foreign_barcode_format, value) ⇒ Object
167
168
169
170
171
172
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 167
def check_foreign_barcode_unique(foreign_barcode_format, value)
return true unless Barcode.exists_for_format?(foreign_barcode_format, value)
upload.errors.add(:base, 'foreign barcode is already in use.')
false
end
|
#check_if_tube_racks_present ⇒ Object
if a tube rack record already exists for any of the rack barcodes in the manifest, it has been processed before and should not be re-processed
57
58
59
60
61
62
63
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 57
def check_if_tube_racks_present
@tube_rack_barcodes_from_manifest.each do |barcode|
existing_barcode_record = Barcode.includes(:asset).find_by(barcode:)
return true if !existing_barcode_record.nil? && !existing_barcode_record.asset.nil?
end
false
end
|
#create_barcodes_for_existing_tubes ⇒ Object
rubocop:todo Metrics/MethodLength
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 149
def create_barcodes_for_existing_tubes upload.rows.each do |row|
tube_barcode = row.value('tube_barcode')
tube = row.labware
barcode_format = Barcode.matching_barcode_format(tube_barcode)
if barcode_format.nil?
error_message = "The tube barcode '#{tube_barcode}' is not a recognised format."
upload.errors.add(:base, error_message)
return false
else
return false unless check_foreign_barcode_unique(barcode_format, tube_barcode)
end
Barcode.create!(asset_id: tube.id, barcode: tube_barcode, format: barcode_format)
end
end
|
#create_tube_rack_if_not_existing(tube_rack_barcode) ⇒ Object
rubocop:todo Metrics/MethodLength
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 126
def create_tube_rack_if_not_existing(tube_rack_barcode) barcode = Barcode.includes(:asset).find_by(asset_id: tube_rack_barcode)
if barcode.nil?
purpose = Purpose.where(target_type: 'TubeRack', size: @rack_size).first
tube_rack = ::TubeRack.create!(size: @rack_size, plate_purpose_id: purpose&.id)
barcode_format = Barcode.matching_barcode_format(tube_rack_barcode)
if barcode_format.nil?
error_message = "The tube rack barcode '#{tube_rack_barcode}' is not a recognised format."
upload.errors.add(:base, error_message)
return nil
end
Barcode.create!(labware: tube_rack, barcode: tube_rack_barcode, format: barcode_format)
else
tube_rack = barcode.labware
end
tube_rack
end
|
#create_tube_racks_and_link_tubes ⇒ Object
103
104
105
106
107
108
109
110
111
112
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 103
def create_tube_racks_and_link_tubes
rack_barcode_to_tube_rack = create_tube_racks_if_not_existing
return false if rack_barcode_to_tube_rack.nil?
success = create_barcodes_for_existing_tubes
return false unless success
link_tubes_to_racks(rack_barcode_to_tube_rack)
true
end
|
#create_tube_racks_if_not_existing ⇒ Object
114
115
116
117
118
119
120
121
122
123
124
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 114
def create_tube_racks_if_not_existing
rack_barcode_to_tube_rack = {}
@tube_rack_barcodes_from_manifest.each do |tube_rack_barcode|
created_rack = create_tube_rack_if_not_existing(tube_rack_barcode)
return nil if created_rack.nil?
rack_barcode_to_tube_rack[tube_rack_barcode] = created_rack
end
rack_barcode_to_tube_rack
end
|
#link_tubes_to_racks(rack_barcode_to_tube_rack) ⇒ Object
174
175
176
177
178
179
180
181
182
183
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 174
def link_tubes_to_racks(rack_barcode_to_tube_rack)
upload.rows.each do |row|
tube_barcode = row.value('tube_barcode')
tube = row.labware
tube_rack_barcode = @tube_barcode_to_rack_barcode[tube_barcode]
tube_rack = rack_barcode_to_tube_rack[tube_rack_barcode]
tube_barcode_to_coordinate = @rack_barcode_to_scan_results[tube_rack_barcode]
RackedTube.create!(tube_rack: tube_rack, tube: tube, coordinate: tube_barcode_to_coordinate[tube_barcode])
end
end
|
#processed? ⇒ Boolean
185
186
187
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 185
def processed?
samples_updated? && sample_manifest_updated? && aliquots_updated? && tube_rack_information_processed?
end
|
#retrieve_scan_results ⇒ Object
65
66
67
68
69
70
71
72
73
74
75
76
77
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 65
def retrieve_scan_results
@rack_barcode_to_scan_results = {}
@tube_barcode_to_rack_barcode = {}
@tube_rack_barcodes_from_manifest.each do |tube_rack_barcode|
results = ::CsvParserClient.get_tube_rack_scan_results(tube_rack_barcode, upload)
return false if results.nil?
@rack_barcode_to_scan_results[tube_rack_barcode] = results
results.keys.each { |tube_barcode| @tube_barcode_to_rack_barcode[tube_barcode] = tube_rack_barcode }
end
true
end
|
#retrieve_tube_rack_barcodes_from_manifest ⇒ Object
48
49
50
51
52
53
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 48
def retrieve_tube_rack_barcodes_from_manifest
rack_barcodes_list = upload.data.description_info.select { |key| key.start_with?('Rack barcode (') }.values
return nil if rack_barcodes_list.any?(nil)
rack_barcodes_list
end
|
#run(tag_group) ⇒ Object
rubocop:todo Metrics/MethodLength
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 30
def run(tag_group) return unless valid?
unless @tube_rack_information_previously_processed
@rack_size = upload.sample_manifest.tube_rack_purpose.size
unless retrieve_scan_results && validate_against_scan_results &&
validate_coordinates(@rack_size, @rack_barcode_to_scan_results)
return
end
success = create_tube_racks_and_link_tubes
@tube_rack_information_processed = true if success
end
update_samples_and_aliquots(tag_group)
update_sample_manifest
end
|
189
190
191
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 189
def tube_rack_information_processed?
@tube_rack_information_processed || @tube_rack_information_previously_processed
end
|
#validate_against_scan_results ⇒ Object
79
80
81
82
83
84
85
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 79
def validate_against_scan_results
return true if @tube_barcodes_from_manifest.sort == @tube_barcode_to_rack_barcode.keys.sort
error_message = 'The scan and the manifest do not contain identical tube barcodes.'
upload.errors.add(:base, error_message)
false
end
|
#validate_coordinates(rack_size, rack_barcode_to_scan_results) ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# File 'app/sample_manifest_excel/sample_manifest_excel/upload/processor/tube_rack.rb', line 87
def validate_coordinates(rack_size, rack_barcode_to_scan_results)
coordinates = rack_barcode_to_scan_results.values.map(&:values).flatten
invalid_coordinates = ::TubeRack.invalid_coordinates(rack_size, coordinates)
return true if invalid_coordinates.empty?
error_message =
"The following coordinates in the scan are not valid for a tube rack of size #{rack_size}: #{invalid_coordinates}."
upload.errors.add(:base, error_message)
false
end
|