Class: CherrypickTask

Inherits:
Task show all
Defined in:
app/models/cherrypick_task.rb

Overview

A Task used in cherrypick pipelines Performs the main bulk of cherrypick action. Although a lot of the options on this page are presented as part of the previous step, and get persisted on this page as hidden fields. This page shows a drag-drop plate layout which lets users set-up the way the plate will be picked. The target asset of each request will have its plate and map set accordingly. Well attributes are set to track picking volumes

Defined Under Namespace

Classes: ControlLocator, PickTarget

Constant Summary collapse

EMPTY_WELL =
[0, 'Empty', ''].freeze
TEMPLATE_EMPTY_WELL =
[0, '---', ''].freeze
DEFAULT_WELLS_TO_LEAVE_FREE =
Rails.application.config.plate_default_control_wells_to_leave_free

Instance Method Summary collapse

Methods inherited from Task

#find_batch, #find_batch_requests, #get_descriptor_value, get_subclass_attribute_options, #get_subclass_attribute_options, #get_subclass_attribute_value, get_subclass_attributes, #get_subclass_attributes, #included_for_do_task, #included_for_render_task, init_class, #set_descriptor_value, set_subclass_attribute, #set_subclass_attribute_value, #sub_events_for

Methods inherited from ApplicationRecord

convert_labware_to_receptacle_for, find_by_id_or_name, find_by_id_or_name!

Methods included from Squishify

extended

Methods included from Warren::BroadcastMessages

#broadcast, included, #queue_associated_for_broadcast, #queue_for_broadcast, #warren

Instance Method Details

#build_plate_wells_from_requests(requests, workflow_controller = nil) ⇒ Object

returns array [ [ request id, source plate barcode, source coordinate ] ]


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/models/cherrypick_task.rb', line 120

def build_plate_wells_from_requests(requests, workflow_controller = nil)
  loaded_requests = Request.where(requests: { id: requests })
                           .includes(asset: [{ plate: :barcodes }, :map])

  source_plate_barcodes = loaded_requests.map { |request| request.asset.plate.human_barcode }.uniq

  begin
    # retrieve Labwhere locations for all source_plate_barcodes, in form { 'DN1234' => 'Sanger / Room 1 - Shelf 2' }
    labwhere_response = Labware.labwhere_locations(source_plate_barcodes)
    barcodes_sorted_by_location = labwhere_response.sort_by { |_k, v| v }.to_h.keys
  rescue LabWhereClient::LabwhereException => e
    message = "Labware locations are unavailable (#{e.message}). Wells are sorted by plate creation order."
    workflow_controller.send(:flash)[:error] = message unless workflow_controller.nil?

    barcodes_sorted_by_location = source_plate_barcodes
  end

  # sort by location in lab, followed by plate id, followed by well coordinate on plate
  sorted_requests = loaded_requests.sort_by do |request|
    [barcodes_sorted_by_location.index(request.asset.plate.human_barcode), request.asset.plate.id,
     request.asset.map.column_order]
  end

  sorted_requests.map do |request|
    [request.id, request.asset.plate.human_barcode, request.asset.map_description]
  end
end

#do_task(workflow_controller, params) ⇒ Object


112
113
114
115
116
117
# File 'app/models/cherrypick_task.rb', line 112

def do_task(workflow_controller, params)
  workflow_controller.do_cherrypick_task(self, params)
rescue Cherrypick::Error => e
  workflow_controller.send(:flash)[:error] = e.message
  false
end

#new_control_locator(batch_id, total_wells, num_control_wells, wells_to_leave_free: DEFAULT_WELLS_TO_LEAVE_FREE) ⇒ CherrypickTask::ControlLocator

Returns a ControlLocator which can generate control locations for plates in a batch. It responds to #control_positions which takes a plate number as an argument

Returns:


23
24
25
26
27
28
29
30
# File 'app/models/cherrypick_task.rb', line 23

def new_control_locator(batch_id, total_wells, num_control_wells, wells_to_leave_free: DEFAULT_WELLS_TO_LEAVE_FREE)
  CherrypickTask::ControlLocator.new(
    batch_id: batch_id,
    total_wells: total_wells,
    num_control_wells: num_control_wells,
    wells_to_leave_free: wells_to_leave_free
  )
end

#partialObject


103
104
105
# File 'app/models/cherrypick_task.rb', line 103

def partial
  'cherrypick_batches'
end

#pick_new_plate(requests, template, robot, plate_purpose, control_source_plate = nil, workflow_controller = nil) ⇒ Object


32
33
34
35
36
37
# File 'app/models/cherrypick_task.rb', line 32

def pick_new_plate(requests, template, robot, plate_purpose, control_source_plate = nil, workflow_controller = nil)
  target_type = PickTarget.for(plate_purpose)
  perform_pick(requests, robot, control_source_plate, workflow_controller) do
    target_type.new(template, plate_purpose.try(:asset_shape))
  end
end

#pick_onto_partial_plate(requests, template, robot, partial_plate, control_source_plate = nil, workflow_controller = nil) ⇒ Object


39
40
41
42
43
44
45
46
47
48
# File 'app/models/cherrypick_task.rb', line 39

def pick_onto_partial_plate(requests, template, robot, partial_plate, control_source_plate = nil, workflow_controller = nil)
  purpose = partial_plate.plate_purpose
  target_type = PickTarget.for(purpose)

  perform_pick(requests, robot, control_source_plate, workflow_controller) do
    target_type.new(template, purpose.try(:asset_shape), partial_plate).tap do
      partial_plate = nil # Ensure that subsequent calls have no partial plate
    end
  end
end

#render_task(workflow_controller, params) ⇒ Object


107
108
109
110
# File 'app/models/cherrypick_task.rb', line 107

def render_task(workflow_controller, params)
  super
  workflow_controller.render_cherrypick_task(self, params)
end