Class: LabwareCreators::MultiStampTubesUsingTubeRackScan

Inherits:
Base
  • Object
show all
Includes:
CustomPage, SupportParent::TubeOnly
Defined in:
app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb

Overview

Handles the creation of a plate from a number of tubes using an uploaded tube rack scan file.

The parents are standard tubes.

The user uploads a tube rack scan of the tube barcodes and their positions, and this creator will transfer the tubes into wells on the plate.

Inputs: 1) A parent tube - the user has clicked the add plate button on a specific tube 2) A tube rack scan CSV file - this is a scan of the rack of 2D tube barcodes (the rack is not being tracked)

Outputs: 1) A child plate - tubes are stamped into corresponding locations in the plate according to the scan file

Validations - Error message to users if any of these are not met: 1) The user must always upload a scan file. Validations of the file must pass and it should parse correctly and contain at least one tube barcode. 2) The tube barcodes must be unique within the file (exclude NO SCAN, NO READ types). 3) The scanned child tube barcode(s) must already exist in the system. List any that do already exist with tube barcode and scan file location. 4) The labware purpose type of each tube must match the one of the expected ones from a list in the plate purpose config. List any that do not match with tube barcode, scan file location and purpose type, and list the expected type(s). 5) The request on the tube must be active, and must match to one of the expected ones from a list in the plate purpose config. This is to check that the tubes are at the appropriate stage of their pipeline to transfer.

rubocop:disable Metrics/ClassLength

Constant Summary collapse

EXPECTED_REQUEST_STATES =
%w[pending started].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

This class inherits a constructor from LabwareCreators::Base

Instance Attribute Details

#fileObject

Returns the value of attribute file.



41
42
43
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 41

def file
  @file
end

Instance Method Details

#create_labware! {|@child| ... } ⇒ Boolean

Creates child plate, performs transfers.

Yields:

Returns:

  • (Boolean)

    true if the child plate was created successfully.



62
63
64
65
66
67
68
69
70
71
72
73
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 62

def create_labware!
  plate_creation =
    api.pooled_plate_creation.create!(parents: parent_tube_uuids, child_purpose: purpose_uuid, user: user_uuid)

  @child = plate_creation.child
  child_v2 = Sequencescape::Api::V2.plate_with_wells(@child.uuid)

  transfer_material_from_parent!(child_v2)

  yield(@child) if block_given?
  true
end

#csv_fileObject

Returns a CsvFile object for the tube rack scan CSV file, or nil if the file doesn’t exist.



76
77
78
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 76

def csv_file
  @csv_file ||= CommonFileHandling::CsvFileForTubeRackWithRackBarcode.new(file) if file
end

#expected_request_type_keysObject



151
152
153
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 151

def expected_request_type_keys
  purpose_config.dig(:creator_class, :args, :expected_request_type_keys).to_a
end

#expected_tube_purpose_namesObject



155
156
157
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 155

def expected_tube_purpose_names
  purpose_config.dig(:creator_class, :args, :expected_tube_purpose_names).to_a
end

#file_valid?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 80

def file_valid?
  file.present? && csv_file&.valid?
end

#filename_for_tube_rack_scanObject



159
160
161
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 159

def filename_for_tube_rack_scan
  purpose_config.dig(:creator_class, :args, :filename_for_tube_rack_scan)
end

#parentObject Originally defined in module SupportParent::TubeOnly

#parent_tubesObject

Fetches all tubes from the CSV file and stores them in a hash indexed by barcode. This method uses memoization to avoid fetching the tubes more than once.



86
87
88
89
90
91
92
93
94
95
96
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 86

def parent_tubes
  @parent_tubes ||=
    csv_file
      .position_details
      .each_with_object({}) do |(_tube_posn, details_hash), tubes|
        foreign_barcode = details_hash['tube_barcode']
        search_params = { barcode: foreign_barcode, includes: Sequencescape::Api::V2::Tube::DEFAULT_INCLUDES }

        tubes[foreign_barcode] = Sequencescape::Api::V2::Tube.find_by(**search_params)
      end
end

#saveObject



54
55
56
57
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 54

def save
  # NB. need the && true!!
  super && upload_tube_rack_file && true
end

#tubes_must_be_of_expected_purpose_typeObject

Validates that all tubes in the parent_tubes hash are of the expected purpose type. If a tube is not of the expected purpose type, an error message is added to the errors object. Tubes that are not found in the database or are of the expected purpose type are skipped. This method is used to ensure that all tubes are of the correct type before starting the transfer.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 117

def tubes_must_be_of_expected_purpose_type
  return unless file_valid?

  parent_tubes.each do |foreign_barcode, tube_in_db|
    # NB. should be catching missing tubes in previous validation
    next if tube_in_db.blank? || expected_tube_purpose_names.include?(tube_in_db.purpose.name)

    msg =
      "Tube barcode #{foreign_barcode} does not match to one of the expected tube purposes (one of type(s): #{
        expected_tube_purpose_names.join(', ')
      })"
    errors.add(:base, msg)
  end
end

#tubes_must_exist_in_limsObject

Validates that all parent tubes in the CSV file exist in the LIMS. Adds an error message for each tube that doesn’t exist.



100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 100

def tubes_must_exist_in_lims
  return unless file_valid?

  parent_tubes.each do |foreign_barcode, tube_in_db|
    next if tube_in_db.present?

    msg =
      "Tube barcode #{foreign_barcode} not found in the LIMS. " \
        'Please check the tube barcodes in the scan file are valid tubes.'
    errors.add(:base, msg)
  end
end

#tubes_must_have_active_requests_of_expected_typeObject

Validates that all tubes in the parent_tubes hash have at least one active request of the expected type. If a tube does not have an active request of the expected type, an error message is added to the errors object. Tubes that are not found in the database or already have an expected active request are skipped. This method is used to ensure that all tubes are ready for processing before starting the transfer.



136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb', line 136

def tubes_must_have_active_requests_of_expected_type
  return unless file_valid?

  parent_tubes.each do |foreign_barcode, tube_in_db|
    # NB. should be catching missing tubes in previous validation
    next if tube_in_db.blank? || tube_has_expected_active_request?(tube_in_db)

    msg =
      "Tube barcode #{foreign_barcode} does not have an expected active request (one of type(s): #{
        expected_request_type_keys.join(', ')
      })"
    errors.add(:base, msg)
  end
end