def sample_turbs(): ham_int, reader_int, reader_int, shaker, *_ = sys_state.instruments #shaker.stop() TODO: for asynchrony for batch in batches: tip_poss = new_tips() aspirate(ham_int, [(turb_plate, i) for i in batch], [read_sample_vol]*8) dispense(ham_int, [(reader_plate, i) for i in batch], [read_sample_vol]*8) tip_eject(ham_int, tip_poss)
def new_tips(): ham_int, reader_int, reader_int, shaker, *_ = sys_state.instruments while True: try: positions =[next(disp_tips_gen) for i in range(8)] tip_pick_up(ham_int, positions) return positions except pyhamilton.TipPresentError: tip_eject(ham_int) except pyhamilton.NoTipError: pass
def replace_mix_tips(ham_int, pump_int, reader_int): change_96_tips(ham_int, mixing_tips) put_96_tips(ham_int, DEFAULT_WASTE, immediately=True) for col in range(num_reused_lagoons / 8): while True: try: tip_pick_up(ham_int, next(replace_tips_gen)) break except pyhamilton.NoTipError: continue tip_eject( ham_int, list(zip([mixing_tips] * 8, range(col * 8, (col + 1) * 8))))
def replace_media(replace_vols): ham_int, reader_int, reader_int, shaker, *_ = sys_state.instruments if sys_state.waffle_clean_thread: sys_state.waffle_clean_thread.join() pump_int.refill(30) shaker.stop() for batch in batches: tip_poss = new_tips() aspirate(ham_int, [(media_reservoir, i%8) for i in batch], [replace_vols[i] for i in batch]) dispense(ham_int, [(turb_plate, i) for i in batch], [replace_vols[i] for i in batch], liquidHeight=fly_disp_height, dispenseMode=9) shaker.start(shake_speed) tip_eject(ham_int, tip_poss) #TODO: only for tip reuse tip_poss = new_tips() #TODO: only for tip reuse shaker.stop() aspirate(ham_int, [(turb_plate, i) for i in batch], [800]*8, liquidHeight=fixed_turb_height) dispense(ham_int, [(bleach_site, i%8 + 88) for i in batch], [800]*8, liquidHeight=15) # +88 for far right side of bleach tip_eject(ham_int, tip_poss) shaker.start(shake_speed)
def service(replace_vols, plate, tips, media_reservoir): ham_int, *_ = sys_state.instruments if not remember.replace_vols: return # no transfer volumes ready to act on liq_move_param = { 'liquidClass': std_class, 'airTransportRetractDist': 0 } for col_num, col_vols in enumerate(replace_vols): array_idxs = [col_num * 8 + i for i in range(8)] tip_poss = [(tips, j) for j in array_idxs] tip_pick_up(ham_int, tip_poss) media_poss = [(media_reservoir, j) for j in array_idxs] aspirate(ham_int, media_poss, col_vols, **liq_move_param) plate_poss = [(plate, j) for j in array_idxs] dispense(ham_int, plate_poss, col_vols, liquidHeight=disp_height, mixCycles=2, mixVolume=mix_vol, dispenseMode=9, **liq_move_param) excess_vols = [max_transfer_vol for _ in media_poss] aspirate(ham_int, plate_poss, excess_vols, liquidHeight=fixed_turb_height, **liq_move_param) dispense( ham_int, [(waste_site, j % 8 + 88) for j in array_idxs], excess_vols, # +88 for far right side of bleach liquidHeight=15, **liq_move_param) wash_vols = [wash_vol for _ in media_poss] bleach_poss = [(bleach_site, j) for j in array_idxs] aspirate(ham_int, bleach_poss, wash_vols, **liq_move_param) dispense(ham_int, bleach_poss, wash_vols, **liq_move_param) water_poss = [(water_site, j) for j in array_idxs] aspirate(ham_int, water_poss, wash_vols, **liq_move_param) dispense(ham_int, water_poss, wash_vols, **liq_move_param) tip_eject(ham_int, tip_poss) remember.replace_vols = None # make sure these transfers are only executed once
def prepare_assays(phage_dilutions, culture_wells, plate_wells): # deal with up to 8 at the same time ham_int, *_ = sys_state.instruments num_phage_dilutions = len(phage_dilutions) agar_positions = all_agar_positions[:num_phage_dilutions] if prep_hard_agar: logging.info('\n##### Filling assay plates with hard agar.') if next(replace_agar_tips): tip_eject(ham_int) new_tips(num_phage_dilutions) aspirate(ham_int, agar_positions, [hard_agar_vol*dipenses_per_prep_tip*1.3]*num_phage_dilutions, liquidClass=agar_class) # Aspirate 10% more to avoid bubbles dispense(ham_int, plate_wells, [hard_agar_vol]*num_phage_dilutions, liquidHeight=6, liquidClass=agar_class) return logging.info('\n##### Moving culture into dilution wells.') new_tips(num_phage_dilutions, 'culture') aspirate(ham_int, culture_wells, [culture_vol]*num_phage_dilutions, liquidClass=std_class) dispense(ham_int, phage_dilutions, [culture_vol]*num_phage_dilutions, liquidClass=std_class) tip_eject(ham_int) logging.info('\n##### Moving agar into dilution tubes.') new_tips(num_phage_dilutions) aspirate(ham_int, agar_positions, [soft_agar_vol + 50]*num_phage_dilutions, liquidClass=agar_class) dispense(ham_int, phage_dilutions, [soft_agar_vol + 50]*num_phage_dilutions, liquidHeight=6, liquidClass=agar_class) logging.info('\n##### Moving finished phage_dilutions into plate wells.') aspirate(ham_int, phage_dilutions, [soft_agar_vol]*num_phage_dilutions, liquidClass=agar_class) dispense(ham_int, plate_wells, [soft_agar_vol]*num_phage_dilutions, liquidHeight=6, liquidClass=agar_class) tip_eject(ham_int)
def service_lagoons(ham_int, pump_int, reader_int): logging.info( '\n\n##### ------------------ Servicing lagoons ------------------' ) logging.info('\n##### Filling reservoir and adding inducer.') culture_fill_thread = run_async( lambda: pump_int.refill(culture_supply_vol)) #while True: # try: # tip_pick_up(ham_int, [next(inducer_tip_pos_gen)]) # break # except pyhamilton.NoTipError: # continue #liq_class_300uL = 'StandardVolumeFilter_Water_DispenseJet_Empty_with_transport_vol' while True: try: tip_pick_up(ham_int, next(disp_lagoon_tips_gen)) break except pyhamilton.NoTipError: continue tip_eject(ham_int, disp_tip_poss) culture_fill_thread.join() #aspirate(ham_int, [(inducer_site, 0)], [inducer_vol], liquidClass=liq_class_300uL) #dispense(ham_int, [(culture_reservoir, 93)], [inducer_vol], liquidClass=liq_class_300uL) #tip_eject(ham_int) logging.info('\n##### Moving fresh culture into lagoons.') change_96_tips(ham_int, culture_tips) aspirate_96(ham_int, culture_reservoir, cycle_replace_vol, mixCycles=6, mixVolume=100, liquidHeight=.5, airTransportRetractDist=30) waffle_clean_thread = run_async(lambda: (pump_int.empty( culture_supply_vol), clean_reservoir(pump_int, shaker))) dispense_96(ham_int, lagoon_plate, cycle_replace_vol, liquidHeight=lagoon_fly_disp_height, dispenseMode=9, airTransportRetractDist=30) # mode: blowout put_96_tips(ham_int, culture_tips, immediately=True) logging.info('\n##### Mixing lagoons.') if sys_state.need_to_read_plate: logging.info( '\n##### Sampling liquid from lagoons to reader plates.') while True: try: reader_plate = next(reader_plate_gen) move_plate(ham_int, reader_plate, reader_plate_site) break except pyhamilton.LabwareError: pass change_96_tips(ham_int, mixing_tips) aspirate_96(ham_int, lagoon_plate, read_sample_vol, mixCycles=2, mixPosition=2, mixVolume=400, liquidFollowing=1, liquidHeight=fixed_lagoon_height, airTransportRetractDist=30) dispense_96(ham_int, reader_plate_site, read_sample_vol, liquidHeight=5, dispenseMode=9, airTransportRetractDist=30) # mode: blowout else: change_96_tips(ham_int, mixing_tips) aspirate_96(ham_int, lagoon_plate, read_sample_vol, mixCycles=2, mixPosition=2, mixVolume=400, liquidFollowing=1, liquidHeight=fixed_lagoon_height, airTransportRetractDist=30) dispense_96(ham_int, lagoon_plate, read_sample_vol, liquidHeight=fixed_lagoon_height + 3, dispenseMode=9, airTransportRetractDist=30) # mode: blowout logging.info('\n##### Draining lagoons to constant height.') excess_vol = max_transfer_vol * .8 aspirate_96(ham_int, lagoon_plate, excess_vol, liquidHeight=fixed_lagoon_height, airTransportRetractDist=30) dispense_96(ham_int, bleach_site, excess_vol, liquidHeight=10, dispenseMode=9, airTransportRetractDist=30) # mode: blowout put_96_tips(ham_int, mixing_corral) change_96_tips(ham_int, temp_layout) if sys_state.need_to_read_plate: aspirate_96(ham_int, lagoon_plate, read_sample_vol, mixCycles=2, mixPosition=2, mixVolume=400, liquidFollowing=1, liquidHeight=fixed_lagoon_height, airTransportRetractDist=30) dispense_96(ham_int, reader_plate_site, read_sample_vol, liquidHeight=5, dispenseMode=9, airTransportRetractDist=30) # mode: blowout else: aspirate_96(ham_int, lagoon_plate, read_sample_vol, mixCycles=2, mixPosition=2, mixVolume=400, liquidFollowing=1, liquidHeight=fixed_lagoon_height, airTransportRetractDist=30) dispense_96(ham_int, lagoon_plate, read_sample_vol, liquidHeight=fixed_lagoon_height + 3, dispenseMode=9, airTransportRetractDist=30) # mode: blowout logging.info('\n##### Draining lagoons to constant height.') aspirate_96(ham_int, lagoon_plate, excess_vol, liquidHeight=fixed_lagoon_height, airTransportRetractDist=30) dispense_96(ham_int, bleach_site, excess_vol, liquidHeight=10, dispenseMode=9, airTransportRetractDist=30) # mode: blowout put_96_tips(ham_int, DEFAULT_WASTE, immediately=True) def bleach(): change_96_tips(ham_int, mixing_corral) bleach_mounted_tips(ham_int, destination=mixing_tips) change_96_tips(ham_int, None) if sys_state.need_to_read_plate: plate_id = reader_plate_id(reader_plate) protocols = ['17_8_12_lum', '17_8_12_abs'] data_types = ['lum', 'abs'] platedatas = read_plate( ham_int, reader_int, reader_tray, reader_plate_site, protocols, plate_id, plate_destination=plate_trash, async_task=bleach ) # throw out plate when done and asynchronously bleach if simulation_on: platedatas = [ PlateData(os.path.join('assets', 'dummy_platedata.csv')) ] * 2 # sim dummies for platedata, data_type in zip(platedatas, data_types): platedata.wait_for_file() db_add_plate_data(platedata, data_type, reader_plate, lagoons, [ *range(8 * 10), *range(8 * 11, 8 * 11 + num_disp_lagoons) ]) reader_int.plate_in(block=False) sys_state.need_to_read_plate = False else: bleach() change_96_tips(ham_int, None) waffle_clean_thread.join() logging.info( '\n##### --------------- Done servicing lagoons ---------------\n')
culture_fill_thread = run_async( lambda: pump_int.refill(culture_supply_vol)) # dispense inducer in an x-pattern into the reservoir logging.info('\n##### Filling reservoir and adding inducer.') # use 8-channel to fetch a tip to put in the tip staging # pick up tip with 8-channel while True: try: tip_pick_up(ham_int, [next(inducer_tip_pos_gen)]) break except pyhamilton.NoTipError: continue # put in tip staging tip_eject(ham_int, [(tip_staging, 95)]) # pick up inducer tip with 96-head and wait for fill to finish tip_pick_up_96(ham_int, tip_staging) culture_fill_thread.join() # add inducer aspirate_96(ham_int, inducer_site, inducer_vol) dispense_96(ham_int, culture_reservoir, inducer_vol) tip_eject_96(ham_int) ## With 96-head, perform culture swap # move the next batch of 48 tips to tip_staging using the 8-channel head shaker.start(250) # start shaker to mix in inducer in meantime for i in range(6): tip_pick_up(