Module: Cherrypick::VolumeByNanoGramsPerMicroLitre

Included in:
Well
Defined in:
app/models/cherrypick/volume_by_nano_grams_per_micro_litre.rb

Overview

Included in Well to provide calculations for cherrypicking

Instance Method Summary collapse

Instance Method Details

#volume_to_cherrypick_by_nano_grams_per_micro_litre(volume_required, concentration_required, source_concentration, source_volume, robot_minimum_picking_volume = 0.0) ⇒ Float

Used in the cherrypicking process to calculate the relative volumes of source and buffer required to reach the target volume and concentration.

  • Ideally will aim for a target well containing volume_required at concentration_required

  • This will be made by combining material from the source well (picked_volume) and buffer (buffer_volume)

  • Maximum picked_volume is limited by source_volume and volume_required

  • If source_volume < volume_required then buffer will be added to make up volume_required even if it reduces the target concentration below concentration_required

rubocop:todo Metrics/MethodLength, Metrics/AbcSize

Parameters:

  • volume_required (Float)

    The volume to aim for in the target well (self)

  • concentration_required (Float)

    The concentration to aim for in the target well (self)

  • source_concentration (Float)

    The concentration (ng/ul) in the source well

  • source_volume (Float)

    The volume (ul) in the source well (ie. the maximum pick)

  • robot_minimum_picking_volume (Float) (defaults to: 0.0)

    (ul) the minimum volume the robot can pick

Returns:

  • (Float)

    The total volume that will be picked from the source well


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'app/models/cherrypick/volume_by_nano_grams_per_micro_litre.rb', line 24

def volume_to_cherrypick_by_nano_grams_per_micro_litre(
  volume_required,
  concentration_required,
  source_concentration,
  source_volume,
  robot_minimum_picking_volume = 0.0
)
  robot_minimum_picking_volume ||= 0

  check_inputs_to_volume_to_cherrypick_by_nano_grams_per_micro_litre!(
    volume_required,
    concentration_required,
    source_concentration
  )

  # @note Here we appear to set the concentration based on the required concentration, regardless of whether we hit it
  # it or not. Checking if this behaviour is desired RT#719205
  well_attribute.concentration = concentration_required
  well_attribute.requested_volume = volume_required

  # Similarly we set current volume based on required. This is only untrue in rare edge cases though
  # (When you have almost all your required volume from your source, then add more buffer than intended
  #  due to minimum robot picks)
  well_attribute.current_volume = volume_required

  # The minimum picking volume is usually determined by the robot, but if the
  # source volume is lower than this, we don't want to try to pick more.
  minimum_picking_volume = [robot_minimum_picking_volume, source_volume].compact.min

  # The maximum picking volume is limited by the source volume, and the volume
  # required.
  maximum_picking_volume = [volume_required, source_volume].compact.min

  volume_needed =
    if source_concentration.zero?
      volume_required # If we have no material, then transfer everything
    else
      (volume_required * concentration_required) / source_concentration
    end

  # clamp applies maximum and minimum values to volume_needed
  volume_to_pick = volume_needed.clamp(minimum_picking_volume..maximum_picking_volume)

  well_attribute.picked_volume = volume_to_pick
  well_attribute.buffer_volume = buffer_volume_required(volume_required, volume_to_pick, robot_minimum_picking_volume)
  well_attribute.robot_minimum_picking_volume = robot_minimum_picking_volume

  volume_to_pick
end