Source code for AFL.automation.prepare.DeckBuilderWidget

import numpy as np
import pandas as pd
from math import sqrt

import plotly.graph_objects as go
import plotly.express as px

import ipywidgets
from ipywidgets import Dropdown,Layout,Label,Button,Checkbox,VBox,HBox,Text
import pickle

import AFL.automation.prepare 
from AFL.automation.shared.units import units
from AFL.automation.APIServer.Client import Client

[docs] class DeckBuilderWidget:
[docs] def __init__(self): self.data_model = DeckBuilderWidget_Model() self.data_view = DeckBuilderWidget_View()
[docs] def build_deck_object(self): config = self.get_deck_config() deck = self.data_model.build_deck_object(config) return deck
[docs] def get_deck_config(self): containers = {} catches = {} tipracks = { 'all':{}, 'left_list':[], 'right_list':[], 'left':self.data_view.pipette_left_tips_dropdown.value, 'right':self.data_view.pipette_right_tips_dropdown.value, } pipettes = { 'left':self.data_view.pipette_left_dropdown.value, 'right':self.data_view.pipette_right_dropdown.value, } for slot,dropdown in self.data_view.deckware_dropdowns.items(): value = dropdown.value if value == 'empty': continue if value in self.data_view.container_list: containers[slot] = value elif value in self.data_view.tipracks_list: tipracks['all'][slot] = value if value == self.data_view.pipette_left_tips_dropdown.value: tipracks['left_list'].append((slot,value)) if value == self.data_view.pipette_right_tips_dropdown.value: tipracks['right_list'].append((slot,value)) elif value in self.data_view.catch_list: catches[slot] = value deck = {'containers':containers,'tipracks':tipracks,'catches':catches,'pipettes':pipettes} return deck
[docs] def set_deck_config(self,config): for slot,value in config['containers'].items(): self.data_view.deckware_dropdowns[slot].value = value for slot,value in config['catches'].items(): self.data_view.deckware_dropdowns[slot].value = value for slot,value in config['tipracks']['all'].items(): self.data_view.deckware_dropdowns[slot].value = value for slot,value in config['tipracks']['right_list']: self.data_view.deckware_dropdowns[slot].value = value for slot,value in config['tipracks']['left_list']: self.data_view.deckware_dropdowns[slot].value = value left_value = config['tipracks']['left'] right_value = config['tipracks']['right'] self.data_view.pipette_left_tips_dropdown.value = left_value self.data_view.pipette_right_tips_dropdown.value = right_value left_value = config['pipettes']['left'] right_value = config['pipettes']['right'] self.data_view.pipette_left_dropdown.value = left_value self.data_view.pipette_right_dropdown.value = right_value
[docs] def send_deck_cb(self,event): deck = self.build_deck_object() ip = self.data_view.send_deck_input.value home = self.data_view.send_deck_home.value deck.init_remote_connection(ip,home=home) deck.send_deck_config()
[docs] def save_cb(self,event): self.data_view.progress.value = 0 config = self.get_deck_config() filename = self.data_view.saveload_deck_input.value with open(filename,'wb') as f: pickle.dump(config,f) self.data_view.progress.value = 1
[docs] def load_cb(self,event): self.data_view.progress.value = 0 filename = self.data_view.saveload_deck_input.value with open(filename,'rb') as f: config = pickle.load(f) self.set_deck_config(config) self.data_view.progress.value = 1
[docs] def update_deck_graphic_cb(self,event): for slot,dropdown in self.data_view.deckware_dropdowns.items(): value = dropdown.value deck_location = self.data_view.deck_map[slot] if value == 'empty': self.data_view.deck[deck_location].style.button_color='gray' elif value in self.data_view.container_list: self.data_view.deck[deck_location].style.button_color='blue' elif value in self.data_view.tipracks_list: self.data_view.deck[deck_location].style.button_color='green' elif value in self.data_view.catch_list: self.data_view.deck[deck_location].style.button_color='red'
[docs] def start(self): widget = self.data_view.start() for slot,dropdown in self.data_view.deckware_dropdowns.items(): dropdown.observe(self.update_deck_graphic_cb,names=['value']) self.data_view.save_deck_button.on_click(self.save_cb) self.data_view.load_deck_button.on_click(self.load_cb) self.data_view.send_deck_button.on_click(self.send_deck_cb) return widget
[docs] class DeckBuilderWidget_Model:
[docs] def __init__(self): self.deck = None
[docs] def send_deck_config(self,pi_ip='piot2',align_script='/home/nistoroboto/align.py'): if self.deck is None: raise ValueError('Can\'t send config without building deck object!') self.deck.make_align_script() self.deck.init_remote_connection(pi_ip) self.deck.send_deck_config()
[docs] def build_deck_object(self,config): self.deck = AFL.automation.prepare.Deck() for slot,value in config['containers'].items(): self.deck.add_container(value,slot) for slot,value in config['catches'].items(): self.deck.add_catch(value,slot) pipette_left = config['pipettes']['left'] if not (pipette_left=='None'): tipracks = config['tipracks']['left_list'] self.deck.add_pipette(pipette_left,'left',tipracks=tipracks) tipracks = config['tipracks']['right_list'] pipette_right = config['pipettes']['right'] if not (pipette_right=='None'): self.deck.add_pipette(pipette_right,'right',tipracks=tipracks) return self.deck
[docs] class DeckBuilderWidget_View:
[docs] def __init__(self): self.pipette_list = ['None','p300_single','p50_single','p1000_single_gen2','p300_single_gen2'] self.container_list = [ 'nist_6_20ml_vials', 'nist_2_100ml_poly_bottle', 'nest_96_wellplate_1600ul', 'nist_6_20ml_stirred_vials', 'shaker_nest_96_wellplate_1600ul' ] self.catch_list = [ 'nist_pneumatic_loader', 'nist_stirred_catch', 'nist_1_10ml_syringeloader', ] self.tipracks_list = ['opentrons_96_tiprack_300ul','opentrons_96_tiprack_1000ul','opentrons_96_tiprack_50ul'] self.deckware_types = ['container','tips','catch'] self.deckware_list = ['empty']+self.container_list+self.tipracks_list+self.catch_list
[docs] def create_expanded_button(self,description, button_style): return Button(description=description, button_style=button_style, layout=Layout(height='auto', width='auto'))
[docs] def draw_deck(self): self.deck = ipywidgets.GridspecLayout(4, 3, height='400px',width='400px') location = 1 self.deck_map = {} for i in reversed(range(4)): for j in range(3): if (i==0) and (j==2): continue self.deck[i,j] = self.create_expanded_button(f'{location}', 'success') self.deck[i,j].style.button_color='gray' self.deck_map[location] = (i,j) location+=1 return self.deck
[docs] def start(self): deck = self.draw_deck() self.deckware_dropdowns = {} self.deckware_groups = {} deckware_control_groups = [] for i in range(1,12): dropdown = Dropdown(description=f"Slot {i}:",options=self.deckware_list) self.deckware_dropdowns[i] = dropdown deckware_control_group = HBox([dropdown],layout={'padding-bottom':'5px'}) self.deckware_groups[i] = deckware_control_group deckware_control_groups.append(deckware_control_group) self.pipette_left_dropdown = Dropdown(description="Pipette Left:",options=self.pipette_list) self.pipette_left_tips_dropdown = Dropdown(description="Left Tips",options=self.tipracks_list) self.pipette_right_dropdown = Dropdown(description="Pipette Right:",options=self.pipette_list) self.pipette_right_tips_dropdown = Dropdown(description="Right Tips",options=self.tipracks_list) deckware_control_groups.append(self.pipette_left_dropdown) deckware_control_groups.append(self.pipette_left_tips_dropdown) deckware_control_groups.append(self.pipette_right_dropdown) deckware_control_groups.append(self.pipette_right_tips_dropdown) vbox1 = VBox([deck]) vbox2 = VBox(deckware_control_groups) vbox3 = VBox([ # self.pipette_left_dropdown, # self.pipette_left_tips_dropdown, #self.pipette_right_dropdown, #self.pipette_right_tips_dropdown ]) hbox_deck = HBox([vbox2,vbox1,vbox3]) self.saveload_deck_label = Label("Filepath:") self.saveload_deck_input = Text(value="./deck.pkl") self.save_deck_button = Button(description="Save Deck") self.load_deck_button = Button(description="Load Deck") hbox_saveload = HBox([ self.saveload_deck_label, self.saveload_deck_input, self.save_deck_button, self.load_deck_button ]) self.send_deck_label = Label(value="OT2 IP:") self.send_deck_input = Text(value="piot2") self.send_deck_button = Button(description="Send Deck") self.send_deck_home = Checkbox(description="Home on Send",value=True) hbox_send = HBox([ self.send_deck_label, self.send_deck_input, self.send_deck_button, self.send_deck_home, ]) self.progress = ipywidgets.IntProgress(min=0,max=1,value=1) vbox = VBox([hbox_deck,hbox_saveload,hbox_send,self.progress]) return vbox