Beispiel #1
0
 def addTemplates(self,names,stockconc,finalconc=None,units="nM",plate=decklayout.EPPENDORFS,looplengths=None,extraVol=30,wellnames=None,initVol=0):
     'Add templates as "reagents", return the list of them'
     if finalconc is None:
         logging.warning("final concentration of template not specified, assuming 0.6x (should add to addTemplates() call")
         [names,stockconc]=listify([names,stockconc])
         finalconc=[0.6*x for x in stockconc]
     else:
         [names,stockconc,finalconc]=listify([names,stockconc,finalconc])
     if len(set(names))!=len(names):
         logging.error("addTemplates: template names must be unique")
         
     r=[]
     if looplengths is not None:
         assert(len(names)==len(looplengths))
     for i in range(len(names)):
         if wellnames is None:
             well=None
         else:
             well=wellnames[i]
         if reagents.isReagent(names[i]):
             r.append(reagents.lookup(names[i]))
         elif looplengths is None:
             r.append(reagents.add(names[i],plate=plate,conc=Concentration(stockconc[i],finalconc[i],units),extraVol=extraVol,well=well,initVol=initVol))
         else:
             r.append(reagents.add(names[i],plate=plate,conc=Concentration(stockconc[i],finalconc[i],units),extraVol=extraVol,extrainfo=looplengths[i],well=well,initVol=initVol))
             
     return r
Beispiel #2
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=diluteName(ref.name,srcDil)
                        src=[Sample.lookup(srcname)]
                        if src[0] is None:
                            logging.error("%s not found"%srcname)
                    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)
Beispiel #3
0
    def runRxInPlace(self,src,vol,master,master2=None,master3=None,returnPlate=True,finalx=1.0):
        'Run reaction on beads in given total volume'
        [vol,src,master,master2,master3]=listify([vol,src,master,master2,master3])
        mastervol=[vol[i]*finalx/master[i].conc.dilutionneeded() for i in range(len(vol))]
        master2vol=[0 if master2[i] is None else vol[i]*finalx/master2[i].conc.dilutionneeded() for i in range(len(vol))]
        master3vol=[0 if master3[i] is None else vol[i]*finalx/master3[i].conc.dilutionneeded() for i in range(len(vol))]
        watervol=[vol[i]-src[i].volume-mastervol[i]-master2vol[i]-master3vol[i] for i in range(len(vol))]
        if any([w < -0.02 for w in watervol]):
            logging.error("runRxInPlace: negative amount of water needed: %.2f"%min(watervol))

        for i in range(len(src)):
            if  watervol[i]+src[i].volume>=4.0 and watervol[i]>0.1:
                self.e.transfer(watervol[i],decklayout.WATER,src[i],(False,False))
                watervol[i]=0
        for i in range(len(src)):
            self.e.transfer(mastervol[i],master[i],src[i],(True,False))
        for i in range(len(src)):
            if master2vol[i]>0:
                self.e.transfer(master2vol[i],master2[i],src[i],(True,False))
            if master3vol[i]>0:
                self.e.transfer(master3vol[i],master3[i],src[i],(True,False))
        for i in range(len(src)):
            if  watervol[i]>=0.1:
                self.e.transfer(watervol[i],decklayout.WATER,src[i],(False,False))
        self.e.shakeSamples(src,returnPlate=returnPlate)
Beispiel #4
0
    def run(self,confirm=False,enzName="EvaUSER",waitForPTC=True):
        """Run the dilutions and QPCR setup"""
        # Setup qPCRs
        #self.jobq.dump()
        self.idler(100000)
        if waitForPTC:
            self.trp.e.waitpgm()		# May still need to wait for TC to complete before able to do final jobs
            self.idler(100000)
        worklist.flushQueue()
        if self.jobq.len()>0:
            logging.error( "Blocked jobs remain on queue:")
            self.jobq.dump()
            assert False

        if len(self.dilProds)==0:
            return
        
        if confirm:
            worklist.userprompt('Continue to setup qPCR')

        worklist.comment('Starting qPCR setup')
        self.trp.e.sanitize(force=True)
        if all([allp in p for allp in self.allprimers() for p in self.primers]):
            print("All samples use same qPCR primers")
            # This allows the Eva to be distributed all at once
            self.trp.runQPCR(src=self.dilProds,vol=self.volume,primers=self.allprimers(),nreplicates=self.nreplicates,enzName=enzName)
        else:
            for p in self.allprimers():
                # Build list of relevant entries
                ind=[ i for i in range(len(self.dilProds)) if p in self.primers[i]]
                self.trp.runQPCR(src=[self.dilProds[i] for i in ind],vol=self.volume,primers=[p],nreplicates=[self.nreplicates[i] for i in ind],enzName=enzName)
Beispiel #5
0
    def finish(self):
        self.e.lihahome()
        worklist.userprompt("Process complete. Continue to turn off reagent cooler")
        self.e.setreagenttemp(None)

        #Sample.printallsamples("At completion")
        hasError=False
        for s in Sample.getAllOnPlate():
            if s.volume<1.0 and s.conc is not None and not s.emptied:
                logging.error("Insufficient volume for %s: need at least %.1f ul additional"%(s.name,1.0-s.volume),fatal=False)
                #hasError=True
            elif s.volume<2.5 and s.conc is not None and not s.emptied:
                logging.warning("Low final volume for "+ s.name)
            elif s.volume>s.plate.maxVolume:
                logging.erorr("Excess final volume  (%.1f) for %s: maximum is %.1f ul"%(s.volume,s.name,s.plate.maxVolume),fatal=False)
                hasError=True
                
        if hasError:
            logging.error("NO OUTPUT DUE TO ERRORS")
            
        print "Wells used:  samples: %d, dilutions: %d, qPCR: %d"%(Sample.numSamplesOnPlate(decklayout.SAMPLEPLATE),Sample.numSamplesOnPlate(decklayout.DILPLATE),Sample.numSamplesOnPlate(decklayout.QPCRPLATE))
        # Save worklist to a file
        #e.saveworklist("trp1.gwl")
        (scriptname,ext)=os.path.splitext(sys.argv[0])
        self.e.savegem(scriptname+".gem")
        self.e.savesummary(scriptname+".txt")
        Sample.savematlab(scriptname+".m")
Beispiel #6
0
    def diluteInPlace(self,tgt,dil=None,finalvol=None):
        # Dilute in place
        # e.g.: trp.diluteInPlace(tgt=rt1,dil=2)
        [tgt,dil,finalvol]=listify([tgt,dil,finalvol])
        dilutant=decklayout.WATER
        for i in range(len(tgt)):
            if finalvol[i] is not None and dil[i] is None:
                self.e.transfer(finalvol[i]-tgt[i].volume,dilutant,tgt[i],mix=(False,False))
            elif finalvol[i] is None and dil[i] is not None:
                self.e.transfer(tgt[i].volume*(dil[i]-1),dilutant,tgt[i],mix=(False,False))
            else:
                logging.error("diluteInPlace: cannot specify both dil and finalvol")

        #print "after dilute, tgt[0]=",str(tgt[0]),",mixed=",tgt[0].isMixed()
        return tgt   #  The name of the samples are unchanged -- the predilution names
Beispiel #7
0
    def run(self):
        """Run the dilutions and QPCR setup"""
        # Setup qPCRs
        # self.jobq.dump()
        self.idler(100000)
        self.trp.e.waitpgm()  # May still need to wait for TC to complete before able to do final jobs
        self.idler(100000)

        if self.jobq.len() > 0:
            logging.error("Blocked jobs remain on queue:")
            self.jobq.dump()
            assert False

        tgt1 = Sample("Barcoded.Mixdown1", decklayout.EPPENDORFS)
        for i in range(1, len(self.dilProds)):
            self.e.transfer(12.5 * 1.2 * 2 / 1.5, self.dilProds[i], tgt1, mix=(False, False))
Beispiel #8
0
 def run(self):
     'Run the dilutions and QPCR setup'
     # Setup qPCRs
     #self.jobq.dump()
     self.idler(100000)
     self.trp.e.waitpgm()		# May still need to wait for PTC to complete before able to do final jobs
     self.idler(100000)
     
     if self.jobq.len()>0:
         logging.error( "Blocked jobs remain on queue:",fatal=False)
         self.jobq.dump()
         assert False
     worklist.comment('Starting qPCR setup')
     for p in self.allprimers():
         # Build list of relevant entries
         ind=[ i for i in range(len(self.dilProds)) if p in self.primers[i]]
         self.trp.runQPCR(src=[self.dilProds[i] for i in ind],vol=self.volume,primers=[p],nreplicates=[self.nreplicates[i] for i in ind])
Beispiel #9
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
Beispiel #10
0
    def runIncubation(self,src=None,vol=None,srcdil=None,tgt=None,enzymes=None,incTemp=37,incTime=15,hiTemp=None,hiTime=0,inPlace=False):
        if len(enzymes)!=1:
            logging.error("runIncubation only supports a single master mix")
        if inPlace:
            if tgt is not None:
                logging.error("tgt specified for in-place incubation")
        elif tgt is None:
            tgt=[Sample("%s.%s"%(src[i].name,enzymes[0].name),decklayout.SAMPLEPLATE) for i in range(len(src))]

        if srcdil==None:
            # Minimum dilution (no water)
            srcdil=1/(1-sum([1/e.conc.dilutionneeded() for e in enzymes]))

        if vol is None and inPlace:
            vol=[s.volume*srcdil for s in src]
            
        [src,tgt,vol,srcdil]=listify([src,tgt,vol,srcdil])

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

        if inPlace:
            self.runRxInPlace(src,vol,enzymes[0],returnPlate=False)
            tgt=src
        else:
            self.e.stage('Incubation',enzymes,src,tgt,vol,destMix=False)
            self.e.shakeSamples(tgt,returnPlate=(incTime is None))

        if incTime is None:
            print "Setup only of incubation with %s"%enzymes[0].name
        else:
            if hiTemp is None:
                worklist.pyrun('PTC\\ptcsetpgm.py INC TEMP@%.0f,%.0f TEMP@25,30'%(incTemp,incTime*60))
                print "Incubating at %dC for %d minutes without heat inactivation"%(incTemp, incTime)
                hiTime=0
            else:
                assert(hiTime>0)
                worklist.pyrun('PTC\\ptcsetpgm.py INC TEMP@%.0f,%.0f TEMP@%.0f,%.0f TEMP@25,30'%(incTemp,incTime*60,hiTemp,hiTime*60))
                print "Incubating at %dC for %d minutes followed by heat inactivate at %dC for %d minutes"%(incTemp,incTime,hiTemp,hiTime)
            self.e.runpgm("INC",incTime+hiTime+2,False,max(vol),hotlidmode="TRACKING",hotlidtemp=10)

        return tgt
Beispiel #11
0
    def beadSupernatant(self,src,tgt=None,sepTime=None,residualVolume=0.1,plate=None):
        if plate is None:
            plate=decklayout.SAMPLEPLATE
        if tgt is None:
            tgt=[]
            for i in range(len(src)):
                tgt.append(Sample("%s.SN"%src[i].name,plate))
        [src,tgt]=listify([src,tgt])

        if any([s.plate!=src[0].plate for s in src]):
            logging.error("beadSupernatant: Attempt to magsep on multiple plates at the same time")

        self.e.moveplate(src[0].plate,"Magnet")	# Move to magnet
        self.sepWait(src,sepTime)

        for i in range(len(src)):
            self.e.transfer(src[i].amountToRemove(residualVolume),src[i],tgt[i],(False,False))	# Transfer elution to new tube

        self.e.moveplate(src[0].plate,"Home")
        return tgt
Beispiel #12
0
    def run(self):
        'Run the dilutions and QPCR setup'
        # Setup qPCRs
        #self.jobq.dump()
        self.idler(100000)
        self.trp.e.waitpgm(
        )  # May still need to wait for PTC to complete before able to do final jobs
        self.idler(100000)

        if self.jobq.len() > 0:
            logging.error("Blocked jobs remain on queue:", fatal=False)
            self.jobq.dump()
            assert False

        tgt1 = Sample("Barcoded.Mixdown1", decklayout.EPPENDORFS)
        for i in range(1, len(self.dilProds)):
            self.e.transfer(12.5 * 1.2 * 2 / 1.5,
                            self.dilProds[i],
                            tgt1,
                            mix=(False, False))
Beispiel #13
0
    def run(self,confirm=False,enzName="EvaUSER"):
        'Run the dilutions and QPCR setup'
        # Setup qPCRs
        #self.jobq.dump()
        self.idler(100000)
        self.trp.e.waitpgm()		# May still need to wait for PTC to complete before able to do final jobs
        self.idler(100000)
        worklist.flushQueue()
        if self.jobq.len()>0:
            logging.error( "Blocked jobs remain on queue:",fatal=False)
            self.jobq.dump()
            assert False

        if confirm:
            worklist.userprompt('Continue to setup qPCR')

        worklist.comment('Starting qPCR setup')
        self.trp.e.sanitize(force=True)
        for p in self.allprimers():
            # Build list of relevant entries
            ind=[ i for i in range(len(self.dilProds)) if p in self.primers[i]]
            self.trp.runQPCR(src=[self.dilProds[i] for i in ind],vol=self.volume,primers=[p],nreplicates=[self.nreplicates[i] for i in ind],enzName=enzName)
Beispiel #14
0
    def bindBeads(self,src,beads=None,beadConc=None,beadDil=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,beadDil]=listify([src,beads,bbuffer,beadConc,beadDil])

        for s in src:
            if s.plate!=decklayout.SAMPLEPLATE:
                logging.error( "runBeadCleanup: src "+s.name+" is not in sample plate.")

            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
        beadDil=[beads[i].conc.stock/(beads[i].conc.final if beadConc[i] is None else beadConc[i]) if beadDil[i] is None else beadDil[i] for i in range(len(beads))]

        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=[src[i].volume/(1-1.0/beadDil[i]) for i in range(len(src))]

        beadvol=[totalvol[i]/beadDil[i] for i in range(len(totalvol))]

        # Transfer the beads
        for i in range(len(src)):
            self.e.transfer(beadvol[i],beads[i],src[i],(True,False))	# Mix beads before

        self.e.shakeSamples(src,dur=incTime,returnPlate=False)
Beispiel #15
0
    def __init__(self, inputs):
        super(IDPrep, self).__init__()
        self.inputs = inputs

        self.qconc = 0.020   # Target qPCR concentration in nM
        self.qprimers = ["End"]

        self.bc1_inputvol = 2  # ul into PCR1

        used = []
        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)

        print("used=",used)
        self.rsrc = [reagents.add("%s-%s-%s" % (inputs[i]['name'], inputs[i]['left'], inputs[i]['right']),
                                  decklayout.SAMPLEPLATE,
                                  well=inputs[i]['well'] if 'well' in inputs[i] else None,
                                  conc=Concentration(stock=inputs[i]['conc'], units="nM"),
                                  initVol=self.bc1_inputvol, extraVol=0)
                     for i in range(len(inputs))]
        self.q = None  # Defined in pgm()
Beispiel #16
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()
Beispiel #17
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)
Beispiel #18
0
    def idbarcoding(self, rsrc, left, right):
        """Perform barcoding of the given inputs;  rsrsc,left,right should all be equal length"""
        pcrcycles = [4]   # Don't need 2nd PCR since this will go directly into constriction
        #pcr1inputconc = 0.05  # PCR1 concentration final in reaction
        pcr1inputdil = 10
        pcr1vol = 30
        pcr1postdil = 100.0 / pcr1vol

        pcr2dil = 50
        pcr2minvol = 50.0

        samps = [s.getsample() for s in rsrc]
        print("Inputs:")
        for i in range(len(samps)):
            print("%2s %-10s %8s-%-8s  %.1f%s" % (
                samps[i].plate.wellname(samps[i].well), self.inputs[i]['name'], left[i], right[i], samps[i].conc.stock,samps[i].conc.units))
        # Compute pcr1inputconc such that lowest concentration input ends up with at least 30ul after dilution
        pcr1inputconc=min([s.conc.stock*s.volume/30.0/pcr1inputdil for s in samps])
        print("Diluting inputs so PCR1 final template conc = %.0f pM"%(pcr1inputconc*1000))
        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
        # Run first pass dilution where needed
        for i in range(len(samps)):
            # Dilute down to desired conc
            dil = samps[i].conc.stock / pcr1inputconc / pcr1inputdil
            dilvol = samps[i].volume * dil
            if dilvol > 100.0:
                logging.notice("Dilution of input %s (%.1f ul) by %.2f would require %.1f ul" % (
                    samps[i].name, samps[i].volume, dil, dilvol))
                # Do a first pass dilution into 150ul, then remove enough so second dilution can go into 100ul
                dil1 = 100.0 / samps[i].volume
                self.diluteInPlace(tgt=[samps[i]], dil=dil1)
                print("First pass dilution of %s by %.1f/%.1f (conc now %.3f nM)" % (samps[i].name, dil1, dil, samps[i].conc.stock))
                dil /=  dil1

        # Make sure they are all mixed
        self.e.shakeSamples(samps)

        # Final dilution
        for s in samps:
            # Dilute down to desired conc
            dil = s.conc.stock / 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>100:
                    toremove=s.volume-100.0/dil
                    print("Removing %.1f ul from %s to allow enough room for dilution"%(toremove,s.name))
                    self.e.dispose(toremove, s)
                self.diluteInPlace(tgt=[s], dil=dil)
                print("Diluting %s by %.1f" % (s.name, dil))

        pcr1 = self.runPCR(src=samps, srcdil=pcr1inputdil, ncycles=pcrcycles[0], vol=pcr1vol,
                           primers=[[left[i], right[i]] for i in range(len(left))], usertime=0, fastCycling=False,
                           inPlace=False, master="MKapa", kapa=True)

        pcr1finalconc = pcr1inputconc * self.pcreff ** pcrcycles[0]
        print("PCR1 output concentration = %.3f 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')

        self.q.addSamples(src=pcr1, needDil=pcr1finalconc / self.qconc, primers=self.qprimers, save=True,
                          nreplicates=1)

        if len(pcrcycles) > 1:
            # Second PCR with 235p/236p on mixture (use at least 4ul of prior)
            pcr2 = self.runPCR(src=pcr1, srcdil=pcr2dil / pcr1postdil, vol=max(pcr2minvol, pcr2dil / pcr1postdil * 4),
                               ncycles=pcrcycles[1],
                               primers="End", fastCycling=False, master="MKapa", kapa=True)

            pcr2finalconc = min(200, pcr1finalconc / (pcr2dil / pcr1postdil) * self.pcreff ** pcrcycles[1])
            print("PCR2 final conc = %.1f nM" % pcr2finalconc)

            d2 = min(4.0, 150.0 / max([p.volume for p in pcr2]))
            if d2 > 1:
                pcr2finalconc /= d2
                print("Post-dilute PCR2 by %.1fx to %.3fnM" % (d2, pcr2finalconc))
                self.diluteInPlace(tgt=pcr2, dil=d2)
                self.e.shakeSamples(pcr2)

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

            self.q.addSamples(src=pcr2, needDil=pcr2finalconc / self.qconc, primers=self.qprimers, save=True,
                              nreplicates=2)
            res = pcr2
        else:
            res = pcr1

        return res