Ejemplo n.º 1
0
    def plateStrandBAndMix():
        # Plate strand B and mix
        # Mixing always needs the p50, but plating may need either; optimize tip usage
        log('Plating Strand B')
        mixed_wells = set()
        for row in range(num_rows):
            for col in range(num_columns):
                volume = strand_b_plate[row][col]
                if volume == 0: continue
                p: EnhancedPipetteV1 = p10 if usesP10(volume,
                                                      allow_zero=True) else p50
                well = plate.rows(row).wells(col)
                log("Plating Strand B: well='%s' vol=%d pipette=%s" %
                    (well.get_name(), volume, p.name))
                if not p.tip_attached: p.pick_up_tip()
                p.transfer(volume,
                           diluted_strand_b,
                           well,
                           new_tip='never',
                           trash=config.trash_control,
                           full_dispense=True)
                if p is p50:
                    mix_plate_well(well, keep_last_tip=True)
                    mixed_wells.add(well)
                p.done_tip()

        for well in plate.wells():
            if well not in mixed_wells:
                mix_plate_well(well)
Ejemplo n.º 2
0
def plateStrandBAndMix():
    # Plate strand B and mix
    # Mixing always needs the p50, but plating may need either; optimize tip usage
    log('Plating Strand B')
    mixed_wells = set()
    for iVolume in range(0, len(strand_volumes)):
        dest_wells = calculateStrandBWells(iVolume)
        volume = strand_volumes[iVolume]
        if usesP10(
                volume, len(dest_wells), allow_zero=True
        ):  # nb: len(dest_wells) is technically incorrect, since we pipette each individually. but we leave for historical reasons
            p = p10
        else:
            p = p50

        # We can't use distribute here as we need to avoid cross contamination from plate well to plate well
        for well in dest_wells:
            if volume != 0:
                log("Plating Strand B: well='%s' vol=%d pipette=%s" %
                    (well.get_name(), volume, p.name))
                p.pick_up_tip()
                p.transfer(volume,
                           diluted_strand_b,
                           well,
                           new_tip='never',
                           full_dispense=True)
            if p is p50:
                mix_plate_well(well, keep_last_tip=True)
                mixed_wells.add(well)
            p.done_tip()

    for well in plate.wells():
        if well not in mixed_wells:
            mix_plate_well(well)
Ejemplo n.º 3
0
def plate_dilutions():
    log('plating dilutions')
    tubes_to_plate = WellSeries([initial_stock]) + dilutions
    volumes = [50, 25, 10, 5]
    num_replicates = 3
    for row, source_tube in enumerate(tubes_to_plate):
        log(f'plating {source_tube.get_name()}')
        if row < 8:
            plate = plateA
            row_delta = 0
        else:
            plate = plateB
            row_delta = 8
        for iVolume, volume in enumerate(volumes):
            col_first = iVolume * num_replicates
            destination_wells = plate.rows(row -
                                           row_delta)[col_first:col_first +
                                                      num_replicates]
            p = p10 if volume <= 10 else p50
            if not p.has_tip:  # make sure we have a tip. can reuse so long as we keep the same source tube
                p.pick_up_tip()
            p.transfer(volume,
                       source_tube,
                       destination_wells,
                       new_tip='never',
                       trash=config.trash_control)
        # We're going on to another source tube. Any tip we have is now junk
        p10.done_tip()
        p50.done_tip()
Ejemplo n.º 4
0
 def mix_master_mix():
     log('Mixing Master Mix')
     p50.layered_mix(
         [master_mix],
         incr=2,
         initial_turnover=master_mix_evagreen_vol * 1.2,
         max_tip_cycles=config.layered_mix.max_tip_cycles_large)
Ejemplo n.º 5
0
def plateStrandA():
    # Plate strand A
    # All plate wells at this point only have water and master mix, so we can't get cross-plate-well
    # contamination. We only need to worry about contaminating the Strand A source, which we accomplish
    # by using new_tip='always'. Update: we don't worry about that pollution, that source is disposable.
    # So we can minimize tip usage.
    log('Plating Strand A')
    p10.pick_up_tip()
    p50.pick_up_tip()
    for iVolume in range(0, len(strand_volumes)):
        dest_wells = calculateStrandAWells(iVolume)
        volume = strand_volumes[iVolume]
        if volume == 0: continue
        if usesP10(volume, len(dest_wells), allow_zero=False):
            p = p10
        else:
            p = p50
        log('Plating Strand A: volume %d with %s' % (volume, p.name))
        volumes = [volume] * len(dest_wells)
        p.transfer(volumes,
                   diluted_strand_a,
                   dest_wells,
                   new_tip='never',
                   trash=config.trash_control,
                   full_dispense=True)
    p10.done_tip()
    p50.done_tip()
Ejemplo n.º 6
0
def plateMasterMix():
    log('Plating Master Mix')
    master_mix_per_well = 28
    p50.transfer(
        master_mix_per_well,
        master_mix,
        usedWells(),
        new_tip='once',
        trash=config.trash_control,
        full_dispense=True  #,
        # aspirate_top_clearance=-5.0  # large to help avoid soap bubbles. remove when we no longer use detergent in buffer
    )
Ejemplo n.º 7
0
def make_dilution(water, source, dilution, dilution_volume, dilution_factor, manual):
    if manual:
        name = f'Dilution of {source.get_name()} by {dilution_factor}x'
        note_liquid(dilution, name, initially=dilution_volume)
    log(f'diluting from {source.get_name()} to {dilution.get_name()}')
    dilution_source_volume = dilution_volume / dilution_factor
    dilution_water_volume = dilution_volume - dilution_source_volume
    if manual:
        info(f'water vol={dilution_water_volume}')
        info(f'source vol={dilution_source_volume}')
    else:
        p50.transfer(dilution_water_volume, water, dilution)
        p50.transfer(dilution_source_volume, source, dilution, new_tip='once', trash=config.trash_control, keep_last_tip=False)
Ejemplo n.º 8
0
def plate_dilution(source, dx):
    # We have two dilutions, three replicates each, so get 16 volumes per
    volumes = [1, 2, 3, 4, 5, 10, 15, 20, 25, 35, 50, 75, 100, 125, 150, 200]
    num_reps = 3
    for i, vol in enumerate(volumes):
        log(f'plating source={source.get_name()} vol={vol}')
        row = i % 8
        col_first = int(i / 8)
        p = p10 if vol <= 10 else p50
        for j in range(num_reps):
            col = col_first * num_reps + j + dx
            dest = plate.rows(row).wells(col)
            # info(f'dest={row},{col}')
            p.transfer(vol, source, dest, trash=config.trash_control)
Ejemplo n.º 9
0
 def plateMasterMix():
     log('Plating Master Mix')
     for row in range(num_rows):
         for col in range(num_columns):
             volume = master_mix_plate[row][col]
             if volume == 0: continue
             p: EnhancedPipetteV1 = p10 if usesP10(volume) else p50
             if not p.tip_attached:
                 p.pick_up_tip()
             well = plate.rows(row).wells(col)
             p.transfer(volume,
                        master_mix,
                        well,
                        new_tip='never',
                        trash=config.trash_control,
                        full_dispense=True)
     p10.done_tip()
     p50.done_tip()
Ejemplo n.º 10
0
 def platePerWellWater():
     log('Plating per-well water')
     # Plate per-well water. We save tips by being happy to pollute our water trough with a bit of master mix.
     for row in range(num_rows):
         for col in range(num_columns):
             volume = per_well_water_plate[row][col]
             if volume == 0: continue
             p: EnhancedPipetteV1 = p10 if usesP10(volume) else p50
             if not p.tip_attached:
                 p.pick_up_tip()
             well = plate.rows(row).wells(col)
             p.transfer(volume,
                        waterB,
                        well,
                        new_tip='never',
                        trash=config.trash_control,
                        full_dispense=True)
     p10.done_tip()
     p50.done_tip()
Ejemplo n.º 11
0
def platePerWellWater():
    log('Plating per-well water')
    # Plate per-well water. We save tips by being happy to pollute our water trough with a bit of master mix.
    # We begin by flattening per_well_water_volumes into a column-major array
    water_volumes = [0] * (columns_per_plate * rows_per_plate)
    for iRow in range(rows_per_plate):
        for iCol in range(len(per_well_water_volumes[iRow])):
            volume = per_well_water_volumes[iRow][iCol]
            for iReplicate in range(num_replicates):
                index = (iCol * num_replicates +
                         iReplicate) * rows_per_plate + iRow
                water_volumes[index] = volume

    p50.transfer(water_volumes,
                 waterB,
                 plate.wells(),
                 new_tip='once',
                 trash=config.trash_control,
                 full_dispense=True)
Ejemplo n.º 12
0
def make_dilutions():
    log('transferring water for dilutions')
    p50.transfer(dilution_water_volume,
                 water,
                 dilutions,
                 new_tip='once',
                 trash=config.trash_control)

    sources = WellSeries([initial_stock]) + dilutions[0:-1]
    destinations = dilutions
    for source, destination in zip(sources, destinations):
        log(f'diluting from {source.get_name()} to {destination.get_name()}')
        p50.transfer(
            dilution_source_volume,
            source,
            destination,
            new_tip='once',
            trash=config.trash_control,
            keep_last_tip=True)  # keep tip cause we can use it for mixing
        p50.layered_mix([destination])
Ejemplo n.º 13
0
 def transfer_multiple(msg, xfer_vol_remaining, tubes, dest,
                       new_tip, *args, **kwargs):
     tube_index = 0
     cur_well = None
     cur_vol = 0
     min_vol = 0
     while xfer_vol_remaining > 0:
         if xfer_vol_remaining < p50_min_vol:
             warn(
                 "remaining transfer volume of %f too small; ignored"
                 % xfer_vol_remaining)
             return
         # advance to next tube if there's not enough in this tube
         while cur_well is None or cur_vol <= min_vol:
             if tube_index >= len(tubes):
                 fatal('%s: more reagent needed' % msg)
             cur_well = tubes[tube_index][0]
             cur_vol = tubes[tube_index][1]
             min_vol = max(
                 p50_min_vol,
                 cur_vol / config.
                 min_aspirate_factor_hack,  # tolerance is proportional to specification of volume. can probably make better guess
                 cur_well.geometry.min_aspiratable_volume)
             tube_index = tube_index + 1
         this_vol = min(xfer_vol_remaining, cur_vol - min_vol)
         assert this_vol >= p50_min_vol  # TODO: is this always the case?
         log('%s: xfer %f from %s in %s to %s in %s' %
             (msg, this_vol, cur_well, cur_well.parent, dest,
              dest.parent))
         p50.transfer(this_vol,
                      cur_well,
                      dest,
                      trash=config.trash_control,
                      new_tip=new_tip,
                      **kwargs)
         xfer_vol_remaining -= this_vol
         cur_vol -= this_vol
Ejemplo n.º 14
0
def make_dilution(water, source, dilution, dilution_volume, dilution_factor,
                  manual):
    if manual:
        name = f'Dilution of {source.get_name()} by {dilution_factor}x'
        note_liquid(dilution, name, initially=dilution_volume)
    log(f'{"Manually" if manual else "Automatically"} diluting from {source.get_name()} to {dilution.get_name()}'
        )
    dilution_source_volume = dilution_volume / dilution_factor
    dilution_water_volume = dilution_volume - dilution_source_volume
    if manual:
        info(f'water vol={dilution_water_volume}')
        info(f'source vol={dilution_source_volume}')
        user_prompt('')
    else:
        p50.transfer(dilution_water_volume,
                     water,
                     dilution,
                     new_tip='once',
                     trash=config.trash_control)
        p50.transfer(dilution_source_volume,
                     source,
                     dilution,
                     new_tip='once',
                     trash=config.trash_control)
Ejemplo n.º 15
0
def plate_dilution(source, stride, parity):
    # We have two dilutions, three replicates each, so get 16 volumes per
    volumes = [
        5, 10, 15, 20, 25, 30, 35, 50, 60, 70, 80, 90, 100, 125, 150, 175
    ]
    num_reps = 3
    for i, vol in enumerate(reversed(volumes)):
        log(f'Plating: source={source.get_name()} vol={vol}')
        row = i % 8
        col_first = int(i / 8)
        offset = abs(parity - (i % 2))
        p = p10 if vol <= 10 else p50
        for j in range(num_reps):
            col = (col_first * num_reps + j) * stride + offset
            dest = plate.rows(row).wells(col)
            if not p.tip_attached:
                p.pick_up_tip()
            p.transfer(vol,
                       source,
                       dest,
                       trash=config.trash_control,
                       new_tip='never')
        if p10.tip_attached: p10.done_tip()
        if p50.tip_attached: p50.done_tip()
Ejemplo n.º 16
0
 def plateStrandA():
     # Plate strand A
     # All plate wells at this point only have water and master mix, so we can't get cross-plate-well
     # contamination. We only need to worry about contaminating the Strand A source, which we accomplish
     # by using new_tip='always'. Update: we don't worry about that pollution, that source is disposable.
     # So we can minimize tip usage.
     log('Plating Strand A')
     for row in range(num_rows):
         for col in range(num_columns):
             volume = strand_a_plate[row][col]
             if volume == 0: continue
             p: EnhancedPipetteV1 = p10 if usesP10(volume) else p50
             if not p.tip_attached:
                 p.pick_up_tip()
             well = plate.rows(row).wells(col)
             log('Plating Strand A: volume %d with %s' % (volume, p.name))
             p.transfer(volume,
                        diluted_strand_a,
                        well,
                        new_tip='never',
                        trash=config.trash_control,
                        full_dispense=True)
     p10.done_tip()
     p50.done_tip()
Ejemplo n.º 17
0
# Control tip usage
p10.start_at_tip(tips10[p10_start_tip])
p50.start_at_tip(tips300a[p50_start_tip])

# All the labware containers
eppendorf_1_5_rack = labware_manager.load('opentrons_24_tuberack_eppendorf_1.5ml_safelock_snapcap', slot=2, label='eppendorf_1_5_rack')
eppendorf_5_0_rack = labware_manager.load('Atkinson_15_tuberack_5ml_eppendorf', slot=5, label='eppendorf_5_0_rack')
plate = labware_manager.load('biorad_96_wellplate_200ul_pcr', slot=6, label='plateA')

# Name specific places in the labware containers
water = eppendorf_5_0_rack['C5']
initial_stock = eppendorf_1_5_rack['A1']
dilutions = eppendorf_5_0_rack.rows['A']['1':2]

# Remember initial liquid names and volumes
log('Liquid Names')
note_liquid(location=water, name='Water', initially=water_volume)
note_liquid(location=initial_stock, name='AlluraRed', concentration="20.1442 mM", initially=stock_volume)

########################################################################################################################
# Dilutions
########################################################################################################################

def make_dilution(water, source, dilution, dilution_volume, dilution_factor, manual):
    if manual:
        name = f'Dilution of {source.get_name()} by {dilution_factor}x'
        note_liquid(dilution, name, initially=dilution_volume)
    log(f'diluting from {source.get_name()} to {dilution.get_name()}')
    dilution_source_volume = dilution_volume / dilution_factor
    dilution_water_volume = dilution_volume - dilution_source_volume
    if manual:
Ejemplo n.º 18
0
    def diluteStrands():
        if manually_dilute_strands:
            note_liquid(location=diluted_strand_a,
                        name='Diluted StrandA',
                        initially=strand_dilution_vol)
            note_liquid(location=diluted_strand_b,
                        name='Diluted StrandB',
                        initially=strand_dilution_vol)

            log('Diluting Strands')
            info(
                pretty.format(
                    'Diluted Strand A recipe: water={0:n} strandA={1:n} vol={2:n}',
                    strand_dilution_water_vol, strand_dilution_source_vol,
                    strand_dilution_vol))
            info(
                pretty.format(
                    'Diluted Strand B recipe: water={0:n} strandB={1:n} vol={2:n}',
                    strand_dilution_water_vol, strand_dilution_source_vol,
                    strand_dilution_vol))
            user_prompt('Ensure diluted strands manually present and mixed')

        else:
            strand_a = eppendorf_1_5_rack['A1']
            strand_b = eppendorf_1_5_rack['B1']
            assert strand_a_min_vol >= strand_dilution_source_vol + strand_a.geometry.min_aspiratable_volume
            assert strand_b_min_vol >= strand_dilution_source_vol + strand_b.geometry.min_aspiratable_volume

            note_liquid(location=strand_a,
                        name='StrandA',
                        concentration=strand_a_conc,
                        initially_at_least=strand_a_min_vol
                        )  # i.e.: we have enough, just not specified how much
            note_liquid(location=strand_b,
                        name='StrandB',
                        concentration=strand_b_conc,
                        initially_at_least=strand_b_min_vol)  # ditto
            note_liquid(location=diluted_strand_a, name='Diluted StrandA')
            note_liquid(location=diluted_strand_b, name='Diluted StrandB')

            # We used to auto-mix, but now, even when auto-diluting, we rely on user to have mixed on the vortexer
            # p50.layered_mix([strand_a])
            # p50.layered_mix([strand_b])

            # Create dilutions of strands
            log('Moving water for diluting Strands A and B')
            p50.transfer(
                strand_dilution_water_vol,
                waterA,
                [diluted_strand_a, diluted_strand_b],
                new_tip=
                'once',  # can reuse for all diluent dispensing since dest tubes are initially empty
                trash=config.trash_control)
            log('Diluting Strand A')
            p50.transfer(strand_dilution_source_vol,
                         strand_a,
                         diluted_strand_a,
                         trash=config.trash_control,
                         keep_last_tip=True)
            p50.layered_mix([diluted_strand_a])

            log('Diluting Strand B')
            p50.transfer(strand_dilution_source_vol,
                         strand_b,
                         diluted_strand_b,
                         trash=config.trash_control,
                         keep_last_tip=True)
            p50.layered_mix([diluted_strand_b])
Ejemplo n.º 19
0
                              label='plateA')
plateB = labware_manager.load('biorad_96_wellplate_200ul_pcr',
                              3,
                              label='plateB')
trough = labware_manager.load('usascientific_12_reservoir_22ml',
                              9,
                              label='trough')

# Name specific places in the labware containers
water = trough['A1']
initial_stock = eppendorf_1_5_rack['A1']
dilutions = eppendorf_1_5_rack.rows(1) + eppendorf_1_5_rack.rows(
    2)  # 12 in all

# Remember initial liquid names and volumes
log('Liquid Names')
note_liquid(location=water, name='Water',
            initially_at_least=7000)  # volume is rough guess
note_liquid(location=initial_stock,
            name='AlluraRed',
            concentration="20.1442 mM",
            initially=stock_volume)

########################################################################################################################
# Dilutions
########################################################################################################################

dilution_volume = 600
dilution_factor = math.sqrt(5)  # yes, that's correct

dilution_source_volume = dilution_volume / dilution_factor
Ejemplo n.º 20
0
    label='eppendorf_1_5_rack')
eppendorf_5_0_rack = labware_manager.load('Atkinson_15_tuberack_5ml_eppendorf',
                                          slot=5,
                                          label='eppendorf_5_0_rack')
plate = labware_manager.load('biorad_96_wellplate_200ul_pcr',
                             slot=6,
                             label='plate')

# Name specific places in the labware containers
waterA = eppendorf_5_0_rack['C4']
waterB = eppendorf_5_0_rack['C5']
initial_stock = eppendorf_1_5_rack['A1']
dilutions = eppendorf_5_0_rack.rows['A']['1':2]

# Remember initial liquid names and volumes
log('Liquid Names')
note_liquid(location=waterA, name='Water', initially=waterA_initial_volume)
note_liquid(location=waterB, name='Water', initially=waterB_initial_volume)
note_liquid(location=initial_stock,
            name='AlluraRed',
            concentration="20.1442 mM",
            initially=stock_volume)

########################################################################################################################
# Dilutions
########################################################################################################################


def make_dilution(water, source, dilution, dilution_volume, dilution_factor,
                  manual):
    if manual:
Ejemplo n.º 21
0
    def createMasterMix():
        if manually_make_master_mix:
            note_liquid(location=master_mix,
                        name='Master Mix',
                        initially=master_mix_vol)

            log('Creating Master Mix')
            info(
                pretty.format(
                    'Master Mix recipe: water={0:n} buffer={1:n} EvaGreen={2:n} total={3:n} (extra={4}%)',
                    master_mix_common_water_vol, master_mix_buffer_vol,
                    master_mix_evagreen_vol, master_mix_vol,
                    100.0 * (mm_overhead_factor - 1)))
            user_prompt('Ensure master mix manually present and mixed')

        else:
            # Mostly just for fun, we put the ingredients for the master mix in a nice warm place to help them melt
            temp_slot = 11
            temp_module = modules_manager.load('tempdeck', slot=temp_slot)
            screwcap_rack = labware_manager.load(
                'opentrons_24_aluminumblock_generic_2ml_screwcap',
                slot=temp_slot,
                label='screwcap_rack',
                share=True,
                well_geometry=IdtTubeWellGeometry)

            buffers = list(zip(screwcap_rack.rows(0), buffer_volumes))
            evagreens = list(zip(screwcap_rack.rows(1), evagreen_volumes))

            for buffer in buffers:
                note_liquid(location=buffer[0],
                            name='Buffer',
                            initially=buffer[1],
                            concentration=buffer_source_concentration)
            for evagreen in evagreens:
                note_liquid(location=evagreen[0],
                            name='Evagreen',
                            initially=evagreen[1],
                            concentration=evagreen_source_concentration)
            note_liquid(location=master_mix, name='Master Mix')

            # Buffer was just unfrozen. Mix to ensure uniformity. EvaGreen doesn't freeze, no need to mix
            p50.layered_mix([buffer for buffer, __ in buffers], incr=2)

            # transfer from multiple source wells, each with a current defined volume
            def transfer_multiple(msg, xfer_vol_remaining, tubes, dest,
                                  new_tip, *args, **kwargs):
                tube_index = 0
                cur_well = None
                cur_vol = 0
                min_vol = 0
                while xfer_vol_remaining > 0:
                    if xfer_vol_remaining < p50_min_vol:
                        warn(
                            "remaining transfer volume of %f too small; ignored"
                            % xfer_vol_remaining)
                        return
                    # advance to next tube if there's not enough in this tube
                    while cur_well is None or cur_vol <= min_vol:
                        if tube_index >= len(tubes):
                            fatal('%s: more reagent needed' % msg)
                        cur_well = tubes[tube_index][0]
                        cur_vol = tubes[tube_index][1]
                        min_vol = max(
                            p50_min_vol,
                            cur_vol / config.
                            min_aspirate_factor_hack,  # tolerance is proportional to specification of volume. can probably make better guess
                            cur_well.geometry.min_aspiratable_volume)
                        tube_index = tube_index + 1
                    this_vol = min(xfer_vol_remaining, cur_vol - min_vol)
                    assert this_vol >= p50_min_vol  # TODO: is this always the case?
                    log('%s: xfer %f from %s in %s to %s in %s' %
                        (msg, this_vol, cur_well, cur_well.parent, dest,
                         dest.parent))
                    p50.transfer(this_vol,
                                 cur_well,
                                 dest,
                                 trash=config.trash_control,
                                 new_tip=new_tip,
                                 **kwargs)
                    xfer_vol_remaining -= this_vol
                    cur_vol -= this_vol

            def mix_master_mix():
                log('Mixing Master Mix')
                p50.layered_mix(
                    [master_mix],
                    incr=2,
                    initial_turnover=master_mix_evagreen_vol * 1.2,
                    max_tip_cycles=config.layered_mix.max_tip_cycles_large)

            log('Creating Master Mix: Water')
            p50.transfer(master_mix_common_water_vol,
                         waterB,
                         master_mix,
                         trash=config.trash_control)

            log('Creating Master Mix: Buffer')
            transfer_multiple(
                'Creating Master Mix: Buffer',
                master_mix_buffer_vol,
                buffers,
                master_mix,
                new_tip='once',
                keep_last_tip=True
            )  # 'once' because we've only got water & buffer in context
            p50.done_tip()  # EvaGreen needs a new tip

            log('Creating Master Mix: EvaGreen')
            transfer_multiple(
                'Creating Master Mix: EvaGreen',
                master_mix_evagreen_vol,
                evagreens,
                master_mix,
                new_tip='always',
                keep_last_tip=True
            )  # 'always' to avoid contaminating the Evagreen source w/ buffer

            mix_master_mix()
Ejemplo n.º 22
0
def plate_dilutions():
    log('Plating')
    plate_dilution(dilutions[0], 0)
    plate_dilution(dilutions[1], 6)