-
Notifications
You must be signed in to change notification settings - Fork 4
/
prpr.py
executable file
·188 lines (159 loc) · 7.74 KB
/
prpr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# prpr.py, a part of PR-PR (previously known as PaR-PaR), a biology-friendly language for liquid-handling robots
# Author: Nina Stawski, [email protected], [email protected]
# Copyright 2012-2013, Lawrence Berkeley National Laboratory
# http://github.com/JBEI/prpr/blob/master/license.txt
__author__ = 'Nina Stawski'
__version__ = '1.1'
import os
import sqlite3
class DatabaseHandler:
"""
Pulls all experiment info from the database and calls the appropriate parser depending on the platform
"""
def __init__(self, expID):
self.conn = sqlite3.connect('prpr.db')
self.crsr = self.conn.cursor()
self.expID = str(expID)
self.getExperimentInfo()
self.mfWellLocations = {}
self.mfWellConnections = {}
self.getMFinfo()
self.transfers = []
self.getAllTransfers()
self.close()
def getAllTransfers(self):
command = 'SELECT ActionID, Type FROM Actions WHERE ExpID = ' + self.expID + ' ORDER BY ActionID ASC'
self.crsr.execute(command)
self.allTransfers = self.crsr.fetchall()
for t in range(0, len(self.allTransfers)):
transfer = self.allTransfers[t]
transferID = str(transfer[0])
transferType = transfer[1]
tr = self.getTransfer(transferID, transferType)
self.transfers.append(tr)
def getExperimentInfo(self):
info = self.getOne('SELECT * from Experiments WHERE ExpID = ' + self.expID)
self.maxTips = info[1]
self.maxVolume = info[2]
self.platform = info[3]
self.language = info[4]
def getTransfer(self, actionID, type):
if type == 'transfer':
command = 'SELECT srcWellID, dstWellID, Volume, Method FROM Transfers WHERE ExpID = ' + self.expID + ' AND ActionID = ' + str(actionID) + ' ORDER BY trOrder ASC'
elif type == 'command':
command = 'SELECT Command, Options, ActionID, trOrder FROM Commands WHERE ExpID = ' + self.expID + ' AND ActionID = ' + str(actionID) + ' ORDER BY trOrder ASC'
self.crsr.execute(command)
transferElements = self.crsr.fetchall()
transfer = {'type' : type, 'info' : []}
for element in transferElements:
if type == 'transfer':
srcWell = self.getWell(element[0])
dstWell = self.getWell(element[1])
if self.platform == "tecan":
volume = eval(element[2])
else:
volume = element[2]
method = element[3]
transfer['info'].append({ 'source' : srcWell, 'destination' : dstWell, 'volume' : volume, 'method' : method })
if type == 'command':
if element[0] == 'mix':
mixOptions = element[1].split('x')
m = self.getAll('SELECT Location FROM CommandLocations WHERE ActionID = ' + str(actionID), order='ORDER BY trOrder ASC')
for well in m:
w = self.getWell(well)
print('mix', mixOptions, element)
transfer['info'].append({'command' : 'mix', 'volume' : mixOptions[0], 'times' : mixOptions[1], 'target' : w })
elif element[0] == 'move':
trOrder = element[-1]
m = self.getAll('SELECT Location FROM CommandLocations WHERE ActionID = ' + str(actionID) + ' AND trOrder = ' + str(trOrder), order='ORDER BY trOrder ASC')
for move in m:
transfer['info'].append({'command' : 'move', 'location' : move})
elif element[0] == 'message' or element[0] == 'comment':
command = element[0]
message = element[1]
transfer['info'].append({'command' : command, 'message' : message})
elif element[0] == 'wait':
print('element is wait in the database', element, element[1])
wait = element[1]
transfer['info'].append({'command' : 'wait', 'wait' : wait})
return transfer
def getMFinfo(self): #mfWellLocations, mfWellConnections
wells = self.getAll('SELECT DISTINCT WellName FROM mfWellLocations WHERE ExpID = ' + self.expID)
for well in wells:
location = self.getOne('SELECT WellCoords from mfWellLocations WHERE WellName = "' + well + '" AND ExpID = ' + self.expID)[0]
connections = self.getAll('SELECT ConnectionName FROM mfWellConnections WHERE WellName = "' + well + '" AND ExpID = ' + self.expID)
self.mfWellConnections[well] = connections
self.mfWellLocations[well] = tuple(int(x) for x in location.split(','))
def getWell(self, wellID):
message = 'SELECT Plate, Location FROM Wells WHERE WellID = ' + str(wellID)
w = self.getOne(message)
plateName = w[0]
if self.platform == 'tecan':
wellLocation = eval(w[1])
else:
wellLocation = w[1]
plateDimensions = self.getOne('SELECT Rows, Columns FROM Plates NATURAL JOIN PlateLocations WHERE Plate = "' + plateName + '"')
plateLocation = self.getOne('SELECT Grid, Site, PlateLocation FROM PlateLocations WHERE Plate = "' + plateName + '"')
componentName = self.getOne('select Name from (ComponentNames NATURAL JOIN Components NATURAL JOIN Wells) WHERE ExpID = ' + self.expID +' AND WellID = ' + str(wellID))[0]
wellPlateName = self.getOne('select Plate from (ComponentNames NATURAL JOIN Components NATURAL JOIN Wells) WHERE ExpID = ' + self.expID +' AND WellID = ' + str(wellID))[0]
return { 'well' : wellLocation, 'plateDimensions' : plateDimensions, 'plate' : plateLocation, 'componentName' : componentName, 'plateName' : wellPlateName }
def getOne(self, message):
self.crsr.execute(message + ' AND ExpID = ' + self.expID)
row = self.crsr.fetchone()
return row
def getAll(self, message, order=''):
self.crsr.execute(message + ' AND ExpID = ' + self.expID + ' ' + order)
all = []
for item in self.crsr.fetchall():
all.append(item[0])
return all
def close(self):
self.conn.commit()
self.crsr.close()
self.conn.close()
@staticmethod
def db(request):
conn = sqlite3.connect('prpr.db')
c = conn.cursor()
c.execute(request)
q = c.fetchall()
conn.commit()
c.close()
conn.close()
return q
class Well:
def __init__(self, dict_):
self.plate = dict_['Plate']
self.location = dict_['Location']
class Component:
# method = 'LC_W_Bot_Bot'
def __init__(self, dict_):
self.name = dict_['name']
self.location = dict_['location']
self.shortLocation = dict_['location']
if 'method' in dict_:
self.method = dict_['method']
else:
self.method = 'empty'
class Plate:
def __init__(self, plateName, factoryName, plateLocation, platform, plateLocationDescription='', dimensions=()):
self.name = plateName
self.factoryName = factoryName
self.location = plateLocation
self.plateLocationDescription = plateLocationDescription
if platform != 'human':
db = DatabaseHandler.db('SELECT Rows, Columns from Plates WHERE FactoryName=' + '"' + factoryName + '"')
self.dimensions = db[0]
else:
self.dimensions = dimensions
class Volume:
def __init__(self, dict):
self.name = dict['name']
self.amount = dict['amount']
class Recipe:
def __init__(self, name):
self.subrecipes = {}
self.name = name
self.lineCounter = 0
def addSubrecipe(self, name, info):
self.subrecipes[name] = info