def runIncubation(self, src=None, vol=None, srcdil=None, tgt=None, enzymes=None, incTemp=37, incTime=15, hiTemp=None, hiTime=0, inPlace=False): if len(enzymes) != 1: print "ERROR: runIncubation only supports a single master mix" assert False if inPlace: if tgt is not None: print "ERROR: tgt specified for in-place incubation" assert False elif tgt is None: tgt = [ Sample("%s.%s" % (src[i].name, enzymes[0].name), decklayout.SAMPLEPLATE) for i in range(len(src)) ] if srcdil == None: # Minimum dilution (no water) srcdil = 1 / (1 - sum([1 / e.conc.dilutionneeded() for e in enzymes])) if vol is None and inPlace: vol = [s.volume * srcdil for s in src] [src, tgt, vol, srcdil] = listify([src, tgt, vol, srcdil]) # Adjust source dilution for i in range(len(src)): src[i].conc = Concentration(srcdil[i], 1) if inPlace: self.runRxInPlace(src, vol, enzymes[0], returnPlate=False) tgt = src else: self.e.stage('User', enzymes, src, tgt, vol, destMix=False) self.e.shakeSamples(tgt, returnPlate=False) if hiTemp is None: worklist.pyrun('PTC\\ptcsetpgm.py INC TEMP@%.0f,%.0f TEMP@25,30' % (incTemp, incTime * 60)) else: assert (hiTime > 0) worklist.pyrun( 'PTC\\ptcsetpgm.py INC TEMP@%.0f,%.0f TEMP@%.0f,%.0f TEMP@25,30' % (incTemp, incTime * 60, hiTemp, hiTime * 60)) self.e.runpgm("INC", incTime + hiTime + 2, False, max(vol), hotlidmode="TRACKING", hotlidtemp=10) return tgt
def runLigPgm(self, vol, ligtemp, inactivate=True, inacttemp=65): if inactivate: pgm = "LIG15-%.0f" % ligtemp worklist.pyrun( 'PTC\\ptcsetpgm.py %s TEMP@%.0f,900 TEMP@%.0f,600 TEMP@25,30' % (pgm, ligtemp, inacttemp)) self.e.runpgm(pgm, 27, False, vol, hotlidmode="TRACKING", hotlidtemp=10) elif ligtemp == 25: worklist.comment('Ligation at room temp') self.e.pause(15 * 60) else: pgm = "TRP%.0f-15" % ligtemp worklist.pyrun('PTC\\ptcsetpgm.py %s TEMP@%.0f,900 TEMP@25,30' % (pgm, ligtemp)) self.e.runpgm(pgm, 17, False, vol, hotlidmode="TRACKING", hotlidtemp=10)
def beadAddElutant(self, src, elutant=None, elutionVol=30, eluteTime=60, returnPlate=True, temp=None): if elutant is None: elutant = decklayout.WATER [src, elutionVol, elutant] = listify([src, elutionVol, elutant]) for i in range(len(src)): if elutionVol[i] < 30: print "WARNING: elution from beads with %.1f ul < minimum of 30ul" % elutionVol[ i] print " src=", src[i] self.e.transfer(elutionVol[i] - src[i].volume, elutant[i], src[i], (False, True)) if temp is None: self.e.shake(src[0].plate, dur=eluteTime, returnPlate=returnPlate) else: self.e.shake(src[0].plate, dur=30, returnPlate=False) worklist.pyrun('PTC\\ptcsetpgm.py elute TEMP@%d,%d TEMP@25,2' % (temp, eluteTime)) self.e.runpgm("elute", eluteTime / 60, False, elutionVol[0]) if returnPlate: self.e.moveplate(src[0].plate, "Home")
def runPCRInPlace(self, prefix, src, vol, ncycles, suffix, annealtemp=57, save=None): [prefix, src, vol, suffix] = listify([prefix, src, vol, suffix]) primer = [ reagents.getsample("MPCR" + prefix[i] + suffix[i]) for i in range(len(prefix)) ] self.runRxInPlace(src, vol, primer, returnPlate=(save is not None)) if save is not None: self.saveSamps(src=src, vol=5, dil=10, tgt=save, plate=decklayout.DILPLATE, dilutant=decklayout.SSDDIL) pgm = "PCR%d" % ncycles # worklist.pyrun('PTC\\ptcsetpgm.py %s TEMP@95,120 TEMP@95,30 TEMP@55,30 TEMP@72,25 GOTO@2,%d TEMP@72,180 TEMP@16,2'%(pgm,ncycles-1)) worklist.pyrun( 'PTC\\ptcsetpgm.py %s TEMP@95,120 TEMP@95,10 TEMP@%f,10 GOTO@2,%d TEMP@72,120 TEMP@25,2' % (pgm, annealtemp, ncycles - 1)) self.e.runpgm(pgm, 4.80 + 1.55 * ncycles, False, max(vol), hotlidmode="CONSTANT", hotlidtemp=100)
def runT7Pgm(self, vol, dur): if dur < 100: pgm = "TRP37-%d" % dur else: pgm = "T37-%d" % dur worklist.pyrun('PTC\\ptcsetpgm.py %s TEMP@37,%d TEMP@25,2' % (pgm, dur * 60)) self.e.runpgm(pgm, dur, False, vol)
def runRTPgm(self, dur=20, heatInactivate=False): if heatInactivate: hidur = 2 pgm = "RT-%d" % dur worklist.pyrun( 'PTC\\ptcsetpgm.py %s TEMP@37,%d TEMP@95,%d TEMP@25,2 RATE 0.5' % (pgm, dur * 60, hidur * 60)) self.e.runpgm( pgm, dur + hidur + 2.5, False, 100 ) # Volume doesn't matter since it's just an incubation, use 100ul else: if dur < 100: pgm = "TRP37-%d" % dur else: pgm = "T37-%d" % dur worklist.pyrun('PTC\\ptcsetpgm.py %s TEMP@37,%d TEMP@25,2' % (pgm, dur * 60)) self.e.runpgm( pgm, dur, False, 100 ) # Volume doesn't matter since it's just an incubation, use 100ul
def oneround(self, q, input, prefixOut, stop, prefixIn, keepCleaved, t7vol, rtvol, pcrdil, cycles, pcrvol, dolig): primerSet = [ set(["MX", "REF", "T7X", prefixIn[i] + "X", prefixOut[i] + "X"]) for i in range(len(prefixIn)) ] if keepCleaved: print "Starting new cleavage round, will add prefix: ", prefixOut assert (dolig) else: print "Starting new uncleaved round, will retain prefix: ", prefixIn print "stop=", stop, "prefixOut=", prefixOut, ", prefixIn=", prefixIn, ",t7vol=", t7vol, ",rtvol=", rtvol, ",pcrdil=", pcrdil, ",cycles=", cycles, ",dolig=", dolig if self.rtCarryForward: assert (dolig) names = [i.name for i in input] if self.rnaInput: rxs = input stopDil = 1 else: print "######## T7 ########### %.0f min" % (clock.elapsed() / 60) print "Inputs: (t7vol=%.2f)" % t7vol inconc = [inp.conc.final for inp in input] for inp in input: if inp.conc.units == 'nM': print " %s: %.1ful@%.1f %s, use %.1f ul (%.3f pmoles)" % ( inp.name, inp.volume, inp.conc.stock, inp.conc.units, t7vol / inp.conc.dilutionneeded(), t7vol * inp.conc.final / 1000) needDil = max([inp.conc.stock for inp in input]) * 1.0 / self.qConc else: print " %s: %.1ful@%.1f %s, use %.1f ul" % ( inp.name, inp.volume, inp.conc.stock, inp.conc.units, t7vol / inp.conc.dilutionneeded()) needDil = 100 / self.qConc # Assume 100nM # inp.conc.final=inp.conc.stock*self.templateDilution if self.directT7 and self.rndNum == 1: # Just add ligands and MT7 to each well if not keepCleaved: for i in range(len(input)): if self.inputs[i]['ligand'] is not None: ligand = reagents.getsample( self.inputs[i]['ligand']) self.e.transfer(t7vol / ligand.conc.dilutionneeded(), ligand, input[i], mix=(False, False)) names[i] += "+" mconc = reagents.getsample("MT7").conc.dilutionneeded() for i in range(len(input)): watervol = t7vol * (1 - 1 / mconc) - input[i].volume if watervol > 0.1: self.e.transfer(watervol, decklayout.WATER, input[i], mix=(False, False)) self.e.transfer(t7vol / mconc, reagents.getsample("MT7"), input[i], mix=(False, False)) assert (abs(input[i].volume - t7vol) < 0.1) rxs = input elif self.rndNum == len( self.rounds) and self.finalPlus and keepCleaved: rxs = self.runT7Setup( src=input, vol=t7vol, srcdil=[inp.conc.dilutionneeded() for inp in input]) for i in range(len(input)): inp = input[i] if self.inputs[i]['ligand'] is not None: rxs += self.runT7Setup( ligands=[ reagents.getsample(self.inputs[i]['ligand']) ], src=[inp], vol=t7vol, srcdil=[inp.conc.dilutionneeded()]) prefixIn += [prefixIn[i]] prefixOut += [prefixOut[i]] stop += [stop[i]] primerSet += [primerSet[i]] names += ["%s+" % names[i]] elif keepCleaved: rxs = self.runT7Setup( src=input, vol=t7vol, srcdil=[inp.conc.dilutionneeded() for inp in input]) else: rxs = self.runT7Setup( ligands=[ reagents.getsample(inp['ligand']) for inp in self.inputs ], src=input, vol=t7vol, srcdil=[inp.conc.dilutionneeded() for inp in input]) if self.rndNum == 1 and "template" in self.qpcrStages: # Initial input for i in range(len(rxs)): q.addSamples(src=rxs[i], needDil=needDil, primers=primerSet[i], names=["%s.T" % names[i]]) needDil = needDil * max( [inp.conc.dilutionneeded() for inp in input]) self.runT7Pgm(dur=self.t7dur, vol=t7vol) for i in range(len(rxs)): rxs[i].name = "%s.t7" % names[i] print "Estimate usable RNA concentration in T7 reaction at %.0f nM" % self.rnaConc print "######## Stop ########### %.0f min" % (clock.elapsed() / 60) self.e.lihahome() print "Have %.1f ul before stop" % rxs[0].volume preStopVolume = rxs[0].volume self.addEDTA(tgt=rxs, finalconc=2) # Stop to 2mM EDTA final stopDil = rxs[0].volume / preStopVolume if self.saveRNA: self.saveSamps( src=rxs, vol=5, dil=self.saveRNADilution, plate=decklayout.DILPLATE, dilutant=reagents.getsample("TE8"), mix=(False, False)) # Save to check [RNA] on Qubit, bioanalyzer needDil = self.rnaConc / self.qConc / stopDil if "stopped" in self.qpcrStages: for i in range(len(rxs)): q.addSamples(src=rxs[i:i + 1], needDil=needDil, primers=primerSet[i], names=["%s.stopped" % names[i]]) print "######## RT Setup ########### %.0f min" % (clock.elapsed() / 60) hiTemp = 95 stop = ["%s-Stop" % n for n in stop] rt = self.runRT(src=rxs, vol=rtvol, srcdil=self.rtDil, heatInactivate=self.rtHI, hiTemp=hiTemp, dur=self.rtdur, incTemp=50, stop=[reagents.getsample(s) for s in stop], stopConc=self.stopConc ) # Heat inactivate also allows splint to fold rxs = rt for i in range(len(rxs)): if dolig and not self.singlePrefix: rxs[i].name = names[i] + "." + prefixOut[i] + ".rt" else: rxs[i].name = names[i] + ".rt" print "RT volume= [", ",".join(["%.1f " % x.volume for x in rxs]), "]" needDil /= self.rtDil if self.rtpostdil[self.rndNum - 1] > 1: print "Dilution after RT: %.2f" % self.rtpostdil[self.rndNum - 1] self.diluteInPlace(tgt=rxs, dil=self.rtpostdil[self.rndNum - 1]) needDil = needDil / self.rtpostdil[self.rndNum - 1] if self.rtSave: rtsv = self.saveSamps( src=rxs, vol=self.rtSaveVol, dil=self.rtSaveDil, plate=decklayout.DILPLATE, dilutant=reagents.getsample("TE8"), mix=(False, False)) # Save to check RT product on gel (2x dil) if "rt" in self.qpcrStages: for i in range(len(rxs)): q.addSamples(src=rtsv[i:i + 1], needDil=needDil / 2, primers=self.rtprimers[self.rndNum - 1] if hasattr(self, 'rtprimers') else primerSet[i], names=["%s.rt" % names[i]]) else: if "rt" in self.qpcrStages: for i in range(len(rxs)): q.addSamples(src=rxs[i:i + 1], needDil=needDil, primers=self.rtprimers[self.rndNum - 1] if hasattr(self, 'rtprimers') else primerSet[i], names=["%s.rt" % names[i]]) rtCarryForwardDil = 10 rtCarryForwardVol = 3.5 if self.rtCarryForward and not keepCleaved: # Also include RT from a prior round from here on for r in self.lastSaved: newsamp = Sample("%s.samp" % r.name, decklayout.SAMPLEPLATE) self.e.transfer(rxs[0].volume, r, newsamp, (False, False)) rxs.append(newsamp) if dolig: print "######## Ligation setup ########### %.0f min" % ( clock.elapsed() / 60) extdil = 5.0 / 4 reagents.getsample("MLigase").conc = Concentration(5) if self.ligInPlace: rxs = self.runLig(rxs, inPlace=True, srcdil=extdil, incTime=self.ligdur) else: rxs = self.runLig(rxs, inPlace=False, srcdil=extdil, vol=20, incTime=self.ligdur) print "Ligation volume= ", [x.volume for x in rxs] needDil = needDil / extdil if self.extpostdil[self.rndNum - 1] > 1: print "Dilution after extension: %.2f" % self.extpostdil[ self.rndNum - 1] self.diluteInPlace(tgt=rxs, dil=self.extpostdil[self.rndNum - 1]) needDil = needDil / self.extpostdil[self.rndNum - 1] pcrdil = pcrdil * 1.0 / self.extpostdil[self.rndNum - 1] if self.saveDil is not None: ext = self.saveSamps( src=rxs, vol=3, dil=self.saveDil, dilutant=reagents.getsample("TE8"), tgt=[ Sample("%s.ext" % n, decklayout.DILPLATE) for n in names ], mix=(False, True)) # Save cDNA product for subsequent NGS if "ext" in self.qpcrStages: for i in range(len(ext)): # Make sure we don't take more than 2 more steps maxdil = q.MAXDIL * q.MAXDIL if needDil / self.saveDil > maxdil: logging.notice( "Diluting ext by %.0fx instead of needed %.0f to save steps" % (maxdil, needDil / self.saveDil)) q.addSamples(src=[ext[i]], needDil=min(maxdil, needDil / self.saveDil), primers=primerSet[i], names=["%s.ext" % names[i]], save=False) else: if "ext" in self.qpcrStages: print "needDil=", needDil for i in range(len(names)): q.addSamples(src=[rxs[i]], needDil=needDil, primers=primerSet[i], names=["%s.ext" % names[i]]) isave = i + len(names) if isave < len(rxs): # samples restored q.addSamples(src=[rxs[isave]], needDil=needDil / rtCarryForwardDil, primers=primerSet[isave]) else: extdil = 1 self.extpostdil[self.rndNum - 1] = 1 if self.rtpostdil[self.rndNum - 1] > 1: pcrdil = pcrdil * 1.0 / self.rtpostdil[self.rndNum - 1] totalDil = stopDil * self.rtDil * self.rtpostdil[ self.rndNum - 1] * extdil * self.extpostdil[self.rndNum - 1] fracRetained = rxs[0].volume / (t7vol * totalDil) print "Total dilution from T7 to Pre-pcr Product = %.2f*%.2f*%.2f*%.2f*%.2f = %.2f, fraction retained=%.0f%%" % ( stopDil, self.rtDil, self.rtpostdil[self.rndNum - 1], extdil, self.extpostdil[self.rndNum - 1], totalDil, fracRetained * 100) if self.rtCarryForward and not keepCleaved: # Remove the extra samples assert (len(self.lastSaved) > 0) rxs = rxs[:len(rxs) - len(self.lastSaved)] self.lastSaved = [] if len(rxs) > len(input): # Have extra samples due when self.finalPlus is True rxs = rxs[0:len(input)] # Only keep -target products prefixOut = prefixOut[0:len(input)] prefixIn = prefixIn[0:len(input)] stop = stop[0:len(input)] if self.dopcr and not (keepCleaved and self.noPCRCleave): print "######### PCR ############# %.0f min" % (clock.elapsed() / 60) maxvol = max([r.volume for r in rxs]) print "PCR Volume: %.1f, Dilution: %.1f, volumes available for PCR: [%s]" % ( pcrvol, pcrdil, ",".join(["%.1f" % r.volume for r in rxs])) initConc = needDil * self.qConc / pcrdil if keepCleaved: initConc = initConc * self.cleavage # Only use cleaved as input conc else: initConc = initConc * (1 - self.cleavage) gain = pcrgain(initConc, 400, cycles) finalConc = min(200, initConc * gain) print "Estimated starting concentration in PCR = %.1f nM, running %d cycles -> %.0f nM\n" % ( needDil * self.qConc / pcrdil, cycles, finalConc) nsplit = int(math.ceil(pcrvol * 1.0 / self.maxPCRVolume)) print "Split each PCR into %d reactions" % nsplit minsrcdil = 1 / (1 - 1.0 / 3 - 1.0 / 4) sampNeeded = pcrvol / pcrdil if self.rtCarryForward and keepCleaved: sampNeeded += rtCarryForwardVol maxvol = max([r.volume for r in rxs]) minvol = min([r.volume for r in rxs]) if keepCleaved and self.rtCarryForward: assert (len(rxs) == len(rtCarryForward)) print "Saving %.1f ul of each pre-PCR sample" % ( rtCarryForwardVol) self.lastSaved = [ Sample("%s.sv" % x.name, decklayout.DILPLATE) for x in rxs ] for i in range(len(rxs)): # Save with rtCarryForwardDil dilution to reduce amount of RT consumed (will have Ct's 2-3 lower than others) self.e.transfer(rtCarryForwardVol, rxs[i], self.lastSaved[i], (False, False)) self.e.transfer( rtCarryForwardVol * (rtCarryForwardDil - 1), decklayout.WATER, self.lastSaved[i], (False, True) ) # Use pipette mixing -- shaker mixing will be too slow #print "NSplit=",nsplit,", PCR vol=",pcrvol/nsplit,", srcdil=",pcrdil,", input vol=",pcrvol/nsplit/pcrdil minvol = min([r.volume for r in rxs]) maxpcrvol = (minvol - 15 - 1.4 * nsplit) * pcrdil if maxpcrvol < pcrvol: print "Reducing PCR volume from %.1ful to %.1ful due to limited input" % ( pcrvol, maxpcrvol) pcrvol = maxpcrvol if keepCleaved: master = "MTaqC" else: master = "MTaqU" if self.barcoding: primers = self.bcprimers[self.rndNum - 1] if primers is not None and nsplit > 1: primers = primers * nsplit else: primers = None if primers is None: primers = [("T7%sX" % x).replace("T7T7", "T7") for x in prefixOut] * nsplit print "Running PCR with master=", master, ", primers=", primers pcr = self.runPCR(src=rxs * nsplit, vol=pcrvol / nsplit, srcdil=pcrdil, ncycles=cycles, primers=primers, usertime=self.usertime if keepCleaved else None, fastCycling=False, inPlace=False, master=master, lowhi=self.lowhi, annealTemp=57) if keepCleaved and self.regenPCRCycles is not None: # Regenerate prefix pcr2 = self.runPCR(src=pcr, vol=self.regenPCRVolume, srcdil=self.regenPCRDilution, ncycles=self.regenPCRCycles, primers=None, usertime=None, fastCycling=False, inPlace=False, master="MTaqR", lowhi=self.lowhi, annealTemp=55) # Add BT575p for 1 more cycle for p in pcr2: self.e.transfer(p.volume * 0.5 / 10, reagents.getsample("Unclvd-Stop"), p, (False, False)) # One more cycle cycling = ' TEMP@95,30 TEMP@55,30 TEMP@68,30 TEMP@25,2' worklist.pyrun('PTC\\ptcsetpgm.py rfin %s' % (cycling)) self.e.runpgm("rfin", 5.0, False, max([p.volume for p in pcr2]), hotlidmode="CONSTANT", hotlidtemp=100) pcr = pcr2 # Use 2nd PCR as actual output if len(pcr) <= len(names): # Don't relabel if we've split for i in range(len(pcr)): pcr[i].name = names[i] + ".pcr" #print "Volume remaining in PCR input source: [",",".join(["%.1f"%r.volume for r in rxs]),"]" needDil = finalConc / self.qConc print "Projected final concentration = %.0f nM" % (needDil * self.qConc) for i in range(len(pcr)): pcr[i].conc = Concentration(stock=finalConc, final=None, units='nM') if self.pcrSave: # Save samples at 1x (move all contents -- can ignore warnings) maxSaveVol = (100 if self.savedilplate else 1500) * 1.0 / nsplit if self.finalRound and nsplit == 1 and self.savedilplate: print "Skipping save of final PCR" sv = pcr else: sv = self.saveSamps( src=pcr[:len(rxs)], vol=[ min([maxSaveVol, x.volume]) for x in pcr[:len(rxs)] ], dil=1, plate=(decklayout.DILPLATE if self.savedilplate else decklayout.EPPENDORFS), atEnd=self.savePCRAtEnd) if nsplit > 1: # Combine split for i in range(len(rxs), len(rxs) * nsplit): self.e.transfer(min([maxSaveVol, pcr[i].volume]), pcr[i], sv[i % len(sv)], mix=(False, i >= len(rxs) * (nsplit - 1))) # Correct concentration (above would've assumed it was diluted) for i in range(len(sv)): sv[i].conc = pcr[i].conc if "pcr" in self.qpcrStages: for i in range(len(sv)): q.addSamples(sv[i], needDil, primers=primerSet[i], names=["%s.pcr" % names[i]]) processEff = 0.5 # Estimate of overall efficiency of process print "Have %.2f pmoles of product (%.0f ul @ %.1f nM)" % ( sv[0].volume * sv[0].conc.stock / 1000, sv[0].volume, sv[0].conc.stock) return sv else: assert "pcr" not in self.qpcrStages ## Not implemented return pcr[:len(rxs)] elif self.noPCRCleave: print "Dilution instead of PCR: %.2f" % self.nopcrdil # Need to add enough t7prefix to compensate for all of the Stop primer currently present, regardless of whether it is for cleaved or uncleaved # Will result in some short transcripts corresponding to the stop primers that are not used for cleaved product, producing just GGG_W_GTCTGC in the next round. These would be reverse-trancribed, but may compete for T7 yield t7prefix = reagents.getsample("BT88") dil = self.extpostdil[self.rndNum - 1] * userDil stopconc = 1000.0 / dil bt88conc = t7prefix.conc.stock relbt88 = stopconc / bt88conc print "Using EXT with %.0fnM of stop oligo as input to next T7, need %.2ful of BT88@%.0fnM per ul of sample" % ( stopconc, relbt88, bt88conc) for r in rxs: vol = r.volume * relbt88 t7prefix.conc.final = t7prefix.conc.stock * vol / (r.volume + vol) r.conc.final = r.conc.stock * r.volume / (r.volume + vol) self.e.transfer(vol, t7prefix, r, mix=(False, False)) if self.nopcrdil > (1 + relbt88): self.diluteInPlace(tgt=rxs, dil=self.nopcrdil / (1.0 + relbt88)) needDil = needDil / self.nopcrdil print "Dilution of EXT product: %.2fx * %.2fx = %2.fx\n" % ( 1 + relbt88, self.nopcrdil / (1 + relbt88), self.nopcrdil) else: print "Dilution of EXT product: %.2fx\n" % (1 + relbt88) return rxs else: return rxs
def runPCR(self, prefix, src, vol, srcdil, tgt=None, ncycles=20, suffix='S', sepPrimers=True, primerDil=4): ## PCR [prefix, src, tgt, vol, srcdil, suffix] = listify([prefix, src, tgt, vol, srcdil, suffix]) for i in range(len(tgt)): if tgt[i] is None: tgt[i] = Sample( "%s.P%s%s" % (src[i].name, prefix[i], suffix[i]), src[i].plate) # Adjust source dilution for i in range(len(src)): src[i].conc = Concentration(srcdil[i], 1) if sepPrimers: sampvols = [vol[i] / srcdil[i] for i in range(len(src))] mm = reagents.getsample("MPCR") mmvols = [ vol[i] / mm.conc.dilutionneeded() for i in range(len(src)) ] for s in prefix + suffix: if not reagents.isReagent(s): reagents.add(name=s, conc=primerDil, extraVol=30) sprefix = [reagents.getsample(p) for p in prefix] ssuffix = [reagents.getsample(p) for p in suffix] prefixvols = [ vol[i] / sprefix[i].conc.dilutionneeded() for i in range(len(src)) ] suffixvols = [ vol[i] / ssuffix[i].conc.dilutionneeded() for i in range(len(src)) ] watervols = [ vol[i] - mmvols[i] - prefixvols[i] - suffixvols[i] - sampvols[i] for i in range(len(src)) ] print "water=", watervols, ", mm=", mmvols, ", prefix=", prefixvols, ", suffix=", suffixvols, ", samp=", sampvols self.e.multitransfer(watervols, decklayout.WATER, tgt, (False, False)) # Transfer water self.e.multitransfer(mmvols, mm, tgt, (False, False)) # PCR master mix sprefixset = set(sprefix) ssuffixset = set(ssuffix) if len(sprefixset) < len(ssuffixset): # Distribute sprefix first for p in sprefixset: self.e.multitransfer([ prefixvols[i] for i in range(len(src)) if sprefix[i] == p ], p, [tgt[i] for i in range(len(src)) if sprefix[i] == p], (False, False)) # Then individually add ssuffix for i in range(len(src)): self.e.transfer(suffixvols[i], ssuffix[i], tgt[i], (False, False)) else: # Distribute ssuffix first for p in ssuffixset: self.e.multitransfer([ suffixvols[i] for i in range(len(src)) if ssuffix[i] == p ], p, [tgt[i] for i in range(len(src)) if ssuffix[i] == p], (False, False)) # Then individually add sprefix for i in range(len(src)): self.e.transfer(prefixvols[i], sprefix[i], tgt[i], (False, False)) # Now add templates for i in range(len(src)): self.e.transfer(sampvols[i], src[i], tgt[i], (False, False)) else: primer = [prefix[i] + suffix[i] for i in range(len(prefix))] print "primer=", primer for up in set(primer): s = "MPCR%s" % up if not reagents.isReagent(s): reagents.add(name=s, conc=4 / 3.0, extraVol=30) self.e.stage( 'PCR%s' % up, [reagents.getsample("MPCR%s" % up)], [src[i] for i in range(len(src)) if primer[i] == up], [tgt[i] for i in range(len(tgt)) if primer[i] == up], [vol[i] for i in range(len(vol)) if primer[i] == up], destMix=False) pgm = "PCR%d" % ncycles self.e.shakeSamples(tgt, returnPlate=False) # worklist.pyrun('PTC\\ptcsetpgm.py %s TEMP@95,120 TEMP@95,30 TEMP@55,30 TEMP@72,25 GOTO@2,%d TEMP@72,180 TEMP@16,2'%(pgm,ncycles-1)) worklist.pyrun( 'PTC\\ptcsetpgm.py %s TEMP@95,120 TEMP@95,10 TEMP@57,10 GOTO@2,%d TEMP@72,120 TEMP@25,2' % (pgm, ncycles - 1)) self.e.runpgm(pgm, 4.80 + 1.55 * ncycles, False, max(vol), hotlidmode="CONSTANT", hotlidtemp=100) return tgt