Example #1
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")
Example #2
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
Example #3
0
    def pgm(self):
        q = QSetup(self,maxdil=16,debug=False,mindilvol=60)
        self.e.addIdleProgram(q.idler)
        t7in = [s.getsample()  for s in self.srcs]
        
        if "negative" in self.qpcrStages:
            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
        self.rndNum=0
        self.nextID=self.firstID
        curPrefix=[inp['prefix'] for inp in self.inputs]

        while self.rndNum<self.nrounds:
            self.rndNum=self.rndNum+1
                
            prefixOut=["A" if p=="W" else "B" if p=="A" else "W" if p=="B" else "BADPREFIX" for p in curPrefix]
            if self.rndNum==1:
                self.t7vol1=self.t7vol1a
            else:
                self.t7vol1=max(20,self.pmolesIn*1000/min([inp.conc.final for inp in t7in])) # New input volueme
            r1=self.oneround(q,t7in,prefixOut,prefixIn=curPrefix,keepCleaved=False,rtvol=self.rtvol1,t7vol=self.t7vol1,cycles=self.pcrcycles1,pcrdil=self.pcrdil1,pcrvol=self.pcrvol1,dolig=self.allLig)
            # pcrvol is set to have same diversity as input 
            for i in range(len(r1)):
                r1[i].name="%s_%d_R%dU_%s"%(curPrefix[i],self.nextID,self.inputs[i]['round']+self.rndNum,self.inputs[i]['ligand'])
                self.nextID+=1
                r1[i].conc.final=r1[i].conc.stock*self.templateDilution
            if self.rndNum>=self.nrounds:
                logging.warning("Warning: ending on an uncleaved round")
                break
            
            self.rndNum=self.rndNum+1
            print "prefixIn=",curPrefix
            print "prefixOut=",prefixOut
            
            self.t7vol2=max(20,self.pmolesIn*1000/min([inp.conc.final for inp in r1]))
            r2=self.oneround(q,r1,prefixOut,prefixIn=curPrefix,keepCleaved=True,rtvol=self.rtvol2,t7vol=self.t7vol2,cycles=self.pcrcycles2,pcrdil=self.pcrdil2,pcrvol=self.pcrvol2,dolig=True)
            # pcrvol is set to have same diversity as input = (self.t7vol2*self.templateDilution/rnagain*stopdil*rtdil*extdil*exodil*pcrdil)
            for i in range(len(self.inputs)):
                r2[i].name="%s_%d_R%dC_%s"%(prefixOut[i],self.nextID,self.inputs[i]['round']+self.rndNum,self.inputs[i]['ligand'])
                self.nextID+=1
                r2[i].conc.final=r2[i].conc.stock*self.templateDilution
            t7in=r2
            curPrefix=prefixOut
        if "finalpcr" in self.qpcrStages:
            for i in range(len(r2)):
                q.addSamples(src=r2[i],needDil=r2[i].conc.stock/self.qConc,primers=["T7X","T7"+prefixOut[i]+"X"])
            
        print "######### qPCR ###########"
        #q.addReferences(mindil=4,nsteps=6,primers=["T7X","MX","T7AX"])
        if self.qpcrWait:
            worklist.userprompt('Continue to setup qPCR')
        q.run()
Example #4
0
    def logmeasure(self,tip,height,submerge,zmax,zadd,time):
        # Time is the time in seconds of this measurement
        sample=self.lastSample[tip]
        if len(sample.extrainfo)>0:
            elapsed=time-sample.extrainfo[0]
        else:
            elapsed=timedelta(0)

        #print "%s: %f"%(sample.name,elapsed)
        sample.extrainfo=[time]    # Keep track of last measurement time of this sample in the extrainfo list
        if sample.plate.location.zmax is not None:
            curzmax=2100-sample.plate.location.zmax-390+TIPOFFSETS[tip-1]
            if zmax!=curzmax:
                logging.warning("ZMax for plate %s, tip %d at time of run was %.0f, currently at %.0f"%(sample.plate.name, tip, zmax, curzmax))
                zmax=curzmax
        prevol=sample.volume-sample.lastadd		# Liquid height is measured before next op, whose volume effect has already been added to sample.volume
        if height==-1:
            vol=sample.plate.getliquidvolume((zadd+submerge)/10.0)
            if vol is not None:
                if prevol<vol and prevol!=0:
                    # The liquid measure failed, but based on the previous volume estimate, it was guaranteed to fail since the submerge depth would've been below bottom
                    # But if we don't know the volume (ie a prefilled tube -> prevol=0), then log this as a fail
                    h=" @[DEEP <%.1fmm:<%.1ful#%d]"%((zadd+submerge)/10.0,vol,tip)
                    #h=""
                else:
                    h=" @[FAIL <%.1fmm:<%.1ful#%d]"%((zadd+submerge)/10,vol,tip)
            else:
                h=" @[FAIL <%.1f#%d]"%((zadd+submerge)/10.0,tip)
        else:
            vol=sample.plate.getliquidvolume((height+submerge-zmax)/10.0)
            if vol is None:
                h=" @[%.1fmm,%.1fmm#%d]"%((height-zmax)/10.0,submerge/10.0,tip)
            else:
                if prevol==0:
                    logging.notice("Got a liquid height measurement for a well that should be empty -- assuming it was prefilled")
                    sample.volume=vol+sample.lastadd
                    prevol=vol
                expectHeight=sample.plate.getliquidheight(prevol)
                errorHeight=(height+submerge-zmax)-expectHeight*10
                h=" @[%.1fmm,%.1fmm:%.1ful#%d]"%((height-zmax)/10.0,submerge/10.0,vol,tip)
                if abs(errorHeight)>1:
                    if abs(errorHeight)>4:
                        emphasize="*"*(min(10,int(abs(errorHeight))-3))
                    else:
                        emphasize=''
                    h=h+"{%sE=%d;%.1ful}"%(emphasize,errorHeight,vol-prevol)
                sample.volume=sample.volume+(vol-prevol)
        # Insert BEFORE last history entry since the liquid height is measured before aspirate/dispense
        hsplit=sample.history.split(' ')
        if elapsed.total_seconds()>=600:   # Log elapsed time if more than 10 min
            sample.history=" ".join(hsplit[:-1]+["(T%.0f)"%(elapsed.total_seconds()/60)]+[h]+hsplit[-1:])
        else:
            sample.history=" ".join(hsplit[:-1]+[h]+hsplit[-1:])
Example #5
0
 def beadAddElutant(self,src,elutant=None,elutionVol=30,eluteTime=60,returnPlate=True,temp=None):
     if elutant is None:
         elutant=decklayout.WATER
     [src,elutionVol,elutant]=listify([src,elutionVol,elutant])
     for i in range(len(src)):
         if elutionVol[i]<30:
             logging.warning("elution from beads of %s with %.1f ul < minimum of 30ul"%(src[i].name,elutionVol[i]))
         self.e.moveplate(src[i].plate,"Home")
         self.e.transfer(elutionVol[i]-src[i].volume,elutant[i],src[i],(False,True))	
     if temp is None:
         for plate in set([s.plate for s in src]):
             self.e.shake(plate,dur=eluteTime,returnPlate=returnPlate,force=True)
     else:
         self.e.shakeSamples(src,dur=30,returnPlate=False)
         worklist.pyrun('PTC\\ptcsetpgm.py elute TEMP@%d,%d TEMP@25,2'%(temp,eluteTime))
         self.e.runpgm("elute",eluteTime/60,False,elutionVol[0])
         if returnPlate:
             self.e.moveplate(src[0].plate,"Home")
Example #6
0
    def __init__(self,op,tip,vol,wellx,welly,rack,grid,pos,lc,std,volset,isMulti):
        self.op=op
        self.tip=tip
        self.vol=vol
        self.lc=lc
        self.std=std
        self.volset=volset
        self.isMulti=isMulti
        self.sample=getSample(wellx,welly,rack,grid,pos)


        if lc=='Air' or lc[0:7]=='Blowout' or lc=='Dip':
            if op=='dispense':
                self.sample.addhistory(lc,vol,tip)
            elif op=='aspirate':
                self.sample.addhistory(lc,-vol,tip)
            else:
                logging.notice("LogEntry: bad op (%s) for LC %s"%(op,lc))
                assert False
            self.sample.lastadd=0
        elif op=='dispense':
            self.sample.addhistory("",vol,tip)
            self.sample.lastadd=vol
        elif op=='detect':
            self.sample.addhistory("detect",0,tip)
            self.sample.lastadd=0
        elif op=='aspirate':
            self.sample.addhistory("",-vol,tip)
            self.sample.lastadd=-(vol+SURFACEREMOVE)	# Extra for tip wetting
        elif op[0:3]=='mix':
            self.sample.addhistory(op,vol,tip)
            self.sample.lastadd=0
        else:
            logging.warning("LogEntry: bad op: %s"%op)
            assert False
        if self.sample.volume+self.sample.lastadd<0 and self.sample.volume!=0:
            self.sample.history=self.sample.history + ("{Emptied%.2f}"%(self.sample.volume+self.sample.lastadd))
            self.sample.volume=0
        else:
            self.sample.volume+=self.sample.lastadd
Example #7
0
    def addSamples(self, src, needDil, primers, nreplicates=1, names=None, saveVol=None, saveDil=None, save=True):
        """Add sample(s) to list of qPCRs to do"""
        # print "addSamples(%s)"%src
        if not isinstance(src, list):
            src = [src]
        if save:
            # saveVol is total amount (after dilution) to be immediately saved
            if saveDil is None:
                saveDil = min(needDil, self.MAXDIL)
                if 1 < needDil / saveDil < 2:
                    saveDil = math.sqrt(needDil)
            elif saveDil > needDil:
                logging.warning("addSamples: saveDil=" + saveDil + ", but needDil is only " + needDil)
                saveDil = needDil

            if saveVol is None:
                saveVol = max(self.MINDILVOL * 1.0 / saveDil, self.TGTINVOL)

            if names is None:
                tgt = [Sample(diluteName(src[i].name, saveDil), decklayout.DILPLATE) for i in range(len(src))]
            else:
                tgt = [Sample(diluteName(names[i], saveDil), decklayout.DILPLATE) for i in range(len(src))]
            sv = tgt

            for i in range(len(sv)):
                # print "Save ",src[i]
                svtmp = self.trp.runQPCRDIL(src=[src[i]], vol=saveVol * saveDil, srcdil=saveDil, tgt=[tgt[i]],
                                            dilPlate=True, dilutant=self.dilutant)
                sv[i] = svtmp[0]
        else:
            saveDil = 1
            sv = src

        needDil = needDil / saveDil
        nstages = int(math.ceil(math.log(needDil) / math.log(self.MAXDIL)))
        ndil = len(src) * (nstages + (1 if save else 0))
        logging.notice("QPCR: %dQ/%dD [%s], dilution:%.1fx, primers: [%s]" % (
            len(src) * len(primers) * nreplicates, ndil,
            ",".join([s.name for s in src]) if names is None else ",".join(names), needDil, ",".join(primers)))

        for svi in range(len(sv)):
            s = sv[svi]
            if s.hasBeads:
                prereqs = []
            else:
                j0 = self.jobq.addShake(sample=s, prereqs=[])
                prereqs = [j0]
            intermed = s

            for i in range(nstages):
                dil = math.pow(needDil, 1.0 / nstages)
                # print "stage ",i,", needDil=",needDil,", dil=",dil
                if i > 0:
                    vol = self.MAXDILVOL
                else:
                    vol = min(self.MAXDILVOL * 1.0, max(self.MINDILVOL * 1.0, dil * self.TGTINVOL * 1.0))
                if intermed.plate == decklayout.DILPLATE:
                    firstWell = intermed.well + 4  # Skip by 4 wells at a time to optimize multi-tip movements
                else:
                    firstWell = 0
                if not save and i == 0 and names is not None:
                    # Need to replace the name in this condition
                    dest = Sample(diluteName(names[svi], dil), decklayout.DILPLATE, firstWell=firstWell)
                else:
                    dest = Sample(diluteName(intermed.name, dil), decklayout.DILPLATE, firstWell=firstWell)
                # print "dest=",dest
                j1 = self.jobq.addMultiTransfer(volume=vol * (dil - 1) / dil, src=self.dilutant, dest=dest, prereqs=[])
                prereqs.append(j1)
                j2 = self.jobq.addTransfer(volume=vol / dil, src=intermed, dest=dest, prereqs=prereqs)
                # print "Dilution of %s was %.2f instead of %.2f (error=%.0f%%)"%(dest.name,(dil/(1+dil))/(1/dil),dil,((dil/(1+dil))/(1/dil)/dil-1)*100)
                if dest.hasBeads:
                    prereqs = [j2]
                else:
                    j3 = self.jobq.addShake(sample=dest, prereqs=[j2])
                    prereqs = [j3]
                intermed = dest
            self.dilProds = self.dilProds + [intermed]
            self.primers = self.primers + [primers]
            self.nreplicates = self.nreplicates + [nreplicates]
Example #8
0
    def setVolumes(self):
        # Computed parameters
        self.rnaConc = 8314 * self.tmplFinalConc / (self.tmplFinalConc +
                                                    55) * self.t7dur / 30
        maxConc = 1000 * self.stopConc * 4 / 0.9
        if maxConc < self.rnaConc:
            logging.warning("Stop@%.1f uM limits usable RNA to %.0f/%.0f nM" %
                            (self.stopConc, 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]
        pcrExtra = [
            1.4 * math.ceil(v / self.maxPCRVolume) for v in self.pcrvol
        ]
        self.minligvol = [
            self.pcrvol[i] / self.pcrdil[i] +
            (pcrExtra[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] == 'C' 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
        #print  "self.rtvol=",self.rtvol
        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

        self.t7extravols = (
            (4 + 1.4) * 0.9 if 'stopped' in self.qpcrStages else 0) + (
                (5 + 1.4) * 0.9 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]))
        self.t7vol = [
            max((15.1 + self.rtvol[i] / 4.0 + 1.4) * 0.9 + self.t7extravols,
                self.pmolesIn * 1000 / self.tmplFinalConc /
                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
        self.t7vol = [min(self.maxSampVolume, v)
                      for v in self.t7vol]  # Make sure no tubes overflow
        if 'template' in self.qpcrStages:
            self.t7vol[0] += 5.4
Example #9
0
    def addSamples(self,
                   src,
                   needDil,
                   primers,
                   nreplicates=1,
                   names=None,
                   saveVol=None,
                   saveDil=None,
                   save=True):
        'Add sample(s) to list of qPCRs to do'
        #print "addSamples(%s)"%src
        if not isinstance(src, list):
            src = [src]
        if save:
            # saveVol is total amount (after dilution) to be immediately saved
            if saveDil is None:
                saveDil = min(needDil, self.MAXDIL)
                if needDil / saveDil > 1 and needDil / saveDil < 2:
                    saveDil = math.sqrt(needDil)
            elif saveDil > needDil:
                logging.warning("addSamples: saveDil=", saveDil,
                                ", but needDil is only ", needDil)
                saveDil = needDil

            if saveVol is None:
                saveVol = max(self.MINDILVOL * 1.0 / saveDil, self.TGTINVOL)

            if names is None:
                tgt = [
                    Sample(diluteName(src[i].name, saveDil),
                           decklayout.DILPLATE) for i in range(len(src))
                ]
            else:
                tgt = [
                    Sample(diluteName(names[i], saveDil), decklayout.DILPLATE)
                    for i in range(len(src))
                ]
            sv = tgt

            for i in range(len(sv)):
                #print "Save ",src[i]
                svtmp = self.trp.runQPCRDIL(src=[src[i]],
                                            vol=saveVol * saveDil,
                                            srcdil=saveDil,
                                            tgt=[tgt[i]],
                                            dilPlate=True,
                                            dilutant=self.dilutant)
                sv[i] = svtmp[0]
        else:
            saveDil = 1
            sv = src

        needDil = needDil / saveDil
        nstages = int(math.ceil(math.log(needDil) / math.log(self.MAXDIL)))
        ndil = len(src) * (nstages + (1 if save else 0))
        logging.notice(
            "QPCR: %dQ/%dD [%s], dilution:%.1fx, primers: [%s]" %
            (len(src) * len(primers) * nreplicates, ndil,
             ",".join([s.name
                       for s in src]) if names is None else ",".join(names),
             needDil, ",".join(primers)))

        for svi in range(len(sv)):
            s = sv[svi]
            if s.hasBeads:
                prereqs = []
            else:
                j0 = self.jobq.addShake(sample=s, prereqs=[])
                prereqs = [j0]
            intermed = s

            for i in range(nstages):
                dil = math.pow(needDil, 1.0 / nstages)
                #print "stage ",i,", needDil=",needDil,", dil=",dil
                if i > 0:
                    vol = self.MAXDILVOL
                else:
                    vol = min(self.MAXDILVOL,
                              max(self.MINDILVOL, dil * self.TGTINVOL))
                if intermed.plate == decklayout.DILPLATE:
                    firstWell = intermed.well + 4  # Skip by 4 wells at a time to optimize multi-tip movements
                else:
                    firstWell = 0
                if not save and i == 0 and names is not None:
                    # Need to replace the name in this condition
                    dest = Sample(diluteName(names[svi], dil),
                                  decklayout.DILPLATE,
                                  firstWell=firstWell)
                else:
                    dest = Sample(diluteName(intermed.name, dil),
                                  decklayout.DILPLATE,
                                  firstWell=firstWell)
                #print "dest=",dest
                j1 = self.jobq.addMultiTransfer(volume=vol * (dil - 1) / dil,
                                                src=self.dilutant,
                                                dest=dest,
                                                prereqs=[])
                prereqs.append(j1)
                j2 = self.jobq.addTransfer(volume=vol / dil,
                                           src=intermed,
                                           dest=dest,
                                           prereqs=prereqs)
                #print "Dilution of %s was %.2f instead of %.2f (error=%.0f%%)"%(dest.name,(dil/(1+dil))/(1/dil),dil,((dil/(1+dil))/(1/dil)/dil-1)*100)
                if dest.hasBeads:
                    prereqs = [j2]
                else:
                    j3 = self.jobq.addShake(sample=dest, prereqs=[j2])
                    prereqs = [j3]
                intermed = dest
            self.dilProds = self.dilProds + [intermed]
            self.primers = self.primers + [primers]
            self.nreplicates = self.nreplicates + [nreplicates]
Example #10
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