Example #1
0
    def runLig(self,prefix=None,src=None,vol=None,srcdil=None,tgt=None,master=None,anneal=True,ligtemp=25):
        if master is None:
            master=[reagents.getsample("MLigAN7") if p=='A' else reagents.getsample("MLigBN7") for p in prefix]

        #Extension
        [src,tgt,vol,srcdil,master]=listify([src,tgt,vol,srcdil,master])
        if tgt is None:
            tgt=[Sample("%s.%s"%(src[i].name,master[i].name),decklayout.SAMPLEPLATE) for i in range(len(src))]

        # Need to check since an unused ligation master mix will not have a concentration
        minsrcdil=1/(1-1/master[0].conc.dilutionneeded()-1/reagents.getsample("MLigase").conc.dilutionneeded())
        for i in srcdil:
            if i<minsrcdil:
                print "runLig: srcdil=%.2f, but must be at least %.2f based on concentrations of master mixes"%(i,minsrcdil)
                assert(False)

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc=Concentration(srcdil[i],1)

        i=0
        while i<len(tgt):
            lasti=i+1
            while lasti<len(tgt) and master[i]==master[lasti]:
                lasti=lasti+1
            self.e.stage('LigAnneal',[master[i]],src[i:lasti],tgt[i:lasti],[vol[j]/1.5 for j in range(i,lasti)],1.5,destMix=False)
            i=lasti
            
        if anneal:
            self.e.shakeSamples(tgt,returnPlate=False)
            self.e.runpgm("TRPANN",5,False,max(vol),hotlidmode="CONSTANT",hotlidtemp=100)
        self.e.stage('Ligation',[reagents.getsample("MLigase")],[],tgt,vol,destMix=False)
        self.e.shakeSamples(tgt,returnPlate=False)
        self.runLigPgm(max(vol),ligtemp)
        return tgt
Example #2
0
    def runLigInPlace(self, src, vol, ligmaster, anneal=True, ligtemp=25):
        'Run ligation on beads'
        [vol, src] = listify([vol, src])
        annealvol = [
            v * (1 - 1 / reagents.getsample("MLigase").conc.dilutionneeded())
            for v in vol
        ]

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc = None

        self.runRxInPlace(src,
                          annealvol,
                          reagents.getsample(ligmaster),
                          returnPlate=not anneal,
                          finalx=1.5)
        if anneal:
            self.e.runpgm("TRPANN",
                          5,
                          False,
                          max([s.volume for s in src]),
                          hotlidmode="CONSTANT",
                          hotlidtemp=100)

        ## Add ligase
        self.runRxInPlace(src,
                          vol,
                          reagents.getsample("MLigase"),
                          returnPlate=False)
        self.runLigPgm(
            max(vol), ligtemp, inactivate=False
        )  # Do not heat inactivate since it may denature the beads
Example #3
0
 def runAmpure(self,src,ratio,tgt=None,incTime=5*60,elutionVol=None,evapTime=2*60):
     if elutionVol is None:
         elutionVol=src[0].volume
     self.bindBeads(src=src,beads=reagents.getsample("Ampure"),beadDil=(ratio+1)/ratio,incTime=incTime)
     self.beadWash(src=src,wash=reagents.getsample("EtOH80"),washVol=100,numWashes=2)
     self.e.pause(evapTime)	# Wait for evaporation
     self.beadAddElutant(src=src,elutant=reagents.getsample("TE8"),elutionVol=elutionVol)
     tgt=self.beadSupernatant(src=src,sepTime=120,tgt=[Sample("%s.ampure"%r.name,decklayout.SAMPLEPLATE) for r in src])
     return tgt
Example #4
0
    def bindBeads(self,
                  src,
                  beads=None,
                  beadConc=None,
                  bbuffer=None,
                  incTime=60,
                  addBuffer=False):
        if beads is None:
            beads = reagents.getsample("Dynabeads")
        if bbuffer is None:
            bbuffer = reagents.getsample("BeadBuffer")

        [src, beads, bbuffer,
         beadConc] = listify([src, beads, bbuffer, beadConc])

        for s in src:
            if s.plate != decklayout.SAMPLEPLATE:
                print "runBeadCleanup: src ", s, " is not in sample plate."
                assert (0)
            s.conc = None  # Can't track concentration of beads

        self.e.moveplate(src[0].plate,
                         "Home")  # Make sure we do this off the magnet

        # Calculate volumes needed
        beadConc = [
            beads[i].conc.final if beadConc[i] is None else beadConc[i]
            for i in range(len(beads))
        ]
        beadDil = beads[i].conc.stock / beadConc[i]
        if addBuffer:
            totalvol = [
                s.volume /
                (1 - 1.0 / beadDil - 1.0 / bbuffer[i].conc.dilutionneeded())
                for s in src
            ]
            buffervol = [
                totalvol[i] / bbuffer[i].conc.dilutionneeded()
                for i in range(len(src))
            ]
            # Add binding buffer to bring to 1x (beads will already be in 1x, so don't need to provide for them)
            for i in range(len(src)):
                self.e.transfer(buffervol[i], bbuffer[i], src[i])
        else:
            buffervol = [0.0 for i in range(len(src))]
            totalvol = [s.volume / (1 - 1.0 / beadDil) for s in src]

        beadvol = [t / beadDil for t in totalvol]

        # Transfer the beads
        for i in range(len(src)):
            self.e.transfer(
                beadvol[i], beads[i], src[i], (True, True)
            )  # Mix beads after (before mixing handled automatically by sample.py)

        self.e.shake(src[0].plate, dur=incTime, returnPlate=False)
Example #5
0
    def runQPCR(self,src,vol,primers,nreplicates=1,enzName="EvaUSER"):
        ## QPCR setup
        worklist.comment("runQPCR: primers=%s, source=%s"%([p for p in primers],[s.name for s in src]))
        [src,vol,nreplicates]=listify([src,vol,nreplicates])
        self.e.shakeSamples(src,returnPlate=True)

        # Build a list of sets to be run
        torun=[]
        for repl in range(max(nreplicates)):
            for p in primers:
                for i in range(len(src)):
                    if nreplicates[i]<=repl:
                        continue
                    if repl==0:
                        sampname="%s.Q%s"%(src[i].name,p)
                    else:
                        sampname="%s.Q%s.%d"%(src[i].name,p,repl+1)
                    s=Sample(sampname,decklayout.QPCRPLATE)
                    torun=torun+[(src[i],s,p,vol[i])]

        # Add enzyme
        e=reagents.getsample(enzName)
        v=[a[3]/e.conc.dilutionneeded() for a in torun]
        t=[a[1] for a in torun]
        self.e.multitransfer(v,e,t)

        # Make the target have 'none' concentration so we can multiadd to it again
        for s in t:
            s.conc=None

        # Fill the master mixes
        dil={}
        for p in primers:
            mname="P-%s"%p
            if not reagents.isReagent(mname):
                reagents.add(name=mname,conc=4,extraVol=30)
            mq=reagents.getsample(mname)
            t=[a[1] for a in torun if a[2]==p]
            v=[a[3]/mq.conc.dilutionneeded() for a in torun if a[2]==p]
            assert(v>0)
            self.e.multitransfer(v,mq,t,(False,False))
            dil[p]=1.0/(1-1/e.conc.dilutionneeded()-1/mq.conc.dilutionneeded())
            
        # Add the samples
        self.e.sanitize()		# In case we are aligned
        for a in torun:
            s=a[0]
            t=a[1]
            p=a[2]
            v=a[3]/dil[p]
            t.conc=None		# Concentration of master mix is irrelevant now
            self.e.transfer(v,s,t)
            
        return [a[1] for a in torun]
Example #6
0
    def runT7Setup(self, theo, src, vol, srcdil, tgt=None, rlist=["MT7"]):
        [theo, src, tgt, srcdil] = listify([theo, src, tgt, srcdil])
        for i in range(len(src)):
            if tgt[i] is None:
                if theo[i]:
                    tgt[i] = Sample("%s.T+" % src[i].name,
                                    decklayout.SAMPLEPLATE)
                else:
                    tgt[i] = Sample("%s.T-" % src[i].name,
                                    decklayout.SAMPLEPLATE)

        worklist.comment("runT7: source=%s" % [str(s) for s in src])

        rvols = [reagents.getsample(x).conc.volneeded(vol) for x in rlist]
        rtotal = sum(rvols)
        sourcevols = [vol * 1.0 / s for s in srcdil]
        if any(theo):
            theovols = [
                (vol * 1.0 /
                 reagents.getsample("Theo").conc.dilutionneeded() if t else 0)
                for t in theo
            ]
            watervols = [
                vol - theovols[i] - sourcevols[i] - rtotal
                for i in range(len(src))
            ]
        else:
            watervols = [vol - sourcevols[i] - rtotal for i in range(len(src))]

        if any([w < -1e-10 for w in watervols]):
            print "runT7Setup: Negative amount of water required: ", watervols
            assert False
        if sum(watervols) > 0.01:
            self.e.multitransfer(watervols, decklayout.WATER, tgt)
        for ir in range(len(rlist)):
            self.e.multitransfer([rvols[ir] for s in tgt],
                                 reagents.getsample(rlist[ir]), tgt)
        if any(theo):
            self.e.multitransfer(
                [tv for tv in theovols if tv > 0.01],
                reagents.getsample("Theo"),
                [tgt[i] for i in range(len(theovols)) if theovols[i] > 0],
                ignoreContents=True)
        for i in range(len(src)):
            self.e.transfer(sourcevols[i], src[i], tgt[i])
        self.e.shakeSamples(tgt, returnPlate=True)
        for t in tgt:
            t.ingredients['BIND'] = 1e-20 * sum(t.ingredients.values())
        return tgt
Example #7
0
    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)
Example #8
0
    def addReferences(self,mindil=1,nsteps=6,dstep=4,nreplicates=1,ref=None,primers=None):
        'Add all needed references'
        #print "addReferences(mindil=",mindil,", nsteps=",nsteps,", dstep=",dstep,", nrep=", nreplicates, ", ref=",ref,")"
        # Make sure the ref reagent is loaded
        if ref is None:
            ref=reagents.getsample("QPCRREF")
        if primers is None:
            primers=self.allprimers()
        dils=[1]
        for i in range(nsteps):
            needDil=mindil*math.pow(dstep,i)
            srcDil=1
            src=[ref]
            for j in range(len(dils)):
                if needDil/dils[j] <= self.MAXDIL:
                    srcDil=dils[j]
                    if srcDil==1:
                        src=[ref]
                    else:
                        srcname="%s.D%d"%(ref.name,srcDil)
                        src=[Sample.lookup(srcname)]
                        if src[0] is None:
                            src=[Sample(srcname,decklayout.DILPLATE)]
                    break
            tmp=self.MINDILVOL
            self.MINDILVOL=75   # Make sure there's enough for resuing dilutions
            self.addSamples(src=src,needDil=needDil/srcDil,primers=primers,nreplicates=nreplicates,save=needDil/srcDil>self.MAXDIL,saveVol=75)
            self.MINDILVOL=tmp
            dils.append(needDil)

        self.addSamples(src=[self.dilutant],needDil=1,primers=primers,nreplicates=nreplicates,save=False)
Example #9
0
    def addReferences(self, mindil=1, nsteps=6, dstep=4, nreplicates=1, ref=None, primers=None):
        """Add all needed references"""
        # print "addReferences(mindil=",mindil,", nsteps=",nsteps,", dstep=",dstep,", nrep=", nreplicates, ", ref=",ref,")"
        # Make sure the ref reagent is loaded
        if ref is None:
            ref = reagents.getsample("QPCRREF")
        if primers is None:
            primers = self.allprimers()
        dils = [1.0]
        for i in range(nsteps):
            needDil = mindil * math.pow(dstep, i)
            srcDil = 1
            src = [ref]
            for j in range(len(dils)):
                if needDil / dils[j] <= self.MAXDIL:
                    srcDil = dils[j]
                    if srcDil == 1:
                        src = [ref]
                    else:
                        srcname = "%s.D%d" % (ref.name, srcDil)
                        src = [Sample.lookup(srcname)]
                        if src[0] is None:
                            src = [Sample(srcname, decklayout.DILPLATE)]
                    break
            tmp = self.MINDILVOL
            self.MINDILVOL = 75  # Make sure there's enough for resuing dilutions
            self.addSamples(src=src, needDil=needDil / srcDil, primers=primers, nreplicates=nreplicates,
                            save=needDil / srcDil > self.MAXDIL, saveVol=75)
            self.MINDILVOL = tmp
            dils.append(needDil)

        self.addSamples(src=[self.dilutant], needDil=1, primers=primers, nreplicates=nreplicates, save=False)
Example #10
0
    def pgm(self):
        self.q = QSetup(self, maxdil=16, debug=False, mindilvol=60)

        #  Don't start idler (to minimize tip cross-contamination); last PCR allows plenty of time for doing dilutions without any effect on run time
        # Will start after first constriction PCR is running
        #self.q.debug = True
        # self.e.addIdleProgram(self.q.idler)

        self.q.addReferences(dstep=10, primers=self.qprimers, ref=reagents.getsample("BT5310"),nreplicates=2)

        samps=[r.getsample() for r in self.rsrc]
        for s in samps:
            self.q.addSamples([s],needDil=max(10,s.conc.stock*1e-9/self.qconc),primers=self.qprimers)
        print("### Mixdown #### (%.0f min)" % (clock.elapsed() / 60.0))
        if len(samps)>1:
            mixdown = self.mix(samps, [x['weight'] for x in self.inputs])
        else:
            mixdown=samps[0]
        self.q.addSamples(mixdown, needDil=max(1.0,mixdown.conc.stock * 1e-9 / self.qconc), primers=self.qprimers)
        print("Mixdown final concentration = %.0f pM" % (mixdown.conc.stock * 1000))
        print("### Constriction #### (%.1f min)" % (clock.elapsed() / 60.0))
        constricted = self.constrict(mixdown, mixdown.conc.stock * 1e-9)
        print("### Regeneration #### (%.0f min)" % (clock.elapsed() / 60.0))
        prefixes = set([x['left'][0] for x in self.inputs])
        self.regenerate(constricted * len(prefixes), [p for p in prefixes for _ in constricted])
        print("### qPCR #### (%.0f min)" % (clock.elapsed() / 60.0))
        self.q.run(confirm=False, enzName='EvaGreen', waitForPTC=True)
        print("### qPCR Done #### (%.0f min)" % (clock.elapsed() / 60.0))
        worklist.userprompt("qPCR done -- only need to complete final PCR", 300)
        self.e.waitpgm()
        print("### Final PCR Done #### (%.0f min)" % (clock.elapsed() / 60.0))
Example #11
0
    def runLigInPlace(self,src,vol,ligmaster,anneal=True,ligtemp=25):
        'Run ligation on beads'
        [vol,src]=listify([vol,src])
        annealvol=[v*(1-1/reagents.getsample("MLigase").conc.dilutionneeded()) for v in vol]

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc=None

        self.runRxInPlace(src,annealvol,reagents.getsample(ligmaster),returnPlate=not anneal,finalx=1.5)
        if anneal:
            self.e.runpgm("TRPANN",5,False,max([s.volume for s in src]),hotlidmode="CONSTANT",hotlidtemp=100)

        ## Add ligase
        self.runRxInPlace(src,vol,reagents.getsample("MLigase"),returnPlate=False)
        self.runLigPgm(max(vol),ligtemp,inactivate=False)	# Do not heat inactivate since it may denature the beads
Example #12
0
    def __init__(self, inputs, pcr1inputconc=0.05, used=None,doqpcr=True,inputPlate=decklayout.SAMPLEPLATE):
        super(Barcoding, self).__init__()
        if used is None:
            used = []
        self.inputs = inputs

        self.qconc = 50e-12  # Target qPCR concentration
        self.qprimers = ["End"]
        self.doqpcr=doqpcr
        
        self.bc1_inputvol = 4  # ul of input samples
        self.mix_conc = 100e-9  # Concentration of mixdown
        self.pcr1inputconc = pcr1inputconc

        for inp in inputs:
            bc = "%s-%s" % (inp['left'], inp['right'])
            if bc in used:
                logging.error("Barcode %s is being reused for %s" % (bc, inp['name']))
            used.append(bc)

        for x in inputs:
            if not reagents.isReagent(x['name']):
                reagents.add(x['name'], inputPlate, well=x['well'] if 'well' in x else None,
                             conc=Concentration(stock=x['conc'], units="nM"),
                             initVol=self.bc1_inputvol, extraVol=0)
            else:
                r = reagents.getsample(x['name'])
                if r.conc.stock != x['conc']:
                    logging.error('Input %s has conflicting concentrations set:  %f and %f', x['name'], r.conc.stock,
                                  x['conc'])
                    assert False

        self.q = None  # Defined in pgm()
Example #13
0
    def runT7Setup(self,src,vol,srcdil,ligands=None,tgt=None,rlist=["MT7"]):
        if isinstance(ligands,bool):
            if not ligands:
                ligands=None
            else:
                assert('runT7Setup:  ligands arg should be ligand samples or None, not True')
                
        [ligands,src,tgt,srcdil]=listify([ligands,src,tgt,srcdil])
        for i in range(len(src)):
            if tgt[i] is None:
                if ligands[i] is not None:
                    tgt[i]=Sample("%s.T+%s"%(src[i].name,ligands[i].name),decklayout.SAMPLEPLATE)
                else:
                    tgt[i]=Sample("%s.T-"%src[i].name,decklayout.SAMPLEPLATE)


        worklist.comment("runT7: source=%s"%[str(s) for s in src])

        rvols=[reagents.getsample(x).conc.volneeded(vol) for x in rlist]
        rtotal=sum(rvols)
        sourcevols=[vol*1.0/s for s in srcdil]
        ligandvols=[0 for s in srcdil]
        watervols=[0 for s in srcdil]
        for i in range(len(srcdil)):
            if ligands[i] is not None:
                ligandvols[i]=vol*1.0/ligands[i].conc.dilutionneeded()
                watervols[i]=vol-ligandvols[i]-sourcevols[i]-rtotal
            else:
                watervols[i]=vol-sourcevols[i]-rtotal

        if any([w<-.01 for w in watervols]):
            logging.error("runT7Setup: Negative amount of water required: "+str(watervols))

        if sum(watervols)>0.01:
            self.e.multitransfer(watervols,decklayout.WATER,tgt)
        for ir in range(len(rlist)):
            self.e.multitransfer([rvols[ir] for s in tgt],reagents.getsample(rlist[ir]),tgt)
        for i in range(len(ligands)):
            if ligandvols[i] > 0.01:
                self.e.transfer(ligandvols[i],ligands[i],tgt[i])
        for i in range(len(src)):
            self.e.transfer(sourcevols[i],src[i],tgt[i])
        self.e.shakeSamples(tgt,returnPlate=True)
        for t in tgt:
            t.ingredients['BIND']=1e-20*sum(t.ingredients.values())
        return tgt
Example #14
0
 def addEDTA(self,tgt,finalconc=4):
     edta=reagents.getsample("EDTA")
     edta.conc.final=finalconc
     srcdil=edta.conc.stock*1.0/(edta.conc.stock-finalconc)
     for t in tgt:
         t.conc=Concentration(srcdil,1)
         v=t.volume*finalconc/(edta.conc.stock-finalconc)
         self.e.transfer(v,edta,t,mix=(False,False))
     self.e.shakeSamples(tgt,returnPlate=True)
Example #15
0
    def runRTInPlace(self,src,vol,dur=20,heatInactivate=False):
        'Run RT on beads in given volume'

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc=None

        self.runRxInPlace(src,vol,reagents.getsample("MPosRT"),returnPlate=False)
        self.runRTPgm(dur,heatInactivate=heatInactivate)
Example #16
0
    def pgm(self):
        self.q = QSetup(self, maxdil=16, debug=False, mindilvol=60)

        self.q.debug = True
        self.q.addReferences(dstep=10, primers=self.qprimers, ref=reagents.getsample("BT5310"),nreplicates=2)

        print("### Barcoding #### (%.0f min)" % (clock.elapsed() / 60.0))
        self.idbarcoding(self.rsrc, left=[x['left'] for x in self.inputs],
                                 right=[x['right'] for x in self.inputs])
        print("### qPCR #### (%.0f min)" % (clock.elapsed() / 60.0))
        self.q.run(confirm=False, enzName='EvaGreen')
Example #17
0
    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)
Example #18
0
    def runRTInPlace(self, src, vol, dur=20, heatInactivate=False):
        'Run RT on beads in given volume'

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc = None

        self.runRxInPlace(src,
                          vol,
                          reagents.getsample("MPosRT"),
                          returnPlate=False)
        self.runRTPgm(dur, heatInactivate=heatInactivate)
Example #19
0
    def runT7Stop(self,theo,tgt,stopmaster=None,srcdil=2):
        [theo,tgt,stopmaster,srcdil]=listify([theo,tgt,stopmaster,srcdil])
        assert( stopmaster is not None)
            
        ## Stop
        sstopmaster=[reagents.getsample(s) for s in stopmaster]
        for i in range(len(tgt)):
            stopvol=tgt[i].volume/(sstopmaster[i].conc.dilutionneeded()-1)
            finalvol=tgt[i].volume+stopvol
            tgt[i].conc=Concentration(finalvol/tgt[i].volume,1)  # Adjust source dilution to avoid warnings
            self.e.transfer(finalvol-tgt[i].volume,sstopmaster[i],tgt[i])
            
        self.e.shakeSamples(tgt,returnPlate=True)

        return tgt
Example #20
0
    def runT7Setup(self,theo,src,vol,srcdil,tgt=None,rlist=["MT7"]):
        [theo,src,tgt,srcdil]=listify([theo,src,tgt,srcdil])
        for i in range(len(src)):
            if tgt[i] is None:
                if theo[i]:
                    tgt[i]=Sample("%s.T+"%src[i].name,decklayout.SAMPLEPLATE)
                else:
                    tgt[i]=Sample("%s.T-"%src[i].name,decklayout.SAMPLEPLATE)


        worklist.comment("runT7: source=%s"%[str(s) for s in src])

        rvols=[reagents.getsample(x).conc.volneeded(vol) for x in rlist]
        rtotal=sum(rvols)
        sourcevols=[vol*1.0/s for s in srcdil]
        if any(theo):
            theovols=[(vol*1.0/reagents.getsample("Theo").conc.dilutionneeded() if t else 0) for t in theo]
            watervols=[vol-theovols[i]-sourcevols[i]-rtotal for i in range(len(src))]
        else:
            watervols=[vol-sourcevols[i]-rtotal for i in range(len(src))]

        if any([w<-1e-10 for w in watervols]):
            print "runT7Setup: Negative amount of water required: ",watervols
            assert False
        if sum(watervols)>0.01:
            self.e.multitransfer(watervols,decklayout.WATER,tgt)
        for ir in range(len(rlist)):
            self.e.multitransfer([rvols[ir] for s in tgt],reagents.getsample(rlist[ir]),tgt)
        if any(theo):
            self.e.multitransfer([tv for tv in theovols if tv>0.01],reagents.getsample("Theo"),[tgt[i] for i in range(len(theovols)) if theovols[i]>0],ignoreContents=True)
        for i in range(len(src)):
            self.e.transfer(sourcevols[i],src[i],tgt[i])
        self.e.shakeSamples(tgt,returnPlate=True)
        for t in tgt:
            t.ingredients['BIND']=1e-20*sum(t.ingredients.values())
        return tgt
Example #21
0
    def bindBeads(self,src,beads=None,beadConc=None,bbuffer=None,incTime=60,addBuffer=False):
        if beads is None:
            beads=reagents.getsample("Dynabeads")
        if bbuffer is None:
            bbuffer=reagents.getsample("BeadBuffer")
            
        [src,beads,bbuffer,beadConc]=listify([src,beads,bbuffer,beadConc])

        for s in src:
            if s.plate!=decklayout.SAMPLEPLATE:
                print "runBeadCleanup: src ",s," is not in sample plate."
                assert(0)
            s.conc=None		# Can't track concentration of beads
            
        self.e.moveplate(src[0].plate,"Home")		# Make sure we do this off the magnet

        # Calculate volumes needed
        beadConc=[beads[i].conc.final if beadConc[i] is None else beadConc[i] for i in range(len(beads))]
        beadDil=beads[i].conc.stock/beadConc[i]
        if addBuffer:
            totalvol=[s.volume/(1-1.0/beadDil-1.0/bbuffer[i].conc.dilutionneeded()) for s in src]
            buffervol=[totalvol[i]/bbuffer[i].conc.dilutionneeded() for i in range(len(src))]
            # Add binding buffer to bring to 1x (beads will already be in 1x, so don't need to provide for them)
            for i in range(len(src)):
                self.e.transfer(buffervol[i],bbuffer[i],src[i])
        else:
            buffervol=[0.0 for i in range(len(src))]
            totalvol=[s.volume/(1-1.0/beadDil) for s in src]

        beadvol=[t/beadDil for t in totalvol]

        # Transfer the beads
        for i in range(len(src)):
            self.e.transfer(beadvol[i],beads[i],src[i],(True,True))	# Mix beads after (before mixing handled automatically by sample.py)

        self.e.shake(src[0].plate,dur=incTime,returnPlate=False)
Example #22
0
    def runRTSetup(self,src,vol,srcdil,tgt=None,rtmaster=None):
        if rtmaster is None:
            rtmaster=reagents.getsample("MPosRT")
        if tgt is None:
            tgt=[Sample(s.name+".RT+",decklayout.SAMPLEPLATE) 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)
            
        self.e.stage('RTPos',[rtmaster],[src[i] for i in range(len(src)) ],[tgt[i] for i in range(len(tgt)) ],[vol[i] for i in range(len(vol))],destMix=False)
        #self.e.shakeSamples(tgt,returnPlate=True)
        return tgt
Example #23
0
 def runUser(self,
             src=None,
             vol=None,
             srcdil=None,
             tgt=None,
             incTime=15,
             inPlace=False):
     return self.runIncubation(src=src,
                               vol=vol,
                               srcdil=srcdil,
                               tgt=tgt,
                               incTemp=37,
                               incTime=incTime,
                               enzymes=[reagents.getsample("MUser")],
                               inPlace=inPlace)
Example #24
0
    def runQPCR(self, src, vol, srcdil, primers=["A", "B"], nreplicates=1):
        ## QPCR setup
        worklist.comment("runQPCR: primers=%s, source=%s" %
                         ([p for p in primers], [s.name for s in src]))
        [src, vol, srcdil,
         nreplicates] = listify([src, vol, srcdil, nreplicates])
        self.e.shakeSamples(src, returnPlate=True)

        # Build a list of sets to be run
        torun = []
        for repl in range(max(nreplicates)):
            for p in primers:
                for i in range(len(src)):
                    if nreplicates[i] <= repl:
                        continue
                    if repl == 0:
                        sampname = "%s.Q%s" % (src[i].name, p)
                    else:
                        sampname = "%s.Q%s.%d" % (src[i].name, p, repl + 1)
                    s = Sample(sampname, decklayout.QPCRPLATE)
                    torun = torun + [(src[i], s, p, vol[i])]

        # Fill the master mixes
        dil = {}
        for p in primers:
            mname = "MQ%s" % p
            if not reagents.isReagent(mname):
                reagents.add(name=mname, conc=15.0 / 9.0, extraVol=30)
            mq = reagents.getsample(mname)
            t = [a[1] for a in torun if a[2] == p]
            v = [a[3] / mq.conc.dilutionneeded() for a in torun if a[2] == p]
            self.e.multitransfer(v, mq, t, (False, False))
            dil[p] = 1.0 / (1 - 1 / mq.conc.dilutionneeded())

        # Add the samples
        self.e.sanitize()  # In case we are aligned
        for a in torun:
            s = a[0]
            t = a[1]
            p = a[2]
            v = a[3] / dil[p]
            t.conc = None  # Concentration of master mix is irrelevant now
            self.e.transfer(v, s, t)

        return [a[1] for a in torun]
Example #25
0
 def runDNase(self,
              src=None,
              vol=None,
              srcdil=None,
              tgt=None,
              incTime=15,
              hiTime=10,
              inPlace=False):
     return self.runIncubation(src=src,
                               vol=vol,
                               srcdil=srcdil,
                               tgt=tgt,
                               incTemp=37,
                               incTime=incTime,
                               hiTemp=75,
                               hiTime=hiTime,
                               enzymes=[reagents.getsample("MDNase")],
                               inPlace=inPlace)
Example #26
0
    def pgm(self):
        self.q = QSetup(self, maxdil=16, debug=False, mindilvol=100)
        self.e.addIdleProgram(self.q.idler)

        if self.doqpcr:
            self.q.addReferences(dstep=10, primers=self.qprimers, ref=reagents.getsample("BT5310"))

        print("### Barcoding #### (%.0f min)" % (clock.elapsed() / 60.0))
        bcout = self.barcoding(names=[x['name'] for x in self.inputs], left=[x['left'] for x in self.inputs],
                               right=[x['right'] for x in self.inputs])

        for i in range(len(self.inputs)):
            x = self.inputs[i]
            if 'bconc' in x and x['bconc'] is not None:
                print("Resetting concentration of %s from expected %.1f to bconc setting of %.1f nM" % \
                      (x['name'], bcout[i].conc.stock, x['bconc']))
                bcout[i].conc.stock = x['bconc']

        print("### qPCR #### (%.0f min)" % (clock.elapsed() / 60.0))
        self.q.run(confirm=False, enzName='EvaGreen')
        print("### qPCR Done #### (%.0f min)" % (clock.elapsed() / 60.0))
        print("### Final PCR Done #### (%.0f min)" % (clock.elapsed() / 60.0))
        worklist.flushQueue()

        if all(['bconc' in x and x['bconc'] is not None for x in self.inputs]):
            print("### Mixdown #### (%.0f min)" % (clock.elapsed() / 60.0))
            worklist.flushQueue()
            worklist.comment('Start mixdown only at this point')
            self.e.sanitize(force=True)
            # mixdown = self.mix(bcout, [x['weight'] for x in self.inputs])
            # Set default mix number to 1
            for x in self.inputs:
                if 'mix' not in x:
                    x['mix']=1
            mixes=set([x['mix'] for x in self.inputs])
            for m in mixes:
                sel=[ i for i in range(len(self.inputs)) if self.inputs[i]['mix']==m] 
                print("sel=",sel)
                mixdown = self.mix([bcout[i] for i in sel], [self.inputs[i]['weight'] for i in sel],prefix="Mix%d_"%m)
                mixdown.name="Mix%d_Final"%m
            # self.q.addSamples(mixdown, needDil=mixdown.conc.stock * 1e-9 / self.qconc, primers=self.qprimers,nreplicates=3)
        else:
            print("### Not doing mixdown as bconc not set in all inputs")
Example #27
0
    def runT7Stop(self,theo,tgt,stopmaster=None,srcdil=2):
        [theo,tgt,stopmaster,srcdil]=listify([theo,tgt,stopmaster,srcdil])
        if stopmaster is None:
            stopmaster=["MStpS_NT" if t==0 else "MStpS_WT" for t in theo]
            
        # Adjust source dilution
        for i in range(len(tgt)):
            tgt[i].conc=Concentration(srcdil[i],1)

        ## Stop
        sstopmaster=[reagents.getsample(s) for s in stopmaster]
        for i in range(len(tgt)):
            stopvol=tgt[i].volume/(sstopmaster[i].conc.dilutionneeded()-1)
            finalvol=tgt[i].volume+stopvol
            self.e.transfer(finalvol-tgt[i].volume,sstopmaster[i],tgt[i])
            
        self.e.shakeSamples(tgt,returnPlate=True)

        return tgt
Example #28
0
 def runKlenow(self,
               src=None,
               vol=None,
               srcdil=None,
               tgt=None,
               incTime=15,
               hiTime=20,
               inPlace=False):
     assert (inPlace or vol is not None)
     return self.runIncubation(src=src,
                               vol=vol,
                               srcdil=srcdil,
                               tgt=tgt,
                               incTemp=37,
                               incTime=incTime,
                               hiTemp=75,
                               hiTime=hiTime,
                               enzymes=[reagents.getsample("MKlenow")],
                               inPlace=inPlace)
Example #29
0
    def runRTSetup(self, src, vol, srcdil, tgt=None, rtmaster=None):
        if rtmaster is None:
            rtmaster = reagents.getsample("MPosRT")
        if tgt is None:
            tgt = [
                Sample(s.name + ".RT+", decklayout.SAMPLEPLATE) 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)

        self.e.stage('RTPos', [rtmaster], [src[i] for i in range(len(src))],
                     [tgt[i] for i in range(len(tgt))],
                     [vol[i] for i in range(len(vol))],
                     destMix=False)
        #self.e.shakeSamples(tgt,returnPlate=True)
        return tgt
Example #30
0
    def runT7Stop(self, theo, tgt, stopmaster=None, srcdil=2):
        [theo, tgt, stopmaster,
         srcdil] = listify([theo, tgt, stopmaster, srcdil])
        if stopmaster is None:
            stopmaster = ["MStpS_NT" if t == 0 else "MStpS_WT" for t in theo]

        # Adjust source dilution
        for i in range(len(tgt)):
            tgt[i].conc = Concentration(srcdil[i], 1)

        ## Stop
        sstopmaster = [reagents.getsample(s) for s in stopmaster]
        for i in range(len(tgt)):
            stopvol = tgt[i].volume / (sstopmaster[i].conc.dilutionneeded() -
                                       1)
            finalvol = tgt[i].volume + stopvol
            self.e.transfer(finalvol - tgt[i].volume, sstopmaster[i], tgt[i])

        self.e.shakeSamples(tgt, returnPlate=True)

        return tgt
Example #31
0
    def runRTSetup(self,src,vol,srcdil,tgt=None,rtmaster=None,stop=None):
        if rtmaster is None:
            rtmaster=reagents.getsample("MPosRT")
        if tgt is None:
            tgt=[Sample(s.name+".RT+",decklayout.SAMPLEPLATE) for s in src]

        [src,tgt,vol,srcdil,stop]=listify([src,tgt,vol,srcdil,stop])

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc=Concentration(srcdil[i],1)
            
        stopvol=[ 0 if stop[i] is None else vol[i]/stop[i].conc.dilutionneeded() for i in range(len(vol))]
        assert(min(stopvol)==max(stopvol))   # Assume all stop volumes are the same
        self.e.stage('RTPos',[rtmaster],[src[i] for i in range(len(src)) ],[tgt[i] for i in range(len(tgt)) ],[vol[i]-stopvol[i] for i in range(len(vol))],destMix=False,finalx=vol[0]/(vol[0]-stopvol[0]))
        for i in range(len(tgt)):
            if stopvol[i]>0.1:
                self.e.transfer(stopvol[i],stop[i],tgt[i],(False,False))

        #self.e.shakeSamples(tgt,returnPlate=True)
        return tgt
Example #32
0
    def pgm(self):
        q = QSetup(self,maxdil=self.maxdilstep,debug=False,mindilvol=60)
        self.e.addIdleProgram(q.idler)

        if self.barcoding:
            # Setup barcode primers for cleaved rounds only
            self.bcprimers=[["BC-%s-R%d_T7"%(inp['ligand'],r+1) for inp in self.inputs] if self.rounds[r]=='C' else None for r in range(len(self.rounds))]
            for bcp in self.bcprimers:
                if bcp is not None:
                    for p in ["P-%s"%pp for pp in bcp]:
                        if not reagents.isReagent(p):
                            reagents.add(name=p,conc=4,extraVol=30,plate=decklayout.REAGENTPLATE,well="B2")
                        s=reagents.getsample(p)   # Force allocation of a well
                        print("Adding %s to reagents at well %s"%(p,s.plate.wellname(s.well)))
            print("BC primers=", self.bcprimers)
            
        # Add any missing fields to inputs
        for i in range(len(self.inputs)):
            if 'ligand' not in self.inputs[i]:
                self.inputs[i]['ligand']=None
            if 'negligand' not in self.inputs[i]:
                self.inputs[i]['negligand']=None
            if 'round' not in self.inputs[i]:
                self.inputs[i]['round']=None
            if 'name' not in self.inputs[i]:
                if self.inputs[i]['ligand'] is None:
                    self.inputs[i]['name']='%s_%d_R%d'%(self.inputs[i]['prefix'],self.inputs[i]['ID'],self.inputs[i]['round'])
                else:
                    self.inputs[i]['name']='%s_%d_R%d_%s'%(self.inputs[i]['prefix'],self.inputs[i]['ID'],self.inputs[i]['round'],self.inputs[i]['ligand'])

        # Add templates
        if self.directT7:
            self.srcs = self.addTemplates([inp['name'] for inp in self.inputs],stockconc=self.tmplFinalConc/self.templateDilution,finalconc=self.tmplFinalConc,plate=decklayout.SAMPLEPLATE,looplengths=[inp['looplength'] for inp in self.inputs],initVol=self.t7vol[0]*self.templateDilution,extraVol=0)
        else:
            self.srcs = self.addTemplates([inp['name'] for inp in self.inputs],stockconc=self.tmplFinalConc/self.templateDilution,finalconc=self.tmplFinalConc,plate=decklayout.DILPLATE,looplengths=[inp['looplength'] for inp in self.inputs],extraVol=15) 

        if self.dopcr:
            # Reserve space for  PCR products
            pcrprods=[ [Sample("R%d-T%s"%(r,inp['ligand']),self.savePlate) for inp in self.inputs] for r in range(len(self.rounds))]
        else:
            pcrprods=None

        t7in = [s.getsample()  for s in self.srcs]
        
        if "negative" in self.qpcrStages:
            q.addSamples(decklayout.SSDDIL,1,self.allprimers,save=False)   # Negative controls
        if "reference" in self.qpcrStages:
            q.addReferences(dstep=10,nsteps=5,primers=["WX","MX","T7X"] if self.useMX else ["WX","T7X"],ref=reagents.getsample("BT5310"),nreplicates=1)

        # Save RT product from first (uncleaved) round and then use it during 2nd (cleaved) round for ligation and qPCR measurements
        self.rndNum=0
        self.nextID=self.firstID
        curPrefix=[inp['prefix'] for inp in self.inputs]
        r1=t7in
        
        for roundType in self.rounds:
            # Run a single round of roundType with r1 as input
            # roundType is either "U" for uncleaved, or a new prefix for a cleaved round (with "T" being a T7 prepend)
            # Set r1 to new output at end

            if self.roundCallback is not None:
                self.roundCallback(self,self.rndNum,roundType)
                
            # Computed output prefix
            if roundType=='U':
                prefixOut=curPrefix
                stop=["Unclvd" for _ in curPrefix]
            else:
                if roundType=='T':
                    stop=['T7%s'%p for p in curPrefix]
                    prefixOut=curPrefix
                elif any([p==roundType for p in curPrefix]):
                    logging.error( "Round %d is a cleaved round but goes to %s without changing prefix"%(self.rndNum, roundType))
                    assert False
                else:
                    prefixOut=[roundType for _ in curPrefix]
                    stop=prefixOut

            # May be explicitly overridden
            for i in range(len(self.inputs)):
                if 'stop' in self.inputs[i]:
                    if isinstance(self.inputs[i]['stop'],list):
                        assert(len(self.inputs[i]['stop'])==len(self.rounds))
                        t=self.inputs[i]['stop'][self.rndNum]
                    else:
                        t=self.inputs[i]['stop']
                    if (roundType=='U') != (t=='U'):
                        print("Attempt to override round %d (type %s) with a input-specific round type of %s"%(self.rndNum, roundType, t))
                        assert False
                    if roundType!='U':
                        if t=='T':
                            stop[i]='T7%s'%curPrefix[i]
                            prefixOut[i]=curPrefix[i]
                        else:
                            stop[i]=t
                            prefixOut[i]=t

            self.rndNum=self.rndNum+1
            self.finalRound=self.rndNum==len(self.rounds)

            db.pushStatus("%s%d"%(roundType,self.rndNum))
            [r1,bc1]=self.oneround(q,r1,prefixOut=prefixOut,stop=stop,prefixIn=curPrefix,keepCleaved=(roundType!='U'),rtvol=self.rtvol[self.rndNum-1],t7vol=self.t7vol[self.rndNum-1],cycles=self.pcrcycles[self.rndNum-1],pcrdil=self.pcrdil[self.rndNum-1],pcrvol=self.pcrvol[self.rndNum-1],dolig=self.allLig or (roundType!='U'),pcrtgt=None if pcrprods is None else pcrprods[self.rndNum-1])
            db.popStatus()

            # Add TRefs specified in rnddefs 
            if 'tref' in self.rnddef[self.rndNum-1]:
                tref=self.rnddef[self.rndNum-1]['tref']
                assert len(tref)==len(r1)
                for i in range(len(r1)):
                    if tref[i] is not None:
                        trefname='TRef%d'%tref[i]
                        print("Adding %s to %s"%(trefname,r1[i].name))
                        if not reagents.isReagent(trefname):
                            reagents.add(name=trefname,conc=10,extraVol=30,well="E4")
                        trefSamp=reagents.getsample(trefname)
                        oldConc=r1[i].conc.stock
                        oldUnits=r1[i].conc.units
                        oldVol=r1[i].volume
                        self.e.transfer(r1[i].volume/(trefSamp.conc.dilutionneeded()-1),trefSamp,r1[i],mix=(False,False))    # TODO: Check that these end up mixed
                        r1[i].conc=Concentration(stock=oldConc*oldVol/r1[i].volume, units=oldUnits)   # Treat TRef as straight dilution
                        print("New conc=",r1[i].conc)

            for i in range(len(r1)):
                if self.inputs[i]['round'] is None:
                    r1[i].name="%s_%d"%(prefixOut[i],self.nextID)
                else:
                    r1[i].name="%d_%s_R%d%c"%(self.nextID,prefixOut[i],self.inputs[i]['round']+self.rndNum,roundType)
                if self.inputs[i]['ligand'] is not None:
                    r1[i].name="%s_%s"%(r1[i].name,self.inputs[i]['ligand'])
                print("Used ID ", self.nextID," for ", r1[i].name,": ",r1[i])
                self.nextID+=1
                r1[i].conc.final=r1[i].conc.stock*self.templateDilution
            for i in range(len(bc1)):
                #print("Renaming",bc1[i].name)
                pts=bc1[i].name.split(".")
                bc1[i].name="%d_BC_R%d%c"%(self.nextID,self.inputs[i//2]['round']+self.rndNum,roundType)
                if self.inputs[i//2]['ligand'] is not None:
                    bc1[i].name="%s_%s"%(bc1[i].name,self.inputs[i//2]['ligand'])
                bc1[i].name+="_"+pts[-2]
                print("Used ID ", self.nextID," for ", bc1[i].name,":",bc1[i])
                self.nextID+=1
            curPrefix=prefixOut


        if "finalpcr" in self.qpcrStages:
            for i in range(len(r1)):
                if self.singlePrefix:
                    q.addSamples(src=r1[i],needDil=r1[i].conc.stock/self.qConc,primers=["T7X","MX"] if self.useMX else ["T7X"])
                else:
                    # noinspection PyUnboundLocalVariable
                    q.addSamples(src=r1[i],needDil=r1[i].conc.stock/self.qConc,primers=["T7X",prefixOut[i]+"X"]+(["MX"] if self.useMX else []))

        # Add TRefs if needed
        for i in range(len(r1)):
            if 'tref' in self.inputs[i]:
                trefname='TRef%d'%self.inputs[i]['tref']
                if not reagents.isReagent(trefname):
                    reagents.add(name=trefname,conc=10,extraVol=30)
                tref=reagents.getsample(trefname)
                self.e.transfer(r1[i].volume/(tref.conc.dilutionneeded()-1),tref,r1[i],mix=(False,False))

        db.pushStatus('qPCR')
        print("######### qPCR ########### %.0f min"%(clock.elapsed()/60))
        self.allprimers=q.allprimers()
        q.run(confirm=self.qpcrWait)
        db.popStatus()
Example #33
0
    def runPCR(self,primers,src,srcdil,vol=None,tgt=None,ncycles=20,usertime=None,fastCycling=False,inPlace=False,master="MTaq",annealTemp=None,kapa=False):
        ## PCR
        if inPlace:
            if vol!=None:
                print "runPCR: cannot specify volume when using inPlace=True, srcdil and input volume determine reaction volume"
                assert(False)
            if tgt!=None:
                print "runPCR: cannot specify tgt when using inPlace=True"
                assert(False)
            [primers,src,vol,srcdil]=listify([primers,src,vol,srcdil])
            vol=[src[i].volume*srcdil[i] for i in range(len(src))]
            tgt=src
        else: 
            [primers,src,tgt,vol,srcdil]=listify([primers,src,tgt,vol,srcdil])
            for i in range(len(tgt)):
                if tgt[i] is None:
                    if isinstance(primers[i],list):
                        tgt[i]=Sample("%s.P%s"%(src[i].name,"+".join(primers[i])),src[i].plate)
                    else:
                        tgt[i]=Sample("%s.P%s"%(src[i].name,primers[i]),src[i].plate)

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc=Concentration(srcdil[i],1)
        
        logging.notice( "primer="+str(primers))

        # Add reagent entries for any missing primers
        if isinstance(primers[0],list):
            allprimers=[x for y in primers for x in y]
        else:
            allprimers=primers
        for up in set(allprimers):
            s="P-%s"%up
            if not reagents.isReagent(s):
                reagents.add(name=s,conc=4,extraVol=30)

        if isinstance(primers[0],list):
            # Multiple primers
            if inPlace:
                assert len(primers[0])==2
                self.runRxInPlace(src,vol,reagents.getsample(master),master2=[reagents.getsample("P-%s"%p[0]) for p in primers],master3=[reagents.getsample("P-%s"%p[1]) for p in primers],returnPlate=False)
            else:
                for i in range(len(primers)):
                    self.e.stage('PCR%d'%i,[reagents.getsample(master)]+[reagents.getsample("P-%s"%s) for s in primers[i]],src[i:i+1] ,tgt[i:i+1],vol[i:i+1],destMix=False)
                #self.e.shakeSamples(tgt,returnPlate=False)
        else:
            # Single primer
            if inPlace:
                self.runRxInPlace(src,vol,reagents.getsample(master),master2=[reagents.getsample("P-%s"%p) for p in primers],returnPlate=False)
            else:
                for up in set(primers):
                    self.e.stage('PCR%s'%up,[reagents.getsample(master),reagents.getsample("P-%s"%up)],[src[i] for i in range(len(src)) if primers[i]==up],[tgt[i] for i in range(len(tgt)) if primers[i]==up],[vol[i] for i in range(len(vol)) if primers[i]==up],destMix=False)
                #self.e.shakeSamples(tgt,returnPlate=False)

        pgm="PCR%d"%ncycles

        if usertime is None:
            runTime=0
        else:
            runTime=usertime

        if annealTemp is None:
            annealTemp=60 if kapa else 57

        meltTemp=98 if kapa else 95
        hotTime=180 if kapa else 30
        extTemp=72 if kapa else 68
        
        if fastCycling:
            cycling='TEMP@37,%d TEMP@95,%d TEMP@%.1f,10 TEMP@%.1f,10 TEMP @%.1f,1 GOTO@3,%d TEMP@%.1f,60 TEMP@25,2'%(1 if usertime is None else usertime*60,hotTime,meltTemp,annealTemp,extTemp,ncycles-1,extTemp)
            runTime+=hotTime/60+2.8+1.65*ncycles
        else:
            cycling='TEMP@37,%d TEMP@95,%d TEMP@%.1f,30 TEMP@%.1f,30 TEMP@%.1f,30 GOTO@3,%d TEMP@%.1f,60 TEMP@25,2'%(1 if usertime is None else usertime*60,hotTime,meltTemp,annealTemp,extTemp,ncycles-1,extTemp)
            runTime+=hotTime/60+2.8+3.0*ncycles
            
        print "PCR volume=[",",".join(["%.1f"%t.volume for t in tgt]), "], srcdil=[",",".join(["%.1fx"%s for s in srcdil]),"], program: %s"%cycling

        worklist.pyrun('PTC\\ptcsetpgm.py %s %s'%(pgm,cycling))
        self.e.runpgm(pgm,runTime,False,max(vol),hotlidmode="CONSTANT",hotlidtemp=100)
        # Mark samples as mixed (by thermal convection)
        print "Marking samples as mixed (by thermal convection)"
        for t in tgt:
            t.wellMixed=True
            t.lastMixed=clock.elapsed()
        #self.e.shakeSamples(tgt,returnPlate=True)
        return tgt
Example #34
0
    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
Example #35
0
    def setVolumes(self):
        # Computed parameters
        # Observed data:   0.1nM@30min -> gain ~1000
        self.rnaConc=8314.0*self.tmplFinalConc/(self.tmplFinalConc+55)*self.t7dur/30
        if self.tmplFinalConc<1:
            self.rnaConc*=6   # Kludge based on being off at 0.1nM template concentrations
        self.rnaConc=max(40.0,self.rnaConc)   # Another kludge
        if isinstance(self.stopConc,list):
            minStopConc=min(self.stopConc)
        else:
            minStopConc=self.stopConc
        maxConc=1000*minStopConc*4/0.9
        if maxConc<self.rnaConc:
            logging.warning( "Stop@%.1f uM limits usable RNA to %.0f/%.0f nM"%(minStopConc,maxConc,self.rnaConc))
            self.rnaConc=min(maxConc,self.rnaConc)
        stopConc=self.rnaConc*0.9
        rtConc=stopConc/self.rtDil
        rtdilConc=[rtConc/self.rtpostdil[i] for i in range(len(self.rounds))]
        ligConc=[None if self.rounds[i]=='U' else rtdilConc[i]/1.25 for i in range(len(self.rounds))]
        ligdilConc=[None if self.rounds[i]=='U' else ligConc[i]/self.extpostdil[i] for i in range(len(self.rounds))]
        pcrConc=[rtConc/self.pcrdil[i] if self.rounds[i]=='U' else ligConc[i]/self.pcrdil[i] for i in range(len(self.rounds))]
        
        for i in range(len(self.rounds)):
            if ligConc[i] is None:
                print("R%d Concs(nM):  RNA: %.0f, Stop: %.0f, RT: %.0f, RTDil: %.0f, PCRIn: %.0f"%(i, self.rnaConc, stopConc, rtConc, rtdilConc[i], pcrConc[i]))
            else:
                print("R%d Concs(nM):  RNA: %.0f, Stop: %.0f, RT: %.0f, RTDil: %.0f, Lig: %.0f, LigDil: %.0f, PCRIn: %.0f"%(i, self.rnaConc, stopConc, rtConc, rtdilConc[i], ligConc[i], ligdilConc[i], pcrConc[i]))

        self.pcrvol=[self.pcrcopies*self.pmolesIn*1000/pcrConc[i]/math.pow(self.enrich,(i+1.0)) for i in range(len(self.rounds))]
        # Use at least 100ul so the evaporation of the saved sample that occurs during the run will be relatively small
        self.pcrvol=[max(100,v) for v in self.pcrvol]
        print("pcrvol=[%s]"%(",".join(["%.1f"%v for v in self.pcrvol])))
        pcrExtra=[1.4*math.ceil(v*1.0/self.maxPCRVolume) for v in self.pcrvol]
        print("pcrExtra=[%s]"%(",".join(["%.1f"%v for v in pcrExtra])))
        self.minligvol=[(self.pcrvol[i]*1.0+pcrExtra[i])/self.pcrdil[i]+((4.4 if self.saveDil is not None else 5.4 if 'ext' in self.qpcrStages else 0)+15.1)/self.extpostdil[i] for i in range(len(self.pcrvol))]
        print("minligvol=[%s]"%(",".join(["%.1f"%v for v in self.minligvol])))

        # Compute RT volume 
        self.rtvol=[ ((self.minligvol[i]/1.25+3.3)/self.rtpostdil[i]) if self.rounds[i]!='U' else (self.pcrvol[i]*1.0/self.pcrdil[i]+(pcrExtra[i]+15.1+3.3)/self.rtpostdil[i]) for i in range(len(self.rounds))]
        print("self.rtvol=",self.rtvol,", rtSave=",self.rtSave)
        if self.rtSave:
            self.rtvol=[max(15.0/self.rtpostdil[i],self.rtvol[i])+(self.rtSaveVol+1.4)/self.rtpostdil[i] for i in range(len(self.rtvol))]  # Extra for saves
        elif "rt" in self.qpcrStages:		# Take from save if rtSave is set
            self.rtvol=[max(15.0/self.rtpostdil[i],self.rtvol[i])+5.4/self.rtpostdil[i] for i in range(len(self.rtvol))]  # Extra for qPCR
        self.rtvol=[max(v,8.0) for v in self.rtvol]   # Minimum volume
        self.rtvol=[min(v,self.maxSampVolume) for v in self.rtvol]  # Maximum volume
        # print ("self.rtvol=",self.rtvol)
        
        self.t7extravols=((4+1.4) if 'stopped' in self.qpcrStages else 0)+ ((self.saveRNAVolume+1.4) if self.saveRNA else 0) # + 3.3  # 3.3 in case pipette mixing used
        #print "self.t7extravols=%.1f ul\n"%self.t7extravols
        #print "self.rtvol=%s ul\n"%(",".join(["%.1f "%x for x in self.rtvol]))

        # Compute dilutions due to tref additions
        trefdil=[1 for _ in self.rnddef ]
        for i in range(len(self.rnddef)-1):
            rd=self.rnddef[i]
            if 'tref' in rd:
                tref = rd['tref'][0]
                if tref is not None:
                    trefname = 'TRef%d' % tref
                    if not reagents.isReagent(trefname):
                        reagents.add(name=trefname, conc=10, extraVol=30, well="E4")
                    trefs = reagents.getsample(trefname)
                    trefdil[i+1]=(trefs.conc.dilutionneeded())/(trefs.conc.dilutionneeded()-1)
        print("Extra dilution due to tref additions: ",trefdil)
        self.t7vol=[max((15.1+self.rtvol[i]/4.0+1.4)+self.t7extravols,self.pmolesIn*1000.0/(self.tmplFinalConc if i==0 else 200*self.templateDilution)*trefdil[i]/math.pow(self.enrich,i*1.0)) for i in range(len(self.rounds))]
        print("self.t7vol=%s ul\n"%(",".join(["%.1f "%x for x in self.t7vol])))
        #self.t7vol=[max(18.0,v) for v in self.t7vol]   # Make sure that there's enough to add at least 2ul of stop
        if 'template' in self.qpcrStages:
            self.t7vol[0]+=5.4
        self.t7vol=[min(self.maxSampVolume,v) for v in self.t7vol]   # Make sure no tubes overflow
Example #36
0
    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
Example #37
0
 def runKlenow(self,src=None,vol=None,srcdil=None,tgt=None,incTime=15,hiTime=20,inPlace=False):
     assert(inPlace or vol is not None)
     return self.runIncubation(src=src,vol=vol,srcdil=srcdil,tgt=tgt,incTemp=37,incTime=incTime,hiTemp=75,hiTime=hiTime,enzymes=[reagents.getsample("MKlenow")],inPlace=inPlace)
Example #38
0
    def oneround(self,q,input,prefixOut,prefixIn,keepCleaved,t7vol,rtvol,pcrdil,cycles,pcrvol,dolig):
        if keepCleaved:
            print "Starting new cleavage round, will add prefix: ",prefixOut
            assert(dolig)
        else:
            print "Starting new uncleaved round, will retain prefix: ",prefixIn

        if self.rtSave:
            assert(dolig)
            
        names=[i.name for i in input]
            
        print "######## T7 ###########"
        print "Inputs:  (t7vol=%.2f)"%t7vol
        inconc=[inp.conc.final for inp in input]
        for inp in input:
            print "    %s:  %.1ful@%.1f nM, use %.1f ul (%.3f pmoles)"%(inp.name,inp.volume,inp.conc.stock,t7vol/inp.conc.dilutionneeded(), t7vol*inp.conc.final/1000)
            # inp.conc.final=inp.conc.stock*self.templateDilution
        needDil = max([inp.conc.stock for inp in input])*1.0/self.qConc
        if self.directT7 and  self.rndNum==1:
            # Just add ligands and MT7 to each well
            for i in range(len(input)):
                ligand=reagents.getsample(self.inputs[i]['ligand'])
                self.e.transfer(t7vol/ligand.conc.dilutionneeded(),ligand,input[i],mix=(False,False))
            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==self.nrounds and self.finalPlus:
            rxs = self.runT7Setup(src=input,vol=t7vol,srcdil=[inp.conc.dilutionneeded() for inp in input])
            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])
            prefixIn+=prefixIn
            prefixOut+=prefixOut
            names+=["%s+"%n for n in names]
        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])
            
        for i in range(len(rxs)):
            rxs[i].name="%s.rx"%names[i]

        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=["T7X","REF","T7"+prefixIn[i]+"X"],names=["%s.T-"%names[i]])
        
        needDil = needDil*max([inp.conc.dilutionneeded() for inp in input])
        t7dur=30
        self.runT7Pgm(dur=t7dur,vol=t7vol)
        print "Estimate RNA concentration in T7 reaction at %.0f nM"%self.rnaConc
        self.rnaConc=min(40,inconc)*t7dur*65/30

        print "######## Stop ###########"
        #self.saveSamps(src=rxs,vol=5,dil=10,plate=decklayout.EPPENDORFS,dilutant=reagents.getsample("TE8"),mix=(False,False))   # Save to check [RNA] on Qubit, bioanalyzer

        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
        
        stop=["Unclvd-Stop" if (not dolig) else "A-Stop" if n=="A" else "B-Stop" if n=="B" else "W-Stop" if n=="W" else "BADPREFIX" for n in prefixOut]

        stopDil=rxs[0].volume/preStopVolume
        needDil = self.rnaConc/self.qConc/stopDil
        if "stopped" in self.qpcrStages:
            q.addSamples(src=rxs,needDil=needDil,primers=["T7AX","MX","T7X","REF"],names=["%s.stopped"%r.name for r in rxs])
        
        print "######## RT  Setup ###########"
        rtDil=4
        hiTemp=95
        rtDur=20

        rxs=self.runRT(src=rxs,vol=rtvol,srcdil=rtDil,heatInactivate=True,hiTemp=hiTemp,dur=rtDur,incTemp=50,stop=[reagents.getsample(s) for s in stop])    # Heat inactivate also allows splint to fold
        print "RT volume= ",[x.volume for x in rxs]
        needDil /= rtDil
        if "rt" in self.qpcrStages:
            q.addSamples(src=rxs,needDil=needDil,primers=["T7AX","MX","REF"],names=["%s.rt"%r.name for r in rxs])

        rtSaveDil=10
        rtSaveVol=3.5

        if self.rtSave 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  ###########"
            extdil=5.0/4
            reagents.getsample("MLigase").conc=Concentration(5)
            rxs=self.runLig(rxs,inPlace=True)

            print "Ligation volume= ",[x.volume for x in rxs]
            needDil=needDil/extdil
            extpostdil=2
            if extpostdil>1:
                print "Dilution after extension: %.2f"%extpostdil
                self.diluteInPlace(tgt=rxs,dil=extpostdil)
                needDil=needDil/extpostdil
                if not self.doexo:
                    pcrdil=pcrdil/extpostdil
                    
            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=["T7"+prefixIn[i]+"X","T7"+prefixOut[i]+"X","MX","T7X","REF"],names=["%s.ext"%names[i]],save=False)
            else:
                if "ext" in self.qpcrStages:
                    for i in range(len(input)):
                        q.addSamples(src=[rxs[i]],needDil=needDil,primers=["T7"+prefixIn[i]+"X","T7"+prefixOut[i]+"X","MX","T7X","REF"],names=["%s.ext"%names[i]])
                        isave=i+len(input)
                        if isave<len(rxs):
                            # samples restored
                            q.addSamples(src=[rxs[isave]],needDil=needDil/rtSaveDil,primers=["T7"+rxs[isave].name[0]+"X","T7"+("B" if rxs[isave].name[0]=="A" else "W" if rxs[isave].name[0]=="B" else "A")+"X","MX","T7X","REF"])

            if self.doexo:
                print "######## Exo ###########"
                prevvol=rxs[0].volume
                rxs=self.runExo(rxs,incTime=30,inPlace=True)
                exoDil=rxs[0].volume/prevvol
                needDil/=exoDil
                needDil/=7   #  Anecdotal based on Ct's -- large components (MX) reduced by exo digestion
                if "exo" in self.qpcrStages:
                    q.addSamples(src=[rxs[i] for i in self.trackIndices],needDil=needDil,primers=["T7AX","T7BX","MX","T7X","REF"],names=["%s.exo"%names[i] for i in self.trackIndices])
                exo=self.saveSamps(src=rxs,vol=10*exoDil,dil=2/exoDil,dilutant=reagents.getsample("TE8"),tgt=[Sample("%s.exo"%n,decklayout.SAMPLEPLATE) for n in names])   # Save cDNA product
            else:
                exoDil=1
                exo=[]
        else:
            extdil=1
            extpostdil=1
            exoDil=1
            
        if self.doampure:
            print "######## Ampure Cleanup ###########"
            ratio=1.5
            elutionVol=30
            cleanIn=ext+exo+user
            needDil=needDil*cleanIn[0].volume/elutionVol
            clean=self.runAmpure(src=cleanIn,ratio=ratio,elutionVol=elutionVol)
            if "ampure" in self.qpcrStages:
                q.addSamples(src=[clean[i] for i in self.trackIndices],needDil=needDil,primers=["T7AX","MX","T7X","REF"])
            rxs=rxs+clean   # Use the cleaned products for PCR
            
        totalDil=stopDil*rtDil*extdil*extpostdil*exoDil
        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,rtDil,extdil,extpostdil,exoDil,totalDil,fracRetained*100)

        if self.rtSave 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):
            rxs=rxs[0:len(input)]    # Only keep -target products
            prefixOut=prefixOut[0:len(input)]
            prefixIn=prefixIn[0:len(input)]
            
        if self.dopcr:
            print "######### PCR #############"
            print "PCR Volume: %.1f, Dilution: %.1f, volumes available for PCR: [%s]"%(pcrvol, pcrdil,",".join(["%.1f"%r.volume for r in rxs]))
            maxSampleVolume=100  # Maximum sample volume of each PCR reaction (thermocycler limit, and mixing limit)

            initConc=needDil*self.qConc/pcrdil
            if keepCleaved:
                if self.doexo:
                    initConc=initConc*7*self.cleavage		# Back out 7x dilution in exo step, but only use cleaved as input conc
                else:
                    initConc=initConc*self.cleavage		# Only use cleaved as input conc
            else:
                initConc=initConc*(1-self.cleavage)
                
            gain=pcrgain(initConc,400,cycles)
            finalConc=initConc*gain
            print "Estimated starting concentration in PCR = %.1f nM, running %d cycles -> %.0f nM\n"%(needDil*self.qConc,cycles,finalConc)
            nsplit=int(math.ceil(pcrvol*1.0/maxSampleVolume))
            print "Split each PCR into %d reactions"%nsplit
            srcdil=(1-1.0/3-1.0/4)
            sampNeeded=pcrvol/pcrdil
            if self.rtSave and keepCleaved:
                sampNeeded+=rtSaveVol
            maxvol=max([r.volume for r in rxs]);
            minvol=min([r.volume for r in rxs]);
            predil=min(75/maxvol,(40+1.4*nsplit)/(minvol-sampNeeded))  # Dilute to have 40ul left -- keeps enough sample to allow good mixing
            if keepCleaved and self.rtSave and predil>rtSaveDil:
                print "Reducing predil from %.1f to %.1f (rtSaveDil)"%(predil, rtSaveDil)
                predil=rtSaveDil
            if predil>1:
                self.diluteInPlace(rxs,predil)
                self.e.shakeSamples(rxs)
                print "Pre-diluting by %.1fx into [%s] ul"%(predil,",".join(["%.1f"%r.volume for r in rxs]))
            if keepCleaved and self.rtSave:
                assert(len(rxs)==len(rtSave))
                print "Saving %.1f ul of each pre-PCR sample (@%.1f*%.1f dilution)"%(rtSaveVol ,predil, rtSaveDil/predil)
                self.lastSaved=[Sample("%s.sv"%x.name,decklayout.DILPLATE) for x in rxs]
                for i in range(len(rxs)):
                    # Save with rtSaveDil dilution to reduce amount of RT consumed (will have Ct's 2-3 lower than others)
                    self.e.transfer(rtSaveVol*predil,rxs[i],self.lastSaved[i],(False,False))
                    self.e.transfer(rtSaveVol*(rtSaveDil/predil-1),decklayout.WATER,self.lastSaved[i],(False,True))  # Use pipette mixing -- shaker mixing will be too slow

            pcr=self.runPCR(src=rxs*nsplit,vol=pcrvol/nsplit,srcdil=pcrdil*1.0/predil,ncycles=cycles,primers=["T7%sX"%x for x in (prefixOut if keepCleaved else prefixIn)]*nsplit,usertime=self.usertime if keepCleaved else None,fastCycling=True,inPlace=False)
                
            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)
                if self.savedilplate:
                    sv=self.saveSamps(src=pcr[:len(rxs)],vol=[x.volume for x in pcr[:len(rxs)]],dil=1,plate=decklayout.DILPLATE,atEnd=True)
                else:
                    sv=self.saveSamps(src=pcr[:len(rxs)],vol=[x.volume for x in pcr[:len(rxs)]],dil=1,plate=decklayout.EPPENDORFS)
                if nsplit>1:
                    # Combine split
                    for i in range(len(rxs),len(rxs)*nsplit):
                        self.e.transfer(pcr[i].volume-16.4,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(pcr)):
                        q.addSamples(pcr,needDil,["T7%sX"%prefixOut[i]])

                processEff=0.5   # Estimate of overall efficiency of process
                print "Saved %.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:
                return pcr[:len(rxs)]
        else:
            return rxs
Example #39
0
    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
Example #40
0
 def runUser(self,src=None,vol=None,srcdil=None,tgt=None,incTime=15,inPlace=False):
     return self.runIncubation(src=src,vol=vol,srcdil=srcdil,tgt=tgt,incTemp=37,incTime=incTime,enzymes=[reagents.getsample("MUser")],inPlace=inPlace)
Example #41
0
    def pgm(self):
        q = QSetup(self,maxdil=16,debug=False,mindilvol=60)
        self.e.addIdleProgram(q.idler)
        input = [s.getsample()  for s in self.srcs]

        qpcrPrimers=["REF","MX","T7X","T7AX","T7BX","T7WX"]
        q.addSamples(decklayout.SSDDIL,1,qpcrPrimers,save=False)   # Negative controls

        # Save RT product from first (uncleaved) round and then use it during 2nd (cleaved) round for ligation and qPCR measurements
        prefixIn=[inp['prefix'] for inp in self.inputs]
        prefixOut=["A" if p=="W" else "B" if p=="A" else "W" if p=="B" else "BADPREFIX" for p in prefixIn]
            
        print "Starting new cleavage round, will add prefix: ",prefixOut

        names=[i.name for i in input]
            
        print "######## T7 ###########"
        print "Inputs:  (t7vol=%.2f)"%self.t7vol
        for inp in input:
            print "    %s:  %.1ful@%.1f nM, use %.1f ul (%.3f pmoles)"%(inp.name,inp.volume,inp.conc.stock,self.t7vol/inp.conc.dilutionneeded(), self.t7vol*inp.conc.final/1000)

        print "input[0]=",input[0]
        needDil = max([inp.conc.final for inp in input])*1.0/self.qConc
        if self.directT7:
            # Just add MT7 and possibly water to each well
            mconc=reagents.getsample("MT7").conc.dilutionneeded()
            for i in range(len(input)):
                watervol=self.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(self.t7vol/mconc,reagents.getsample("MT7"),input[i],mix=(False,False))
                assert(input[i].volume==self.t7vol)
            rxs=input
        else:
            rxs = self.runT7Setup(src=input,vol=self.t7vol,srcdil=[inp.conc.dilutionneeded() for inp in input])
        print "input[0]=",input[0]
            
        #for i in range(len(rxs)):
        #   q.addSamples(src=rxs],needDil=needDil,primers=["T7"+prefixIn[i]+"X","MX","T7X","REF"],names=["%s.T-"%names[i]])
        
        self.runT7Pgm(dur=self.t7dur,vol=self.t7vol)
        print "Template conc=%.1f nM, estimated RNA concentration in T7 reaction at %.0f nM"%(self.tmplFinalConc,self.rnaConc)
        
        print "######## Stop ###########"
        #self.saveSamps(src=rxs,vol=5,dil=10,plate=decklayout.EPPENDORFS,dilutant=reagents.getsample("TE8"),mix=(False,False))   # Save to check [RNA] on Qubit, bioanalyzer

        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
        
        stop=[ "A-Stop" if n=="A" else "B-Stop" if n=="B" else "W-Stop" if n=="W" else "BADPREFIX" for n in prefixOut]

        for i in range(len(rxs)):
            rxs[i].name=rxs[i].name+"."+stop[i]

        stopDil=rxs[0].volume/preStopVolume
        needDil = self.rnaConc/self.qConc/stopDil
        #q.addSamples(src=rxs,needDil=needDil,primers=["T7AX","MX","T7X","REF"],names=["%s.stopped"%r.name for r in rxs])
        
        print "######## RT  Setup ###########"
        rtDil=4
        hiTemp=95
        rtDur=20

        rxin=rxs
        rxs=self.runRT(src=rxs,vol=self.rtvol,srcdil=rtDil,heatInactivate=True,hiTemp=hiTemp,dur=rtDur,incTemp=50,stop=[reagents.getsample(s) for s in stop])    # Heat inactivate also allows splint to fold
        print "RT volume= ",[x.volume for x in rxs]
        for r in rxin:
            if r.volume>20:
                print "Have more T7 reaction remaining than needed: %s has %.1f ul"%(r.name,r.volume)

        needDil /= rtDil
        rtPostDil=5
        if rtPostDil!=1:
            self.diluteInPlace(tgt=rxs,dil=rtPostDil)
            needDil /= rtPostDil
        #q.addSamples(src=rxs,needDil=needDil,primers=["T7AX","MX","REF"],names=["%s.rt"%r.name for r in rxs])

        print "######## Ligation setup  ###########"
        extdil=5.0/4
        reagents.getsample("MLigase").conc=Concentration(5)
        extvol=20;
        print "Extension volume=",extvol
        rxs=self.runLig(rxs,vol=extvol)

        print "Ligation volume= ",[x.volume for x in rxs]
        needDil=needDil/extdil
        extpostdil=4
        if extpostdil>1:
            print "Dilution after extension: %.2f"%extpostdil
            self.diluteInPlace(tgt=rxs,dil=extpostdil)
            needDil=needDil/extpostdil
            if not self.doexo:
                self.pcrdil=self.pcrdil/extpostdil

        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
            for i in range(len(rxs)):
                q.addSamples(src=[ext[i]],needDil=needDil/self.saveDil,primers=["T7"+prefixIn[i]+"X","T7"+prefixOut[i]+"X","MX","T7X","REF"],names=["%s.ext"%names[i]])
        else:
            for i in range(len(rxs)):
                q.addSamples(src=[rxs[i]],needDil=needDil,primers=["T7"+prefixIn[i]+"X","T7"+prefixOut[i]+"X","MX","T7X","REF"],names=["%s.ext"%names[i]])

        if self.doexo:
            print "######## Exo ###########"
            prevvol=rxs[0].volume
            rxs=self.runExo(rxs,incTime=30,inPlace=True)
            exoDil=rxs[0].volume/prevvol
            needDil/=exoDil
            needDil/=7   #  Anecdotal based on Ct's -- large components (MX) reduced by exo digestion
            q.addSamples(src=rxs,needDil=needDil,primers=["T7AX","T7BX","MX","T7X","REF"],names=["%s.exo"%names[i] for i in range(len(rxs))])
            #exo=self.saveSamps(src=rxs,vol=10*exoDil,dil=2/exoDil,dilutant=reagents.getsample("TE8"),tgt=[Sample("%s.exo"%n,decklayout.SAMPLEPLATE) for n in names])   # Save cDNA product
        else:
            exoDil=1
            exo=[]
        
        if self.doampure:
            print "######## Ampure Cleanup ###########"
            ratio=1.5
            elutionVol=30
            cleanIn=ext+exo+user
            needDil=needDil*cleanIn[0].volume/elutionVol
            clean=self.runAmpure(src=cleanIn,ratio=ratio,elutionVol=elutionVol)
            q.addSamples(src=[clean[i] for i in range(len(rxs))],needDil=needDil,primers=["T7AX","MX","T7X","REF"])
            rxs=rxs+clean   # Use the cleaned products for PCR
            
        totalDil=stopDil*rtDil*rtPostDil*extdil*extpostdil*exoDil
        fracRetained=rxs[0].volume/(self.t7vol*totalDil)
        print "Total dilution from T7 to Pre-pcr Product = %.2f*%.2f*%.2f*%.2f*%.2f*%.2f = %.2f, fraction retained=%.0f%%"%(stopDil,rtDil,rtPostDil,extdil,extpostdil,exoDil,totalDil,fracRetained*100)

        if self.dopcr:
            print "######### PCR #############"
            print "PCR Volume: %.1f, Dilution: %.1f, volumes available for PCR: [%s]"%(self.pcrvol, self.pcrdil,",".join(["%.1f"%r.volume for r in rxs]))
            maxSampleVolume=100  # Maximum sample volume of each PCR reaction (thermocycler limit, and mixing limit)

            initConc=needDil*self.qConc/self.pcrdil
            if self.doexo:
                initConc=initConc*7*self.cleavage		# Back out 7x dilution in exo step, but only use cleaved as input conc
            else:
                initConc=initConc*self.cleavage		# Only use cleaved as input conc

            gain=pcrgain(initConc,400,self.pcrcycles)
            finalConc=initConc*gain
            print "Estimated starting concentration in PCR = %.1f nM, running %d cycles -> %.0f nM\n"%(needDil*self.qConc,self.pcrcycles,finalConc)
            pcr=self.runPCR(src=rxs,vol=self.pcrvol,srcdil=self.pcrdil,ncycles=self.pcrcycles,primers=["T7%sX"%x for x in prefixOut],usertime=self.usertime,fastCycling=True)
                
            needDil=finalConc/self.qConc
            pcrpostdil=2
            if pcrpostdil>1:
                self.diluteInPlace(pcr,pcrpostdil)
                needDil=needDil/pcrpostdil
            print "Projected final concentration = %.0f nM (after %.1fx dilution)"%(needDil*self.qConc,pcrpostdil)
            for i in range(len(pcr)):
                pcr[i].conc=Concentration(stock=finalConc/pcrpostdil,final=None,units='nM')

            if self.pcrSave:
                # Save samples at 1x
                if self.savedilplate:
                    sv=self.saveSamps(src=pcr[:len(rxs)],vol=[x.volume-16.4 for x in pcr[:len(rxs)]],dil=1,plate=decklayout.DILPLATE)
                else:
                    sv=self.saveSamps(src=pcr[:len(rxs)],vol=[x.volume-16.4 for x in pcr[:len(rxs)]],dil=1,plate=decklayout.EPPENDORFS)

                # for i in range(len(pcr)):
                #     q.addSamples(pcr,needDil,["T7%sX"%prefixOut[i]])

                processEff=0.5   # Estimate of overall efficiency of process
                print "Saved %.2f pmoles of product (%.0f ul @ %.1f nM)"%(sv[0].volume*sv[0].conc.stock/1000,sv[0].volume,sv[0].conc.stock)

        print "######### qPCR ###########"
        #q.addReferences(mindil=4,nsteps=6,primers=["T7X","MX","T7AX"])
        #worklist.userprompt('Continue to setup qPCR')
        q.run()
Example #42
0
 def runDNase(self,src=None,vol=None,srcdil=None,tgt=None,incTime=15,hiTime=10,inPlace=False):
     return self.runIncubation(src=src,vol=vol,srcdil=srcdil,tgt=tgt,incTemp=37,incTime=incTime,hiTemp=75,hiTime=hiTime,enzymes=[reagents.getsample("MDNase")],inPlace=inPlace)
Example #43
0
    def pgm(self):
        q = QSetup(self, maxdil=self.maxdilstep, debug=False, mindilvol=60)
        self.e.addIdleProgram(q.idler)

        if self.barcoding:
            # Setup barcode primers for cleaved rounds only
            self.bcprimers = [[
                "BC-%s-R%d_T7" % (inp['ligand'], r + 1) for inp in self.inputs
            ] if self.rounds[r] == 'C' else None
                              for r in range(len(self.rounds))]
            for bcp in self.bcprimers:
                if bcp is not None:
                    for p in ["P-%s" % pp for pp in bcp]:
                        if not reagents.isReagent(p):
                            reagents.add(name=p,
                                         conc=4,
                                         extraVol=30,
                                         plate=decklayout.REAGENTPLATE,
                                         well="B2")
                        s = reagents.getsample(p)  # Force allocation of a well
                        print "Adding %s to reagents at well %s" % (
                            p, s.plate.wellname(s.well))
            print "BC primers=", self.bcprimers

        # Add any missing fields to inputs
        for i in range(len(self.inputs)):
            if 'ligand' not in self.inputs[i]:
                self.inputs[i]['ligand'] = None
            if 'round' not in self.inputs[i]:
                self.inputs[i]['round'] = None
            if 'name' not in self.inputs[i]:
                if self.inputs[i]['ligand'] is None:
                    self.inputs[i]['name'] = '%s_%d_R%d' % (
                        self.inputs[i]['prefix'], self.inputs[i]['ID'],
                        self.inputs[i]['round'])
                else:
                    self.inputs[i]['name'] = '%s_%d_R%d_%s' % (
                        self.inputs[i]['prefix'], self.inputs[i]['ID'],
                        self.inputs[i]['round'], self.inputs[i]['ligand'])

        # Add templates
        if self.directT7:
            self.srcs = self.addTemplates(
                [inp['name'] for inp in self.inputs],
                stockconc=self.tmplFinalConc / self.templateDilution,
                finalconc=self.tmplFinalConc,
                plate=decklayout.SAMPLEPLATE,
                looplengths=[inp['looplength'] for inp in self.inputs],
                initVol=self.t7vol[0] * self.templateDilution,
                extraVol=0)
        else:
            self.srcs = self.addTemplates(
                [inp['name'] for inp in self.inputs],
                stockconc=self.tmplFinalConc / self.templateDilution,
                finalconc=self.tmplFinalConc,
                plate=decklayout.DILPLATE,
                looplengths=[inp['looplength'] for inp in self.inputs],
                extraVol=15)

        t7in = [s.getsample() for s in self.srcs]

        if "negative" in self.qpcrStages:
            q.addSamples(decklayout.SSDDIL, 1, self.allprimers,
                         save=False)  # Negative controls
        if "reference" in self.qpcrStages:
            q.addReferences(dstep=10,
                            nsteps=5,
                            primers=["T7WX", "MX", "T7X"],
                            ref=reagents.getsample("BT5310"),
                            nreplicates=1)
            q.addReferences(dstep=10,
                            nsteps=5,
                            primers=["T7WX", "MX", "T7X"],
                            ref=reagents.getsample("BT5310"),
                            nreplicates=1)

        # Save RT product from first (uncleaved) round and then use it during 2nd (cleaved) round for ligation and qPCR measurements
        self.rndNum = 0
        self.nextID = self.firstID
        curPrefix = [inp['prefix'] for inp in self.inputs]
        r1 = t7in

        for roundType in self.rounds:
            # Run a single round of roundType with r1 as input
            # roundType is either "U" for uncleaved, or a new prefix for a cleaved round (with "T" being a T7 prepend)
            # Set r1 to new output at end

            # Computed output prefix
            if roundType == 'U':
                prefixOut = curPrefix
                stop = ["Unclvd" for p in curPrefix]
            else:
                if roundType == 'T':
                    stop = ['T7%s' % p for p in curPrefix]
                    prefixOut = curPrefix
                elif any([p == roundType for p in curPrefix]):
                    logging.error(
                        "Round %d is a cleaved round but goes to %s without changing prefix"
                        % (self.rndNum, roundType))
                    assert (False)
                else:
                    prefixOut = [roundType for p in curPrefix]
                    stop = prefixOut

            # May be explicitly overridden
            for i in range(len(self.inputs)):
                if 'stop' in self.inputs[i]:
                    if isinstance(self.inputs[i]['stop'], list):
                        assert (len(self.inputs[i]['stop']) == len(
                            self.rounds))
                        t = self.inputs[i]['stop'][self.rndNum]
                    else:
                        t = self.inputs[i]['stop']
                    if (roundType == 'U') != (t == 'U'):
                        print "Attempt to override round %d (type %s) with a input-specific round type of %s" % (
                            self.rndNum, roundType, t)
                        assert (False)
                    if roundType != 'U':
                        if t == 'T':
                            stop[i] = 'T7%s' % curPrefix[i]
                            prefixOut[i] = curPrefix[i]
                        else:
                            stop[i] = t
                            prefixOut[i] = t

            self.rndNum = self.rndNum + 1
            self.finalRound = self.rndNum == len(self.rounds)

            r1 = self.oneround(q,
                               r1,
                               prefixOut=prefixOut,
                               stop=stop,
                               prefixIn=curPrefix,
                               keepCleaved=(roundType != 'U'),
                               rtvol=self.rtvol[self.rndNum - 1],
                               t7vol=self.t7vol[self.rndNum - 1],
                               cycles=self.pcrcycles[self.rndNum - 1],
                               pcrdil=self.pcrdil[self.rndNum - 1],
                               pcrvol=self.pcrvol[self.rndNum - 1],
                               dolig=self.allLig or (roundType != 'U'))

            for i in range(len(r1)):
                r1[i].name = "%s_%d" % (prefixOut[i], self.nextID)
                if self.inputs[i]['round'] is not None:
                    r1[i].name = "%s_R%d%c" % (r1[i].name,
                                               self.inputs[i]['round'] +
                                               self.rndNum, roundType)
                if self.inputs[i]['ligand'] is not None:
                    r1[i].name = "%s_%s" % (r1[i].name,
                                            self.inputs[i]['ligand'])
                print "Used ID ", self.nextID, " for ", r1[i].name, ": ", r1[i]
                self.nextID += 1
                r1[i].conc.final = r1[i].conc.stock * self.templateDilution
            curPrefix = prefixOut

        if "finalpcr" in self.qpcrStages:
            for i in range(len(r1)):
                if self.singlePrefix:
                    q.addSamples(src=r1[i],
                                 needDil=r1[i].conc.stock / self.qConc,
                                 primers=["T7X", "MX"])
                else:
                    q.addSamples(src=r1[i],
                                 needDil=r1[i].conc.stock / self.qConc,
                                 primers=["T7X", prefixOut[i] + "X", "MX"])

        print "######### qPCR ########### %.0f min" % (clock.elapsed() / 60)
        self.allprimers = q.allprimers()
        q.run(confirm=self.qpcrWait)
Example #44
0
    def barcoding(self, names, left, right):
        """Perform barcoding of the given inputs;  rsrsc,left,right should all be equal length"""
        pcrcycles = [5, 10]
        pcr1inputdil = 10
        pcr1vol = 30
        pcr1postdil = 100.0 / pcr1vol

        pcr2dil = 10*pcr1postdil
        pcr2vol = 40.0

        samps = [reagents.getsample(s) for s in names]
        print("Inputs:")
        for i in range(len(samps)):
            print("%2s %-10s %8s-%-8s  %s" % (
                samps[i].plate.wellname(samps[i].well), self.inputs[i]['name'], left[i], right[i], str(samps[i].conc)))

        wellnum = 5
        for s in left + right:
            primer = "P-" + s
            if not reagents.isReagent(primer):
                reagents.add(primer, conc=Concentration(2.67, 0.4, 'uM'), extraVol=30, plate=decklayout.REAGENTPLATE,
                             well=decklayout.REAGENTPLATE.wellname(wellnum))
                wellnum += 1
        for s in samps:
            # Dilute down to desired conc
            dil = s.conc.stock / self.pcr1inputconc / pcr1inputdil
            if dil < 1.0:
                logging.error("Input %s requires dilution of %.2f" % (s.name, dil))
            elif dil > 1.0:
                dilvol = s.volume * dil
                if dilvol > 150.0:
                    maxdil = 150.0 / s.volume
                    logging.info(
                        "Dilution of input %s (%.1f ul) by %.2f would require %.1f ul -- only diluting by %.1fx" % (
                            s.name, s.volume, dil, dilvol, maxdil))
                    dil = maxdil
                self.diluteInPlace(tgt=[s], dil=dil)
                print("Diluting %s by %.1f" % (s.name, dil))

        print("### PCR1 #### (%.0f min)" % (clock.elapsed() / 60.0))

        pcr1 = self.runPCR(src=samps, srcdil=[s.conc.stock / self.pcr1inputconc for s in samps], ncycles=pcrcycles[0],
                           vol=pcr1vol,
                           primers=[[left[i], right[i]] for i in range(len(left))], usertime=30, fastCycling=False,
                           inPlace=False, master="MPCR1", kapa=False, annealTemp=57)

        pcr1finalconc = self.pcr1inputconc * 2 ** pcrcycles[0]
        print("PCR1 output concentration = %.1f nM" % pcr1finalconc)

        if pcr1postdil > 1:
            pcr1finalconc /= pcr1postdil
            print("Post dilute PCR1 by %.2fx to %.3f nM " % (pcr1postdil, pcr1finalconc))
            self.diluteInPlace(tgt=pcr1, dil=pcr1postdil)

        for x in pcr1:
            x.conc = Concentration(stock=pcr1finalconc, units='nM')

        if len(pcrcycles) > 1:
            # Second PCR with 235p/236p on mixture (use at least 4ul of prior)
            print("### PCR2 #### (%.0f min)" % (clock.elapsed() / 60.0))

            pcr2 = self.runPCR(src=pcr1, srcdil=pcr2dil / pcr1postdil, vol=pcr2vol, ncycles=pcrcycles[1],
                               primers=None, fastCycling=False, master="MPCR2", kapa=True, annealTemp=64)

            pcr2finalconc = pcr1finalconc / (pcr2dil / pcr1postdil) * 2 ** pcrcycles[1]
            print("PCR2 final conc = %.1f nM" % pcr2finalconc)
            if pcr2finalconc > 200:
                print("Capping at 200nM")
                pcr2finalconc = 200

            for x in pcr2:
                x.conc = Concentration(stock=pcr2finalconc, units='nM')

            if self.doqpcr:
                self.q.addSamples(src=pcr2, needDil=pcr2finalconc * 1e-9 / self.qconc, primers=self.qprimers)
            res = pcr2
        else:
            self.q.addSamples(src=pcr1, needDil=pcr1finalconc / (self.qconc * 1e9), primers=self.qprimers, save=True,
                              nreplicates=1)
            res = pcr1

        return res
Example #45
0
    def oneround(self, q, inputs, prefixOut, stop, prefixIn, keepCleaved, t7vol, rtvol, pcrdil, cycles, pcrvol, dolig,pcrtgt=None):
        primerSet=[set(["REF","T7X",prefixIn[i]+"X",prefixOut[i]+"X"]+(["MX"] if self.useMX else [])) for i in range(len(prefixIn))]
        if self.extraQPCRPrimers is not None:
            primerSet=[set(list(p) + self.extraQPCRPrimers) for p in primerSet]
            print("primerSet=",primerSet)
            
        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=",round(t7vol,ndigits=2),",rtvol=",rtvol,",pcrdil=",pcrdil,",cycles=",cycles,",dolig=",dolig)
        if self.rtCarryForward:
            assert dolig
            
        names=[i.name for i in inputs]
            
        if self.rnaInput:
            rxs=inputs
            stopDil=1
        else:
            print("######## T7 ########### %.0f min"%(clock.elapsed()/60))
            db.pushStatus("T7")
            print("Inputs:  (t7vol=%.2f)"%t7vol)
            for inp in inputs:
                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))
                else:
                    print("    %s:  %.1ful@%.1f %s, use %.1f ul"%(inp.name,inp.volume,inp.conc.stock,inp.conc.units,t7vol/inp.conc.dilutionneeded()))
                # inp.conc.final=inp.conc.stock*self.templateDilution
            units=list(set([inp.conc.units for inp in inputs]))
            if len(units)>1:
                print("Inputs have inconsistent concentration units: ",units)
                assert False
            if units[0]=='nM':
                needDil = max([inp.conc.stock for inp in inputs]) * 1.0 / self.qConc
            else:
                needDil = 100 / self.qConc  # Assume 100nM

            if self.directT7 and  self.rndNum==1:
                # Just add ligands and MT7 to each well
                mconc=reagents.getsample("MT7").conc.dilutionneeded()
                for i in range(len(inputs)):
                    watervol=t7vol*(1-1/mconc) - inputs[i].volume
                    if watervol<-0.1:
                        print("Negative amount of water (%.1f ul) needed for T7 setup"%watervol)
                        assert False
                    elif watervol>0.1:
                        self.e.transfer(watervol, decklayout.WATER, inputs[i], mix=(False, False))
                    self.e.transfer(t7vol / mconc, reagents.getsample("MT7"), inputs[i], mix=(False, False))
                    assert(abs(inputs[i].volume - t7vol) < 0.1)
                # Add ligands last in case they crash out when they hit aqueous;  this way, they'll be as dilute as possible
                if keepCleaved:
                    for i in range(len(inputs)):
                        if self.inputs[i]['negligand'] is not None:
                            negligand=reagents.getsample(self.inputs[i]['negligand'])
                            self.e.transfer(t7vol / negligand.conc.dilutionneeded(), negligand, inputs[i], mix=(False, False))
                            names[i]+="+"
                else:
                    for i in range(len(inputs)):
                        if self.inputs[i]['ligand'] is not None:
                            ligand=reagents.getsample(self.inputs[i]['ligand'])
                            self.e.transfer(t7vol / ligand.conc.dilutionneeded(), ligand, inputs[i], mix=(False, False))
                            names[i]+="+"
                rxs=inputs
                self.e.shakeSamples(inputs,returnPlate=True)
            elif self.rndNum==len(self.rounds) and self.finalPlus and keepCleaved:
                rxs = self.runT7Setup(ligands=[reagents.getsample(inp['ligand']) for inp in self.inputs],src=inputs, vol=t7vol, srcdil=[inp.conc.dilutionneeded() for inp in inputs])
                for i in range(len(inputs)):
                    inp=inputs[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(ligands=[reagents.getsample(inp['negligand']) for inp in self.inputs], src=inputs, vol=t7vol, srcdil=[inp.conc.dilutionneeded() for inp in inputs])
            else:
                rxs = self.runT7Setup(ligands=[reagents.getsample(inp['ligand']) for inp in self.inputs], src=inputs, vol=t7vol, srcdil=[inp.conc.dilutionneeded() for inp in inputs])

            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]])

            self.runT7Pgm(dur=self.t7dur,vol=t7vol)
            for i in range(len(rxs)):
                rxs[i].name="%s.t7"%names[i]

            self.e.lihahome()
            print("Estimate usable RNA concentration in T7 reaction at %.0f nM"%self.rnaConc)

            if self.rndNum==1:
                worklist.userprompt("T7 Incubation Started",120)
            
            self.e.waitpgm()   # So elapsed time will be updated
            db.popStatus()
            if self.edtastop:
                print("######## Stop ########### %.0f min"%(clock.elapsed()/60))
                db.pushStatus("Stop")
                print("Have %.1f ul before stop"%rxs[0].volume)
                preStopVolume=rxs[0].volume
                self.addEDTA(tgt=rxs,finalconc=2)	# Stop to 2mM EDTA final
                db.popStatus("Stop")

                stopDil=rxs[0].volume/preStopVolume
            else:
                stopDil=1

            if self.pauseAfterStop:
                worklist.userprompt("Post EDTA pause")
                
            if self.saveRNA:
                self.saveSamps(src=rxs,vol=self.saveRNAVolume,dil=self.saveRNADilution,plate=self.savePlate,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))
        db.pushStatus("RT")
        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]

        # Discard extra volume of any sample that has more than current rt volume so that we can shake at high speed
        for r in Sample.getAllOnPlate(rxs[0].plate):
            if r not in rxs and r.volume>max(15+1.4,rxs[0].volume)+4:
                remove=r.volume-(15+1.4)
                oldvol=r.volume
                if r.lastMixed is None:
                    r.lastMixed=clock.elapsed  # Override since we don't care about mixing for disposal
                self.e.dispose(remove,r)
                print("Discarding some of %s to reduce volume from %.1f to %.1f to allow faster shaking"%(r.name,oldvol,r.volume))

        print("RT volume= ",[x.volume for x in rxs])
        self.e.shakeSamples(rxs)
        
        if self.rtSave:
            rtsv=self.saveSamps(src=rxs,vol=self.rtSaveVol,dil=self.rtSaveDil,plate=self.savePlate,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)
        db.popStatus()

        if dolig:
            print("######## Ligation setup  ########### %.0f min"%(clock.elapsed()/60))
            db.pushStatus("Ligation")
            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,self.savePlate) 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))
                        pset=primerSet[i]
                        if "extraQPCR" in self.inputs[i]:
                            pset.udpate(self.inputs[i]["extraQPCR"])
                        q.addSamples(src=[ext[i]],needDil=min(maxdil,needDil/self.saveDil),primers=pset,names=["%s.ext"%names[i]],save=False)
            else:
                if "ext" in self.qpcrStages:
                    print("needDil=",needDil)
                    for i in range(len(names)):
                        pset=primerSet[i]
                        if "extraQPCR" in self.inputs[i]:
                            pset.update(self.inputs[i]["extraQPCR"])
                        q.addSamples(src=[rxs[i]],needDil=needDil,primers=pset,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])
            db.popStatus()
        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(inputs):
            # Have extra samples due when self.finalPlus is True
            rxs= rxs[0:len(inputs)]    # Only keep -target products
            prefixOut= prefixOut[0:len(inputs)]
            prefixIn= prefixIn[0:len(inputs)]
            stop= stop[0:len(inputs)]
            
        if self.dopcr and not (keepCleaved and self.noPCRCleave):
            print("######### PCR ############# %.0f min"%(clock.elapsed()/60))
            db.pushStatus("PCR")
            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)
            sampNeeded=pcrvol/pcrdil
            if self.rtCarryForward and keepCleaved:
                sampNeeded+=rtCarryForwardVol
            if keepCleaved and self.rtCarryForward:
                print("Saving %.1f ul of each pre-PCR sample" % rtCarryForwardVol)
                self.lastSaved=[Sample("%s.sv"%x.name,self.savePlate) 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"

            reagents.getsample(master)    # Allocate for this before primers
            
            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

            rnddef = self.rnddef[self.rndNum-1]
            bcout=[]
            if 'barcode' in rnddef:
                # Add barcoding primers 
                assert len(rnddef['barcode'])==len(rxs)
                dil=self.saveSamps(rxs,dil=50,vol=2,plate=decklayout.SAMPLEPLATE)
                for i in range(len(rxs)):
                    dil[i].conc=Concentration(25,1)
                    for bc in rnddef['barcode'][i]:
                        tgt=Sample("%s.%s"%(rxs[i].name,bc),decklayout.SAMPLEPLATE)
                        bparts=bc.split("/")
                        for b in bparts:
                            if not reagents.isReagent("P-%s"%b):
                                reagents.add(name="P-%s"%b,conc=Concentration(2.67,0.4,'uM'),extraVol=30)
                        print("PCR-%s"%bc)
                        self.e.stage("PCR-%s"%bc,reagents=[reagents.getsample("MTaqBar"),reagents.getsample("P-%s"%bparts[0]),reagents.getsample("P-%s"%bparts[1])],samples=[tgt],sources=[dil[i] ],volume=50,destMix=False)
                        bcout.append(tgt)
                        print(tgt.name,"wellMixed=",tgt.wellMixed)
                        
            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'
                thermocycler.setpgm('rfin',100,cycling)
                self.e.runpgm("rfin",5.0,False,max([p.volume for p in pcr2]))
                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')
            db.popStatus()

            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 and pcrtgt is None:
                    print("Skipping save of final PCR")
                    sv=pcr
                else:
                    residual=2.4   # Amount to leave behind to avoid aspirating air
                    sv=self.saveSamps(src=pcr[:len(rxs)],vol=[min([maxSaveVol,x.volume-residual]) for x in pcr[:len(rxs)]],dil=1,plate=(self.savePlate if self.savedilplate else decklayout.EPPENDORFS),tgt=pcrtgt)
                    if nsplit>1:
                        # Combine split
                        for i in range(len(rxs),len(rxs)*nsplit):
                            self.e.transfer(min([maxSaveVol,pcr[i].volume-residual]),pcr[i],sv[i%len(sv)],mix=(False,False))
                        # Correct concentration (above would've assumed it was diluted)
                        for i in range(len(sv)):
                            sv[i].conc=pcr[i].conc
                        # Shake
                        self.e.shakeSamples(sv)

                if "pcr" in self.qpcrStages:
                    for i in range(len(sv)):
                        q.addSamples(sv[i],needDil,primers=primerSet[i],names=["%s.pcr"%names[i]])

                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))

                # Save barcoded products too
                if len(bcout)>0:
                    print("bcout=",",".join(str(b) for b in bcout))
                    print("mixed=",bcout[0].isMixed(),", wellMixed=",bcout[0].wellMixed)
                    bcsave=self.saveSamps(src=bcout,vol=[b.volume for b in bcout],dil=1,plate=self.savePlate,mix=(False,False))
                    if "bc" in self.qpcrStages:
                        print("Doing qPCR of barcoding: ",bcsave)
                        for i in range(len(bcsave)):
                            needDil=640
                            q.addSamples(src=bcsave[i],needDil=needDil,primers=["T7X","WX","ZX"]+(["MX"] if self.useMX else []),save=False)
                else:
                    bcsave=[]
                    
                return sv, bcsave
            else:
                assert "pcr" not in self.qpcrStages   ## Not implemented
                return pcr[:len(rxs)], bcout

        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]  # FIXME: Is this correct?  Used to have a 'userDil' term
            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  # needDil not used subsequently
                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, []
Example #46
0
    def pgm(self):
        q = QSetup(self, maxdil=16, debug=False, mindilvol=60)
        self.e.addIdleProgram(q.idler)
        input = [s.getsample() for s in self.srcs]

        # Save RT product from first (uncleaved) round and then use it during 2nd (cleaved) round for ligation and qPCR measurements
        prefixIn = [inp['prefix'] for inp in self.inputs]
        prefixOut = [
            "A" if p == "W" else
            "B" if p == "A" else "W" if p == "B" else "BADPREFIX"
            for p in prefixIn
        ]

        qpcrPrimers = ["REF", "MX", "T7X"]
        if "W" in prefixIn + prefixOut:
            qpcrPrimers += ["T7WX"]
        if "A" in prefixIn + prefixOut:
            qpcrPrimers += ["T7AX"]
        if "B" in prefixIn + prefixOut:
            qpcrPrimers += ["T7BX"]
        q.addSamples(decklayout.SSDDIL, 1, qpcrPrimers,
                     save=False)  # Negative controls

        print "Starting new cleavage round, will add prefix: ", prefixOut

        names = [i.name for i in input]

        print "######## T7 ###########"
        print "Inputs:  (t7vol=%.2f)" % self.t7vol
        for inp in input:
            print "    %s:  %.1ful@%.1f nM, use %.1f ul (%.3f pmoles)" % (
                inp.name, inp.volume, inp.conc.stock, self.t7vol /
                inp.conc.dilutionneeded(), self.t7vol * inp.conc.final / 1000)

        print "input[0]=", input[0]
        needDil = max([inp.conc.final for inp in input]) * 1.0 / self.qConc
        if self.directT7:
            # Just add MT7 and possibly water to each well
            mconc = reagents.getsample("MT7").conc.dilutionneeded()
            for i in range(len(input)):
                watervol = self.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(self.t7vol / mconc,
                                reagents.getsample("MT7"),
                                input[i],
                                mix=(False, False))
                assert (input[i].volume == self.t7vol)
            rxs = input
        else:
            rxs = self.runT7Setup(
                src=input,
                vol=self.t7vol,
                srcdil=[inp.conc.dilutionneeded() for inp in input])
        print "input[0]=", input[0]

        #for i in range(len(rxs)):
        #   q.addSamples(src=rxs],needDil=needDil,primers=["T7"+prefixIn[i]+"X","MX","T7X","REF"],names=["%s.T-"%names[i]])

        self.runT7Pgm(dur=self.t7dur, vol=self.t7vol)
        print "Template conc=%.1f nM, estimated RNA concentration in T7 reaction at %.0f nM" % (
            self.tmplFinalConc, self.rnaConc)

        print "######## Stop ###########"
        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=2,
                plate=decklayout.DILPLATE,
                dilutant=reagents.getsample("TE8"),
                mix=(False,
                     False))  # Save to check [RNA] on Qubit, bioanalyzer

        stop = [
            "A-Stop" if n == "A" else
            "B-Stop" if n == "B" else "W-Stop" if n == "W" else "BADPREFIX"
            for n in prefixOut
        ]

        for i in range(len(rxs)):
            rxs[i].name = rxs[i].name + "." + stop[i]

        needDil = self.rnaConc / self.qConc / stopDil
        #q.addSamples(src=rxs,needDil=needDil,primers=["T7AX","MX","T7X","REF"],names=["%s.stopped"%r.name for r in rxs])

        print "######## RT  Setup ###########"
        rtDil = 4
        hiTemp = 95
        rtDur = 20

        rxin = rxs
        rxs = self.runRT(src=rxs,
                         vol=self.rtvol,
                         srcdil=rtDil,
                         heatInactivate=True,
                         hiTemp=hiTemp,
                         dur=rtDur,
                         incTemp=50,
                         stop=[reagents.getsample(s) for s in stop
                               ])  # Heat inactivate also allows splint to fold
        print "RT volume= ", [x.volume for x in rxs]
        for r in rxin:
            if r.volume > 20:
                print "Have more T7 reaction remaining than needed: %s has %.1f ul" % (
                    r.name, r.volume)

        needDil /= rtDil
        rtPostDil = 5
        if rtPostDil != 1:
            self.diluteInPlace(tgt=rxs, dil=rtPostDil)
            needDil /= rtPostDil
        #q.addSamples(src=rxs,needDil=needDil,primers=["T7AX","MX","REF"],names=["%s.rt"%r.name for r in rxs])

        print "######## Ligation setup  ###########"
        extdil = 5.0 / 4
        reagents.getsample("MLigase").conc = Concentration(5)
        extvol = 20
        print "Extension volume=", extvol
        rxs = self.runLig(rxs, vol=extvol)

        print "Ligation volume= ", [x.volume for x in rxs]
        needDil = needDil / extdil
        extpostdil = 4
        if extpostdil > 1:
            print "Dilution after extension: %.2f" % extpostdil
            self.diluteInPlace(tgt=rxs, dil=extpostdil)
            needDil = needDil / extpostdil
            if not self.doexo:
                self.pcrdil = self.pcrdil / extpostdil

        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
            for i in range(len(rxs)):
                q.addSamples(src=[ext[i]],
                             needDil=needDil / self.saveDil,
                             primers=[
                                 "T7" + prefixIn[i] + "X",
                                 "T7" + prefixOut[i] + "X", "MX", "T7X", "REF"
                             ],
                             names=["%s.ext" % names[i]])
        else:
            for i in range(len(rxs)):
                q.addSamples(src=[rxs[i]],
                             needDil=needDil,
                             primers=[
                                 "T7" + prefixIn[i] + "X",
                                 "T7" + prefixOut[i] + "X", "MX", "T7X", "REF"
                             ],
                             names=["%s.ext" % names[i]])

        if self.doexo:
            print "######## Exo ###########"
            prevvol = rxs[0].volume
            rxs = self.runExo(rxs, incTime=30, inPlace=True)
            exoDil = rxs[0].volume / prevvol
            needDil /= exoDil
            needDil /= 7  #  Anecdotal based on Ct's -- large components (MX) reduced by exo digestion
            q.addSamples(src=rxs,
                         needDil=needDil,
                         primers=["T7AX", "T7BX", "MX", "T7X", "REF"],
                         names=["%s.exo" % names[i] for i in range(len(rxs))])
            #exo=self.saveSamps(src=rxs,vol=10*exoDil,dil=2/exoDil,dilutant=reagents.getsample("TE8"),tgt=[Sample("%s.exo"%n,decklayout.SAMPLEPLATE) for n in names])   # Save cDNA product
        else:
            exoDil = 1
            exo = []

        if self.doampure:
            print "######## Ampure Cleanup ###########"
            ratio = 1.5
            elutionVol = 30
            cleanIn = ext + exo + user
            needDil = needDil * cleanIn[0].volume / elutionVol
            clean = self.runAmpure(src=cleanIn,
                                   ratio=ratio,
                                   elutionVol=elutionVol)
            q.addSamples(src=[clean[i] for i in range(len(rxs))],
                         needDil=needDil,
                         primers=["T7AX", "MX", "T7X", "REF"])
            rxs = rxs + clean  # Use the cleaned products for PCR

        totalDil = stopDil * rtDil * rtPostDil * extdil * extpostdil * exoDil
        fracRetained = rxs[0].volume / (self.t7vol * totalDil)
        print "Total dilution from T7 to Pre-pcr Product = %.2f*%.2f*%.2f*%.2f*%.2f*%.2f = %.2f, fraction retained=%.0f%%" % (
            stopDil, rtDil, rtPostDil, extdil, extpostdil, exoDil, totalDil,
            fracRetained * 100)

        if self.dopcr:
            print "######### PCR #############"
            print "PCR Volume: %.1f, Dilution: %.1f, volumes available for PCR: [%s]" % (
                self.pcrvol, self.pcrdil, ",".join(
                    ["%.1f" % r.volume for r in rxs]))
            maxSampleVolume = 100  # Maximum sample volume of each PCR reaction (thermocycler limit, and mixing limit)

            initConc = needDil * self.qConc / self.pcrdil
            if self.doexo:
                initConc = initConc * 7 * self.cleavage  # Back out 7x dilution in exo step, but only use cleaved as input conc
            else:
                initConc = initConc * self.cleavage  # Only use cleaved as input conc

            gain = pcrgain(initConc, 400, self.pcrcycles)
            finalConc = initConc * gain
            print "Estimated starting concentration in PCR = %.1f nM, running %d cycles -> %.0f nM\n" % (
                needDil * self.qConc, self.pcrcycles, finalConc)
            pcr = self.runPCR(src=rxs,
                              vol=self.pcrvol,
                              srcdil=self.pcrdil,
                              ncycles=self.pcrcycles,
                              primers=["T7%sX" % x for x in prefixOut],
                              usertime=self.usertime,
                              fastCycling=True)

            needDil = finalConc / self.qConc
            pcrpostdil = 2
            if pcrpostdil > 1:
                self.diluteInPlace(pcr, pcrpostdil)
                needDil = needDil / pcrpostdil
            print "Projected final concentration = %.0f nM (after %.1fx dilution)" % (
                needDil * self.qConc, pcrpostdil)
            for i in range(len(pcr)):
                pcr[i].conc = Concentration(stock=finalConc / pcrpostdil,
                                            final=None,
                                            units='nM')

            if self.pcrSave:
                # Save samples at 1x
                if self.savedilplate:
                    sv = self.saveSamps(
                        src=pcr[:len(rxs)],
                        vol=[x.volume - 16.4 for x in pcr[:len(rxs)]],
                        dil=1,
                        plate=decklayout.DILPLATE)
                else:
                    sv = self.saveSamps(
                        src=pcr[:len(rxs)],
                        vol=[x.volume - 16.4 for x in pcr[:len(rxs)]],
                        dil=1,
                        plate=decklayout.EPPENDORFS)

                # for i in range(len(pcr)):
                #     q.addSamples(pcr,needDil,["T7%sX"%prefixOut[i]])

                processEff = 0.5  # Estimate of overall efficiency of process
                print "Saved %.2f pmoles of product (%.0f ul @ %.1f nM)" % (
                    sv[0].volume * sv[0].conc.stock / 1000, sv[0].volume,
                    sv[0].conc.stock)

        print "######### qPCR ###########"
        #q.addReferences(mindil=4,nsteps=6,primers=["T7X","MX","T7AX"])
        q.run(confirm=False)
Example #47
0
    def runLig(self,
               prefix=None,
               src=None,
               vol=None,
               srcdil=None,
               tgt=None,
               master=None,
               anneal=True,
               ligtemp=25):
        if master is None:
            master = [
                reagents.getsample("MLigAN7")
                if p == 'A' else reagents.getsample("MLigBN7") for p in prefix
            ]

        #Extension
        [src, tgt, vol, srcdil,
         master] = listify([src, tgt, vol, srcdil, master])
        if tgt is None:
            tgt = [
                Sample("%s.%s" % (src[i].name, master[i].name),
                       decklayout.SAMPLEPLATE) for i in range(len(src))
            ]

        # Need to check since an unused ligation master mix will not have a concentration
        minsrcdil = 1 / (1 - 1 / master[0].conc.dilutionneeded() - 1 /
                         reagents.getsample("MLigase").conc.dilutionneeded())
        for i in srcdil:
            if i < minsrcdil:
                print "runLig: srcdil=%.2f, but must be at least %.2f based on concentrations of master mixes" % (
                    i, minsrcdil)
                assert (False)

        # Adjust source dilution
        for i in range(len(src)):
            src[i].conc = Concentration(srcdil[i], 1)

        i = 0
        while i < len(tgt):
            lasti = i + 1
            while lasti < len(tgt) and master[i] == master[lasti]:
                lasti = lasti + 1
            self.e.stage('LigAnneal', [master[i]],
                         src[i:lasti],
                         tgt[i:lasti], [vol[j] / 1.5 for j in range(i, lasti)],
                         1.5,
                         destMix=False)
            i = lasti

        if anneal:
            self.e.shakeSamples(tgt, returnPlate=False)
            self.e.runpgm("TRPANN",
                          5,
                          False,
                          max(vol),
                          hotlidmode="CONSTANT",
                          hotlidtemp=100)
        self.e.stage('Ligation', [reagents.getsample("MLigase")], [],
                     tgt,
                     vol,
                     destMix=False)
        self.e.shakeSamples(tgt, returnPlate=False)
        self.runLigPgm(max(vol), ligtemp)
        return tgt