Class: LabwareCreators::PlateSplitToTubeRacks
- Includes:
- CustomPage, SupportParent::PlateOnly
- Defined in:
- app/models/labware_creators/plate_split_to_tube_racks.rb
Overview
Handles the creation of up to 2 child racks of tubes from a single parent 96-well plate. Intended for use in a PBMC cell extraction pipeline.
There will typically be one rack of tubes for ‘contingency’ and one for ‘sequencing’ (this rack is optional).
The parent plate contains multiple copies of material prepared from the same sample. One well instance of each sample will go into a tube in the ‘sequencing’ rack (if present), and any remaining copies will go into tubes in the ‘contingency’ rack.
If after the initial preparation the users feel they need more contingency tubes, then they will go back to prepare more material for that sample from an earlier step in the pipeline and create just ‘contingency’ tubes at this step.
Inputs: 1) The parent plate - This plate contains multiple groups of wells containing the same samples e.g.
there may be 3 wells with sample 1, 3 with sample 2, 3 with sample 3 etc. The number of copies of
each sample is not known in advance.
The first of these parent wells will be transferred into a tube in the 'sequencing' rack if it is
present, and any remaining parent wells for the same sample will be transferred into tubes in the
'contingency' rack.
2) Child tube rack scan CSV files - these are scans of racks of 2D tube barcodes from the ‘contingency’
and 'sequencing' tube racks, to allow us to know the position and barcode of each available tube.
On the upload screen displays counts of how many tubes are needed (e.g. To perform this transfer you
will either need 20 sequencing and 40 contingency tubes, or 60 contingency tubes.)
Validations - Error message to users if any of these are not met: 1) The user must always upload a scan file for the ‘contingency’ rack tube barcodes, whereas the
'sequencing' rack file is optional.
2) The scanned child tube barcodes must be unique and must not already exist in the system i.e. they are
new unused empty tubes. List any that do already exist with rack type and location.
3) The number of tubes available in the racks must be correct for the number of parent wells being
transferred. e.g. if there are 20 distinct samples in the parent and 40 additional copies (60 wells
total), then there must be 20 tubes in the first rack and 40 in the second rack.
rubocop:disable Metrics/ClassLength
Constant Summary collapse
- PARENT_PLATE_INCLUDES =
'wells.aliquots,wells.aliquots.sample,wells.downstream_tubes,wells.downstream_tubes.custom_metadatum_collection'
Instance Attribute Summary collapse
-
#child_contingency_tubes ⇒ Object
readonly
Returns the value of attribute child_contingency_tubes.
-
#child_sequencing_tubes ⇒ Object
readonly
Returns the value of attribute child_sequencing_tubes.
-
#contingency_file ⇒ Object
Returns the value of attribute contingency_file.
-
#sequencing_file ⇒ Object
Returns the value of attribute sequencing_file.
Instance Method Summary collapse
-
#add_error_if_wrong_number_of_tubes(file, num_tubes, required_tubes) ⇒ Object
Adds an error when there are insufficient or too many tubes in the given file.
-
#anchor ⇒ Object
Display the children tab in the plate view so we see the child tubes listed.
-
#check_tube_barcodes_differ_between_files ⇒ Object
Validation to compare the tube barcodes in the two files to check for duplication.
-
#check_tube_rack_barcodes_differ_between_files ⇒ Object
Validation to compare the tube rack barcodes in the two files to check for duplication.
-
#check_tube_rack_scan_file(tube_rack_file, msg_prefix) ⇒ void
Checks if the tube barcodes in the given tube rack file already exist in the LIMS.
-
#contingency_csv_file ⇒ CsvFile?
Returns a CsvFile object for the contingency tube rack scan CSV file, or nil if the file doesn’t exist.
- #contingency_file_valid? ⇒ Boolean
-
#create_child_contingency_tubes ⇒ Array<Tube>
Creates a child contingency tube for each parent well not already assigned to a sequencing tube.
-
#create_child_sequencing_tubes ⇒ Array<Tube>
Creates a single child sequencing tube for each parent well containing a unique sample.
-
#create_labware! ⇒ Boolean
Creates child sequencing and contingency tubes, performs transfers.
- #extract_barcodes(file) ⇒ Object
- #extract_tube_rack_barcode(file) ⇒ Object
-
#files_valid? ⇒ Boolean
Checks the files passed their validations.
-
#labware_wells ⇒ Array<Well>
Returns the list of wells of the parent labware.
-
#must_have_correct_number_of_tubes_in_rack_files ⇒ Object
Validation that checks if there are the correct number of tubes in the child tube racks for all the parent wells.
-
#num_parent_unique_samples ⇒ Integer
Returns the number of unique sample UUIDs for the parent wells after applying the current well filter.
-
#num_parent_wells ⇒ Integer
Returns the number of parent wells after applying the current well filter.
-
#parent ⇒ Object
v2 api is used to select the parent plate.
-
#parent_v1 ⇒ Object
v1 api is used to upload the tube rack scan files and create the tubes.
-
#perform_transfers ⇒ void
Creates transfer requests for the given transfer request attributes and performs the transfers.
-
#redirection_target ⇒ Object
We will create multiple child tubes, so redirect to the parent plate.
- #same_tube_rack_barcode? ⇒ Boolean
- #save ⇒ Object
-
#sequencing_csv_file ⇒ CsvFile?
Returns a CsvFile object for the sequencing tube rack scan CSV file, or nil if the file doesn’t exist.
- #sequencing_file_valid? ⇒ Boolean
-
#tube_barcodes_are_unique? ⇒ void
Validation that the tube barcodes are unique and do not already exist in the system.
Constructor Details
This class inherits a constructor from LabwareCreators::Base
Instance Attribute Details
#child_contingency_tubes ⇒ Object (readonly)
Returns the value of attribute child_contingency_tubes.
51 52 53 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 51 def child_contingency_tubes @child_contingency_tubes end |
#child_sequencing_tubes ⇒ Object (readonly)
Returns the value of attribute child_sequencing_tubes.
51 52 53 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 51 def child_sequencing_tubes @child_sequencing_tubes end |
#contingency_file ⇒ Object
Returns the value of attribute contingency_file.
50 51 52 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 50 def contingency_file @contingency_file end |
#sequencing_file ⇒ Object
Returns the value of attribute sequencing_file.
50 51 52 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 50 def sequencing_file @sequencing_file end |
Instance Method Details
#add_error_if_wrong_number_of_tubes(file, num_tubes, required_tubes) ⇒ Object
Adds an error when there are insufficient or too many tubes in the given file
259 260 261 262 263 264 265 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 259 def add_error_if_wrong_number_of_tubes(file, num_tubes, required_tubes) # msg if too many tubes errors.add(file, 'contains more tubes than needed') if num_tubes > required_tubes # msg if not enough tubes errors.add(file, 'contains insufficient tubes') unless num_tubes >= required_tubes end |
#anchor ⇒ Object
Display the children tab in the plate view so we see the child tubes listed.
139 140 141 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 139 def anchor 'children_tab' end |
#check_tube_barcodes_differ_between_files ⇒ Object
Validation to compare the tube barcodes in the two files to check for duplication
Sets errors if the tube rack barcodes are the same
203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 203 def return unless contingency_file_valid? && sequencing_file_valid? = (sequencing_csv_file) = (contingency_csv_file) = & return if .empty? errors.add( :contingency_csv_file, "Tube barcodes are duplicated across contingency and sequencing files (#{.join(', ')})" ) end |
#check_tube_rack_barcodes_differ_between_files ⇒ Object
Validation to compare the tube rack barcodes in the two files to check for duplication
Sets errors if the tube rack barcodes are the same
178 179 180 181 182 183 184 185 186 187 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 178 def return unless contingency_file_valid? && sequencing_file_valid? return unless errors.add( :contingency_csv_file, 'The tube rack barcodes within the contingency and sequencing files must be different' ) end |
#check_tube_rack_scan_file(tube_rack_file, msg_prefix) ⇒ void
This method returns an undefined value.
Checks if the tube barcodes in the given tube rack file already exist in the LIMS.
282 283 284 285 286 287 288 289 290 291 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 282 def check_tube_rack_scan_file(tube_rack_file, msg_prefix) tube_rack_file.position_details.each do |tube_posn, tube_details| = tube_details['tube_barcode'] tube_in_db = Sequencescape::Api::V2::Tube.find_by(barcode: ) next if tube_in_db.blank? msg = "#{msg_prefix} tube barcode #{} (at rack position #{tube_posn}) already exists in the LIMS" errors.add(:tube_rack_file, msg) end end |
#contingency_csv_file ⇒ CsvFile?
Returns a CsvFile object for the contingency tube rack scan CSV file, or nil if the file doesn’t exist.
doesn’t exist.
156 157 158 159 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 156 def contingency_csv_file @contingency_csv_file ||= CommonFileHandling::CsvFileForTubeRackWithRackBarcode.new(contingency_file) if contingency_file end |
#contingency_file_valid? ⇒ Boolean
254 255 256 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 254 def contingency_file_valid? contingency_file.present? && contingency_csv_file&.valid? end |
#create_child_contingency_tubes ⇒ Array<Tube>
Creates a child contingency tube for each parent well not already assigned to a sequencing tube.
122 123 124 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 122 def create_child_contingency_tubes create_tubes(contingency_tube_purpose_uuid, parent_wells_for_contingency.length, contingency_tube_attributes) end |
#create_child_sequencing_tubes ⇒ Array<Tube>
Creates a single child sequencing tube for each parent well containing a unique sample.
113 114 115 116 117 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 113 def create_child_sequencing_tubes return [] if require_contingency_tubes_only? create_tubes(sequencing_tube_purpose_uuid, parent_wells_for_sequencing.length, sequencing_tube_attributes) end |
#create_labware! ⇒ Boolean
Creates child sequencing and contingency tubes, performs transfers.
102 103 104 105 106 107 108 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 102 def create_labware! @child_sequencing_tubes = create_child_sequencing_tubes @child_contingency_tubes = create_child_contingency_tubes perform_transfers true end |
#extract_barcodes(file) ⇒ Object
218 219 220 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 218 def (file) file.position_details.values.pluck('tube_barcode') end |
#extract_tube_rack_barcode(file) ⇒ Object
196 197 198 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 196 def (file) file.position_details.values.first['tube_rack_barcode'] end |
#files_valid? ⇒ Boolean
Checks the files passed their validations
244 245 246 247 248 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 244 def files_valid? return contingency_file_valid? if require_contingency_tubes_only? contingency_file_valid? && sequencing_file_valid? end |
#labware_wells ⇒ Array<Well>
Returns the list of wells of the parent labware. In column order (A1, B1, C1 etc.) Used in WellFilter.
95 96 97 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 95 def labware_wells parent.wells_in_columns end |
#must_have_correct_number_of_tubes_in_rack_files ⇒ Object
Validation that checks if there are the correct number of tubes in the child tube racks for all the parent wells. This depends on the number of unique samples in the parent plate, and the number of parent wells, as well as whether they are using both sequencing tubes and contingency tubes or just contingency.
Sets errors if there are insufficient or too many tubes.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 228 def must_have_correct_number_of_tubes_in_rack_files return unless files_valid? if require_contingency_tubes_only? add_error_if_wrong_number_of_tubes(:contingency_csv_file, num_contingency_tubes, num_parent_wells) else add_error_if_wrong_number_of_tubes( :contingency_csv_file, num_contingency_tubes, num_parent_wells - num_parent_unique_samples ) add_error_if_wrong_number_of_tubes(:sequencing_csv_file, num_sequencing_tubes, num_parent_unique_samples) end end |
#num_parent_unique_samples ⇒ Integer
Returns the number of unique sample UUIDs for the parent wells after applying the current well filter.
164 165 166 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 164 def num_parent_unique_samples @num_parent_unique_samples ||= parent_uniq_sample_uuids.length end |
#num_parent_wells ⇒ Integer
Returns the number of parent wells after applying the current well filter.
171 172 173 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 171 def num_parent_wells @num_parent_wells ||= well_filter.filtered.length end |
#parent ⇒ Object
v2 api is used to select the parent plate
81 82 83 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 81 def parent @parent ||= Sequencescape::Api::V2.plate_with_custom_includes(PARENT_PLATE_INCLUDES, uuid: parent_uuid) end |
#parent_v1 ⇒ Object
v1 api is used to upload the tube rack scan files and create the tubes
86 87 88 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 86 def parent_v1 @parent_v1 ||= api.plate.find(parent_uuid) end |
#perform_transfers ⇒ void
This method returns an undefined value.
Creates transfer requests for the given transfer request attributes and performs the transfers.
129 130 131 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 129 def perform_transfers api.transfer_request_collection.create!(user: user_uuid, transfer_requests: transfer_request_attributes) end |
#redirection_target ⇒ Object
We will create multiple child tubes, so redirect to the parent plate
134 135 136 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 134 def redirection_target parent end |
#same_tube_rack_barcode? ⇒ Boolean
189 190 191 192 193 194 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 189 def seq_tube_rack = (sequencing_csv_file) cont_tube_rack = (contingency_csv_file) seq_tube_rack == cont_tube_rack end |
#save ⇒ Object
75 76 77 78 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 75 def save # NB. need the && true!! super && upload_tube_rack_files && true end |
#sequencing_csv_file ⇒ CsvFile?
Returns a CsvFile object for the sequencing tube rack scan CSV file, or nil if the file doesn’t exist.
doesn’t exist.
147 148 149 150 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 147 def sequencing_csv_file @sequencing_csv_file ||= CommonFileHandling::CsvFileForTubeRackWithRackBarcode.new(sequencing_file) if sequencing_file end |
#sequencing_file_valid? ⇒ Boolean
250 251 252 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 250 def sequencing_file_valid? sequencing_file.present? && sequencing_csv_file&.valid? end |
#tube_barcodes_are_unique? ⇒ void
This method returns an undefined value.
Validation that the tube barcodes are unique and do not already exist in the system. NB. this checks all the tube barcodes in the uploaded tube rack scan files, not just the ones that will be used.
272 273 274 275 |
# File 'app/models/labware_creators/plate_split_to_tube_racks.rb', line 272 def check_tube_rack_scan_file(sequencing_csv_file, 'Sequencing') if sequencing_file check_tube_rack_scan_file(contingency_csv_file, 'Contingency') if contingency_file end |